App layout
parent
52a6968f4e
commit
50e3f4a8f0
File diff suppressed because it is too large
Load Diff
|
|
@ -9,7 +9,7 @@
|
|||
"@types/node": "^16.18.88",
|
||||
"@types/react": "^18.2.65",
|
||||
"@types/react-dom": "^18.2.21",
|
||||
"evergreen-ui": "^7.1.9",
|
||||
"antd": "^5.15.2",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^6.22.3",
|
||||
|
|
|
|||
|
|
@ -15,29 +15,10 @@
|
|||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>React App</title>
|
||||
<title>EVA-Notify Admin Page</title>
|
||||
</head>
|
||||
<body>
|
||||
<body style="margin: 0;">
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
.app {
|
||||
width: 100%;
|
||||
}
|
||||
139
src/App.tsx
139
src/App.tsx
|
|
@ -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 {
|
||||
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 (
|
||||
<Routes>
|
||||
<Route path='/' element={<p>Main</p>} />
|
||||
<Route path='/hello' element={<p>Hello</p>} />
|
||||
</Routes>
|
||||
<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 © {new Date().getFullYear()} EVA Tech
|
||||
</Footer>
|
||||
</Layout>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const App: FC = () => {
|
||||
return (
|
||||
<div className='app'>
|
||||
<AppLayout router={<AppRouter />} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
Loading…
Reference in New Issue