refactor(FE): Add validation and error messages to filter modal

This commit is contained in:
rstubryan
2026-01-09 09:30:51 +07:00
parent 4fdfe63dc9
commit 3ce30115f8
@@ -230,6 +230,7 @@ const UniformityTable = () => {
const [filterStartDate, setFilterStartDate] = useState('');
const [filterEndDate, setFilterEndDate] = useState('');
const [projectFlockSearchValue, setProjectFlockSearchValue] = useState('');
const [filterErrors, setFilterErrors] = useState<Record<string, string>>({});
const {
setInputValue: setFilterLocationInputValue,
@@ -423,9 +424,38 @@ const UniformityTable = () => {
}, []);
const handleApplyFilters = useCallback(() => {
setIsSubmitted(true);
filterModal.closeModal();
}, [filterModal]);
const errors: Record<string, string> = {};
if (!filterStartDate) {
errors.start_date = 'Tanggal mulai wajib diisi';
}
if (!filterEndDate) {
errors.end_date = 'Tanggal akhir wajib diisi';
}
if (!filterLocation) {
errors.location = 'Lokasi wajib dipilih';
}
if (!filterProjectFlock) {
errors.project_flock = 'Project Flock wajib dipilih';
}
if (!filterKandang) {
errors.kandang = 'Kandang wajib dipilih';
}
setFilterErrors(errors);
if (Object.keys(errors).length === 0) {
setIsSubmitted(true);
filterModal.closeModal();
}
}, [
filterModal,
filterStartDate,
filterEndDate,
filterLocation,
filterProjectFlock,
filterKandang,
]);
const selectedRowIds = useMemo(() => {
return Object.keys(rowSelection)
@@ -1124,58 +1154,105 @@ const UniformityTable = () => {
</div>
<div className='space-y-4 px-4'>
<div className='grid grid-cols-1 sm:grid-cols-2 sm:gap-4'>
<DateInput
label='Tanggal'
name='start_date'
value={filterStartDate}
onChange={(e) => setFilterStartDate(e.target.value)}
className={{ wrapper: 'w-full' }}
/>
<div>
<DateInput
label='Tanggal'
name='start_date'
value={filterStartDate}
onChange={(e) => {
setFilterStartDate(e.target.value);
setFilterErrors((prev) => ({ ...prev, start_date: '' }));
}}
className={{ wrapper: 'w-full' }}
/>
{filterErrors.start_date && (
<p className='text-red-500 text-sm mt-1'>
{filterErrors.start_date}
</p>
)}
</div>
<DateInput
label=' '
name='end_date'
value={filterEndDate}
onChange={(e) => setFilterEndDate(e.target.value)}
className={{ wrapper: 'w-full' }}
/>
<div>
<DateInput
label=' '
name='end_date'
value={filterEndDate}
onChange={(e) => {
setFilterEndDate(e.target.value);
setFilterErrors((prev) => ({ ...prev, end_date: '' }));
}}
className={{ wrapper: 'w-full' }}
/>
{filterErrors.end_date && (
<p className='text-red-500 text-sm mt-1'>
{filterErrors.end_date}
</p>
)}
</div>
</div>
<SelectInput
label='Lokasi'
placeholder='Pilih Lokasi...'
value={filterLocation}
onChange={handleFilterLocationChange}
options={filterLocationOptions}
onInputChange={setFilterLocationInputValue}
isLoading={isLoadingFilterLocations}
isClearable
className={{ wrapper: 'w-full' }}
/>
<div>
<SelectInput
label='Lokasi'
placeholder='Pilih Lokasi...'
value={filterLocation}
onChange={(value) => {
handleFilterLocationChange(value);
setFilterErrors((prev) => ({ ...prev, location: '' }));
}}
options={filterLocationOptions}
onInputChange={setFilterLocationInputValue}
isLoading={isLoadingFilterLocations}
className={{ wrapper: 'w-full' }}
/>
{filterErrors.location && (
<p className='text-red-500 text-sm mt-1'>
{filterErrors.location}
</p>
)}
</div>
<SelectInput
label='Project Flock'
placeholder='Pilih Project Flock...'
value={filterProjectFlock}
onChange={handleFilterProjectFlockChange}
options={filterProjectFlockOptions}
onInputChange={setProjectFlockSearchValue}
isLoading={isLoadingFilterProjectFlocks}
isDisabled={!filterLocation}
isClearable
className={{ wrapper: 'w-full' }}
/>
<div>
<SelectInput
label='Project Flock'
placeholder='Pilih Project Flock...'
value={filterProjectFlock}
onChange={(value) => {
handleFilterProjectFlockChange(value);
setFilterErrors((prev) => ({ ...prev, project_flock: '' }));
}}
options={filterProjectFlockOptions}
onInputChange={setProjectFlockSearchValue}
isLoading={isLoadingFilterProjectFlocks}
isDisabled={!filterLocation}
className={{ wrapper: 'w-full' }}
/>
{filterErrors.project_flock && (
<p className='text-red-500 text-sm mt-1'>
{filterErrors.project_flock}
</p>
)}
</div>
<SelectInput
label='Kandang'
placeholder='Pilih Kandang...'
value={filterKandang}
onChange={handleFilterKandangChange}
options={filterKandangOptions}
isDisabled={!filterProjectFlock}
isClearable
className={{ wrapper: 'w-full' }}
/>
<div>
<SelectInput
label='Kandang'
placeholder='Pilih Kandang...'
value={filterKandang}
onChange={(value) => {
handleFilterKandangChange(value);
setFilterErrors((prev) => ({ ...prev, kandang: '' }));
}}
options={filterKandangOptions}
isDisabled={!filterProjectFlock}
className={{ wrapper: 'w-full' }}
/>
{filterErrors.kandang && (
<p className='text-red-500 text-sm mt-1'>
{filterErrors.kandang}
</p>
)}
</div>
</div>
{/* Action Buttons */}