From 4ddd1dc8e3e434cad55fdabffdcfdc4a799d4e91 Mon Sep 17 00:00:00 2001 From: randy-ar Date: Wed, 24 Dec 2025 18:45:33 +0700 Subject: [PATCH] feat(FE-337): slicing ui form add finance --- src/app/finance/add/page.tsx | 8 +- src/components/pages/finance/FinanceTable.tsx | 44 +- .../finance/add/FormFinanceAdd.schema.ts | 75 ++++ .../pages/finance/add/FormFinanceAdd.tsx | 378 ++++++++++++++++++ .../FinanceAddInitialBalance.tsx | 0 .../FormFinanceAddInitialBalance.schema.ts} | 0 .../FormFinanceAddInitialBalance.tsx} | 0 .../finance/adjust/FinanceAdjust.schema.ts | 0 .../pages/finance/adjust/FinanceAdjust.tsx | 5 - .../FormFinanceAdjust.schema.ts} | 0 .../finance/adjust/FormFinanceAdjust.tsx | 5 + src/config/constant.ts | 13 + 12 files changed, 499 insertions(+), 29 deletions(-) create mode 100644 src/components/pages/finance/add/FormFinanceAdd.schema.ts create mode 100644 src/components/pages/finance/add/FormFinanceAdd.tsx delete mode 100644 src/components/pages/finance/add/initial-balance/FinanceAddInitialBalance.tsx rename src/components/pages/finance/add/{FinanceAdd.schema.ts => initial-balance/FormFinanceAddInitialBalance.schema.ts} (100%) rename src/components/pages/finance/add/{FinanceAdd.tsx => initial-balance/FormFinanceAddInitialBalance.tsx} (100%) delete mode 100644 src/components/pages/finance/adjust/FinanceAdjust.schema.ts delete mode 100644 src/components/pages/finance/adjust/FinanceAdjust.tsx rename src/components/pages/finance/{add/initial-balance/FinanceAddInitialBalance.schema.ts => adjust/FormFinanceAdjust.schema.ts} (100%) create mode 100644 src/components/pages/finance/adjust/FormFinanceAdjust.tsx diff --git a/src/app/finance/add/page.tsx b/src/app/finance/add/page.tsx index 93ab79fb..162cd7ec 100644 --- a/src/app/finance/add/page.tsx +++ b/src/app/finance/add/page.tsx @@ -1,5 +1,7 @@ -const FinanceAdd = () => { - return
Finance Add
; +import FormFinanceAdd from '@/components/pages/finance/add/FormFinanceAdd'; + +const FinanceAddPage = () => { + return ; }; -export default FinanceAdd; +export default FinanceAddPage; diff --git a/src/components/pages/finance/FinanceTable.tsx b/src/components/pages/finance/FinanceTable.tsx index e6776521..b4b4e60c 100644 --- a/src/components/pages/finance/FinanceTable.tsx +++ b/src/components/pages/finance/FinanceTable.tsx @@ -264,7 +264,7 @@ const FinanceTable = () => { - @@ -300,26 +300,28 @@ const FinanceTable = () => { onChange={transactionTypeChangeHandler} isClearable /> - {isResponseSuccess(bankRawData) && ( - ({ - label: - bankRawData.data.find((data) => data.id === bank.value) - ?.alias + - ' - ' + - bankRawData.data.find((data) => data.id === bank.value) - ?.account_number + - ' - ' + - bankRawData.data.find((data) => data.id === bank.value) - ?.owner, - value: bank.value, - }))} - label='Bank' - value={selectedBank} - onChange={bankChangeHandler} - isClearable - /> - )} + ({ + label: + bankRawData.data.find((data) => data.id === bank.value) + ?.alias + + ' - ' + + bankRawData.data.find((data) => data.id === bank.value) + ?.account_number + + ' - ' + + bankRawData.data.find((data) => data.id === bank.value) + ?.owner, + value: bank.value, + })) + : [] + } + label='Bank' + value={selectedBank} + onChange={bankChangeHandler} + isClearable + /> { + const router = useRouter(); + + // ===== Formik ===== + const formikInitialValues = useMemo((): FinanceFormValues => { + return { + party_type_option: initialValues?.party_type_option || null, + party_id_option: initialValues?.party_id_option || null, + payment_date: initialValues?.payment_date || '', + payment_method_option: initialValues?.payment_method_option || null, + bank_id_option: initialValues?.bank_id_option || null, + party_account_number: initialValues?.party_account_number || '', + reference_number: initialValues?.reference_number || '', + nominal: initialValues?.nominal || '', + notes: initialValues?.notes || '', + }; + }, [initialValues]); + + const formik = useFormik({ + initialValues: formikInitialValues, + validationSchema: FinanceFormSchema, + onSubmit: async (values) => { + const payload = transformFormValuesToPayload(values); + + switch (type) { + case 'add': + await createFinance(payload); + break; + + case 'edit': + if (initialValues?.id) { + await updateFinance(initialValues.id, payload); + } + break; + } + }, + }); + + // ===== Options ===== + const { options: partyOptions, isLoadingOptions: isLoadingPartyOptions } = + useSelect( + formik.values.party_type_option?.value === 'CUSTOMER' + ? CustomerApi.basePath + : SupplierApi.basePath, + 'id', + 'name', + '', + { limit: 'limit' } + ); + const { + options: bankOptions, + rawData: bankRawData, + isLoadingOptions: isLoadingBankOptions, + } = useSelect(BankApi.basePath, 'id', 'name', '', { limit: 'limit' }); + + // ===== Helper Functions ===== + const transformFormValuesToPayload = ( + values: FinanceFormValues + ): FinancePayload => { + return { + party_id: Number(values.party_id_option?.value) || 0, + party_type: (values.party_type_option?.value as string) || '', + payment_date: values.payment_date, + payment_method: (values.payment_method_option?.value as string) || '', + bank_id: Number(values.bank_id_option?.value) || 0, + reference_number: values.reference_number, + nominal: Number(values.nominal.replace(/\D/g, '')) || 0, + notes: values.notes, + }; + }; + + // ===== Handler ===== + const createFinance = useCallback( + async (payload: FinancePayload) => { + const response = await FinanceApi.create(payload); + + if (isResponseError(response)) { + toast.error(response.message); + return; + } + + toast.success('Data berhasil ditambahkan'); + router.refresh(); + router.push('/finance'); + }, + [router] + ); + const updateFinance = useCallback( + async (financeId: number, payload: FinancePayload) => { + const response = await FinanceApi.update(financeId, payload); + + if (isResponseError(response)) { + toast.error(response.message); + return; + } + + toast.success('Data berhasil diperbarui'); + router.refresh(); + router.push('/finance'); + }, + [router] + ); + + return ( + <> +
+
+ +
+ { + formik.setFieldValue('party_type_option', value); + formik.setFieldTouched('party_type_option', true); + }} + isError={ + !!( + formik.touched.party_type_option && + formik.errors.party_type_option + ) + } + errorMessage={ + formik.touched.party_type_option && + formik.errors.party_type_option + ? String(formik.errors.party_type_option) + : '' + } + required + isClearable + /> + { + formik.setFieldValue('party_id_option', value); + formik.setFieldTouched('party_id_option', true); + }} + isLoading={isLoadingPartyOptions} + isError={ + !!( + formik.touched.party_id_option && + formik.errors.party_id_option + ) + } + errorMessage={ + formik.touched.party_id_option && formik.errors.party_id_option + ? String(formik.errors.party_id_option) + : '' + } + required + isClearable + isDisabled={!formik.values.party_type_option?.value} + /> + + { + formik.setFieldValue('payment_method_option', value); + formik.setFieldTouched('payment_method_option', true); + }} + isError={ + !!( + formik.touched.payment_method_option && + formik.errors.payment_method_option + ) + } + errorMessage={ + formik.touched.payment_method_option && + formik.errors.payment_method_option + ? String(formik.errors.payment_method_option) + : '' + } + required + isClearable + /> + ({ + 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} + onChange={(value) => { + formik.setFieldValue('bank_id_option', value); + formik.setFieldTouched('bank_id_option', true); + }} + isLoading={isLoadingBankOptions} + isError={ + !!( + formik.touched.bank_id_option && formik.errors.bank_id_option + ) + } + errorMessage={ + formik.touched.bank_id_option && formik.errors.bank_id_option + ? String(formik.errors.bank_id_option) + : '' + } + required + isClearable + /> + + + +