From c249585bc292571ff3c0abc8d1a41a207f555c6c Mon Sep 17 00:00:00 2001 From: rstubryan Date: Wed, 22 Oct 2025 13:55:12 +0700 Subject: [PATCH] refactor(FE-114): enhance form UI by adding required field indicators for multiple inputs --- .../inventory/movement/form/MovementForm.tsx | 92 +++++++- .../recording/form/RecordingForm.tsx | 217 ++++++++++++++---- 2 files changed, 254 insertions(+), 55 deletions(-) diff --git a/src/components/pages/inventory/movement/form/MovementForm.tsx b/src/components/pages/inventory/movement/form/MovementForm.tsx index 8f432700..662eaca8 100644 --- a/src/components/pages/inventory/movement/form/MovementForm.tsx +++ b/src/components/pages/inventory/movement/form/MovementForm.tsx @@ -864,8 +864,24 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => { )} - Produk - Qty + + Produk + + * + + + + Qty + + * + + {type !== 'detail' && Aksi} @@ -1032,7 +1048,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => { {/* Deliveries table */}
-

Pengiriman

+

Pengiriman

@@ -1064,14 +1080,70 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => { )} - - - - + + + + - - - + + + {type !== 'detail' && } diff --git a/src/components/pages/production/recording/form/RecordingForm.tsx b/src/components/pages/production/recording/form/RecordingForm.tsx index 98fd0f0b..bcf3a0cf 100644 --- a/src/components/pages/production/recording/form/RecordingForm.tsx +++ b/src/components/pages/production/recording/form/RecordingForm.tsx @@ -418,27 +418,96 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { formik.setFieldValue('body_weight', newBodyWeight); }; - const handleBodyWeightChange = - (fieldName: string, idx: number) => - (e: React.ChangeEvent) => { - formik.handleChange(e); - setTimeout(() => { - const currentWeight = formik.values.body_weight?.[idx]; - if (currentWeight) { - const newAverage = - currentWeight.chicken_count > 0 - ? Math.round( - currentWeight.chicken_weight / currentWeight.chicken_count - ) - : 0; + // Handle calculation when chicken_weight changes + const handleChickenWeightChange = useCallback( + (idx: number, value: number) => { + formik.setFieldValue(`body_weight.${idx}.chicken_weight`, value); + const currentWeight = formik.values.body_weight?.[idx]; + if (currentWeight) { + const chickenCount = currentWeight.chicken_count; + if (chickenCount > 0 && value > 0) { + const averageWeight = Math.round(value / chickenCount); formik.setFieldValue( `body_weight.${idx}.average_chicken_weight`, - newAverage + averageWeight ); + } else { + formik.setFieldValue(`body_weight.${idx}.average_chicken_weight`, ''); } - }, 0); - }; + } + }, + [formik] + ); + + // Handle calculation when chicken_count changes + const handleChickenCountChange = useCallback( + (idx: number, value: number) => { + formik.setFieldValue(`body_weight.${idx}.chicken_count`, value); + + const currentWeight = formik.values.body_weight?.[idx]; + if (currentWeight) { + const chickenWeight = currentWeight.chicken_weight; + if (chickenWeight > 0 && value > 0) { + const averageWeight = Math.round(chickenWeight / value); + formik.setFieldValue( + `body_weight.${idx}.average_chicken_weight`, + averageWeight + ); + } else { + formik.setFieldValue(`body_weight.${idx}.average_chicken_weight`, ''); + } + } + }, + [formik] + ); + + // Handle calculation when average_weight changes + const handleAverageWeightChange = useCallback( + (idx: number, value: number) => { + formik.setFieldValue(`body_weight.${idx}.average_chicken_weight`, value); + + const currentWeight = formik.values.body_weight?.[idx]; + if (currentWeight) { + const chickenCount = currentWeight.chicken_count; + if (chickenCount > 0 && value > 0) { + const totalWeight = value * chickenCount; + formik.setFieldValue( + `body_weight.${idx}.chicken_weight`, + totalWeight + ); + } else if (value === 0) { + formik.setFieldValue(`body_weight.${idx}.chicken_weight`, ''); + } + } + }, + [formik] + ); + + // Create wrapper handlers that match NumberInput's onChange signature + const handleChickenWeightChangeWrapper = useCallback( + (idx: number) => (e: React.ChangeEvent) => { + const value = parseFloat(e.target.value) || 0; + handleChickenWeightChange(idx, value); + }, + [handleChickenWeightChange] + ); + + const handleChickenCountChangeWrapper = useCallback( + (idx: number) => (e: React.ChangeEvent) => { + const value = parseFloat(e.target.value) || 0; + handleChickenCountChange(idx, value); + }, + [handleChickenCountChange] + ); + + const handleAverageWeightChangeWrapper = useCallback( + (idx: number) => (e: React.ChangeEvent) => { + const value = parseFloat(e.target.value) || 0; + handleAverageWeightChange(idx, value); + }, + [handleAverageWeightChange] + ); const removeBodyWeight = (idx: number) => { const updatedBodyWeight = formik.values.body_weight?.filter( @@ -712,9 +781,25 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { )} - + - + {type !== 'detail' && } @@ -945,9 +1030,33 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { )} - - - + + + {type !== 'detail' && } @@ -981,10 +1090,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { required name={`body_weight.${idx}.chicken_weight`} value={weight.chicken_weight} - onChange={handleBodyWeightChange( - 'chicken_weight', - idx - )} + onChange={handleChickenWeightChangeWrapper(idx)} onBlur={formik.handleBlur} maskType='weight' weightUnit='gram' @@ -1015,10 +1121,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { required name={`body_weight.${idx}.chicken_count`} value={weight.chicken_count} - onChange={handleBodyWeightChange( - 'chicken_count', - idx - )} + onChange={handleChickenCountChangeWrapper(idx)} onBlur={formik.handleBlur} maskType='number' decimals={0} @@ -1048,15 +1151,8 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { 0 - ? Math.round( - weight.chicken_weight / - weight.chicken_count - ) - : 0 - } - onChange={formik.handleChange} + value={weight.average_chicken_weight || ''} + onChange={handleAverageWeightChangeWrapper(idx)} onBlur={formik.handleBlur} maskType='weight' weightUnit='gram' @@ -1076,12 +1172,11 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { idx ).errorMessage } - readOnly={true} - disabled={true} + readOnly={type === 'detail'} className={{ wrapper: 'w-full min-w-24', }} - placeholder='0' + placeholder='' /> @@ -1175,9 +1270,25 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { )} - + - + {type !== 'detail' && } @@ -1418,8 +1529,24 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { )} - - + + {type !== 'detail' && }
ProdukQtySupplierPlat Nomor + Produk + + * + + + Qty + + * + + + Supplier + + * + + + Plat Nomor + + * + + DokumenBiaya Pengiriman (Rp.)Biaya Per Item (Rp.)Nama Sopir + Biaya Pengiriman (Rp.) + + * + + + Biaya Per Item (Rp.) + + * + + + Nama Sopir + + * + + Aksi
Nama Pakan + Nama Pakan + + * + + Total Stock pada saat iniJumlah Stock yang digunakan + Jumlah Stock yang digunakan + + * + + Action
Berat (Gram)Jumlah AyamRata-rata berat Ayam + Berat (Gram) + + * + + + Jumlah Ayam + + * + + + Rata-rata berat Ayam + + * + + Action
Name Vaksin + Name Vaksin + + * + + Total Stock pada saat iniJumlah Stock yang digunakan + Jumlah Stock yang digunakan + + * + + Action
Kondisi/Alasan MortalitasJumlah + Kondisi/Alasan Mortalitas + + * + + + Jumlah + + * + + Action