From 926a1b81658508c6da50b0dc7f9ac3b1a15fe515 Mon Sep 17 00:00:00 2001 From: nessi Date: Thu, 9 Jul 2026 14:58:15 +0200 Subject: [PATCH] feat: redesign sidebar navigation with grouped sections, improved visual hierarchy, and enhanced active state indicators Restructure navigation into three logical groups (Operate, Network, Security) with uppercase section labels, move system-related items (Jobs, Audit, Users, Settings) to separate bottom section with border separator, add NF logo badge next to app title in header, extract SidebarLink component with refined styling including left accent bar for active items, update active state to --- frontend/src/components/Layout.tsx | 115 ++++++++++++++++++++--------- 1 file changed, 81 insertions(+), 34 deletions(-) diff --git a/frontend/src/components/Layout.tsx b/frontend/src/components/Layout.tsx index 240c35d..98f135b 100644 --- a/frontend/src/components/Layout.tsx +++ b/frontend/src/components/Layout.tsx @@ -18,31 +18,76 @@ import { SquareStack, Sun, Users, + type LucideIcon, } from "lucide-react"; import { useEffect } from "react"; import { token } from "../api/client"; import { useTheme } from "../stores/theme"; -const nav = [ - { to: "/", label: "Dashboard", icon: LayoutDashboard }, - { to: "/clusters", label: "Clusters", icon: Server }, - { to: "/nodes", label: "Nodes", icon: Activity }, - { to: "/workloads", label: "VMs/LXCs", icon: Blocks }, - { to: "/networks", label: "Networks", icon: Network }, - { to: "/ipam", label: "IPAM", icon: Database }, - { to: "/tenants", label: "Tenants", icon: BriefcaseBusiness }, - { to: "/security-groups", label: "Security Groups", icon: Shield }, - { to: "/policies", label: "Policies", icon: GitBranch }, - { to: "/services", label: "Service Catalog", icon: SquareStack }, - { to: "/designer", label: "Policy Designer", icon: LockKeyhole }, - { to: "/firewall", label: "Firewall Preview", icon: Flame }, +const navGroups = [ + { + label: "Operate", + items: [ + { to: "/", label: "Dashboard", icon: LayoutDashboard }, + { to: "/clusters", label: "Clusters", icon: Server }, + { to: "/nodes", label: "Nodes", icon: Activity }, + { to: "/workloads", label: "VMs/LXCs", icon: Blocks }, + ], + }, + { + label: "Network", + items: [ + { to: "/networks", label: "Networks", icon: Network }, + { to: "/ipam", label: "IPAM", icon: Database }, + { to: "/services", label: "Service Catalog", icon: SquareStack }, + { to: "/tenants", label: "Tenants", icon: BriefcaseBusiness }, + ], + }, + { + label: "Security", + items: [ + { to: "/security-groups", label: "Security Groups", icon: Shield }, + { to: "/policies", label: "Policies", icon: GitBranch }, + { to: "/designer", label: "Policy Designer", icon: LockKeyhole }, + { to: "/firewall", label: "Firewall Preview", icon: Flame }, + ], + }, +]; + +const systemNav = [ { to: "/jobs", label: "Jobs", icon: ClipboardList }, { to: "/audit", label: "Audit Logs", icon: BookOpen }, { to: "/users", label: "Users", icon: Users }, { to: "/settings", label: "Settings", icon: Settings }, ]; +function SidebarLink({ item }: { item: { to: string; label: string; icon: LucideIcon } }) { + const Icon = item.icon; + return ( + + `group relative flex h-9 items-center gap-3 rounded-md px-3 text-sm transition-colors ${ + isActive + ? "bg-accent/10 text-accent dark:bg-accent/15" + : "text-slate-600 hover:bg-slate-100 hover:text-slate-950 dark:text-slate-300 dark:hover:bg-slate-800/80 dark:hover:text-white" + }` + } + > + {({ isActive }) => ( + <> + + + {item.label} + + )} + + ); +} + export function Layout() { const navigate = useNavigate(); const { dark, toggle } = useTheme(); @@ -60,29 +105,31 @@ export function Layout() {