сделал авторизацию

This commit is contained in:
Андрей Дувакин 2025-02-07 19:19:47 +05:00
parent e2958b9de6
commit 8e85ea7b23
26 changed files with 114 additions and 6 deletions

View File

@ -3,7 +3,27 @@
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Линза+</title> <title>Линза </title>
<link rel="apple-touch-icon" sizes="57x57" href="/favicons/favicon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/favicons/favicon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/favicons/favicon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="/favicons/favicon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="/favicons/favicon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="/favicons/favicon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/favicons/favicon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/favicons/favicon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/favicons/favicon-180x180.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicons/favicon-16x16.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="/favicons/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="192x192" href="/favicons/favicon-192x192.png">
<link rel="shortcut icon" type="image/x-icon" href="/favicons/favicon.ico">
<link rel="icon" type="image/x-icon" href="/favicons/favicon.ico">
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-TileImage" content="/favicons/favicon-144x144.png">
<meta name="msapplication-config" content="/favicons/browserconfig.xml">
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>

View File

@ -0,0 +1,12 @@
<?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>
</browserconfig>

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 681 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 496 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 KiB

View File

@ -1,13 +1,14 @@
import {Routes, Route} from "react-router-dom"; import {Routes, Route} from "react-router-dom";
import PrivateRoute from "./components/PrivateRoute.jsx"; import PrivateRoute from "./components/PrivateRoute.jsx";
import LoginPage from "./pages/LoginPage.jsx";
const AppRouter = () => ( const AppRouter = () => (
<Routes> <Routes>
<Route path="/login"/> <Route path="/login" element={<LoginPage/>}/>
<Route element={<PrivateRoute/>}> <Route element={<PrivateRoute/>}>
<Route path={"/"} element={<p>1234</p>}/>
</Route> </Route>
</Routes> </Routes>
) )

View File

@ -18,9 +18,10 @@ export const AuthProvider = ({children}) => {
try { try {
const token = await loginUser(loginData); const token = await loginUser(loginData);
localStorage.setItem("access_token", token); localStorage.setItem("access_token", token);
setUser({ token }); setUser({token});
} catch (error) { } catch (error) {
console.error("Login failed", error); console.error("Login failed", error);
throw error;
} }
}; };

View File

@ -2,12 +2,17 @@ import axios from "axios";
import CONFIG from "../core/Config.jsx"; import CONFIG from "../core/Config.jsx";
export const loginUser = async (loginData) => { export const loginUser = async (loginData) => {
console.log(loginData)
try { try {
const response = await axios.post(`${CONFIG.BASE_URL}/login/`, loginData, { const response = await axios.post(`${CONFIG.BASE_URL}/login/`, loginData, {
withCredentials: true, withCredentials: true,
}); });
return response.data.access_token; return response.data.access_token;
} catch (error) { } catch (error) {
throw new Error("Login failed: " + error.message); if (error.status === 401) {
throw new Error("Неверное имя пользователя или пароль")
}
throw new Error(error.message);
} }
}; };

View File

@ -1,5 +1,5 @@
const CONFIG = { const CONFIG = {
BASE_URL: 'http://localhost:8080/api/v1/', BASE_URL: 'http://localhost:8000/api/v1',
}; };
export default CONFIG; export default CONFIG;

View File

@ -0,0 +1,69 @@
import {Form, Input, Button, Row, Col, Typography} from 'antd';
import {useState} from 'react';
import {useAuth} from "../AuthContext.jsx";
const {Title} = Typography;
const LoginPage = () => {
const {login} = useAuth();
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const onFinish = async (values) => {
setLoading(true);
setError(null);
try {
await login(values);
} catch (error) {
setError(`Ошибка при входе: ${error.message}`);
} finally {
setLoading(false);
}
};
return (
<Row justify="center" align="middle" style={{minHeight: '100vh'}}>
<Col xs={24} sm={18} md={12} lg={8} xl={6}>
<div style={{padding: 20, border: '1px solid #ddd', borderRadius: 8}}>
<Title level={2} style={{textAlign: 'center'}}>Авторизация</Title>
{error && <div style={{color: 'red', marginBottom: 15}}>{error}</div>}
<Form
name="login"
initialValues={{remember: true}}
onFinish={onFinish}
>
<Form.Item
name="login"
rules={[{required: true, message: 'Пожалуйста, введите логин'}]}
>
<Input placeholder="Логин"/>
</Form.Item>
<Form.Item
name="password"
rules={[{required: true, message: 'Пожалуйста, введите пароль'}]}
>
<Input.Password placeholder="Пароль"/>
</Form.Item>
<Form.Item>
<Button
type="primary"
htmlType="submit"
block
loading={loading}
>
Войти
</Button>
</Form.Item>
</Form>
</div>
</Col>
</Row>
);
};
export default LoginPage;