import { CalendarIcon, HomeIcon, NewspaperIcon, QuestionMarkCircleIcon, } from '@heroicons/react/24/outline' import { CogIcon, GlobeAltIcon, HomeIcon as SolidHomeIcon, LinkIcon, QuestionMarkCircleIcon as SolidQuestionIcon, UserCircleIcon, UsersIcon, } from '@heroicons/react/24/solid' import clsx from 'clsx' import {IS_MAINTENANCE} from 'common/constants' import {Profile} from 'common/profiles/profile' import {User} from 'common/user' import {buildArray} from 'common/util/array' import {ReactNode, useState} from 'react' import {Toaster} from 'react-hot-toast' import {FaEnvelope} from 'react-icons/fa' import {MdThumbUp} from 'react-icons/md' import {Col} from 'web/components/layout/col' import {PrivateMessagesIcon} from 'web/components/messaging/messages-icon' import {BottomNavBar} from 'web/components/nav/bottom-nav-bar' import {SkipLink} from 'web/components/skip-link' import {useIsMobile} from 'web/hooks/use-is-mobile' import {useOnline} from 'web/hooks/use-online' import {useProfile} from 'web/hooks/use-profile' import {useTracking} from 'web/hooks/use-tracking' import {useUser} from 'web/hooks/use-user' import {GoogleOneTapLogin} from 'web/lib/firebase/google-onetap-login' import Sidebar from './nav/sidebar' import {NotificationsIcon, SolidNotificationsIcon} from './notifications-icon' export function PageBase(props: { trackPageView?: string | false trackPageProps?: Record className?: string children?: ReactNode hideSidebar?: boolean hideBottomBar?: boolean }) { const {trackPageView, trackPageProps, children, className, hideSidebar, hideBottomBar} = props const user = useUser() const isMobile = useIsMobile() const profile = useProfile() const bottomNavOptions = user ? getBottomNavigation(user, profile) : getBottomSignedOutNavigation() // const [isModalOpen, setIsModalOpen] = useState(false) const desktopSidebarOptions = getDesktopNavigation(user) const mobileSidebarOptions = getMobileSidebar(user, () => setIsAddFundsModalOpen(true)) // eslint-disable-next-line react-hooks/rules-of-hooks if (trackPageView) useTracking(`view ${trackPageView}`, trackPageProps) useOnline() const [_, setIsAddFundsModalOpen] = useState(false) const colSpan = className?.split(' ').find((c) => c.startsWith('col-span-')) ?? 'col-span-8' const restClassName = className ?.split(' ') .filter((c) => !c.startsWith('col-span-')) .join(' ') return ( <> {/* Maintenance banner */} {IS_MAINTENANCE && (
Maintenance in progress: Some features may be broken for the next few hours.
)} {hideSidebar ? (
) : ( )}
{children}
{!hideBottomBar && ( )} ) } const Profiles = { key: 'nav.people', name: 'People', href: '/', icon: UsersIcon, } const Home = {key: 'nav.home', name: 'Home', href: '/', icon: HomeIcon} const faq = { key: 'nav.faq', name: 'FAQ', href: '/faq', icon: SolidQuestionIcon, } const About = { key: 'nav.about', name: 'About', href: '/about', icon: QuestionMarkCircleIcon, } const Signin = { key: 'nav.sign_in', name: 'Sign in', href: '/signin', icon: UserCircleIcon, } const Notifs = { key: 'nav.notifs', name: 'Notifs', href: `/notifications`, icon: NotificationsIcon, } const NotifsSolid = { key: 'nav.notifs', name: 'Notifs', href: `/notifications`, icon: SolidNotificationsIcon, } const Social = { key: 'nav.social', name: 'Socials', href: '/social', icon: LinkIcon, } const Organization = { key: 'nav.organization', name: 'Organization', href: '/organization', icon: GlobeAltIcon, } const Vote = {key: 'nav.vote', name: 'Vote', href: '/vote', icon: MdThumbUp} const Contact = { key: 'nav.contact', name: 'Contact', href: '/contact', icon: FaEnvelope, } const News = { key: 'nav.news', name: "What's new", href: '/news', icon: NewspaperIcon, } const Settings = { key: 'nav.settings', name: 'Settings', href: '/settings', icon: CogIcon, } const Events = { key: 'nav.events', name: 'Events', href: '/events', icon: CalendarIcon, } // Stable component for Messages icon to prevent re-mounting on every render const MessagesIconComponent = (props: any) => const base = [About, faq, Vote, Events, News, Social, Organization, Contact] function getBottomNavigation(user: User, profile: Profile | null | undefined) { return buildArray( Profiles, NotifsSolid, { key: 'nav.profile', name: 'Profile', href: profile === null ? '/signup' : `/${user.username}`, icon: SolidHomeIcon, }, { key: 'nav.messages', name: 'Messages', href: '/messages', icon: MessagesIconComponent, }, ) } const getBottomSignedOutNavigation = () => [Home, About, Signin] const getDesktopNavigation = (user: User | null | undefined) => { if (user) return buildArray( Profiles, Notifs, { key: 'nav.messages', name: 'Messages', href: '/messages', icon: MessagesIconComponent, }, Settings, ...base, ) return buildArray(...base) } const getMobileSidebar = (user: User | null | undefined, _toggleModal: () => void) => { if (user) return buildArray(Settings, ...base) return buildArray(...base) }