'use client' import { useState } from 'react' import DatePicker from 'react-multi-date-picker' import persian from 'react-date-object/calendars/persian' import persian_fa from 'react-date-object/locales/persian_fa' import 'react-multi-date-picker/styles/layouts/mobile.css' import { addToast } from '@/lib/toast' import Input from '@/components/formElements/Input' import Modal from '@/components/modals/Modal' import axiosInstance from '@/config/axios' import { convertToISOFormat, coerceToString } from '@/helpers' import { API_ROUTES } from '@/services/config' import { extractServerErrorDetail } from '@/services/errorHandler' interface CreateSettlementModalProps { isOpen: boolean onClose: () => void onCreated: () => void } const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i type FieldErrors = Partial> function toDatePickerValue(value: string): Date | null { if (!value) return null const date = new Date(value) return Number.isFinite(date.getTime()) ? date : null } const CreateSettlementModal = ({ isOpen, onClose, onCreated }: CreateSettlementModalProps) => { const [organizerId, setOrganizerId] = useState('') const [bankAccountId, setBankAccountId] = useState('') const [periodStart, setPeriodStart] = useState('') const [periodEnd, setPeriodEnd] = useState('') const [errors, setErrors] = useState({}) const [isSubmitting, setIsSubmitting] = useState(false) const resetForm = () => { setOrganizerId('') setBankAccountId('') setPeriodStart('') setPeriodEnd('') setErrors({}) } const handleClose = () => { if (isSubmitting) return resetForm() onClose() } const validate = (): FieldErrors => { const nextErrors: FieldErrors = {} if (!organizerId.trim()) { nextErrors.organizerId = 'شناسه میزبان الزامی است' } else if (!UUID_PATTERN.test(organizerId.trim())) { nextErrors.organizerId = 'شناسه میزبان باید یک UUID معتبر باشد' } if (!bankAccountId.trim()) { nextErrors.bankAccountId = 'شناسه حساب بانکی الزامی است' } else if (!UUID_PATTERN.test(bankAccountId.trim())) { nextErrors.bankAccountId = 'شناسه حساب بانکی باید یک UUID معتبر باشد' } if (!periodStart) { nextErrors.periodStart = 'ابتدای بازه الزامی است' } if (!periodEnd) { nextErrors.periodEnd = 'انتهای بازه الزامی است' } if (periodStart && periodEnd && periodEnd < periodStart) { nextErrors.periodEnd = 'انتهای بازه باید بعد از ابتدای بازه باشد' } return nextErrors } const handleSubmit = async () => { const nextErrors = validate() setErrors(nextErrors) if (Object.keys(nextErrors).length > 0) return try { setIsSubmitting(true) await axiosInstance.post(API_ROUTES.SETTLEMENTS.ADMIN_CREATE, { organizerId: organizerId.trim(), bankAccountId: bankAccountId.trim(), periodStart, periodEnd, }) addToast({ title: 'تسویه با موفقیت ایجاد شد', color: 'success' }) resetForm() onCreated() } catch (err) { const detail = extractServerErrorDetail((err as { response?: { data?: unknown } })?.response?.data) addToast({ title: 'ایجاد تسویه ناموفق بود', description: detail ?? 'ممکن است حساب بانکی معتبر نباشد یا درآمد قابل تسویه‌ای در این بازه وجود نداشته باشد.', color: 'danger', }) } finally { setIsSubmitting(false) } } return ( { if (!open) handleClose() }} onReject={handleClose} >
{ setOrganizerId(coerceToString(next)) }} /> {errors.organizerId && {errors.organizerId}}
{ setBankAccountId(coerceToString(next)) }} /> {errors.bankAccountId && {errors.bankAccountId}}
ابتدای بازه { setPeriodStart(date ? convertToISOFormat(date).split('T')[0] : '') }} /> {errors.periodStart && {errors.periodStart}}
انتهای بازه { setPeriodEnd(date ? convertToISOFormat(date).split('T')[0] : '') }} /> {errors.periodEnd && {errors.periodEnd}}
) } export default CreateSettlementModal