feat(FE-363): Add pagination to purchases per supplier report

This commit is contained in:
rstubryan
2025-12-15 11:08:05 +07:00
parent 63c2a240d2
commit 5c9332537c
2 changed files with 91 additions and 49 deletions
@@ -37,6 +37,10 @@ const PurchasesPerSupplierTab = () => {
'received_date'
);
// ===== PAGINATION STATE =====
const [currentPage, setCurrentPage] = useState(1);
const [pageSize, setPageSize] = useState(10);
// ===== TABLE FILTER STATE =====
const { state: tableFilterState, updateFilter } = useTableFilter({
initial: {
@@ -169,6 +173,8 @@ const PurchasesPerSupplierTab = () => {
po_date: tableFilterState.po_date || undefined,
start_date: tableFilterState.start_date || undefined,
end_date: tableFilterState.end_date || undefined,
page: currentPage,
limit: pageSize,
};
return ['logistic-purchase-report', params];
@@ -181,7 +187,9 @@ const PurchasesPerSupplierTab = () => {
params.received_date,
params.po_date,
params.start_date,
params.end_date
params.end_date,
params.page,
params.limit
)
);
@@ -191,6 +199,32 @@ const PurchasesPerSupplierTab = () => {
? (purchasePerSupplier?.data as unknown as LogisticPurchasePerSupplier[])
: [];
const meta =
isResponseSuccess(purchasePerSupplier) && 'meta' in purchasePerSupplier
? purchasePerSupplier.meta
: undefined;
// ===== PAGINATION HANDLERS =====
const handlePageChange = (page: number) => {
setCurrentPage(page);
};
const handleRowChange = (pageSize: number) => {
setPageSize(pageSize);
};
const handleNextPage = () => {
if (meta && currentPage < meta.total_pages) {
setCurrentPage(currentPage + 1);
}
};
const handlePrevPage = () => {
if (currentPage > 1) {
setCurrentPage(currentPage - 1);
}
};
const getTableColumns = (
totals: Totals
): ColumnDef<LogisticPurchasePerSupplierItems>[] => {
@@ -505,55 +539,56 @@ const PurchasesPerSupplierTab = () => {
const tableColumns = getTableColumns(totals);
return (
<>
<Card
key={supplier.id}
title={supplier.supplier.name}
subtitle={`Total Pembelian: ${formatCurrency(totalPurchase)}`}
className={{ wrapper: 'w-full' }}
collapsible={true}
>
<Table
data={supplier.items}
columns={tableColumns}
pageSize={10}
renderFooter={supplier.items.length > 0}
className={{
containerClassName: 'w-full',
tableWrapperClassName: 'overflow-x-auto mt-4',
tableClassName: 'w-full table-auto text-sm',
headerRowClassName:
'border-b border-b-gray-200 bg-gray-50',
headerColumnClassName:
'px-4 py-3 text-xs font-semibold text-gray-700 text-left border border-gray-200',
bodyRowClassName:
'hover:bg-gray-50 transition-colors border-b border-l border-r border-b-gray-200 border-l-gray-200 border-r-gray-200',
bodyColumnClassName:
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
tableFooterClassName:
'bg-gray-100 font-semibold border border-gray-200',
footerRowClassName: 'border-t-2 border-gray-300',
footerColumnClassName:
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
}}
/>
<Pagination
key={supplier.id}
currentPage={1}
totalItems={supplier.items.length}
onPageChange={() => {}}
onRowChange={() => {}}
onNextPage={() => {}}
onPrevPage={() => {}}
rowOptions={[10, 25, 50, 100]}
itemsPerPage={10}
/>
</Card>
</>
<Card
key={supplier.id}
title={supplier.supplier.name}
subtitle={`Total Pembelian: ${formatCurrency(totalPurchase)}`}
className={{ wrapper: 'w-full' }}
collapsible={true}
>
<Table
data={supplier.items}
columns={tableColumns}
pageSize={10}
renderFooter={supplier.items.length > 0}
className={{
containerClassName: 'w-full',
tableWrapperClassName: 'overflow-x-auto mt-4',
tableClassName: 'w-full table-auto text-sm',
headerRowClassName: 'border-b border-b-gray-200 bg-gray-50',
headerColumnClassName:
'px-4 py-3 text-xs font-semibold text-gray-700 text-left border border-gray-200',
bodyRowClassName:
'hover:bg-gray-50 transition-colors border-b border-l border-r border-b-gray-200 border-l-gray-200 border-r-gray-200',
bodyColumnClassName:
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
tableFooterClassName:
'bg-gray-100 font-semibold border border-gray-200',
footerRowClassName: 'border-t-2 border-gray-300',
footerColumnClassName:
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
paginationClassName: 'hidden',
}}
/>
</Card>
);
})
)}
</Card>
{meta && data.length > 0 && (
<div className='mt-6'>
<Pagination
currentPage={meta.page}
totalItems={meta.total_results}
onPageChange={handlePageChange}
onRowChange={handleRowChange}
onNextPage={handleNextPage}
onPrevPage={handlePrevPage}
rowOptions={[10, 25, 50, 100]}
itemsPerPage={meta.limit}
/>
</div>
)}
</div>
);
};
+10 -3
View File
@@ -18,11 +18,13 @@ export class LogisticApiService extends BaseApiService<
received_date?: string,
po_date?: string,
start_date?: string,
end_date?: string
end_date?: string,
page?: number,
limit?: number
): Promise<BaseApiResponse<LogisticPurchasePerSupplierReport> | undefined> {
return await this.customRequest<
BaseApiResponse<LogisticPurchasePerSupplierReport>
>(`purchase-supplier`, {
>(`logistic-stock`, {
method: 'GET',
params: {
area_id: area_id,
@@ -32,9 +34,14 @@ export class LogisticApiService extends BaseApiService<
po_date: po_date,
start_date: start_date,
end_date: end_date,
page: page,
limit: limit,
},
});
}
}
export const LogisticApi = new LogisticApiService('/reports');
// TODO: REPLACE WITH PRODUCTION URL
export const LogisticApi = new LogisticApiService(
'http://localhost:4010/api/report'
);