'use client'; import LocaleSelector from '@/components/layout/locale-selector'; import { Logo } from '@/components/layout/logo'; import { ModeSwitcherHorizontal } from '@/components/layout/mode-switcher-horizontal'; import { Button, buttonVariants } from '@/components/ui/button'; import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from '@/components/ui/collapsible'; import { getNavbarLinks } from '@/config/navbar-config'; import { LocaleLink, useLocalePathname } from '@/i18n/navigation'; import { authClient } from '@/lib/auth-client'; import { cn } from '@/lib/utils'; import { Routes } from '@/routes'; import { Portal } from '@radix-ui/react-portal'; import { ArrowUpRightIcon, ChevronDownIcon, ChevronRightIcon, MenuIcon, XIcon, } from 'lucide-react'; import { useTranslations } from 'next-intl'; import * as React from 'react'; import { useEffect, useState } from 'react'; import { RemoveScroll } from 'react-remove-scroll'; import { Skeleton } from '../ui/skeleton'; import { UserButtonMobile } from './user-button-mobile'; export function NavbarMobile({ className, ...other }: React.HTMLAttributes) { const t = useTranslations(); const [open, setOpen] = React.useState(false); const localePathname = useLocalePathname(); const [mounted, setMounted] = useState(false); const { data: session, isPending } = authClient.useSession(); const currentUser = session?.user; useEffect(() => { setMounted(true); }, []); useEffect(() => { const handleRouteChangeStart = () => { if (document.activeElement instanceof HTMLInputElement) { document.activeElement.blur(); } setOpen(false); }; handleRouteChangeStart(); }, [localePathname]); const handleChange = () => { const mediaQueryList = window.matchMedia('(min-width: 1024px)'); setOpen((open) => (open ? !mediaQueryList.matches : false)); }; useEffect(() => { handleChange(); const mediaQueryList = window.matchMedia('(min-width: 1024px)'); mediaQueryList.addEventListener('change', handleChange); return () => mediaQueryList.removeEventListener('change', handleChange); }, []); const handleToggleMobileMenu = (): void => { setOpen((open) => !open); }; if (!mounted) { return null; } return ( <>
{/* navbar left shows logo */} {t('Metadata.name')} {/* navbar right shows menu icon and user button */}
{/* show user button if user is logged in */} {isPending ? ( ) : currentUser ? ( <> {/* */} ) : null}
{/* mobile menu */} {open && ( {/* if we don't add RemoveScroll component, the underlying page will scroll when we scroll the mobile menu */} {/* Only render MainMobileMenu when not in loading state */} {!isPending && ( )} )} ); } interface MainMobileMenuProps { userLoggedIn: boolean; onLinkClicked: () => void; } function MainMobileMenu({ userLoggedIn, onLinkClicked }: MainMobileMenuProps) { const [expanded, setExpanded] = React.useState>({}); const t = useTranslations(); const menuLinks = getNavbarLinks(); const localePathname = useLocalePathname(); return (
{/* action buttons */} {userLoggedIn ? null : (
{t('Common.login')} {t('Common.signUp')}
)} {/* main menu */}
    {menuLinks?.map((item) => { const isActive = item.href ? item.href === '/' ? localePathname === '/' : localePathname.startsWith(item.href) : item.items?.some( (subItem) => subItem.href && (subItem.href === '/' ? localePathname === '/' : localePathname.startsWith(subItem.href)) ); return (
  • {item.items ? ( setExpanded((prev) => ({ ...prev, [item.title.toLowerCase()]: isOpen, })) } >
      {item.items.map((subItem) => { const isSubItemActive = subItem.href && localePathname.startsWith(subItem.href); return (
    • {subItem.icon ? subItem.icon : null}
      {subItem.title} {/* hide description for now */} {/* {subItem.description && (

      {subItem.description}

      )} */}
      {subItem.external && ( )}
    • ); })}
    ) : (
    {item.title}
    )}
  • ); })}
{/* bottom buttons */}
); }