feat(FE-114,136): add error handling for repeater inputs in RecordingForm

This commit is contained in:
rstubryan
2025-10-15 10:37:04 +07:00
parent 6f0467918b
commit 24144f01d4
@@ -112,6 +112,32 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
const flockOptions = DUMMY_FLOCKS;
const isRepeaterInputError = <T extends keyof CreateRecordingPayload>(
arrayName: T,
field: T extends 'data_pakan'
? keyof CreateRecordingPayload['data_pakan'][0]
: T extends 'bobot_badan'
? keyof CreateRecordingPayload['bobot_badan'][0]
: T extends 'vaksinasi'
? keyof CreateRecordingPayload['vaksinasi'][0]
: T extends 'mortalitas'
? keyof CreateRecordingPayload['mortalitas'][0]
: never,
idx: number
) => {
const touched = formik.touched[arrayName] as
| Record<string, boolean | undefined>[]
| undefined;
const errors = formik.errors[arrayName] as
| Record<string, string | undefined>[]
| undefined;
return (
touched?.[idx]?.[field as string] &&
Boolean(errors?.[idx]?.[field as string])
);
};
const addDataPakan = () => {
const newDataPakan = [
...(formik.values.data_pakan || []),
@@ -371,7 +397,15 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
value={pakan.nama_pakan}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
isError={isRepeaterInputError(
'data_pakan',
'nama_pakan',
idx
)}
readOnly={type === 'detail'}
className={{
wrapper: 'w-full min-w-24',
}}
/>
</td>
<td>
@@ -382,7 +416,15 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
value={pakan.qty_pakan}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
isError={isRepeaterInputError(
'data_pakan',
'qty_pakan',
idx
)}
readOnly={type === 'detail'}
className={{
wrapper: 'w-full min-w-24',
}}
/>
</td>
<td>
@@ -393,7 +435,15 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
value={pakan.stock_pakan}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
isError={isRepeaterInputError(
'data_pakan',
'stock_pakan',
idx
)}
readOnly={type === 'detail'}
className={{
wrapper: 'w-full min-w-24',
}}
/>
</td>
{type !== 'detail' && (
@@ -515,6 +565,11 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
value={bobot.berat_ayam}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
isError={isRepeaterInputError(
'bobot_badan',
'berat_ayam',
idx
)}
readOnly={type === 'detail'}
/>
</td>
@@ -526,6 +581,11 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
value={bobot.jumlah_ayam}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
isError={isRepeaterInputError(
'bobot_badan',
'jumlah_ayam',
idx
)}
readOnly={type === 'detail'}
/>
</td>
@@ -537,6 +597,11 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
value={bobot.rata_rata_berat_ayam}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
isError={isRepeaterInputError(
'bobot_badan',
'rata_rata_berat_ayam',
idx
)}
readOnly={type === 'detail'}
/>
</td>
@@ -658,7 +723,15 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
value={vaksin.nama_vaksin}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
isError={isRepeaterInputError(
'vaksinasi',
'nama_vaksin',
idx
)}
readOnly={type === 'detail'}
className={{
wrapper: 'w-full min-w-24',
}}
/>
</td>
<td>
@@ -669,7 +742,15 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
value={vaksin.total_stock}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
isError={isRepeaterInputError(
'vaksinasi',
'total_stock',
idx
)}
readOnly={type === 'detail'}
className={{
wrapper: 'w-full min-w-24',
}}
/>
</td>
<td>
@@ -680,7 +761,15 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
value={vaksin.jumlah_stock}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
isError={isRepeaterInputError(
'vaksinasi',
'jumlah_stock',
idx
)}
readOnly={type === 'detail'}
className={{
wrapper: 'w-full min-w-24',
}}
/>
</td>
{type !== 'detail' && (
@@ -805,6 +894,11 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
(val as OptionType)?.value
);
}}
isError={isRepeaterInputError(
'mortalitas',
'kondisi',
idx
)}
options={RECORDING_FLAG_OPTIONS}
isDisabled={type === 'detail'}
/>
@@ -817,7 +911,15 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
value={mortal.jumlah}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
isError={isRepeaterInputError(
'mortalitas',
'jumlah',
idx
)}
readOnly={type === 'detail'}
className={{
wrapper: 'w-full min-w-24',
}}
/>
</td>
{type !== 'detail' && (