'use client'; import Link from 'next/link'; import { usePathname } from 'next/navigation'; import { Anchor, BarChart3, Bookmark, Building2, FileSignature, Globe, Home, Inbox, Receipt, Settings, Shield, Ship, } from 'lucide-react'; import { useQuery } from '@tanstack/react-query'; import { Drawer, DrawerContent, DrawerHeader, DrawerTitle, DrawerClose, } from '@/components/shared/drawer'; import { useUmamiActive } from '@/components/website-analytics/use-website-analytics'; import { apiFetch } from '@/lib/api/client'; type MoreItem = { label: string; icon: typeof Building2; segment: string; }; type MoreGroup = { label: string; items: MoreItem[]; }; // Logical grouping (vs alphabetical or frequency-ranked): keeps a stable // spatial layout — reps' muscle memory survives — while making the // "kind of thing" each tile is explicit. Three sections: // - Records: entity lists (people, vessels, properties) // - Operations: daily-use action surfaces // - Configuration: port-level setup, hidden from most reps // // Interests stays here (not bottom nav) to dodge the Clients-vs- // Interests UX confusion. Inbox replaces the previously-separate // Alerts + Reminders entries (merged 2026-05-11). Website analytics // and Reservations are filtered out below when not applicable. const MORE_GROUPS: MoreGroup[] = [ { label: 'Records', items: [ { label: 'Documents', icon: FileSignature, segment: 'documents' }, { label: 'Interests', icon: Bookmark, segment: 'interests' }, { label: 'Yachts', icon: Ship, segment: 'yachts' }, { label: 'Companies', icon: Building2, segment: 'companies' }, { label: 'Residential', icon: Home, segment: 'residential/clients' }, ], }, { label: 'Operations', items: [ { label: 'Alerts & Reminders', icon: Inbox, segment: 'inbox' }, { label: 'Expenses', icon: Receipt, segment: 'expenses' }, { label: 'Reservations', icon: Anchor, segment: 'berth-reservations' }, { label: 'Reports', icon: BarChart3, segment: 'reports' }, ], }, { label: 'Configuration', items: [ { label: 'Website analytics', icon: Globe, segment: 'website-analytics' }, { label: 'Settings', icon: Settings, segment: 'settings' }, { label: 'Admin', icon: Shield, segment: 'admin' }, ], }, ]; export function MoreSheet({ open, onOpenChange, }: { open: boolean; onOpenChange: (next: boolean) => void; }) { const pathname = usePathname(); const portSlug = pathname.split('/').filter(Boolean)[0] ?? 'port-nimara'; // Hide "Website analytics" if Umami isn't wired up for this port — the // dedicated tile on the dashboard already does the same. const umami = useUmamiActive('today'); const umamiConfigured = !umami.isLoading && umami.data?.notConfigured !== true; // Hide "Reservations" until at least one exists for this port — until the // marina has confirmed bookings, the page is empty and surfaces nothing // useful. Cheap count via pageSize=1; cached 5 min so opening the sheet // repeatedly doesn't refetch. const reservations = useQuery<{ pagination?: { total: number } }>({ queryKey: ['berth-reservations', 'sheet-count'], queryFn: () => apiFetch('/api/v1/berth-reservations?pageSize=1'), staleTime: 5 * 60_000, enabled: open, }); const hasReservations = !reservations.isLoading && (reservations.data?.pagination?.total ?? 0) > 0; // Per-group filter: keep only the items relevant to this port's state. const groups = MORE_GROUPS.map((g) => ({ ...g, items: g.items.filter((item) => { if (item.segment === 'website-analytics') return umamiConfigured; if (item.segment === 'berth-reservations') return hasReservations; return true; }), })).filter((g) => g.items.length > 0); return ( More
{groups.map((group) => (

{group.label}

    {group.items.map((item) => { const Icon = item.icon; return (
  • {item.label}
  • ); })}
))}
); }