'use client'; import { useState } from 'react'; import { usePathname } from 'next/navigation'; import { useAuth } from '@/contexts/AuthContext'; import { Wordmark, Ticker } from '@/components/vyndr'; import { HeartbeatBar } from '@/components/vyndr/LiveLayer'; import NotificationBell from '@/components/NotificationBell'; // Nav labels are English literals for now; nav-string i18n lands in Phase G // (Session 38) once the locale dictionaries carry slate/terminal/etc. keys. // VYNDR 2.0 nav (§6, Session 34). Primary links are SLATE / SCAN / LEDGER; // everything else lives under a More dropdown. All nav chrome is // JetBrains Mono, uppercase, 11px — system language, not SaaS sans. Active // route is grade-green (--g-a); a Ticker runs under the bar. // Session 57 (Phase 0) — TERMINAL removed: the surface was fabricated sample // data (audit verdict REBUILD). Its layouts live on as §12 content-engine // templates in components/intel/TerminalTemplates.tsx; "The Terminal" survives // as brand language only. Don't re-add the link until it's fed real data. const PRIMARY = [ { id: 'slate', label: 'Slate', href: '/dashboard' }, { id: 'scan', label: 'Scan', href: '/scan' }, { id: 'ledger', label: 'Ledger', href: '/ledger' }, ]; const MORE = [ { label: 'Explore', href: '/explore' }, // Session 60 (4.4) — discoverable Parlay Lab entry (opens the drawer). { label: 'Parlay Lab', href: '#parlay', action: 'parlay' as const }, { label: 'Compare', href: '/compare' }, { label: 'Tracker', href: '/tracker' }, { label: 'The Report', href: '/blog' }, { label: 'Invite', href: '/invite' }, { label: 'Pricing', href: '/pricing' }, { label: 'Settings', href: '/settings' }, ]; // Session 57 (Phase 0) — the hardcoded fallback ticker items (fake Wembanyama // signal, "NYK vs SA Q3", invented Tatum move) are DELETED. The ticker renders // only real /api/ticker snapshot exhaust, and hides itself entirely below 4 // real items (spec §3). Never seed it with fabricated content again. function isActive(pathname: string, href: string) { return pathname === href || pathname.startsWith(href + '/'); } const linkStyle = (active: boolean) => ({ fontFamily: 'var(--mono)', fontSize: 11, fontWeight: 700, letterSpacing: '0.08em', textTransform: 'uppercase' as const, color: active ? 'var(--g-a)' : 'var(--text-1)', textDecoration: 'none', whiteSpace: 'nowrap' as const, transition: 'color .15s', background: 'transparent', border: 'none', cursor: 'pointer', padding: '6px 4px', }); export default function Nav() { const { user, tier, scansRemaining, signOut } = useAuth(); const pathname = usePathname() || ''; const [menuOpen, setMenuOpen] = useState(false); const [moreOpen, setMoreOpen] = useState(false); const [mobileOpen, setMobileOpen] = useState(false); const showReadCounter = pathname.startsWith('/scan') || pathname.startsWith('/dashboard'); const moreActive = MORE.some((l) => isActive(pathname, l.href)); return (
{/* Ticker + heartbeat under the bar (§8 living layer). No fallback items — real snapshot exhaust or nothing. */}
); } const menuItem: React.CSSProperties = { display: 'block', padding: '10px 12px', fontSize: 13, color: 'var(--text-1)', textDecoration: 'none', fontFamily: 'var(--sans)', };