refactor(FE-114): enhance tanggal_recording handling and improve error messaging in RecordingForm

This commit is contained in:
rstubryan
2025-10-15 13:45:48 +07:00
parent 24144f01d4
commit 2ee88a2742
@@ -67,7 +67,10 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
setRecordingFormErrorMessage(''); setRecordingFormErrorMessage('');
const payload: CreateRecordingPayload = { const payload: CreateRecordingPayload = {
flock_id: values.flock_id, flock_id: values.flock_id,
tanggal_recording: values.tanggal_recording.toISOString(), tanggal_recording:
values.tanggal_recording instanceof Date
? values.tanggal_recording.toISOString()
: new Date().toISOString(),
data_pakan: (values.data_pakan ?? []).map((p) => ({ data_pakan: (values.data_pakan ?? []).map((p) => ({
nama_pakan: p.nama_pakan, nama_pakan: p.nama_pakan,
qty_pakan: p.qty_pakan, qty_pakan: p.qty_pakan,
@@ -126,16 +129,31 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
idx: number idx: number
) => { ) => {
const touched = formik.touched[arrayName] as const touched = formik.touched[arrayName] as
| Record<string, boolean | undefined>[] | {
| undefined; [key: string]: boolean | undefined;
const errors = formik.errors[arrayName] as }[]
| Record<string, string | undefined>[]
| undefined; | undefined;
return ( const errors = formik.errors[arrayName] as
touched?.[idx]?.[field as string] && | {
Boolean(errors?.[idx]?.[field as string]) [key: string]: string | undefined;
); }[]
| undefined;
if (!touched || !Array.isArray(touched)) {
return {
isError: false,
errorMessage: undefined,
};
}
const touchedField = touched[idx]?.[field as string];
const errorField = errors?.[idx]?.[field as string];
return {
isError: touchedField && Boolean(errorField),
errorMessage: touchedField ? errorField : undefined,
};
}; };
const addDataPakan = () => { const addDataPakan = () => {
@@ -312,11 +330,17 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
label='Tanggal Recording' label='Tanggal Recording'
type='date' type='date'
name='tanggal_recording' name='tanggal_recording'
value={formik.values.tanggal_recording value={
formik.values.tanggal_recording instanceof Date
? formik.values.tanggal_recording
.toISOString() .toISOString()
.substring(0, 10)} .substring(0, 10)
: ''
}
onChange={(e) => { onChange={(e) => {
const date = new Date(e.target.value); const date = e.target.value
? new Date(e.target.value)
: new Date();
formik.setFieldValue('tanggal_recording', date); formik.setFieldValue('tanggal_recording', date);
}} }}
onBlur={formik.handleBlur} onBlur={formik.handleBlur}
@@ -397,11 +421,20 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
value={pakan.nama_pakan} value={pakan.nama_pakan}
onChange={formik.handleChange} onChange={formik.handleChange}
onBlur={formik.handleBlur} onBlur={formik.handleBlur}
isError={isRepeaterInputError( isError={
isRepeaterInputError(
'data_pakan', 'data_pakan',
'nama_pakan', 'nama_pakan',
idx idx
)} ).isError
}
errorMessage={
isRepeaterInputError(
'data_pakan',
'nama_pakan',
idx
).errorMessage
}
readOnly={type === 'detail'} readOnly={type === 'detail'}
className={{ className={{
wrapper: 'w-full min-w-24', wrapper: 'w-full min-w-24',
@@ -416,11 +449,20 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
value={pakan.qty_pakan} value={pakan.qty_pakan}
onChange={formik.handleChange} onChange={formik.handleChange}
onBlur={formik.handleBlur} onBlur={formik.handleBlur}
isError={isRepeaterInputError( isError={
isRepeaterInputError(
'data_pakan', 'data_pakan',
'qty_pakan', 'qty_pakan',
idx idx
)} ).isError
}
errorMessage={
isRepeaterInputError(
'data_pakan',
'qty_pakan',
idx
).errorMessage
}
readOnly={type === 'detail'} readOnly={type === 'detail'}
className={{ className={{
wrapper: 'w-full min-w-24', wrapper: 'w-full min-w-24',
@@ -435,11 +477,20 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
value={pakan.stock_pakan} value={pakan.stock_pakan}
onChange={formik.handleChange} onChange={formik.handleChange}
onBlur={formik.handleBlur} onBlur={formik.handleBlur}
isError={isRepeaterInputError( isError={
isRepeaterInputError(
'data_pakan', 'data_pakan',
'stock_pakan', 'stock_pakan',
idx idx
)} ).isError
}
errorMessage={
isRepeaterInputError(
'data_pakan',
'stock_pakan',
idx
).errorMessage
}
readOnly={type === 'detail'} readOnly={type === 'detail'}
className={{ className={{
wrapper: 'w-full min-w-24', wrapper: 'w-full min-w-24',
@@ -565,11 +616,20 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
value={bobot.berat_ayam} value={bobot.berat_ayam}
onChange={formik.handleChange} onChange={formik.handleChange}
onBlur={formik.handleBlur} onBlur={formik.handleBlur}
isError={isRepeaterInputError( isError={
isRepeaterInputError(
'bobot_badan', 'bobot_badan',
'berat_ayam', 'berat_ayam',
idx idx
)} ).isError
}
errorMessage={
isRepeaterInputError(
'bobot_badan',
'berat_ayam',
idx
).errorMessage
}
readOnly={type === 'detail'} readOnly={type === 'detail'}
/> />
</td> </td>
@@ -581,11 +641,20 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
value={bobot.jumlah_ayam} value={bobot.jumlah_ayam}
onChange={formik.handleChange} onChange={formik.handleChange}
onBlur={formik.handleBlur} onBlur={formik.handleBlur}
isError={isRepeaterInputError( isError={
isRepeaterInputError(
'bobot_badan', 'bobot_badan',
'jumlah_ayam', 'jumlah_ayam',
idx idx
)} ).isError
}
errorMessage={
isRepeaterInputError(
'bobot_badan',
'jumlah_ayam',
idx
).errorMessage
}
readOnly={type === 'detail'} readOnly={type === 'detail'}
/> />
</td> </td>
@@ -597,11 +666,20 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
value={bobot.rata_rata_berat_ayam} value={bobot.rata_rata_berat_ayam}
onChange={formik.handleChange} onChange={formik.handleChange}
onBlur={formik.handleBlur} onBlur={formik.handleBlur}
isError={isRepeaterInputError( isError={
isRepeaterInputError(
'bobot_badan', 'bobot_badan',
'rata_rata_berat_ayam', 'rata_rata_berat_ayam',
idx idx
)} ).isError
}
errorMessage={
isRepeaterInputError(
'bobot_badan',
'rata_rata_berat_ayam',
idx
).errorMessage
}
readOnly={type === 'detail'} readOnly={type === 'detail'}
/> />
</td> </td>
@@ -723,11 +801,20 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
value={vaksin.nama_vaksin} value={vaksin.nama_vaksin}
onChange={formik.handleChange} onChange={formik.handleChange}
onBlur={formik.handleBlur} onBlur={formik.handleBlur}
isError={isRepeaterInputError( isError={
isRepeaterInputError(
'vaksinasi', 'vaksinasi',
'nama_vaksin', 'nama_vaksin',
idx idx
)} ).isError
}
errorMessage={
isRepeaterInputError(
'vaksinasi',
'nama_vaksin',
idx
).errorMessage
}
readOnly={type === 'detail'} readOnly={type === 'detail'}
className={{ className={{
wrapper: 'w-full min-w-24', wrapper: 'w-full min-w-24',
@@ -742,11 +829,20 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
value={vaksin.total_stock} value={vaksin.total_stock}
onChange={formik.handleChange} onChange={formik.handleChange}
onBlur={formik.handleBlur} onBlur={formik.handleBlur}
isError={isRepeaterInputError( isError={
isRepeaterInputError(
'vaksinasi', 'vaksinasi',
'total_stock', 'total_stock',
idx idx
)} ).isError
}
errorMessage={
isRepeaterInputError(
'vaksinasi',
'total_stock',
idx
).errorMessage
}
readOnly={type === 'detail'} readOnly={type === 'detail'}
className={{ className={{
wrapper: 'w-full min-w-24', wrapper: 'w-full min-w-24',
@@ -761,11 +857,20 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
value={vaksin.jumlah_stock} value={vaksin.jumlah_stock}
onChange={formik.handleChange} onChange={formik.handleChange}
onBlur={formik.handleBlur} onBlur={formik.handleBlur}
isError={isRepeaterInputError( isError={
isRepeaterInputError(
'vaksinasi', 'vaksinasi',
'jumlah_stock', 'jumlah_stock',
idx idx
)} ).isError
}
errorMessage={
isRepeaterInputError(
'vaksinasi',
'jumlah_stock',
idx
).errorMessage
}
readOnly={type === 'detail'} readOnly={type === 'detail'}
className={{ className={{
wrapper: 'w-full min-w-24', wrapper: 'w-full min-w-24',
@@ -894,11 +999,14 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
(val as OptionType)?.value (val as OptionType)?.value
); );
}} }}
isError={isRepeaterInputError( isError={
'mortalitas', isRepeaterInputError('mortalitas', 'kondisi', idx)
'kondisi', .isError
idx }
)} errorMessage={
isRepeaterInputError('mortalitas', 'kondisi', idx)
.errorMessage
}
options={RECORDING_FLAG_OPTIONS} options={RECORDING_FLAG_OPTIONS}
isDisabled={type === 'detail'} isDisabled={type === 'detail'}
/> />
@@ -911,11 +1019,14 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
value={mortal.jumlah} value={mortal.jumlah}
onChange={formik.handleChange} onChange={formik.handleChange}
onBlur={formik.handleBlur} onBlur={formik.handleBlur}
isError={isRepeaterInputError( isError={
'mortalitas', isRepeaterInputError('mortalitas', 'jumlah', idx)
'jumlah', .isError
idx }
)} errorMessage={
isRepeaterInputError('mortalitas', 'jumlah', idx)
.errorMessage
}
readOnly={type === 'detail'} readOnly={type === 'detail'}
className={{ className={{
wrapper: 'w-full min-w-24', wrapper: 'w-full min-w-24',