Files
lti-web-client/src/components/pages/closing/ClosingSapronakCalculationTable.tsx
T
2025-12-31 13:18:22 +07:00

250 lines
6.6 KiB
TypeScript

'use client';
import Card from '@/components/Card';
import Table from '@/components/Table';
import { formatCurrency, formatDate, formatNumber } from '@/lib/helper';
import {
RowSapronakCalculation,
TotalSapronakCalculation,
} from '@/types/api/closing';
import { ColumnDef } from '@tanstack/react-table';
import { useMemo } from 'react';
import useSWR from 'swr';
import { ClosingApi } from '@/services/api/closing';
import { isResponseSuccess } from '@/lib/api-helper';
interface ClosingSapronakCalculationTableProps {
type?: 'detail';
projectFlockId: number;
}
const ClosingSapronakCalculationTable = ({
type,
projectFlockId,
}: ClosingSapronakCalculationTableProps) => {
const { data: sapronakCalculation, isLoading } = useSWR(
`/closing/sapronak-calculation/${projectFlockId}`,
() => ClosingApi.getPerhitunganSapronak(projectFlockId),
{
keepPreviousData: true,
}
);
// Helper function to create columns with footer support
const createColumns = (
total?: TotalSapronakCalculation
): ColumnDef<RowSapronakCalculation>[] => [
{
header: 'Tanggal',
accessorKey: 'tanggal',
cell: (props) =>
props.row.original.tanggal
? formatDate(props.row.original.tanggal, 'DD MMM YYYY')
: '-',
footer: 'Total',
},
{
header: 'No. Referensi',
accessorKey: 'no_referensi',
cell: (props) => (props.row.original.no_referensi as string) || '-',
footer: '',
},
{
header: 'QTY Masuk',
accessorKey: 'qty_masuk',
cell: (props) =>
props.row.original.qty_masuk
? formatNumber(props.row.original.qty_masuk as number)
: '-',
footer: total
? () => (
<div className='font-semibold text-gray-900'>
{total?.qty_masuk ? formatNumber(total?.qty_masuk) : '-'}
</div>
)
: '',
},
{
header: 'QTY Keluar',
accessorKey: 'qty_keluar',
cell: (props) =>
props.row.original.qty_keluar
? formatNumber(props.row.original.qty_keluar as number)
: '-',
footer: total
? () => (
<div className='font-semibold text-gray-900'>
{total?.qty_keluar ? formatNumber(total?.qty_keluar) : '-'}
</div>
)
: '',
},
{
header: 'QTY Pakai',
accessorKey: 'qty_pakai',
cell: (props) =>
props.row.original.qty_pakai
? formatNumber(props.row.original.qty_pakai as number)
: '-',
footer: total
? () => (
<div className='font-semibold text-gray-900'>
{total?.qty_pakai ? formatNumber(total?.qty_pakai) : '-'}
</div>
)
: '',
},
{
header: 'Uraian',
accessorKey: 'uraian',
cell: (props) => (props.row.original.uraian as string) || '-',
footer: '',
},
{
header: 'Kategori Produk',
accessorKey: 'kategori_produk',
cell: (props) => (props.row.original.kategori_produk as string) || '-',
footer: '',
},
{
header: 'Harga Beli/Qty (Rp)',
accessorKey: 'harga_beli_per_qty',
cell: (props) =>
props.row.original.harga_beli_per_qty
? formatCurrency(props.row.original.harga_beli_per_qty as number)
: '-',
footer: total
? () => (
<div className='font-semibold text-gray-900'>
{total?.harga_beli_per_qty
? formatCurrency(total?.harga_beli_per_qty)
: '-'}
</div>
)
: '',
},
{
header: 'Total Harga (Rp)',
accessorKey: 'total_harga',
cell: (props) =>
props.row.original.total_harga
? formatCurrency(props.row.original.total_harga as number)
: '-',
footer: total
? () => (
<div className='font-semibold text-gray-900'>
{total?.total_harga ? formatCurrency(total?.total_harga) : '-'}
</div>
)
: '',
},
{
header: 'Keterangan',
accessorKey: 'keterangan',
cell: (props) => (props.row.original.keterangan as string) || '-',
footer: '',
},
];
// Memoize columns untuk setiap kategori
const docBroilerColumns = useMemo(
() =>
isResponseSuccess(sapronakCalculation)
? createColumns(sapronakCalculation.data?.doc_broiler?.total)
: createColumns(),
[sapronakCalculation]
);
const ovkColumns = useMemo(
() =>
isResponseSuccess(sapronakCalculation)
? createColumns(sapronakCalculation.data?.ovk?.total)
: createColumns(),
[sapronakCalculation]
);
const pakanColumns = useMemo(
() =>
isResponseSuccess(sapronakCalculation)
? createColumns(sapronakCalculation.data?.pakan?.total)
: createColumns(),
[sapronakCalculation]
);
return (
<div className='flex flex-col gap-4'>
<Card
title='DOC Broiler'
collapsible
defaultCollapsed={false}
className={{
wrapper: 'w-full',
body: 'p-4 shadow',
}}
>
<Table<RowSapronakCalculation>
data={
isResponseSuccess(sapronakCalculation)
? (sapronakCalculation.data?.doc_broiler?.rows ?? [])
: []
}
columns={docBroilerColumns}
className={{
containerClassName: 'my-4',
}}
renderFooter={isResponseSuccess(sapronakCalculation)}
/>
</Card>
<Card
title='OVK'
variant='bordered'
collapsible
defaultCollapsed={true}
className={{
wrapper: 'w-full',
}}
>
<Table<RowSapronakCalculation>
data={
isResponseSuccess(sapronakCalculation)
? (sapronakCalculation.data?.ovk?.rows ?? [])
: []
}
columns={ovkColumns}
className={{
containerClassName: 'my-4',
}}
renderFooter={isResponseSuccess(sapronakCalculation)}
/>
</Card>
<Card
title='Pakan'
variant='bordered'
collapsible
defaultCollapsed={true}
className={{
wrapper: 'w-full',
}}
>
<Table<RowSapronakCalculation>
data={
isResponseSuccess(sapronakCalculation)
? (sapronakCalculation.data?.pakan?.rows ?? [])
: []
}
columns={pakanColumns}
className={{
containerClassName: 'my-4',
}}
renderFooter={isResponseSuccess(sapronakCalculation)}
/>
</Card>
</div>
);
};
export default ClosingSapronakCalculationTable;