dashboard-mobile-nav.tsx76 lines · main
1'use client';
2
3import Link from 'next/link';
4import { usePathname } from 'next/navigation';
5
6/**
7 * Mobile-only horizontal nav strip. Mirrors the four (or five) sidebar
8 * links — projects / teams / billing / settings (+ admin). Renders
9 * below the dashboard header and is hidden md+ where the sidebar
10 * takes over. Lives as a separate component so the icon-bearing
11 * sidebar doesn't need to grow a responsive branch.
12 */
13const AUTH_ACCENT = '#FFFD74';
14
15const NAV = [
16 { href: '/dashboard', label: 'overview' },
17 { href: '/dashboard/projects', label: 'projects' },
18 { href: '/dashboard/auth', label: 'Auth', auth: true },
19 { href: '/dashboard/s3', label: 'S3 bucket' },
20 { href: '/dashboard/teams', label: 'teams' },
21 { href: '/dashboard/billing', label: 'billing' },
22 { href: '/dashboard/settings', label: 'settings' },
23] as const;
24
25// No 'admin' item here: the single admin entry is the avatar-dropdown row
26// pointing at admin.briven.tech (the only admin address).
27export function DashboardMobileNav() {
28 const pathname = usePathname();
29 const items = NAV;
30 return (
31 <nav
32 aria-label="dashboard sections"
33 className="flex gap-1 overflow-x-auto border-b border-[var(--color-border-subtle)] px-4 py-2 md:hidden [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden"
34 >
35 {items.map((item) => {
36 // overview matches exactly — every other tab matches by prefix.
37 const active =
38 item.href === '/dashboard' ? pathname === '/dashboard' : pathname.startsWith(item.href);
39 const isAuth = 'auth' in item && item.auth;
40 return (
41 <Link
42 key={item.href}
43 href={item.href}
44 className={`shrink-0 whitespace-nowrap rounded-md px-3 py-1.5 font-mono text-xs transition ${
45 active
46 ? 'bg-[var(--color-surface-raised)]'
47 : isAuth
48 ? 'text-[var(--color-text-muted)] hover:bg-[var(--color-surface-raised)]'
49 : 'text-[var(--color-text-muted)] hover:text-[var(--color-text)]'
50 }`}
51 style={
52 active && isAuth
53 ? { color: AUTH_ACCENT }
54 : active
55 ? { color: 'var(--color-text)' }
56 : undefined
57 }
58 // Auth hover uses same yellow as active (group via CSS variable)
59 onMouseEnter={(e) => {
60 if (isAuth && !active) {
61 (e.currentTarget as HTMLElement).style.color = AUTH_ACCENT;
62 }
63 }}
64 onMouseLeave={(e) => {
65 if (isAuth && !active) {
66 (e.currentTarget as HTMLElement).style.color = '';
67 }
68 }}
69 >
70 {item.label}
71 </Link>
72 );
73 })}
74 </nav>
75 );
76}