Files
Checkmate/Client/src/Features/Auth/authSlice.js
T

137 lines
3.9 KiB
JavaScript

import axios from "axios";
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import { jwtDecode } from "jwt-decode";
const BASE_URL = import.meta.env.VITE_APP_API_BASE_URL;
const initialState = {
isLoading: false,
authToken: "",
user: "",
success: null,
msg: null,
};
export const register = createAsyncThunk(
"auth/register",
async (form, thunkApi) => {
try {
const res = await axios.post(`${BASE_URL}/auth/register`, form);
return res.data;
} catch (error) {
if (error.response.data) {
return thunkApi.rejectWithValue(error.response.data);
}
return thunkApi.rejectWithValue(error.message);
}
}
);
export const login = createAsyncThunk("auth/login", async (form, thunkApi) => {
try {
const res = await axios.post(`${BASE_URL}/auth/login`, form);
return res.data;
} catch (error) {
if (error.response && error.response.data) {
return thunkApi.rejectWithValue(error.response.data);
}
return thunkApi.rejectWithValue(error.message);
}
});
export const update = createAsyncThunk(
"auth/update",
async (data, thunkApi) => {
const { authToken: token, localData: form } = data;
const user = jwtDecode(token);
try {
//1.5s delay to show loading spinner
await new Promise((resolve) => setTimeout(resolve, 1500));
const fd = new FormData();
const imageResult = await axios.get(form.file, { responseType: "blob" });
fd.append("firstname", form.firstname);
fd.append("lastname", form.lastname);
fd.append("profileImage", imageResult.data);
const res = await axios.post(`${BASE_URL}/auth/user/${user._id}`, fd, {
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "multipart/form-data",
},
});
return res.data;
} catch (error) {
if (error.response && error.response.data) {
return thunkApi.rejectWithValue(error.response.data);
}
return thunkApi.rejectWithValue(error.message);
}
}
);
const handleAuthFulfilled = (state, action) => {
state.isLoading = false;
state.success = action.payload.success;
state.msg = action.payload.msg;
state.authToken = action.payload.data.token;
state.user = action.payload.data.user;
};
const handleAuthRejected = (state, action) => {
state.isLoading = false;
state.success = false;
state.msg = action.payload
? action.payload.msg
: "Failed to login or register";
};
const handleUpdateFulfilled = (state, action) => {
state.isLoading = false;
state.success = action.payload.success;
state.msg = action.payload.msg;
state.user = action.payload.data;
};
const handleUpdateRejected = (state, action) => {
state.isLoading = false;
state.success = false;
state.msg = action.payload
? action.payload.msg
: "Failed to update profile data.";
};
const authSlice = createSlice({
name: "auth",
initialState,
reducers: {
clearAuthState: (state) => {
state.authToken = "";
state.user = "";
state.isLoading = false;
state.success = true;
state.msg = "Logged out successfully";
},
},
extraReducers: (builder) => {
builder
// Register thunk
.addCase(register.pending, (state) => {
state.isLoading = true;
})
.addCase(register.fulfilled, handleAuthFulfilled)
.addCase(register.rejected, handleAuthRejected)
// Login thunk
.addCase(login.pending, (state) => {
state.isLoading = true;
})
.addCase(login.fulfilled, handleAuthFulfilled)
.addCase(login.rejected, handleAuthRejected)
// Update thunk
.addCase(update.pending, (state) => {
state.isLoading = true;
})
.addCase(update.fulfilled, handleUpdateFulfilled)
.addCase(update.rejected, handleUpdateRejected);
},
});
export default authSlice.reducer;
export const { clearAuthState } = authSlice.actions;