155 lines
4.0 KiB
JavaScript
155 lines
4.0 KiB
JavaScript
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;
|