refactor(FE-361): Refactor table and pagination components

This commit is contained in:
rstubryan
2025-12-09 18:04:33 +07:00
parent b039ec832b
commit 8f5dd1851a
3 changed files with 560 additions and 510 deletions
@@ -164,200 +164,144 @@ const PurchasesPerSupplierTab = () => {
// TODO START
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const tableColumns: ColumnDef<any>[] = [
{
header: 'No',
accessorKey: 'no',
cell: (props) => {
const isFooter = '_isFooter' in props.row.original;
if (isFooter) {
return (
<div className='font-semibold text-gray-900'>
{props.row.original.no}
</div>
);
}
return props.row.index + 1;
const getTableColumns = (totals: any) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const tableColumns: ColumnDef<any>[] = [
{
id: 'no',
header: 'No',
cell: (props) => props.row.index + 1,
footer: () => <div className='font-semibold text-gray-900'>Total</div>,
},
},
{
header: 'Tanggal Terima',
accessorKey: 'received_date',
cell: (props) => {
const isFooter = '_isFooter' in props.row.original;
if (isFooter) {
return (
<div className='font-semibold text-gray-900'>
{props.row.original.received_date}
</div>
);
}
return formatDate(props.row.original.received_date, 'DD MMM YYYY');
{
id: 'received_date',
header: 'Tanggal Terima',
accessorKey: 'received_date',
cell: (props) => formatDate(props.getValue() as string, 'DD MMM YYYY'),
},
},
{
header: 'Tanggal PO',
accessorKey: 'po_date',
cell: (props) => {
const isFooter = '_isFooter' in props.row.original;
if (isFooter) return null;
return formatDate(props.row.original.po_date, 'DD MMM YYYY');
{
id: 'po_date',
header: 'Tanggal PO',
accessorKey: 'po_date',
cell: (props) => formatDate(props.getValue() as string, 'DD MMM YYYY'),
},
},
{
header: 'No. Referensi',
accessorKey: 'po_number',
cell: (props) => {
const isFooter = '_isFooter' in props.row.original;
if (isFooter) return null;
return props.row.original.po_number;
{
id: 'po_number',
header: 'No. Referensi',
accessorKey: 'po_number',
cell: (props) => props.getValue() || '-',
},
},
{
header: 'Nama Produk',
accessorKey: 'product_name',
cell: (props) => {
const isFooter = '_isFooter' in props.row.original;
if (isFooter) return null;
return props.row.original.product_name;
{
id: 'product_name',
header: 'Nama Produk',
accessorKey: 'product_name',
cell: (props) => props.getValue() || '-',
},
},
{
header: 'Tujuan',
accessorKey: 'destination_warehouse',
cell: (props) => {
const isFooter = '_isFooter' in props.row.original;
if (isFooter) return null;
return props.row.original.destination_warehouse;
{
id: 'destination_warehouse',
header: 'Tujuan',
accessorKey: 'destination_warehouse',
cell: (props) => props.getValue() || '-',
},
},
{
header: 'QTY',
accessorKey: 'qty',
cell: (props) => {
const value = props.getValue() as number;
const isFooter = '_isFooter' in props.row.original;
return (
<div
className={
isFooter ? 'text-right font-semibold text-gray-900' : 'text-right'
}
>
{value.toLocaleString()}
{
id: 'qty',
header: 'QTY',
accessorKey: 'qty',
cell: (props) => {
const value = props.getValue() as number;
return <div className='text-right'>{value.toLocaleString()}</div>;
},
footer: () => (
<div className='text-right font-semibold text-gray-900'>
{totals.totalQty.toLocaleString()}
</div>
);
),
},
},
{
header: 'Harga Beli (Rp)',
accessorKey: 'price',
cell: (props) => {
const value = props.getValue() as number;
const isFooter = '_isFooter' in props.row.original;
if (isFooter) {
return (
<div className='text-right font-semibold text-gray-900'>
{formatCurrency(value)}
</div>
);
}
return (
<div className='text-right'>
{formatCurrency(props.row.original.price)}
{
id: 'price',
header: 'Harga Beli (Rp)',
accessorKey: 'price',
cell: (props) => {
const value = props.getValue() as number;
return <div className='text-right'>{formatCurrency(value)}</div>;
},
footer: () => (
<div className='text-right font-semibold text-gray-900'>
{formatCurrency(totals.totalPrice)}
</div>
);
),
},
},
{
header: 'Value Harga Beli (Rp)',
accessorKey: 'purchase_amount',
cell: (props) => {
const value = props.getValue() as number;
const isFooter = '_isFooter' in props.row.original;
return (
<div
className={
isFooter ? 'text-right font-semibold text-gray-900' : 'text-right'
}
>
{formatCurrency(value)}
{
id: 'purchase_amount',
header: 'Value Harga Beli (Rp)',
accessorKey: 'purchase_amount',
cell: (props) => {
const value = props.getValue() as number;
return <div className='text-right'>{formatCurrency(value)}</div>;
},
footer: () => (
<div className='text-right font-semibold text-gray-900'>
{formatCurrency(totals.totalPurchaseAmount)}
</div>
);
),
},
},
{
header: 'Transport (Rp)',
accessorKey: 'transport',
cell: (props) => {
const value = props.getValue() as number;
const isFooter = '_isFooter' in props.row.original;
if (isFooter) {
return (
<div className='text-right font-semibold text-gray-900'>
{formatCurrency(value)}
</div>
);
}
return (
<div className='text-right'>
{formatCurrency(props.row.original.transport)}
{
id: 'transport',
header: 'Transport (Rp)',
accessorKey: 'transport',
cell: (props) => {
const value = props.getValue() as number;
return <div className='text-right'>{formatCurrency(value)}</div>;
},
footer: () => (
<div className='text-right font-semibold text-gray-900'>
{formatCurrency(totals.totalTransport)}
</div>
);
),
},
},
{
header: 'Value Transport (Rp)',
accessorKey: 'value_transport',
cell: (props) => {
const value = props.getValue() as number;
const isFooter = '_isFooter' in props.row.original;
return (
<div
className={
isFooter ? 'text-right font-semibold text-gray-900' : 'text-right'
}
>
{formatCurrency(value)}
{
id: 'value_transport',
header: 'Value Transport (Rp)',
accessorKey: 'value_transport',
cell: (props) => {
const value = props.getValue() as number;
return <div className='text-right'>{formatCurrency(value)}</div>;
},
footer: () => (
<div className='text-right font-semibold text-gray-900'>
{formatCurrency(totals.totalValueTransport)}
</div>
);
),
},
},
{
header: 'Jumlah (Rp)',
accessorKey: 'total',
cell: (props) => {
const value = props.getValue() as number;
const isFooter = '_isFooter' in props.row.original;
return (
<div
className={
isFooter ? 'text-right font-semibold text-gray-900' : 'text-right'
}
>
{formatCurrency(value)}
{
id: 'total',
header: 'Jumlah (Rp)',
accessorKey: 'total',
cell: (props) => {
const value = props.getValue() as number;
return <div className='text-right'>{formatCurrency(value)}</div>;
},
footer: () => (
<div className='text-right font-semibold text-gray-900'>
{formatCurrency(totals.totalJumlah)}
</div>
);
),
},
},
{
header: 'Ekspedisi',
accessorKey: 'expedition_vendor_name',
cell: (props) => {
const isFooter = '_isFooter' in props.row.original;
if (isFooter) return null;
return props.row.original.expedition_vendor_name;
{
id: 'expedition_vendor_name',
header: 'Ekspedisi',
accessorKey: 'expedition_vendor_name',
cell: (props) => props.getValue() || '-',
},
},
{
header: 'Surat Jalan',
accessorKey: 'travel_number',
cell: (props) => {
const isFooter = '_isFooter' in props.row.original;
if (isFooter) return null;
return props.row.original.travel_number;
{
id: 'travel_number',
header: 'Surat Jalan',
accessorKey: 'travel_number',
cell: (props) => props.getValue() || '-',
},
},
];
];
return tableColumns;
};
return (
<>
@@ -451,31 +395,8 @@ const PurchasesPerSupplierTab = () => {
totalJumlah,
};
const footerData =
supplier.items.length > 0
? [
{
id: -999,
no: 'Total',
received_date: '',
po_date: null,
po_number: null,
product_name: null,
destination_warehouse: null,
qty: totals.totalQty,
price: totals.totalPrice,
purchase_amount: totals.totalPurchaseAmount,
transport: totals.totalTransport,
value_transport: totals.totalValueTransport,
total: totals.totalJumlah,
expedition_vendor_name: null,
travel_number: null,
_isFooter: true,
},
]
: [];
const totalPurchase = totals.totalJumlah;
const tableColumns = getTableColumns(totals);
return (
<Card
@@ -489,7 +410,6 @@ const PurchasesPerSupplierTab = () => {
data={supplier.items}
columns={tableColumns}
pageSize={10}
footerData={footerData}
renderFooter={supplier.items.length > 0}
className={{
tableWrapperClassName: 'overflow-x-auto mt-4',