mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-24 07:15:44 +00:00
feat: add start_date, end_date, and filter_by input
This commit is contained in:
@@ -10,6 +10,7 @@ import Button from '@/components/Button';
|
|||||||
import DateInput from '@/components/input/DateInput';
|
import DateInput from '@/components/input/DateInput';
|
||||||
import SelectInputCheckbox from '@/components/input/SelectInputCheckbox';
|
import SelectInputCheckbox from '@/components/input/SelectInputCheckbox';
|
||||||
import SelectInput from '@/components/input/SelectInput';
|
import SelectInput from '@/components/input/SelectInput';
|
||||||
|
import SelectInputRadio from '@/components/input/SelectInputRadio';
|
||||||
|
|
||||||
import { OptionType, useSelect } from '@/components/input/SelectInput';
|
import { OptionType, useSelect } from '@/components/input/SelectInput';
|
||||||
import { PurchaseFilter } from '@/types/api/purchase/purchase';
|
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 { ProjectFlock } from '@/types/api/production/project-flock';
|
||||||
import { isResponseSuccess } from '@/lib/api-helper';
|
import { isResponseSuccess } from '@/lib/api-helper';
|
||||||
|
|
||||||
|
const filterByOptions: OptionType<string>[] = [
|
||||||
|
{ 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 {
|
interface PurchaseFilterModalProps {
|
||||||
ref: RefObject<HTMLDialogElement | null>;
|
ref: RefObject<HTMLDialogElement | null>;
|
||||||
initialValues?: {
|
initialValues?: {
|
||||||
poDate: string;
|
poDate: string;
|
||||||
|
start_date: string;
|
||||||
|
end_date: string;
|
||||||
|
filterBy: OptionType<string> | undefined;
|
||||||
category: OptionType<number>[];
|
category: OptionType<number>[];
|
||||||
status: OptionType<string>[];
|
status: OptionType<string>[];
|
||||||
supplier: OptionType<number> | null;
|
supplier: OptionType<number> | null;
|
||||||
@@ -51,6 +62,7 @@ const PurchaseFilterModal = ({
|
|||||||
}, [ref]);
|
}, [ref]);
|
||||||
|
|
||||||
// ===== DATE ERROR STATE =====
|
// ===== DATE ERROR STATE =====
|
||||||
|
const [hasDateError, setHasDateError] = useState(false);
|
||||||
const [dateErrorShown, setDateErrorShown] = useState(false);
|
const [dateErrorShown, setDateErrorShown] = useState(false);
|
||||||
|
|
||||||
// ===== CLEANUP TOAST ON UNMOUNT =====
|
// ===== CLEANUP TOAST ON UNMOUNT =====
|
||||||
@@ -139,6 +151,9 @@ const PurchaseFilterModal = ({
|
|||||||
|
|
||||||
const formik = useFormik<{
|
const formik = useFormik<{
|
||||||
poDate: string;
|
poDate: string;
|
||||||
|
start_date: string;
|
||||||
|
end_date: string;
|
||||||
|
filterBy: OptionType<string> | undefined;
|
||||||
category: { label: string; value: number }[];
|
category: { label: string; value: number }[];
|
||||||
status: { label: string; value: string }[];
|
status: { label: string; value: string }[];
|
||||||
supplier: OptionType<number> | null;
|
supplier: OptionType<number> | null;
|
||||||
@@ -150,6 +165,9 @@ const PurchaseFilterModal = ({
|
|||||||
// enableReinitialize: true,
|
// enableReinitialize: true,
|
||||||
initialValues: initialValues || {
|
initialValues: initialValues || {
|
||||||
poDate: '',
|
poDate: '',
|
||||||
|
start_date: '',
|
||||||
|
end_date: '',
|
||||||
|
filterBy: undefined,
|
||||||
category: [],
|
category: [],
|
||||||
status: [],
|
status: [],
|
||||||
supplier: null,
|
supplier: null,
|
||||||
@@ -230,9 +248,17 @@ const PurchaseFilterModal = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const formikResetHandler = useCallback(() => {
|
const formikResetHandler = useCallback(() => {
|
||||||
|
setHasDateError(false);
|
||||||
|
if (dateErrorShown) {
|
||||||
|
toast.dismiss();
|
||||||
|
setDateErrorShown(false);
|
||||||
|
}
|
||||||
resetForm({
|
resetForm({
|
||||||
values: {
|
values: {
|
||||||
poDate: '',
|
poDate: '',
|
||||||
|
start_date: '',
|
||||||
|
end_date: '',
|
||||||
|
filterBy: undefined,
|
||||||
category: [],
|
category: [],
|
||||||
status: [],
|
status: [],
|
||||||
supplier: null,
|
supplier: null,
|
||||||
@@ -246,7 +272,56 @@ const PurchaseFilterModal = ({
|
|||||||
setSelectedLocationId('');
|
setSelectedLocationId('');
|
||||||
onReset?.();
|
onReset?.();
|
||||||
closeModalHandler();
|
closeModalHandler();
|
||||||
}, [resetForm, onReset, closeModalHandler]);
|
}, [resetForm, onReset, closeModalHandler, dateErrorShown]);
|
||||||
|
|
||||||
|
const handleStartDateChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
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<HTMLInputElement>) => {
|
||||||
|
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 () => {
|
const formikSubmitHandler = useCallback(async () => {
|
||||||
await submitForm();
|
await submitForm();
|
||||||
@@ -287,6 +362,44 @@ const PurchaseFilterModal = ({
|
|||||||
{/* Modal Body */}
|
{/* Modal Body */}
|
||||||
<div className='p-4 flex flex-col gap-1.5'>
|
<div className='p-4 flex flex-col gap-1.5'>
|
||||||
<div className='flex flex-col'>
|
<div className='flex flex-col'>
|
||||||
|
<div>
|
||||||
|
<label className='block text-xs font-semibold text-base-content py-2'>
|
||||||
|
Tanggal
|
||||||
|
</label>
|
||||||
|
<div className='flex flex-row gap-1.5 items-center justify-between'>
|
||||||
|
<DateInput
|
||||||
|
name='start_date'
|
||||||
|
value={formik.values.start_date}
|
||||||
|
onChange={handleStartDateChange}
|
||||||
|
className={{ wrapper: 'w-full' }}
|
||||||
|
isNestedModal
|
||||||
|
/>
|
||||||
|
<hr className='w-full max-w-3 h-px border-base-content/10' />
|
||||||
|
<DateInput
|
||||||
|
name='end_date'
|
||||||
|
value={formik.values.end_date}
|
||||||
|
onChange={handleEndDateChange}
|
||||||
|
className={{ wrapper: 'w-full' }}
|
||||||
|
isNestedModal
|
||||||
|
isError={hasDateError}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<SelectInputRadio
|
||||||
|
label='Filter Berdasarkan'
|
||||||
|
placeholder='Pilih Filter Berdasarkan'
|
||||||
|
options={filterByOptions}
|
||||||
|
value={formik.values.filterBy ?? null}
|
||||||
|
onChange={(val) =>
|
||||||
|
formik.setFieldValue(
|
||||||
|
'filterBy',
|
||||||
|
!Array.isArray(val) ? (val ?? undefined) : undefined
|
||||||
|
)
|
||||||
|
}
|
||||||
|
isClearable
|
||||||
|
/>
|
||||||
|
|
||||||
<DateInput
|
<DateInput
|
||||||
label='PO Date'
|
label='PO Date'
|
||||||
name='poDate'
|
name='poDate'
|
||||||
@@ -436,6 +549,7 @@ const PurchaseFilterModal = ({
|
|||||||
<Button
|
<Button
|
||||||
type='button'
|
type='button'
|
||||||
onClick={formikSubmitHandler}
|
onClick={formikSubmitHandler}
|
||||||
|
disabled={hasDateError}
|
||||||
className='p-3 rounded-lg w-fit sm:w-full max-w-40 text-base-100 text-sm'
|
className='p-3 rounded-lg w-fit sm:w-full max-w-40 text-base-100 text-sm'
|
||||||
>
|
>
|
||||||
Apply Filter
|
Apply Filter
|
||||||
|
|||||||
Reference in New Issue
Block a user