"use client"; import { useCallback, useEffect } from "react"; import { usePathname, useRouter } from "next/navigation"; type NavItem = { id: string; label: string; href?: string }; const NAV_ITEMS: NavItem[] = [ { id: "overview", label: "Academy" }, { id: "ebook", label: "Book" }, { id: "translate", label: "Translate", href: "/translate" }, { id: "projects", label: "Projects" }, { id: "sermon", label: "Sermon" }, ]; /** Overview — mission control hub */ function IconGrid() { return ( ); } /** Ebook — audio to ebook production */ function IconEbook() { return ( ); } /** Projects — saved workspace archive */ function IconProjects() { return ( ); } /** Translate — standalone translation pipeline */ function IconTranslate() { return ( ); } /** Sermon — live sermon restructuring assistant */ function IconSermon() { return ( ); } const NAV_ICONS: Record React.JSX.Element> = { overview: IconGrid, ebook: IconEbook, translate: IconTranslate, projects: IconProjects, sermon: IconSermon, }; type NexusNavProps = { active: string; onSelect: (id: string) => void; }; function IconLogout() { return ( ); } export function NexusNav({ active, onSelect }: NexusNavProps) { const pathname = usePathname(); const router = useRouter(); const navigateTo = useCallback((href: string) => { // Skip redundant pushes to avoid unnecessary route remounts. if (href === "/translate" && pathname.startsWith("/translate")) return; if (href.startsWith("/ebook") && pathname.startsWith("/ebook")) return; if (href === "/" && pathname === "/") return; router.push(href); }, [pathname, router]); useEffect(() => { router.prefetch("/"); router.prefetch("/ebook?tab=pipeline"); router.prefetch("/translate"); }, [router]); const handleLogout = useCallback(async () => { await fetch("/api/auth/logout", { method: "POST" }); router.push("/login"); }, [router]); const LogoMark = () => ( ); return ( <> {/* ── Desktop sidebar (lg+) ─────────────────────────────── */} {NAV_ITEMS.map((item) => { const Icon = NAV_ICONS[item.id] ?? IconGrid; const isAcademyGroup = item.id === "overview"; const isActive = item.href ? pathname.startsWith(item.href) : isAcademyGroup ? active !== "ebook" && active !== "sermon" && active !== "projects" && active !== "translate" : active === item.id; const btnClass = [ "focus-ring relative flex min-h-12 w-12 items-center justify-center rounded-xl transition-all duration-150", isActive ? "bg-gradient-to-br from-cyan-500/25 to-violet-500/15 text-cyan-300 ring-1 ring-cyan-400/40" : "text-slate-500 hover:bg-slate-700/40 hover:text-slate-200 active:bg-slate-700/60" ].join(" "); const indicator = isActive ? ( ) : null; if (item.href) { return ( navigateTo(item.href)} aria-label={item.label} aria-current={isActive ? "page" : undefined} className={btnClass} style={isActive ? { boxShadow: "0 0 12px rgba(6,182,212,0.20)" } : undefined} > {indicator} ); } return ( onSelect(item.id)} aria-label={item.label} aria-current={isActive ? "page" : undefined} className={btnClass} style={isActive ? { boxShadow: "0 0 12px rgba(6,182,212,0.20)" } : undefined} > {indicator} ); })} {/* ── Mobile bottom bar ( {/* Logo tap — goes to overview */} { e.preventDefault(); onSelect("overview"); }} onClick={() => onSelect("overview")} aria-label="Overview" className="flex min-h-[52px] min-w-[48px] touch-manipulation flex-col items-center justify-center gap-0.5 px-1 pt-2 active:bg-slate-800/40" style={{ touchAction: "manipulation" }} > {/* Logout — far right of mobile bar */} { e.preventDefault(); void handleLogout(); }} aria-label="Log out" className="relative flex min-h-[52px] min-w-[48px] touch-manipulation flex-col items-center justify-center gap-0.5 px-1 pt-2 text-slate-600 hover:text-rose-400 active:bg-slate-800/40" style={{ touchAction: "manipulation" }} > Logout {NAV_ITEMS.map((item) => { const Icon = NAV_ICONS[item.id] ?? IconGrid; const isAcademyGroup = item.id === "overview"; const isActive = item.href ? pathname.startsWith(item.href) : isAcademyGroup ? active !== "ebook" && active !== "sermon" && active !== "projects" && active !== "translate" : active === item.id; const inner = ( <> {item.label} > ); return ( { if (e.pointerType === "touch") { e.preventDefault(); if (item.href) navigateTo(item.href); else onSelect(item.id); } }} onClick={() => { if (item.href) navigateTo(item.href); else onSelect(item.id); }} aria-label={item.label} aria-current={isActive ? "page" : undefined} className="relative flex min-h-[52px] min-w-[48px] touch-manipulation flex-col items-center justify-center gap-0.5 px-1 pt-2 active:bg-slate-800/40" style={{ touchAction: "manipulation" }} > {inner} ); })} > ); }