diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 78f312c..6a3468f 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -11,6 +11,7 @@ import Calendar from "./components/calendar/calendar"; import KanbanBoard from "./components/kanbanBoard/kanbanBoard"; import IconSideNav from "./components/navigations/IconSideNav"; import Eisenhower from "./components/eisenhowerMatrix/Eisenhower"; +import PrivateRoute from "./PrivateRoute"; const App = () => { const location = useLocation(); @@ -18,24 +19,32 @@ const App = () => { const isLoginPageOrSignUpPage = prevention.some(_ => location.pathname.includes(_)); return ( -
- {!isLoginPageOrSignUpPage && } -
- -
- - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - -
+
+ {!isLoginPageOrSignUpPage && } +
+ +
+ + } /> + }> + } /> + + } /> + }> + } /> + + }> + } /> + + }> + } /> + + } /> + } /> +
+
); }; diff --git a/frontend/src/PrivateRoute.jsx b/frontend/src/PrivateRoute.jsx new file mode 100644 index 0000000..936a7d9 --- /dev/null +++ b/frontend/src/PrivateRoute.jsx @@ -0,0 +1,10 @@ +import React from 'react'; +import { Navigate, Outlet } from 'react-router-dom'; +import IsAuthenticated from './hooks/authentication/IsAuthenticated'; + +const PrivateRoute = () => { + const auth = IsAuthenticated(); + return auth ? : ; +} + +export default PrivateRoute; \ No newline at end of file diff --git a/frontend/src/api/configs/AxiosConfig.jsx b/frontend/src/api/configs/AxiosConfig.jsx index 80015ac..a6469ae 100644 --- a/frontend/src/api/configs/AxiosConfig.jsx +++ b/frontend/src/api/configs/AxiosConfig.jsx @@ -1,4 +1,5 @@ import axios from 'axios'; +import { redirect } from 'react-router-dom'; const axiosInstance = axios.create({ baseURL: 'http://127.0.0.1:8000/api/', @@ -16,7 +17,7 @@ axiosInstance.interceptors.response.use( error => { const originalRequest = error.config; const refresh_token = localStorage.getItem('refresh_token'); - + // Check if the error is due to 401 and a refresh token is available if (error.response.status === 401 && error.response.statusText === "Unauthorized" && refresh_token !== "undefined") { return axiosInstance diff --git a/frontend/src/components/authentication/IsAuthenticated.jsx b/frontend/src/components/authentication/IsAuthenticated.jsx deleted file mode 100644 index 48322de..0000000 --- a/frontend/src/components/authentication/IsAuthenticated.jsx +++ /dev/null @@ -1,19 +0,0 @@ -import { useState, useEffect } from 'react'; - -function IsAuthenticated() { - const [isAuthenticated, setIsAuthenticated] = useState(false); - - useEffect(() => { - const access_token = localStorage.getItem('access_token'); - - if (access_token) { - setIsAuthenticated(true); - } else { - setIsAuthenticated(false); - } - }, []); - - return isAuthenticated; -} - -export default IsAuthenticated; \ No newline at end of file diff --git a/frontend/src/components/navigations/Navbar.jsx b/frontend/src/components/navigations/Navbar.jsx index 75cd8a7..9328e1c 100644 --- a/frontend/src/components/navigations/Navbar.jsx +++ b/frontend/src/components/navigations/Navbar.jsx @@ -1,6 +1,6 @@ import * as React from "react"; import { useNavigate } from "react-router-dom"; -import IsAuthenticated from "../authentication/IsAuthenticated"; +import IsAuthenticated from "../../hooks/authentication/IsAuthenticated"; import axiosapi from "../../api/AuthenticationApi"; const settings = { diff --git a/frontend/src/hooks/authentication/IsAuthenticated.jsx b/frontend/src/hooks/authentication/IsAuthenticated.jsx new file mode 100644 index 0000000..a132fb2 --- /dev/null +++ b/frontend/src/hooks/authentication/IsAuthenticated.jsx @@ -0,0 +1,25 @@ +import { useEffect, useState } from 'react'; + +function IsAuthenticated() { + const [isAuthenticated, setIsAuthenticated] = useState(() => { + const access_token = localStorage.getItem('access_token'); + return !!access_token; + }); + + useEffect(() => { + const handleTokenChange = () => { + const newAccessToken = localStorage.getItem('access_token'); + setIsAuthenticated(!!newAccessToken); + }; + + window.addEventListener('storage', handleTokenChange); + + return () => { + window.removeEventListener('storage', handleTokenChange); + }; + }, []); + + return isAuthenticated; +} + +export default IsAuthenticated; diff --git a/frontend/src/main.jsx b/frontend/src/main.jsx index f5430b9..262782a 100644 --- a/frontend/src/main.jsx +++ b/frontend/src/main.jsx @@ -1,15 +1,17 @@ -import React from "react"; +import React, { Fragment } from "react"; import ReactDOM from "react-dom/client"; import App from "./App"; -import { GoogleOAuthProvider} from '@react-oauth/google'; -import { BrowserRouter } from 'react-router-dom'; +import { GoogleOAuthProvider } from "@react-oauth/google"; +import { BrowserRouter } from "react-router-dom"; -const GOOGLE_CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID +const GOOGLE_CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID; ReactDOM.createRoot(document.getElementById("root")).render( - + + + -); \ No newline at end of file +);