Files
shop-front/src/app/profile/page.tsx
T
hamid zarghami 87bc7866fa prile form:
2025-09-16 10:46:02 +03:30

218 lines
10 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client'
import React, { useState, useEffect } from 'react'
import { useForm } from 'react-hook-form'
import { yupResolver } from '@hookform/resolvers/yup'
import * as yup from 'yup'
import { Button } from '@/components/ui/button'
import Input from '@/components/Input'
import { Edit2 } from 'lucide-react'
import Layout from '@/hoc/Layout'
import { Heart, ShoppingCart } from 'iconsax-react'
import Menu from './components/Menu'
import { useGetProfile, useUpdateProfile } from './hooks/useProfileData'
// Schema validation
const profileSchema = yup.object({
fullName: yup.string().required('نام و نام خانوادگی الزامی است'),
phoneNumber: yup
.string()
.required('شماره تماس الزامی است')
.matches(/^09\d{9}$/, 'شماره تماس باید با 09 شروع شود و 11 رقم باشد'),
dateOfBirth: yup.string().required('تاریخ تولد الزامی است'),
nationalCode: yup
.string()
.required('کد ملی الزامی است')
.matches(/^\d{10}$/, 'کد ملی باید 10 رقم باشد'),
address: yup.string().required('آدرس الزامی است'),
})
const ProfilePage = () => {
const { data: profile, isLoading } = useGetProfile()
const updateProfileMutation = useUpdateProfile()
const [isEditing, setIsEditing] = useState(false)
const {
register,
handleSubmit,
formState: { errors, isSubmitting },
reset,
setValue,
} = useForm({
resolver: yupResolver(profileSchema),
mode: 'onChange',
defaultValues: {
fullName: '',
phoneNumber: '',
dateOfBirth: '',
nationalCode: '',
address: '',
},
})
// Set form values when profile data is loaded
useEffect(() => {
if (profile?.results?.info) {
const userInfo = profile.results.info
setValue('fullName', userInfo.fullName || '')
setValue('phoneNumber', userInfo.phoneNumber || '')
setValue('dateOfBirth', userInfo.dateOfBirth || '')
setValue('nationalCode', userInfo.nationalCode || '')
setValue('address', userInfo.userAddress?.address || '')
}
}, [profile, setValue])
const onSubmit = async (data: Record<string, unknown>) => {
await updateProfileMutation.mutateAsync(data)
setIsEditing(false)
}
const handleFormSubmit = (e: React.FormEvent) => {
e.preventDefault()
handleSubmit(onSubmit)(e)
}
const handleCancel = () => {
reset()
setIsEditing(false)
}
if (isLoading) {
return (
<div className="p-3 sm:p-4 md:p-6">
<Menu pageActive='profile' />
<div className='mt-4 sm:mt-6 md:mt-8 lg:mt-10'>
<div className="flex justify-center items-center h-64">
<div className="text-gray-500">در حال بارگذاری...</div>
</div>
</div>
</div>
)
}
return (
<div className="p-3 sm:p-4 md:p-6">
<Menu pageActive='profile' />
<div className='mt-4 sm:mt-6 md:mt-8 lg:mt-10'>
<div className="flex flex-col lg:flex-row gap-4 sm:gap-6">
<div className="flex-1">
<div className="bg-[#FAFAFA] rounded-lg p-3 sm:p-4 md:p-6">
<div className="flex flex-col sm:flex-row items-start sm:items-center justify-between mb-4 sm:mb-6 gap-3 sm:gap-0">
<h1 className="text-base sm:text-lg font-bold text-gray-900">اطلاعات کاربری</h1>
<Button
onClick={() => setIsEditing(!isEditing)}
variant="outline"
className="flex items-center gap-2 text-sm sm:text-base"
>
<Edit2 size={16} />
<span className="hidden sm:inline">ویرایش</span>
</Button>
</div>
<form onSubmit={handleFormSubmit}>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4">
<div>
<Input
label="نام و نام خانوادگی"
{...register('fullName')}
readOnly={!isEditing}
error_text={errors.fullName?.message}
/>
</div>
<div>
<Input
label="کد ملی"
{...register('nationalCode')}
readOnly={!isEditing}
error_text={errors.nationalCode?.message}
/>
</div>
<div>
<Input
label="شماره تماس"
{...register('phoneNumber')}
readOnly={!isEditing}
error_text={errors.phoneNumber?.message}
/>
</div>
<div>
<Input
label="تاریخ تولد"
{...register('dateOfBirth')}
readOnly={!isEditing}
error_text={errors.dateOfBirth?.message}
/>
</div>
</div>
<div className="mt-3 sm:mt-4">
<Input
label="آدرس"
{...register('address')}
readOnly={!isEditing}
error_text={errors.address?.message}
/>
</div>
{isEditing && (
<div className="mt-4 sm:mt-6 flex flex-col sm:flex-row gap-3">
<Button
type="submit"
disabled={isSubmitting || updateProfileMutation.isPending}
className="px-6 sm:px-8 bg-blue-600 hover:bg-blue-700 text-sm sm:text-base"
>
{isSubmitting || updateProfileMutation.isPending ? 'در حال ذخیره...' : 'ذخیره تغییرات'}
</Button>
<Button
type="button"
onClick={handleCancel}
variant="outline"
className="text-sm sm:text-base"
>
انصراف
</Button>
</div>
)}
</form>
</div>
</div>
<div className='flex-1 flex lg:flex-row flex-col gap-6'>
<div className='flex flex-row lg:flex-col gap-3 sm:gap-4 lg:gap-6 flex-1'>
<div className='flex-1 lg:w-full bg-[#FAFAFA] rounded-[10px] flex flex-col gap-3 sm:gap-4 lg:gap-6 justify-center items-center h-[100px] sm:h-[120px] lg:h-[160px] xl:h-[200px]'>
<div className='size-10 sm:size-12 lg:size-16 xl:size-20 bg-[#F2F2F2] rounded-full flex justify-center items-center'>
<ShoppingCart size={20} color='#000' className='sm:w-6 sm:h-6 lg:w-8 lg:h-8 xl:w-10 xl:h-10' />
</div>
<div className='text-xs sm:text-sm lg:text-base text-center'>
سفارشات
</div>
</div>
<div className='flex-1 lg:w-full bg-[#FAFAFA] rounded-[10px] flex flex-col gap-3 sm:gap-4 lg:gap-6 justify-center items-center h-[100px] sm:h-[120px] lg:h-[160px] xl:h-[200px]'>
<div className='size-10 sm:size-12 lg:size-16 xl:size-20 bg-[#F2F2F2] rounded-full flex justify-center items-center'>
<Heart size={20} color='#000' className='sm:w-6 sm:h-6 lg:w-8 lg:h-8 xl:w-10 xl:h-10' />
</div>
<div className='text-xs sm:text-sm lg:text-base text-center'>
علاقه مندی ها
</div>
</div>
</div>
<div className='flex-1 bg-red-50 '>
{/* محتوای اضافی */}
</div>
</div>
</div>
</div>
</div>
)
}
export default function ProfilePageWithLayout() {
return (
<Layout>
<ProfilePage />
</Layout>
)
}