import type { BottomNavItem } from "@/components/navigation/bottom-nav"; /** * Single source of truth for the merged staff/owner/super-admin bottom nav * and desktop sidebar (see docs/implementation-plan.md and the Phase 11 * "merged navigation" brief). Owner is a permission on a staff account, not * a separate app — Owner and SuperAdmin nav reuse the exact same personal * routes (`/staff/current`, `/staff/clients`, `/staff/settings`) a barber * uses, rather than duplicating them under `/owner`. This is what lets * owners reach barber tools and business tools from one menu with zero new * routes. * * A Super Administrator has no StaffProfile by construction (see * isSuperAdmin/getActingBusinessContext) — they get no "Now" tab, since * there is no personal schedule to show, per the brief's explicit "do not * fabricate a personal barber schedule for the Super Administrator". */ export type NavRole = "staff" | "owner" | "superadmin"; const CALENDAR: BottomNavItem = { href: "/staff", label: "Calendar", icon: "calendar-days" }; const OWNER_CALENDAR: BottomNavItem = { href: "/owner/calendar", label: "Calendar", icon: "calendar-days" }; const NOW: BottomNavItem = { href: "/staff/current", label: "Now", icon: "scissors" }; const CLIENTS: BottomNavItem = { href: "/staff/clients", label: "Clients", icon: "users" }; const MANAGE: BottomNavItem = { href: "/owner", label: "Manage", icon: "briefcase" }; const SETTINGS: BottomNavItem = { href: "/staff/settings", label: "Settings", icon: "settings" }; const NAV_ITEMS_BY_ROLE: Record = { staff: [CALENDAR, NOW, CLIENTS, SETTINGS], owner: [OWNER_CALENDAR, NOW, CLIENTS, MANAGE, SETTINGS], superadmin: [OWNER_CALENDAR, CLIENTS, MANAGE, SETTINGS], }; export function getNavItems(role: NavRole): BottomNavItem[] { return NAV_ITEMS_BY_ROLE[role]; } /** * Longest-matching-href wins, rather than "every item whose href is a * pathname prefix" (the previous per-component logic) — that scheme let * `/staff/current` mark both "Calendar" (href `/staff`) and "Now" active at * once, since `/staff/current` also starts with `/staff`. Sorting by href * length and taking the first match makes only the most specific item win, * which is what makes nested routes (e.g. `/owner/settings/loyalty`, * `/staff/clients/[id]`) activate exactly one, correct primary tab. */ export function resolveActiveHref(pathname: string, items: BottomNavItem[]): string | null { const matches = items.filter((item) => pathname === item.href || pathname.startsWith(`${item.href}/`)); if (matches.length === 0) return null; return matches.reduce((longest, item) => (item.href.length > longest.href.length ? item : longest)).href; }