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
@@ -1,6 +1,6 @@
'use client';
import { RefObject, useMemo, useState } from 'react';
import { RefObject, useEffect, useMemo, useState } from 'react';
import { useFormik } from 'formik';
import * as yup from 'yup';
@@ -60,6 +60,11 @@ const ReportDepreciationFilterModal = ({
string | undefined
>(initialValues?.location_id || undefined);
useEffect(() => {
setSelectedAreaId(initialValues?.area_id || undefined);
setSelectedLocationId(initialValues?.location_id || undefined);
}, [initialValues?.area_id, initialValues?.location_id]);
const closeModalHandler = () => {
ref.current?.close();
};
@@ -97,6 +102,7 @@ const ReportDepreciationFilterModal = ({
const formik = useFormik<ReportDepreciationFilterValues>({
initialValues: initialValues || defaultInitialValues,
enableReinitialize: true,
validationSchema: ReportDepreciationFilterSchema,
onSubmit: async (values) => {
onSubmit?.(values);
@@ -126,8 +126,35 @@ const ReportExpenseTab = ({ tabId }: ReportExpenseTabProps) => {
});
handleFilterModalOpenRef.current = () => {
const restoredLocation = filterParams.location_id
? locationOptions.find((opt) => String(opt.value) === filterParams.location_id) ||
{ value: filterParams.location_id, label: filterParams.location_id }
: null;
const restoredSupplier = filterParams.supplier_id
? supplierOptions.find((opt) => String(opt.value) === filterParams.supplier_id) ||
{ value: filterParams.supplier_id, label: filterParams.supplier_id }
: null;
const restoredKandang = filterParams.kandang_id
? projectFlockKandangOptions.find((opt) => String(opt.value) === filterParams.kandang_id) ||
{ value: filterParams.kandang_id, label: filterParams.kandang_id }
: null;
const restoredNonstock = filterParams.nonstock_id
? nonstockOptions.find((opt) => String(opt.value) === filterParams.nonstock_id) ||
{ value: filterParams.nonstock_id, label: filterParams.nonstock_id }
: null;
const restoredCategory = filterParams.category
? categoryOptions.find((opt) => opt.value === filterParams.category) || null
: null;
formik.setValues({
location_id: restoredLocation,
supplier_id: restoredSupplier,
kandang_id: restoredKandang,
nonstock_id: restoredNonstock,
realization_date: filterParams.realization_date || null,
category: restoredCategory,
});
filterModal.openModal();
formik.validateForm();
};
// ===== OPTIONS =====
@@ -38,6 +38,7 @@ import CustomerSupplierSkeleton from '@/components/pages/report/finance/skeleton
import { OptionType } from '@/components/table/TableRowSizeSelector';
import { Color } from '@/types/theme';
import ButtonFilter from '@/components/helper/ButtonFilter';
import Pagination from '@/components/Pagination';
interface CustomerPaymentTabProps {
tabId: string;
@@ -58,7 +59,7 @@ const CustomerPaymentTab = ({ tabId }: CustomerPaymentTabProps) => {
// ===== PAGINATION STATE =====
const [currentPage, setCurrentPage] = useState(1);
const [pageSize] = useState(10);
const [pageSize, setPageSize] = useState(10);
// ===== SUBMISSION STATE =====
const [filterParams, setFilterParams] = useState<FilterParams>({});
@@ -117,8 +118,13 @@ const CustomerPaymentTab = ({ tabId }: CustomerPaymentTabProps) => {
});
handleFilterModalOpenRef.current = () => {
formik.setValues({
start_date: filterParams.start_date || null,
end_date: filterParams.end_date || null,
customer_ids: filterParams.customer_ids || null,
filter_by: filterParams.filter_by || null,
});
filterModal.openModal();
formik.validateForm();
};
const getPaymentStatusBadgeColor = (notes: string): Color => {
@@ -249,6 +255,14 @@ const CustomerPaymentTab = ({ tabId }: CustomerPaymentTabProps) => {
[customerPayment]
);
const meta = useMemo(
() =>
isResponseSuccess(customerPayment) && customerPayment.meta
? customerPayment.meta
: null,
[customerPayment]
);
// ===== EXPORT DATA FETCHER =====
const customerPaymentExport = useCallback(async (): Promise<
CustomerPaymentReport[] | null
@@ -717,6 +731,29 @@ const CustomerPaymentTab = ({ tabId }: CustomerPaymentTabProps) => {
/>
)}
{!isLoading && data.length > 0 && meta && (
<div className='max-w-sm ml-auto'>
<Pagination
totalItems={meta.total_results || 0}
itemsPerPage={meta.limit || 0}
currentPage={meta.page || 0}
onPrevPage={() =>
setCurrentPage((curr) => (curr > 1 ? curr - 1 : curr))
}
onNextPage={() =>
setCurrentPage((curr) =>
meta.total_pages && curr < meta.total_pages
? curr + 1
: curr
)
}
onPageChange={(pageNumber) => setCurrentPage(pageNumber)}
rowOptions={[10, 20, 50, 100]}
onRowChange={setPageSize}
/>
</div>
)}
{!isLoading &&
data.length > 0 &&
data.map((customerReport) => {
@@ -1,6 +1,7 @@
import Button from '@/components/Button';
import Card from '@/components/Card';
import Dropdown from '@/components/Dropdown';
import Pagination from '@/components/Pagination';
import DateInput from '@/components/input/DateInput';
import { OptionType, useSelect } from '@/components/input/SelectInput';
import Modal, { useModal } from '@/components/Modal';
@@ -78,6 +79,10 @@ const DebtSupplierTab = ({ tabId }: DebtSupplierTabProps) => {
const [isExcelExportLoading, setIsExcelExportLoading] = useState(false);
const isAnyExportLoading = isPdfExportLoading || isExcelExportLoading;
// ===== PAGINATION STATE =====
const [currentPage, setCurrentPage] = useState(1);
const [pageSize, setPageSize] = useState(10);
// ===== SUBMISSION STATE =====
const [filterParams, setFilterParams] = useState<DebtSupplierFilter>({
start_date: undefined,
@@ -128,7 +133,7 @@ const DebtSupplierTab = ({ tabId }: DebtSupplierTabProps) => {
filter_by: values.filterBy?.value?.toString() || undefined,
});
filterModal.closeModal();
// setIsSubmitted(true);
setCurrentPage(1);
},
onReset: () => {
setFilterParams({
@@ -137,14 +142,29 @@ const DebtSupplierTab = ({ tabId }: DebtSupplierTabProps) => {
supplier_ids: undefined,
filter_by: undefined,
});
// setIsSubmitted(false);
setCurrentPage(1);
filterModal.closeModal();
},
});
handleFilterModalOpenRef.current = () => {
const restoredFilterBy =
dataTypeOptions.find((opt) => opt.value === filterParams.filter_by) || null;
const supplierIdList = filterParams.supplier_ids
? filterParams.supplier_ids.split(',')
: [];
const restoredSupplierIds = supplierOptions.filter((opt) =>
supplierIdList.includes(String(opt.value))
);
formik.setValues({
startDate: filterParams.start_date || null,
endDate: filterParams.end_date || null,
supplierIds: restoredSupplierIds.length > 0 ? restoredSupplierIds : null,
filterBy: restoredFilterBy,
});
filterModal.openModal();
formik.validateForm();
};
// ===== DATA FETCHING =====
@@ -155,6 +175,8 @@ const DebtSupplierTab = ({ tabId }: DebtSupplierTabProps) => {
filter_by: filterParams.filter_by,
start_date: filterParams.start_date,
end_date: filterParams.end_date,
page: currentPage,
limit: pageSize,
};
return ['debt-supplier-report', params];
@@ -164,7 +186,9 @@ const DebtSupplierTab = ({ tabId }: DebtSupplierTabProps) => {
params.supplier_ids,
params.filter_by,
params.start_date,
params.end_date
params.end_date,
params.page,
params.limit
)
);
@@ -176,6 +200,14 @@ const DebtSupplierTab = ({ tabId }: DebtSupplierTabProps) => {
[debtSupplier]
);
const meta = useMemo(
() =>
isResponseSuccess(debtSupplier) && debtSupplier.meta
? debtSupplier.meta
: null,
[debtSupplier]
);
// ===== EXPORT DATA FETCHER =====
const debtSupplierExport = useCallback(async (): Promise<
DebtSupplier[] | null
@@ -630,6 +662,29 @@ const DebtSupplierTab = ({ tabId }: DebtSupplierTabProps) => {
/>
)}
{!isLoading && data.length > 0 && meta && (
<div className='max-w-sm ml-auto'>
<Pagination
totalItems={meta.total_results || 0}
itemsPerPage={meta.limit || 0}
currentPage={meta.page || 0}
onPrevPage={() =>
setCurrentPage((curr) => (curr > 1 ? curr - 1 : curr))
}
onNextPage={() =>
setCurrentPage((curr) =>
meta.total_pages && curr < meta.total_pages
? curr + 1
: curr
)
}
onPageChange={(pageNumber) => setCurrentPage(pageNumber)}
rowOptions={[10, 20, 50, 100]}
onRowChange={setPageSize}
/>
</div>
)}
{!isLoading &&
data.length > 0 &&
data.map((supplierReport) => {
@@ -156,8 +156,17 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
});
handleFilterModalOpenRef.current = () => {
formik.setValues({
start_date: filterParams.start_date || null,
end_date: filterParams.end_date || null,
area_ids: filterParams.area_id || null,
supplier_ids: filterParams.supplier_id || null,
product_ids: filterParams.product_id || null,
product_category_ids: filterParams.product_category_id || null,
filter_by: filterParams.filter_by || null,
sort_by: filterParams.sort_by || null,
});
filterModal.openModal();
formik.validateForm();
};
const { setFieldValue } = formik;
@@ -156,8 +156,21 @@ const DailyMarketingTab = ({ tabId }: DailyMarketingTabProps) => {
});
handleFilterModalOpenRef.current = () => {
formik.setValues({
page: formik.values.page,
pageSize: formik.values.pageSize,
search: formik.values.search,
area_id: filterParams.area_id || null,
location_id: filterParams.location_id || null,
warehouse_id: filterParams.warehouse_id || null,
customer_id: filterParams.customer_id || null,
start_date: filterParams.start_date || null,
end_date: filterParams.end_date || null,
filter_by: filterParams.filter_by || null,
marketing_type: filterParams.marketing_type || null,
sort_by: filterParams.sort_by || null,
});
filterModal.openModal();
formik.validateForm();
};
// ===== SEARCH CHANGE HANDLER =====
@@ -152,8 +152,19 @@ const HppPerKandangTab = ({ tabId }: HppPerKandangTabProps) => {
});
handleFilterModalOpenRef.current = () => {
formik.setValues({
page: formik.values.page,
pageSize: formik.values.pageSize,
area_id: filterParams.area_id || null,
location_id: filterParams.location_id || null,
kandang_id: filterParams.kandang_id || null,
weight_min: filterParams.weight_min || null,
weight_max: filterParams.weight_max || null,
period: filterParams.period || null,
sort_by: filterParams.sort_by || null,
show_unrecorded: filterParams.show_unrecorded ?? false,
});
filterModal.openModal();
formik.validateForm();
};
// ===== WEIGHT CHANGE HANDLERS =====
@@ -263,8 +263,30 @@ const ProductionResultContent = ({ tabId }: ProductionResultTabProps) => {
});
handleFilterModalOpenRef.current = () => {
const restoredAreaId = filterParams.area_id
? areaOptions.find((opt) => String(opt.value) === filterParams.area_id) ||
{ value: filterParams.area_id, label: filterParams.area_id }
: null;
const restoredLocationId = filterParams.location_id
? locationOptions.find((opt) => String(opt.value) === filterParams.location_id) ||
{ value: filterParams.location_id, label: filterParams.location_id }
: null;
const restoredProjectFlockId = filterParams.project_flock_id
? projectFlockOptions.find((opt) => String(opt.value) === filterParams.project_flock_id) ||
{ value: filterParams.project_flock_id, label: filterParams.project_flock_id }
: null;
const restoredKandangId = filterParams.project_flock_kandang_id
? projectFlockKandangOptions.find((opt) => String(opt.value) === filterParams.project_flock_kandang_id) ||
{ value: filterParams.project_flock_kandang_id, label: filterParams.project_flock_kandang_id }
: null;
formik.setValues({
area_id: restoredAreaId,
location_id: restoredLocationId,
project_flock_id: restoredProjectFlockId,
kandang_id: restoredKandangId,
});
filterModal.openModal();
formik.validateForm();
};
const [selectedProjectFlockKandang, setSelectedProjectFlockKandang] =