new branch
This commit is contained in:
99
frontend/src/components/AppLayout/AppLayout.tsx
Normal file
99
frontend/src/components/AppLayout/AppLayout.tsx
Normal file
@@ -0,0 +1,99 @@
|
||||
import { ReactNode } from 'react'
|
||||
import { Layout, Menu, Typography, Button } from 'antd'
|
||||
import {
|
||||
DashboardOutlined,
|
||||
DatabaseOutlined,
|
||||
UserOutlined,
|
||||
SettingOutlined,
|
||||
BarChartOutlined,
|
||||
MenuUnfoldOutlined,
|
||||
} from '@ant-design/icons'
|
||||
import { Link, useLocation } from 'react-router-dom'
|
||||
import { useAuthStore } from '../../stores/auth'
|
||||
|
||||
const { Header, Sider, Content } = Layout
|
||||
const { Text } = Typography
|
||||
|
||||
interface AppLayoutProps {
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
function AppLayout({ children }: AppLayoutProps) {
|
||||
const location = useLocation()
|
||||
const { user, logout } = useAuthStore()
|
||||
|
||||
const menuItems = [
|
||||
{ key: '/', icon: <DashboardOutlined />, label: <Link to="/">仪表盘</Link> },
|
||||
{ key: '/datasources', icon: <DatabaseOutlined />, label: <Link to="/datasources">数据源</Link> },
|
||||
{ key: '/data', icon: <BarChartOutlined />, label: <Link to="/data">采集数据</Link> },
|
||||
{ key: '/users', icon: <UserOutlined />, label: <Link to="/users">用户管理</Link> },
|
||||
{ key: '/settings', icon: <SettingOutlined />, label: <Link to="/settings">系统配置</Link> },
|
||||
]
|
||||
|
||||
return (
|
||||
<Layout className="dashboard-layout">
|
||||
<Sider
|
||||
width={240}
|
||||
collapsible
|
||||
collapsed={false}
|
||||
onCollapse={(collapsed) => {
|
||||
const sider = document.querySelector('.dashboard-sider') as HTMLElement
|
||||
if (sider) {
|
||||
sider.style.width = collapsed ? '80px' : '240px'
|
||||
sider.style.minWidth = collapsed ? '80px' : '240px'
|
||||
sider.style.maxWidth = collapsed ? '80px' : '240px'
|
||||
}
|
||||
}}
|
||||
className="dashboard-sider"
|
||||
trigger={null}
|
||||
breakpoint="lg"
|
||||
onBreakpoint={(broken) => {
|
||||
const sider = document.querySelector('.dashboard-sider') as HTMLElement
|
||||
if (sider) {
|
||||
sider.style.width = broken ? '80px' : '240px'
|
||||
sider.style.minWidth = broken ? '80px' : '240px'
|
||||
sider.style.maxWidth = broken ? '80px' : '240px'
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div style={{ height: 64, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
||||
<Text strong style={{ color: 'white', fontSize: 18 }}>智能星球</Text>
|
||||
</div>
|
||||
<Menu
|
||||
theme="dark"
|
||||
mode="inline"
|
||||
selectedKeys={[location.pathname]}
|
||||
items={menuItems}
|
||||
/>
|
||||
</Sider>
|
||||
<Layout>
|
||||
<Header className="dashboard-header" style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '0 16px' }}>
|
||||
<Button
|
||||
type="text"
|
||||
icon={<MenuUnfoldOutlined />}
|
||||
onClick={() => {
|
||||
const sider = document.querySelector('.ant-layout-sider') as HTMLElement
|
||||
if (sider) {
|
||||
const currentWidth = sider.style.width || '240px'
|
||||
const isCollapsed = currentWidth === '80px'
|
||||
sider.style.width = isCollapsed ? '240px' : '80px'
|
||||
sider.style.minWidth = isCollapsed ? '240px' : '80px'
|
||||
sider.style.maxWidth = isCollapsed ? '240px' : '80px'
|
||||
}
|
||||
}}
|
||||
style={{ fontSize: 16 }}
|
||||
/>
|
||||
<Text strong>欢迎, {user?.username}</Text>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
|
||||
<Button type="link" danger onClick={logout}>退出登录</Button>
|
||||
</div>
|
||||
</Header>
|
||||
<Content className="dashboard-content" style={{ padding: 24, minHeight: '100%', overflow: 'auto' }}>
|
||||
{children}
|
||||
</Content>
|
||||
</Layout>
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
||||
export default AppLayout
|
||||
Reference in New Issue
Block a user