import React, { useState, useEffect } from 'react'; import { HashRouter as Router, Routes, Route, Link, useLocation } from 'react-router-dom'; import { Bot, Book, User, LayoutDashboard, Mic2, Video, GitBranch, Zap, PanelLeftClose, PanelLeftOpen, History as HistoryIcon, ChevronDown, ChevronRight, Box, Wand2, Wrench, BrainCircuit, AudioLines } from 'lucide-react'; import { AssistantsPage } from './pages/Assistants'; import { KnowledgeBasePage } from './pages/KnowledgeBase'; import { HistoryPage } from './pages/History'; import { ProfilePage } from './pages/Profile'; import { DashboardPage } from './pages/Dashboard'; import { VoiceLibraryPage } from './pages/VoiceLibrary'; import { WorkflowsPage } from './pages/Workflows'; import { WorkflowEditorPage } from './pages/WorkflowEditor'; import { AutoTestPage } from './pages/AutoTest'; import { ToolLibraryPage } from './pages/ToolLibrary'; import { LLMLibraryPage } from './pages/LLMLibrary'; import { ASRLibraryPage } from './pages/ASRLibrary'; type NavItemType = { path: string; label: string; icon: React.ReactNode; children?: NavItemType[]; }; const SidebarItem: React.FC<{ item: NavItemType; isActive: boolean; isCollapsed: boolean; onExpand: () => void; }> = ({ item, isActive, isCollapsed, onExpand }) => { const location = useLocation(); const [isOpen, setIsOpen] = useState(false); const hasChildren = item.children && item.children.length > 0; // Check if any child is active to auto-expand const isChildActive = hasChildren && item.children!.some(child => location.pathname.startsWith(child.path)); useEffect(() => { if (isChildActive) { setIsOpen(true); } }, [isChildActive]); const handleClick = (e: React.MouseEvent) => { if (hasChildren) { e.preventDefault(); if (isCollapsed) { onExpand(); setIsOpen(true); } else { setIsOpen(!isOpen); } } }; const activeClass = "bg-primary/20 text-primary border-r-2 border-primary"; const inactiveClass = "text-muted-foreground hover:bg-muted/50 hover:text-foreground"; if (hasChildren) { return (
{item.icon}
{!isCollapsed && {item.label}}
{!isCollapsed && (
{isOpen ? : }
)}
{!isCollapsed && isOpen && (
{item.children!.map(child => { const childActive = location.pathname.startsWith(child.path); return (
{child.icon}
{child.label} ); })}
)}
); } return (
{item.icon}
{!isCollapsed && {item.label}} ); }; const AppLayout: React.FC<{ children: React.ReactNode }> = ({ children }) => { const location = useLocation(); const [isCollapsed, setIsCollapsed] = useState(false); const navItems: NavItemType[] = [ { path: '/', label: '首页', icon: }, { path: '#creation', label: '创建助手', icon: , children: [ { path: '/assistants', label: '小助手', icon: }, { path: '/workflows', label: '工作流', icon: }, ] }, { path: '/history', label: '历史记录', icon: }, { path: '/auto-test', label: '测试助手', icon: }, { path: '#components', label: '组件库', icon: , children: [ { path: '/llms', label: '大模型库', icon: }, { path: '/asr', label: '语音识别', icon: }, { path: '/voices', label: '声音库', icon: }, { path: '/knowledge', label: '知识库', icon: }, { path: '/tools', label: '工具库', icon: }, ] }, { path: '/profile', label: '个人中心', icon: }, ]; return (
{/* Sidebar with Glass effect and collapse logic */} {/* Main Content */}
AI视频助手
{children}
); }; const App: React.FC = () => { return ( } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> ); }; export default App;