'use client' import { zodResolver } from '@hookform/resolvers/zod' import { useEffect, useState } from 'react' import { FormProvider, useForm } from 'react-hook-form' import { addToast } from '@/lib/toast' import type { AdminUserDetail } from '@/services/adminUserDetail' import Modal from '@/components/modals/Modal' import Input from '@/components/formElements/Input' import { AdminFormSection } from '@/components/forms/AdminFormLayout' import UnsavedChangesIndicator from '@/components/forms/UnsavedChangesIndicator' import { ADMIN_UPDATE_USER, type AdminUpdateUserPayload } from '@/services/adminUsers' import { API_ROUTES } from '@/services/config' import { AdminUserEditValidation, type AdminUserEditValues } from '@/validation/adminUsers' import useAlertModal from '@/hooks/useAlertModal' import axiosInstance from '@/config/axios' const STATUS_OPTIONS = [ { id: 'active', name: 'فعال' }, { id: 'suspended', name: 'معلق' }, ] const HOST_PLAN_OPTIONS = [ { id: 'free', name: 'رایگان (حداکثر ۱۰ ایونت)' }, { id: 'unlimited', name: 'نامحدود' }, ] const GENDER_OPTIONS = [ { id: 'male', name: 'مرد' }, { id: 'female', name: 'زن' }, { id: 'other', name: 'سایر' }, ] interface CityOption { id: number name: string } const toFormValues = (user: AdminUserDetail): AdminUserEditValues => ({ firstName: user.firstName ?? '', lastName: user.lastName ?? '', gender: user.gender ?? '', cityId: user.cityId ? String(user.cityId) : '', avatarUrl: user.avatarUrl ?? '', bio: user.bio ?? '', status: user.status === 'suspended' ? 'suspended' : 'active', hostPlan: user.hostPlan ?? 'free', }) interface UserEditModalProps { isOpen: boolean onOpenChange: (isOpen: boolean) => void user: AdminUserDetail /** Current admin's own id — status can't be self-edited. */ currentAdminId?: string onSuccess: () => void } const UserEditModal = ({ isOpen, onOpenChange, user, currentAdminId, onSuccess }: UserEditModalProps) => { const { showAlert } = useAlertModal() const [submitting, setSubmitting] = useState(false) const [cities, setCities] = useState([]) const isSelfEdit = Boolean(currentAdminId) && currentAdminId === user.id const form = useForm({ resolver: zodResolver(AdminUserEditValidation), defaultValues: toFormValues(user), }) const { reset } = form // Modal stays mounted across opens, so reset explicitly whenever it opens // (and the target user's data may have refreshed since the last edit). useEffect(() => { if (isOpen) { reset(toFormValues(user)) } }, [isOpen, reset, user]) useEffect(() => { if (!isOpen || cities.length > 0) return axiosInstance .get(API_ROUTES.GEOGRAPHY.ALL_CITIES) .then((res) => { const payload: unknown = res.data let list: unknown = [] if (Array.isArray(payload)) { list = payload } else if (typeof payload === 'object' && payload !== null) { const record = payload as { data?: unknown; body?: unknown } list = record.data ?? record.body ?? [] } setCities(Array.isArray(list) ? (list as { id: number; name: string }[]) : []) }) .catch(() => { setCities([]) }) }, [isOpen, cities.length]) const buildDiffPayload = (values: AdminUserEditValues): AdminUpdateUserPayload => { const initial = toFormValues(user) const payload: AdminUpdateUserPayload = {} if (values.firstName && values.firstName !== initial.firstName) payload.firstName = values.firstName if (values.lastName && values.lastName !== initial.lastName) payload.lastName = values.lastName if (values.gender && values.gender !== initial.gender) payload.gender = values.gender if (values.cityId && values.cityId !== initial.cityId) payload.cityId = Number(values.cityId) if (values.avatarUrl && values.avatarUrl !== initial.avatarUrl) payload.avatarUrl = values.avatarUrl if (values.bio && values.bio !== initial.bio) payload.bio = values.bio if (!isSelfEdit && values.status !== initial.status) payload.status = values.status if (values.hostPlan !== initial.hostPlan) payload.hostPlan = values.hostPlan return payload } const submitUpdate = async (values: AdminUserEditValues) => { const payload = buildDiffPayload(values) if (Object.keys(payload).length === 0) { onOpenChange(false) return } setSubmitting(true) const result = await ADMIN_UPDATE_USER(user.id, payload) setSubmitting(false) if (!result.ok) return addToast({ title: 'اطلاعات کاربر ذخیره شد', color: 'success' }) onOpenChange(false) onSuccess() } const handleSubmit = (values: AdminUserEditValues) => { const initial = toFormValues(user) const payload = buildDiffPayload(values) if (Object.keys(payload).length === 0) { onOpenChange(false) return } if (!isSelfEdit && values.status === 'suspended' && initial.status !== 'suspended') { showAlert('این کاربر معلق شود؟ کاربر تا فعال‌سازی مجدد امکان استفاده از حساب را نخواهد داشت.', () => submitUpdate(values), undefined, { dangerAccept: true, }) return } showAlert('تغییرات این کاربر ذخیره شود؟', () => submitUpdate(values)) } return (
{isSelfEdit && (
وضعیت حساب خودتان از این‌جا قابل ویرایش نیست.
)}
) } export default UserEditModal