MIF_E31220277/denta-admin/src/components/layout/app-sidebar.tsx

240 lines
7.9 KiB
TypeScript

'use client';
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger
} from '@/components/ui/collapsible';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger
} from '@/components/ui/dropdown-menu';
import {
Sidebar,
SidebarContent,
SidebarFooter,
SidebarGroup,
SidebarGroupLabel,
SidebarHeader,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
SidebarMenuSub,
SidebarMenuSubButton,
SidebarMenuSubItem,
SidebarRail
} from '@/components/ui/sidebar';
import { UserAvatarProfile } from '@/components/user-avatar-profile';
import { navItems } from '@/constants/data';
import { useMediaQuery } from '@/hooks/use-media-query';
import useAuthUser from '@/features/auth/hooks/use-auth-user';
import { useSignOutMutation } from '@/features/auth/hooks/use-mutation';
import {
IconBell,
IconChevronRight,
IconChevronsDown,
IconCreditCard,
IconLogout,
IconPhotoUp,
IconUserCircle
} from '@tabler/icons-react';
import Link from 'next/link';
import { usePathname, useRouter } from 'next/navigation';
import * as React from 'react';
import { Icons } from '../icons';
import { OrgSwitcher } from '../org-switcher';
import { toast } from 'sonner';
export const company = {
name: 'Acme Inc',
logo: IconPhotoUp,
plan: 'Enterprise'
};
const tenants = [
{ id: '1', name: 'Acme Inc' },
{ id: '2', name: 'Beta Corp' },
{ id: '3', name: 'Gamma Ltd' }
];
export default function AppSidebar() {
const pathname = usePathname();
const { isOpen } = useMediaQuery();
const { data: user } = useAuthUser();
const signOutMutation = useSignOutMutation();
const router = useRouter();
const handleSwitchTenant = (_tenantId: string) => {
// Tenant switching functionality would be implemented here
};
const handleSignOut = () => {
signOutMutation.mutate(undefined, {
onSuccess: () => {
toast.success('Signed out successfully');
router.push('/auth/sign-in');
},
onError: (error: any) => {
toast.error(error.message || 'Sign out failed');
}
});
};
const activeTenant = tenants[0];
React.useEffect(() => {
// Side effects based on sidebar state changes
}, [isOpen]);
return (
<Sidebar collapsible='icon'>
<SidebarHeader>
<OrgSwitcher
tenants={tenants}
defaultTenant={activeTenant}
onTenantSwitch={handleSwitchTenant}
/>
</SidebarHeader>
<SidebarContent className='overflow-x-hidden'>
<SidebarGroup>
<SidebarGroupLabel>Overview</SidebarGroupLabel>
<SidebarMenu>
{navItems.map((item) => {
const Icon = item.icon ? Icons[item.icon] : Icons.logo;
return item?.items && item?.items?.length > 0 ? (
<Collapsible
key={item.title}
asChild
defaultOpen={item.isActive}
className='group/collapsible'
>
<SidebarMenuItem>
<CollapsibleTrigger asChild>
<SidebarMenuButton
tooltip={item.title}
isActive={pathname === item.url}
>
{item.icon && <Icon />}
<span>{item.title}</span>
<IconChevronRight className='ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90' />
</SidebarMenuButton>
</CollapsibleTrigger>
<CollapsibleContent>
<SidebarMenuSub>
{item.items?.map((subItem) => (
<SidebarMenuSubItem key={subItem.title}>
<SidebarMenuSubButton
asChild
isActive={pathname === subItem.url}
>
<Link href={subItem.url}>
<span>{subItem.title}</span>
</Link>
</SidebarMenuSubButton>
</SidebarMenuSubItem>
))}
</SidebarMenuSub>
</CollapsibleContent>
</SidebarMenuItem>
</Collapsible>
) : (
<SidebarMenuItem key={item.title}>
<SidebarMenuButton
asChild
tooltip={item.title}
isActive={pathname === item.url}
>
<Link href={item.url}>
<Icon />
<span>{item.title}</span>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
);
})}
</SidebarMenu>
</SidebarGroup>
</SidebarContent>
<SidebarFooter>
<SidebarMenu>
<SidebarMenuItem>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<SidebarMenuButton
size='lg'
className='data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground'
>
{user && (
<UserAvatarProfile
className='h-8 w-8 rounded-lg'
showInfo
user={{
imageUrl: user.photoURL || undefined,
fullName: user.displayName,
emailAddresses: [{ emailAddress: user.email || '' }]
}}
/>
)}
<IconChevronsDown className='ml-auto size-4' />
</SidebarMenuButton>
</DropdownMenuTrigger>
<DropdownMenuContent
className='w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg'
side='bottom'
align='end'
sideOffset={4}
>
<DropdownMenuLabel className='p-0 font-normal'>
<div className='px-1 py-1.5'>
{user && (
<UserAvatarProfile
className='h-8 w-8 rounded-lg'
showInfo
user={{
imageUrl: user.photoURL || undefined,
fullName: user.displayName,
emailAddresses: [{ emailAddress: user.email || '' }]
}}
/>
)}
</div>
</DropdownMenuLabel>
<DropdownMenuSeparator />
{/* <DropdownMenuGroup>
<DropdownMenuItem
onClick={() => router.push('/dashboard/profile')}
>
<IconUserCircle className='mr-2 h-4 w-4' />
Profile
</DropdownMenuItem>
<DropdownMenuItem>
<IconCreditCard className='mr-2 h-4 w-4' />
Billing
</DropdownMenuItem>
<DropdownMenuItem>
<IconBell className='mr-2 h-4 w-4' />
Notifications
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator /> */}
<DropdownMenuItem
onClick={handleSignOut}
disabled={signOutMutation.isPending}
>
<IconLogout className='mr-2 h-4 w-4' />
{signOutMutation.isPending ? 'Signing out...' : 'Sign out'}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</SidebarMenuItem>
</SidebarMenu>
</SidebarFooter>
<SidebarRail />
</Sidebar>
);
}