import { LayoutDashboard, Boxes, Network, Cog, ListChecks, Activity, Settings, BookText, KeyRound, ServerCog, } from 'lucide-react' import { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInset, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarProvider, SidebarTrigger, } from '@evobgp/ui/components/sidebar' import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, } from '@evobgp/ui/components/breadcrumb' import { Separator } from '@evobgp/ui/components/separator' import { Link, useRouterState } from '@tanstack/react-router' import type { ComponentType, ReactNode } from 'react' import { ModeToggle } from '@/components/mode-toggle' interface NavItem { to: string label: string icon: ComponentType<{ className?: string }> } interface NavGroup { label: string items: NavItem[] } const NAV_GROUPS: NavGroup[] = [ { label: 'Обзор', items: [{ to: '/dashboard', label: 'Dashboard', icon: LayoutDashboard }], }, { label: 'Маршрутизация', items: [ { to: '/modules', label: 'Модули', icon: Boxes }, { to: '/network', label: 'Сеть', icon: Network }, { to: '/directories', label: 'Справочники', icon: BookText }, ], }, { label: 'Операции', items: [ { to: '/operations', label: 'Операции', icon: Cog }, { to: '/schedule', label: 'Задачи', icon: ListChecks }, { to: '/monitoring', label: 'Мониторинг', icon: Activity }, ], }, { label: 'Система', items: [ { to: '/access', label: 'Доступ', icon: KeyRound }, { to: '/tenant-settings', label: 'Настройки BIRD', icon: ServerCog }, { to: '/settings', label: 'Настройки UI', icon: Settings }, ], }, ] const ALL_NAV_ITEMS = NAV_GROUPS.flatMap((g) => g.items) const ROUTE_LABELS: Record = Object.fromEntries( ALL_NAV_ITEMS.map((i) => [i.to, i.label]), ) const PARENT_ROUTE: Record = {} export function AppShell({ children }: { children: ReactNode }) { const pathname = useRouterState({ select: (s) => s.location.pathname }) const activeItem = ALL_NAV_ITEMS.find((i) => pathname === i.to || (i.to !== '/' && pathname.startsWith(`${i.to}/`))) ?? ALL_NAV_ITEMS[0] const parentTo = PARENT_ROUTE[activeItem.to] const parentLabel = parentTo ? ROUTE_LABELS[parentTo] : null return (
B
EvoBGP Control Plane
{NAV_GROUPS.map((group) => ( {group.label} {group.items.map((item) => { const Icon = item.icon const isActive = pathname === item.to || pathname.startsWith(`${item.to}/`) return ( } isActive={isActive} tooltip={item.label} > {item.label} ) })} ))}
{parentLabel && parentTo ? ( <> }>{parentLabel} ) : null} {ROUTE_LABELS[activeItem.to] ?? activeItem.label}
{children}
) }