import { AppShell, Burger, Group, Tooltip, UnstyledButton, Title, useMantineTheme, } from '@mantine/core'; import { useDisclosure, useMediaQuery } from '@mantine/hooks'; import { useEffect, useMemo, useRef, useState } from 'react'; import { Link, useLocation, useNavigate } from 'react-router-dom'; import { default as LogoIcon } from '../../assets/icons/favicon'; import { mainLinksdata } from '../../data/navigationsLinks_1'; import { submenuLinks } from '../../data/submenuLinks_1'; import classes from './Appshell.module.css'; type AppShellWithMenuProps = { children?: React.ReactNode; }; // Persistencia en localStorage const STORAGE_KEY = 'lastSubmenuRoutes'; function getLastSubmenuRoute(section: string): string | null { try { const raw = localStorage.getItem(STORAGE_KEY); const parsed = raw ? JSON.parse(raw) : {}; return parsed[section] ?? null; } catch { return null; } } function setLastSubmenuRoute(section: string, route: string) { try { const raw = localStorage.getItem(STORAGE_KEY); const parsed = raw ? JSON.parse(raw) : {}; parsed[section] = route; localStorage.setItem(STORAGE_KEY, JSON.stringify(parsed)); } catch { // fallback silencioso } } export function AppShellWithMenu({ children }: AppShellWithMenuProps) { const theme = useMantineTheme(); const location = useLocation(); const navigate = useNavigate(); const isMobile = useMediaQuery('(max-width: 768px)'); const [mobileOpened, { toggle: toggleMobile, close: closeMobile }] = useDisclosure(false); const [desktopOpened, { toggle: toggleDesktop, open: openDesktop }] = useDisclosure(true); const isCollapsed = useMemo( () => (isMobile ? !mobileOpened : !desktopOpened), [isMobile, mobileOpened, desktopOpened] ); // Estado para el main link activo const [activeMain, setActiveMain] = useState('Home'); // Ref para saber si el usuario ha hecho clic manualmente en el main link const userClickedMainRef = useRef(false); useEffect(() => { const currentPath = location.pathname.toLowerCase().replace(/\/$/, ''); let matchedMain: string | null = null; let maxMatchLength = 0; Object.entries(submenuLinks).forEach(([main, items]) => { items.forEach((item) => { const itemPath = item.to.toLowerCase().replace(/\/$/, ''); if ( currentPath === itemPath || currentPath.startsWith(itemPath + '/') ) { if (itemPath.length > maxMatchLength) { matchedMain = main; maxMatchLength = itemPath.length; } } }); }); if (matchedMain) { setActiveMain(matchedMain); } }, [location.pathname]); const activeLink = submenuLinks[activeMain as keyof typeof submenuLinks]?.find( (item) => item.to === location.pathname )?.label ?? ''; const mainLinks = mainLinksdata.map((link) => ( { userClickedMainRef.current = true; setActiveMain(link.label); const remembered = getLastSubmenuRoute(link.label); const fallback = submenuLinks[link.label as keyof typeof submenuLinks]?.[0]?.to; if (isCollapsed && (remembered || fallback)) { navigate(remembered ?? fallback); } }} className={classes.mainLink} data-active={link.label === activeMain || undefined} > )); const links = (submenuLinks[activeMain as keyof typeof submenuLinks] || []).map((item) => ( { setLastSubmenuRoute(activeMain, item.to); if (isMobile) closeMobile(); }} > {item.label} )); useEffect(() => { if (!isMobile) openDesktop(); }, [isMobile, openDesktop]); return ( {/* Header */} {/* Navbar */}
{mainLinks}
{!isCollapsed && ( {activeMain} )} {links}
{/* Main Content */} {children}
); }