prmbr-image-mksaas/src/components/layout/user-button-mobile.tsx

123 lines
3.7 KiB
TypeScript

'use client';
import { UserAvatar } from '@/components/layout/user-avatar';
import {
Drawer,
DrawerContent,
DrawerHeader,
DrawerOverlay,
DrawerPortal,
DrawerTitle,
DrawerTrigger,
} from '@/components/ui/drawer';
import { getAvatarLinks } from '@/config/avatar-config';
import { LocaleLink, useLocaleRouter } from '@/i18n/navigation';
import { authClient } from '@/lib/auth-client';
import type { User } from 'better-auth';
import { LogOutIcon } from 'lucide-react';
import { useTranslations } from 'next-intl';
import { useState } from 'react';
import { toast } from 'sonner';
interface UserButtonProps {
user: User;
}
export function UserButtonMobile({ user }: UserButtonProps) {
const t = useTranslations();
const avatarLinks = getAvatarLinks();
const localeRouter = useLocaleRouter();
const [open, setOpen] = useState(false);
const closeDrawer = () => {
setOpen(false);
};
const handleSignOut = async () => {
await authClient.signOut({
fetchOptions: {
onSuccess: () => {
console.log('sign out success');
// TanStack Query automatically handles cache invalidation on sign out
localeRouter.replace('/');
},
onError: (error) => {
console.error('sign out error:', error);
toast.error(t('Common.logoutFailed'));
},
},
});
};
return (
<Drawer open={open} onClose={closeDrawer}>
<DrawerTrigger onClick={() => setOpen(true)}>
<UserAvatar
name={user.name}
image={user.image}
className="size-8 border cursor-pointer"
/>
</DrawerTrigger>
<DrawerPortal>
<DrawerOverlay className="fixed inset-0 z-40 bg-background/50" />
<DrawerContent
className="fixed inset-x-0 bottom-0 z-50 mt-24
overflow-hidden rounded-t-[10px] border bg-background px-3 text-sm"
>
<DrawerHeader>
<DrawerTitle />
</DrawerHeader>
<div className="flex items-center justify-start gap-4 p-2">
<UserAvatar
name={user.name}
image={user.image}
className="size-8 border cursor-pointer"
/>
<div className="flex flex-col">
<p className="font-medium">{user.name}</p>
<p className="w-[200px] truncate text-muted-foreground">
{user.email}
</p>
</div>
</div>
<ul className="mb-14 mt-1 w-full text-muted-foreground">
{avatarLinks?.map((item) => (
<li
key={item.title}
className="rounded-lg text-foreground hover:bg-muted"
>
<LocaleLink
href={item.href || '#'}
onClick={closeDrawer}
className="flex w-full items-center gap-3 px-2.5 py-2"
>
{item.icon ? item.icon : null}
<p className="text-sm">{item.title}</p>
</LocaleLink>
</li>
))}
<li
key="logout"
className="rounded-lg text-foreground hover:bg-muted"
>
<a
href="#"
onClick={async (event) => {
event.preventDefault();
closeDrawer();
handleSignOut();
}}
className="flex w-full items-center gap-3 px-2.5 py-2"
>
<LogOutIcon className="size-4" />
<p className="text-sm">{t('Common.logout')}</p>
</a>
</li>
</ul>
</DrawerContent>
</DrawerPortal>
</Drawer>
);
}