合并JWL,WZY,TRM代码
Change-Id: Ifb4fcad3c06733e1e005e7d8d9403e3561010fb4
diff --git a/Merge/front/src/components/Sidebar.jsx b/Merge/front/src/components/Sidebar.jsx
new file mode 100644
index 0000000..26118b2
--- /dev/null
+++ b/Merge/front/src/components/Sidebar.jsx
@@ -0,0 +1,103 @@
+import React, { useState, useEffect } from 'react'
+import { NavLink, useLocation, useNavigate } from 'react-router-dom'
+import {
+ Home,
+ BookOpen,
+ BarChart3,
+ Activity,
+ Users,
+ ChevronDown,
+} from 'lucide-react'
+import '../App.css'
+
+const menuItems = [
+ { id: 'home', label: '首页', icon: Home, path: '/home' },
+ { id: 'notebooks', label: '笔记管理', icon: BookOpen, path: '/notebooks' },
+ {
+ id: 'dashboard',
+ label: '数据看板',
+ icon: BarChart3,
+ path: '/dashboard',
+ submenu: [
+ { id: 'overview', label: '账号概况', path: '/dashboard/overview' },
+ { id: 'content', label: '内容分析', path: '/dashboard/content' },
+ { id: 'fans', label: '粉丝数据', path: '/dashboard/fans' },
+ ]
+ },
+ { id: 'activity', label: '活动中心', icon: Activity, path: '/activity' },
+ { id: 'notes', label: '笔记灵感', icon: BookOpen, path: '/notes' },
+ { id: 'creator', label: '创作学院', icon: Users, path: '/creator' },
+ { id: 'journal', label: '创作日刊', icon: BookOpen, path: '/journal' },
+]
+
+export default function Sidebar() {
+ const [expandedMenu, setExpandedMenu] = useState(null)
+ const location = useLocation()
+ const navigate = useNavigate()
+
+ // 打开 dashboard 下拉时保持展开
+ useEffect(() => {
+ if (location.pathname.startsWith('/dashboard')) {
+ setExpandedMenu('dashboard')
+ }
+ }, [location.pathname])
+
+ const toggleMenu = item => {
+ if (item.submenu) {
+ setExpandedMenu(expandedMenu === item.id ? null : item.id)
+ } else {
+ navigate(item.path)
+ setExpandedMenu(null)
+ }
+ }
+
+ return (
+ <aside className="sidebar">
+ {/* 发布笔记 按钮 */}
+ <button
+ className="publish-btn"
+ onClick={() => navigate('/posts/new')}
+ >
+ 发布笔记
+ </button>
+
+ <nav className="nav-menu">
+ {menuItems.map(item => (
+ <div key={item.id} className="nav-item">
+ <a
+ href="#"
+ className={`nav-link${location.pathname === item.path ? ' active' : ''}`}
+ onClick={e => { e.preventDefault(); toggleMenu(item) }}
+ >
+ <item.icon size={16} />
+ <span>{item.label}</span>
+ {item.submenu && (
+ <ChevronDown
+ size={16}
+ style={{
+ marginLeft: 'auto',
+ transform: expandedMenu === item.id ? 'rotate(180deg)' : 'rotate(0deg)',
+ transition: 'transform 0.3s ease'
+ }}
+ />
+ )}
+ </a>
+ {item.submenu && expandedMenu === item.id && (
+ <div className="nav-submenu">
+ {item.submenu.map(sub => (
+ <NavLink
+ key={sub.id}
+ to={sub.path}
+ className={({ isActive }) => `nav-link${isActive ? ' active' : ''}`}
+ >
+ {sub.label}
+ </NavLink>
+ ))}
+ </div>
+ )}
+ </div>
+ ))}
+ </nav>
+ </aside>
+ )
+}