From 372b439ff01cdc542f861da5c0ba52bc9a413d2d Mon Sep 17 00:00:00 2001 From: rstubryan Date: Thu, 5 Feb 2026 11:13:53 +0700 Subject: [PATCH] refactor(FE): Validate date range and show persistent toast --- src/components/pages/finance/FinanceTable.tsx | 92 +++++++++++++++++-- 1 file changed, 84 insertions(+), 8 deletions(-) diff --git a/src/components/pages/finance/FinanceTable.tsx b/src/components/pages/finance/FinanceTable.tsx index 40091237..6f422753 100644 --- a/src/components/pages/finance/FinanceTable.tsx +++ b/src/components/pages/finance/FinanceTable.tsx @@ -189,6 +189,7 @@ const FinanceTable = () => { const [selectedSortBy, setSelectedSortBy] = useState(null); const [selectedFinance, setSelectedFinance] = useState(null); const [isDeleteLoading, setIsDeleteLoading] = useState(false); + const [dateErrorShown, setDateErrorShown] = useState(false); // ===== Formik for Filter ===== const filterFormik = useFormik({ @@ -323,6 +324,70 @@ const FinanceTable = () => { val ? ((val as OptionType).value as string) : '' ); }; + + const startDateChangeHandler = (e: React.ChangeEvent) => { + 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) => { + 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 (
@@ -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} />