/** * Sidebar - 侧边栏导航组件(Task 1.3) * * 功能: * - 分组导航菜单(创作工具 / 资源管理 / 系统) * - 每个菜单项:图标 + 文字 * - 当前页面对应菜单项高亮(基于路由匹配) * - 点击跳转路由 * - 折叠态:仅显示图标,隐藏文字(通过 SidebarContext 读取 collapsed 状态) * - 响应式:移动端自动折叠 */ import React, { useContext } from "react"; import { useLocation, useNavigate } from "react-router-dom"; import { DashboardOutlined, VideoCameraOutlined, FileOutlined, AudioOutlined, FileTextOutlined, TrophyOutlined, AppstoreOutlined, HistoryOutlined, ControlOutlined, CrownOutlined, } from "@ant-design/icons"; import { SidebarContext } from "./MainLayout"; import "./Sidebar.css"; /** 导航项定义 */ interface SidebarMenuItem { key: string; label: string; path: string; icon: React.ReactNode; } /** 导航分组定义 */ interface SidebarMenuGroup { title: string; items: SidebarMenuItem[]; } /** 侧边栏导航分组 */ const MENU_GROUPS: SidebarMenuGroup[] = [ { title: "创作工具", items: [ { key: "dashboard", label: "首页", path: "/dashboard", icon: , }, { key: "generate", label: "一键生成", path: "/generate", icon: , }, ], }, { title: "资源管理", items: [ { key: "assets", label: "素材库", path: "/assets", icon: , }, { key: "voices", label: "配音库", path: "/voices", icon: , }, { key: "titles", label: "标题库", path: "/titles", icon: , }, { key: "products", label: "成片库", path: "/products", icon: , }, { key: "templates", label: "模板库", path: "/templates", icon: , }, ], }, { title: "系统", items: [ { key: "history", label: "任务历史", path: "/history", icon: , }, { key: "admin", label: "控制台", path: "/admin", icon: , }, { key: "subscription", label: "订阅管理", path: "/subscription", icon: , }, ], }, ]; /** 判断菜单项是否激活 */ const isMenuItemActive = (pathname: string, path: string): boolean => { if (path === "/dashboard") { return pathname === "/" || pathname === "/dashboard"; } return pathname.startsWith(path); }; const Sidebar: React.FC = () => { const { collapsed } = useContext(SidebarContext); const location = useLocation(); const navigate = useNavigate(); const handleNavigate = (path: string) => { navigate(path); }; return (
{MENU_GROUPS.map((group) => (
{!collapsed && (
{group.title}
)}
    {group.items.map((item) => { const active = isMenuItemActive(location.pathname, item.path); return (
  • handleNavigate(item.path)} > {item.icon} {!collapsed && ( {item.label} )}
  • ); })}
))}
); }; export default Sidebar;