App layout

This commit is contained in:
2024-03-14 01:44:38 +08:00
parent 52a6968f4e
commit 50e3f4a8f0
6 changed files with 1063 additions and 228 deletions
+3
View File
@@ -0,0 +1,3 @@
.app {
width: 100%;
}
+129 -10
View File
@@ -1,13 +1,132 @@
import { Component, ReactNode } from 'react';
import { Route, Routes } from 'react-router-dom';
import { useState, FC } from 'react';
import { useNavigate } from 'react-router-dom';
import { TeamOutlined, UserOutlined, DesktopOutlined } from '@ant-design/icons';
import type { MenuProps } from 'antd';
import { Breadcrumb, Layout, Menu, theme } from 'antd';
import { AppRouter } from './router';
import './App.scss';
export default class App extends Component {
render(): ReactNode {
return (
<Routes>
<Route path='/' element={<p>Main</p>} />
<Route path='/hello' element={<p>Hello</p>} />
</Routes>
);
const { Content, Footer, Sider } = Layout;
type MenuItem = Required<MenuProps>['items'][number];
type KeyRouterMap = Map<React.Key, string>;
const keyRouterMap: KeyRouterMap = new Map();
function getItem(
label: React.ReactNode,
key: React.Key,
route?: { path: string; map: KeyRouterMap },
icon?: React.ReactNode,
children?: MenuItem[],
): MenuItem {
if (route !== undefined) {
route.map.set(key, route.path);
}
return {
key,
icon,
children,
label,
} as MenuItem;
}
function defMenu(
label: React.ReactNode,
key: React.Key,
icon: React.ReactNode,
path: string,
map: KeyRouterMap,
): MenuItem {
return getItem(label, key, { path: path, map: map }, icon);
}
function defRootMenu(
label: React.ReactNode,
key: React.Key,
icon: React.ReactNode,
children: MenuItem[],
): MenuItem {
return getItem(label, key, undefined, icon, children);
}
function defSubMenu(
label: React.ReactNode,
key: React.Key,
path: string,
map: KeyRouterMap,
): MenuItem {
return getItem(label, key, { path, map });
}
const items: MenuItem[] = [
defMenu('主页', '0', <DesktopOutlined />, '/', keyRouterMap),
defRootMenu('展示信息管理', 'sub1', <UserOutlined />, [
defSubMenu('选项1', '1', '/hello1', keyRouterMap),
defSubMenu('选项2', '2', '/hello2', keyRouterMap),
defSubMenu('选项3', '3', '/hello3', keyRouterMap),
]),
defRootMenu('值班组长', 'sub2', <TeamOutlined />, [
defSubMenu('选项1', '4', '/hi1', keyRouterMap),
defSubMenu('选项2', '5', '/hi2', keyRouterMap),
]),
];
const AppLayout: FC<{ router: JSX.Element }> = (props) => {
const [collapsed, setCollapsed] = useState(false);
const { colorBgContainer, borderRadiusLG } = theme.getDesignToken();
const navigate = useNavigate();
return (
<Layout style={{ minHeight: '100vh' }}>
<Sider
collapsible
collapsed={collapsed}
onCollapse={(value) => setCollapsed(value)}
>
<div className='demo-logo-vertical' />
<Menu
theme='dark'
defaultSelectedKeys={['1']}
mode='inline'
items={items}
onClick={(info: { key: React.Key }) => {
console.log('path', keyRouterMap.get(info.key));
navigate(keyRouterMap.get(info.key) || '/');
}}
/>
</Sider>
<Layout>
<Content style={{ margin: '0 16px' }}>
<Breadcrumb style={{ margin: '16px 0' }}>
<Breadcrumb.Item>User</Breadcrumb.Item>
<Breadcrumb.Item>Bill</Breadcrumb.Item>
</Breadcrumb>
<div
style={{
padding: 24,
minHeight: 360,
background: colorBgContainer,
borderRadius: borderRadiusLG,
}}
>
<div>{props.router}</div>
</div>
</Content>
<Footer style={{ textAlign: 'center' }}>
EVA-Notify Admin Page &copy; {new Date().getFullYear()} EVA Tech
</Footer>
</Layout>
</Layout>
);
};
const App: FC = () => {
return (
<div className='app'>
<AppLayout router={<AppRouter />} />
</div>
);
};
export default App;
+12
View File
@@ -0,0 +1,12 @@
import { Routes, Route } from 'react-router-dom';
export const AppRouter: React.FC = () => {
return (
<Routes>
<Route path='/' element={<p>Main</p>} />
<Route path='/hello1' element={<p>Hello1</p>} />
<Route path='/hello2' element={<p>Hello1</p>} />
<Route path='/hello3' element={<p>Hello1</p>} />
</Routes>
);
};