import { useEffect, useState } from "react"; import { NavLink } from "react-router-dom"; import { useTranslation } from "react-i18next"; import { BookMarked, Boxes, PanelLeft, PanelLeftClose, Search, Tags, Users, } from "lucide-react"; import type { LucideIcon } from "lucide-react"; import { cn } from "@/lib/utils"; import { Tooltip } from "@/components/ui/tooltip"; import { useMediaQuery } from "@/lib/use-media-query"; import { useConfig } from "../config/config-context"; const STORAGE_KEY = "sidebar-collapsed"; type NavItem = { to: string; /** i18n key under `nav.*`. */ label: string; Icon: LucideIcon; }; const NAV_ITEMS: readonly NavItem[] = [ { to: "/objects", label: "nav.objects", Icon: Boxes }, { to: "/vocabularies", label: "nav.vocabularies", Icon: BookMarked }, { to: "/authorities", label: "nav.authorities", Icon: Users }, { to: "/search", label: "nav.search", Icon: Search }, { to: "/fields", label: "nav.fields", Icon: Tags }, ]; function readStored(): boolean { if (typeof window === "undefined") return false; return window.localStorage.getItem(STORAGE_KEY) === "true"; } function navLinkClass(collapsed: boolean) { return ({ isActive }: { isActive: boolean }) => cn( "flex items-center gap-2 rounded-md px-2 py-1 outline-none", "focus-visible:ring-3 focus-visible:ring-ring/50", collapsed && "justify-center", isActive && "bg-accent font-medium", ); } export function Sidebar() { const { t } = useTranslation(); const { app_name } = useConfig(); const narrow = useMediaQuery("(max-width: 768px)"); const [stored, setStored] = useState(readStored); // On narrow viewports the rail is always collapsed regardless of the stored // preference; the toggle only takes effect when wide. const collapsed = narrow || stored; useEffect(() => { if (typeof window !== "undefined") { window.localStorage.setItem(STORAGE_KEY, String(stored)); } }, [stored]); const toggle = () => setStored((prev) => !prev); return ( ); }