init
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
import { useMemo, useState } from 'react'
|
||||
import { Outlet, useLocation, useNavigate } from 'react-router-dom'
|
||||
import {
|
||||
Layout,
|
||||
Menu,
|
||||
theme,
|
||||
Dropdown,
|
||||
Space,
|
||||
Typography,
|
||||
Avatar,
|
||||
} from 'antd'
|
||||
import {
|
||||
DashboardOutlined,
|
||||
SkinOutlined,
|
||||
ShoppingOutlined,
|
||||
TeamOutlined,
|
||||
UserOutlined,
|
||||
LogoutOutlined,
|
||||
MenuFoldOutlined,
|
||||
MenuUnfoldOutlined,
|
||||
} from '@ant-design/icons'
|
||||
import { useAuth } from '../store/auth'
|
||||
import type { MenuProps } from 'antd'
|
||||
|
||||
const { Header, Sider, Content } = Layout
|
||||
|
||||
export default function MainLayout() {
|
||||
const [collapsed, setCollapsed] = useState(false)
|
||||
const { user, logout, isAdmin } = useAuth()
|
||||
const navigate = useNavigate()
|
||||
const location = useLocation()
|
||||
const {
|
||||
token: { colorBgContainer, borderRadiusLG },
|
||||
} = theme.useToken()
|
||||
|
||||
const menuItems: MenuProps['items'] = useMemo(() => {
|
||||
const items: MenuProps['items'] = [
|
||||
{ key: '/', icon: <DashboardOutlined />, label: '数据概览' },
|
||||
{ key: '/skins', icon: <SkinOutlined />, label: '皮肤商品' },
|
||||
{ key: '/orders', icon: <ShoppingOutlined />, label: '订单管理' },
|
||||
]
|
||||
if (isAdmin) {
|
||||
items.push({ key: '/distributors', icon: <TeamOutlined />, label: '分销商' })
|
||||
}
|
||||
return items
|
||||
}, [isAdmin])
|
||||
|
||||
const userMenu: MenuProps['items'] = [
|
||||
{
|
||||
key: 'logout',
|
||||
icon: <LogoutOutlined />,
|
||||
label: '退出登录',
|
||||
onClick: () => {
|
||||
logout()
|
||||
navigate('/login')
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<Layout style={{ minHeight: '100vh' }}>
|
||||
<Sider trigger={null} collapsible collapsed={collapsed} theme="dark">
|
||||
<div
|
||||
style={{
|
||||
height: 64,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
color: '#fff',
|
||||
fontWeight: 700,
|
||||
fontSize: collapsed ? 14 : 16,
|
||||
letterSpacing: 1,
|
||||
}}
|
||||
>
|
||||
{collapsed ? '皮肤' : '皮肤分销系统'}
|
||||
</div>
|
||||
<Menu
|
||||
theme="dark"
|
||||
mode="inline"
|
||||
selectedKeys={[location.pathname === '/' ? '/' : `/${location.pathname.split('/')[1]}`]}
|
||||
items={menuItems}
|
||||
onClick={({ key }) => navigate(key)}
|
||||
/>
|
||||
</Sider>
|
||||
<Layout>
|
||||
<Header
|
||||
style={{
|
||||
padding: '0 24px',
|
||||
background: colorBgContainer,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
}}
|
||||
>
|
||||
<span
|
||||
style={{ fontSize: 18, cursor: 'pointer' }}
|
||||
onClick={() => setCollapsed(!collapsed)}
|
||||
>
|
||||
{collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
|
||||
</span>
|
||||
<Dropdown menu={{ items: userMenu }}>
|
||||
<Space style={{ cursor: 'pointer' }}>
|
||||
<Avatar size="small" icon={<UserOutlined />} />
|
||||
<Typography.Text>
|
||||
{user?.nickname || user?.username}
|
||||
{isAdmin ? '(管理员)' : '(分销商)'}
|
||||
</Typography.Text>
|
||||
</Space>
|
||||
</Dropdown>
|
||||
</Header>
|
||||
<Content style={{ margin: 24 }}>
|
||||
<div
|
||||
style={{
|
||||
padding: 24,
|
||||
minHeight: 360,
|
||||
background: colorBgContainer,
|
||||
borderRadius: borderRadiusLG,
|
||||
}}
|
||||
>
|
||||
<Outlet />
|
||||
</div>
|
||||
</Content>
|
||||
</Layout>
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user