import React, { useState, useEffect } from "react";
import { Link, Outlet, useNavigate, useLocation } from "react-router-dom";
import { useAuth } from "@/contexts/AuthContext";
import {
Package,
ChevronLeft,
ChevronRight,
User,
LogOut,
CirclePlay,
CircleArrowRight,
SquareArrowRight,
SquarePlay,
SquareDot,
CircleDot,
SquareAsterisk,
KeyRound,
Home,
} from "lucide-react";
// Color mappings for navigation items — defined outside component for stable reference
const colorClasses = {
gray: {
inactive: "text-gray-300 hover:text-white hover:bg-gray-800",
active: "bg-gray-800 text-white",
icon: "text-gray-400",
},
cyan: {
inactive: "text-cyan-300 hover:text-cyan-100 hover:bg-cyan-950/30",
active: "bg-cyan-950/50 text-cyan-100 shadow-lg shadow-cyan-900/50",
icon: "text-cyan-400",
},
blue: {
inactive: "text-blue-300 hover:text-blue-100 hover:bg-blue-950/30",
active: "bg-blue-950/50 text-blue-100 shadow-lg shadow-blue-900/50",
icon: "text-blue-400",
},
violet: {
inactive: "text-violet-300 hover:text-violet-100 hover:bg-violet-950/30",
active: "bg-violet-950/50 text-violet-100 shadow-lg shadow-violet-900/50",
icon: "text-violet-400",
},
purple: {
inactive: "text-purple-300 hover:text-purple-100 hover:bg-purple-950/30",
active: "bg-purple-950/50 text-purple-100 shadow-lg shadow-purple-900/50",
icon: "text-purple-400",
},
fuchsia: {
inactive: "text-fuchsia-300 hover:text-fuchsia-100 hover:bg-fuchsia-950/30",
active:
"bg-fuchsia-950/50 text-fuchsia-100 shadow-lg shadow-fuchsia-900/50",
icon: "text-fuchsia-400",
},
rose: {
inactive: "text-rose-300 hover:text-rose-100 hover:bg-rose-950/30",
active: "bg-rose-950/50 text-rose-100 shadow-lg shadow-rose-900/50",
icon: "text-rose-400",
},
orange: {
inactive: "text-orange-300 hover:text-orange-100 hover:bg-orange-950/30",
active: "bg-orange-950/50 text-orange-100 shadow-lg shadow-orange-900/50",
icon: "text-orange-400",
},
};
// Navigation sections with dividers and colors
const navSections = [
{
items: [{ to: "/", label: "Dashboard", icon: Home, color: "gray" }],
},
{
// Component Management - Cool colors (cyan -> blue -> violet)
items: [
{ to: "/actions", label: "Actions", icon: SquarePlay, color: "cyan" },
{ to: "/rules", label: "Rules", icon: SquareArrowRight, color: "blue" },
{
to: "/triggers",
label: "Triggers",
icon: SquareDot,
color: "violet",
},
{
to: "/sensors",
label: "Sensors",
icon: SquareAsterisk,
color: "purple",
},
],
},
{
// Runtime Logs - Warm colors (fuchsia -> rose -> orange)
items: [
{
to: "/executions",
label: "Execution History",
icon: CirclePlay,
color: "fuchsia",
},
{
to: "/enforcements",
label: "Enforcement History",
icon: CircleArrowRight,
color: "rose",
},
{
to: "/events",
label: "Event History",
icon: CircleDot,
color: "orange",
},
],
},
{
items: [
{ to: "/keys", label: "Keys & Secrets", icon: KeyRound, color: "gray" },
{
to: "/packs",
label: "Pack Management",
icon: Package,
color: "gray",
},
],
},
];
// NavLink extracted outside MainLayout so React preserves DOM identity across
// re-renders, which is required for CSS transitions to work on collapse/expand.
function NavLink({
to,
label,
icon: Icon,
color = "gray",
isCollapsed,
isActive,
}: {
to: string;
label: string;
icon: React.ElementType;
color?: string;
isCollapsed: boolean;
isActive: boolean;
}) {
const colors =
colorClasses[color as keyof typeof colorClasses] || colorClasses.gray;
return (
{user?.login}
{user?.login}