mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-23 14:55:44 +00:00
refactor(FE-344): update pagination UI and table footer handling
This commit is contained in:
@@ -16,10 +16,6 @@ interface SalesReportTableProps {
|
||||
initialValues?: BaseClosingSales;
|
||||
}
|
||||
|
||||
interface FooterSalesRow extends BaseSales {
|
||||
_isFooter: true;
|
||||
}
|
||||
|
||||
const SalesReportTable = ({
|
||||
type = 'detail',
|
||||
initialValues,
|
||||
@@ -72,29 +68,6 @@ const SalesReportTable = ({
|
||||
};
|
||||
}, [salesData]);
|
||||
|
||||
const footerData = useMemo((): FooterSalesRow[] => {
|
||||
if (salesData.length === 0) return [];
|
||||
|
||||
const footerRow: FooterSalesRow = {
|
||||
id: -999,
|
||||
realization_date: 'Total Penjualan',
|
||||
age: 0,
|
||||
do_number: '',
|
||||
product: {} as Product,
|
||||
customer: {} as Customer,
|
||||
qty: totals.totalQuantity,
|
||||
weight: totals.totalWeight,
|
||||
avg_weight: totals.avgWeight,
|
||||
price: totals.avgPricePartner,
|
||||
total_price: totals.totalPartner,
|
||||
kandang: {} as Kandang,
|
||||
payment_status: '',
|
||||
_isFooter: true,
|
||||
};
|
||||
|
||||
return [footerRow];
|
||||
}, [salesData, totals]);
|
||||
|
||||
const salesColumns: ColumnDef<BaseSales>[] = useMemo(
|
||||
() => [
|
||||
{
|
||||
@@ -102,43 +75,30 @@ const SalesReportTable = ({
|
||||
accessorKey: 'realization_date',
|
||||
header: 'Tanggal Realisasi',
|
||||
cell: (props) => {
|
||||
const isFooter = '_isFooter' in props.row.original;
|
||||
if (isFooter) {
|
||||
return (
|
||||
<div className='font-semibold text-gray-900 col-span-5'>
|
||||
{props.row.original.realization_date}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
const date = props.row.original.realization_date;
|
||||
return date ? formatDate(date, 'DD MMM YYYY') : '-';
|
||||
},
|
||||
footer: () => (
|
||||
<div className='font-semibold text-gray-900'>Total Penjualan</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'age',
|
||||
accessorKey: 'age',
|
||||
header: 'Umur',
|
||||
cell: (props) => {
|
||||
const isFooter = '_isFooter' in props.row.original;
|
||||
return isFooter ? null : props.getValue() || '-';
|
||||
},
|
||||
cell: (props) => props.getValue() || '-',
|
||||
},
|
||||
{
|
||||
id: 'do_number',
|
||||
accessorKey: 'do_number',
|
||||
header: 'No. DO',
|
||||
cell: (props) => {
|
||||
const isFooter = '_isFooter' in props.row.original;
|
||||
return isFooter ? null : props.getValue() || '-';
|
||||
},
|
||||
cell: (props) => props.getValue() || '-',
|
||||
},
|
||||
{
|
||||
id: 'product',
|
||||
accessorKey: 'product',
|
||||
header: 'Produk',
|
||||
cell: (props) => {
|
||||
const isFooter = '_isFooter' in props.row.original;
|
||||
if (isFooter) return null;
|
||||
const product = props.getValue() as Product;
|
||||
return product?.name || '-';
|
||||
},
|
||||
@@ -148,47 +108,43 @@ const SalesReportTable = ({
|
||||
accessorKey: 'customer',
|
||||
header: 'Customer',
|
||||
cell: (props) => {
|
||||
const isFooter = '_isFooter' in props.row.original;
|
||||
if (isFooter) return null;
|
||||
const customer = props.getValue() as Customer;
|
||||
return customer?.name || '-';
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'qty',
|
||||
accessorKey: 'qty',
|
||||
header: 'Kuantitas',
|
||||
cell: (props) => {
|
||||
const value = props.getValue() as number;
|
||||
const isFooter = '_isFooter' in props.row.original;
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
isFooter ? 'text-left font-semibold text-gray-900' : 'text-left'
|
||||
}
|
||||
>
|
||||
{formatNumber(value)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'weight',
|
||||
accessorKey: 'weight',
|
||||
header: 'Kg',
|
||||
cell: (props) => {
|
||||
const value = props.getValue() as number;
|
||||
const isFooter = '_isFooter' in props.row.original;
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
isFooter ? 'text-left font-semibold text-gray-900' : 'text-left'
|
||||
}
|
||||
>
|
||||
{formatNumber(value)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
id: 'jumlah',
|
||||
header: 'Jumlah',
|
||||
columns: [
|
||||
{
|
||||
id: 'qty',
|
||||
accessorKey: 'qty',
|
||||
header: 'Kuantitas',
|
||||
cell: (props) => {
|
||||
const value = props.getValue() as number;
|
||||
return <div className='text-left'>{formatNumber(value)}</div>;
|
||||
},
|
||||
footer: () => (
|
||||
<div className='text-left font-semibold text-gray-900'>
|
||||
{formatNumber(totals.totalQuantity)}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'weight',
|
||||
accessorKey: 'weight',
|
||||
header: 'Kg',
|
||||
cell: (props) => {
|
||||
const value = props.getValue() as number;
|
||||
return <div className='text-left'>{formatNumber(value)}</div>;
|
||||
},
|
||||
footer: () => (
|
||||
<div className='text-left font-semibold text-gray-900'>
|
||||
{formatNumber(totals.totalWeight)}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'avg_weight',
|
||||
@@ -196,17 +152,13 @@ const SalesReportTable = ({
|
||||
header: 'AVG (Kg)',
|
||||
cell: (props) => {
|
||||
const value = props.getValue() as number;
|
||||
const isFooter = '_isFooter' in props.row.original;
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
isFooter ? 'text-left font-semibold text-gray-900' : 'text-left'
|
||||
}
|
||||
>
|
||||
{formatNumber(value)}
|
||||
</div>
|
||||
);
|
||||
return <div className='text-left'>{formatNumber(value)}</div>;
|
||||
},
|
||||
footer: () => (
|
||||
<div className='text-left font-semibold text-gray-900'>
|
||||
{formatNumber(totals.avgWeight)}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'price_partner',
|
||||
@@ -214,19 +166,13 @@ const SalesReportTable = ({
|
||||
header: 'Harga Mitra (Rp)',
|
||||
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)}
|
||||
</div>
|
||||
);
|
||||
return <div className='text-right'>{formatCurrency(value)}</div>;
|
||||
},
|
||||
footer: () => (
|
||||
<div className='text-right font-semibold text-gray-900'>
|
||||
{formatCurrency(totals.avgPricePartner)}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'total_mitra',
|
||||
@@ -234,19 +180,13 @@ const SalesReportTable = ({
|
||||
header: 'Total Mitra (Rp)',
|
||||
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)}
|
||||
</div>
|
||||
);
|
||||
return <div className='text-right'>{formatCurrency(value)}</div>;
|
||||
},
|
||||
footer: () => (
|
||||
<div className='text-right font-semibold text-gray-900'>
|
||||
{formatCurrency(totals.totalPartner)}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'price_act',
|
||||
@@ -254,18 +194,7 @@ const SalesReportTable = ({
|
||||
header: 'Harga Act (Rp)',
|
||||
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)}
|
||||
</div>
|
||||
);
|
||||
return <div className='text-right'>{formatCurrency(value)}</div>;
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -274,18 +203,7 @@ const SalesReportTable = ({
|
||||
header: 'Total Act (Rp)',
|
||||
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)}
|
||||
</div>
|
||||
);
|
||||
return <div className='text-right'>{formatCurrency(value)}</div>;
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -293,8 +211,6 @@ const SalesReportTable = ({
|
||||
accessorKey: 'kandang',
|
||||
header: 'Kandang',
|
||||
cell: (props) => {
|
||||
const isFooter = '_isFooter' in props.row.original;
|
||||
if (isFooter) return null;
|
||||
const kandang = props.getValue() as Kandang;
|
||||
return kandang?.name || '-';
|
||||
},
|
||||
@@ -304,9 +220,6 @@ const SalesReportTable = ({
|
||||
accessorKey: 'payment_status',
|
||||
header: 'Status Pembayaran',
|
||||
cell: (props) => {
|
||||
const isFooter = '_isFooter' in props.row.original;
|
||||
if (isFooter) return null;
|
||||
|
||||
const status = props.getValue() as string;
|
||||
const getStatusColor = (status: string) => {
|
||||
if (!status) return 'neutral';
|
||||
@@ -345,16 +258,14 @@ const SalesReportTable = ({
|
||||
<Table
|
||||
data={salesData}
|
||||
columns={salesColumns}
|
||||
footerData={footerData}
|
||||
renderFooter={salesData.length > 0}
|
||||
className={{
|
||||
tableWrapperClassName: 'overflow-x-auto',
|
||||
tableClassName: 'w-full table-auto text-sm',
|
||||
headerRowClassName: 'border-b border-b-gray-200',
|
||||
headerColumnClassName:
|
||||
'px-4 py-3 text-xs font-semibold text-gray-500 last:flex last:flex-row last:justify-end whitespace-nowrap',
|
||||
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',
|
||||
'hover:bg-gray-50 transition-colors border-b border-gray-200 first:border-t first:border-t-gray-200',
|
||||
bodyColumnClassName:
|
||||
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
|
||||
tableFooterClassName:
|
||||
|
||||
Reference in New Issue
Block a user