'use client'; import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; import { SidebarMenu, SidebarMenuButton, SidebarMenuItem, useSidebar, } from '@/components/ui/sidebar'; import { websiteConfig } from '@/config/website'; import { useLocalePathname, useLocaleRouter } from '@/i18n/navigation'; import { LOCALES, routing } from '@/i18n/routing'; import { authClient } from '@/lib/auth-client'; import { useLocaleStore } from '@/stores/locale-store'; import type { User } from 'better-auth'; import { ChevronsUpDown, Languages, LaptopIcon, LogOut, MoonIcon, SunIcon, } from 'lucide-react'; import { type Locale, useTranslations } from 'next-intl'; import { useTheme } from 'next-themes'; import { useParams } from 'next/navigation'; import { useTransition } from 'react'; import { toast } from 'sonner'; import { UserAvatar } from '../layout/user-avatar'; interface SidebarUserProps { user: User; className?: string; } /** * User navigation for the dashboard sidebar */ export function SidebarUser({ user, className }: SidebarUserProps) { const { setTheme } = useTheme(); const router = useLocaleRouter(); const { isMobile } = useSidebar(); const pathname = useLocalePathname(); const params = useParams(); const { currentLocale, setCurrentLocale } = useLocaleStore(); const [, startTransition] = useTransition(); const t = useTranslations(); const setLocale = (nextLocale: Locale) => { setCurrentLocale(nextLocale); startTransition(() => { router.replace( // @ts-expect-error -- TypeScript will validate that only known `params` // are used in combination with a given `pathname`. Since the two will // always match for the current route, we can skip runtime checks. { pathname, params }, { locale: nextLocale } ); }); }; const showModeSwitch = websiteConfig.metadata.mode?.enableSwitch ?? false; const showLocaleSwitch = LOCALES.length > 1; const handleSignOut = async () => { await authClient.signOut({ fetchOptions: { onSuccess: () => { console.log('sign out success'); // TanStack Query automatically handles cache invalidation on sign out router.replace('/'); }, onError: (error) => { console.error('sign out error:', error); toast.error(t('Common.logoutFailed')); }, }, }); }; return (
{user.name} {user.email}
{user.name} {user.email}
{(showModeSwitch || showLocaleSwitch) && } {showModeSwitch && ( {t('Common.mode.label')} setTheme('light')} > {t('Common.mode.light')} setTheme('dark')} > {t('Common.mode.dark')} setTheme('system')} > {t('Common.mode.system')} )} {showLocaleSwitch && ( {t('Common.language')} {routing.locales.map((localeOption) => ( setLocale(localeOption)} className="cursor-pointer" > {websiteConfig.i18n.locales[localeOption].flag && ( {websiteConfig.i18n.locales[localeOption].flag} )} {websiteConfig.i18n.locales[localeOption].name} ))} )} { event.preventDefault(); handleSignOut(); }} > {t('Common.logout')}
); }