fix: implement table persist state in recording filter

This commit is contained in:
ValdiANS
2026-05-05 16:10:57 +07:00
parent 35001ff422
commit 79e41d8a6f
2 changed files with 184 additions and 289 deletions
@@ -1,13 +1,6 @@
'use client'; 'use client';
import axios from 'axios'; import React, { useCallback, useState, useMemo, useEffect } from 'react';
import React, {
useCallback,
useState,
useMemo,
useEffect,
useRef,
} from 'react';
import useSWR from 'swr'; import useSWR from 'swr';
import { Icon } from '@iconify/react'; import { Icon } from '@iconify/react';
import { SortingState, CellContext, ColumnDef } from '@tanstack/react-table'; import { SortingState, CellContext, ColumnDef } from '@tanstack/react-table';
@@ -46,8 +39,6 @@ import { useTableFilter } from '@/services/hooks/useTableFilter';
import toast from 'react-hot-toast'; import toast from 'react-hot-toast';
import StatusBadge from '@/components/helper/StatusBadge'; import StatusBadge from '@/components/helper/StatusBadge';
import CheckboxInput from '@/components/input/CheckboxInput'; import CheckboxInput from '@/components/input/CheckboxInput';
import { useUiStore } from '@/stores/ui/ui.store';
import { usePathname } from 'next/navigation';
import { Color } from '@/types/theme'; import { Color } from '@/types/theme';
import ButtonFilter from '@/components/helper/ButtonFilter'; import ButtonFilter from '@/components/helper/ButtonFilter';
import Dropdown from '@/components/Dropdown'; import Dropdown from '@/components/Dropdown';
@@ -77,6 +68,26 @@ const getStatusBadgeColor = (status: string): Color => {
return statusBadgeColorMap[normalizedStatus] || 'neutral'; return statusBadgeColorMap[normalizedStatus] || 'neutral';
}; };
const isRecordingApproved = (recording: Recording): boolean => {
return (
recording.approval?.action === 'APPROVED' &&
recording.approval?.step_name === 'Disetujui'
);
};
// ===== FILTER HELPERS =====
const recordingApprovalStatusOptions: OptionType<string>[] = [
{ value: 'CREATED', label: 'Pengajuan' },
{ value: 'UPDATED', label: 'Diperbarui' },
{ value: 'APPROVED', label: 'Disetujui' },
{ value: 'REJECTED', label: 'Ditolak' },
];
const projectFlockCategoryOptions: OptionType<string>[] = [
{ value: 'GROWING', label: 'Growing' },
{ value: 'LAYING', label: 'Laying' },
];
const RowOptionsMenu = ({ const RowOptionsMenu = ({
popoverPosition = 'bottom', popoverPosition = 'bottom',
props, props,
@@ -268,25 +279,31 @@ const RowOptionsMenu = ({
}; };
const RecordingTable = () => { const RecordingTable = () => {
const { searchValue, setSearchValue, setTableState } = useUiStore();
const pathname = usePathname();
const { const {
state: tableFilterState, state: tableFilterState,
updateFilter, updateFilter,
setPage, setPage,
setPageSize, setPageSize,
toQueryString: getTableFilterQueryString, toQueryString: getTableFilterQueryString,
} = useTableFilter({ } = useTableFilter<{
search: string;
areaFilter: OptionType<number> | null;
locationFilter: OptionType<number> | null;
projectFlockFilter: OptionType<number> | null;
kandangFilter: OptionType<number> | null;
projectFlockKandangFilter: number | null;
approvalStatusFilter: OptionType<string> | null;
projectFlockCategoryFilter: OptionType<string> | null;
}>({
initial: { initial: {
search: '', search: '',
areaFilter: '', areaFilter: null,
locationFilter: '', locationFilter: null,
projectFlockFilter: '', projectFlockFilter: null,
kandangFilter: '', kandangFilter: null,
projectFlockKandangFilter: '', projectFlockKandangFilter: null,
approvalStatusFilter: '', approvalStatusFilter: null,
projectFlockCategoryFilter: '', projectFlockCategoryFilter: null,
}, },
paramMap: { paramMap: {
page: 'page', page: 'page',
@@ -300,68 +317,73 @@ const RecordingTable = () => {
approvalStatusFilter: 'approval_status', approvalStatusFilter: 'approval_status',
projectFlockCategoryFilter: 'project_flock_category', projectFlockCategoryFilter: 'project_flock_category',
}, },
});
useEffect(() => { persist: true,
updateFilter('search', searchValue); storeName: 'recording-table',
}, [searchValue, updateFilter]); });
// ===== FILTER MODAL STATE ===== // ===== FILTER MODAL STATE =====
const filterModal = useModal(); const filterModal = useModal();
// ===== FILTER STATE =====
const [filterArea, setFilterArea] = useState<OptionType | null>(null);
const [filterLocation, setFilterLocation] = useState<OptionType | null>(null);
const [filterProjectFlock, setFilterProjectFlock] =
useState<OptionType | null>(null);
const [filterKandang, setFilterKandang] = useState<OptionType | null>(null);
const [, setFilterProjectFlockKandangId] = useState<number | undefined>(
undefined
);
const [filterLocationAreaId, setFilterLocationAreaId] = useState<string>('');
const [filterProjectFlockLocationId, setFilterProjectFlockLocationId] =
useState<string>('');
// ===== FORMIK SETUP ===== // ===== FORMIK SETUP =====
const formik = useFormik<RecordingFilterType>({ const formik = useFormik<RecordingFilterType>({
initialValues: { initialValues: {
area_id: null, area_id: tableFilterState.areaFilter,
location_id: null, location_id: tableFilterState.locationFilter,
project_flock_id: null, project_flock_id: tableFilterState.projectFlockFilter,
kandang_id: null, kandang_id: tableFilterState.kandangFilter,
project_flock_kandang_id: null, project_flock_kandang_id: tableFilterState.projectFlockKandangFilter,
approval_status: null, approval_status: tableFilterState.approvalStatusFilter,
project_flock_category: null, project_flock_category: tableFilterState.projectFlockCategoryFilter,
}, },
validationSchema: RecordingFilterSchema, validationSchema: RecordingFilterSchema,
onSubmit: (values, { setSubmitting }) => { onSubmit: (values, { setSubmitting }) => {
updateFilter('areaFilter', values.area_id || ''); updateFilter('areaFilter', values.area_id, true);
updateFilter('locationFilter', values.location_id || ''); updateFilter('locationFilter', values.location_id, true);
updateFilter('projectFlockFilter', values.project_flock_id || ''); updateFilter('projectFlockFilter', values.project_flock_id, true);
updateFilter('kandangFilter', values.kandang_id || ''); updateFilter('kandangFilter', values.kandang_id, true);
updateFilter( updateFilter(
'projectFlockKandangFilter', 'projectFlockKandangFilter',
values.project_flock_kandang_id || '' values.project_flock_kandang_id,
true
); );
updateFilter('approvalStatusFilter', values.approval_status || ''); updateFilter('approvalStatusFilter', values.approval_status, true);
updateFilter( updateFilter(
'projectFlockCategoryFilter', 'projectFlockCategoryFilter',
values.project_flock_category || '' values.project_flock_category,
true
); );
filterModal.closeModal(); filterModal.closeModal();
setSubmitting(false); setSubmitting(false);
}, },
onReset: () => {
updateFilter('areaFilter', '');
updateFilter('locationFilter', '');
updateFilter('projectFlockFilter', '');
updateFilter('kandangFilter', '');
updateFilter('projectFlockKandangFilter', '');
updateFilter('approvalStatusFilter', '');
updateFilter('projectFlockCategoryFilter', '');
},
}); });
const formikResetHandler = () => {
updateFilter('areaFilter', null, true);
updateFilter('locationFilter', null, true);
updateFilter('projectFlockFilter', null, true);
updateFilter('kandangFilter', null, true);
updateFilter('projectFlockKandangFilter', null, true);
updateFilter('approvalStatusFilter', null, true);
updateFilter('projectFlockCategoryFilter', null, true);
formik.resetForm({
values: {
area_id: null,
location_id: null,
project_flock_id: null,
kandang_id: null,
project_flock_kandang_id: null,
approval_status: null,
project_flock_category: null,
},
});
filterModal.closeModal();
};
const { project_flock_id, kandang_id } = formik.values;
const [sorting, setSorting] = useState<SortingState>([]); const [sorting, setSorting] = useState<SortingState>([]);
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({}); const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
const selectedRowIds = Object.keys(rowSelection).map((item) => const selectedRowIds = Object.keys(rowSelection).map((item) =>
@@ -396,13 +418,6 @@ const RecordingTable = () => {
); );
// ===== LOCATION, AREA, KANDANG OPTIONS ===== // ===== LOCATION, AREA, KANDANG OPTIONS =====
const locationParams = useMemo(() => {
if (filterLocationAreaId) {
return { area_id: filterLocationAreaId };
}
return undefined;
}, [filterLocationAreaId]);
const { const {
setInputValue: setLocationInputValue, setInputValue: setLocationInputValue,
options: locationOptions, options: locationOptions,
@@ -413,7 +428,9 @@ const RecordingTable = () => {
'id', 'id',
'name', 'name',
'search', 'search',
locationParams {
area_id: String(formik.values.area_id?.value),
}
); );
const { const {
@@ -428,13 +445,6 @@ const RecordingTable = () => {
'search' 'search'
); );
const projectFlockParams = useMemo(() => {
if (filterProjectFlockLocationId) {
return { location_id: filterProjectFlockLocationId };
}
return undefined;
}, [filterProjectFlockLocationId]);
const { const {
setInputValue: setProjectFlockInputValue, setInputValue: setProjectFlockInputValue,
options: projectFlockOptions, options: projectFlockOptions,
@@ -446,34 +456,41 @@ const RecordingTable = () => {
'id', 'id',
'flock_name', 'flock_name',
'search', 'search',
projectFlockParams {
location_id: String(formik.values.location_id?.value),
}
); );
const kandangOptions = useMemo(() => { const kandangOptions = useMemo(() => {
if (!filterProjectFlock || !projectFlocksRawData) return []; if (!project_flock_id || !projectFlocksRawData) return [];
if (!isResponseSuccess(projectFlocksRawData)) return []; if (!isResponseSuccess(projectFlocksRawData)) return [];
const data = projectFlocksRawData.data as ProjectFlock[]; const data = projectFlocksRawData.data as ProjectFlock[];
const selectedProjectFlockData = data.find( const selectedProjectFlockData = data.find((pf) =>
(pf) => pf.id === filterProjectFlock.value pf.id === formik.values.project_flock_id?.value
? Number(formik.values.project_flock_id.value)
: 0
); );
if (!selectedProjectFlockData?.kandangs) return []; if (!selectedProjectFlockData?.kandangs) return [];
return selectedProjectFlockData.kandangs.map((k) => ({ return selectedProjectFlockData.kandangs.map((k) => ({
value: k.id, value: k.id,
label: k.name || '', label: k.name || '',
})); }));
}, [filterProjectFlock, projectFlocksRawData]); }, [project_flock_id, projectFlocksRawData]);
// ===== PROJECT FLOCK KANDANG LOOKUP ===== // ===== PROJECT FLOCK KANDANG LOOKUP =====
const projectFlockKandangLookupUrl = useMemo(() => { const projectFlockKandangLookupUrl = useMemo(() => {
if (!filterProjectFlock || !filterKandang) return null; if (!project_flock_id?.value || !kandang_id?.value) return null;
const params = new URLSearchParams({ const params = new URLSearchParams({
project_flock_id: filterProjectFlock.value.toString(), project_flock_id: project_flock_id.value.toString(),
kandang_id: filterKandang.value.toString(), kandang_id: kandang_id.value.toString(),
}); });
return `${ProjectFlockApi.basePath}/kandangs/lookup?${params.toString()}`; return `${ProjectFlockApi.basePath}/kandangs/lookup?${params.toString()}`;
}, [filterProjectFlock, filterKandang]); }, [project_flock_id, kandang_id]);
const { data: projectFlockKandangLookupData } = useSWR( const { data: projectFlockKandangLookupData } = useSWR(
projectFlockKandangLookupUrl, projectFlockKandangLookupUrl,
@@ -495,154 +512,45 @@ const RecordingTable = () => {
? projectFlockKandangLookupData.data ? projectFlockKandangLookupData.data
: undefined; : undefined;
const formikRef = useRef(formik);
useEffect(() => {
formikRef.current = formik;
});
useEffect(() => { useEffect(() => {
if (projectFlockKandangLookup?.id) { if (projectFlockKandangLookup?.id) {
const pfkId = String(projectFlockKandangLookup.id); const pfkId = String(projectFlockKandangLookup.id);
setFilterProjectFlockKandangId(projectFlockKandangLookup.id); formik.setFieldValue('project_flock_kandang_id', pfkId);
formikRef.current.setFieldValue('project_flock_kandang_id', pfkId);
} else { } else {
setFilterProjectFlockKandangId(undefined); formik.setFieldValue('project_flock_kandang_id', null);
formikRef.current.setFieldValue('project_flock_kandang_id', null);
} }
}, [projectFlockKandangLookup]); }, [projectFlockKandangLookup]);
// ===== FILTER HANDLERS ===== // ===== FILTER HANDLERS =====
const handleFilterAreaChange = useCallback( const handleFilterAreaChange = (val: OptionType | OptionType[] | null) => {
(val: OptionType | OptionType[] | null) => { formik.setFieldValue('area_id', val);
const area = val as OptionType | null; formik.setFieldValue('location_id', null);
const areaId = area?.value ? String(area.value) : null; formik.setFieldValue('project_flock_id', null);
formik.setFieldValue('kandang_id', null);
formik.setFieldValue('project_flock_kandang_id', null);
};
formik.setFieldValue('area_id', areaId); const handleFilterLocationChange = (
formik.setFieldValue('location_id', null); val: OptionType | OptionType[] | null
formik.setFieldValue('project_flock_id', null); ) => {
formik.setFieldValue('kandang_id', null); formik.setFieldValue('location_id', val);
formik.setFieldValue('project_flock_kandang_id', null); formik.setFieldValue('project_flock_id', null);
formik.setFieldValue('kandang_id', null);
formik.setFieldValue('project_flock_kandang_id', null);
};
setFilterArea(area); const handleFilterProjectFlockChange = (
setFilterLocation(null); val: OptionType | OptionType[] | null
setFilterProjectFlock(null); ) => {
setFilterKandang(null); formik.setFieldValue('project_flock_id', val);
setFilterLocationAreaId(areaId || ''); formik.setFieldValue('kandang_id', null);
setFilterProjectFlockLocationId(''); formik.setFieldValue('project_flock_kandang_id', null);
}, };
[formik]
);
const handleFilterLocationChange = useCallback( const handleFilterKandangChange = (val: OptionType | OptionType[] | null) => {
(val: OptionType | OptionType[] | null) => { formik.setFieldValue('kandang_id', val);
const location = val as OptionType | null; formik.setFieldValue('project_flock_kandang_id', null);
const locationId = location?.value ? String(location.value) : null; };
formik.setFieldValue('location_id', locationId);
formik.setFieldValue('project_flock_id', null);
formik.setFieldValue('kandang_id', null);
formik.setFieldValue('project_flock_kandang_id', null);
setFilterLocation(location);
setFilterProjectFlock(null);
setFilterKandang(null);
setFilterProjectFlockLocationId(locationId || '');
},
[formik]
);
const handleFilterProjectFlockChange = useCallback(
(val: OptionType | OptionType[] | null) => {
const projectFlock = val as OptionType | null;
const projectFlockId = projectFlock?.value
? String(projectFlock.value)
: null;
formik.setFieldValue('project_flock_id', projectFlockId);
formik.setFieldValue('kandang_id', null);
formik.setFieldValue('project_flock_kandang_id', null);
setFilterProjectFlock(projectFlock);
setFilterKandang(null);
},
[formik]
);
const handleFilterKandangChange = useCallback(
(val: OptionType | OptionType[] | null) => {
const kandang = val as OptionType | null;
const kandangId = kandang?.value ? String(kandang.value) : null;
formik.setFieldValue('kandang_id', kandangId);
formik.setFieldValue('project_flock_kandang_id', null);
setFilterKandang(kandang);
},
[formik]
);
// ===== FILTER HELPERS =====
const areaIdValue = 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 locationIdValue = useMemo(() => {
if (!formik.values.location_id) return null;
return (
locationOptions.find(
(opt) => String(opt.value) === formik.values.location_id
) || null
);
}, [formik.values.location_id, locationOptions]);
const projectFlockIdValue = useMemo(() => {
if (!filterProjectFlock) return null;
return filterProjectFlock;
}, [filterProjectFlock]);
const kandangIdValue = useMemo(() => {
if (!formik.values.kandang_id) return null;
return (
kandangOptions.find(
(opt) => String(opt.value) === formik.values.kandang_id
) || null
);
}, [formik.values.kandang_id, kandangOptions]);
const recordingApprovalStatusOptions: OptionType<string>[] = [
{ value: 'CREATED', label: 'Pengajuan' },
{ value: 'UPDATED', label: 'Diperbarui' },
{ value: 'APPROVED', label: 'Disetujui' },
{ value: 'REJECTED', label: 'Ditolak' },
];
const projectFlockCategoryOptions: OptionType<string>[] = [
{ value: 'GROWING', label: 'Growing' },
{ value: 'LAYING', label: 'Laying' },
];
const approvalStatusValue = useMemo(() => {
if (!formik.values.approval_status) return null;
return (
recordingApprovalStatusOptions.find(
(opt) => opt.value === formik.values.approval_status
) || null
);
}, [formik.values.approval_status]);
const projectFlockCategoryValue = useMemo(() => {
if (!formik.values.project_flock_category) return null;
return (
projectFlockCategoryOptions.find(
(opt) => opt.value === formik.values.project_flock_category
) || null
);
}, [formik.values.project_flock_category]);
// ===== HANDLE FILTER MODAL OPEN ===== // ===== HANDLE FILTER MODAL OPEN =====
const handleFilterModalOpen = () => { const handleFilterModalOpen = () => {
@@ -650,25 +558,9 @@ const RecordingTable = () => {
formik.validateForm(); formik.validateForm();
}; };
const isRecordingApproved = useCallback((recording: Recording): boolean => { const searchChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
return ( updateFilter('search', e.target.value, true);
recording.approval?.action === 'APPROVED' && };
recording.approval?.step_name === 'Disetujui'
);
}, []);
useEffect(() => {
setTableState('recording-table', pathname);
}, [pathname, setTableState]);
const searchChangeHandler = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
updateFilter('search', e.target.value);
setSearchValue(e.target.value);
setPage(1);
},
[updateFilter, setSearchValue, setPage]
);
const singleDeleteHandler = async () => { const singleDeleteHandler = async () => {
setIsDeleteLoading(true); setIsDeleteLoading(true);
@@ -1220,7 +1112,7 @@ const RecordingTable = () => {
return ( return (
<div className='text-center'> <div className='text-center'>
{value !== null && value !== undefined {value !== null && value !== undefined
? `${value.toFixed(2)}%` ? `${value.toFixed(2)} butir`
: '-'} : '-'}
</div> </div>
); );
@@ -1236,7 +1128,7 @@ const RecordingTable = () => {
return ( return (
<div className='text-center text-gray-600'> <div className='text-center text-gray-600'>
{value !== null && value !== undefined {value !== null && value !== undefined
? `${value.toFixed(2)}%` ? `${value.toFixed(2)} btr`
: '-'} : '-'}
</div> </div>
); );
@@ -1572,13 +1464,13 @@ const RecordingTable = () => {
<Icon icon='heroicons:x-mark' width={20} height={20} /> <Icon icon='heroicons:x-mark' width={20} height={20} />
</Button> </Button>
</div> </div>
<form onSubmit={formik.handleSubmit} onReset={formik.handleReset}> <form onSubmit={formik.handleSubmit} onReset={formikResetHandler}>
<div className='p-4 flex flex-col gap-1.5'> <div className='p-4 flex flex-col gap-1.5'>
<SelectInput <SelectInput
label='Area' label='Area'
placeholder='Pilih Area' placeholder='Pilih Area'
options={areaOptions} options={areaOptions}
value={areaIdValue} value={formik.values.area_id}
onChange={handleFilterAreaChange} onChange={handleFilterAreaChange}
onInputChange={setAreaInputValue} onInputChange={setAreaInputValue}
isLoading={isLoadingAreaOptions} isLoading={isLoadingAreaOptions}
@@ -1591,13 +1483,13 @@ const RecordingTable = () => {
label='Lokasi' label='Lokasi'
placeholder='Pilih Lokasi' placeholder='Pilih Lokasi'
options={locationOptions} options={locationOptions}
value={locationIdValue} value={formik.values.location_id}
onChange={handleFilterLocationChange} onChange={handleFilterLocationChange}
onInputChange={setLocationInputValue} onInputChange={setLocationInputValue}
isLoading={isLoadingLocationOptions} isLoading={isLoadingLocationOptions}
isClearable isClearable
onMenuScrollToBottom={loadMoreLocations} onMenuScrollToBottom={loadMoreLocations}
isDisabled={!filterArea} isDisabled={!formik.values.area_id?.value}
className={{ wrapper: 'w-full' }} className={{ wrapper: 'w-full' }}
/> />
@@ -1605,13 +1497,13 @@ const RecordingTable = () => {
label='Project Flock' label='Project Flock'
placeholder='Pilih Project Flock' placeholder='Pilih Project Flock'
options={projectFlockOptions} options={projectFlockOptions}
value={projectFlockIdValue} value={formik.values.project_flock_id}
onChange={handleFilterProjectFlockChange} onChange={handleFilterProjectFlockChange}
onInputChange={setProjectFlockInputValue} onInputChange={setProjectFlockInputValue}
isLoading={isLoadingProjectFlocks} isLoading={isLoadingProjectFlocks}
isClearable isClearable
onMenuScrollToBottom={loadMoreProjectFlocks} onMenuScrollToBottom={loadMoreProjectFlocks}
isDisabled={!filterLocation} isDisabled={!formik.values.location_id?.value}
className={{ wrapper: 'w-full' }} className={{ wrapper: 'w-full' }}
/> />
@@ -1619,11 +1511,11 @@ const RecordingTable = () => {
label='Kandang' label='Kandang'
placeholder='Pilih Kandang' placeholder='Pilih Kandang'
options={kandangOptions} options={kandangOptions}
value={kandangIdValue} value={formik.values.kandang_id}
onChange={handleFilterKandangChange} onChange={handleFilterKandangChange}
isLoading={!filterProjectFlock} isLoading={!formik.values.project_flock_id?.value}
isClearable isClearable
isDisabled={!filterProjectFlock} isDisabled={!formik.values.project_flock_id?.value}
className={{ wrapper: 'w-full' }} className={{ wrapper: 'w-full' }}
/> />
@@ -1631,12 +1523,9 @@ const RecordingTable = () => {
label='Kategori' label='Kategori'
placeholder='Pilih Kategori' placeholder='Pilih Kategori'
options={projectFlockCategoryOptions} options={projectFlockCategoryOptions}
value={projectFlockCategoryValue} value={formik.values.project_flock_category}
onChange={(val) => { onChange={(val) => {
formik.setFieldValue( formik.setFieldValue('project_flock_category', val);
'project_flock_category',
!Array.isArray(val) && val ? String(val.value) : null
);
}} }}
isClearable isClearable
className={{ wrapper: 'w-full' }} className={{ wrapper: 'w-full' }}
@@ -1646,12 +1535,9 @@ const RecordingTable = () => {
label='Status Approval' label='Status Approval'
placeholder='Pilih Status Approval' placeholder='Pilih Status Approval'
options={recordingApprovalStatusOptions} options={recordingApprovalStatusOptions}
value={approvalStatusValue} value={formik.values.approval_status}
onChange={(val) => { onChange={(val) => {
formik.setFieldValue( formik.setFieldValue('approval_status', val);
'approval_status',
!Array.isArray(val) && val ? String(val.value) : null
);
}} }}
isClearable isClearable
className={{ wrapper: 'w-full' }} className={{ wrapper: 'w-full' }}
@@ -1661,19 +1547,9 @@ const RecordingTable = () => {
{/* Modal Footer */} {/* Modal Footer */}
<div className='flex justify-between items-center gap-4 p-4 border-t border-base-content/10 bg-gray-50'> <div className='flex justify-between items-center gap-4 p-4 border-t border-base-content/10 bg-gray-50'>
<Button <Button
type='button' type='reset'
variant='soft' variant='soft'
className='rounded-lg text-base-content/65 bg-transparent border-none hover:bg-base-content/10 hover:text-base-content/65 transition-colors px-3 py-2' className='rounded-lg text-base-content/65 bg-transparent border-none hover:bg-base-content/10 hover:text-base-content/65 transition-colors px-3 py-2'
onClick={() => {
formik.resetForm();
setFilterArea(null);
setFilterLocation(null);
setFilterProjectFlock(null);
setFilterKandang(null);
setFilterLocationAreaId('');
setFilterProjectFlockLocationId('');
filterModal.closeModal();
}}
> >
Reset Filter Reset Filter
</Button> </Button>
@@ -1,21 +1,40 @@
import { string, object } from 'yup'; import { OptionType } from '@/components/input/SelectInput';
import * as Yup from 'yup';
export const RecordingFilterSchema = object().shape({ export const RecordingFilterSchema = Yup.object().shape({
area_id: string().nullable(), area_id: Yup.object({
location_id: string().nullable(), value: Yup.number().nullable(),
project_flock_id: string().nullable(), label: Yup.string().nullable(),
kandang_id: string().nullable(), }).nullable(),
project_flock_kandang_id: string().nullable(), location_id: Yup.object({
approval_status: string().nullable(), value: Yup.number().nullable(),
project_flock_category: string().nullable(), label: Yup.string().nullable(),
}).nullable(),
project_flock_id: Yup.object({
value: Yup.number().nullable(),
label: Yup.string().nullable(),
}).nullable(),
kandang_id: Yup.object({
value: Yup.number().nullable(),
label: Yup.string().nullable(),
}).nullable(),
project_flock_kandang_id: Yup.number().nullable(),
approval_status: Yup.object({
value: Yup.string().nullable(),
label: Yup.string().nullable(),
}).nullable(),
project_flock_category: Yup.object({
value: Yup.string().nullable(),
label: Yup.string().nullable(),
}).nullable(),
}); });
export type RecordingFilterType = { export type RecordingFilterType = {
area_id: string | null; area_id: OptionType<number> | null;
location_id: string | null; location_id: OptionType<number> | null;
project_flock_id: string | null; project_flock_id: OptionType<number> | null;
kandang_id: string | null; kandang_id: OptionType<number> | null;
project_flock_kandang_id: string | null; project_flock_kandang_id: number | null;
approval_status: string | null; approval_status: OptionType<string> | null;
project_flock_category: string | null; project_flock_category: OptionType<string> | null;
}; };