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 [selectedSortBy, setSelectedSortBy] = useState<OptionType | null>(null);
const [selectedFinance, setSelectedFinance] = useState<Finance | null>(null); const [selectedFinance, setSelectedFinance] = useState<Finance | null>(null);
const [isDeleteLoading, setIsDeleteLoading] = useState(false); const [isDeleteLoading, setIsDeleteLoading] = useState(false);
const [dateErrorShown, setDateErrorShown] = useState(false);
// ===== Formik for Filter ===== // ===== Formik for Filter =====
const filterFormik = useFormik<FinanceTableFilterValues>({ const filterFormik = useFormik<FinanceTableFilterValues>({
@@ -323,6 +324,70 @@ const FinanceTable = () => {
val ? ((val as OptionType).value as string) : '' 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 = () => { const resetFilterHandler = () => {
setSelectedTransactionType(null); setSelectedTransactionType(null);
setSelectedBank(null); setSelectedBank(null);
@@ -461,6 +526,14 @@ const FinanceTable = () => {
]; ];
}, []); }, []);
useEffect(() => {
return () => {
if (dateErrorShown) {
toast.dismiss();
}
};
}, [dateErrorShown]);
useEffect(() => { useEffect(() => {
previousPathRef.current = window.location.pathname; previousPathRef.current = window.location.pathname;
@@ -474,8 +547,13 @@ const FinanceTable = () => {
if (isPreviousPathFinance && !isCurrentPathFinance) { if (isPreviousPathFinance && !isCurrentPathFinance) {
resetSearchValue(); resetSearchValue();
} }
if (dateErrorShown) {
toast.dismiss();
setDateErrorShown(false);
}
}; };
}, [resetSearchValue]); }, [resetSearchValue, dateErrorShown]);
return ( return (
<section className='size-full flex flex-col gap-6'> <section className='size-full flex flex-col gap-6'>
@@ -584,25 +662,23 @@ const FinanceTable = () => {
name='start_date' name='start_date'
label='Periode Tanggal (Mulai)' label='Periode Tanggal (Mulai)'
value={filterFormik.values.start_date} value={filterFormik.values.start_date}
onChange={filterFormik.handleChange} onChange={startDateChangeHandler}
errorMessage={ errorMessage={
filterFormik.touched.start_date && filterFormik.errors.start_date filterFormik.errors.end_date
? filterFormik.errors.start_date ? filterFormik.errors.end_date
: undefined : undefined
} }
onBlur={filterFormik.handleBlur}
/> />
<DateInput <DateInput
name='end_date' name='end_date'
label='Periode Tanggal (Akhir)' label='Periode Tanggal (Akhir)'
value={filterFormik.values.end_date} value={filterFormik.values.end_date}
onChange={filterFormik.handleChange} onChange={endDateChangeHandler}
errorMessage={ errorMessage={
filterFormik.touched.end_date && filterFormik.errors.end_date filterFormik.errors.end_date
? filterFormik.errors.end_date ? filterFormik.errors.end_date
: undefined : undefined
} }
onBlur={filterFormik.handleBlur}
/> />
<DebouncedTextInput <DebouncedTextInput
name='search' name='search'