refactor(FE): Validate date range and show persistent toast

This commit is contained in:
rstubryan
2026-02-05 11:13:53 +07:00
parent 4aa9d54b1e
commit 372b439ff0
+84 -8
View File
@@ -189,6 +189,7 @@ const FinanceTable = () => {
const [selectedSortBy, setSelectedSortBy] = useState<OptionType | null>(null);
const [selectedFinance, setSelectedFinance] = useState<Finance | null>(null);
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
const [dateErrorShown, setDateErrorShown] = useState(false);
// ===== Formik for Filter =====
const filterFormik = useFormik<FinanceTableFilterValues>({
@@ -323,6 +324,70 @@ const FinanceTable = () => {
val ? ((val as OptionType).value as string) : ''
);
};
const startDateChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value;
const endDate = filterFormik.values.end_date;
filterFormik.setFieldValue('start_date', value);
if (value && endDate) {
const startDate = new Date(value);
const endDateObj = new Date(endDate);
if (endDateObj < startDate) {
filterFormik.setFieldError(
'end_date',
'Tanggal akhir tidak boleh masa lampau'
);
if (!dateErrorShown) {
toast.error('Tanggal akhir tidak boleh masa lampau', {
duration: Infinity,
});
setDateErrorShown(true);
}
} else {
filterFormik.setFieldError('end_date', undefined);
if (dateErrorShown) {
toast.dismiss();
setDateErrorShown(false);
}
}
}
};
const endDateChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value;
const startDate = filterFormik.values.start_date;
filterFormik.setFieldValue('end_date', value);
if (value && startDate) {
const startDateObj = new Date(startDate);
const endDate = new Date(value);
if (endDate < startDateObj) {
filterFormik.setFieldError(
'end_date',
'Tanggal akhir tidak boleh masa lampau'
);
if (!dateErrorShown) {
toast.error('Tanggal akhir tidak boleh masa lampau', {
duration: Infinity,
});
setDateErrorShown(true);
}
return;
}
}
filterFormik.setFieldError('end_date', undefined);
if (dateErrorShown) {
toast.dismiss();
setDateErrorShown(false);
}
};
const resetFilterHandler = () => {
setSelectedTransactionType(null);
setSelectedBank(null);
@@ -461,6 +526,14 @@ const FinanceTable = () => {
];
}, []);
useEffect(() => {
return () => {
if (dateErrorShown) {
toast.dismiss();
}
};
}, [dateErrorShown]);
useEffect(() => {
previousPathRef.current = window.location.pathname;
@@ -474,8 +547,13 @@ const FinanceTable = () => {
if (isPreviousPathFinance && !isCurrentPathFinance) {
resetSearchValue();
}
if (dateErrorShown) {
toast.dismiss();
setDateErrorShown(false);
}
};
}, [resetSearchValue]);
}, [resetSearchValue, dateErrorShown]);
return (
<section className='size-full flex flex-col gap-6'>
@@ -584,25 +662,23 @@ const FinanceTable = () => {
name='start_date'
label='Periode Tanggal (Mulai)'
value={filterFormik.values.start_date}
onChange={filterFormik.handleChange}
onChange={startDateChangeHandler}
errorMessage={
filterFormik.touched.start_date && filterFormik.errors.start_date
? filterFormik.errors.start_date
filterFormik.errors.end_date
? filterFormik.errors.end_date
: undefined
}
onBlur={filterFormik.handleBlur}
/>
<DateInput
name='end_date'
label='Periode Tanggal (Akhir)'
value={filterFormik.values.end_date}
onChange={filterFormik.handleChange}
onChange={endDateChangeHandler}
errorMessage={
filterFormik.touched.end_date && filterFormik.errors.end_date
filterFormik.errors.end_date
? filterFormik.errors.end_date
: undefined
}
onBlur={filterFormik.handleBlur}
/>
<DebouncedTextInput
name='search'