diff --git a/src/components/admin/admin-layout.tsx b/src/components/admin/admin-layout.tsx index da1df21..de7ae4f 100644 --- a/src/components/admin/admin-layout.tsx +++ b/src/components/admin/admin-layout.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useState } from 'react'; +import { useState, useEffect, useRef } from 'react'; import Link from 'next/link'; import { usePathname, useRouter } from 'next/navigation'; import { useAuth } from './auth-context'; @@ -82,11 +82,48 @@ const menuItems = [ export function AdminLayout({ children }: { children: React.ReactNode }) { const [sidebarOpen, setSidebarOpen] = useState(false); - const [expandedMenus, setExpandedMenus] = useState>(new Set(['内容管理'])); const { user, logout } = useAuth(); const pathname = usePathname(); const router = useRouter(); + const isActive = (href: string) => pathname === href || pathname?.startsWith(href + '/'); + + /** + * 根据当前路径自动展开对应的父菜单组 + */ + const getExpandedMenusForPath = (_path: string): Set => { + const result = new Set(); + for (const group of menuItems) { + for (const item of group.children) { + if (isActive(item.href)) { + result.add(group.label); + break; + } + } + } + // 若当前路径在某个组内,保留已有展开状态并追加;否则保留默认展开 + if (result.size > 0) { + return result; + } + return new Set(['内容管理']); + }; + + const [expandedMenus, setExpandedMenus] = useState>(() => getExpandedMenusForPath(pathname)); + + // 路径变化时自动展开对应父菜单组 + const prevPathname = useRef(pathname); + useEffect(() => { + if (prevPathname.current !== pathname) { + prevPathname.current = pathname; + const menusForPath = getExpandedMenusForPath(pathname); + setExpandedMenus((prev) => { + const next = new Set(prev); + menusForPath.forEach((label) => next.add(label)); + return next; + }); + } + }, [pathname]); + const toggleMenu = (label: string) => { setExpandedMenus((prev) => { const next = new Set(prev); @@ -101,8 +138,6 @@ export function AdminLayout({ children }: { children: React.ReactNode }) { router.push('/admin/login'); }; - const isActive = (href: string) => pathname === href || pathname?.startsWith(href + '/'); - return (
{/* Mobile overlay */} @@ -146,11 +181,17 @@ export function AdminLayout({ children }: { children: React.ReactNode }) { {/* Menu groups */} - {menuItems.map((group) => ( + {menuItems.map((group) => { + const hasActiveChild = group.children.some((item) => isActive(item.href)); + return (
)}
- ))} + ); + })} {/* User info */}