feat: add MainLayout with sidebar
This commit is contained in:
@@ -1,7 +1,21 @@
|
||||
import React from 'react';
|
||||
import { Route, Routes } from 'react-router-dom';
|
||||
import MainLayout from './pages/MainLayout';
|
||||
import ProtectedRoute from './pages/ProtectedRoute';
|
||||
|
||||
function App() {
|
||||
return <div className="App"></div>;
|
||||
return (
|
||||
<div className="App">
|
||||
<div>
|
||||
<Routes>
|
||||
<Route path="/login" element={<div>login</div>} />
|
||||
<Route element={<ProtectedRoute />}>
|
||||
<Route path="*" element={<MainLayout />}></Route>
|
||||
</Route>
|
||||
</Routes>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
61
client/src/components/SiderMenu.tsx
Normal file
61
client/src/components/SiderMenu.tsx
Normal file
@@ -0,0 +1,61 @@
|
||||
import { Menu, MenuProps } from 'antd';
|
||||
|
||||
type MenuItem = Required<MenuProps>['items'][number];
|
||||
|
||||
function getItem(
|
||||
label: React.ReactNode,
|
||||
key: React.Key,
|
||||
icon?: React.ReactNode,
|
||||
children?: MenuItem[]
|
||||
): MenuItem {
|
||||
return {
|
||||
key,
|
||||
icon,
|
||||
children,
|
||||
label,
|
||||
} as MenuItem;
|
||||
}
|
||||
|
||||
const sidebarItems: MenuItem[] = [
|
||||
getItem('VORKOUT', '0', <img src="./icons/sider/menu.svg" alt="toggle" />),
|
||||
getItem(
|
||||
'Схемы процессов',
|
||||
'1',
|
||||
<img src="./icons/sider/process-diagram.svg" alt="process diagram" />
|
||||
),
|
||||
getItem(
|
||||
'Запущенные процессы',
|
||||
'2',
|
||||
<img src="./icons/sider/running-processes.svg" alt="running processes" />
|
||||
),
|
||||
getItem(
|
||||
'Настройки',
|
||||
'sub1',
|
||||
<img src="./icons/sider/settings.svg" alt="settings" />,
|
||||
[
|
||||
getItem('Учетные записи', '3'),
|
||||
getItem('Справичник событий', '4'),
|
||||
getItem('Конфигурация', '5'),
|
||||
]
|
||||
),
|
||||
];
|
||||
|
||||
interface SiderMenuProps {
|
||||
selectedKey: string;
|
||||
hangleMenuClick: (e: any) => void;
|
||||
}
|
||||
|
||||
export default function SiderMenu({
|
||||
selectedKey,
|
||||
hangleMenuClick,
|
||||
}: SiderMenuProps) {
|
||||
return (
|
||||
<Menu
|
||||
theme="light"
|
||||
selectedKeys={[selectedKey]}
|
||||
mode="inline"
|
||||
items={sidebarItems}
|
||||
onClick={hangleMenuClick}
|
||||
/>
|
||||
);
|
||||
}
|
@@ -2,8 +2,13 @@ import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import './index.css';
|
||||
import App from './App';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
|
||||
const root = ReactDOM.createRoot(
|
||||
document.getElementById('root') as HTMLElement
|
||||
);
|
||||
root.render(<App />);
|
||||
root.render(
|
||||
<BrowserRouter>
|
||||
<App />
|
||||
</BrowserRouter>
|
||||
);
|
||||
|
40
client/src/pages/MainLayout.tsx
Normal file
40
client/src/pages/MainLayout.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Layout } from 'antd';
|
||||
import Sider from 'antd/es/layout/Sider';
|
||||
import SiderMenu from '../components/SiderMenu';
|
||||
|
||||
export default function MainLayout() {
|
||||
const [collapsed, setCollapsed] = useState(false);
|
||||
const [selectedKey, setSelectedKey] = useState('1');
|
||||
|
||||
function hangleMenuClick(e: any) {
|
||||
if (e.key === '0') {
|
||||
setCollapsed((prev) => !prev);
|
||||
return;
|
||||
}
|
||||
|
||||
setSelectedKey(e.key);
|
||||
}
|
||||
|
||||
return (
|
||||
<Layout style={{ minHeight: '100vh' }}>
|
||||
<Sider
|
||||
collapsible
|
||||
collapsed={collapsed}
|
||||
onCollapse={(value) => setCollapsed(value)}
|
||||
theme="light"
|
||||
width={'15%'}
|
||||
collapsedWidth={'3.8%'}
|
||||
trigger={null}
|
||||
>
|
||||
<SiderMenu
|
||||
selectedKey={selectedKey}
|
||||
hangleMenuClick={hangleMenuClick}
|
||||
/>
|
||||
</Sider>
|
||||
<Layout>
|
||||
<div>Main layout</div>
|
||||
</Layout>
|
||||
</Layout>
|
||||
);
|
||||
}
|
8
client/src/pages/ProtectedRoute.tsx
Normal file
8
client/src/pages/ProtectedRoute.tsx
Normal file
@@ -0,0 +1,8 @@
|
||||
// ProtectedRoute.js
|
||||
import { Outlet } from 'react-router-dom';
|
||||
import React from 'react';
|
||||
|
||||
const ProtectedRoute = (): React.JSX.Element => {
|
||||
return <Outlet />;
|
||||
};
|
||||
export default ProtectedRoute;
|
Reference in New Issue
Block a user