155 lines
4.0 KiB
React
155 lines
4.0 KiB
React
|
|
import React, { useState } from 'react';
|
|||
|
|
import { Layout, Avatar, Tooltip, Button } from 'antd';
|
|||
|
|
import {
|
|||
|
|
MenuUnfoldOutlined,
|
|||
|
|
MenuFoldOutlined,
|
|||
|
|
LogoutOutlined,
|
|||
|
|
QuestionCircleOutlined,
|
|||
|
|
RightOutlined,
|
|||
|
|
LeftOutlined
|
|||
|
|
} from '@ant-design/icons';
|
|||
|
|
import './ModernSidebar.css';
|
|||
|
|
|
|||
|
|
const { Sider } = Layout;
|
|||
|
|
|
|||
|
|
const ModernSidebar = ({
|
|||
|
|
logo,
|
|||
|
|
menuGroups = [],
|
|||
|
|
activeKey,
|
|||
|
|
onNavigate,
|
|||
|
|
user,
|
|||
|
|
onLogout,
|
|||
|
|
onProfileClick,
|
|||
|
|
collapsed,
|
|||
|
|
onCollapse,
|
|||
|
|
width = 260,
|
|||
|
|
collapsedWidth = 80,
|
|||
|
|
className = '',
|
|||
|
|
style = {}
|
|||
|
|
}) => {
|
|||
|
|
|
|||
|
|
const handleItemClick = (item) => {
|
|||
|
|
if (onNavigate) {
|
|||
|
|
onNavigate(item.key, item);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const renderMenuItem = (item) => {
|
|||
|
|
const isActive = activeKey === item.key;
|
|||
|
|
|
|||
|
|
// 如果是折叠状态,只显示图标,并使用Tooltip
|
|||
|
|
if (collapsed) {
|
|||
|
|
return (
|
|||
|
|
<Tooltip title={item.label} placement="right" key={item.key}>
|
|||
|
|
<div
|
|||
|
|
className={`modern-sidebar-item collapsed ${isActive ? 'active' : ''}`}
|
|||
|
|
onClick={() => handleItemClick(item)}
|
|||
|
|
>
|
|||
|
|
<div className="item-icon">{item.icon}</div>
|
|||
|
|
</div>
|
|||
|
|
</Tooltip>
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<div
|
|||
|
|
key={item.key}
|
|||
|
|
className={`modern-sidebar-item ${isActive ? 'active' : ''}`}
|
|||
|
|
onClick={() => handleItemClick(item)}
|
|||
|
|
>
|
|||
|
|
<div className="item-content">
|
|||
|
|
<div className="item-icon">{item.icon}</div>
|
|||
|
|
<span className="item-label">{item.label}</span>
|
|||
|
|
</div>
|
|||
|
|
{isActive && <RightOutlined className="item-arrow" />}
|
|||
|
|
</div>
|
|||
|
|
);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<Sider
|
|||
|
|
width={width}
|
|||
|
|
collapsed={collapsed}
|
|||
|
|
collapsedWidth={collapsedWidth}
|
|||
|
|
trigger={null}
|
|||
|
|
className={`modern-sidebar ${className}`}
|
|||
|
|
theme="light"
|
|||
|
|
style={style}
|
|||
|
|
>
|
|||
|
|
{/* 顶部 Logo 区域 */}
|
|||
|
|
<div className="modern-sidebar-header">
|
|||
|
|
<div className="logo-container">
|
|||
|
|
{logo}
|
|||
|
|
</div>
|
|||
|
|
{/* 折叠按钮 - 悬浮在边缘 */}
|
|||
|
|
<div
|
|||
|
|
className="collapse-trigger"
|
|||
|
|
onClick={() => onCollapse && onCollapse(!collapsed)}
|
|||
|
|
>
|
|||
|
|
{collapsed ? <RightOutlined /> : <LeftOutlined />}
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
{/* 菜单列表区域 */}
|
|||
|
|
<div className="modern-sidebar-menu">
|
|||
|
|
{menuGroups.map((group, index) => (
|
|||
|
|
<div key={index} className="menu-group">
|
|||
|
|
{!collapsed && group.title && (
|
|||
|
|
<div className="group-title">{group.title}</div>
|
|||
|
|
)}
|
|||
|
|
<div className="group-items">
|
|||
|
|
{group.items.map(item => renderMenuItem(item))}
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
))}
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
{/* 底部区域 */}
|
|||
|
|
<div className="modern-sidebar-footer">
|
|||
|
|
{/* 帮助支持 */}
|
|||
|
|
{!collapsed && (
|
|||
|
|
<div className="footer-link">
|
|||
|
|
<QuestionCircleOutlined />
|
|||
|
|
<span>帮助支持</span>
|
|||
|
|
</div>
|
|||
|
|
)}
|
|||
|
|
{collapsed && (
|
|||
|
|
<div className="footer-link collapsed">
|
|||
|
|
<QuestionCircleOutlined />
|
|||
|
|
</div>
|
|||
|
|
)}
|
|||
|
|
|
|||
|
|
{/* 用户卡片 */}
|
|||
|
|
<div className="user-card">
|
|||
|
|
<div
|
|||
|
|
className="user-info"
|
|||
|
|
onClick={onProfileClick}
|
|||
|
|
style={{ cursor: onProfileClick ? 'pointer' : 'default' }}
|
|||
|
|
>
|
|||
|
|
<Avatar
|
|||
|
|
size={collapsed ? 32 : 40}
|
|||
|
|
src={user?.avatar}
|
|||
|
|
style={{ backgroundColor: '#1677ff' }}
|
|||
|
|
>
|
|||
|
|
{user?.name?.[0]?.toUpperCase() || 'U'}
|
|||
|
|
</Avatar>
|
|||
|
|
{!collapsed && (
|
|||
|
|
<div className="user-details">
|
|||
|
|
<div className="user-name">{user?.name || 'User'}</div>
|
|||
|
|
<div className="user-role">{user?.role || 'Member'}</div>
|
|||
|
|
</div>
|
|||
|
|
)}
|
|||
|
|
</div>
|
|||
|
|
{!collapsed && (
|
|||
|
|
<div className="logout-btn" onClick={onLogout} title="退出登录">
|
|||
|
|
<LogoutOutlined />
|
|||
|
|
</div>
|
|||
|
|
)}
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</Sider>
|
|||
|
|
);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
export default ModernSidebar;
|