import { zodResolver } from "@hookform/resolvers/zod"; import { useState } from "react"; import { useForm } from "react-hook-form"; import { useTranslation } from "react-i18next"; import { useBankMutations } from "../../api/mutations"; import { type BankCard, useBankCard } from "../../api/queries"; import { bankMoneyValue, bankToday } from "../../model/form-validation"; import { bankCardSchema, type BankCardValues } from "../../model/form.schema"; import { useBankFormFocus } from "../useBankFormFocus"; type BankCardFormProps = { card?: BankCard; onClose: () => void }; function useBankCardFormVm(props: BankCardFormProps) { useBankFormFocus(); const [opened, setOpened] = useState(true); const { t } = useTranslation(); const [intent] = useState(() => crypto.randomUUID()); const [version, setVersion] = useState(props.card?.version ?? 1); const [error, setError] = useState(); const [latest, setLatest] = useState(); const fresh = useBankCard(props.card?.id); const mutation = useBankMutations(); const methods = useForm({ defaultValues: { bankName: props.card?.bankName ?? "", lastFour: props.card?.lastFour ?? "", name: props.card?.name ?? "", openingBalance: props.card?.openingBalance.value ?? "0", openingDate: props.card?.openingDate ?? bankToday(), paymentSystem: props.card?.paymentSystem ?? "", }, resolver: zodResolver(bankCardSchema), }); const isPending = !opened || methods.formState.isSubmitting || (fresh.isFetching && Boolean(error)); const onRequestClose = () => !isPending && setOpened(false); const dialogTitle = t(props.card ? "bank.editCard" : "bank.addCard"); const onSubmit = methods.handleSubmit(async (values) => { setError(undefined); try { const metadata = { bankName: values.bankName || null, lastFour: values.lastFour || null, name: values.name, paymentSystem: values.paymentSystem || null, }; const financial = { openingBalance: { currency: "RUB" as const, value: bankMoneyValue(values.openingBalance), }, openingDate: values.openingDate, }; if (props.card) await mutation.updateCard.mutateAsync({ body: { ...metadata, ...(!props.card.archivedAt && financial), version, }, id: props.card.id, }); else await mutation.createCard.mutateAsync({ id: intent, ...metadata, ...financial, }); setOpened(false); } catch (error_) { setError(error_); } }); const onReloadRecord = async () => { const response = await fresh.refetch(); if (response.data && !response.error) setLatest(response.data); else setError(response.error); }; const onAdoptVersion = () => { if (!latest) return; setVersion(latest.version); setLatest(undefined); setError(undefined); }; const onCancel = () => setOpened(false); return { dialogTitle, error, isPending, latest, methods, onAdoptVersion, onCancel, onReloadRecord, onRequestClose, onSubmit, opened, t, version, }; } export { useBankCardFormVm };