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 [filterStartDate, setFilterStartDate] = useState('');
const [filterEndDate, setFilterEndDate] = useState(''); const [filterEndDate, setFilterEndDate] = useState('');
const [projectFlockSearchValue, setProjectFlockSearchValue] = useState(''); const [projectFlockSearchValue, setProjectFlockSearchValue] = useState('');
const [filterErrors, setFilterErrors] = useState<Record<string, string>>({});
const { const {
setInputValue: setFilterLocationInputValue, setInputValue: setFilterLocationInputValue,
@@ -423,9 +424,38 @@ const UniformityTable = () => {
}, []); }, []);
const handleApplyFilters = useCallback(() => { const handleApplyFilters = useCallback(() => {
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); setIsSubmitted(true);
filterModal.closeModal(); filterModal.closeModal();
}, [filterModal]); }
}, [
filterModal,
filterStartDate,
filterEndDate,
filterLocation,
filterProjectFlock,
filterKandang,
]);
const selectedRowIds = useMemo(() => { const selectedRowIds = useMemo(() => {
return Object.keys(rowSelection) return Object.keys(rowSelection)
@@ -1124,58 +1154,105 @@ const UniformityTable = () => {
</div> </div>
<div className='space-y-4 px-4'> <div className='space-y-4 px-4'>
<div className='grid grid-cols-1 sm:grid-cols-2 sm:gap-4'> <div className='grid grid-cols-1 sm:grid-cols-2 sm:gap-4'>
<div>
<DateInput <DateInput
label='Tanggal' label='Tanggal'
name='start_date' name='start_date'
value={filterStartDate} value={filterStartDate}
onChange={(e) => setFilterStartDate(e.target.value)} onChange={(e) => {
setFilterStartDate(e.target.value);
setFilterErrors((prev) => ({ ...prev, start_date: '' }));
}}
className={{ wrapper: 'w-full' }} className={{ wrapper: 'w-full' }}
/> />
{filterErrors.start_date && (
<p className='text-red-500 text-sm mt-1'>
{filterErrors.start_date}
</p>
)}
</div>
<div>
<DateInput <DateInput
label=' ' label=' '
name='end_date' name='end_date'
value={filterEndDate} value={filterEndDate}
onChange={(e) => setFilterEndDate(e.target.value)} onChange={(e) => {
setFilterEndDate(e.target.value);
setFilterErrors((prev) => ({ ...prev, end_date: '' }));
}}
className={{ wrapper: 'w-full' }} className={{ wrapper: 'w-full' }}
/> />
{filterErrors.end_date && (
<p className='text-red-500 text-sm mt-1'>
{filterErrors.end_date}
</p>
)}
</div>
</div> </div>
<div>
<SelectInput <SelectInput
label='Lokasi' label='Lokasi'
placeholder='Pilih Lokasi...' placeholder='Pilih Lokasi...'
value={filterLocation} value={filterLocation}
onChange={handleFilterLocationChange} onChange={(value) => {
handleFilterLocationChange(value);
setFilterErrors((prev) => ({ ...prev, location: '' }));
}}
options={filterLocationOptions} options={filterLocationOptions}
onInputChange={setFilterLocationInputValue} onInputChange={setFilterLocationInputValue}
isLoading={isLoadingFilterLocations} isLoading={isLoadingFilterLocations}
isClearable
className={{ wrapper: 'w-full' }} className={{ wrapper: 'w-full' }}
/> />
{filterErrors.location && (
<p className='text-red-500 text-sm mt-1'>
{filterErrors.location}
</p>
)}
</div>
<div>
<SelectInput <SelectInput
label='Project Flock' label='Project Flock'
placeholder='Pilih Project Flock...' placeholder='Pilih Project Flock...'
value={filterProjectFlock} value={filterProjectFlock}
onChange={handleFilterProjectFlockChange} onChange={(value) => {
handleFilterProjectFlockChange(value);
setFilterErrors((prev) => ({ ...prev, project_flock: '' }));
}}
options={filterProjectFlockOptions} options={filterProjectFlockOptions}
onInputChange={setProjectFlockSearchValue} onInputChange={setProjectFlockSearchValue}
isLoading={isLoadingFilterProjectFlocks} isLoading={isLoadingFilterProjectFlocks}
isDisabled={!filterLocation} isDisabled={!filterLocation}
isClearable
className={{ wrapper: 'w-full' }} className={{ wrapper: 'w-full' }}
/> />
{filterErrors.project_flock && (
<p className='text-red-500 text-sm mt-1'>
{filterErrors.project_flock}
</p>
)}
</div>
<div>
<SelectInput <SelectInput
label='Kandang' label='Kandang'
placeholder='Pilih Kandang...' placeholder='Pilih Kandang...'
value={filterKandang} value={filterKandang}
onChange={handleFilterKandangChange} onChange={(value) => {
handleFilterKandangChange(value);
setFilterErrors((prev) => ({ ...prev, kandang: '' }));
}}
options={filterKandangOptions} options={filterKandangOptions}
isDisabled={!filterProjectFlock} isDisabled={!filterProjectFlock}
isClearable
className={{ wrapper: 'w-full' }} className={{ wrapper: 'w-full' }}
/> />
{filterErrors.kandang && (
<p className='text-red-500 text-sm mt-1'>
{filterErrors.kandang}
</p>
)}
</div>
</div> </div>
{/* Action Buttons */} {/* Action Buttons */}