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