refactor(FE): Refactor TransferToLayingFilterModal to use schema

validation
This commit is contained in:
rstubryan
2026-02-25 11:02:26 +07:00
parent 90942b41b9
commit e2e64f093f
3 changed files with 64 additions and 21 deletions
@@ -13,6 +13,10 @@ import { OptionType, useSelect } from '@/components/input/SelectInput';
import { ProjectFlockApi } from '@/services/api/production';
import { Flock } from '@/types/api/master-data/flock';
import { TransferToLayingFilter } from '@/types/api/production/transfer-to-laying';
import {
TransferToLayingFilterSchema,
TransferToLayingFilterValues,
} from '@/components/pages/production/transfer-to-laying/filter/TransferToLayingFilter';
interface TransferToLayingFilterModal {
ref: RefObject<HTMLDialogElement | null>;
@@ -49,13 +53,7 @@ const TransferToLayingFilterModal = ({
category: 'LAYING',
});
const formik = useFormik<{
startDate: string;
endDate: string;
flockSource: { value: number; label: string }[];
flockDestination: { value: number; label: string }[];
status: { value: number; label: string }[];
}>({
const formik = useFormik<TransferToLayingFilterValues>({
initialValues: {
startDate: '',
endDate: '',
@@ -63,15 +61,22 @@ const TransferToLayingFilterModal = ({
flockDestination: [],
status: [],
},
validationSchema: TransferToLayingFilterSchema,
onSubmit: async (values) => {
const formattedValues = {
...values,
flockSource: values.flockSource.map((item) => item.value),
flockDestination: values.flockDestination.map((item) => item.value),
status: values.status.map((item) => item.value),
flockSource: values.flockSource
? (values.flockSource as OptionType[]).map((item) => item.value)
: [],
flockDestination: values.flockDestination
? (values.flockDestination as OptionType[]).map((item) => item.value)
: [],
status: values.status
? (values.status as OptionType[]).map((item) => item.value)
: [],
};
onSubmit?.(formattedValues);
onSubmit?.(formattedValues as TransferToLayingFilter);
closeModalHandler();
},
onReset: () => {
@@ -81,17 +86,17 @@ const TransferToLayingFilterModal = ({
});
const flockSourceChangeHandler = (val: OptionType | OptionType[] | null) => {
formik.setFieldValue('flockSource', val as OptionType[]);
formik.setFieldValue('flockSource', val);
};
const flockDestinationChangeHandler = (
val: OptionType | OptionType[] | null
) => {
formik.setFieldValue('flockDestination', val as OptionType[]);
formik.setFieldValue('flockDestination', val);
};
const statusChangeHandler = (val: OptionType | OptionType[] | null) => {
formik.setFieldValue('status', val as OptionType[]);
formik.setFieldValue('status', val);
};
return (
@@ -132,7 +137,7 @@ const TransferToLayingFilterModal = ({
<DateInput
name='startDate'
placeholder='Tanggal Awal'
value={formik.values.startDate}
value={formik.values.startDate || ''}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
/>
@@ -140,16 +145,22 @@ const TransferToLayingFilterModal = ({
<DateInput
name='endDate'
placeholder='Tanggal Akhir'
value={formik.values.endDate}
value={formik.values.endDate || ''}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
isError={formik.touched.endDate && !!formik.errors.endDate}
/>
</div>
{formik.touched.endDate && formik.errors.endDate && (
<span className='text-xs text-error mt-1'>
{formik.errors.endDate}
</span>
)}
<SelectInputCheckbox
label='Flock Asal'
placeholder='Flock Asal'
value={formik.values.flockSource}
value={formik.values.flockSource as OptionType[]}
onChange={flockSourceChangeHandler}
options={flockSourceOptions}
isLoading={isLoadingFlockSourceOptions}
@@ -160,7 +171,7 @@ const TransferToLayingFilterModal = ({
<SelectInputCheckbox
label='Flock Tujuan'
placeholder='Flock Tujuan'
value={formik.values.flockDestination}
value={formik.values.flockDestination as OptionType[]}
onChange={flockDestinationChangeHandler}
options={flockDestinationOptions}
isLoading={isLoadingFlockDestinationOptions}
@@ -176,7 +187,7 @@ const TransferToLayingFilterModal = ({
{ value: 'APPROVED', label: 'Disetujui' },
{ value: 'REJECTED', label: 'Ditolak' },
]}
value={formik.values.status}
value={formik.values.status as OptionType[]}
onChange={statusChangeHandler}
/>
</div>
@@ -1,6 +1,6 @@
'use client';
import { ChangeEventHandler, useEffect, useMemo, useState } from 'react';
import { ChangeEventHandler, useEffect, useState } from 'react';
import useSWR from 'swr';
import {
CellContext,
@@ -17,7 +17,6 @@ import { useModal } from '@/components/Modal';
import CheckboxInput from '@/components/input/CheckboxInput';
import RequirePermission from '@/components/helper/RequirePermission';
import PopoverButton from '@/components/popover/PopoverButton';
import Badge from '@/components/Badge';
import PopoverContent from '@/components/popover/PopoverContent';
import Dropdown from '@/components/Dropdown';
import StatusBadge from '@/components/helper/StatusBadge';
@@ -0,0 +1,33 @@
import * as yup from 'yup';
export type TransferToLayingFilterType = {
startDate: string | null;
endDate: string | null;
flockSource: number[];
flockDestination: number[];
status: string[];
};
export const TransferToLayingFilterSchema = yup.object({
startDate: yup.string().optional().nullable(),
endDate: yup
.string()
.optional()
.nullable()
.test(
'is-greater-than-start',
'Tanggal akhir tidak boleh masa lampau',
function (value) {
const { startDate } = this.parent;
if (!startDate || !value) return true;
return new Date(value) >= new Date(startDate);
}
),
flockSource: yup.array().optional().nullable(),
flockDestination: yup.array().optional().nullable(),
status: yup.array().optional().nullable(),
});
export type TransferToLayingFilterValues = yup.InferType<
typeof TransferToLayingFilterSchema
>;