// frontend\src\components\Sidebar.tsx import { Dialog, DialogBackdrop, DialogPanel, TransitionChild, } from '@headlessui/react' import { CalendarIcon, ChartPieIcon, ChatBubbleLeftRightIcon, Cog6ToothIcon, ComputerDesktopIcon, CpuChipIcon, DocumentDuplicateIcon, ServerStackIcon, ShieldCheckIcon, VideoCameraIcon, HomeIcon, XMarkIcon, } from '@heroicons/react/24/outline' import type { ComponentType, SVGProps } from 'react' import { NavLink, useLocation } from 'react-router' import { hasRight } from './permissions' import type { User, Team } from './types' type NavigationItem = { name: string href: string icon: ComponentType> right?: string children?: NavigationItem[] } type NavigationSection = { name?: string items: NavigationItem[] } const navigationSections: NavigationSection[] = [ { items: [ { name: 'Dashboard', href: '/', icon: HomeIcon, }, ], }, { name: 'Betrieb', items: [ { name: 'Geräte', href: '/geraete', icon: ComputerDesktopIcon, right: 'devices:read', }, { name: 'Einsätze', href: '/einsaetze', icon: VideoCameraIcon, right: 'operations:read', children: [ { name: 'Milestone-Speicher', href: '/einsaetze/milestone-speicher', icon: ServerStackIcon, right: 'administration:read', }, { name: 'Milestone-Geräte', href: '/einsaetze/milestone-devices', icon: CpuChipIcon, right: 'administration:read', }, ], }, ], }, { name: 'Organisation', items: [ { name: 'Kalender', href: '/kalender', icon: CalendarIcon, right: 'calendar:read', }, { name: 'Dokumente', href: '/dokumente', icon: DocumentDuplicateIcon, right: 'documents:read', }, { name: 'Berichte', href: '/berichte', icon: ChartPieIcon, right: 'reports:read', }, ], }, ] type SidebarProps = { user: User sidebarOpen: boolean setSidebarOpen: (open: boolean) => void onNavigate?: () => void } function classNames(...classes: Array) { return classes.filter(Boolean).join(' ') } function getTeamInitial(team: Team) { if (team.initial) { return team.initial } return team.name.charAt(0).toUpperCase() } function isPathActive(pathname: string, href: string) { if (href === '/') { return pathname === '/' } return pathname === href || pathname.startsWith(`${href}/`) } function itemIsActive(item: NavigationItem, pathname: string): boolean { return ( isPathActive(pathname, item.href) || (item.children ?? []).some((child) => itemIsActive(child, pathname)) ) } function filterNavigationItems( items: NavigationItem[], user: User, ): NavigationItem[] { return items .map((item) => ({ ...item, children: item.children ? filterNavigationItems(item.children, user) : undefined, })) .filter((item) => { const canSeeItem = !item.right || hasRight(user, item.right) const hasVisibleChildren = Boolean(item.children?.length) return canSeeItem || hasVisibleChildren }) } function getVisibleNavigationSections(user: User) { return navigationSections .map((section) => ({ ...section, items: filterNavigationItems(section.items, user), })) .filter((section) => section.items.length > 0) } function SidebarContent({ user, setSidebarOpen, onNavigate, }: { user: User setSidebarOpen: (open: boolean) => void onNavigate?: () => void }) { const teams = user.teams ?? [] const location = useLocation() const visibleNavigationSections = getVisibleNavigationSections(user) const isAdministrationActive = location.pathname === '/administration' || location.pathname.startsWith('/administration/') const isSettingsActive = location.pathname === '/einstellungen' || location.pathname.startsWith('/einstellungen/') const isFeedbackActive = location.pathname === '/feedback' function handleNavigate() { onNavigate?.() setSidebarOpen(false) } function renderNavigationItem(item: NavigationItem) { const active = itemIsActive(item, location.pathname) const children = item.children ?? [] const showChildren = children.length > 0 return (
  • {showChildren && (
      {children.map((child) => { const childActive = itemIsActive(child, location.pathname) return (
    • ) })}
    )}
  • ) } return ( <>
    Your Company

    TEG

    SE Düsseldorf

    ) } export default function Sidebar({ user, sidebarOpen, setSidebarOpen, onNavigate, }: SidebarProps) { return ( <>
    ) }