Files
dragonsstash/src/components/layout/sidebar.tsx

121 lines
3.1 KiB
TypeScript

"use client";
import { useState } from "react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { useSession } from "next-auth/react";
import {
LayoutDashboard,
Cylinder,
Droplets,
Paintbrush,
Gem,
FileBox,
Send,
ClipboardList,
Building2,
MapPin,
Settings,
Flame,
PanelLeftClose,
PanelLeft,
} from "lucide-react";
import { cn } from "@/lib/utils";
import { APP_NAME, NAV_ITEMS } from "@/lib/constants";
import { Button } from "@/components/ui/button";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
const icons = {
LayoutDashboard,
Cylinder,
Droplets,
Paintbrush,
Gem,
FileBox,
Send,
ClipboardList,
Building2,
MapPin,
Settings,
} as const;
export function Sidebar() {
const pathname = usePathname();
const [collapsed, setCollapsed] = useState(false);
const { data: session } = useSession();
const isAdmin = session?.user?.role === "ADMIN";
const visibleItems = NAV_ITEMS.filter((item) => !item.adminOnly || isAdmin);
return (
<aside
className={cn(
"flex h-screen flex-col border-r border-border bg-card transition-all duration-200",
collapsed ? "w-16" : "w-60"
)}
>
{/* Logo */}
<div className="flex h-14 items-center gap-2 border-b border-border px-4">
<Flame className="h-6 w-6 shrink-0 text-primary" />
{!collapsed && (
<span className="text-sm font-bold tracking-tight">{APP_NAME}</span>
)}
</div>
{/* Navigation */}
<nav className="flex-1 space-y-1 p-2">
{visibleItems.map((item) => {
const Icon = icons[item.icon];
const isActive = pathname.startsWith(item.href);
const link = (
<Link
key={item.href}
href={item.href}
className={cn(
"flex items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition-colors",
isActive
? "border-l-2 border-primary bg-primary/10 text-primary"
: "text-muted-foreground hover:bg-muted hover:text-foreground"
)}
>
<Icon className="h-4 w-4 shrink-0" />
{!collapsed && <span>{item.label}</span>}
</Link>
);
if (collapsed) {
return (
<Tooltip key={item.href}>
<TooltipTrigger asChild>{link}</TooltipTrigger>
<TooltipContent side="right">{item.label}</TooltipContent>
</Tooltip>
);
}
return link;
})}
</nav>
{/* Collapse toggle */}
<div className="border-t border-border p-2">
<Button
variant="ghost"
size="sm"
className="w-full justify-center"
onClick={() => setCollapsed(!collapsed)}
>
{collapsed ? (
<PanelLeft className="h-4 w-4" />
) : (
<>
<PanelLeftClose className="h-4 w-4 mr-2" />
<span className="text-xs">Collapse</span>
</>
)}
</Button>
</div>
</aside>
);
}