feat: create TransferToLayingFilterModal component

This commit is contained in:
ValdiANS
2026-01-23 23:03:34 +07:00
parent 6c70dc93ce
commit 0b1349ca8d
@@ -0,0 +1,208 @@
'use client';
import { RefObject } from 'react';
import { useFormik } from 'formik';
import { Icon } from '@iconify/react';
import Modal from '@/components/Modal';
import Button from '@/components/Button';
import DateInput from '@/components/input/DateInput';
import SelectInputCheckbox from '@/components/input/SelectInputCheckbox';
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';
interface TransferToLayingFilterModal {
ref: RefObject<HTMLDialogElement | null>;
onSubmit?: (values: TransferToLayingFilter) => void;
onReset?: () => void;
}
const TransferToLayingFilterModal = ({
ref,
onSubmit,
onReset,
}: TransferToLayingFilterModal) => {
const closeModalHandler = () => {
ref.current?.close();
};
// Flock Source
const {
setInputValue: setFlockSourceInputValue,
options: flockSourceOptions,
isLoadingOptions: isLoadingFlockSourceOptions,
loadMore: loadMoreFlockSource,
} = useSelect<Flock>(ProjectFlockApi.basePath, 'id', 'flock_name', 'search', {
category: 'GROWING',
});
// Flock Destination
const {
setInputValue: setFlockDestinationInputValue,
options: flockDestinationOptions,
isLoadingOptions: isLoadingFlockDestinationOptions,
loadMore: loadMoreFlockDestination,
} = useSelect<Flock>(ProjectFlockApi.basePath, 'id', 'flock_name', 'search', {
category: 'LAYING',
});
const formik = useFormik<{
startDate: string;
endDate: string;
flockSource: { value: number; label: string }[];
flockDestination: { value: number; label: string }[];
status: { value: number; label: string }[];
}>({
initialValues: {
startDate: '',
endDate: '',
flockSource: [],
flockDestination: [],
status: [],
},
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),
};
onSubmit?.(formattedValues);
closeModalHandler();
},
onReset: () => {
onReset?.();
closeModalHandler();
},
});
const flockSourceChangeHandler = (val: OptionType | OptionType[] | null) => {
formik.setFieldValue('flockSource', val as OptionType[]);
};
const flockDestinationChangeHandler = (
val: OptionType | OptionType[] | null
) => {
formik.setFieldValue('flockDestination', val as OptionType[]);
};
const statusChangeHandler = (val: OptionType | OptionType[] | null) => {
formik.setFieldValue('status', val as OptionType[]);
};
return (
<Modal
ref={ref}
className={{
modalBox: 'p-0 rounded-xl',
}}
>
<form
onSubmit={formik.handleSubmit}
onReset={formik.handleReset}
className='w-full flex flex-col'
>
{/* Modal Header */}
<div className='p-4 flex items-center justify-between gap-2 border-b border-gray-300'>
<div className='flex items-center gap-2 text-primary'>
<Icon icon='heroicons:funnel' width={20} height={20} />
<h3 className='text-sm font-medium'>Filter Data</h3>
</div>
<Button
type='button'
variant='ghost'
color='none'
onClick={closeModalHandler}
className='p-0 text-base-content/50 hover:text-base-content'
>
<Icon icon='heroicons:x-mark' width={20} height={20} />
</Button>
</div>
{/* Modal Body */}
<div className='p-4 flex flex-col gap-1.5'>
<div className='flex flex-col'>
<span className='py-2 text-xs font-semibold'>Tanggal</span>
<div className='flex flex-row items-center gap-1.5'>
<DateInput
name='startDate'
placeholder='Tanggal Awal'
value={formik.values.startDate}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
/>
<hr className='w-full max-w-3 h-px border-base-content/10' />
<DateInput
name='endDate'
placeholder='Tanggal Akhir'
value={formik.values.endDate}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
/>
</div>
<SelectInputCheckbox
label='Flock Asal'
placeholder='Flock Asal'
value={formik.values.flockSource}
onChange={flockSourceChangeHandler}
options={flockSourceOptions}
isLoading={isLoadingFlockSourceOptions}
onInputChange={setFlockSourceInputValue}
onMenuScrollToBottom={loadMoreFlockSource}
/>
<SelectInputCheckbox
label='Flock Tujuan'
placeholder='Flock Tujuan'
value={formik.values.flockDestination}
onChange={flockDestinationChangeHandler}
options={flockDestinationOptions}
isLoading={isLoadingFlockDestinationOptions}
onInputChange={setFlockDestinationInputValue}
onMenuScrollToBottom={loadMoreFlockDestination}
/>
<SelectInputCheckbox
label='Status'
placeholder='Pilih Status'
options={[
{ value: 'PENDING', label: 'Pengajuan' },
{ value: 'APPROVED', label: 'Disetujui' },
{ value: 'REJECTED', label: 'Ditolak' },
]}
value={formik.values.status}
onChange={statusChangeHandler}
/>
</div>
</div>
{/* Modal Footer */}
<div className='p-4 flex justify-between gap-4 border-t border-gray-300 bg-gray-100'>
<Button
type='reset'
variant='ghost'
color='none'
className='p-3 rounded-lg text-base-content/65'
>
Reset Filter
</Button>
<Button
type='submit'
className='p-3 rounded-lg w-fit sm:w-full max-w-40 text-base-100 text-sm'
>
Apply Filter
</Button>
</div>
</form>
</Modal>
);
};
export default TransferToLayingFilterModal;