Files
nextjs-elysia-allaos/src/components/layout/app-sidebar.tsx
phaichayon a330abf9b6 commit
2026-04-23 15:37:01 +07:00

218 lines
7.3 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, tenantNavConfig } from "@/constants/data";
import { useMediaQuery } from "@/hooks/use-media-query";
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 { useAuth } from "@/providers/AuthProvider";
export const company = {
name: "ALLA",
logo: IconPhotoUp,
plan: "Enterprise",
};
const tenants = [
{ id: "1", name: "ALLA" },
{ id: "2", name: "ONVALLA" },
];
export default function AppSidebar() {
const pathname = usePathname();
const { isOpen } = useMediaQuery();
const router = useRouter();
const [activeTenant, setActiveTenant] = React.useState(tenants[0]);
const { isAuthenticated, userInfo, logout } = useAuth();
const handleSwitchTenant = (tenantId: string) => {
const newTenant = tenants.find((t) => t.id === tenantId);
if (newTenant) {
setActiveTenant(newTenant);
// Optional: Redirect to the tenant's dashboard after switching
// router.push(tenantNavConfig[tenantId][0]?.url || "/");
}
};
// Get navItems based on active tenant
const currentNavItems = tenantNavConfig[activeTenant.id] || navItems;
return (
<Sidebar collapsible="icon">
<SidebarHeader>
<OrgSwitcher
tenants={tenants}
defaultTenant={activeTenant}
onTenantSwitch={handleSwitchTenant}
/>
</SidebarHeader>
<SidebarContent className="overflow-x-hidden">
<SidebarGroup>
<SidebarGroupLabel>Overview</SidebarGroupLabel>
<SidebarMenu>
{currentNavItems.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"
>
{userInfo && (
<div className="flex items-center gap-2">
<IconUserCircle className="h-8 w-8" />
<div className="flex flex-col text-center">
<span className="text-sm ">
{userInfo?.name ||
userInfo?.preferred_username ||
"User"}
</span>
</div>
</div>
)}
<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="flex items-center gap-3 px-1 py-1.5 text-left text-sm">
{userInfo && (
<>
<IconUserCircle className="h-8 w-8 rounded-lg bg-muted" />
<div className="grid flex-1 text-left text-sm leading-tight">
<span className="truncate font-semibold">
{userInfo?.name ||
userInfo?.preferred_username ||
"User"}
</span>
</div>
</>
)}
</div>
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
<IconBell className="mr-2 h-4 w-4" />
Notifications
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={() => logout()}>
<IconLogout className="mr-2 h-4 w-4" />
Logout
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</SidebarMenuItem>
</SidebarMenu>
</SidebarFooter>
<SidebarRail />
</Sidebar>
);
}