diff --git a/Client/src/Features/Auth/authSlice.js b/Client/src/Features/Auth/authSlice.js index d361ffa05..bef6e8630 100644 --- a/Client/src/Features/Auth/authSlice.js +++ b/Client/src/Features/Auth/authSlice.js @@ -23,7 +23,12 @@ export const register = createAsyncThunk( ); export const login = createAsyncThunk("auth/login", async (form, thunkApi) => { - console.log(form); + try { + const res = await axios.post(`${BASE_URL}/auth/login`, form); + return res.data; + } catch (error) { + return thunkApi.rejectWithValue(error.response.data); + } }); const authSlice = createSlice({ @@ -32,6 +37,7 @@ const authSlice = createSlice({ reducers: {}, extraReducers: (builder) => { builder + // Register thunk .addCase(register.pending, (state, action) => { state.isLoading = true; }) @@ -47,6 +53,23 @@ const authSlice = createSlice({ state.isLoading = false; state.success = action.payload.success; state.msg = action.payload.msg; + }) + // Login thunk + .addCase(login.pending, (state, action) => { + state.isLoading = true; + }) + .addCase(login.fulfilled, (state, action) => { + state.isLoading = false; + state.success = action.payload.success; + state.msg = action.payload.msg; + const decodedToken = jwtDecode(action.payload.data); + const user = { ...decodedToken }; + state.user = user; + }) + .addCase(login.rejected, (state, action) => { + state.isLoading = false; + state.success = action.payload.success; + state.msg = action.payload.msg; }); }, }); diff --git a/Client/src/Pages/Login/index.jsx b/Client/src/Pages/Login/index.jsx index 3732e52c8..593f5aee1 100644 --- a/Client/src/Pages/Login/index.jsx +++ b/Client/src/Pages/Login/index.jsx @@ -1,4 +1,6 @@ import { useState, useEffect } from "react"; +import { useNavigate } from "react-router-dom"; + import "./index.css"; import BackgroundPattern from "../../Components/BackgroundPattern/BackgroundPattern"; import Logomark from "../../assets/Images/Logomark.png"; @@ -14,6 +16,7 @@ import { useDispatch } from "react-redux"; const Login = () => { const dispatch = useDispatch(); + const navigate = useNavigate(); const idMap = { "login-email-input": "email", @@ -38,19 +41,51 @@ const Login = () => { return { ...acc, [err.path[0]]: err.message }; }, {}); setErrors(validationErrors); + } else { + setErrors({}); } }, []); const handleSubmit = async () => { try { await loginValidation.validateAsync(form, { abortEarly: false }); - dispatch(login(form)); + const action = await dispatch(login(form)); + if (action.meta.requestStatus === "fulfilled") { + const token = action.payload.data; + localStorage.setItem("token", token); + navigate("/"); + } + if (action.meta.requestStatus === "rejected") { + const error = new Error("Request rejected"); + error.response = action.payload; + throw error; + } } catch (error) { - console.log(error); + if (error.name === "ValidationError") { + // TODO Handle validation errors + console.log(error.details); + alert("Invalid input"); + } else if (error.response) { + // TODO handle dispatch errors + alert(error.response.msg); + } else { + // TODO handle unknown errors + console.log(error); + alert("Unknown error"); + } } }; const handleInput = (e) => { + const fieldName = idMap[e.target.id]; + // Extract and validate individual fields as input changes + const fieldSchema = loginValidation.extract(fieldName); + const { error } = fieldSchema.validate(e.target.value); + let errMsg = ""; + if (error) { + errMsg = error.message; + } + setErrors({ ...errors, [fieldName]: errMsg }); const newForm = { ...form, [idMap[e.target.id]]: e.target.value }; setForm(newForm); }; diff --git a/Client/src/Pages/Register/index.jsx b/Client/src/Pages/Register/index.jsx index bd1b63760..8a7200599 100644 --- a/Client/src/Pages/Register/index.jsx +++ b/Client/src/Pages/Register/index.jsx @@ -54,6 +54,15 @@ const Register = () => { }, []); const handleInput = (e) => { + const fieldName = idMap[e.target.id]; + // Extract and validate individual fields as input changes + const fieldSchema = registerValidation.extract(fieldName); + const { error } = fieldSchema.validate(e.target.value); + let errMsg = ""; + if (error) { + errMsg = error.message; + } + setErrors({ ...errors, [fieldName]: errMsg }); const newForm = { ...form, [idMap[e.target.id]]: e.target.value }; setForm(newForm); };