diff --git a/client/src/Features/Auth/authSlice.js b/client/src/Features/Auth/authSlice.js index 1d93ce3fa..d6c63b6a9 100644 --- a/client/src/Features/Auth/authSlice.js +++ b/client/src/Features/Auth/authSlice.js @@ -203,6 +203,9 @@ const authSlice = createSlice({ state.authToken = action.payload.data.token; state.user = action.payload.data.user; }, + setUser: (state, action) => { + state.user = action.payload; + }, }, extraReducers: (builder) => { // Register thunk @@ -256,4 +259,4 @@ const authSlice = createSlice({ }); export default authSlice.reducer; -export const { clearAuthState, setAuthState } = authSlice.actions; +export const { clearAuthState, setAuthState, setUser } = authSlice.actions; diff --git a/client/src/Pages/Account/TabProfile.tsx b/client/src/Pages/Account/TabProfile.tsx index 6fccfc851..9108e8c32 100644 --- a/client/src/Pages/Account/TabProfile.tsx +++ b/client/src/Pages/Account/TabProfile.tsx @@ -1,44 +1,161 @@ -import { Stack } from "@mui/material"; +import { useState } from "react"; +import { Stack, Box } from "@mui/material"; import { useTranslation } from "react-i18next"; +import { useForm, Controller } from "react-hook-form"; +import { useSelector, useDispatch } from "react-redux"; +import { useNavigate } from "react-router-dom"; import { ConfigBox } from "@/Components/v2/design-elements"; import { TextField, Button } from "@/Components/v2/inputs"; import { ImageUpload } from "@/Components/v2/inputs"; +import { useProfileForm } from "@/Hooks/useProfileForm"; +import { usePatch, useDelete } from "@/Hooks/UseApi"; +import { setUser, clearAuthState } from "@/Features/Auth/authSlice"; +import type { ProfileFormData } from "@/Validation/profile"; +import type { RootState } from "@/Types/state"; +import type { User } from "@/Types/User"; export const TabProfile = () => { const { t } = useTranslation(); + const dispatch = useDispatch(); + const navigate = useNavigate(); + const user = useSelector((state: RootState) => state.auth?.user); + const { resolver, defaults } = useProfileForm(); + const { patch, loading: patchLoading } = usePatch(); + const { deleteFn, loading: deleteLoading } = useDelete(); + const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); + + const { control, handleSubmit, setValue, watch } = useForm({ + resolver, + defaultValues: { + firstName: user?.firstName ?? defaults.firstName, + lastName: user?.lastName ?? defaults.lastName, + profileImage: defaults.profileImage, + deleteProfileImage: defaults.deleteProfileImage, + }, + }); + + const currentImage = watch("profileImage"); + const deleteImage = watch("deleteProfileImage"); + + const getCurrentImageSrc = () => { + if (deleteImage) return undefined; + if (currentImage) return URL.createObjectURL(currentImage); + if (user?.avatarImage) return `data:image/png;base64,${user.avatarImage}`; + return undefined; + }; + + const handleImageChange = ( + fileObj: { src: string; name: string; file: File } | undefined + ) => { + if (fileObj) { + setValue("profileImage", fileObj.file); + setValue("deleteProfileImage", false); + } else { + setValue("profileImage", null); + setValue("deleteProfileImage", true); + } + }; + + const onSubmit = async (data: ProfileFormData) => { + const fd = new FormData(); + fd.append("firstName", data.firstName); + fd.append("lastName", data.lastName); + + if (data.profileImage) { + fd.append("profileImage", data.profileImage); + } + + if (data.deleteProfileImage) { + fd.append("deleteProfileImage", "true"); + } + + console.log(fd); + + // const result = await patch("/auth/user", fd); + // if (result?.success && result.data) { + // dispatch(setUser(result.data)); + // } + }; + + const handleDeleteAccount = async () => { + const result = await deleteFn("/auth/user"); + if (result?.success) { + dispatch(clearAuthState()); + navigate("/login"); + } + }; + + const showDeleteSection = !user?.role?.includes("demo"); return ( - - - - - - } - /> - } - /> - - + + + ( + + )} + /> + ( + + )} + /> + + } + /> + + } + /> + + + + ); }; diff --git a/client/src/Types/state.ts b/client/src/Types/state.ts index 1575fffb8..b5bfcfdb8 100644 --- a/client/src/Types/state.ts +++ b/client/src/Types/state.ts @@ -1,7 +1,9 @@ +import type { User } from "./User"; + export interface AuthState { isLoading: boolean; authToken: string; - user: string; + user: User | null; success: boolean | null; msg: string | null; }