import { type ReactNode } from "react"; import { NavLink, useLocation } from "react-router-dom"; import { useAuth } from "../context/AuthContext"; import { useTheme } from "../../context/ThemeContext"; interface MenuItem { path: string; label: string; end?: boolean; permission?: string | string[]; matchPrefix?: string; matchAlso?: string[]; matchExclude?: string[]; icon: ReactNode; } interface MenuSection { label: string; items: MenuItem[]; } const menuSections: MenuSection[] = [ { label: "Přehled", items: [ { path: "/", label: "Přehled", end: true, icon: ( ), }, ], }, { label: "Docházka", items: [ { path: "/attendance", label: "Záznam", permission: "attendance.record", end: true, icon: ( ), }, { path: "/attendance/history", label: "Moje historie", permission: "attendance.history", icon: ( ), }, { path: "/attendance/requests", label: "Žádosti", permission: "attendance.record", icon: ( ), }, { path: "/attendance/approval", label: "Schvalování", permission: "attendance.approve", icon: ( ), }, { path: "/attendance/admin", label: "Správa", permission: "attendance.admin", matchPrefix: "/attendance/admin", matchAlso: ["/attendance/create", "/attendance/location"], icon: ( ), }, { path: "/attendance/balances", label: "Správa bilancí", permission: "attendance.balances", icon: ( ), }, ], }, { label: "Kniha jízd", items: [ { path: "/trips", label: "Záznam", permission: "trips.record", end: true, icon: ( ), }, { path: "/trips/history", label: "Moje historie", permission: "trips.history", icon: ( ), }, { path: "/trips/admin", label: "Správa", permission: "trips.admin", icon: ( ), }, { path: "/vehicles", label: "Vozidla", permission: "trips.vehicles", icon: ( ), }, ], }, { label: "Administrativa", items: [ { path: "/offers", label: "Nabídky", permission: "offers.view", matchPrefix: "/offers", matchExclude: ["/offers/customers", "/offers/templates"], icon: ( ), }, { path: "/orders", label: "Objednávky", permission: "orders.view", matchPrefix: "/orders", icon: ( ), }, { path: "/invoices", label: "Faktury", permission: "invoices.view", matchPrefix: "/invoices", icon: ( ), }, { path: "/projects", label: "Projekty", permission: "projects.view", matchPrefix: "/projects", icon: ( ), }, { path: "/offers/customers", label: "Zákazníci", permission: "offers.view", icon: ( ), }, ], }, { label: "Systém", items: [ { path: "/users", label: "Uživatelé", permission: "users.view", icon: ( ), }, { path: "/settings", label: "Nastavení", permission: "settings.manage", icon: ( ), }, { path: "/audit-log", label: "Audit log", permission: "settings.audit", icon: ( ), }, ], }, ]; interface SidebarProps { isOpen: boolean; onClose: () => void; onLogout: () => void; } export default function Sidebar({ isOpen, onClose, onLogout }: SidebarProps) { const { user, hasPermission } = useAuth(); const { theme } = useTheme(); const location = useLocation(); const isItemActive = (item: MenuItem) => { if (item.matchPrefix) { let active = location.pathname.startsWith(item.matchPrefix); if (active && item.matchExclude) { active = !item.matchExclude.some((ex) => location.pathname.startsWith(ex), ); } return active; } if (item.end) { return location.pathname === item.path; } return location.pathname.startsWith(item.path); }; const hasItemPermission = (item: MenuItem) => { if (!item.permission) { return true; } if (Array.isArray(item.permission)) { return item.permission.some((p) => hasPermission(p)); } return hasPermission(item.permission); }; const visibleSections = menuSections .map((section) => ({ ...section, items: section.items.filter(hasItemPermission), })) .filter((section) => section.items.length > 0); return ( <>
> ); }