diff --git a/panel/src/App.tsx b/panel/src/App.tsx index fa55429..ff1d4df 100644 --- a/panel/src/App.tsx +++ b/panel/src/App.tsx @@ -10,10 +10,8 @@ import { Dashboard } from "@/pages/Dashboard"; import { MyServers } from "@/pages/MyServers"; import { ServerConsole } from "@/pages/ServerConsole"; import { Account } from "@/pages/Account"; -import { AdminHome } from "@/pages/admin/AdminHome"; import { ServerAdmin } from "@/pages/admin/ServerAdmin"; import { ImageAdmin } from "@/pages/admin/ImageAdmin"; -import { OpsOverview } from "@/pages/ops/OpsOverview"; import { FleetTable } from "@/pages/ops/FleetTable"; // Three UX surfaces over two Zero-Trust tiers (DESIGN-WEB-3SIDES): @@ -45,16 +43,19 @@ export default function App() { } /> } /> - {/* Admin-Side — admin-tier (server & content ops) */} + {/* Admin-Side — admin-tier (server & content ops). + /admin has no landing page; redirect to the first concrete view + so the section root and any stale bookmarks land somewhere useful. */} }> - } /> + } /> } /> } /> - {/* SysAdmin-Side — admin-tier (platform observability) */} + {/* SysAdmin-Side — admin-tier (platform observability). + Same redirect treatment as /admin — fleet is the meaningful view. */} }> - } /> + } /> } /> diff --git a/panel/src/components/AppShell.tsx b/panel/src/components/AppShell.tsx index 6ceb0ad..85858d9 100644 --- a/panel/src/components/AppShell.tsx +++ b/panel/src/components/AppShell.tsx @@ -5,10 +5,49 @@ import { useTranslation } from "react-i18next"; import * as SelectPrimitive from "@radix-ui/react-select"; import { cn } from "@/lib/utils"; import { useTier } from "@/lib/tier"; -import { visibleSections } from "@/lib/nav"; +import { visibleSections, type NavSection } from "@/lib/nav"; import { Select, SelectContent, SelectItem } from "@/components/ui/select"; import { useTheme } from "@/lib/theme"; +function SectionGroup({ section, isFirst }: { section: NavSection; isFirst: boolean }) { + const { t } = useTranslation("navigation"); + + return ( +
+ {section.titleKey && ( +
+ {t(section.titleKey)} +
+ )} + {section.items.map((item) => ( + + cn( + "flex items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition-colors", + isActive + ? "bg-primary/15 text-primary" + : "text-muted-foreground hover:bg-accent hover:text-foreground", + ) + } + > + + {t(item.key)} + + ))} +
+ ); +} + function LangToggle() { const { i18n } = useTranslation(); @@ -67,33 +106,9 @@ export function AppShell() { {t("common:brand_name")} -