"use client"; import { Fragment, type ReactNode } from "react"; import Link from "next/link"; import { usePathname } from "next/navigation"; import { ChevronDown, Settings } from "lucide-react"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { GlobalSearch } from "@/components/global-search"; import { headerSubtitle } from "@/components/header-context"; import { useMissingPrecedentsOpenCount } from "@/lib/api/missing-precedents"; import { usePendingApprovals } from "@/lib/api/chair"; /** * Ezer Mishpati navigation shell — two-row header. * * Row 1 (brand): logo + dynamic context subtitle · global search · agent boards * Row 2 (nav): work links · knowledge dropdowns (פסיקה/סגנון) · admin dropdown * * Editorial/judicial aesthetic preserved: * - Navy background with a gold hairline rule (border-b-3) * - Parchment text, gold accents on hover/active * - Hebrew RTL throughout (set on in layout.tsx) * - Active item gets `aria-current="page"` and a gold underline anchored * to the bottom border, so screen readers announce the section and * sighted users see where they are. */ // `groupLabel`, when present, renders a separator + sub-heading inside a // dropdown *before* this item — used to set off secondary tools. type NavItem = { href: string; label: string; groupLabel?: string }; type NavMenuDef = { id: string; label: string; items: NavItem[] }; // Work cluster — direct links, the daily hubs. const WORK_LINKS: NavItem[] = [ { href: "/", label: "בית" }, { href: "/approvals", label: "מרכז אישורים" }, { href: "/feedback", label: "הערות יו״ר" }, { href: "/archive", label: "ארכיון" }, ]; // Knowledge cluster — grouped under dropdowns so the bar stays scannable. // All routes are preserved; only their placement in the nav changes. const KNOWLEDGE_MENUS: NavMenuDef[] = [ { id: "precedents", label: "פסיקה", items: [ { href: "/precedents", label: "ספריית פסיקה" }, { href: "/digests", label: "יומונים" }, { href: "/missing-precedents", label: "פסיקה חסרה" }, { href: "/graph", label: "מפת הקורפוס", groupLabel: "ניתוח וכיול" }, { href: "/goldset", label: "מדגם-זהב" }, ], }, { id: "style", label: "סגנון", items: [ { href: "/training", label: "אימון סגנון" }, { href: "/methodology", label: "מתודולוגיה" }, ], }, ]; const ADMIN_ITEMS: NavItem[] = [ { href: "/skills", label: "מיומנויות" }, { href: "/diagnostics", label: "אבחון" }, { href: "/settings", label: "הגדרות" }, ]; type AgentBoard = { prefix: string; label: string; hint: string }; const AGENT_BOARDS: AgentBoard[] = [ { prefix: "CMP", label: "רישוי ובניה", hint: "תיקי 1xxx" }, { prefix: "CMPA", label: "היטלי השבחה", hint: "תיקי 8xxx / 9xxx" }, ]; const PAPERCLIP_BASE = "https://pc.nautilus.marcusgroup.org"; function isActive(pathname: string, href: string): boolean { if (href === "/") return pathname === "/"; return pathname === href || pathname.startsWith(`${href}/`); } export function AppShell({ children }: { children: ReactNode }) { const pathname = usePathname(); const subtitle = headerSubtitle(pathname); const adminActive = ADMIN_ITEMS.some((i) => isActive(pathname, i.href)); return ( <>
{/* ─── Row 1 — brand bar (3-column grid) ─── */} {/* Side columns flex 1fr each so the search column stays centered on the viewport regardless of how wide the brand or agent labels grow. */}
עוזר משפטי {subtitle}
ניהול סוכנים Paperclip פתח דאשבורד {AGENT_BOARDS.map((board) => ( {board.label} {board.prefix} · {board.hint} ))}
{/* ─── Row 2 — section nav ─── */}
מערכת {ADMIN_ITEMS.map((item) => { const active = isActive(pathname, item.href); return ( {item.label} ); })}
{children}
); } function NavLink({ item, active }: { item: NavItem; active: boolean }) { return ( {item.label} {item.href === "/approvals" ? : null} {active && (