сделал заготовку под навигацию
This commit is contained in:
parent
8e85ea7b23
commit
df5809232b
@ -1,7 +1,7 @@
|
||||
from pydantic import BaseModel, Field
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class AuthEntity(BaseModel):
|
||||
login: str = Field(..., example='user@example.com')
|
||||
password: str = Field(..., min_length=5, example='strongpassword')
|
||||
login: str
|
||||
password: str
|
||||
|
||||
|
||||
@ -4,9 +4,9 @@ from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class RegisterEntity(BaseModel):
|
||||
first_name: str = Field(..., example='Ivan')
|
||||
last_name: str = Field(..., example='Ivanov')
|
||||
patronymic: Optional[str] = Field(None, example='Ivanov')
|
||||
role_id: int = Field(..., example=1)
|
||||
login: str = Field(..., example='user@example.com')
|
||||
password: str = Field(..., min_length=5, example='strongpassword')
|
||||
first_name: str
|
||||
last_name: str
|
||||
patronymic: Optional[str]
|
||||
role_id: int
|
||||
login: str
|
||||
password: str
|
||||
|
||||
@ -4,11 +4,10 @@ from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class UserEntity(BaseModel):
|
||||
id: int = Field(..., example=1)
|
||||
first_name: str = Field(..., example='Ivan')
|
||||
last_name: str = Field(..., example='Ivanov')
|
||||
patronymic: Optional[str] = Field(None, example='Ivanov')
|
||||
login: str = Field(..., example='ivanov74')
|
||||
|
||||
role_id: int = Field(..., example=1)
|
||||
id: int
|
||||
first_name: str
|
||||
last_name: str
|
||||
patronymic: Optional[str]
|
||||
login: str
|
||||
|
||||
role_id: int
|
||||
|
||||
7
web-app/package-lock.json
generated
7
web-app/package-lock.json
generated
@ -8,6 +8,7 @@
|
||||
"name": "web-app",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^5.6.1",
|
||||
"@react-buddy/ide-toolbox": "^2.4.0",
|
||||
"@react-buddy/palette-antd": "^5.3.0",
|
||||
"antd": "^5.23.1",
|
||||
@ -86,9 +87,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ant-design/icons": {
|
||||
"version": "5.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-5.5.2.tgz",
|
||||
"integrity": "sha512-xc53rjVBl9v2BqFxUjZGti/RfdDeA8/6KYglmInM2PNqSXc/WfuGDTifJI/ZsokJK0aeKvOIbXc9y2g8ILAhEA==",
|
||||
"version": "5.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-5.6.1.tgz",
|
||||
"integrity": "sha512-0/xS39c91WjPAZOWsvi1//zjx6kAp4kxWwctR6kuU6p133w8RU0D2dSCvZC19uQyharg/sAvYxGYWl01BbZZfg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ant-design/colors": "^7.0.0",
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^5.6.1",
|
||||
"@react-buddy/ide-toolbox": "^2.4.0",
|
||||
"@react-buddy/palette-antd": "^5.3.0",
|
||||
"antd": "^5.23.1",
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square70x70logo src="/favicon-70x70.png"/>
|
||||
<square150x150logo src="/favicon-150x150.png"/>
|
||||
<square310x310logo src="/favicon-310x310.png"/>
|
||||
<TileColor>#ffffff</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square70x70logo src="/favicon-70x70.png"/>
|
||||
<square150x150logo src="/favicon-150x150.png"/>
|
||||
<square310x310logo src="/favicon-310x310.png"/>
|
||||
<TileColor>#ffffff</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import {Routes, Route} from "react-router-dom";
|
||||
import PrivateRoute from "./components/PrivateRoute.jsx";
|
||||
import LoginPage from "./pages/LoginPage.jsx";
|
||||
import MainLayout from "./layouts/MainLayout.jsx";
|
||||
|
||||
|
||||
const AppRouter = () => (
|
||||
@ -8,7 +9,9 @@ const AppRouter = () => (
|
||||
<Route path="/login" element={<LoginPage/>}/>
|
||||
|
||||
<Route element={<PrivateRoute/>}>
|
||||
<Route path={"/"} element={<p>1234</p>}/>
|
||||
<Route element={<MainLayout/>}>
|
||||
<Route path={"/"} element={<p>1234</p>}/>
|
||||
</Route>
|
||||
</Route>
|
||||
</Routes>
|
||||
)
|
||||
|
||||
66
web-app/src/layouts/MainLayout.jsx
Normal file
66
web-app/src/layouts/MainLayout.jsx
Normal file
@ -0,0 +1,66 @@
|
||||
import {useState} from "react";
|
||||
import {Layout, Menu} from "antd";
|
||||
import {Outlet, useLocation, useNavigate} from "react-router-dom";
|
||||
import {
|
||||
DesktopOutlined,
|
||||
FileOutlined,
|
||||
PieChartOutlined,
|
||||
TeamOutlined,
|
||||
UserOutlined,
|
||||
} from "@ant-design/icons";
|
||||
|
||||
const {Content, Footer, Sider} = Layout;
|
||||
|
||||
const getItem = (label, key, icon, children) => ({
|
||||
key,
|
||||
icon,
|
||||
children,
|
||||
label,
|
||||
});
|
||||
|
||||
const items = [
|
||||
getItem("Главная", "/", <PieChartOutlined/>),
|
||||
getItem("Настройки", "/settings", <DesktopOutlined/>),
|
||||
getItem("Пользователи", "sub1", <UserOutlined/>, [
|
||||
getItem("Том", "/users/tom"),
|
||||
getItem("Билл", "/users/bill"),
|
||||
getItem("Алекс", "/users/alex"),
|
||||
]),
|
||||
getItem("Команда", "sub2", <TeamOutlined/>, [
|
||||
getItem("Команда 1", "/team/1"),
|
||||
getItem("Команда 2", "/team/2"),
|
||||
]),
|
||||
getItem("Файлы", "/files", <FileOutlined/>),
|
||||
];
|
||||
|
||||
const MainLayout = () => {
|
||||
const [collapsed, setCollapsed] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
|
||||
return (
|
||||
<Layout style={{minHeight: "100vh"}}>
|
||||
<Sider collapsible collapsed={collapsed} onCollapse={setCollapsed}>
|
||||
<Menu
|
||||
theme="dark"
|
||||
defaultSelectedKeys={[location.pathname]}
|
||||
mode="inline"
|
||||
items={items}
|
||||
onClick={({key}) => navigate(key)}
|
||||
/>
|
||||
</Sider>
|
||||
|
||||
<Layout>
|
||||
<Content style={{margin: "0 16px"}}>
|
||||
<div style={{padding: 24, minHeight: 360, background: "#fff", borderRadius: 8}}>
|
||||
<Outlet/>
|
||||
</div>
|
||||
</Content>
|
||||
|
||||
<Footer style={{textAlign: "center"}}>Линза+ © {new Date().getFullYear()}</Footer>
|
||||
</Layout>
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
|
||||
export default MainLayout;
|
||||
@ -1,20 +1,30 @@
|
||||
import {Form, Input, Button, Row, Col, Typography} from 'antd';
|
||||
import {useState} from 'react';
|
||||
import {useEffect, useState} from 'react';
|
||||
import {useAuth} from "../AuthContext.jsx";
|
||||
import {useNavigate} from "react-router-dom";
|
||||
|
||||
const {Title} = Typography;
|
||||
|
||||
const LoginPage = () => {
|
||||
const {login} = useAuth();
|
||||
const {user, login} = useAuth();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState(null);
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
if (user) {
|
||||
navigate("/");
|
||||
}
|
||||
}, [user, navigate]);
|
||||
|
||||
const onFinish = async (values) => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
await login(values);
|
||||
navigate("/");
|
||||
} catch (error) {
|
||||
setError(`Ошибка при входе: ${error.message}`);
|
||||
} finally {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user