feat: add more filters

This commit is contained in:
Adnan Zahir
2026-04-25 12:15:42 +07:00
parent 2dfac0be72
commit c875ebd951
17 changed files with 633 additions and 172 deletions
@@ -172,6 +172,9 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => {
kandang_id: '',
category: '',
period: '',
area_name: '',
location_name: '',
kandang_name: '',
},
paramMap: {
page: 'page',
@@ -183,7 +186,7 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => {
category: 'category',
period: 'period',
},
excludeKeysFromUrl: ['area_name', 'location_name', 'kandang_name'],
persist: true,
storeName: 'project-flock-table',
});
@@ -259,6 +262,9 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => {
updateFilter('kandang_id', values.kandang_id || '');
updateFilter('category', values.category || '');
updateFilter('period', values.period || '');
updateFilter('area_name', areaValue?.label ? String(areaValue.label) : '');
updateFilter('location_name', locationValue?.label ? String(locationValue.label) : '');
updateFilter('kandang_name', kandangValue?.label ? String(kandangValue.label) : '');
filterModal.closeModal();
setSubmitting(false);
},
@@ -268,6 +274,9 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => {
updateFilter('kandang_id', '');
updateFilter('category', '');
updateFilter('period', '');
updateFilter('area_name', '');
updateFilter('location_name', '');
updateFilter('kandang_name', '');
setFilterAreaId(undefined);
setFilterLocationId(undefined);
filterModal.closeModal();
@@ -320,29 +329,37 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => {
// ===== FILTER HELPERS =====
const areaValue = useMemo(() => {
if (!formik.values.area_id) return null;
return (
areaOptions.find((opt) => String(opt.value) === formik.values.area_id) ||
null
);
}, [formik.values.area_id, areaOptions]);
const found = areaOptions.find((opt) => String(opt.value) === formik.values.area_id);
if (found) return found;
if (tableFilterState.area_name) {
return { value: formik.values.area_id, label: tableFilterState.area_name };
}
return null;
}, [formik.values.area_id, areaOptions, tableFilterState.area_name]);
const locationValue = useMemo(() => {
if (!formik.values.location_id) return null;
return (
locationOptions.find(
(opt) => String(opt.value) === formik.values.location_id
) || null
const found = locationOptions.find(
(opt) => String(opt.value) === formik.values.location_id
);
}, [formik.values.location_id, locationOptions]);
if (found) return found;
if (tableFilterState.location_name) {
return { value: formik.values.location_id, label: tableFilterState.location_name };
}
return null;
}, [formik.values.location_id, locationOptions, tableFilterState.location_name]);
const kandangValue = useMemo(() => {
if (!formik.values.kandang_id) return null;
return (
kandangOptions.find(
(opt) => String(opt.value) === formik.values.kandang_id
) || null
const found = kandangOptions.find(
(opt) => String(opt.value) === formik.values.kandang_id
);
}, [formik.values.kandang_id, kandangOptions]);
if (found) return found;
if (tableFilterState.kandang_name) {
return { value: formik.values.kandang_id, label: tableFilterState.kandang_name };
}
return null;
}, [formik.values.kandang_id, kandangOptions, tableFilterState.kandang_name]);
const categoryValue = useMemo(() => {
if (!formik.values.category) return null;
@@ -967,7 +984,7 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => {
<ButtonFilter
values={tableFilterState}
excludeFields={['page', 'pageSize', 'search']}
excludeFields={['page', 'pageSize', 'search', 'area_name', 'location_name', 'kandang_name']}
onClick={handleFilterModalOpen}
className='px-3 py-2.5'
/>
@@ -13,7 +13,6 @@ import SelectInputCheckbox from '@/components/input/SelectInputCheckbox';
import { OptionType, useSelect } from '@/components/input/SelectInput';
import { ProjectFlockApi } from '@/services/api/production';
import { Flock } from '@/types/api/master-data/flock';
import { TransferToLayingFilter } from '@/types/api/production/transfer-to-laying';
import {
TransferToLayingFilterSchema,
TransferToLayingFilterValues,
@@ -21,12 +20,14 @@ import {
interface TransferToLayingFilterModal {
ref: RefObject<HTMLDialogElement | null>;
onSubmit?: (values: TransferToLayingFilter) => void;
initialValues?: Partial<TransferToLayingFilterValues>;
onSubmit?: (values: TransferToLayingFilterValues) => void;
onReset?: () => void;
}
const TransferToLayingFilterModal = ({
ref,
initialValues: initialValuesProp,
onSubmit,
onReset,
}: TransferToLayingFilterModal) => {
@@ -86,28 +87,16 @@ const TransferToLayingFilterModal = ({
const formik = useFormik<TransferToLayingFilterValues>({
initialValues: {
startDate: '',
endDate: '',
flockSource: [],
flockDestination: [],
status: [],
startDate: initialValuesProp?.startDate ?? '',
endDate: initialValuesProp?.endDate ?? '',
flockSource: initialValuesProp?.flockSource ?? [],
flockDestination: initialValuesProp?.flockDestination ?? [],
status: initialValuesProp?.status ?? [],
},
enableReinitialize: true,
validationSchema: TransferToLayingFilterSchema,
onSubmit: async (values) => {
const formattedValues = {
...values,
flockSource: values.flockSource
? (values.flockSource as OptionType[]).map((item) => item.value)
: [],
flockDestination: values.flockDestination
? (values.flockDestination as OptionType[]).map((item) => item.value)
: [],
status: values.status
? (values.status as OptionType[]).map((item) => item.value)
: [],
};
onSubmit?.(formattedValues as TransferToLayingFilter);
onSubmit?.(values);
closeModalHandler();
},
onReset: () => {
@@ -1,6 +1,6 @@
'use client';
import { ChangeEventHandler, useEffect, useState } from 'react';
import { ChangeEventHandler, useEffect, useMemo, useState } from 'react';
import { usePathname } from 'next/navigation';
import { useUiStore } from '@/stores/ui/ui.store';
import useSWR from 'swr';
@@ -26,10 +26,9 @@ import TransferToLayingFilterModal from '@/components/pages/production/transfer-
import TransferToLayingConfirmationModal from '@/components/pages/production/transfer-to-laying/TransferToLayingConfirmationModal';
import TransferToLayingTableSkeleton from '@/components/pages/production/transfer-to-laying/skeleton/TransferToLayingTableSkeleton';
import {
TransferToLaying,
TransferToLayingFilter,
} from '@/types/api/production/transfer-to-laying';
import { TransferToLaying } from '@/types/api/production/transfer-to-laying';
import { TransferToLayingFilterValues } from '@/components/pages/production/transfer-to-laying/filter/TransferToLayingFilter';
import { OptionType } from '@/components/input/SelectInput';
import { TransferToLayingApi } from '@/services/api/production/transfer-to-laying';
import { cn, formatDate, formatNumber } from '@/lib/helper';
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
@@ -142,6 +141,8 @@ const TransferToLayingsTable = () => {
status: '',
filter_by: '',
sort_by: '',
flockSourceNames: '',
flockDestinationNames: '',
},
paramMap: {
page: 'page',
@@ -154,6 +155,9 @@ const TransferToLayingsTable = () => {
filter_by: 'filter_by',
sort_by: 'sort_by',
},
excludeKeysFromUrl: ['flockSourceNames', 'flockDestinationNames'],
persist: true,
storeName: 'transfer-to-laying-table',
});
const {
@@ -431,12 +435,72 @@ const TransferToLayingsTable = () => {
updateFilter('search', e.target.value);
};
const filterSubmitHandler = (values: TransferToLayingFilter) => {
updateFilter('startDate', values.startDate);
updateFilter('endDate', values.endDate);
updateFilter('flockSource', values.flockSource.join(','));
updateFilter('flockDestination', values.flockDestination.join(','));
updateFilter('status', values.status.join(','));
const STATUS_FILTER_OPTIONS = [
{ value: 'PENDING', label: 'Pengajuan' },
{ value: 'APPROVED', label: 'Disetujui' },
{ value: 'REJECTED', label: 'Ditolak' },
];
const filterModalInitialValues = useMemo(() => {
const flockSourceIds = tableFilterState.flockSource
? tableFilterState.flockSource.split(',')
: [];
const flockSourceNameList = tableFilterState.flockSourceNames
? tableFilterState.flockSourceNames.split(',')
: [];
const flockSourceOptions = flockSourceIds.filter(Boolean).map((id, i) => ({
value: parseInt(id),
label: flockSourceNameList[i] || id,
}));
const flockDestIds = tableFilterState.flockDestination
? tableFilterState.flockDestination.split(',')
: [];
const flockDestNameList = tableFilterState.flockDestinationNames
? tableFilterState.flockDestinationNames.split(',')
: [];
const flockDestOptions = flockDestIds.filter(Boolean).map((id, i) => ({
value: parseInt(id),
label: flockDestNameList[i] || id,
}));
const statusIds = tableFilterState.status
? tableFilterState.status.split(',')
: [];
const statusOptions = statusIds.filter(Boolean).map((id) => {
const found = STATUS_FILTER_OPTIONS.find((opt) => opt.value === id);
return found || { value: id, label: id };
});
return {
startDate: tableFilterState.startDate || '',
endDate: tableFilterState.endDate || '',
flockSource: flockSourceOptions,
flockDestination: flockDestOptions,
status: statusOptions,
};
}, [
tableFilterState.startDate,
tableFilterState.endDate,
tableFilterState.flockSource,
tableFilterState.flockDestination,
tableFilterState.status,
tableFilterState.flockSourceNames,
tableFilterState.flockDestinationNames,
]);
const filterSubmitHandler = (values: TransferToLayingFilterValues) => {
const flockSourceOpts = (values.flockSource as OptionType[]) || [];
const flockDestOpts = (values.flockDestination as OptionType[]) || [];
const statusOpts = (values.status as OptionType[]) || [];
updateFilter('startDate', values.startDate || '');
updateFilter('endDate', values.endDate || '');
updateFilter('flockSource', flockSourceOpts.map((o) => String(o.value)).join(','));
updateFilter('flockDestination', flockDestOpts.map((o) => String(o.value)).join(','));
updateFilter('status', statusOpts.map((o) => String(o.value)).join(','));
updateFilter('flockSourceNames', flockSourceOpts.map((o) => String(o.label)).join(','));
updateFilter('flockDestinationNames', flockDestOpts.map((o) => String(o.label)).join(','));
};
const filterResetHandler = () => {
@@ -445,6 +509,8 @@ const TransferToLayingsTable = () => {
updateFilter('flockSource', '');
updateFilter('flockDestination', '');
updateFilter('status', '');
updateFilter('flockSourceNames', '');
updateFilter('flockDestinationNames', '');
};
const exportToExcelHandler = async () => {
@@ -558,6 +624,8 @@ const TransferToLayingsTable = () => {
'search',
'filter_by',
'sort_by',
'flockSourceNames',
'flockDestinationNames',
]}
fieldGroups={[['startDate', 'endDate']]}
onClick={filterModal.openModal}
@@ -670,6 +738,7 @@ const TransferToLayingsTable = () => {
<TransferToLayingFilterModal
ref={filterModal.ref}
initialValues={filterModalInitialValues}
onSubmit={filterSubmitHandler}
onReset={filterResetHandler}
/>