From e2958b9de6f923c3c4111359c5e0ddc57d6ac5fc Mon Sep 17 00:00:00 2001 From: Andrei Duvakin Date: Fri, 7 Feb 2025 13:17:30 +0500 Subject: [PATCH] =?UTF-8?q?=D1=81=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=20=D0=BF?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=B0=D0=B9=D0=B4=D0=B5=D1=80=20=D0=B8=20?= =?UTF-8?q?=D0=B7=D0=B0=D1=89=D0=B8=D1=89=D0=B5=D0=BD=D0=BD=D1=8B=D0=B5=20?= =?UTF-8?q?=D1=80=D0=BE=D1=83=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/domain/entities/user.py | 2 +- web-app/package-lock.json | 4 +-- web-app/package.json | 7 ++-- web-app/src/App.jsx | 17 ++++++---- web-app/src/AppRouter.jsx | 15 +++++++++ web-app/src/AuthContext.jsx | 45 +++++++++++++++++++++++++ web-app/src/api/LoginRequest.jsx | 13 +++++++ web-app/src/components/PrivateRoute.jsx | 14 ++++++++ web-app/src/core/Config.jsx | 5 +++ 9 files changed, 108 insertions(+), 14 deletions(-) create mode 100644 web-app/src/AppRouter.jsx create mode 100644 web-app/src/AuthContext.jsx create mode 100644 web-app/src/api/LoginRequest.jsx create mode 100644 web-app/src/components/PrivateRoute.jsx create mode 100644 web-app/src/core/Config.jsx diff --git a/api/app/domain/entities/user.py b/api/app/domain/entities/user.py index 8ab8c37..ba2347b 100644 --- a/api/app/domain/entities/user.py +++ b/api/app/domain/entities/user.py @@ -8,7 +8,7 @@ class UserEntity(BaseModel): first_name: str = Field(..., example='Ivan') last_name: str = Field(..., example='Ivanov') patronymic: Optional[str] = Field(None, example='Ivanov') - login: str = Field(..., example='user@example.com') + login: str = Field(..., example='ivanov74') role_id: int = Field(..., example=1) diff --git a/web-app/package-lock.json b/web-app/package-lock.json index 4b92f5e..0680458 100644 --- a/web-app/package-lock.json +++ b/web-app/package-lock.json @@ -12,6 +12,7 @@ "@react-buddy/palette-antd": "^5.3.0", "antd": "^5.23.1", "axios": "^1.7.9", + "prop-types": "^15.8.1", "react": "^18.3.1", "react-dom": "^18.3.1", "react-router-dom": "^7.1.1" @@ -3617,7 +3618,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -3888,7 +3888,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", @@ -4552,7 +4551,6 @@ "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true, "license": "MIT" }, "node_modules/react-router": { diff --git a/web-app/package.json b/web-app/package.json index e811463..c1149c1 100644 --- a/web-app/package.json +++ b/web-app/package.json @@ -10,13 +10,14 @@ "preview": "vite preview" }, "dependencies": { + "@react-buddy/ide-toolbox": "^2.4.0", + "@react-buddy/palette-antd": "^5.3.0", "antd": "^5.23.1", "axios": "^1.7.9", + "prop-types": "^15.8.1", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-router-dom": "^7.1.1", - "@react-buddy/ide-toolbox": "^2.4.0", - "@react-buddy/palette-antd": "^5.3.0" + "react-router-dom": "^7.1.1" }, "devDependencies": { "@eslint/js": "^9.17.0", diff --git a/web-app/src/App.jsx b/web-app/src/App.jsx index f240c23..506895e 100644 --- a/web-app/src/App.jsx +++ b/web-app/src/App.jsx @@ -1,10 +1,13 @@ -function App() { +import {BrowserRouter as Router} from "react-router-dom"; +import AppRouter from "./AppRouter.jsx"; +import {AuthProvider} from "./AuthContext.jsx"; - return ( - <> -

1234

- - ) -} +const App = () => ( + + + + + +); export default App diff --git a/web-app/src/AppRouter.jsx b/web-app/src/AppRouter.jsx new file mode 100644 index 0000000..7b6487d --- /dev/null +++ b/web-app/src/AppRouter.jsx @@ -0,0 +1,15 @@ +import {Routes, Route} from "react-router-dom"; +import PrivateRoute from "./components/PrivateRoute.jsx"; + + +const AppRouter = () => ( + + + + }> + + + +) + +export default AppRouter; \ No newline at end of file diff --git a/web-app/src/AuthContext.jsx b/web-app/src/AuthContext.jsx new file mode 100644 index 0000000..c7ea3c7 --- /dev/null +++ b/web-app/src/AuthContext.jsx @@ -0,0 +1,45 @@ +import {createContext, useState, useContext, useEffect} from "react"; +import PropTypes from "prop-types"; +import {loginUser} from "./api/LoginRequest.jsx"; + +const AuthContext = createContext(undefined); + +export const AuthProvider = ({children}) => { + const [user, setUser] = useState(null); + + useEffect(() => { + const token = localStorage.getItem("access_token"); + if (token) { + setUser({token}); + } + }, []); + + const login = async (loginData) => { + try { + const token = await loginUser(loginData); + localStorage.setItem("access_token", token); + setUser({ token }); + } catch (error) { + console.error("Login failed", error); + } + }; + + const logout = () => { + localStorage.removeItem("access_token"); + setUser(null); + }; + + return ( + + {children} + + ); +}; + +AuthProvider.propTypes = { + children: PropTypes.node.isRequired, +}; + +export const useAuth = () => { + return useContext(AuthContext); +}; diff --git a/web-app/src/api/LoginRequest.jsx b/web-app/src/api/LoginRequest.jsx new file mode 100644 index 0000000..15a6bd5 --- /dev/null +++ b/web-app/src/api/LoginRequest.jsx @@ -0,0 +1,13 @@ +import axios from "axios"; +import CONFIG from "../core/Config.jsx"; + +export const loginUser = async (loginData) => { + try { + const response = await axios.post(`${CONFIG.BASE_URL}/login/`, loginData, { + withCredentials: true, + }); + return response.data.access_token; + } catch (error) { + throw new Error("Login failed: " + error.message); + } +}; diff --git a/web-app/src/components/PrivateRoute.jsx b/web-app/src/components/PrivateRoute.jsx new file mode 100644 index 0000000..e9553ad --- /dev/null +++ b/web-app/src/components/PrivateRoute.jsx @@ -0,0 +1,14 @@ +import {Navigate, Outlet} from "react-router-dom"; +import {useAuth} from "../AuthContext.jsx"; + +const PrivateRoute = () => { + const {user} = useAuth(); + + if (!user) { + return ; + } + + return ; +}; + +export default PrivateRoute; diff --git a/web-app/src/core/Config.jsx b/web-app/src/core/Config.jsx new file mode 100644 index 0000000..78ec13c --- /dev/null +++ b/web-app/src/core/Config.jsx @@ -0,0 +1,5 @@ +const CONFIG = { + BASE_URL: 'http://localhost:8080/api/v1/', +}; + +export default CONFIG; \ No newline at end of file