'use client'; import Button from '@/components/Button'; import AlertErrorList from '@/components/helper/form/FormErrors'; import { FormHeader } from '@/components/helper/form/FormHeader'; import DateInput from '@/components/input/DateInput'; import NumberInput from '@/components/input/NumberInput'; import SelectInput, { useSelect } from '@/components/input/SelectInput'; import TextArea from '@/components/input/TextArea'; import { InjectionFormSchema, InjectionFormValues, } from '@/components/pages/finance/add/injection/FormFinanceInjection.schema'; import { useFormikErrorList } from '@/services/hooks/useFormikErrorList'; import { isResponseError, isResponseSuccess } from '@/lib/api-helper'; import { formatDate } from '@/lib/helper'; import { FinanceApi } from '@/services/api/finance'; import { BankApi } from '@/services/api/master-data'; import { CreateInjection, Finance, UpdateInjection, } from '@/types/api/finance/finance'; import { Bank } from '@/types/api/master-data/bank'; import { useFormik } from 'formik'; import { useRouter } from 'next/navigation'; import { useCallback, useMemo, useState } from 'react'; import toast from 'react-hot-toast'; import Alert from '@/components/Alert'; import { Icon } from '@iconify/react'; interface FormFinanceInjectionProps { type?: 'add' | 'edit'; initialValues?: Finance; } const FormFinanceInjection = ({ type = 'add', initialValues, }: FormFinanceInjectionProps) => { const router = useRouter(); const [serverErrorMessage, setServerErrorMessage] = useState(''); // ===== Formik ===== const formikInitialValues = useMemo((): InjectionFormValues => { return { bank_id_option: initialValues?.bank ? { label: initialValues.bank?.name, value: initialValues.bank?.id, } : null, adjustment_date: initialValues?.payment_date || '', nominal: initialValues?.nominal?.toString() || '', note: initialValues?.notes || '', }; }, [initialValues]); const formik = useFormik({ initialValues: formikInitialValues, validationSchema: InjectionFormSchema, validateOnChange: true, validateOnBlur: true, onSubmit: async (values) => { const payload = transformFormValuesToPayload(values); switch (type) { case 'add': await createInjection(payload); break; case 'edit': if (initialValues?.id) { await updateInjection(initialValues.id, payload); } break; } }, }); // ===== Options ===== const { options: bankOptions, rawData: bankRawData, isLoadingOptions: isLoadingBankOptions, setInputValue: setBankInputValue, loadMore: loadMoreBankOptions, } = useSelect(BankApi.basePath, 'id', 'name'); // ===== Helper Functions ===== const transformFormValuesToPayload = ( values: InjectionFormValues ): CreateInjection => { return { bank_id: Number(values.bank_id_option?.value) || 0, adjustment_date: formatDate(values.adjustment_date, 'YYYY-MM-DD'), nominal: Number(values.nominal.replace(/\D/g, '')) || 0, notes: values.note, }; }; // ===== Handler ===== const createInjection = useCallback( async (payload: CreateInjection) => { const response = await FinanceApi.createInjections(payload); if (isResponseError(response)) { toast.error(response.message); setServerErrorMessage(response.message); return; } toast.success('Injeksi dana berhasil ditambahkan'); router.refresh(); router.push('/finance'); }, [router] ); const updateInjection = useCallback( async (financeId: number, payload: UpdateInjection) => { const response = await FinanceApi.updateInjections(financeId, payload); if (isResponseError(response)) { toast.error(response.message); setServerErrorMessage(response.message); return; } toast.success('Injeksi dana berhasil diperbarui'); router.refresh(); router.push('/finance'); }, [router] ); // ===== Formik Error List ===== const { formErrorList, close, handleFormSubmit } = useFormikErrorList(formik); return ( <>
({ label: bankRawData.data?.find( (item) => item.id === option.value )?.alias + ' - ' + bankRawData.data?.find( (item) => item.id === option.value )?.account_number + ' - ' + bankRawData.data?.find( (item) => item.id === option.value )?.owner, value: option.value, })) : [] } value={formik.values.bank_id_option} onInputChange={setBankInputValue} onMenuScrollToBottom={loadMoreBankOptions} onChange={(value) => { formik.setFieldValue('bank_id_option', value); }} isLoading={isLoadingBankOptions} isError={Boolean( formik.touched.bank_id_option && formik.errors.bank_id_option )} errorMessage={ formik.touched.bank_id_option && formik.errors.bank_id_option ? formik.errors.bank_id_option : '' } required isClearable />