mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-24 07:15:44 +00:00
refactor(FE): Refactor date validation to use shared state and cleanup
This commit is contained in:
@@ -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'
|
||||
|
||||
@@ -250,6 +250,10 @@ const UniformityTable = () => {
|
||||
useState<string>('');
|
||||
const [, setFilterErrors] = useState<Record<string, string>>({});
|
||||
|
||||
// ===== DATE ERROR STATE =====
|
||||
const [dateErrorShown, setDateErrorShown] = useState(false);
|
||||
const [hasDateError, setHasDateError] = useState(false);
|
||||
|
||||
const {
|
||||
setInputValue: setFilterLocationInputValue,
|
||||
options: filterLocationOptions,
|
||||
@@ -792,6 +796,23 @@ const UniformityTable = () => {
|
||||
}
|
||||
}, [uniformities, rowSelection]);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (dateErrorShown) {
|
||||
toast.dismiss();
|
||||
}
|
||||
};
|
||||
}, [dateErrorShown]);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (dateErrorShown) {
|
||||
toast.dismiss();
|
||||
setDateErrorShown(false);
|
||||
}
|
||||
};
|
||||
}, [filterModal.open, dateErrorShown]);
|
||||
|
||||
// ===== TABLE COLUMNS DEFINITION =====
|
||||
const uniformityColumns: ColumnDef<Uniformity>[] = useMemo(
|
||||
() => [
|
||||
@@ -1245,9 +1266,38 @@ const UniformityTable = () => {
|
||||
placeholder='Tanggal Mulai'
|
||||
value={filterFormik.values.start_date}
|
||||
errorMessage={filterFormik.errors.start_date}
|
||||
onChange={(e) =>
|
||||
filterFormik.setFieldValue('start_date', e.target.value)
|
||||
}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value;
|
||||
filterFormik.setFieldValue('start_date', value);
|
||||
|
||||
if (value && filterFormik.values.end_date) {
|
||||
const startDate = new Date(value);
|
||||
const endDateObj = new Date(
|
||||
filterFormik.values.end_date
|
||||
);
|
||||
|
||||
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);
|
||||
}
|
||||
}}
|
||||
isError={
|
||||
filterFormik.touched.start_date &&
|
||||
Boolean(filterFormik.errors.start_date)
|
||||
@@ -1259,13 +1309,38 @@ const UniformityTable = () => {
|
||||
placeholder='Tanggal Akhir'
|
||||
value={filterFormik.values.end_date}
|
||||
errorMessage={filterFormik.errors.end_date}
|
||||
onChange={(e) =>
|
||||
filterFormik.setFieldValue('end_date', e.target.value)
|
||||
}
|
||||
isError={
|
||||
filterFormik.touched.end_date &&
|
||||
Boolean(filterFormik.errors.end_date)
|
||||
}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value;
|
||||
filterFormik.setFieldValue('end_date', value);
|
||||
|
||||
if (value && filterFormik.values.start_date) {
|
||||
const startDateObj = new Date(
|
||||
filterFormik.values.start_date
|
||||
);
|
||||
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);
|
||||
}
|
||||
}}
|
||||
isError={hasDateError}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user