From a4e5116beff006994191e439887a76b08e28369f Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Thu, 21 May 2026 14:44:07 +0700 Subject: [PATCH] feat: add start_date, end_date, and filter_by input --- .../pages/purchase/PurchaseFilterModal.tsx | 116 +++++++++++++++++- 1 file changed, 115 insertions(+), 1 deletion(-) diff --git a/src/components/pages/purchase/PurchaseFilterModal.tsx b/src/components/pages/purchase/PurchaseFilterModal.tsx index 856f2074..55db1aea 100644 --- a/src/components/pages/purchase/PurchaseFilterModal.tsx +++ b/src/components/pages/purchase/PurchaseFilterModal.tsx @@ -10,6 +10,7 @@ import Button from '@/components/Button'; import DateInput from '@/components/input/DateInput'; import SelectInputCheckbox from '@/components/input/SelectInputCheckbox'; import SelectInput from '@/components/input/SelectInput'; +import SelectInputRadio from '@/components/input/SelectInputRadio'; import { OptionType, useSelect } from '@/components/input/SelectInput'; import { PurchaseFilter } from '@/types/api/purchase/purchase'; @@ -24,10 +25,20 @@ import { ProjectFlockApi } from '@/services/api/production'; import { ProjectFlock } from '@/types/api/production/project-flock'; import { isResponseSuccess } from '@/lib/api-helper'; +const filterByOptions: OptionType[] = [ + { value: 'po_date', label: 'Tanggal PO' }, + { value: 'received_date', label: 'Tanggal Terima' }, + { value: 'due_date', label: 'Tanggal Jatuh Tempo' }, + { value: 'created_at', label: 'Tanggal Dibuat' }, +]; + interface PurchaseFilterModalProps { ref: RefObject; initialValues?: { poDate: string; + start_date: string; + end_date: string; + filterBy: OptionType | undefined; category: OptionType[]; status: OptionType[]; supplier: OptionType | null; @@ -51,6 +62,7 @@ const PurchaseFilterModal = ({ }, [ref]); // ===== DATE ERROR STATE ===== + const [hasDateError, setHasDateError] = useState(false); const [dateErrorShown, setDateErrorShown] = useState(false); // ===== CLEANUP TOAST ON UNMOUNT ===== @@ -139,6 +151,9 @@ const PurchaseFilterModal = ({ const formik = useFormik<{ poDate: string; + start_date: string; + end_date: string; + filterBy: OptionType | undefined; category: { label: string; value: number }[]; status: { label: string; value: string }[]; supplier: OptionType | null; @@ -150,6 +165,9 @@ const PurchaseFilterModal = ({ // enableReinitialize: true, initialValues: initialValues || { poDate: '', + start_date: '', + end_date: '', + filterBy: undefined, category: [], status: [], supplier: null, @@ -230,9 +248,17 @@ const PurchaseFilterModal = ({ }; const formikResetHandler = useCallback(() => { + setHasDateError(false); + if (dateErrorShown) { + toast.dismiss(); + setDateErrorShown(false); + } resetForm({ values: { poDate: '', + start_date: '', + end_date: '', + filterBy: undefined, category: [], status: [], supplier: null, @@ -246,7 +272,56 @@ const PurchaseFilterModal = ({ setSelectedLocationId(''); onReset?.(); closeModalHandler(); - }, [resetForm, onReset, closeModalHandler]); + }, [resetForm, onReset, closeModalHandler, dateErrorShown]); + + const handleStartDateChange = (e: React.ChangeEvent) => { + const value = e.target.value; + formik.setFieldValue('start_date', value); + + if (value && formik.values.end_date) { + if (new Date(formik.values.end_date) < new Date(value)) { + setHasDateError(true); + if (!dateErrorShown) { + toast.error('Tanggal akhir tidak boleh sebelum tanggal mulai', { + duration: Infinity, + }); + setDateErrorShown(true); + } + } else { + setHasDateError(false); + if (dateErrorShown) { + toast.dismiss(); + setDateErrorShown(false); + } + } + } else { + setHasDateError(false); + } + }; + + const handleEndDateChange = (e: React.ChangeEvent) => { + const value = e.target.value; + formik.setFieldValue('end_date', value); + + if (value && formik.values.start_date) { + if (new Date(value) < new Date(formik.values.start_date)) { + setHasDateError(true); + if (!dateErrorShown) { + toast.error('Tanggal akhir tidak boleh sebelum tanggal mulai', { + duration: Infinity, + }); + setDateErrorShown(true); + } + return; + } + } + + setHasDateError(false); + if (dateErrorShown) { + toast.dismiss(); + setDateErrorShown(false); + } + }; const formikSubmitHandler = useCallback(async () => { await submitForm(); @@ -287,6 +362,44 @@ const PurchaseFilterModal = ({ {/* Modal Body */}
+
+ +
+ +
+ +
+
+ + + formik.setFieldValue( + 'filterBy', + !Array.isArray(val) ? (val ?? undefined) : undefined + ) + } + isClearable + /> + Apply Filter