raghub-fe / frontend /src /components /layout /AppRoleSidebar.tsx
lifedebugger's picture
Deploy files from GitHub repository with LFS
6cd3bab
import type { LucideIcon } from "lucide-react";
import { LogOut, UserCircle2 } from "lucide-react";
import { Button } from "@/components/ui/button";
import {
Sidebar,
SidebarContent,
SidebarFooter,
SidebarHeader,
useSidebar,
} from "@/components/ui/sidebar";
import { cn } from "@/lib/utils";
export type RoleSidebarItem<TMenu extends string> = {
id: TMenu;
label: string;
icon: LucideIcon;
};
type AppRoleSidebarProps<TMenu extends string> = {
brandIcon: LucideIcon;
brandTitle: string;
menuItems: RoleSidebarItem<TMenu>[];
activeMenu: TMenu;
onSelectMenu: (menu: TMenu) => void;
userName: string;
userRoleLabel: string;
onLogout: () => void;
};
export function AppRoleSidebar<TMenu extends string>({
brandIcon: BrandIcon,
brandTitle,
menuItems,
activeMenu,
onSelectMenu,
userName,
userRoleLabel,
onLogout,
}: AppRoleSidebarProps<TMenu>) {
const { isMobile, setOpenMobile } = useSidebar();
return (
<Sidebar
collapsible="offcanvas"
className="bg-sidebar text-sidebar-foreground"
>
<SidebarHeader
className="h-20 border-b border-sidebar-border px-5"
>
<div className="flex items-center gap-3">
<div className="flex size-8 items-center justify-center rounded-full bg-primary">
<BrandIcon className="size-4 text-primary-foreground" />
</div>
<p className="text-xl font-semibold leading-none md:text-2xl">
{brandTitle}
</p>
</div>
</SidebarHeader>
<SidebarContent className="p-4">
<div className="space-y-2">
{menuItems.map((item) => {
const isActive = activeMenu === item.id;
return (
<Button
key={item.id}
type="button"
variant={isActive ? "default" : "ghost"}
onClick={() => {
onSelectMenu(item.id);
if (isMobile) setOpenMobile(false);
}}
className={cn(
"h-10 w-full justify-start gap-2 px-3 text-left text-sm font-medium",
isActive
? "bg-sidebar-primary text-sidebar-primary-foreground hover:bg-sidebar-primary/90"
: "text-sidebar-foreground/90 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
)}
>
<item.icon className="size-4" />
<span>{item.label}</span>
</Button>
);
})}
</div>
</SidebarContent>
<SidebarFooter className="border-t border-sidebar-border p-4">
<div className="mb-4 flex items-center gap-2 rounded-lg bg-sidebar-accent px-3 py-2">
<UserCircle2 className="size-5 text-sidebar-foreground/90" />
<div className="min-w-0">
<p className="line-clamp-1 text-sm font-semibold text-sidebar-foreground">
{userName}
</p>
<p className="text-xs text-sidebar-foreground/80">
{userRoleLabel}
</p>
</div>
</div>
<Button
type="button"
variant="ghost"
onClick={onLogout}
className="h-auto justify-start px-0 text-sm font-semibold text-destructive hover:bg-transparent hover:text-destructive/80"
>
<LogOut className="size-4" />
<span>Logout</span>
</Button>
</SidebarFooter>
</Sidebar>
);
}