142 lines
5.1 KiB
TypeScript
142 lines
5.1 KiB
TypeScript
'use client';
|
|
|
|
import { FC } from 'react';
|
|
import Link from 'next/link';
|
|
import Image from 'next/image';
|
|
import { usePathname, useRouter } from 'next/navigation';
|
|
import { cn } from '@/utils/helpers';
|
|
import { useAppSelector, useAppDispatch } from '@/store/redux/hooks';
|
|
import { toggleSidebar } from '@/store/redux/slices/settingsSlice';
|
|
import { logoutService } from '@/services/authService';
|
|
import { toast } from '@/components/common';
|
|
import styles from './Sidebar.module.scss';
|
|
|
|
/**
|
|
* 侧边栏菜单项配置
|
|
*/
|
|
interface MenuItem {
|
|
key: string;
|
|
icon: string;
|
|
label: string;
|
|
path: string;
|
|
}
|
|
|
|
// 主导航菜单
|
|
const topMenuItems: MenuItem[] = [
|
|
{ key: 'dashboard', icon: '/images/Container1.svg', label: '仪表板', path: '/dashboard' },
|
|
{ key: 'users', icon: '/images/Container2.svg', label: '用户管理', path: '/users' },
|
|
{ key: 'leaderboard', icon: '/images/Container3.svg', label: '龙虎榜', path: '/leaderboard' },
|
|
{ key: 'authorization', icon: '/images/Container4.svg', label: '授权管理', path: '/authorization' },
|
|
{ key: 'co-managed-wallet', icon: '/images/Container4.svg', label: '共管钱包', path: '/co-managed-wallet' },
|
|
{ key: 'notifications', icon: '/images/Container3.svg', label: '通知管理', path: '/notifications' },
|
|
{ key: 'pending-actions', icon: '/images/Container3.svg', label: '待办操作', path: '/pending-actions' },
|
|
{ key: 'withdrawals', icon: '/images/Container5.svg', label: '提现审核', path: '/withdrawals' },
|
|
{ key: 'statistics', icon: '/images/Container5.svg', label: '数据统计', path: '/statistics' },
|
|
{ key: 'maintenance', icon: '/images/Container6.svg', label: '系统维护', path: '/maintenance' },
|
|
{ key: 'settings', icon: '/images/Container6.svg', label: '系统设置', path: '/settings' },
|
|
];
|
|
|
|
// 底部导航菜单
|
|
const bottomMenuItems: MenuItem[] = [
|
|
{ key: 'help', icon: '/images/Container7.svg', label: '帮助中心', path: '/help' },
|
|
];
|
|
|
|
/**
|
|
* 侧边栏组件
|
|
* 基于 UIPro Figma 设计实现
|
|
*/
|
|
export const Sidebar: FC = () => {
|
|
const pathname = usePathname();
|
|
const router = useRouter();
|
|
const dispatch = useAppDispatch();
|
|
const collapsed = useAppSelector((state) => state.settings.sidebarCollapsed);
|
|
|
|
// 切换侧边栏展开/收起
|
|
const handleToggle = () => {
|
|
dispatch(toggleSidebar());
|
|
};
|
|
|
|
// 退出登录
|
|
const handleLogout = () => {
|
|
// 清除所有上下文和存储
|
|
logoutService.logout();
|
|
toast.success('已安全退出登录');
|
|
// 跳转到登录页
|
|
router.push('/login');
|
|
};
|
|
|
|
// 渲染菜单项
|
|
const renderMenuItem = (item: MenuItem) => {
|
|
const isActive = pathname === item.path || pathname.startsWith(`${item.path}/`);
|
|
|
|
return (
|
|
<Link
|
|
key={item.key}
|
|
href={item.path}
|
|
className={cn(styles.sidebar__item, isActive && styles['sidebar__item--active'])}
|
|
title={collapsed ? item.label : undefined}
|
|
>
|
|
<span className={styles.sidebar__icon}>
|
|
<Image src={item.icon} width={24} height={28} alt={item.label} />
|
|
</span>
|
|
{!collapsed && <span className={styles.sidebar__label}>{item.label}</span>}
|
|
</Link>
|
|
);
|
|
};
|
|
|
|
return (
|
|
<aside className={cn(styles.sidebar, collapsed && styles['sidebar--collapsed'])}>
|
|
{/* Logo 区域 */}
|
|
<div className={styles.sidebar__header}>
|
|
<div className={styles.sidebar__logo}>
|
|
<span className={styles.sidebar__logoIcon}>
|
|
<Image src="/images/Container.svg" width={30} height={36} alt="Logo" priority />
|
|
</span>
|
|
{!collapsed && <span className={styles.sidebar__logoText}>榴莲认种管理后台</span>}
|
|
</div>
|
|
</div>
|
|
|
|
{/* 主导航区域 */}
|
|
<div className={styles.sidebar__navWrapper}>
|
|
<nav className={styles.sidebar__nav}>
|
|
{topMenuItems.map(renderMenuItem)}
|
|
</nav>
|
|
|
|
{/* 折叠按钮 */}
|
|
<button
|
|
className={styles.sidebar__toggle}
|
|
onClick={handleToggle}
|
|
aria-label={collapsed ? '展开侧边栏' : '收起侧边栏'}
|
|
>
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
|
{collapsed ? (
|
|
<polyline points="9 18 15 12 9 6" />
|
|
) : (
|
|
<polyline points="15 18 9 12 15 6" />
|
|
)}
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
|
|
{/* 底部导航区域 */}
|
|
<div className={styles.sidebar__bottomNav}>
|
|
<div className={styles.sidebar__bottomMenu}>
|
|
{bottomMenuItems.map(renderMenuItem)}
|
|
|
|
{/* 退出登录按钮 */}
|
|
<button
|
|
className={styles.sidebar__logoutItem}
|
|
onClick={handleLogout}
|
|
title={collapsed ? '退出登录' : undefined}
|
|
>
|
|
<span className={styles.sidebar__icon}>
|
|
<Image src="/images/Container8.svg" width={24} height={28} alt="退出登录" />
|
|
</span>
|
|
{!collapsed && <span className={styles.sidebar__label}>退出登录</span>}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
);
|
|
};
|