22301008 | af17315 | 2025-06-15 10:46:25 +0800 | [diff] [blame] | 1 | import React, { useState, useEffect } from 'react' |
| 2 | import { NavLink, useLocation, useNavigate } from 'react-router-dom' |
| 3 | import { |
| 4 | Home, |
| 5 | BookOpen, |
| 6 | BarChart3, |
| 7 | Activity, |
| 8 | Users, |
| 9 | ChevronDown, |
| 10 | } from 'lucide-react' |
| 11 | |
| 12 | |
| 13 | const menuItems = [ |
| 14 | { id: 'home', label: '首页', icon: Home, path: '/home' }, |
| 15 | { id: 'notebooks', label: '笔记管理', icon: BookOpen, path: '/notebooks' }, |
| 16 | { |
| 17 | id: 'dashboard', |
| 18 | label: '数据看板', |
| 19 | icon: BarChart3, |
| 20 | path: '/dashboard', |
| 21 | submenu: [ |
| 22 | { id: 'overview', label: '账号概况', path: '/dashboard/overview' }, |
| 23 | { id: 'content', label: '内容分析', path: '/dashboard/content' }, |
| 24 | { id: 'fans', label: '粉丝数据', path: '/dashboard/fans' }, |
| 25 | ] |
| 26 | }, |
| 27 | { id: 'activity', label: '活动中心', icon: Activity, path: '/activity' }, |
| 28 | { id: 'notes', label: '笔记灵感', icon: BookOpen, path: '/notes' }, |
| 29 | { id: 'creator', label: '创作学院', icon: Users, path: '/creator' }, |
| 30 | { id: 'journal', label: '创作日刊', icon: BookOpen, path: '/journal' }, |
| 31 | ] |
| 32 | |
| 33 | export default function Sidebar() { |
| 34 | const [expandedMenu, setExpandedMenu] = useState(null) |
| 35 | const location = useLocation() |
| 36 | const navigate = useNavigate() |
| 37 | |
| 38 | useEffect(() => { |
| 39 | if (location.pathname.startsWith('/dashboard')) { |
| 40 | setExpandedMenu('dashboard') |
| 41 | } |
| 42 | }, [location.pathname]) |
| 43 | |
| 44 | const toggleMenu = item => { |
| 45 | if (item.submenu) { |
| 46 | setExpandedMenu(expandedMenu === item.id ? null : item.id) |
| 47 | } else { |
| 48 | navigate(item.path) |
| 49 | setExpandedMenu(null) |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | return ( |
| 54 | <aside className="sidebar"> |
| 55 | <button className="publish-btn">发布笔记</button> |
| 56 | <nav className="nav-menu"> |
| 57 | {menuItems.map(item => ( |
| 58 | <div key={item.id} className="nav-item"> |
| 59 | <a |
| 60 | href="#" |
| 61 | className={`nav-link${location.pathname === item.path ? ' active' : ''}`} |
| 62 | onClick={e => { e.preventDefault(); toggleMenu(item) }} |
| 63 | > |
| 64 | <item.icon size={16} /> |
| 65 | <span>{item.label}</span> |
| 66 | {item.submenu && ( |
| 67 | <ChevronDown |
| 68 | size={16} |
| 69 | style={{ |
| 70 | marginLeft: 'auto', |
| 71 | transform: expandedMenu === item.id ? 'rotate(180deg)' : 'rotate(0deg)', |
| 72 | transition: 'transform 0.3s ease' |
| 73 | }} |
| 74 | /> |
| 75 | )} |
| 76 | </a> |
| 77 | {item.submenu && expandedMenu === item.id && ( |
| 78 | <div className="nav-submenu"> |
| 79 | {item.submenu.map(sub => ( |
| 80 | <NavLink |
| 81 | key={sub.id} |
| 82 | to={sub.path} |
| 83 | className={({ isActive }) => `nav-link${isActive ? ' active' : ''}`} |
| 84 | > |
| 85 | {sub.label} |
| 86 | </NavLink> |
| 87 | ))} |
| 88 | </div> |
| 89 | )} |
| 90 | </div> |
| 91 | ))} |
| 92 | </nav> |
| 93 | </aside> |
| 94 | ) |
| 95 | } |