diff --git a/src/app/[name]/(Profile)/profile/edit/page.tsx b/src/app/[name]/(Profile)/profile/edit/page.tsx index 69007e0..1f84c4a 100644 --- a/src/app/[name]/(Profile)/profile/edit/page.tsx +++ b/src/app/[name]/(Profile)/profile/edit/page.tsx @@ -6,55 +6,161 @@ import ComboBox from '@/components/combobox/Combobox'; import InputField from '@/components/input/InputField'; import { PORFILE_EDIT_PAGE_ELEMENT } from '@/enums'; import { Popover, PopoverTrigger, PopoverContent } from '@radix-ui/react-popover'; -// import { useProfile } from '@/hooks/auth/useProfile'; -// import { useAuthStore } from '@/zustand/authStore'; import { Calendar2, Camera } from 'iconsax-react'; import Image from 'next/image'; -import React, { ChangeEvent, useState } from 'react' +import React, { useEffect, useMemo } from 'react' import Calendar from '@/components/ui/calendar'; import { getDateLib } from "react-day-picker/persian"; import { useRouter } from 'next/navigation'; +import { useGetProfile, useUpdateProfile } from '../hooks/userProfileData'; +import { useFormik } from 'formik'; +import * as Yup from 'yup'; +import { UpdateProfileType } from '../types/Types'; +import { toast } from '@/components/Toast'; +import { extractErrorMessage } from '@/lib/func'; type Props = object function ProfileIndex({ }: Props) { - const [fullname, setFullName] = useState(""); - const [email, setEmail] = useState(""); - const [phoneNumber, setPhoneNumber] = useState(""); - const [dateOfBirth, setDateOfBirth] = React.useState(new Date()); - const [selectedGender, setSelectedGender] = useState(""); - const [showCalendar, setShowCalendar] = useState(false); + + const { data, isPending } = useGetProfile(); + const { mutate: updateProfile, isPending: isUpdating } = useUpdateProfile(); + const [showCalendar, setShowCalendar] = React.useState(false); const dateLib = getDateLib() const router = useRouter(); + const userData = data?.data; + + // تابع برای بررسی معتبر بودن Date + const isValidDate = (date: Date | null | undefined): date is Date => { + return date instanceof Date && !isNaN(date.getTime()); + }; + + // تابع برای تبدیل string تاریخ به Date بدون مشکل timezone + const parseLocalDate = (dateString: string): Date | undefined => { + try { + if (!dateString) return undefined; + + // اگر تاریخ به فرمت ISO یا کامل است، ابتدا به Date تبدیل می‌کنیم + const date = new Date(dateString); + if (isValidDate(date)) { + // برای جلوگیری از مشکل timezone، فقط سال، ماه و روز را می‌گیریم + const year = date.getFullYear(); + const month = date.getMonth(); + const day = date.getDate(); + return new Date(year, month, day); + } + + // اگر فرمت ISO کار نکرد، سعی می‌کنیم فرمت YYYY-MM-DD را parse کنیم + const parts = dateString.split('T')[0].split('-'); + if (parts.length === 3) { + const [year, month, day] = parts.map(Number); + if (!isNaN(year) && !isNaN(month) && !isNaN(day)) { + const parsedDate = new Date(year, month - 1, day); + if (isValidDate(parsedDate)) { + return parsedDate; + } + } + } + + return undefined; + } catch { + return undefined; + } + }; + + // تابع برای تبدیل Date به string تاریخ + const formatDateToString = (date: Date): string => { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + return `${year}-${month}-${day}`; + }; + + // تابع برای format کردن تاریخ با dateLib + const formatDateForDisplay = (date: Date | null | undefined): string => { + if (!date || !isValidDate(date)) { + return "انتخاب کنید"; + } + try { + return dateLib.format(date, "yyyy/MM/dd"); + } catch { + return "انتخاب کنید"; + } + }; + + type FormValues = { + firstName: string; + lastName: string; + birthDate?: Date | null; + gender?: boolean; + }; + + const validationSchema: Yup.ObjectSchema = Yup.object({ + firstName: Yup.string().required('نام اجباری است'), + lastName: Yup.string().required('نام خانوادگی اجباری است'), + }) as Yup.ObjectSchema; + + const formik = useFormik({ + initialValues: { + firstName: '', + lastName: '', + birthDate: undefined, + gender: undefined, + }, + validationSchema, + enableReinitialize: true, + onSubmit: (values) => { + const { birthDate, ...submitValues } = values; + const payload: UpdateProfileType = { + firstName: submitValues.firstName, + lastName: submitValues.lastName, + birthDate: birthDate ? formatDateToString(birthDate) : undefined, + gender: submitValues.gender, + }; + + updateProfile(payload, { + onSuccess: () => { + toast('اطلاعات با موفقیت به‌روزرسانی شد', 'success'); + router.back(); + }, + onError: (error) => { + toast(extractErrorMessage(error), 'error'); + }, + }); + }, + }); + + useEffect(() => { + if (userData) { + const birthDate = userData.birthDate ? parseLocalDate(userData.birthDate) : undefined; + const values: FormValues = { + firstName: userData.firstName || '', + lastName: userData.lastName || '', + birthDate: birthDate, + gender: userData.gender !== undefined ? userData.gender : undefined, + }; + formik.setValues(values); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [userData]); + + const selectedGenderId = useMemo(() => { + if (formik.values.gender === true) return '0'; + if (formik.values.gender === false) return '1'; + return ''; + }, [formik.values.gender]); + const changeGender = (e: React.MouseEvent, index: number) => { - setSelectedGender(() => String(index)); + formik.setFieldValue('gender', index === 0); } - // const isAuthenticated = useAuthStore((state) => state.isAuthenticated); - - // const { mutate, data, isPending } = useProfile(); - - // useEffect(() => { - // if (isAuthenticated) { - // mutate(); - // } - // // eslint-disable-next-line react-hooks/exhaustive-deps - // }, [isAuthenticated]) - - const onChange = (e: ChangeEvent) => { - if (e.target.name == PORFILE_EDIT_PAGE_ELEMENT.INPUT_FULLNAME) { - setFullName(() => e.target.value) - } - else if (e.target.name == PORFILE_EDIT_PAGE_ELEMENT.INPUT_EMAIL) { - setEmail(() => e.target.value) - } - else if (e.target.name == PORFILE_EDIT_PAGE_ELEMENT.INPUT_PHONE) { - setPhoneNumber(() => e.target.value) - } - // else if (e.target.name == PORFILE_EDIT_PAGE_ELEMENT.INPUT_DOB) { - // setDateOfBirth(() => e.target.value) - // } + if (isPending) { + return ( +
+

