import { HomeIcon, SearchIcon, BookOpenIcon, DotsHorizontalIcon, CashIcon, HeartIcon, UserGroupIcon, TrendingUpIcon, ChatIcon, } from '@heroicons/react/outline' import clsx from 'clsx' import Link from 'next/link' import { useRouter } from 'next/router' import { usePrivateUser, useUser } from 'web/hooks/use-user' import { firebaseLogout, User } from 'web/lib/firebase/users' import { ManifoldLogo } from './manifold-logo' import { MenuButton } from './menu' import { ProfileSummary } from './profile-menu' import NotificationsIcon from 'web/components/notifications-icon' import React, { useEffect, useState } from 'react' import { IS_PRIVATE_MANIFOLD } from 'common/envs/constants' import { CreateQuestionButton } from 'web/components/create-question-button' import { useMemberGroups } from 'web/hooks/use-group' import { groupPath } from 'web/lib/firebase/groups' import { trackCallback, withTracking } from 'web/lib/service/analytics' import { Group, GROUP_CHAT_SLUG } from 'common/group' import { Spacer } from '../layout/spacer' import { useUnseenPreferredNotifications } from 'web/hooks/use-notifications' import { setNotificationsAsSeen } from 'web/pages/notifications' import { PrivateUser } from 'common/user' import { useWindowSize } from 'web/hooks/use-window-size' function getNavigation() { return [ { name: 'Home', href: '/home', icon: HomeIcon }, { name: 'Notifications', href: `/notifications`, icon: NotificationsIcon, }, ...(IS_PRIVATE_MANIFOLD ? [] : [{ name: 'Get M$', href: '/add-funds', icon: CashIcon }]), ] } function getMoreNavigation(user?: User | null) { if (IS_PRIVATE_MANIFOLD) { return [{ name: 'Leaderboards', href: '/leaderboards' }] } if (!user) { return [ { name: 'Leaderboards', href: '/leaderboards' }, { name: 'Charity', href: '/charity' }, { name: 'Blog', href: 'https://news.manifold.markets' }, { name: 'Discord', href: 'https://discord.gg/eHQBNBqXuh' }, { name: 'Twitter', href: 'https://twitter.com/ManifoldMarkets' }, ] } return [ { name: 'Send M$', href: '/links' }, { name: 'Leaderboards', href: '/leaderboards' }, { name: 'Charity', href: '/charity' }, { name: 'Discord', href: 'https://discord.gg/eHQBNBqXuh' }, { name: 'About', href: 'https://docs.manifold.markets/$how-to' }, { name: 'Sign out', href: '#', onClick: withTracking(firebaseLogout, 'sign out'), }, ] } const signedOutNavigation = [ { name: 'Home', href: '/home', icon: HomeIcon }, { name: 'Explore', href: '/markets', icon: SearchIcon }, { name: 'Charity', href: '/charity', icon: HeartIcon }, { name: 'About', href: 'https://docs.manifold.markets/$how-to', icon: BookOpenIcon, }, ] const signedOutMobileNavigation = [ { name: 'About', href: 'https://docs.manifold.markets/$how-to', icon: BookOpenIcon, }, { name: 'Charity', href: '/charity', icon: HeartIcon }, { name: 'Leaderboards', href: '/leaderboards', icon: TrendingUpIcon }, { name: 'Discord', href: 'https://discord.gg/eHQBNBqXuh', icon: ChatIcon }, ] const signedInMobileNavigation = [ ...(IS_PRIVATE_MANIFOLD ? [] : [{ name: 'Get M$', href: '/add-funds', icon: CashIcon }]), { name: 'About', href: 'https://docs.manifold.markets/$how-to', icon: BookOpenIcon, }, ] function getMoreMobileNav() { return [ ...(IS_PRIVATE_MANIFOLD ? [] : [ { name: 'Send M$', href: '/links' }, { name: 'Charity', href: '/charity' }, { name: 'Discord', href: 'https://discord.gg/eHQBNBqXuh' }, ]), { name: 'Leaderboards', href: '/leaderboards' }, { name: 'Sign out', href: '#', onClick: withTracking(firebaseLogout, 'sign out'), }, ] } export type Item = { name: string trackingEventName?: string href: string icon?: React.ComponentType<{ className?: string }> } function SidebarItem(props: { item: Item; currentPage: string }) { const { item, currentPage } = props return ( {item.icon && ( )} {item.name} ) } function SidebarButton(props: { text: string icon: React.ComponentType<{ className?: string }> children?: React.ReactNode }) { const { text, children } = props return ( {text} {children} ) } function MoreButton() { return } export default function Sidebar(props: { className?: string }) { const { className } = props const router = useRouter() const currentPage = router.pathname const user = useUser() const privateUser = usePrivateUser(user?.id) // usePing(user?.id) const navigationOptions = !user ? signedOutNavigation : getNavigation() const mobileNavigationOptions = !user ? signedOutMobileNavigation : signedInMobileNavigation const memberItems = ( useMemberGroups( user?.id, { withChatEnabled: true }, { by: 'mostRecentChatActivityTime' } ) ?? [] ).map((group: Group) => ({ name: group.name, href: `${groupPath(group.slug)}/${GROUP_CHAT_SLUG}`, })) return ( {user && ( )} {/* Mobile navigation */} {mobileNavigationOptions.map((item) => ( ))} {user && ( } /> )} {privateUser && ( )} {/* Desktop navigation */} {navigationOptions.map((item) => ( ))} } /> {/* Spacer if there are any groups */} {memberItems.length > 0 && ( )} {privateUser && ( )} ) } function GroupsList(props: { currentPage: string memberItems: Item[] privateUser: PrivateUser }) { const { currentPage, memberItems, privateUser } = props const preferredNotifications = useUnseenPreferredNotifications( privateUser, { customHref: '/group/', }, memberItems.length > 0 ? memberItems.length : undefined ) // Set notification as seen if our current page is equal to the isSeenOnHref property useEffect(() => { const currentPageGroupSlug = currentPage.split('/')[2] preferredNotifications.forEach((notification) => { if ( notification.isSeenOnHref === currentPage || // Old chat style group chat notif ended just with the group slug notification.isSeenOnHref?.endsWith(currentPageGroupSlug) || // They're on the home page, so if they've a chat notif, they're seeing the chat (notification.isSeenOnHref?.endsWith(GROUP_CHAT_SLUG) && currentPage.endsWith(currentPageGroupSlug)) ) { setNotificationsAsSeen([notification]) } }) }, [currentPage, preferredNotifications]) const { height } = useWindowSize() const [containerRef, setContainerRef] = useState(null) const remainingHeight = (height ?? window.innerHeight) - (containerRef?.offsetTop ?? 0) return ( <> {memberItems.map((item) => ( !n.isSeen && (n.isSeenOnHref === item.href || n.isSeenOnHref === item.href.replace('/chat', '')) ) && 'font-bold' )} > {item.name} ))} > ) }