This repository has been archived on 2026-02-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
v1-frontend/src/layouts/components/Sidebar.tsx
2025-10-18 17:34:11 +08:00

115 lines
3.8 KiB
TypeScript

import { makeStyles, tokens } from '@fluentui/react-components';
import { Home24Regular, Add24Regular, History24Regular, Info24Regular, DocumentSearch24Regular, PeopleSearch24Regular, ChevronDown24Regular, ChevronRight24Regular } from '@fluentui/react-icons';
import React from 'react';
import { Link, useLocation } from 'react-router-dom';
const useStyles = makeStyles({
sidebar: {
padding: tokens.spacingVerticalM,
},
menuItem: {
display: 'flex',
alignItems: 'center',
padding: tokens.spacingVerticalS + ' ' + tokens.spacingHorizontalM,
color: tokens.colorNeutralForeground1,
textDecoration: 'none',
borderRadius: tokens.borderRadiusMedium,
gap: tokens.spacingHorizontalS,
':hover': {
backgroundColor: tokens.colorNeutralBackground1Hover,
},
},
activeMenuItem: {
backgroundColor: tokens.colorNeutralBackground1Selected,
color: tokens.colorBrandForeground1,
':hover': {
backgroundColor: tokens.colorNeutralBackground1Selected,
},
},
});
const menuItems = [
{ path: '/', icon: Home24Regular, label: '主页' },
{ path: '/create', icon: Add24Regular, label: '发布新帖' },
{
path: '/progress',
icon: History24Regular,
label: '进度查询',
subItems: [
{ path: '/progress/review', icon: DocumentSearch24Regular, label: '投稿审核' },
{ path: '/progress/complaint', icon: PeopleSearch24Regular, label: '投诉受理' }
]
},
{ path: '/about', icon: Info24Regular, label: '关于' },
];
const Sidebar = () => {
const [expandedItems, setExpandedItems] = React.useState<Record<string, boolean>>({});
const styles = useStyles();
const location = useLocation();
return (
<nav className={styles.sidebar}>
{menuItems.map((item) => {
const Icon = item.icon;
const isActive = location.pathname === item.path ||
(item.subItems && item.subItems.some(subItem => location.pathname === subItem.path));
const isExpanded = expandedItems[item.path];
return (
<div key={item.path}>
{item.subItems ? (
<div
className={`${styles.menuItem} ${isActive ? styles.activeMenuItem : ''}`}
onClick={() => setExpandedItems(prev => ({
...prev,
[item.path]: !prev[item.path]
}))}
style={{ cursor: 'pointer' }}
>
<Icon />
{item.label}
{item.subItems && (
isExpanded ?
<ChevronDown24Regular style={{ marginLeft: 'auto' }} /> :
<ChevronRight24Regular style={{ marginLeft: 'auto' }} />
)}
</div>
) : (
<Link
to={item.path}
className={`${styles.menuItem} ${isActive ? styles.activeMenuItem : ''}`}
>
<Icon />
{item.label}
</Link>
)}
{item.subItems && isExpanded && (
<div style={{ marginLeft: tokens.spacingHorizontalL }}>
{item.subItems.map((subItem) => {
const SubIcon = subItem.icon;
const isSubActive = location.pathname === subItem.path;
return (
<Link
key={subItem.path}
to={subItem.path}
className={`${styles.menuItem} ${isSubActive ? styles.activeMenuItem : ''}`}
style={{ paddingLeft: tokens.spacingHorizontalXXL }}
>
<SubIcon />
{subItem.label}
</Link>
);
})}
</div>
)}
</div>
);
})}
</nav>
);
};
export default Sidebar;