refactor(FE): Refactor form field updates to use destructured Formik

methods
This commit is contained in:
rstubryan
2026-03-04 16:48:21 +07:00
parent 7ae04b3f3e
commit f4a522fc0c
@@ -1,6 +1,6 @@
'use client'; 'use client';
import { useCallback, useEffect, useMemo, useState } from 'react'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useFormik } from 'formik'; import { useFormik } from 'formik';
import useSWR from 'swr'; import useSWR from 'swr';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
@@ -234,6 +234,8 @@ const PurchaseRequestForm = ({
}, },
}); });
const { setFieldValue, setFieldTouched, handleBlur } = formik;
const handleValidateForm = async () => { const handleValidateForm = async () => {
const errors = await formik.validateForm(); const errors = await formik.validateForm();
@@ -317,51 +319,73 @@ const PurchaseRequestForm = ({
}; };
// ===== UTILITY FUNCTIONS ===== // ===== UTILITY FUNCTIONS =====
const updateCreditTermBasedOnSupplier = useCallback( const prevSupplierIdRef = useRef<number | string>('');
(supplierId: number) => {
if (supplierId > 0 && isResponseSuccess(supplierRawData)) {
const supplierData = supplierRawData.data.find(
(s: Supplier) => s.id === supplierId
);
if (supplierData?.due_date) {
formik.setFieldTouched('credit_term', false);
formik.setFieldValue('credit_term', supplierData.due_date.toString());
} else {
formik.setFieldTouched('credit_term', false);
formik.setFieldValue('credit_term', '');
}
} else {
formik.setFieldTouched('credit_term', false);
formik.setFieldValue('credit_term', '');
}
},
[supplierRawData]
);
const resetPurchaseItems = useCallback(() => {
if (formik.values.items) {
formik.values.items.forEach((_, idx) => {
formik.setFieldTouched(`items.${idx}.product`, false);
formik.setFieldValue(`items.${idx}.product`, null);
formik.setFieldTouched(`items.${idx}.product_id`, false);
formik.setFieldValue(`items.${idx}.product_id`, 0);
formik.setFieldTouched(`items.${idx}.qty`, false);
formik.setFieldValue(`items.${idx}.qty`, 0);
});
}
}, []);
// ===== SIDE EFFECTS =====
useEffect(() => { useEffect(() => {
if (formik.values.supplier_id && Number(formik.values.supplier_id) > 0) { const currentSupplierId = formik.values.supplier_id || '';
updateCreditTermBasedOnSupplier(Number(formik.values.supplier_id));
resetPurchaseItems(); if (currentSupplierId === prevSupplierIdRef.current) {
} else { return;
formik.setFieldTouched('credit_term', false);
formik.setFieldValue('credit_term', '');
resetPurchaseItems();
} }
}, [formik.values.supplier_id]);
prevSupplierIdRef.current = currentSupplierId;
if (currentSupplierId && Number(currentSupplierId) > 0) {
if (isResponseSuccess(supplierRawData)) {
const supplierData = supplierRawData.data.find(
(s: Supplier) => s.id === Number(currentSupplierId)
);
const newCreditTerm = supplierData?.due_date || 0;
if (formik.values.credit_term !== newCreditTerm) {
setFieldTouched('credit_term', false);
setFieldValue('credit_term', newCreditTerm);
}
}
const itemsNeedReset = formik.values.items?.filter(
(item) => item.product_id !== 0 || item.product !== null
);
if (itemsNeedReset && itemsNeedReset.length > 0) {
formik.values.items.forEach((item, idx) => {
if (item.product_id !== 0 || item.product !== null) {
setFieldTouched(`items.${idx}.product`, false);
setFieldValue(`items.${idx}.product`, null);
setFieldTouched(`items.${idx}.product_id`, false);
setFieldValue(`items.${idx}.product_id`, 0);
setFieldTouched(`items.${idx}.qty`, false);
setFieldValue(`items.${idx}.qty`, 0);
}
});
}
} else {
if (formik.values.credit_term !== 0) {
setFieldTouched('credit_term', false);
setFieldValue('credit_term', 0);
}
const itemsNeedReset = formik.values.items?.filter(
(item) => item.product_id !== 0 || item.product !== null
);
if (itemsNeedReset && itemsNeedReset.length > 0) {
formik.values.items.forEach((item, idx) => {
if (item.product_id !== 0 || item.product !== null) {
setFieldTouched(`items.${idx}.product`, false);
setFieldValue(`items.${idx}.product`, null);
setFieldTouched(`items.${idx}.product_id`, false);
setFieldValue(`items.${idx}.product_id`, 0);
setFieldTouched(`items.${idx}.qty`, false);
setFieldValue(`items.${idx}.qty`, 0);
}
});
}
}
}, [
formik.values.supplier_id,
formik.values.items,
formik.values.credit_term,
supplierRawData,
setFieldTouched,
setFieldValue,
]);
useEffect(() => { useEffect(() => {
if (type !== 'add' && initialValues) { if (type !== 'add' && initialValues) {
@@ -381,63 +405,63 @@ const PurchaseRequestForm = ({
const supplier = val as OptionType | null; const supplier = val as OptionType | null;
const supplierId = Number(supplier?.value); const supplierId = Number(supplier?.value);
formik.setFieldTouched('supplier', true); setFieldTouched('supplier', true);
formik.setFieldValue('supplier', supplier); setFieldValue('supplier', supplier);
formik.setFieldTouched('supplier_id', true); setFieldTouched('supplier_id', true);
formik.setFieldValue('supplier_id', supplierId); setFieldValue('supplier_id', supplierId);
}, },
[] [setFieldTouched, setFieldValue]
); );
const handleCreditTermChange = useCallback( const handleCreditTermChange = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => { (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value; const value = e.target.value;
formik.setFieldTouched('credit_term', true); setFieldTouched('credit_term', true);
formik.setFieldValue('credit_term', value); setFieldValue('credit_term', value);
}, },
[] [setFieldTouched, setFieldValue]
); );
const handleCreditTermBlur = useCallback( const handleCreditTermBlur = useCallback(
(e: React.FocusEvent<HTMLInputElement>) => { (e: React.FocusEvent<HTMLInputElement>) => {
formik.handleBlur(e); handleBlur(e);
}, },
[formik] [handleBlur]
); );
const handleAreaChange = useCallback( const handleAreaChange = useCallback(
(val: OptionType | OptionType[] | null) => { (val: OptionType | OptionType[] | null) => {
const area = val as OptionType | null; const area = val as OptionType | null;
formik.setFieldTouched('area_id', true); setFieldTouched('area_id', true);
formik.setFieldValue('area_id', (area as OptionType)?.value || 0); setFieldValue('area_id', (area as OptionType)?.value || 0);
formik.setFieldTouched('area', true); setFieldTouched('area', true);
formik.setFieldValue('area', area); setFieldValue('area', area);
setSelectedArea((area as OptionType)?.value as string); setSelectedArea((area as OptionType)?.value as string);
setSelectedLocation(''); setSelectedLocation('');
const disabled = (area as OptionType)?.value == null; const disabled = (area as OptionType)?.value == null;
setDisabledLocation(disabled); setDisabledLocation(disabled);
formik.setFieldTouched('location_id', false); setFieldTouched('location_id', false);
formik.setFieldValue('location_id', 0); setFieldValue('location_id', 0);
formik.setFieldTouched('location', false); setFieldTouched('location', false);
formik.setFieldValue('location', null); setFieldValue('location', null);
}, },
[] [setFieldTouched, setFieldValue]
); );
const handleLocationChange = useCallback( const handleLocationChange = useCallback(
(val: OptionType | OptionType[] | null) => { (val: OptionType | OptionType[] | null) => {
const location = val as OptionType | null; const location = val as OptionType | null;
formik.setFieldTouched('location_id', true); setFieldTouched('location_id', true);
formik.setFieldValue('location_id', (location as OptionType)?.value || 0); setFieldValue('location_id', (location as OptionType)?.value || 0);
formik.setFieldTouched('location', true); setFieldTouched('location', true);
formik.setFieldValue('location', location); setFieldValue('location', location);
setSelectedLocation((location as OptionType)?.value as string); setSelectedLocation((location as OptionType)?.value as string);
}, },
[] [setFieldTouched, setFieldValue]
); );
const handleWarehouseChange = useCallback( const handleWarehouseChange = useCallback(
@@ -445,12 +469,12 @@ const PurchaseRequestForm = ({
const warehouse = val as OptionType | null; const warehouse = val as OptionType | null;
const warehouseId = (warehouse as OptionType)?.value || 0; const warehouseId = (warehouse as OptionType)?.value || 0;
formik.setFieldTouched(`items.${idx}.warehouse`, true); setFieldTouched(`items.${idx}.warehouse`, true);
formik.setFieldValue(`items.${idx}.warehouse`, warehouse); setFieldValue(`items.${idx}.warehouse`, warehouse);
formik.setFieldTouched(`items.${idx}.warehouse_id`, true); setFieldTouched(`items.${idx}.warehouse_id`, true);
formik.setFieldValue(`items.${idx}.warehouse_id`, warehouseId); setFieldValue(`items.${idx}.warehouse_id`, warehouseId);
}, },
[] [setFieldTouched, setFieldValue]
); );
// ===== PURCHASE ITEM OPERATIONS ===== // ===== PURCHASE ITEM OPERATIONS =====