در حال بارگذاری...

+
+ ); } return ( @@ -64,16 +170,13 @@ function ProfileIndex({ }: Props) {

ویرایش اطلاعات

-
- +
-
-
- +
-
+
) } diff --git a/src/app/[name]/(Profile)/profile/hooks/userProfileData.ts b/src/app/[name]/(Profile)/profile/hooks/userProfileData.ts index d567bb6..d56fcb5 100644 --- a/src/app/[name]/(Profile)/profile/hooks/userProfileData.ts +++ b/src/app/[name]/(Profile)/profile/hooks/userProfileData.ts @@ -1,4 +1,4 @@ -import { useQuery } from "@tanstack/react-query"; +import { useMutation, useQuery } from "@tanstack/react-query"; import * as api from "../service/ProfileService"; import { getToken } from "@/lib/api/func"; @@ -10,3 +10,9 @@ export const useGetProfile = () => { enabled: !!getToken(), }); }; + +export const useUpdateProfile = () => { + return useMutation({ + mutationFn: api.updateProfile, + }); +}; diff --git a/src/app/[name]/(Profile)/profile/service/ProfileService.ts b/src/app/[name]/(Profile)/profile/service/ProfileService.ts index 3d6c990..7a0ab0c 100644 --- a/src/app/[name]/(Profile)/profile/service/ProfileService.ts +++ b/src/app/[name]/(Profile)/profile/service/ProfileService.ts @@ -1,7 +1,12 @@ import { api } from "@/config/axios"; -import { GetProfileResponse } from "../types/Types"; +import { GetProfileResponse, UpdateProfileType } from "../types/Types"; export const getProfile = async (): Promise => { const { data } = await api.get("/public/user/me"); return data; }; + +export const updateProfile = async (params: UpdateProfileType) => { + const { data } = await api.patch("/public/user/update", params); + return data; +}; diff --git a/src/app/[name]/(Profile)/profile/types/Types.ts b/src/app/[name]/(Profile)/profile/types/Types.ts index e8d88fa..fd88a01 100644 --- a/src/app/[name]/(Profile)/profile/types/Types.ts +++ b/src/app/[name]/(Profile)/profile/types/Types.ts @@ -21,3 +21,11 @@ export interface GetProfileResponse { success: boolean; data: UserProfile; } + +export interface UpdateProfileType { + firstName: string; + lastName: string; + birthDate?: string; + marriageDate?: string; + gender?: boolean; +}