From 363c9b3d5692ba2f3f183bc75854e00758979645 Mon Sep 17 00:00:00 2001 From: simoleo89 Date: Wed, 15 Jul 2026 21:29:36 +0200 Subject: [PATCH] Reorganize admin into tabbed hubs with a condensed sidebar. Replace the long flat nav with hub entries, shared AdminHubChrome tabs, and AdminPageShell. Existing URLs stay stable; Settings/Radio and other sections now share one chrome. Co-authored-by: Cursor --- src/app/admin/layout.tsx | 403 ++---------------- src/app/admin/settings/page.tsx | 37 -- src/app/globals.css | 6 + src/components/admin/admin-hub-chrome.tsx | 30 ++ src/components/admin/admin-nav-link.tsx | 22 +- src/components/admin/admin-page-shell.tsx | 52 +++ src/components/admin/admin-section-tabs.tsx | 61 +++ src/lib/admin-nav.ts | 435 ++++++++++++++++++++ src/messages/bg.json | 11 +- src/messages/cs.json | 11 +- src/messages/da.json | 11 +- src/messages/de.json | 11 +- src/messages/el.json | 11 +- src/messages/en.json | 9 + src/messages/es.json | 11 +- src/messages/fr.json | 11 +- src/messages/hr.json | 11 +- src/messages/hu.json | 11 +- src/messages/it.json | 11 +- src/messages/nl.json | 11 +- src/messages/no.json | 11 +- src/messages/pl.json | 11 +- src/messages/pt.json | 11 +- src/messages/ro.json | 11 +- src/messages/ru.json | 11 +- src/messages/sk.json | 11 +- src/messages/sr.json | 11 +- src/messages/sv.json | 11 +- src/messages/tr.json | 11 +- src/messages/uk.json | 11 +- 30 files changed, 854 insertions(+), 432 deletions(-) create mode 100644 src/components/admin/admin-hub-chrome.tsx create mode 100644 src/components/admin/admin-page-shell.tsx create mode 100644 src/components/admin/admin-section-tabs.tsx create mode 100644 src/lib/admin-nav.ts diff --git a/src/app/admin/layout.tsx b/src/app/admin/layout.tsx index 957dafe93f..9531db03da 100644 --- a/src/app/admin/layout.tsx +++ b/src/app/admin/layout.tsx @@ -1,361 +1,18 @@ -import { - Award, - Ban, - Bell, - Calendar, - ClipboardList, - Cog, - Compass, - CreditCard, - DoorOpen, - FileText, - Filter, - Gem, - Globe, - Group, - HelpCircle, - History, - Image, - Key, - Languages, - LayoutDashboard, - LogOut, - Mail, - Megaphone, - MessageSquare, - Monitor, - Music, - Newspaper, - Palette, - Radio, - Receipt, - Settings, - Shield, - ShoppingCart, - SquarePen, - Store, - Tags, - Terminal, - Ticket, - Trophy, - Upload, - Users, - Wrench, -} from "lucide-react"; +import { LogOut } from "lucide-react"; import Link from "next/link"; import { redirect } from "next/navigation"; import { getTranslations } from "next-intl/server"; import type { ReactNode } from "react"; +import { AdminHubChrome } from "@/components/admin/admin-hub-chrome"; import { AdminMobileWrapper } from "@/components/admin/admin-mobile-wrapper"; import { AdminNavLink } from "@/components/admin/admin-nav-link"; import { requireStaff } from "@/lib/admin/guard"; +import { ADMIN_NAV_GROUPS } from "@/lib/admin-nav"; import { prisma } from "@/lib/prisma"; import { siteSettings } from "@/lib/services/site-settings"; export const dynamic = "force-dynamic"; -function getNavGroups(t: (key: string) => string) { - return [ - { - label: t("overview"), - icon: , - items: [ - { - href: "/admin", - label: t("dashboard"), - icon: , - }, - ], - }, - { - label: t("content"), - icon: , - items: [ - { - href: "/admin/articles", - label: t("articles"), - icon: , - }, - { href: "/admin/tags", label: t("tags"), icon: }, - { - href: "/admin/navigation", - label: t("navigator"), - icon: , - }, - { - href: "/admin/help-questions", - label: t("helpCenter"), - icon: , - }, - { - href: "/admin/ads", - label: t("advertisements"), - icon: , - }, - { - href: "/admin/writeable-boxes", - label: t("writeableBoxes"), - icon: , - }, - { - href: "/admin/photos", - label: t("photos"), - icon: , - }, - { - href: "/admin/tickets", - label: t("tickets"), - icon: , - }, - { - href: "/admin/events", - label: t("events"), - icon: , - }, - { - href: "/admin/polls", - label: t("polls"), - icon: , - }, - { href: "/admin/banners", label: t("banners"), icon: }, - { - href: "/admin/prefixes", - label: t("prefixes"), - icon: , - }, - ], - }, - { - label: t("usersAndAccess"), - icon: , - items: [ - { href: "/admin/users", label: t("users"), icon: }, - { href: "/admin/bans", label: t("bans"), icon: }, - { - href: "/admin/ip", - label: t("ipManagement"), - icon: , - }, - { href: "/admin/vpn", label: t("vpn"), icon: }, - { - href: "/admin/applications", - label: t("applications"), - icon: , - }, - { href: "/admin/teams", label: t("teams"), icon: }, - { - href: "/admin/permissions", - label: t("permissions"), - icon: , - }, - { - href: "/admin/online", - label: t("onlineUsers"), - icon: , - }, - { - href: "/admin/moderation", - label: t("moderation"), - icon: , - }, - ], - }, - { - label: t("economy"), - icon: , - items: [ - { - href: "/admin/catalog", - label: t("catalog"), - icon: , - }, - { - href: "/admin/shop", - label: t("shop"), - icon: , - }, - { - href: "/admin/transactions", - label: t("transactions"), - icon: , - }, - { - href: "/admin/vouchers", - label: t("vouchers"), - icon: , - }, - { - href: "/admin/subscriptions", - label: t("subscriptions"), - icon: , - }, - { - href: "/admin/rare-values", - label: t("rareValues"), - icon: , - }, - { - href: "/admin/badges", - label: t("badges"), - icon: , - }, - { - href: "/admin/achievements", - label: t("achievements"), - icon: , - }, - { - href: "/admin/calendar", - label: t("calendar"), - icon: , - }, - ], - }, - { - label: t("radio"), - icon: , - items: [ - { href: "/admin/radio", label: t("radio"), icon: }, - { - href: "/admin/radio/history", - label: t("radioHistory"), - icon: , - }, - { - href: "/admin/radio/banners", - label: t("radioBanners"), - icon: , - }, - { - href: "/admin/radio/embed", - label: t("radioEmbed"), - icon: , - }, - { - href: "/admin/radio/api-keys", - label: t("radioApiKeys"), - icon: , - }, - { - href: "/admin/radio/moderation", - label: t("radioModeration"), - icon: , - }, - { - href: "/admin/radio/settings", - label: t("radioSettings"), - icon: , - }, - { - href: "/admin/radio/monitoring", - label: t("radioMonitoring"), - icon: , - }, - { - href: "/admin/radio/points", - label: t("radioPoints"), - icon: , - }, - { - href: "/admin/radio/ranks", - label: t("radioRanks"), - icon: , - }, - { - href: "/admin/radio/autodj", - label: t("radioAutodj"), - icon: , - }, - ], - }, - { - label: t("system"), - icon: , - items: [ - { - href: "/admin/commandocentrum", - label: t("commandocentrum"), - icon: , - }, - { - href: "/admin/emulator", - label: t("emulator"), - icon: , - }, - { href: "/admin/alerts", label: t("alerts"), icon: }, - { href: "/admin/logs", label: t("logs"), icon: }, - { - href: "/admin/logs/audit", - label: t("auditLog"), - icon: , - }, - { - href: "/admin/analytics", - label: t("analytics"), - icon: , - }, - { href: "/admin/devops", label: t("devops"), icon: }, - { - href: "/admin/wordfilter", - label: t("wordFilter"), - icon: , - }, - { - href: "/admin/maintenance", - label: t("maintenance"), - icon: , - }, - { - href: "/admin/housekeeping", - label: t("housekeeping"), - icon: , - }, - { - href: "/admin/rooms", - label: t("rooms"), - icon: , - }, - { - href: "/admin/email-templates", - label: t("emailTemplates"), - icon: , - }, - { - href: "/admin/theme", - label: t("theme"), - icon: , - }, - { href: "/admin/media", label: t("media"), icon: }, - { - href: "/admin/favicon", - label: t("favicon"), - icon: , - }, - { - href: "/admin/sounds", - label: t("sounds"), - icon: , - }, - { - href: "/admin/translations", - label: t("translations"), - icon: , - }, - { - href: "/admin/import", - label: t("import"), - icon: , - }, - { - href: "/admin/settings", - label: t("settings"), - icon: , - }, - ], - }, - ]; -} - export default async function AdminLayout({ children, }: { @@ -380,7 +37,9 @@ export default async function AdminLayout({ style={{ backgroundColor: "var(--admin-canvas)" }} > -
{children}
+
+ {children} +
); @@ -393,7 +52,6 @@ async function Sidebar({ }) { const t = await getTranslations("pages.admin.nav"); const initial = staff.username.charAt(0).toUpperCase(); - const navGroups = getNavGroups(t); return (