Files
asset_helper/frontend/src/layouts/MainLayout.tsx
2026-04-26 14:40:55 +08:00

105 lines
2.6 KiB
TypeScript

import { useState } from 'react'
import { Outlet, useNavigate } from 'react-router-dom'
import { Layout, Menu, Button, theme, Dropdown, Avatar, Space } from 'antd'
import {
DashboardOutlined,
LogoutOutlined,
UserOutlined,
MenuFoldOutlined,
MenuUnfoldOutlined,
} from '@ant-design/icons'
import { useAuthStore } from '@/stores/auth'
const { Header, Sider, Content } = Layout
export default function MainLayout() {
const [collapsed, setCollapsed] = useState(false)
const logout = useAuthStore((s) => s.logout)
const navigate = useNavigate()
const {
token: { colorBgContainer, borderRadiusLG },
} = theme.useToken()
const menuItems = [
{
key: '/',
icon: <DashboardOutlined />,
label: '仪表盘',
},
]
const userMenuItems = [
{
key: 'logout',
icon: <LogoutOutlined />,
label: '退出登录',
danger: true,
onClick: () => {
logout()
navigate('/login')
},
},
]
return (
<Layout style={{ minHeight: '100vh' }}>
<Sider trigger={null} collapsible collapsed={collapsed} theme="light">
<div
style={{
height: 64,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontWeight: 'bold',
fontSize: collapsed ? 14 : 18,
borderBottom: '1px solid #f0f0f0',
}}
>
{collapsed ? 'AH' : 'Asset Helper'}
</div>
<Menu
mode="inline"
defaultSelectedKeys={['/']}
items={menuItems}
onClick={({ key }) => navigate(key)}
/>
</Sider>
<Layout>
<Header
style={{
padding: '0 24px',
background: colorBgContainer,
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
}}
>
<Button
type="text"
icon={collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
onClick={() => setCollapsed(!collapsed)}
/>
<Dropdown menu={{ items: userMenuItems }} placement="bottomRight">
<Space style={{ cursor: 'pointer' }}>
<Avatar icon={<UserOutlined />} />
<span></span>
</Space>
</Dropdown>
</Header>
<Content
style={{
margin: 24,
padding: 24,
background: colorBgContainer,
borderRadius: borderRadiusLG,
overflow: 'auto',
}}
>
<Outlet />
</Content>
</Layout>
</Layout>
)
}