2026-01-08 19:10:40 +02:00
|
|
|
"use client";
|
|
|
|
|
|
2026-03-07 02:34:23 +05:30
|
|
|
import { Spinner } from "@/components/ui/spinner";
|
2026-01-08 19:10:40 +02:00
|
|
|
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
|
|
|
|
|
import { cn } from "@/lib/utils";
|
|
|
|
|
import type { NavItem } from "../../types/layout.types";
|
|
|
|
|
|
|
|
|
|
interface NavSectionProps {
|
|
|
|
|
items: NavItem[];
|
|
|
|
|
onItemClick?: (item: NavItem) => void;
|
|
|
|
|
isCollapsed?: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function NavSection({ items, onItemClick, isCollapsed = false }: NavSectionProps) {
|
|
|
|
|
return (
|
|
|
|
|
<div className={cn("flex flex-col gap-0.5 py-2", isCollapsed && "items-center")}>
|
|
|
|
|
{items.map((item) => {
|
|
|
|
|
const Icon = item.icon;
|
|
|
|
|
|
|
|
|
|
// Add data-joyride for onboarding tour
|
|
|
|
|
const joyrideAttr =
|
|
|
|
|
item.title === "Documents" || item.title.toLowerCase().includes("documents")
|
|
|
|
|
? { "data-joyride": "documents-sidebar" }
|
2026-01-24 19:53:56 +05:30
|
|
|
: item.title === "Inbox" || item.title.toLowerCase().includes("inbox")
|
|
|
|
|
? { "data-joyride": "inbox-sidebar" }
|
|
|
|
|
: {};
|
2026-01-08 19:10:40 +02:00
|
|
|
|
|
|
|
|
if (isCollapsed) {
|
|
|
|
|
return (
|
|
|
|
|
<Tooltip key={item.url}>
|
|
|
|
|
<TooltipTrigger asChild>
|
|
|
|
|
<button
|
|
|
|
|
type="button"
|
|
|
|
|
onClick={() => onItemClick?.(item)}
|
|
|
|
|
className={cn(
|
2026-01-21 19:43:20 +05:30
|
|
|
"relative flex h-10 w-10 items-center justify-center rounded-md transition-colors",
|
2026-01-08 19:10:40 +02:00
|
|
|
"hover:bg-accent hover:text-accent-foreground",
|
2026-01-24 20:05:42 +05:30
|
|
|
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
2026-01-08 19:10:40 +02:00
|
|
|
)}
|
|
|
|
|
{...joyrideAttr}
|
|
|
|
|
>
|
|
|
|
|
<Icon className="h-4 w-4" />
|
2026-03-07 02:34:23 +05:30
|
|
|
{item.showSpinner ? (
|
|
|
|
|
<span className="absolute top-0.5 right-0.5 inline-flex items-center justify-center h-[14px] w-[14px] rounded-full bg-primary/15">
|
|
|
|
|
<Spinner size="xs" className="text-primary" />
|
|
|
|
|
</span>
|
|
|
|
|
) : item.badge ? (
|
2026-01-24 01:20:51 +05:30
|
|
|
<span className="absolute top-0.5 right-0.5 inline-flex items-center justify-center min-w-[14px] h-[14px] px-0.5 rounded-full bg-red-500 text-white text-[9px] font-medium">
|
2026-01-21 19:43:20 +05:30
|
|
|
{item.badge}
|
|
|
|
|
</span>
|
2026-03-07 02:34:23 +05:30
|
|
|
) : null}
|
2026-01-08 19:10:40 +02:00
|
|
|
<span className="sr-only">{item.title}</span>
|
|
|
|
|
</button>
|
|
|
|
|
</TooltipTrigger>
|
|
|
|
|
<TooltipContent side="right">
|
|
|
|
|
{item.title}
|
|
|
|
|
{item.badge && ` (${item.badge})`}
|
|
|
|
|
</TooltipContent>
|
|
|
|
|
</Tooltip>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<button
|
|
|
|
|
key={item.url}
|
|
|
|
|
type="button"
|
|
|
|
|
onClick={() => onItemClick?.(item)}
|
|
|
|
|
className={cn(
|
|
|
|
|
"flex items-center gap-2 rounded-md mx-2 px-2 py-1.5 text-sm transition-colors text-left",
|
|
|
|
|
"hover:bg-accent hover:text-accent-foreground",
|
2026-01-24 20:05:42 +05:30
|
|
|
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
2026-01-08 19:10:40 +02:00
|
|
|
)}
|
|
|
|
|
{...joyrideAttr}
|
|
|
|
|
>
|
2026-03-07 02:34:23 +05:30
|
|
|
{item.showSpinner ? (
|
|
|
|
|
<Spinner size="sm" className="shrink-0 text-primary" />
|
|
|
|
|
) : (
|
|
|
|
|
<Icon className="h-4 w-4 shrink-0" />
|
|
|
|
|
)}
|
2026-01-08 19:10:40 +02:00
|
|
|
<span className="flex-1 truncate">{item.title}</span>
|
2026-01-21 19:43:20 +05:30
|
|
|
{item.badge && (
|
2026-01-24 01:20:51 +05:30
|
|
|
<span className="inline-flex items-center justify-center min-w-4 h-4 px-1 rounded-full bg-red-500 text-white text-[10px] font-medium">
|
2026-01-21 19:43:20 +05:30
|
|
|
{item.badge}
|
|
|
|
|
</span>
|
|
|
|
|
)}
|
2026-01-08 19:10:40 +02:00
|
|
|
</button>
|
|
|
|
|
);
|
|
|
|
|
})}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|