import type { LucideIcon } from "lucide-react"; import { Ban, Calendar, Cog, Compass, Gavel, LayoutDashboard, Monitor, Newspaper, Puzzle, Radio, Settings, Shield, ShoppingCart, Store, Users, Wrench, } from "lucide-react"; import { pluginRegistry } from "@/lib/plugins"; import "@/lib/plugins/loader"; export interface AdminHubTab { href: string; /** Key under pages.admin.hubs.tabs.* */ labelKey: string; match?: string[]; /** Optional group id for multi-row tab strips (e.g. Radio primary/tools). */ group?: string; } export interface AdminHubDefinition { id: string; /** Key under pages.admin.hubs.* for title/subtitle */ titleKey: string; subtitleKey: string; icon: LucideIcon; /** Path prefixes belonging to this hub (for chrome + sidebar active). */ prefixes: string[]; tabs: AdminHubTab[]; } export interface AdminNavItem { href: string; labelKey: string; icon: LucideIcon; /** When set, sidebar item is active if pathname matches any prefix. */ matchPrefixes?: string[]; } export interface AdminNavGroup { labelKey: string; icon: LucideIcon; items: AdminNavItem[]; } export const ADMIN_HUBS: AdminHubDefinition[] = [ { id: "news-media", titleKey: "newsMedia", subtitleKey: "newsMediaSubtitle", icon: Newspaper, prefixes: [ "/admin/articles", "/admin/photos", "/admin/banners", "/admin/ads", "/admin/media", ], tabs: [ { href: "/admin/articles", labelKey: "articles", match: ["/admin/articles"], }, { href: "/admin/photos", labelKey: "photos" }, { href: "/admin/banners", labelKey: "banners" }, { href: "/admin/ads", labelKey: "ads", match: ["/admin/ads"] }, { href: "/admin/media", labelKey: "media" }, ], }, { id: "site-content", titleKey: "siteContent", subtitleKey: "siteContentSubtitle", icon: Compass, prefixes: [ "/admin/navigation", "/admin/help-questions", "/admin/writeable-boxes", "/admin/tags", "/admin/prefixes", ], tabs: [ { href: "/admin/navigation", labelKey: "navigator" }, { href: "/admin/help-questions", labelKey: "help", match: ["/admin/help-questions"], }, { href: "/admin/writeable-boxes", labelKey: "boxes" }, { href: "/admin/tags", labelKey: "tags" }, { href: "/admin/prefixes", labelKey: "prefixes" }, ], }, { id: "engagement", titleKey: "engagement", subtitleKey: "engagementSubtitle", icon: Calendar, prefixes: ["/admin/events", "/admin/polls", "/admin/tickets"], tabs: [ { href: "/admin/events", labelKey: "events", match: ["/admin/events"] }, { href: "/admin/events/types", labelKey: "eventTypes" }, { href: "/admin/polls", labelKey: "polls", match: ["/admin/polls"] }, { href: "/admin/tickets", labelKey: "tickets", match: ["/admin/tickets"], }, { href: "/admin/tickets/templates", labelKey: "templates" }, ], }, { id: "users", titleKey: "users", subtitleKey: "usersSubtitle", icon: Users, prefixes: [ "/admin/users", "/admin/online", "/admin/applications", "/admin/teams", ], tabs: [ { href: "/admin/users", labelKey: "directory", match: ["/admin/users"], }, { href: "/admin/users/multi-accounts", labelKey: "multiAccounts" }, { href: "/admin/online", labelKey: "online" }, { href: "/admin/applications", labelKey: "applications" }, { href: "/admin/teams", labelKey: "teams" }, ], }, { id: "access", titleKey: "access", subtitleKey: "accessSubtitle", icon: Shield, prefixes: [ "/admin/bans", "/admin/ip", "/admin/vpn", "/admin/permissions", "/admin/wordfilter", ], tabs: [ { href: "/admin/bans", labelKey: "bans" }, { href: "/admin/ip", labelKey: "ip" }, { href: "/admin/vpn", labelKey: "vpn" }, { href: "/admin/permissions", labelKey: "permissions", match: ["/admin/permissions"], }, { href: "/admin/wordfilter", labelKey: "wordFilter" }, ], }, { id: "moderation", titleKey: "moderation", subtitleKey: "moderationSubtitle", icon: Gavel, prefixes: ["/admin/moderation"], tabs: [ { href: "/admin/moderation", labelKey: "overview" }, { href: "/admin/moderation/actions", labelKey: "actions" }, { href: "/admin/moderation/cfh", labelKey: "cfh", match: ["/admin/moderation/cfh"], }, { href: "/admin/moderation/team", labelKey: "team" }, ], }, { id: "catalog", titleKey: "catalog", subtitleKey: "catalogSubtitle", icon: Store, prefixes: [ "/admin/catalog", "/admin/rare-values", "/admin/badges", "/admin/achievements", "/admin/sounds", ], tabs: [ { href: "/admin/catalog", labelKey: "catalogTab", match: ["/admin/catalog"] }, { href: "/admin/rare-values", labelKey: "rares" }, { href: "/admin/badges", labelKey: "badges" }, { href: "/admin/achievements", labelKey: "achievements" }, { href: "/admin/sounds", labelKey: "sounds" }, ], }, { id: "shop", titleKey: "shop", subtitleKey: "shopSubtitle", icon: ShoppingCart, prefixes: [ "/admin/shop", "/admin/transactions", "/admin/vouchers", "/admin/subscriptions", "/admin/calendar", ], tabs: [ { href: "/admin/shop", labelKey: "shopTab" }, { href: "/admin/transactions", labelKey: "transactions" }, { href: "/admin/vouchers", labelKey: "vouchers" }, { href: "/admin/subscriptions", labelKey: "subscriptions" }, { href: "/admin/calendar", labelKey: "calendar", match: ["/admin/calendar"], }, ], }, { id: "radio", titleKey: "radio", subtitleKey: "radioSubtitle", icon: Radio, prefixes: ["/admin/radio"], tabs: [ { href: "/admin/radio", labelKey: "overview", group: "primary" }, { href: "/admin/radio/history", labelKey: "history", group: "primary" }, { href: "/admin/radio/moderation", labelKey: "moderationTab", group: "primary", }, { href: "/admin/radio/monitoring", labelKey: "monitoring", group: "primary", }, { href: "/admin/radio/settings", labelKey: "settingsTab", group: "primary" }, { href: "/admin/radio/banners", labelKey: "banners", group: "tools" }, { href: "/admin/radio/embed", labelKey: "embed", group: "tools" }, { href: "/admin/radio/api-keys", labelKey: "apiKeys", group: "tools" }, { href: "/admin/radio/points", labelKey: "points", group: "tools" }, { href: "/admin/radio/ranks", labelKey: "ranks", group: "tools" }, { href: "/admin/radio/autodj", labelKey: "autoDj", group: "tools" }, ], }, { id: "settings", titleKey: "settings", subtitleKey: "settingsSubtitle", icon: Cog, prefixes: [ "/admin/settings", "/admin/theme", "/admin/maintenance", "/admin/favicon", "/admin/emulator", "/admin/email-templates", "/admin/housekeeping", "/admin/webhooks", ], tabs: [ { href: "/admin/settings", labelKey: "cms" }, { href: "/admin/theme", labelKey: "theme" }, { href: "/admin/maintenance", labelKey: "maintenance" }, { href: "/admin/favicon", labelKey: "favicon" }, { href: "/admin/emulator", labelKey: "emulator" }, { href: "/admin/email-templates", labelKey: "email" }, { href: "/admin/housekeeping", labelKey: "housekeeping" }, { href: "/admin/webhooks", labelKey: "webhooks" }, ], }, { id: "tools", titleKey: "tools", subtitleKey: "toolsSubtitle", icon: Wrench, prefixes: [ "/admin/commandocentrum", "/admin/rooms", "/admin/import", "/admin/translations", ], tabs: [ { href: "/admin/commandocentrum", labelKey: "commando" }, { href: "/admin/rooms", labelKey: "rooms", match: ["/admin/rooms"] }, { href: "/admin/import", labelKey: "import", match: ["/admin/import"] }, { href: "/admin/translations", labelKey: "translations", match: ["/admin/translations"], }, ], }, { id: "observability", titleKey: "observability", subtitleKey: "observabilitySubtitle", icon: Monitor, prefixes: [ "/admin/logs", "/admin/analytics", "/admin/devops", "/admin/alerts", ], tabs: [ { href: "/admin/logs", labelKey: "logs" }, { href: "/admin/logs/audit", labelKey: "audit" }, { href: "/admin/logs/chat", labelKey: "chat" }, { href: "/admin/logs/commands", labelKey: "commands" }, { href: "/admin/logs/trades", labelKey: "trades" }, { href: "/admin/analytics", labelKey: "analytics", match: ["/admin/analytics"], }, { href: "/admin/analytics/activity", labelKey: "activity" }, { href: "/admin/analytics/economy", labelKey: "economy" }, { href: "/admin/devops", labelKey: "devops", match: ["/admin/devops"] }, { href: "/admin/devops/errors", labelKey: "errors" }, { href: "/admin/alerts", labelKey: "alerts" }, ], }, { id: "plugins", titleKey: "plugins", subtitleKey: "pluginsSubtitle", icon: Puzzle, prefixes: ["/admin/plugins"], tabs: [ { href: "/admin/plugins", labelKey: "plugins" }, ], }, ]; export function allHubs(enabled?: Record): AdminHubDefinition[] { const allReg = pluginRegistry.getHubs(); const pluginHubs: AdminHubDefinition[] = []; for (const h of allReg) { const hubPlugin = pluginRegistry .getAll() .find((p) => (p.hubs ?? []).some((ph) => ph.id === h.id)); if (hubPlugin && enabled && enabled[hubPlugin.id] === false) continue; pluginHubs.push({ id: h.id, titleKey: h.titleKey, subtitleKey: h.subtitleKey, icon: h.icon, prefixes: h.prefixes, tabs: h.tabs.map((t) => ({ href: t.href, labelKey: t.labelKey, match: t.match, group: t.group, })), }); } return [...ADMIN_HUBS, ...pluginHubs]; } export function findAdminHub(pathname: string, enabled?: Record): AdminHubDefinition | null { const hubs = allHubs(enabled); return ( hubs.find((hub) => hub.prefixes.some((p) => pathname === p || pathname.startsWith(`${p}/`)), ) ?? null ); } export function allNavGroups(enabled?: Record): AdminNavGroup[] { const allReg = pluginRegistry.getNavGroups(); const pluginGroups: AdminNavGroup[] = []; for (const g of allReg) { const groupPlugin = pluginRegistry .getAll() .find((p) => (p.navGroups ?? []).some((pg) => pg.labelKey === g.labelKey)); if (groupPlugin && enabled && enabled[groupPlugin.id] === false) continue; pluginGroups.push({ labelKey: g.labelKey, icon: g.icon, items: g.items.map((item) => ({ href: item.href, labelKey: item.labelKey, icon: item.icon, matchPrefixes: item.matchPrefixes, })), }); } if (pluginGroups.length === 0) return ADMIN_NAV_GROUPS; return [ ...ADMIN_NAV_GROUPS, { labelKey: "plugins", icon: Puzzle, items: pluginGroups.flatMap((g) => g.items), }, ]; } function hubPrefixes(id: string): string[] { return ADMIN_HUBS.find((h) => h.id === id)?.prefixes ?? []; } /** Condensed sidebar — one entry per hub (plus dashboard). */ export const ADMIN_NAV_GROUPS: AdminNavGroup[] = [ { labelKey: "overview", icon: LayoutDashboard, items: [ { href: "/admin", labelKey: "dashboard", icon: LayoutDashboard, }, ], }, { labelKey: "content", icon: Newspaper, items: [ { href: "/admin/articles", labelKey: "hubNewsMedia", icon: Newspaper, matchPrefixes: hubPrefixes("news-media"), }, { href: "/admin/navigation", labelKey: "hubSiteContent", icon: Compass, matchPrefixes: hubPrefixes("site-content"), }, { href: "/admin/events", labelKey: "hubEngagement", icon: Calendar, matchPrefixes: hubPrefixes("engagement"), }, ], }, { labelKey: "usersAndAccess", icon: Shield, items: [ { href: "/admin/users", labelKey: "hubUsers", icon: Users, matchPrefixes: hubPrefixes("users"), }, { href: "/admin/bans", labelKey: "hubAccess", icon: Ban, matchPrefixes: hubPrefixes("access"), }, { href: "/admin/moderation", labelKey: "moderation", icon: Gavel, matchPrefixes: hubPrefixes("moderation"), }, ], }, { labelKey: "economy", icon: ShoppingCart, items: [ { href: "/admin/catalog", labelKey: "hubCatalog", icon: Store, matchPrefixes: hubPrefixes("catalog"), }, { href: "/admin/shop", labelKey: "hubShop", icon: ShoppingCart, matchPrefixes: hubPrefixes("shop"), }, ], }, { labelKey: "radio", icon: Radio, items: [ { href: "/admin/radio", labelKey: "radio", icon: Radio, matchPrefixes: ["/admin/radio"], }, ], }, { labelKey: "system", icon: Settings, items: [ { href: "/admin/settings", labelKey: "settings", icon: Cog, matchPrefixes: hubPrefixes("settings"), }, { href: "/admin/commandocentrum", labelKey: "hubTools", icon: Wrench, matchPrefixes: hubPrefixes("tools"), }, { href: "/admin/logs", labelKey: "hubObservability", icon: Monitor, matchPrefixes: hubPrefixes("observability"), }, ], }, { labelKey: "pluginsGroup", icon: Puzzle, items: [ { href: "/admin/plugins", labelKey: "hubPlugins", icon: Puzzle, matchPrefixes: ["/admin/plugins"], }, ], }, ];