mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
feat(FE-344,345): Add CosExpeditionReportTable component
This commit is contained in:
@@ -0,0 +1,154 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import React, { useMemo } from 'react';
|
||||||
|
import { ColumnDef } from '@tanstack/react-table';
|
||||||
|
import Table from '@/components/Table';
|
||||||
|
import Card from '@/components/Card';
|
||||||
|
import { formatCurrency } from '@/lib/helper';
|
||||||
|
import {
|
||||||
|
BaseClosingCosExpedition,
|
||||||
|
BaseCosExpedition,
|
||||||
|
} from '@/types/api/closing/closing';
|
||||||
|
|
||||||
|
interface CosExpeditionReportTableProps {
|
||||||
|
type?: 'detail';
|
||||||
|
initialValues?: BaseClosingCosExpedition;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FooterCosExpeditionRow extends BaseCosExpedition {
|
||||||
|
_isFooter: true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CosExpeditionReportTable = ({
|
||||||
|
type = 'detail',
|
||||||
|
initialValues,
|
||||||
|
}: CosExpeditionReportTableProps) => {
|
||||||
|
const cosExpeditionData: BaseCosExpedition[] = useMemo(() => {
|
||||||
|
return initialValues?.cos_expeditions || [];
|
||||||
|
}, [initialValues]);
|
||||||
|
|
||||||
|
const totals = useMemo(() => {
|
||||||
|
if (cosExpeditionData.length === 0) {
|
||||||
|
return {
|
||||||
|
totalHpp: 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalHpp = cosExpeditionData.reduce(
|
||||||
|
(sum, item) => sum + (item.hpp || 0),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
totalHpp,
|
||||||
|
};
|
||||||
|
}, [cosExpeditionData]);
|
||||||
|
|
||||||
|
const footerData = useMemo((): FooterCosExpeditionRow[] => {
|
||||||
|
if (cosExpeditionData.length === 0) return [];
|
||||||
|
|
||||||
|
const footerRow: FooterCosExpeditionRow = {
|
||||||
|
id: -999,
|
||||||
|
expedition_name: 'Total HPP Ekspedisi',
|
||||||
|
hpp: totals.totalHpp,
|
||||||
|
_isFooter: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
return [footerRow];
|
||||||
|
}, [cosExpeditionData, totals]);
|
||||||
|
|
||||||
|
const cosExpeditionColumns: ColumnDef<BaseCosExpedition>[] = useMemo(
|
||||||
|
() => [
|
||||||
|
{
|
||||||
|
id: 'id',
|
||||||
|
accessorKey: 'id',
|
||||||
|
header: 'No',
|
||||||
|
cell: (props) => {
|
||||||
|
const isFooter = '_isFooter' in props.row.original;
|
||||||
|
if (isFooter) {
|
||||||
|
return (
|
||||||
|
<div className='font-semibold text-gray-900 col-span-2'>
|
||||||
|
{props.row.original.expedition_name}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return props.getValue() || '-';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'expedition_name',
|
||||||
|
accessorKey: 'expedition_name',
|
||||||
|
header: 'Nama Ekspedisi',
|
||||||
|
cell: (props) => {
|
||||||
|
const isFooter = '_isFooter' in props.row.original;
|
||||||
|
if (isFooter) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return props.getValue() || '-';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'hpp',
|
||||||
|
accessorKey: 'hpp',
|
||||||
|
header: 'HPP Ekspedisi',
|
||||||
|
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 (
|
||||||
|
<>
|
||||||
|
<section className='w-full'>
|
||||||
|
<div className='p-4'>
|
||||||
|
<h2 className='text-xl font-semibold mb-4'>HPP Ekspedisi</h2>
|
||||||
|
<Card
|
||||||
|
className={{
|
||||||
|
wrapper: 'w-full bg-base-100',
|
||||||
|
body: 'p-0',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Table
|
||||||
|
data={cosExpeditionData}
|
||||||
|
columns={cosExpeditionColumns}
|
||||||
|
footerData={footerData}
|
||||||
|
renderFooter={cosExpeditionData.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',
|
||||||
|
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',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CosExpeditionReportTable;
|
||||||
Reference in New Issue
Block a user