-
-
-
+ return (
+
+
+ {profile?.joinedAt && (
+
+
+
✨
+
+
+ شروعِ ماجرا از
+
+
+ {moment(profile.joinedAt)
+ .locale('fa')
+ .format('jMMMM jYYYY')}
+
+
-
+ )}
+
-
-
-
-
-
- {profile?.name || 'کاربر'}
-
-
- @{profile?.username || '-'}
-
-
- {profile?.coins !== undefined && (
-
-
-
- )}
-
-
+
+ {profile?.name || 'کاربر'}
+
+
+ @{profile?.username || 'username'}
+
-
-
-
-
-
-
-
- ایمیل
-
-
- {profile?.email || '-'}
-
-
-
+ {profile?.coins !== undefined && (
+
+
+
+ )}
+
-
-
- {getGenderInfo(profile?.gender).icon && (
-
- {getGenderInfo(profile?.gender).icon}
-
- )}
-
-
-
- جنسیت
-
-
- {getGenderInfo(profile?.gender).label}
-
-
-
+
+
}
+ label="نام و نام خانوادگی"
+ value={profile?.name}
+ />
-
-
-
-
-
-
- تاریخ تولد
-
-
- {formatJalaliDate(profile?.birthDate)}
-
-
-
-
+
}
+ label="ایمیل"
+ value={profile?.email}
+ isLtr
+ />
-
-
-
-
-
+
{genderInfo.icon}}
+ label="جنسیت"
+ value={genderInfo.label}
+ />
- {profile?.inCache && (
-
-
-
- )}
+
}
+ label="تاریخ تولد"
+ value={formatJalaliDate(profile?.birthDate)}
+ />
+
+
}
+ label="شغل"
+ value={profile?.occupation?.label}
+ />
+
+
}
+ label="علایق"
+ value={
+ profile?.interests?.map((i) => i.label).join('، ') ||
+ 'انتخاب نشده'
+ }
+ />
+
+ {/* دکمه ویرایش */}
+
+
+ {profile?.inCache && (
+
+
+
+ )}
)
}
+
+const DisplayRow = ({
+ icon,
+ label,
+ value,
+ isLtr = false,
+}: {
+ icon: React.ReactNode
+ label: string
+ value?: string
+ isLtr?: boolean
+}) => (
+
+)
diff --git a/src/layouts/setting/tabs/account/components/profile-edit-form.tsx b/src/layouts/setting/tabs/account/components/profile-edit-form.tsx
index ca904108..05ede312 100644
--- a/src/layouts/setting/tabs/account/components/profile-edit-form.tsx
+++ b/src/layouts/setting/tabs/account/components/profile-edit-form.tsx
@@ -1,19 +1,27 @@
import type { AxiosError } from 'axios'
import moment from 'jalali-moment'
import { useEffect, useRef, useState } from 'react'
+import { LuCamera, LuUser, LuBriefcase, LuChevronRight } from 'react-icons/lu'
import { AvatarComponent } from '@/components/avatar.component'
import { Button } from '@/components/button/button'
-import { ItemSelector } from '@/components/item-selector'
import { TextInput } from '@/components/text-input'
+import { OccupationSelector } from '@/layouts/setting/tabs/account/components/occupation-selector'
+import { InterestsSelector } from '@/layouts/setting/tabs/account/components/interests-selector'
import { safeAwait } from '@/services/api'
import {
useUpdateUsername,
useUpdateUserProfile,
} from '@/services/hooks/auth/authService.hook'
import type { UserProfile } from '@/services/hooks/user/userService.hook'
+import {
+ useGetOccupations,
+ useGetInterests,
+} from '@/services/hooks/profile/getProfileMeta.hook'
import { translateError } from '@/utils/translate-error'
import JalaliDatePicker from './profile-date-picker'
import { showToast } from '@/common/toast'
+import { SectionPanel } from '@/components/section-panel'
+import { FaMars, FaQuestion, FaVenus } from 'react-icons/fa'
interface ProfileEditFormProps {
profile?: UserProfile
@@ -21,6 +29,21 @@ interface ProfileEditFormProps {
onSuccess: () => void
}
+const options = {
+ MALE: {
+ label: 'آقا هستم',
+ icon:
,
+ },
+ FEMALE: {
+ label: 'خانم هستم',
+ icon:
,
+ },
+ OTHER: {
+ label: 'بماند',
+ icon:
,
+ },
+}
+
export const ProfileEditForm = ({
profile,
onCancel,
@@ -32,13 +55,17 @@ export const ProfileEditForm = ({
birthdate: '',
avatar: null as File | null,
username: null as string | null,
+ occupation: null as string | null,
+ interests: [] as string[],
})
const [error, setError] = useState
(null)
const updateProfileMutation = useUpdateUserProfile()
const updateUsernameMutation = useUpdateUsername()
-
+ const { data: occupations = [], isLoading: occupationsLoading } = useGetOccupations()
+ const { data: interests = [], isLoading: interestsLoading } = useGetInterests()
const avatarRef = useRef(null)
+
useEffect(() => {
setFormData({
name: profile?.name || '',
@@ -46,6 +73,8 @@ export const ProfileEditForm = ({
birthdate: profile?.birthDate || '',
avatar: null,
username: profile?.username || null,
+ occupation: profile?.occupation?.id || null,
+ interests: profile?.interests.map((i) => i.id) || [],
})
}, [profile])
@@ -53,7 +82,6 @@ export const ProfileEditForm = ({
e.preventDefault()
const data = new FormData()
data.append('name', formData.name)
-
if (formData.gender) data.append('gender', formData.gender)
if (formData.birthdate) {
const gregorianDate = moment(formData.birthdate, 'jYYYY-jMM-jDD')
@@ -62,31 +90,25 @@ export const ProfileEditForm = ({
data.append('birthdate', gregorianDate)
}
if (formData.avatar) data.append('avatar', formData.avatar)
+ if (formData.occupation) data.append('occupationId', formData.occupation)
+
+ formData.interests.map((id) => data.append('interestIds[]', id))
try {
if (formData.username && formData.username !== profile?.username) {
const usernameRegex = /^[a-zA-Z0-9_]{4,250}$/
if (!usernameRegex.test(formData.username)) {
- setError(
- 'نام کاربری باید فقط شامل حروف انگلیسی، اعداد و زیرخط باشد و بین 4 تا 250 کاراکتر باشد.'
- )
+ setError('نام کاربری نامعتبر است')
return
}
-
- const [err, response] = await safeAwait(
+ const [err, _] = await safeAwait(
updateUsernameMutation.mutateAsync(formData.username)
)
if (err) {
errorHandling(err, setError)
return
- } else {
- setFormData((prev) => ({
- ...prev,
- username: response.username || '',
- }))
}
}
-
await updateProfileMutation.mutateAsync(data)
setError(null)
onSuccess()
@@ -98,162 +120,245 @@ export const ProfileEditForm = ({
const onChangeAvatar = (e: React.ChangeEvent) => {
const file = e.target.files?.[0]
if (file && file.size > 1024 * 1024) {
- showToast('فایل باید کمتر از 1 مگابایت باشد', 'error')
+ showToast('فایل بزرگتر از ۱ مگابایت است', 'error')
return
}
-
const validTypes = ['image/png', 'image/jpeg', 'image/webp']
if (file && !validTypes.includes(file.type)) {
- showToast('فقط فرمتهای png، jpeg و webp مجاز هستند', 'error')
+ showToast('فرمت فایل نامعتبر است', 'error')
return
}
-
- setFormData((prev) => ({
- ...prev,
- avatar: file || null,
- }))
+ setFormData((prev) => ({ ...prev, avatar: file || null }))
}
- const onChangeGender = (gender: 'MALE' | 'FEMALE' | 'OTHER') => {
- setFormData((prev) => ({
- ...prev,
- gender,
- }))
- }
+ return (
+
+
- const onChangeBirthdate = (date: any) => {
- setFormData((prev) => ({
- ...prev,
- birthdate: date,
- }))
- }
+
+
+
+
+
avatarRef.current?.click()}
+ />
+
+
+
+
+
- return (
-
-
{error && (
-
-
{error}
+
+ {error}
)}
+