diff --git a/Client/src/Components/TabPanels/Account/ProfilePanel.jsx b/Client/src/Components/TabPanels/Account/ProfilePanel.jsx index 804cd92eb..ab44b34b3 100644 --- a/Client/src/Components/TabPanels/Account/ProfilePanel.jsx +++ b/Client/src/Components/TabPanels/Account/ProfilePanel.jsx @@ -12,11 +12,16 @@ import { imageValidation, } from "../../../Validation/validation"; import { useDispatch, useSelector } from "react-redux"; -import { update } from "../../../Features/Auth/authSlice"; +import { + clearAuthState, + deleteUser, + update, +} from "../../../Features/Auth/authSlice"; import ImageField from "../../TextFields/Image"; import ImageIcon from "@mui/icons-material/Image"; import ProgressUpload from "../../ProgressBars"; import { formatBytes } from "../../../Utils/fileUtils"; +import { clearMonitorState } from "../../../Features/Monitors/monitorsSlice"; /** * ProfilePanel component displays a form for editing user profile information @@ -178,8 +183,12 @@ const ProfilePanel = () => { }; // Initiates the account deletion process - const handleDeleteAccount = () => { - //TODO - implement delete account function + const handleDeleteAccount = async () => { + const action = await dispatch(deleteUser(authToken)); + if (action.payload.success) { + dispatch(clearAuthState()); + dispatch(clearMonitorState()); + } }; // Modal state and control functions diff --git a/Client/src/Features/Auth/authSlice.js b/Client/src/Features/Auth/authSlice.js index 98119ebd6..b5e3faa50 100644 --- a/Client/src/Features/Auth/authSlice.js +++ b/Client/src/Features/Auth/authSlice.js @@ -52,6 +52,7 @@ export const update = createAsyncThunk( if (form.file && form.file !== "") { const imageResult = await axiosInstance.get(form.file, { responseType: "blob", + baseURL: "", }); fd.append("profileImage", imageResult.data); } @@ -74,6 +75,25 @@ export const update = createAsyncThunk( } ); +export const deleteUser = createAsyncThunk( + "auth/delete", + async (data, thunkApi) => { + const user = jwtDecode(data); + + try { + const res = await axiosInstance.delete(`/auth/user/${user._id}`, { + headers: { Authorization: `Bearer ${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; @@ -101,6 +121,16 @@ const handleUpdateRejected = (state, action) => { ? action.payload.msg : "Failed to update profile data."; }; +const handleDeleteFulfilled = (state, action) => { + state.isLoading = false; + state.success = action.payload.success; + state.msg = action.payload.msg; +}; +const handleDeleteRejected = (state, action) => { + state.isLoading = false; + state.success = false; + state.msg = action.payload ? action.payload.msg : "Failed to delete account."; +}; const authSlice = createSlice({ name: "auth", @@ -115,25 +145,37 @@ const authSlice = createSlice({ }, }, extraReducers: (builder) => { + // Register thunk builder - // Register thunk .addCase(register.pending, (state) => { state.isLoading = true; }) .addCase(register.fulfilled, handleAuthFulfilled) - .addCase(register.rejected, handleAuthRejected) - // Login thunk + .addCase(register.rejected, handleAuthRejected); + + // Login thunk + builder .addCase(login.pending, (state) => { state.isLoading = true; }) .addCase(login.fulfilled, handleAuthFulfilled) - .addCase(login.rejected, handleAuthRejected) - // Update thunk + .addCase(login.rejected, handleAuthRejected); + + // Update thunk + builder .addCase(update.pending, (state) => { state.isLoading = true; }) .addCase(update.fulfilled, handleUpdateFulfilled) .addCase(update.rejected, handleUpdateRejected); + + // Delete thunk + builder + .addCase(deleteUser.pending, (state) => { + state.isLoading = true; + }) + .addCase(deleteUser.fulfilled, handleDeleteFulfilled) + .addCase(deleteUser.rejected, handleDeleteRejected); }, });