refactor(FE): Refactor date validation to use shared state and cleanup

This commit is contained in:
rstubryan
2026-02-25 15:56:12 +07:00
parent 0af7b172a0
commit a75d84556a
8 changed files with 371 additions and 56 deletions
@@ -1,7 +1,8 @@
'use client';
import { RefObject } from 'react';
import { RefObject, useState, useEffect } from 'react';
import { useFormik } from 'formik';
import toast from 'react-hot-toast';
import { Icon } from '@iconify/react';
import Modal from '@/components/Modal';
@@ -33,6 +34,36 @@ const TransferToLayingFilterModal = ({
ref.current?.close();
};
// ===== DATE ERROR STATE =====
const [dateErrorShown, setDateErrorShown] = useState(false);
const [hasDateError, setHasDateError] = useState(false);
// ===== CLEANUP TOAST ON UNMOUNT =====
useEffect(() => {
return () => {
if (dateErrorShown) {
toast.dismiss();
}
};
}, [dateErrorShown]);
// ===== CLEANUP TOAST WHEN MODAL CLOSES =====
useEffect(() => {
const dialogElement = ref.current;
const handleModalClose = () => {
if (dateErrorShown) {
toast.dismiss();
setDateErrorShown(false);
}
};
dialogElement?.addEventListener('close', handleModalClose);
return () => {
dialogElement?.removeEventListener('close', handleModalClose);
};
}, [ref, dateErrorShown]);
// Flock Source
const {
setInputValue: setFlockSourceInputValue,
@@ -138,24 +169,77 @@ const TransferToLayingFilterModal = ({
name='startDate'
placeholder='Tanggal Awal'
value={formik.values.startDate || ''}
onChange={formik.handleChange}
errorMessage={formik.errors.startDate}
onChange={(e) => {
const value = e.target.value;
formik.setFieldValue('startDate', value);
if (value && formik.values.endDate) {
const startDate = new Date(value);
const endDateObj = new Date(formik.values.endDate);
if (endDateObj < startDate) {
setHasDateError(true);
if (!dateErrorShown) {
toast.error('Tanggal akhir tidak boleh masa lampau', {
duration: Infinity,
});
setDateErrorShown(true);
}
} else {
setHasDateError(false);
if (dateErrorShown) {
toast.dismiss();
setDateErrorShown(false);
}
}
} else {
setHasDateError(false);
}
}}
onBlur={formik.handleBlur}
isError={
formik.touched.startDate && Boolean(formik.errors.startDate)
}
/>
<hr className='w-full max-w-3 h-px border-base-content/10' />
<DateInput
name='endDate'
placeholder='Tanggal Akhir'
value={formik.values.endDate || ''}
onChange={formik.handleChange}
errorMessage={formik.errors.endDate}
onChange={(e) => {
const value = e.target.value;
formik.setFieldValue('endDate', value);
if (value && formik.values.startDate) {
const startDateObj = new Date(formik.values.startDate);
const endDate = new Date(value);
if (endDate < startDateObj) {
setHasDateError(true);
if (!dateErrorShown) {
toast.error('Tanggal akhir tidak boleh masa lampau', {
duration: Infinity,
});
setDateErrorShown(true);
}
return;
}
}
setHasDateError(false);
if (dateErrorShown) {
toast.dismiss();
setDateErrorShown(false);
}
}}
onBlur={formik.handleBlur}
isError={formik.touched.endDate && !!formik.errors.endDate}
isError={
(formik.touched.endDate && Boolean(formik.errors.endDate)) || hasDateError
}
/>
</div>
{formik.touched.endDate && formik.errors.endDate && (
<span className='text-xs text-error mt-1'>
{formik.errors.endDate}
</span>
)}
<SelectInputCheckbox
label='Flock Asal'