import { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Alert, Form, Input, InputNumber, Modal, Select, message } from 'antd'; import { FormProvider, useForm } from 'react-hook-form'; import { ClientBulkAdjustFormSchema, type ClientBulkAdjustFormValues } from '@/schemas/client'; import { TLS_FLOW_CONTROL } from '@/schemas/primitives/flow'; import { FormField } from '@/components/form/rhf'; const GB = 1024 * 1024 * 1024; const FLOW_CLEAR = 'none'; const EMPTY: ClientBulkAdjustFormValues = { addDays: 0, addGB: 0, flow: '', limitHwid: null, adTag: '', }; interface ClientBulkAdjustModalProps { open: boolean; count: number; onOpenChange: (open: boolean) => void; onSubmit: ( addDays: number, addBytes: number, flow: string, limitHwid?: number | null, adTag?: string, ) => Promise<{ adjusted: number; skipped?: { email: string; reason: string }[] } | null>; } export default function ClientBulkAdjustModal({ open, count, onOpenChange, onSubmit, }: ClientBulkAdjustModalProps) { const { t } = useTranslation(); const [messageApi, messageContextHolder] = message.useMessage(); const [submitting, setSubmitting] = useState(false); const methods = useForm({ defaultValues: EMPTY }); useEffect(() => { if (open) methods.reset(EMPTY); }, [open, methods]); async function handleOk() { const values = methods.getValues(); const validated = ClientBulkAdjustFormSchema.safeParse({ addDays: Math.trunc(Number(values.addDays) || 0), addGB: Number(values.addGB) || 0, flow: values.flow, limitHwid: values.limitHwid !== null && values.limitHwid !== undefined && (values.limitHwid as unknown) !== '' ? Math.trunc(Number(values.limitHwid)) : null, adTag: values.adTag?.trim() ?? '', }); if (!validated.success) { messageApi.warning(t(validated.error.issues[0]?.message ?? 'somethingWentWrong')); return; } const { addDays: days, addGB: gb, flow: flowValue, limitHwid, adTag } = validated.data; setSubmitting(true); try { const bytes = Math.trunc(gb * GB); const result = await onSubmit(days, bytes, flowValue, limitHwid, adTag); if (!result) return; const ok = result.adjusted ?? 0; const skipped = result.skipped?.length ?? 0; if (skipped === 0) { messageApi.success(t('pages.clients.toasts.bulkAdjusted', { count: ok })); } else { const firstReason = result.skipped?.[0]?.reason ?? ''; messageApi.warning( firstReason ? `${t('pages.clients.toasts.bulkAdjustedMixed', { ok, skipped })} — ${firstReason}` : t('pages.clients.toasts.bulkAdjustedMixed', { ok, skipped }), ); } onOpenChange(false); } finally { setSubmitting(false); } } return ( <> {messageContextHolder} onOpenChange(false)} destroyOnHidden >
); }