'use client'; import { useCallback, useEffect, useMemo, useState } from 'react'; import Link from 'next/link'; import { usePathname } from 'next/navigation'; import type { MenuNode } from '@/lib/api/types/menu'; import { NavTooltip } from '@/components/layout/nav-tooltip'; import { NavIconOrLabel, NavStateGuard, NavTreeItem, normalizeHref, layoutNavRootsFromApi, subtreeContainsActivePath, visibleChildren, } from '@/components/layout/nav-shared'; import { useMenuNavigation } from '@/lib/hooks/use-menu-navigation'; export function IconSidebarLayout({ items, loading, error, authed, onCloseMobile, }: { items: MenuNode[]; loading: boolean; error: string | null; authed: boolean; onMenuNavigate?: (path: string, title: string) => void; onCloseMobile?: () => void; }) { const pathname = usePathname() ?? '/'; const roots = useMemo(() => layoutNavRootsFromApi(items), [items]); const onMenuNavigate = useMenuNavigation(); const findFlyoutRootForPath = useCallback( (path: string): MenuNode | null => { for (const r of roots) { const kids = visibleChildren(r); if (kids.length === 0) continue; if (subtreeContainsActivePath(r, path)) return r; } return null; }, [roots], ); const [flyoutRoot, setFlyoutRoot] = useState(null); useEffect(() => { const next = findFlyoutRootForPath(pathname); setFlyoutRoot((prev) => { if (next) return next; if (prev && subtreeContainsActivePath(prev, pathname)) return prev; return null; }); }, [pathname, findFlyoutRootForPath]); useEffect(() => { const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') setFlyoutRoot(null); }; window.addEventListener('keydown', onKey); return () => window.removeEventListener('keydown', onKey); }, []); const toggleFlyout = (root: MenuNode) => { setFlyoutRoot((r) => (r?.id === root.id ? null : root)); }; const railShell = (inner: React.ReactNode) => (
{inner}
); if (!authed || loading || error) { return railShell( , ); } return (
{flyoutRoot && visibleChildren(flyoutRoot).length > 0 ? (
{flyoutRoot.menu_name}
{visibleChildren(flyoutRoot).map((c) => ( ))}
) : null}
); }