"use client"; import React from "react"; import Link from "next/link"; import { usePathname, useRouter } from "next/navigation"; import { FolderOpen, Search as SearchIcon, TriangleAlert, CornerDownLeft, } from "lucide-react"; import { useAuth } from "@/components/auth/authContext"; import { getBranches } from "@/lib/frontend/apiClient"; import { branchPath, searchPath } from "@/lib/frontend/routes"; import { isValidBranchParam } from "@/lib/frontend/params"; import { buildNextUrlForBranchSwitch, readRouteBranchFromPathname, safeReadLocalStorageBranch, safeWriteLocalStorageBranch, } from "@/lib/frontend/quickNav/branchSwitch"; import { getPrimaryNavFromPathname, PRIMARY_NAV, } from "@/lib/frontend/nav/activeRoute"; import { Button } from "@/components/ui/button"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Tooltip, TooltipContent, TooltipTrigger, } from "@/components/ui/tooltip"; const STORAGE_KEY_LAST_BRANCH = "rhl_last_branch"; const BRANCH_LIST_STATE = Object.freeze({ IDLE: "idle", LOADING: "loading", READY: "ready", ERROR: "error", }); const TOPNAV_BUTTON_CLASS = "shadow-none has-[>svg]:px-3"; const ACTIVE_NAV_BUTTON_CLASS = "border-blue-600 bg-blue-50 text-blue-900 hover:bg-blue-50 " + "dark:border-blue-900 dark:bg-blue-950 dark:text-blue-50 dark:hover:bg-blue-950"; export default function QuickNav() { const router = useRouter(); const pathname = usePathname() || "/"; const { status, user, retry } = useAuth(); const isAuthenticated = status === "authenticated" && user; const isAdminDev = isAuthenticated && (user.role === "admin" || user.role === "dev"); const isBranchUser = isAuthenticated && user.role === "branch"; const canRevalidate = typeof retry === "function"; const [selectedBranch, setSelectedBranch] = React.useState(null); const [branchList, setBranchList] = React.useState({ status: BRANCH_LIST_STATE.IDLE, branches: null, }); const activePrimaryNav = React.useMemo(() => { return getPrimaryNavFromPathname(pathname); }, [pathname]); const isExplorerActive = activePrimaryNav?.active === PRIMARY_NAV.EXPLORER; const isSearchActive = activePrimaryNav?.active === PRIMARY_NAV.SEARCH; const routeBranch = React.useMemo(() => { return readRouteBranchFromPathname(pathname); }, [pathname]); const knownBranches = branchList.status === BRANCH_LIST_STATE.READY && Array.isArray(branchList.branches) ? branchList.branches : null; const hasInvalidRouteBranch = Boolean( isAdminDev && routeBranch && knownBranches && !knownBranches.includes(routeBranch), ); React.useEffect(() => { if (!isAuthenticated) return; if (isBranchUser) { const own = user.branchId; setSelectedBranch(own && isValidBranchParam(own) ? own : null); return; } const fromStorage = safeReadLocalStorageBranch(STORAGE_KEY_LAST_BRANCH); if (fromStorage && fromStorage !== selectedBranch) { setSelectedBranch(fromStorage); } }, [isAuthenticated, isBranchUser, user?.branchId, selectedBranch]); React.useEffect(() => { if (!isAdminDev) return; let cancelled = false; setBranchList({ status: BRANCH_LIST_STATE.LOADING, branches: null }); (async () => { try { const res = await getBranches(); if (cancelled) return; const branches = Array.isArray(res?.branches) ? res.branches : []; setBranchList({ status: BRANCH_LIST_STATE.READY, branches }); } catch (err) { if (cancelled) return; console.error("[QuickNav] getBranches failed:", err); setBranchList({ status: BRANCH_LIST_STATE.ERROR, branches: null }); } })(); return () => { cancelled = true; }; }, [isAdminDev, user?.userId]); React.useEffect(() => { if (!isAdminDev) return; if (!knownBranches || knownBranches.length === 0) return; if (!selectedBranch || !knownBranches.includes(selectedBranch)) { const next = knownBranches[0]; setSelectedBranch(next); safeWriteLocalStorageBranch(STORAGE_KEY_LAST_BRANCH, next); } }, [isAdminDev, knownBranches, selectedBranch]); React.useEffect(() => { if (!isAdminDev) return; if (!routeBranch) return; if (!knownBranches) return; const isKnownRouteBranch = knownBranches.includes(routeBranch); if (!isKnownRouteBranch) return; if (routeBranch !== selectedBranch) { setSelectedBranch(routeBranch); safeWriteLocalStorageBranch(STORAGE_KEY_LAST_BRANCH, routeBranch); } }, [isAdminDev, routeBranch, knownBranches, selectedBranch]); React.useEffect(() => { if (!isAdminDev) return; if (!selectedBranch) return; safeWriteLocalStorageBranch(STORAGE_KEY_LAST_BRANCH, selectedBranch); }, [isAdminDev, selectedBranch]); if (!isAuthenticated) return null; const effectiveBranch = isBranchUser ? user.branchId : selectedBranch; const canNavigate = Boolean( effectiveBranch && isValidBranchParam(effectiveBranch), ); function navigateToBranchKeepingContext(nextBranch) { if (!isValidBranchParam(nextBranch)) return; const currentPathname = typeof window !== "undefined" ? window.location.pathname || pathname : pathname; const currentSearch = typeof window !== "undefined" ? window.location.search || "" : ""; const nextUrl = buildNextUrlForBranchSwitch({ pathname: currentPathname, search: currentSearch, nextBranch, }); if (!nextUrl) return; if (canRevalidate) retry(); router.push(nextUrl); } const branchTooltipText = hasInvalidRouteBranch ? `Achtung: ${routeBranch} existiert nicht. Bitte eine gültige Niederlassung wählen.` : "Niederlassung auswählen"; return (