From f411ea00a45db71771b83c1617532063c302cb94 Mon Sep 17 00:00:00 2001 From: keannu125 Date: Mon, 6 Mar 2023 13:06:43 +0800 Subject: [PATCH] Allow querying for saved login session --- src/App.tsx | 10 +++--- src/Components/Api/Api.tsx | 34 +++++++++++++++---- src/Components/Container/Container.tsx | 18 +++++++++- src/Components/Login/Login.tsx | 10 ++++-- src/Components/Logout/Logout.tsx | 2 +- .../LoggedInUserSlice/LoggedInUserSlice.tsx | 33 ++++++++++++++++++ .../{ => Redux/Slices}/Login/LoginSlice.tsx | 0 src/Interfaces/Interfaces.tsx | 2 +- src/Plugins/Redux/Store/Store.tsx | 4 ++- src/Routes/Login/Login.tsx | 8 +++-- src/index.tsx | 18 ++++------ 11 files changed, 107 insertions(+), 32 deletions(-) create mode 100644 src/Features/Redux/Slices/LoggedInUserSlice/LoggedInUserSlice.tsx rename src/Features/{ => Redux/Slices}/Login/LoginSlice.tsx (100%) diff --git a/src/App.tsx b/src/App.tsx index 414c525..203be88 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useEffect } from "react"; import Dashboard from "./Routes/Dashboard/Dashboard"; import Error from "./Routes/Error/Error"; import Products from "./Routes/Products/Products"; @@ -60,10 +60,8 @@ const router = createBrowserRouter([ export default function App() { return ( - - - - - + + + ); } diff --git a/src/Components/Api/Api.tsx b/src/Components/Api/Api.tsx index ac5c5e4..bddfe1f 100644 --- a/src/Components/Api/Api.tsx +++ b/src/Components/Api/Api.tsx @@ -6,6 +6,9 @@ import { LoginParams, RegistrationParams, } from "../../Interfaces/Interfaces"; +import { useDispatch } from "react-redux"; +import { SetUser } from "../../Features/Redux/Slices/LoggedInUserSlice/LoggedInUserSlice"; +import { toggle_login } from "../../Features/Redux/Slices/Login/LoginSlice"; // Note APIs @@ -47,7 +50,7 @@ export function UpdateProduct(note: UpdateProductParams) { return response.data; }) .catch((error) => { - console.log("Error updating product", error); + console.log("Error updating product", error.response); return error; }); } @@ -64,7 +67,7 @@ export function AddProduct(note: AddProductParams) { return response.data; }) .catch((error) => { - console.log("Error adding product", error); + console.log("Error adding product", error.response); return error; }); } @@ -78,7 +81,7 @@ export function DeleteProduct(id: number) { }, }) .catch((error) => { - console.log("Error deleting product", error); + console.log("Error deleting product", error.response); return error; }); } @@ -93,7 +96,7 @@ export function UserRegister(register: RegistrationParams) { return true; }) .catch((error) => { - console.log("Registration failed: " + error); + console.log("Registration failed: " + error.response); return false; }); } @@ -110,7 +113,7 @@ export function UserLogin(user: LoginParams) { return true; }) .catch((error) => { - console.log("Login Failed: " + error); + console.log("Login Failed: " + error.response); return false; }); } @@ -126,6 +129,10 @@ export function UserInfo() { .then((response) => { console.log(response.data); return response.data; + }) + .catch((error) => { + console.log("Error retrieving user data", error.response); + return false; }); } @@ -137,7 +144,22 @@ export function UserActivate(activation: ActivationParams) { return true; }) .catch((error) => { - console.log("Activation failed: " + error); + console.log("Activation failed: " + error.response); return false; }); } + +export async function CheckSavedSession() { + console.log("Checking for saved session by querying user data"); + if (JSON.parse(localStorage.getItem("token") || "{}")) { + if (await UserInfo()) { + console.log("Previous session found"); + return true; + } else { + console.log("Previous session found but expired"); + return false; + } + } + console.log("No previous session found"); + return false; +} diff --git a/src/Components/Container/Container.tsx b/src/Components/Container/Container.tsx index a664f9d..906ffe1 100644 --- a/src/Components/Container/Container.tsx +++ b/src/Components/Container/Container.tsx @@ -1,13 +1,29 @@ -import React from "react"; +import React, { useEffect } from "react"; import Sidebar from "../Sidebar/Sidebar"; import Header from "../Header/Header"; import styles from "../../styles"; +import { CheckSavedSession, UserInfo } from "../Api/Api"; +import { toggle_login } from "../../Features/Redux/Slices/Login/LoginSlice"; +import { SetUser } from "../../Features/Redux/Slices/LoggedInUserSlice/LoggedInUserSlice"; +import { useDispatch } from "react-redux"; export interface props { children: React.ReactNode; } export default function Container(props: props) { + const dispatch = useDispatch(); + // Function to check for previous login session + async function CheckPreviousSession() { + if (await CheckSavedSession()) { + await dispatch(toggle_login()); + await dispatch(SetUser(await UserInfo())); + } + } + useEffect(() => { + CheckPreviousSession(); + }, []); + return (
diff --git a/src/Components/Login/Login.tsx b/src/Components/Login/Login.tsx index 4a33838..0dbcc93 100644 --- a/src/Components/Login/Login.tsx +++ b/src/Components/Login/Login.tsx @@ -1,8 +1,9 @@ import { useSelector, useDispatch } from "react-redux"; -import { toggle_login } from "../../Features/Login/LoginSlice"; +import { toggle_login } from "../../Features/Redux/Slices/Login/LoginSlice"; import { Button } from "@mui/material"; import styles from "../../styles"; import { useNavigate } from "react-router-dom"; +import { LoggedInUserState } from "../../Interfaces/Interfaces"; export interface state { logged_in: { @@ -11,6 +12,9 @@ export interface state { } export default function Login() { const logged_in = useSelector((state: state) => state.logged_in.value); + const logged_in_user = useSelector( + (state: LoggedInUserState) => state.logged_in_user.value + ); const navigate = useNavigate(); const dispatch = useDispatch(); async function login() { @@ -20,7 +24,9 @@ export default function Login() { if (logged_in) { return ( -

Welcome Jophiel

+

+ Logged in as {logged_in_user.username} +

); } else { return ( diff --git a/src/Components/Logout/Logout.tsx b/src/Components/Logout/Logout.tsx index 226aabc..036f478 100644 --- a/src/Components/Logout/Logout.tsx +++ b/src/Components/Logout/Logout.tsx @@ -1,6 +1,6 @@ import React from "react"; import { useDispatch } from "react-redux"; -import { toggle_login } from "../../Features/Login/LoginSlice"; +import { toggle_login } from "../../Features/Redux/Slices/Login/LoginSlice"; import { Button } from "@mui/material"; import styles from "../../styles"; import { useNavigate } from "react-router-dom"; diff --git a/src/Features/Redux/Slices/LoggedInUserSlice/LoggedInUserSlice.tsx b/src/Features/Redux/Slices/LoggedInUserSlice/LoggedInUserSlice.tsx new file mode 100644 index 0000000..2fa228a --- /dev/null +++ b/src/Features/Redux/Slices/LoggedInUserSlice/LoggedInUserSlice.tsx @@ -0,0 +1,33 @@ +import { createSlice } from "@reduxjs/toolkit"; + +export const LoggedInUserSlice = createSlice({ + name: "Login", + initialState: { + value: { + email: "", + id: 0, + username: "", + }, + }, + reducers: { + SetUser: (state, action) => { + state.value = { + email: action.payload.email, + id: action.payload.id, + username: action.payload.username, + }; + }, + UnsetUser: (state) => { + state.value = { + email: "", + id: 0, + username: "", + }; + }, + }, +}); + +// Action creators are generated for each case reducer function +export const { SetUser, UnsetUser } = LoggedInUserSlice.actions; + +export default LoggedInUserSlice.reducer; diff --git a/src/Features/Login/LoginSlice.tsx b/src/Features/Redux/Slices/Login/LoginSlice.tsx similarity index 100% rename from src/Features/Login/LoginSlice.tsx rename to src/Features/Redux/Slices/Login/LoginSlice.tsx diff --git a/src/Interfaces/Interfaces.tsx b/src/Interfaces/Interfaces.tsx index 300bb2b..e3bf52c 100644 --- a/src/Interfaces/Interfaces.tsx +++ b/src/Interfaces/Interfaces.tsx @@ -14,7 +14,7 @@ export interface LoginState { } export interface LoggedInUserState { - LoggedInUser: { + logged_in_user: { value: { email: string; id: number; diff --git a/src/Plugins/Redux/Store/Store.tsx b/src/Plugins/Redux/Store/Store.tsx index 65ca2bc..169e668 100644 --- a/src/Plugins/Redux/Store/Store.tsx +++ b/src/Plugins/Redux/Store/Store.tsx @@ -1,8 +1,10 @@ import { configureStore } from "@reduxjs/toolkit"; -import LoginReducer from "../../../Features/Login/LoginSlice"; +import LoginReducer from "../../../Features/Redux/Slices/Login/LoginSlice"; +import LoggedInUserReducer from "../../../Features/Redux/Slices/LoggedInUserSlice/LoggedInUserSlice"; export default configureStore({ reducer: { logged_in: LoginReducer, + logged_in_user: LoggedInUserReducer, }, }); diff --git a/src/Routes/Login/Login.tsx b/src/Routes/Login/Login.tsx index d217113..f728fce 100644 --- a/src/Routes/Login/Login.tsx +++ b/src/Routes/Login/Login.tsx @@ -6,8 +6,9 @@ import { useDispatch } from "react-redux"; import { useNavigate } from "react-router-dom"; import { useState } from "react"; -import { UserLogin } from "../../Components/Api/Api"; -import { toggle_login } from "../../Features/Login/LoginSlice"; +import { UserInfo, UserLogin } from "../../Components/Api/Api"; +import { toggle_login } from "../../Features/Redux/Slices/Login/LoginSlice"; +import { SetUser } from "../../Features/Redux/Slices/LoggedInUserSlice/LoggedInUserSlice"; export default function Login() { const navigate = useNavigate(); @@ -68,7 +69,7 @@ export default function Login() { }); if (await UserLogin(user)) { await dispatch(toggle_login()); - // await dispatch(SetUser(await UserInfo())); + await dispatch(SetUser(await UserInfo())); navigate("/"); } else { setError("Invalid Login"); @@ -89,6 +90,7 @@ export default function Login() { > Register +

{error}

); diff --git a/src/index.tsx b/src/index.tsx index 032464f..50f8f2f 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,17 +1,13 @@ -import React from 'react'; -import ReactDOM from 'react-dom/client'; -import './index.css'; -import App from './App'; -import reportWebVitals from './reportWebVitals'; +import React from "react"; +import ReactDOM from "react-dom/client"; +import "./index.css"; +import App from "./App"; +import reportWebVitals from "./reportWebVitals"; const root = ReactDOM.createRoot( - document.getElementById('root') as HTMLElement -); -root.render( - - - + document.getElementById("root") as HTMLElement ); +root.render(); // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log))