diff --git a/apps/web/src/layout/app-sidebar-nav.tsx b/apps/web/src/layout/app-sidebar-nav.tsx index 6f700ac2..b9a646aa 100644 --- a/apps/web/src/layout/app-sidebar-nav.tsx +++ b/apps/web/src/layout/app-sidebar-nav.tsx @@ -8,13 +8,20 @@ import { SidebarMenu, SidebarMenuButton, SidebarMenuItem, + SidebarMenuSub, + SidebarMenuSubButton, + SidebarMenuSubItem, } from "@repo/shadcn-ui/components"; import { cn } from "@repo/shadcn-ui/lib/utils"; import { ChevronDownIcon } from "lucide-react"; import * as React from "react"; -import { Link } from "react-router-dom"; +import { Link, useLocation } from "react-router-dom"; -import type { AppSidebarNavSection, AppSidebarSectionAccent } from "./app-sidebar.config"; +import type { + AppSidebarNavItem, + AppSidebarNavSection, + AppSidebarSectionAccent, +} from "./app-sidebar.config"; interface AppSidebarNavProps { sections: AppSidebarNavSection[]; @@ -29,9 +36,11 @@ interface SidebarSectionAccentStyles { } export const AppSidebarNav = ({ sections }: AppSidebarNavProps) => { + const { pathname } = useLocation(); const [openSections, setOpenSections] = React.useState>(() => Object.fromEntries(sections.map((s) => [s.title, true])) ); + const [openItems, setOpenItems] = React.useState>({}); const sectionAccentStyles: Record = { blue: { @@ -67,6 +76,25 @@ export const AppSidebarNav = ({ sections }: AppSidebarNavProps) => { }, }; + const isRouteActive = React.useCallback( + (item: AppSidebarNavItem): boolean => { + if (item.items?.length) { + return item.items.some((child) => isRouteActive(child)); + } + + if (!item.href) { + return false; + } + + if (item.exact) { + return pathname === item.href; + } + + return pathname === item.href || pathname.startsWith(`${item.href}/`); + }, + [pathname] + ); + return (