diff --git a/src/app/admin/settings/page.tsx b/src/app/admin/settings/page.tsx
index b73850c792..d311746b35 100644
--- a/src/app/admin/settings/page.tsx
+++ b/src/app/admin/settings/page.tsx
@@ -1,5 +1,3 @@
-import { Cog, ExternalLink } from "lucide-react";
-import Link from "next/link";
import { redirect } from "next/navigation";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
@@ -10,13 +8,6 @@ import { CmsSettingsForm } from "./cms-settings-form";
export const dynamic = "force-dynamic";
export const metadata = { title: "CMS Settings" };
-const RELATED = [
- { href: "/admin/theme", label: "Theme & colors" },
- { href: "/admin/maintenance", label: "Maintenance" },
- { href: "/admin/vpn", label: "VPN / proxy block" },
- { href: "/admin/emulator", label: "Emulator config" },
-] as const;
-
export default async function AdminSettings() {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.SETTINGS_VIEW, session.user.rank)) {
@@ -49,34 +40,6 @@ export default async function AdminSettings() {
return (
-
-
-
-
-
-
-
- CMS Settings
-
-
- Configure hotel identity, imaging, client, radio and security.
-
-
-
-
- {RELATED.map((item) => (
-
- {item.label}
-
-
- ))}
-
-
-
{settings.length} keys in database
diff --git a/src/app/globals.css b/src/app/globals.css
index d6c28eb26e..a6e98b126b 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -505,6 +505,12 @@ tbody tr:hover {
scroll-margin-top: 1rem;
}
+/* Hub chrome already shows the section title — soften page-level heroes. */
+.admin-hub-panel > .space-y-6 > div:first-child > h1.text-3xl {
+ font-size: 1.15rem;
+ letter-spacing: -0.01em;
+}
+
/* Page heading */
.admin-page main > h1:first-child,
.admin-page > h1:first-child {
diff --git a/src/components/admin/admin-hub-chrome.tsx b/src/components/admin/admin-hub-chrome.tsx
new file mode 100644
index 0000000000..952a1a3f62
--- /dev/null
+++ b/src/components/admin/admin-hub-chrome.tsx
@@ -0,0 +1,30 @@
+"use client";
+
+import { usePathname } from "next/navigation";
+import type { ReactNode } from "react";
+import { AdminPageShell } from "@/components/admin/admin-page-shell";
+import { AdminSectionTabs } from "@/components/admin/admin-section-tabs";
+import { findAdminHub } from "@/lib/admin-nav";
+
+/**
+ * When the current path belongs to a hub, wraps children with a shared
+ * title + tab strip. Dashboard and unknown routes render children as-is.
+ */
+export function AdminHubChrome({ children }: { children: ReactNode }) {
+ const pathname = usePathname() ?? "";
+ const hub = findAdminHub(pathname);
+
+ if (!hub) return <>{children}>;
+
+ return (
+ }
+ className="admin-hub-panel"
+ >
+ {children}
+
+ );
+}
diff --git a/src/components/admin/admin-nav-link.tsx b/src/components/admin/admin-nav-link.tsx
index f06b5acf3f..5dceb87ee1 100644
--- a/src/components/admin/admin-nav-link.tsx
+++ b/src/components/admin/admin-nav-link.tsx
@@ -6,25 +6,33 @@ import type { ReactNode } from "react";
import { useAdminMobile } from "@/components/admin/admin-mobile-wrapper";
/**
- * Sidebar link that highlights when its route is active. "/admin" matches
- * exactly; every other entry also matches its sub-routes (e.g. /admin/radio is
- * active on /admin/radio/history) so the current section stays lit.
+ * Sidebar link that highlights when its route is active.
+ * Optional matchPrefixes cover multi-page hubs (e.g. Settings → theme/vpn).
*/
export function AdminNavLink({
href,
icon,
+ matchPrefixes,
children,
}: {
href: string;
icon?: ReactNode;
+ matchPrefixes?: string[];
children: ReactNode;
}) {
const pathname = usePathname() ?? "";
const { close } = useAdminMobile();
- const active =
- href === "/admin"
- ? pathname === "/admin"
- : pathname === href || pathname.startsWith(`${href}/`);
+
+ let active: boolean;
+ if (href === "/admin") {
+ active = pathname === "/admin";
+ } else if (matchPrefixes?.length) {
+ active = matchPrefixes.some(
+ (p) => pathname === p || pathname.startsWith(`${p}/`),
+ );
+ } else {
+ active = pathname === href || pathname.startsWith(`${href}/`);
+ }
return (
+
+
+ {Icon ? (
+
+
+
+ ) : null}
+
+
+ {title}
+
+ {subtitle ? (
+
+ {subtitle}
+
+ ) : null}
+
+
+ {actions ? (
+
{actions}
+ ) : null}
+
+ {tabs}
+ {children}
+
+ );
+}
diff --git a/src/components/admin/admin-section-tabs.tsx b/src/components/admin/admin-section-tabs.tsx
new file mode 100644
index 0000000000..8e76cdaddf
--- /dev/null
+++ b/src/components/admin/admin-section-tabs.tsx
@@ -0,0 +1,61 @@
+"use client";
+
+import Link from "next/link";
+import { usePathname } from "next/navigation";
+import { cn } from "@/lib/utils";
+
+export interface AdminTab {
+ href: string;
+ label: string;
+ /** Extra prefixes that count as active for this tab (detail routes). */
+ match?: string[];
+}
+
+function matchLength(pathname: string, prefix: string): number {
+ if (pathname === prefix) return prefix.length + 1; // prefer exact
+ if (pathname.startsWith(`${prefix}/`)) return prefix.length;
+ return -1;
+}
+
+export function AdminSectionTabs({ tabs }: { tabs: AdminTab[] }) {
+ const pathname = usePathname() ?? "";
+
+ let bestIndex = -1;
+ let bestScore = -1;
+ tabs.forEach((tab, index) => {
+ const prefixes = tab.match ?? [tab.href];
+ for (const prefix of prefixes) {
+ const score = matchLength(pathname, prefix);
+ if (score > bestScore) {
+ bestScore = score;
+ bestIndex = index;
+ }
+ }
+ });
+
+ return (
+
+ );
+}
diff --git a/src/lib/admin-nav.ts b/src/lib/admin-nav.ts
new file mode 100644
index 0000000000..eb4970ac21
--- /dev/null
+++ b/src/lib/admin-nav.ts
@@ -0,0 +1,435 @@
+import type { LucideIcon } from "lucide-react";
+import {
+ Ban,
+ Calendar,
+ Cog,
+ Compass,
+ LayoutDashboard,
+ Monitor,
+ Newspaper,
+ Radio,
+ Settings,
+ Shield,
+ ShoppingCart,
+ Store,
+ Users,
+ Wrench,
+} from "lucide-react";
+
+export interface AdminHubTab {
+ href: string;
+ label: string;
+ match?: string[];
+}
+
+export interface AdminHubDefinition {
+ id: string;
+ title: string;
+ subtitle: 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",
+ title: "News & media",
+ subtitle: "Articles, photos, banners, ads and media library",
+ icon: Newspaper,
+ prefixes: [
+ "/admin/articles",
+ "/admin/photos",
+ "/admin/banners",
+ "/admin/ads",
+ "/admin/media",
+ ],
+ tabs: [
+ {
+ href: "/admin/articles",
+ label: "Articles",
+ match: ["/admin/articles"],
+ },
+ { href: "/admin/photos", label: "Photos" },
+ { href: "/admin/banners", label: "Banners" },
+ { href: "/admin/ads", label: "Ads", match: ["/admin/ads"] },
+ { href: "/admin/media", label: "Media" },
+ ],
+ },
+ {
+ id: "site-content",
+ title: "Site content",
+ subtitle: "Navigation, help center, boxes, tags and prefixes",
+ icon: Compass,
+ prefixes: [
+ "/admin/navigation",
+ "/admin/help-questions",
+ "/admin/writeable-boxes",
+ "/admin/tags",
+ "/admin/prefixes",
+ ],
+ tabs: [
+ { href: "/admin/navigation", label: "Navigator" },
+ {
+ href: "/admin/help-questions",
+ label: "Help",
+ match: ["/admin/help-questions"],
+ },
+ { href: "/admin/writeable-boxes", label: "Boxes" },
+ { href: "/admin/tags", label: "Tags" },
+ { href: "/admin/prefixes", label: "Prefixes" },
+ ],
+ },
+ {
+ id: "engagement",
+ title: "Engagement",
+ subtitle: "Events, polls and support tickets",
+ icon: Calendar,
+ prefixes: ["/admin/events", "/admin/polls", "/admin/tickets"],
+ tabs: [
+ { href: "/admin/events", label: "Events", match: ["/admin/events"] },
+ { href: "/admin/polls", label: "Polls", match: ["/admin/polls"] },
+ {
+ href: "/admin/tickets",
+ label: "Tickets",
+ match: ["/admin/tickets"],
+ },
+ ],
+ },
+ {
+ id: "users",
+ title: "Users",
+ subtitle: "Directory, online players, applications and teams",
+ icon: Users,
+ prefixes: [
+ "/admin/users",
+ "/admin/online",
+ "/admin/applications",
+ "/admin/teams",
+ ],
+ tabs: [
+ { href: "/admin/users", label: "Directory", match: ["/admin/users"] },
+ { href: "/admin/online", label: "Online" },
+ { href: "/admin/applications", label: "Applications" },
+ { href: "/admin/teams", label: "Teams" },
+ ],
+ },
+ {
+ id: "access",
+ title: "Access & security",
+ subtitle: "Bans, IP, VPN, permissions and word filter",
+ icon: Shield,
+ prefixes: [
+ "/admin/bans",
+ "/admin/ip",
+ "/admin/vpn",
+ "/admin/permissions",
+ "/admin/wordfilter",
+ ],
+ tabs: [
+ { href: "/admin/bans", label: "Bans" },
+ { href: "/admin/ip", label: "IP" },
+ { href: "/admin/vpn", label: "VPN" },
+ {
+ href: "/admin/permissions",
+ label: "Permissions",
+ match: ["/admin/permissions"],
+ },
+ { href: "/admin/wordfilter", label: "Word filter" },
+ ],
+ },
+ {
+ id: "moderation",
+ title: "Moderation",
+ subtitle: "Reports, actions and moderation team",
+ icon: Shield,
+ prefixes: ["/admin/moderation"],
+ tabs: [
+ { href: "/admin/moderation", label: "Overview" },
+ { href: "/admin/moderation/actions", label: "Actions" },
+ {
+ href: "/admin/moderation/cfh",
+ label: "CFH",
+ match: ["/admin/moderation/cfh"],
+ },
+ { href: "/admin/moderation/team", label: "Team" },
+ ],
+ },
+ {
+ id: "catalog",
+ title: "Catalog & rares",
+ subtitle: "Catalog, rares, badges, achievements and sounds",
+ icon: Store,
+ prefixes: [
+ "/admin/catalog",
+ "/admin/rare-values",
+ "/admin/badges",
+ "/admin/achievements",
+ "/admin/sounds",
+ ],
+ tabs: [
+ { href: "/admin/catalog", label: "Catalog", match: ["/admin/catalog"] },
+ { href: "/admin/rare-values", label: "Rares" },
+ { href: "/admin/badges", label: "Badges" },
+ { href: "/admin/achievements", label: "Achievements" },
+ { href: "/admin/sounds", label: "Sounds" },
+ ],
+ },
+ {
+ id: "shop",
+ title: "Shop & payments",
+ subtitle: "Shop, transactions, vouchers, subscriptions and calendar",
+ icon: ShoppingCart,
+ prefixes: [
+ "/admin/shop",
+ "/admin/transactions",
+ "/admin/vouchers",
+ "/admin/subscriptions",
+ "/admin/calendar",
+ ],
+ tabs: [
+ { href: "/admin/shop", label: "Shop" },
+ { href: "/admin/transactions", label: "Transactions" },
+ { href: "/admin/vouchers", label: "Vouchers" },
+ { href: "/admin/subscriptions", label: "Subscriptions" },
+ {
+ href: "/admin/calendar",
+ label: "Calendar",
+ match: ["/admin/calendar"],
+ },
+ ],
+ },
+ {
+ id: "radio",
+ title: "Radio",
+ subtitle: "Stream, DJ tools, embed and monitoring",
+ icon: Radio,
+ prefixes: ["/admin/radio"],
+ tabs: [
+ { href: "/admin/radio", label: "Overview" },
+ { href: "/admin/radio/history", label: "History" },
+ { href: "/admin/radio/banners", label: "Banners" },
+ { href: "/admin/radio/embed", label: "Embed" },
+ { href: "/admin/radio/api-keys", label: "API keys" },
+ { href: "/admin/radio/moderation", label: "Moderation" },
+ { href: "/admin/radio/settings", label: "Settings" },
+ { href: "/admin/radio/monitoring", label: "Monitoring" },
+ { href: "/admin/radio/points", label: "Points" },
+ { href: "/admin/radio/ranks", label: "Ranks" },
+ { href: "/admin/radio/autodj", label: "Auto DJ" },
+ ],
+ },
+ {
+ id: "settings",
+ title: "Settings",
+ subtitle: "CMS config, theme, maintenance and related tools",
+ icon: Cog,
+ prefixes: [
+ "/admin/settings",
+ "/admin/theme",
+ "/admin/maintenance",
+ "/admin/favicon",
+ "/admin/emulator",
+ "/admin/email-templates",
+ "/admin/housekeeping",
+ ],
+ tabs: [
+ { href: "/admin/settings", label: "CMS" },
+ { href: "/admin/theme", label: "Theme" },
+ { href: "/admin/maintenance", label: "Maintenance" },
+ { href: "/admin/favicon", label: "Favicon" },
+ { href: "/admin/emulator", label: "Emulator" },
+ { href: "/admin/email-templates", label: "Email" },
+ { href: "/admin/housekeeping", label: "Housekeeping" },
+ ],
+ },
+ {
+ id: "tools",
+ title: "Tools",
+ subtitle: "RCON, rooms, import and translations",
+ icon: Wrench,
+ prefixes: [
+ "/admin/commandocentrum",
+ "/admin/rooms",
+ "/admin/import",
+ "/admin/translations",
+ ],
+ tabs: [
+ { href: "/admin/commandocentrum", label: "Commando" },
+ { href: "/admin/rooms", label: "Rooms", match: ["/admin/rooms"] },
+ { href: "/admin/import", label: "Import", match: ["/admin/import"] },
+ {
+ href: "/admin/translations",
+ label: "Translations",
+ match: ["/admin/translations"],
+ },
+ ],
+ },
+ {
+ id: "observability",
+ title: "Observability",
+ subtitle: "Logs, analytics, DevOps and hotel alerts",
+ icon: Monitor,
+ prefixes: [
+ "/admin/logs",
+ "/admin/analytics",
+ "/admin/devops",
+ "/admin/alerts",
+ ],
+ tabs: [
+ { href: "/admin/logs", label: "Logs", match: ["/admin/logs"] },
+ { href: "/admin/logs/audit", label: "Audit" },
+ {
+ href: "/admin/analytics",
+ label: "Analytics",
+ match: ["/admin/analytics"],
+ },
+ { href: "/admin/devops", label: "DevOps", match: ["/admin/devops"] },
+ { href: "/admin/alerts", label: "Alerts" },
+ ],
+ },
+];
+
+export function findAdminHub(pathname: string): AdminHubDefinition | null {
+ return (
+ ADMIN_HUBS.find((hub) =>
+ hub.prefixes.some((p) => pathname === p || pathname.startsWith(`${p}/`)),
+ ) ?? null
+ );
+}
+
+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: Shield,
+ 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"),
+ },
+ ],
+ },
+];
diff --git a/src/messages/bg.json b/src/messages/bg.json
index a764011296..1294df4669 100644
--- a/src/messages/bg.json
+++ b/src/messages/bg.json
@@ -755,7 +755,16 @@
"backToSite": "Обратно към сайта",
"housekeeping": "Домакинство",
"hotelManagementPanel": "Панел за управление на хотел",
- "rankLabel": "Ранг {rank}"
+ "rankLabel": "Ранг {rank}",
+ "hubNewsMedia": "News & media",
+ "hubSiteContent": "Site content",
+ "hubEngagement": "Engagement",
+ "hubUsers": "Users",
+ "hubAccess": "Access & security",
+ "hubCatalog": "Catalog & rares",
+ "hubShop": "Shop & payments",
+ "hubTools": "Tools",
+ "hubObservability": "Observability"
},
"dashboard": {
"title": "Табло за управление",
diff --git a/src/messages/cs.json b/src/messages/cs.json
index adba05ab96..2762045970 100644
--- a/src/messages/cs.json
+++ b/src/messages/cs.json
@@ -755,7 +755,16 @@
"backToSite": "Zpět na stránku",
"housekeeping": "Úklid",
"hotelManagementPanel": "Panel správy hotelu",
- "rankLabel": "Hodnost {rank}"
+ "rankLabel": "Hodnost {rank}",
+ "hubNewsMedia": "News & media",
+ "hubSiteContent": "Site content",
+ "hubEngagement": "Engagement",
+ "hubUsers": "Users",
+ "hubAccess": "Access & security",
+ "hubCatalog": "Catalog & rares",
+ "hubShop": "Shop & payments",
+ "hubTools": "Tools",
+ "hubObservability": "Observability"
},
"dashboard": {
"title": "Dashboard",
diff --git a/src/messages/da.json b/src/messages/da.json
index a12c74b05f..b25476d939 100644
--- a/src/messages/da.json
+++ b/src/messages/da.json
@@ -755,7 +755,16 @@
"backToSite": "Tilbage til webstedet",
"housekeeping": "Husholdning",
"hotelManagementPanel": "Hotel management panel",
- "rankLabel": "Rangering {rank}"
+ "rankLabel": "Rangering {rank}",
+ "hubNewsMedia": "News & media",
+ "hubSiteContent": "Site content",
+ "hubEngagement": "Engagement",
+ "hubUsers": "Users",
+ "hubAccess": "Access & security",
+ "hubCatalog": "Catalog & rares",
+ "hubShop": "Shop & payments",
+ "hubTools": "Tools",
+ "hubObservability": "Observability"
},
"dashboard": {
"title": "Dashboard",
diff --git a/src/messages/de.json b/src/messages/de.json
index 524a96bdb1..8d8b71672c 100644
--- a/src/messages/de.json
+++ b/src/messages/de.json
@@ -719,7 +719,16 @@
"backToSite": "Zurück zur Website",
"housekeeping": "Hausverwaltung",
"hotelManagementPanel": "Hotel-Verwaltungsbereich",
- "rankLabel": "Rang {rank}"
+ "rankLabel": "Rang {rank}",
+ "hubNewsMedia": "News & media",
+ "hubSiteContent": "Site content",
+ "hubEngagement": "Engagement",
+ "hubUsers": "Users",
+ "hubAccess": "Access & security",
+ "hubCatalog": "Catalog & rares",
+ "hubShop": "Shop & payments",
+ "hubTools": "Tools",
+ "hubObservability": "Observability"
},
"dashboard": {
"title": "Dashboard",
diff --git a/src/messages/el.json b/src/messages/el.json
index 5217cc6d4d..9fbcd213d5 100644
--- a/src/messages/el.json
+++ b/src/messages/el.json
@@ -755,7 +755,16 @@
"backToSite": "Επιστροφή στον ιστότοπο",
"housekeeping": "Οικονομία",
"hotelManagementPanel": "Πάνελ διαχείρισης ξενοδοχείου",
- "rankLabel": "Κατάταξη {rank}"
+ "rankLabel": "Κατάταξη {rank}",
+ "hubNewsMedia": "News & media",
+ "hubSiteContent": "Site content",
+ "hubEngagement": "Engagement",
+ "hubUsers": "Users",
+ "hubAccess": "Access & security",
+ "hubCatalog": "Catalog & rares",
+ "hubShop": "Shop & payments",
+ "hubTools": "Tools",
+ "hubObservability": "Observability"
},
"dashboard": {
"title": "Ταμπλό",
diff --git a/src/messages/en.json b/src/messages/en.json
index 2c847e1760..482bc15ad6 100644
--- a/src/messages/en.json
+++ b/src/messages/en.json
@@ -690,6 +690,9 @@
"overview": "Overview",
"dashboard": "Dashboard",
"content": "Content",
+ "hubNewsMedia": "News & media",
+ "hubSiteContent": "Site content",
+ "hubEngagement": "Engagement",
"articles": "Articles",
"tags": "Tags",
"navigator": "Navigator",
@@ -703,6 +706,8 @@
"banners": "Banners",
"prefixes": "Prefixes",
"usersAndAccess": "Users & access",
+ "hubUsers": "Users",
+ "hubAccess": "Access & security",
"users": "Users",
"bans": "Bans",
"ipManagement": "IP management",
@@ -713,6 +718,8 @@
"onlineUsers": "Online users",
"moderation": "Moderation",
"economy": "Economy",
+ "hubCatalog": "Catalog & rares",
+ "hubShop": "Shop & payments",
"catalog": "Catalog",
"shop": "Shop",
"transactions": "Transactions",
@@ -734,6 +741,8 @@
"radioRanks": "Ranks",
"radioAutodj": "Auto DJ",
"system": "System",
+ "hubTools": "Tools",
+ "hubObservability": "Observability",
"commandocentrum": "Commandocentrum",
"emulator": "Emulator",
"alerts": "Alerts",
diff --git a/src/messages/es.json b/src/messages/es.json
index 8d8e287cd4..df9282bdb0 100644
--- a/src/messages/es.json
+++ b/src/messages/es.json
@@ -719,7 +719,16 @@
"backToSite": "Volver al sitio",
"housekeeping": "Housekeeping",
"hotelManagementPanel": "Panel de gestión del hotel",
- "rankLabel": "Rango {rank}"
+ "rankLabel": "Rango {rank}",
+ "hubNewsMedia": "News & media",
+ "hubSiteContent": "Site content",
+ "hubEngagement": "Engagement",
+ "hubUsers": "Users",
+ "hubAccess": "Access & security",
+ "hubCatalog": "Catalog & rares",
+ "hubShop": "Shop & payments",
+ "hubTools": "Tools",
+ "hubObservability": "Observability"
},
"dashboard": {
"title": "Panel",
diff --git a/src/messages/fr.json b/src/messages/fr.json
index aeaf4c669f..9f0e6bbd54 100644
--- a/src/messages/fr.json
+++ b/src/messages/fr.json
@@ -719,7 +719,16 @@
"backToSite": "Retour au site",
"housekeeping": "Gouvernance",
"hotelManagementPanel": "Panneau de gestion de l'hôtel",
- "rankLabel": "Rang {rank}"
+ "rankLabel": "Rang {rank}",
+ "hubNewsMedia": "News & media",
+ "hubSiteContent": "Site content",
+ "hubEngagement": "Engagement",
+ "hubUsers": "Users",
+ "hubAccess": "Access & security",
+ "hubCatalog": "Catalog & rares",
+ "hubShop": "Shop & payments",
+ "hubTools": "Tools",
+ "hubObservability": "Observability"
},
"dashboard": {
"title": "Tableau de bord",
diff --git a/src/messages/hr.json b/src/messages/hr.json
index 76e929c9a4..d7547a43b7 100644
--- a/src/messages/hr.json
+++ b/src/messages/hr.json
@@ -755,7 +755,16 @@
"backToSite": "Povratak na stranicu",
"housekeeping": "Domaćinstvo",
"hotelManagementPanel": "Upravljačka ploča hotela",
- "rankLabel": "Rang {rank}"
+ "rankLabel": "Rang {rank}",
+ "hubNewsMedia": "News & media",
+ "hubSiteContent": "Site content",
+ "hubEngagement": "Engagement",
+ "hubUsers": "Users",
+ "hubAccess": "Access & security",
+ "hubCatalog": "Catalog & rares",
+ "hubShop": "Shop & payments",
+ "hubTools": "Tools",
+ "hubObservability": "Observability"
},
"dashboard": {
"title": "Nadzorna ploča",
diff --git a/src/messages/hu.json b/src/messages/hu.json
index 66e032194d..d7ba4e0150 100644
--- a/src/messages/hu.json
+++ b/src/messages/hu.json
@@ -755,7 +755,16 @@
"backToSite": "Vissza a webhelyre",
"housekeeping": "Takarítás",
"hotelManagementPanel": "Hotel menedzsment panel",
- "rankLabel": "rang {rank}"
+ "rankLabel": "rang {rank}",
+ "hubNewsMedia": "News & media",
+ "hubSiteContent": "Site content",
+ "hubEngagement": "Engagement",
+ "hubUsers": "Users",
+ "hubAccess": "Access & security",
+ "hubCatalog": "Catalog & rares",
+ "hubShop": "Shop & payments",
+ "hubTools": "Tools",
+ "hubObservability": "Observability"
},
"dashboard": {
"title": "Irányítópult",
diff --git a/src/messages/it.json b/src/messages/it.json
index f84008b0f6..252e0decef 100644
--- a/src/messages/it.json
+++ b/src/messages/it.json
@@ -719,7 +719,16 @@
"settings": "Impostazioni",
"backToSite": "Torna al sito",
"hotelManagementPanel": "Pannello di gestione hotel",
- "rankLabel": "Grado {rank}"
+ "rankLabel": "Grado {rank}",
+ "hubNewsMedia": "News & media",
+ "hubSiteContent": "Site content",
+ "hubEngagement": "Engagement",
+ "hubUsers": "Users",
+ "hubAccess": "Access & security",
+ "hubCatalog": "Catalog & rares",
+ "hubShop": "Shop & payments",
+ "hubTools": "Tools",
+ "hubObservability": "Observability"
},
"dashboard": {
"title": "Dashboard",
diff --git a/src/messages/nl.json b/src/messages/nl.json
index 400717cd64..6dea611c22 100644
--- a/src/messages/nl.json
+++ b/src/messages/nl.json
@@ -755,7 +755,16 @@
"backToSite": "Terug naar site",
"housekeeping": "Housekeeping",
"hotelManagementPanel": "Hotelbeheerpaneel",
- "rankLabel": "Rang {rank}"
+ "rankLabel": "Rang {rank}",
+ "hubNewsMedia": "News & media",
+ "hubSiteContent": "Site content",
+ "hubEngagement": "Engagement",
+ "hubUsers": "Users",
+ "hubAccess": "Access & security",
+ "hubCatalog": "Catalog & rares",
+ "hubShop": "Shop & payments",
+ "hubTools": "Tools",
+ "hubObservability": "Observability"
},
"dashboard": {
"title": "Dashboard",
diff --git a/src/messages/no.json b/src/messages/no.json
index e292c40863..b2adcf44da 100644
--- a/src/messages/no.json
+++ b/src/messages/no.json
@@ -755,7 +755,16 @@
"backToSite": "Tilbake til nettstedet",
"housekeeping": "Rengjøring",
"hotelManagementPanel": "Hotellstyringspanel",
- "rankLabel": "Rangering {rank}"
+ "rankLabel": "Rangering {rank}",
+ "hubNewsMedia": "News & media",
+ "hubSiteContent": "Site content",
+ "hubEngagement": "Engagement",
+ "hubUsers": "Users",
+ "hubAccess": "Access & security",
+ "hubCatalog": "Catalog & rares",
+ "hubShop": "Shop & payments",
+ "hubTools": "Tools",
+ "hubObservability": "Observability"
},
"dashboard": {
"title": "Dashbord",
diff --git a/src/messages/pl.json b/src/messages/pl.json
index f42224e613..b598744880 100644
--- a/src/messages/pl.json
+++ b/src/messages/pl.json
@@ -755,7 +755,16 @@
"backToSite": "Powrót do serwisu",
"housekeeping": "Sprzątanie",
"hotelManagementPanel": "Panel zarządzania hotelem",
- "rankLabel": "Ranga {rank}"
+ "rankLabel": "Ranga {rank}",
+ "hubNewsMedia": "News & media",
+ "hubSiteContent": "Site content",
+ "hubEngagement": "Engagement",
+ "hubUsers": "Users",
+ "hubAccess": "Access & security",
+ "hubCatalog": "Catalog & rares",
+ "hubShop": "Shop & payments",
+ "hubTools": "Tools",
+ "hubObservability": "Observability"
},
"dashboard": {
"title": "Pulpit nawigacyjny",
diff --git a/src/messages/pt.json b/src/messages/pt.json
index b0d108c304..e8d6baf095 100644
--- a/src/messages/pt.json
+++ b/src/messages/pt.json
@@ -755,7 +755,16 @@
"backToSite": "Voltar ao site",
"housekeeping": "Limpeza",
"hotelManagementPanel": "Painel de gestão hoteleira",
- "rankLabel": "Classificação {rank}"
+ "rankLabel": "Classificação {rank}",
+ "hubNewsMedia": "News & media",
+ "hubSiteContent": "Site content",
+ "hubEngagement": "Engagement",
+ "hubUsers": "Users",
+ "hubAccess": "Access & security",
+ "hubCatalog": "Catalog & rares",
+ "hubShop": "Shop & payments",
+ "hubTools": "Tools",
+ "hubObservability": "Observability"
},
"dashboard": {
"title": "Painel",
diff --git a/src/messages/ro.json b/src/messages/ro.json
index 821d86f492..353c29014c 100644
--- a/src/messages/ro.json
+++ b/src/messages/ro.json
@@ -755,7 +755,16 @@
"backToSite": "Înapoi la site",
"housekeeping": "Menaj",
"hotelManagementPanel": "Panoul de management al hotelului",
- "rankLabel": "Clasament {rank}"
+ "rankLabel": "Clasament {rank}",
+ "hubNewsMedia": "News & media",
+ "hubSiteContent": "Site content",
+ "hubEngagement": "Engagement",
+ "hubUsers": "Users",
+ "hubAccess": "Access & security",
+ "hubCatalog": "Catalog & rares",
+ "hubShop": "Shop & payments",
+ "hubTools": "Tools",
+ "hubObservability": "Observability"
},
"dashboard": {
"title": "Tabloul de bord",
diff --git a/src/messages/ru.json b/src/messages/ru.json
index bd38e723e3..8fcc5a8c74 100644
--- a/src/messages/ru.json
+++ b/src/messages/ru.json
@@ -755,7 +755,16 @@
"backToSite": "Вернуться на сайт",
"housekeeping": "Ведение домашнего хозяйства",
"hotelManagementPanel": "Панель управления отелем",
- "rankLabel": "Ранг {rank}"
+ "rankLabel": "Ранг {rank}",
+ "hubNewsMedia": "News & media",
+ "hubSiteContent": "Site content",
+ "hubEngagement": "Engagement",
+ "hubUsers": "Users",
+ "hubAccess": "Access & security",
+ "hubCatalog": "Catalog & rares",
+ "hubShop": "Shop & payments",
+ "hubTools": "Tools",
+ "hubObservability": "Observability"
},
"dashboard": {
"title": "Панель управления",
diff --git a/src/messages/sk.json b/src/messages/sk.json
index 97ed464f61..849fa3068d 100644
--- a/src/messages/sk.json
+++ b/src/messages/sk.json
@@ -755,7 +755,16 @@
"backToSite": "Späť na stránku",
"housekeeping": "Upratovanie",
"hotelManagementPanel": "Panel riadenia hotela",
- "rankLabel": "Hodnotenie {rank}"
+ "rankLabel": "Hodnotenie {rank}",
+ "hubNewsMedia": "News & media",
+ "hubSiteContent": "Site content",
+ "hubEngagement": "Engagement",
+ "hubUsers": "Users",
+ "hubAccess": "Access & security",
+ "hubCatalog": "Catalog & rares",
+ "hubShop": "Shop & payments",
+ "hubTools": "Tools",
+ "hubObservability": "Observability"
},
"dashboard": {
"title": "Dashboard",
diff --git a/src/messages/sr.json b/src/messages/sr.json
index 22e95ac6f4..7514a255d5 100644
--- a/src/messages/sr.json
+++ b/src/messages/sr.json
@@ -755,7 +755,16 @@
"backToSite": "Назад на сајт",
"housekeeping": "Домаћинство",
"hotelManagementPanel": "Панел за управљање хотелом",
- "rankLabel": "Ранг {rank}"
+ "rankLabel": "Ранг {rank}",
+ "hubNewsMedia": "News & media",
+ "hubSiteContent": "Site content",
+ "hubEngagement": "Engagement",
+ "hubUsers": "Users",
+ "hubAccess": "Access & security",
+ "hubCatalog": "Catalog & rares",
+ "hubShop": "Shop & payments",
+ "hubTools": "Tools",
+ "hubObservability": "Observability"
},
"dashboard": {
"title": "Дасхбоард",
diff --git a/src/messages/sv.json b/src/messages/sv.json
index fc9f492714..3d4507a376 100644
--- a/src/messages/sv.json
+++ b/src/messages/sv.json
@@ -755,7 +755,16 @@
"backToSite": "Tillbaka till webbplatsen",
"housekeeping": "Städning",
"hotelManagementPanel": "Hotellledningspanel",
- "rankLabel": "Rank {rank}"
+ "rankLabel": "Rank {rank}",
+ "hubNewsMedia": "News & media",
+ "hubSiteContent": "Site content",
+ "hubEngagement": "Engagement",
+ "hubUsers": "Users",
+ "hubAccess": "Access & security",
+ "hubCatalog": "Catalog & rares",
+ "hubShop": "Shop & payments",
+ "hubTools": "Tools",
+ "hubObservability": "Observability"
},
"dashboard": {
"title": "Instrumentbräda",
diff --git a/src/messages/tr.json b/src/messages/tr.json
index c215089d7d..5c0915eccc 100644
--- a/src/messages/tr.json
+++ b/src/messages/tr.json
@@ -755,7 +755,16 @@
"backToSite": "Siteye geri dön",
"housekeeping": "Temizlik",
"hotelManagementPanel": "Otel yönetim paneli",
- "rankLabel": "Sıra {rank}"
+ "rankLabel": "Sıra {rank}",
+ "hubNewsMedia": "News & media",
+ "hubSiteContent": "Site content",
+ "hubEngagement": "Engagement",
+ "hubUsers": "Users",
+ "hubAccess": "Access & security",
+ "hubCatalog": "Catalog & rares",
+ "hubShop": "Shop & payments",
+ "hubTools": "Tools",
+ "hubObservability": "Observability"
},
"dashboard": {
"title": "Kontrol Paneli",
diff --git a/src/messages/uk.json b/src/messages/uk.json
index 1089e6f9d9..364cafc8ad 100644
--- a/src/messages/uk.json
+++ b/src/messages/uk.json
@@ -755,7 +755,16 @@
"backToSite": "Повернутися на сайт",
"housekeeping": "Прибирання",
"hotelManagementPanel": "Панель управління готелем",
- "rankLabel": "Рейтинг {rank}"
+ "rankLabel": "Рейтинг {rank}",
+ "hubNewsMedia": "News & media",
+ "hubSiteContent": "Site content",
+ "hubEngagement": "Engagement",
+ "hubUsers": "Users",
+ "hubAccess": "Access & security",
+ "hubCatalog": "Catalog & rares",
+ "hubShop": "Shop & payments",
+ "hubTools": "Tools",
+ "hubObservability": "Observability"
},
"dashboard": {
"title": "Приладова панель",