SPB Git forge

spb/rareindex

Public
54commits 1branches 0releases
7.1 MBsize
maindefault branch
10 days agolast push
TypeScript 61.9% HTML 37.2% SQL 0.7%
3.5 KB · 93 lines tsx
Raw Blame History
1'use client';23import Link from 'next/link';4import { usePathname } from 'next/navigation';5import { cn } from '@/lib/format';67export interface AccountNavItem {8  href: string;9  label: string;10  badge?: number;11}1213export const ACCOUNT_NAV: Array<{ label: string; items: AccountNavItem[] }> = [14  {15    label: 'My RareIndex',16    items: [17      { href: '/collections', label: 'Collections' },18      { href: '/my-index', label: 'My Index' },19      { href: '/watchlist', label: 'Watchlist' },20      { href: '/targets', label: 'Price targets' },21      { href: '/deals', label: 'Deal Radar' },22      { href: '/saved', label: 'Saved searches' },23    ],24  },25  {26    label: 'Signals',27    items: [28      { href: '/alerts', label: 'Alerts' },29      { href: '/notifications', label: 'Inbox' },30    ],31  },32  {33    label: 'Account',34    items: [35      { href: '/account/settings', label: 'Profile' },36      { href: '/account/security', label: 'Security' },37      { href: '/account/notifications', label: 'Notifications' },38      { href: '/account/api-keys', label: 'API keys' },39      { href: '/account/data', label: 'Data & privacy' },40    ],41  },42];4344export function AccountNav({ unread, handle }: { unread: number; handle: string | null }) {45  const pathname = usePathname();46  return (47    <nav aria-label="Account" className="text-[13px]">48      {/* mobile: horizontal scroll */}49      <div className="-mx-4 flex gap-1 overflow-x-auto px-4 pb-2 scrollbar-none lg:hidden">50        {ACCOUNT_NAV.flatMap((g) => g.items).map((i) => {51          const active = pathname === i.href || pathname.startsWith(`${i.href}/`);52          return (53            <Link key={i.href} href={i.href} className={cn('shrink-0 rounded-full border px-3 py-1.5', active ? 'border-fg bg-accent text-accent-fg' : 'border-border text-muted')}>54              {i.label}55              {i.href === '/notifications' && unread > 0 ? <span className="ml-1.5 rounded-full bg-alert px-1.5 text-[10px] font-semibold text-white">{unread}</span> : null}56            </Link>57          );58        })}59      </div>60      {/* desktop: sidebar */}61      <div className="hidden lg:block">62        {ACCOUNT_NAV.map((g) => (63          <div key={g.label} className="mb-4">64            <p className="mb-1 px-2 text-[10px] font-semibold uppercase tracking-wider text-subtle">{g.label}</p>65            <ul className="space-y-0.5">66              {g.items.map((i) => {67                const active = pathname === i.href || pathname.startsWith(`${i.href}/`);68                return (69                  <li key={i.href}>70                    <Link href={i.href} className={cn('flex items-center justify-between rounded-md px-2 py-1.5', active ? 'bg-inset font-medium text-fg' : 'text-muted hover:bg-inset hover:text-fg')}>71                      {i.label}72                      {i.href === '/notifications' && unread > 0 ? <span className="rounded-full bg-alert px-1.5 text-[10px] font-semibold text-white">{unread}</span> : null}73                    </Link>74                  </li>75                );76              })}77            </ul>78          </div>79        ))}80        {handle ? (81          <Link href={`/u/${handle}`} className="block rounded-md border border-dashed border-border px-2 py-1.5 text-xs text-muted hover:text-fg">82            Public profile → /u/{handle}83          </Link>84        ) : (85          <Link href="/account/settings#handle" className="block rounded-md border border-dashed border-border px-2 py-1.5 text-xs text-muted hover:text-fg">86            Claim a public handle →87          </Link>88        )}89      </div>90    </nav>91  );92}93