import { useState } from "react";
import { Link, useLocation } from "react-router";
import { Box, Drawer } from "@mui/material";
import { BrandLockup, BrandMark } from "@/components/common/brand-lockup";
import { getActiveNavPath, getSidebarWidth, navGroups, type NavItemDef } from "@/config/menu";
function getNavItemAppearance(isActive: boolean, isHover: boolean) {
if (isActive) {
return {
itemColor: "var(--primary)",
iconColor: "var(--primary)",
itemBg: "var(--color-sidebar-item-active-bg)",
};
}
if (isHover) {
return {
itemColor: "var(--primary-hover)",
iconColor: "var(--primary-hover)",
itemBg: "var(--sidebar-accent)",
};
}
return {
itemColor: "var(--foreground)",
iconColor: "var(--muted-foreground)",
itemBg: "transparent",
};
}
type NavItemProps = NavItemDef & {
collapsed: boolean;
active: boolean;
onNavigate?: () => void;
};
function NavItem({ label, icon: Icon, path, collapsed, active, badge, onNavigate }: NavItemProps) {
const [hovered, setHovered] = useState(false);
const isHover = hovered && !active;
const { itemColor, iconColor, itemBg } = getNavItemAppearance(active, isHover);
return (
setHovered(true)}
onMouseLeave={() => setHovered(false)}
sx={{
position: "relative",
display: "flex",
alignItems: "center",
width: "100%",
height: 40,
gap: "12px",
px: collapsed ? 0 : "12px",
justifyContent: collapsed ? "center" : "flex-start",
borderRadius: "6px",
cursor: "pointer",
fontFamily: "var(--font-sans)",
fontSize: 14,
fontWeight: active ? 600 : 500,
color: itemColor,
backgroundColor: itemBg,
boxShadow: active ? "var(--color-sidebar-item-active-shadow)" : "none",
transition: "all var(--duration-fast, 150ms) var(--ease-default, ease)",
mb: "4px",
textAlign: "left",
}}
>
{active && (
)}
{!collapsed && (
<>
{label}
{badge != null && (
{badge}
)}
>
)}
);
}
type AppSidebarProps = {
collapsed: boolean;
mobile?: boolean;
open?: boolean;
onClose?: () => void;
};
export function AppSidebar({ collapsed, mobile = false, open = true, onClose }: AppSidebarProps) {
const width = getSidebarWidth(collapsed);
const { pathname } = useLocation();
const activePath = getActiveNavPath(pathname);
return (
{collapsed ? : }
{navGroups.map((group, groupIndex) => (
{collapsed ? (
groupIndex > 0 && (
)
) : group.title ? (
{group.title}
) : (
)}
{group.items.map(({ label, icon, path, badge }) => (
))}
))}
);
}