mirror of
https://github.com/lemeow125/EquipmentTracker-Frontend.git
synced 2024-11-17 06:09:25 +08:00
Added revalidation component to restore previous user sessions
This commit is contained in:
parent
139c0a3e3c
commit
f4468d4010
4 changed files with 103 additions and 20 deletions
15
src/App.tsx
15
src/App.tsx
|
@ -8,17 +8,28 @@ import { ToastContainer } from "react-toastify";
|
||||||
import "react-toastify/dist/ReactToastify.css";
|
import "react-toastify/dist/ReactToastify.css";
|
||||||
import ErrorPage from "./Pages/ErrorPage/ErrorPage";
|
import ErrorPage from "./Pages/ErrorPage/ErrorPage";
|
||||||
import DashboardPage from "./Pages/DashboardPage/DashboardPage";
|
import DashboardPage from "./Pages/DashboardPage/DashboardPage";
|
||||||
|
import Revalidator from "./Components/Revalidator/Revalidator";
|
||||||
|
|
||||||
const queryClient = new QueryClient();
|
const queryClient = new QueryClient();
|
||||||
const router = createHashRouter([
|
const router = createHashRouter([
|
||||||
{
|
{
|
||||||
path: "/",
|
path: "/",
|
||||||
element: <LandingPage />,
|
element: (
|
||||||
|
<>
|
||||||
|
<Revalidator />
|
||||||
|
<LandingPage />
|
||||||
|
</>
|
||||||
|
),
|
||||||
errorElement: <ErrorPage />,
|
errorElement: <ErrorPage />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/dashboard",
|
path: "/dashboard",
|
||||||
element: <DashboardPage />,
|
element: (
|
||||||
|
<>
|
||||||
|
<Revalidator />
|
||||||
|
<DashboardPage />
|
||||||
|
</>
|
||||||
|
),
|
||||||
errorElement: <ErrorPage />,
|
errorElement: <ErrorPage />,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -1,10 +1,40 @@
|
||||||
|
/* eslint-disable react-refresh/only-export-components */
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { ActivationType, LoginType, RegisterType } from "../Types/Types";
|
import { ActivationType, LoginType, RegisterType } from "../Types/Types";
|
||||||
|
|
||||||
// Product APIs
|
|
||||||
const instance = axios.create({
|
const instance = axios.create({
|
||||||
baseURL: "http://localhost:8000/",
|
baseURL: "http://localhost:8000/",
|
||||||
});
|
});
|
||||||
|
// Token Handling
|
||||||
|
export async function getAccessToken() {
|
||||||
|
const accessToken = await localStorage.getItem("access_token");
|
||||||
|
return accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getRefreshToken() {
|
||||||
|
const refreshToken = await localStorage.getItem("refresh_token");
|
||||||
|
return refreshToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function setAccessToken(access: string) {
|
||||||
|
await localStorage.setItem("access_token", access);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function setRefreshToken(refresh: string) {
|
||||||
|
await localStorage.setItem("refresh_token", refresh);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Header Config Template for REST
|
||||||
|
export async function GetConfig() {
|
||||||
|
const accessToken = await getAccessToken();
|
||||||
|
return {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${accessToken}`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// User APIs
|
// User APIs
|
||||||
|
|
||||||
|
@ -25,7 +55,10 @@ export function LoginAPI(user: LoginType) {
|
||||||
return instance
|
return instance
|
||||||
.post("api/v1/accounts/jwt/create/", user)
|
.post("api/v1/accounts/jwt/create/", user)
|
||||||
.then(async (response) => {
|
.then(async (response) => {
|
||||||
localStorage.setItem("token", JSON.stringify(response.data.auth_token));
|
console.log(response.data);
|
||||||
|
setAccessToken(response.data.access);
|
||||||
|
setRefreshToken(response.data.refresh);
|
||||||
|
|
||||||
console.log("Login Success ");
|
console.log("Login Success ");
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
|
@ -35,6 +68,21 @@ export function LoginAPI(user: LoginType) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function JWTRefreshAPI() {
|
||||||
|
const refresh = await getRefreshToken();
|
||||||
|
return instance
|
||||||
|
.post("api/v1/accounts/jwt/refresh/", {
|
||||||
|
refresh: refresh,
|
||||||
|
})
|
||||||
|
.then(async (response) => {
|
||||||
|
setAccessToken(response.data.access);
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function UserAPI() {
|
export function UserAPI() {
|
||||||
const token = JSON.parse(localStorage.getItem("token") || "{}");
|
const token = JSON.parse(localStorage.getItem("token") || "{}");
|
||||||
return instance
|
return instance
|
||||||
|
@ -44,7 +92,6 @@ export function UserAPI() {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
console.log(response.data);
|
|
||||||
return response.data;
|
return response.data;
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
|
|
|
@ -1,28 +1,14 @@
|
||||||
import { useEffect, useState } from "react";
|
import { useState } from "react";
|
||||||
import styles, { colors } from "../../styles";
|
import styles, { colors } from "../../styles";
|
||||||
import MenuIcon from "@mui/icons-material/Menu";
|
import MenuIcon from "@mui/icons-material/Menu";
|
||||||
import SidebarModal from "../SidebarModal/SidebarModal";
|
import SidebarModal from "../SidebarModal/SidebarModal";
|
||||||
import { Drawer } from "@mui/material";
|
import { Drawer } from "@mui/material";
|
||||||
import { useSelector } from "react-redux";
|
|
||||||
import { RootState } from "../Plugins/Redux/Store/Store";
|
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
|
|
||||||
export interface props {
|
export interface props {
|
||||||
label: string;
|
label: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Header(props: props) {
|
export default function Header(props: props) {
|
||||||
const [SidebarOpen, SetSidebarOpen] = useState(false);
|
const [SidebarOpen, SetSidebarOpen] = useState(false);
|
||||||
const authenticated = useSelector((state: RootState) => state.auth.value);
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!authenticated) {
|
|
||||||
navigate("/");
|
|
||||||
console.log("Not logged in. Redirecting to landing page");
|
|
||||||
}
|
|
||||||
}, [authenticated, navigate]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
|
|
39
src/Components/Revalidator/Revalidator.tsx
Normal file
39
src/Components/Revalidator/Revalidator.tsx
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { JWTRefreshAPI, setAccessToken, setRefreshToken } from "../API/API";
|
||||||
|
import { auth_toggle } from "../Plugins/Redux/Slices/AuthSlice/AuthSlice";
|
||||||
|
import { RootState } from "../Plugins/Redux/Store/Store";
|
||||||
|
|
||||||
|
export default function Revalidator() {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const authenticated = useSelector((state: RootState) => state.auth.value);
|
||||||
|
const [rechecked, setRechecked] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!authenticated && rechecked) {
|
||||||
|
navigate("/");
|
||||||
|
console.log("Not logged in");
|
||||||
|
}
|
||||||
|
}, [authenticated, navigate, rechecked]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!authenticated) {
|
||||||
|
JWTRefreshAPI().then(async (response) => {
|
||||||
|
if (response) {
|
||||||
|
await dispatch(auth_toggle());
|
||||||
|
navigate("/dashboard");
|
||||||
|
console.log("User session restored");
|
||||||
|
} else {
|
||||||
|
await setRefreshToken("");
|
||||||
|
await setAccessToken("");
|
||||||
|
console.log("User session expired");
|
||||||
|
}
|
||||||
|
setRechecked(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return <></>;
|
||||||
|
}
|
Loading…
Reference in a new issue