159 lines
5.2 KiB
TypeScript
159 lines
5.2 KiB
TypeScript
import { authClient } from '@/lib/auth-client';
|
|
import { m } from '@/paraglide/messages';
|
|
import {
|
|
DotsThreeVerticalIcon,
|
|
KeyIcon,
|
|
SignInIcon,
|
|
SignOutIcon,
|
|
UserCircleIcon,
|
|
} from '@phosphor-icons/react';
|
|
import { useQueryClient } from '@tanstack/react-query';
|
|
import { createLink, Link, useNavigate } from '@tanstack/react-router';
|
|
import { toast } from 'sonner';
|
|
import { useAuth } from '../auth/auth-provider';
|
|
import AvatarUser from '../avatar/avatar-user';
|
|
import RoleBadge from '../avatar/role-badge';
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuGroup,
|
|
DropdownMenuItem,
|
|
DropdownMenuLabel,
|
|
DropdownMenuSeparator,
|
|
DropdownMenuTrigger,
|
|
} from '../ui/dropdown-menu';
|
|
import {
|
|
SidebarMenu,
|
|
SidebarMenuButton,
|
|
SidebarMenuItem,
|
|
useSidebar,
|
|
} from '../ui/sidebar';
|
|
|
|
const SidebarMenuButtonLink = createLink(SidebarMenuButton);
|
|
|
|
const NavUser = () => {
|
|
const navigate = useNavigate();
|
|
const { isMobile } = useSidebar();
|
|
const queryClient = useQueryClient();
|
|
const { data: session } = useAuth();
|
|
|
|
const signout = async () => {
|
|
await authClient.signOut({
|
|
fetchOptions: {
|
|
onSuccess: () => {
|
|
navigate({ to: '/' });
|
|
queryClient.invalidateQueries({ queryKey: ['auth', 'session'] });
|
|
toast.success(m.login_page_messages_logout_success(), {
|
|
richColors: true,
|
|
});
|
|
},
|
|
onError: (ctx) => {
|
|
console.error(ctx.error.code);
|
|
toast.error(m.backend_message({ code: ctx.error.code }), {
|
|
richColors: true,
|
|
});
|
|
},
|
|
},
|
|
});
|
|
};
|
|
|
|
if (!session?.user)
|
|
return (
|
|
<SidebarMenu>
|
|
<SidebarMenuItem>
|
|
<SidebarMenuButtonLink
|
|
to="/sign-in"
|
|
className="flex items-center gap-2 w-full"
|
|
tooltip="Sign In"
|
|
>
|
|
<SignInIcon size={28} />
|
|
{m.ui_login_btn()}
|
|
</SidebarMenuButtonLink>
|
|
</SidebarMenuItem>
|
|
</SidebarMenu>
|
|
);
|
|
|
|
return (
|
|
<SidebarMenu>
|
|
<SidebarMenuItem>
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger asChild>
|
|
<SidebarMenuButton
|
|
size="lg"
|
|
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground cursor-pointer"
|
|
tooltip={session.user.name}
|
|
>
|
|
<AvatarUser className="h-8 w-8" />
|
|
<div className="grid flex-1 text-left text-sm leading-tight">
|
|
<span className="truncate font-medium">
|
|
{session.user.name}
|
|
</span>
|
|
<span className="truncate text-xs">{session.user.email}</span>
|
|
</div>
|
|
<DotsThreeVerticalIcon size={28} />
|
|
</SidebarMenuButton>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent
|
|
className="w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg"
|
|
side={isMobile ? 'bottom' : 'right'}
|
|
align="end"
|
|
sideOffset={15}
|
|
>
|
|
{/* Dropdown menu content */}
|
|
<DropdownMenuLabel className="p-0 font-normal">
|
|
<div className="flex items-center gap-2 px-1 py-1.5 text-left text-sm">
|
|
<AvatarUser className="h-8 w-8" />
|
|
<div className="grid flex-1 text-left text-sm leading-tight">
|
|
<div className="flex gap-2 items-center">
|
|
<span className="truncate font-medium">
|
|
{session.user.name}
|
|
</span>
|
|
<RoleBadge
|
|
type={session.user.role}
|
|
className="text-[10px] px-2 py-0 leading-0.5 h-4"
|
|
/>
|
|
</div>
|
|
<span className="truncate text-xs">{session.user.email}</span>
|
|
</div>
|
|
</div>
|
|
</DropdownMenuLabel>
|
|
<DropdownMenuSeparator />
|
|
<DropdownMenuGroup>
|
|
<DropdownMenuItem className="cursor-pointer" asChild>
|
|
<Link to="/account/profile">
|
|
<UserCircleIcon size={28} />
|
|
{m.nav_account()}
|
|
</Link>
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem className="cursor-pointer" asChild>
|
|
<Link to="/account/change-password">
|
|
<KeyIcon size={28} />
|
|
{m.nav_change_password()}
|
|
</Link>
|
|
</DropdownMenuItem>
|
|
</DropdownMenuGroup>
|
|
<DropdownMenuSeparator />
|
|
<DropdownMenuGroup>
|
|
<DropdownMenuItem className="cursor-pointer" asChild>
|
|
<Link to="/account/settings">
|
|
<UserCircleIcon size={28} />
|
|
{m.nav_settings()}
|
|
</Link>
|
|
</DropdownMenuItem>
|
|
</DropdownMenuGroup>
|
|
<DropdownMenuSeparator />
|
|
<DropdownMenuGroup>
|
|
<DropdownMenuItem onSelect={signout} className="cursor-pointer">
|
|
<SignOutIcon size={28} />
|
|
{m.ui_logout_btn()}
|
|
</DropdownMenuItem>
|
|
</DropdownMenuGroup>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
</SidebarMenuItem>
|
|
</SidebarMenu>
|
|
);
|
|
};
|
|
|
|
export default NavUser;
|