import { canReadAdmin, type UserRole } from './auth.js'; export interface NavigationItem { label: string; href: string; shortcut?: string; matches?: (path: string) => boolean; } export interface NavigationGroup { id: string; label: string; admin?: boolean; items: NavigationItem[]; } export const navigationGroups: NavigationGroup[] = [ { id: 'fleet', label: 'Fleet', items: [ { label: 'Servers', href: '/', shortcut: 'f', matches: (path) => path === '/' || path.startsWith('/servers/') }, { label: 'Hosts', href: '/hosts', shortcut: 'o', matches: (path) => path === '/hosts' || /^\/hosts\/(?!operations(?:\/|$))/.test(path) }, { label: 'Capacity', href: '/capacity' }, { label: 'Autoscaling', href: '/autoscaling' }, { label: 'Collections', href: '/collections' } ] }, { id: 'releases', label: 'Releases', items: [ { label: 'Scripts', href: '/scripts', shortcut: 's' }, { label: 'Configs', href: '/configs', shortcut: 'c' }, { label: 'Plugins', href: '/plugins', shortcut: 'p' }, { label: 'Game files', href: '/game-files' }, { label: 'Betas', href: '/betas', shortcut: 'b' }, { label: 'Campaigns', href: '/campaigns', shortcut: 'a' } ] }, { id: 'activity', label: 'Activity', items: [ { label: 'Activity log', href: '/activity', shortcut: 'd', matches: (path) => path === '/activity' || path === '/operations' || path === '/hosts/operations' }, { label: 'Provisioning', href: '/provisioning', matches: (path) => /^\/(provisioning|deployments)(\/|$)/.test(path) }, { label: 'Maintenance', href: '/maintenance', shortcut: 'w', matches: (path) => /^\/(maintenance|watchdog)(\/|$)/.test(path) } ] }, { id: 'players', label: 'Players', items: [ { label: 'Leaderboard', href: '/leaderboard', shortcut: 'l' }, { label: 'Matches', href: '/matches' }, { label: 'Bank', href: '/bank' }, { label: 'Usage', href: '/metrics', shortcut: 'm' } ] }, { id: 'admin', label: 'Admin', admin: true, items: [ { label: 'Users', href: '/settings/users' }, { label: 'Keys', href: '/server-keys', shortcut: 'k' }, { label: 'Settings', href: '/settings', shortcut: 'h', matches: (path) => path === '/settings' } ] } ]; export function visibleNavigation(role: UserRole): NavigationGroup[] { return navigationGroups.filter((group) => !group.admin || canReadAdmin(role)); } export function navigationItemActive(item: NavigationItem, path: string): boolean { return item.matches ? item.matches(path) : path === item.href || path.startsWith(item.href + '/'); } export function navigationLocation(path: string, role: UserRole) { for (const group of visibleNavigation(role)) { const item = group.items.find((item) => navigationItemActive(item, path)); if (item) return { group, item }; } return null; }