Files
Web_BLV_OA_Exam_Prod/src/layouts/AdminLayout.tsx

134 lines
3.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useState, useEffect } from 'react';
import { Layout, Menu, Button, Avatar, Dropdown, message } from 'antd';
import { Outlet, useNavigate, useLocation } from 'react-router-dom';
import {
DashboardOutlined,
QuestionCircleOutlined,
SettingOutlined,
BarChartOutlined,
UserOutlined,
LogoutOutlined,
DatabaseOutlined,
SafetyOutlined,
BookOutlined,
CalendarOutlined,
TeamOutlined
} from '@ant-design/icons';
import { useAdmin } from '../contexts';
const { Header, Sider, Content } = Layout;
const AdminLayout = ({ children }: { children: React.ReactNode }) => {
const navigate = useNavigate();
const location = useLocation();
const { admin, clearAdmin } = useAdmin();
const [collapsed, setCollapsed] = useState(false);
const menuItems = [
{
key: '/admin/dashboard',
icon: <DashboardOutlined />,
label: '仪表盘',
},
{
key: '/admin/questions',
icon: <QuestionCircleOutlined />,
label: '题库管理',
},
{
key: '/admin/categories',
icon: <SafetyOutlined />,
label: '题目类别',
},
{
key: '/admin/subjects',
icon: <BookOutlined />,
label: '考试科目',
},
{
key: '/admin/tasks',
icon: <CalendarOutlined />,
label: '考试任务',
},
{
key: '/admin/users',
icon: <TeamOutlined />,
label: '用户管理',
},
{
key: '/admin/statistics',
icon: <BarChartOutlined />,
label: '数据统计',
},
{
key: '/admin/backup',
icon: <DatabaseOutlined />,
label: '数据备份',
},
];
const handleMenuClick = ({ key }: { key: string }) => {
navigate(key);
};
const handleLogout = () => {
clearAdmin();
message.success('退出登录成功');
navigate('/admin/login');
};
const userMenuItems = [
{
key: 'logout',
icon: <LogoutOutlined />,
label: '退出登录',
onClick: handleLogout,
},
];
return (
<Layout style={{ minHeight: '100vh' }}>
<Sider trigger={null} collapsible collapsed={collapsed} theme="light">
<div className="logo p-4 text-center">
<h2 className="text-lg font-bold text-blue-600 m-0">
{collapsed ? '问卷' : '问卷系统'}
</h2>
</div>
<Menu
mode="inline"
selectedKeys={[location.pathname]}
items={menuItems}
onClick={handleMenuClick}
style={{ borderRight: 0 }}
/>
</Sider>
<Layout>
<Header className="bg-white shadow-sm flex justify-between items-center px-6">
<Button
type="text"
icon={collapsed ? <DashboardOutlined /> : <DashboardOutlined />}
onClick={() => setCollapsed(!collapsed)}
className="text-lg"
/>
<div className="flex items-center">
<span className="mr-4 text-gray-600">
{admin?.username}
</span>
<Dropdown menu={{ items: userMenuItems }} placement="bottomRight">
<Avatar icon={<UserOutlined />} className="cursor-pointer" />
</Dropdown>
</div>
</Header>
<Content className="m-6 p-6 bg-white rounded-lg shadow-sm">
{children}
</Content>
</Layout>
</Layout>
);
};
export default AdminLayout;