diff --git a/src/components/nav-sidebar/nav-main.tsx b/src/components/nav-sidebar/nav-main.tsx index d631bf0..62fca62 100644 --- a/src/components/nav-sidebar/nav-main.tsx +++ b/src/components/nav-sidebar/nav-main.tsx @@ -1,4 +1,6 @@ -import { ChevronRight } from "lucide-react" +import { useAtom } from "jotai" +import { ChevronRight, Maximize2, Minimize2 } from "lucide-react" +import { useEffect, useMemo } from "react" import { useTranslation } from "react-i18next" import { Link, useLocation } from "react-router-dom" @@ -19,6 +21,7 @@ import { SidebarMenuSubItem, } from "@/components/ui/sidebar" import type { IMenu } from "@/models/menu" +import { navOpenItemsAtom } from "@/store/nav" export function NavMain({ items, @@ -27,24 +30,79 @@ export function NavMain({ }) { const { t } = useTranslation("navigation") const location = useLocation() + const [openItems, setOpenItems] = useAtom(navOpenItemsAtom) - const isPathActive = (path: string) => { - return location.pathname === path || location.pathname.startsWith(`${path}/`) + const { isPathActive, isParentActive } = useMemo(() => { + const isPathActive = (path: string) => { + return location.pathname === path || location.pathname.startsWith(`${path}/`) + } + + const isParentActive = (item: IMenu) => { + return item.children?.some((child) => isPathActive(child.to)) + } + + return { isPathActive, isParentActive } + }, [location.pathname]) + + useEffect(() => { + const newOpenItems: Record = { ...openItems } + let hasChanges = false + + items.forEach((item) => { + const shouldBeOpen = isPathActive(item.to) || isParentActive(item) + if (shouldBeOpen && !newOpenItems[item.title]) { + newOpenItems[item.title] = true + hasChanges = true + } + }) + + if (hasChanges) { + setOpenItems(newOpenItems) + } + }, [location.pathname, items, isPathActive, isParentActive, setOpenItems, openItems]) + + const handleToggle = (title: string) => { + setOpenItems((prev) => ({ + ...prev, + [title]: !prev[title], + })) } - const isParentActive = (item: IMenu) => { - return item.children?.some((child) => isPathActive(child.to)) + const handleToggleAll = () => { + const allExpanded = items.every((item) => openItems[item.title]) + const newOpenItems: Record = {} + + items.forEach((item) => { + newOpenItems[item.title] = !allExpanded + }) + + setOpenItems(newOpenItems) } return ( - Platform +
+ Platform + +
{items.map((item) => ( handleToggle(item.title)} > >("nav-open-items", {})