From c9552dec2db111b47ed73f66fa46987d19f87ea7 Mon Sep 17 00:00:00 2001 From: rstubryan Date: Sat, 6 Dec 2025 09:47:38 +0700 Subject: [PATCH] refactor(FE-326): Remove custom header rows and simplify Table --- src/components/Table.tsx | 208 ++++-------------- .../pages/closing/sale/SalesReportTable.tsx | 138 +----------- 2 files changed, 53 insertions(+), 293 deletions(-) diff --git a/src/components/Table.tsx b/src/components/Table.tsx index 69406220..b5148fea 100644 --- a/src/components/Table.tsx +++ b/src/components/Table.tsx @@ -14,8 +14,6 @@ import { SortingState, OnChangeFn, Row, - HeaderGroup, - Column, } from '@tanstack/react-table'; import { rankItem } from '@tanstack/match-sorter-utils'; import { Icon } from '@iconify/react'; @@ -34,21 +32,6 @@ interface TableClassNames { bodyRowClassName?: string; bodyColumnClassName?: string; paginationClassName?: string; - customHeaderRowClassName?: string; - customHeaderCellClassName?: string; -} - -export interface CustomHeaderRow { - id: string; - cells: Array<{ - id: string; - content: ReactNode; - colSpan?: number; - rowSpan?: number; - className?: string; - field?: string; - }>; - className?: string; } export interface TableProps { @@ -69,13 +52,6 @@ export interface TableProps { rowSelection?: Record; setRowSelection?: OnChangeFn>; enableRowSelection?: boolean | ((row: Row) => boolean); - customHeaderRows?: CustomHeaderRow[]; - renderCustomHeaders?: boolean; - onCustomHeaderCellRender?: ( - cell: ReactNode, - column: Column, - headerGroup: HeaderGroup - ) => ReactNode; renderFooter?: boolean; footerContent?: ReactNode; } @@ -111,8 +87,6 @@ const Table = ({ bodyRowClassName: '', bodyColumnClassName: '', paginationClassName: '', - customHeaderRowClassName: '', - customHeaderCellClassName: '', }, emptyContent = emptyContentDefaultValue, sorting, @@ -121,9 +95,6 @@ const Table = ({ rowSelection, setRowSelection, enableRowSelection, - customHeaderRows = [], - renderCustomHeaders = false, - onCustomHeaderCellRender, renderFooter = false, footerContent, }: TableProps) => { @@ -228,143 +199,55 @@ const Table = ({
- {renderCustomHeaders && - customHeaderRows.length > 0 && - customHeaderRows.map((headerRow) => ( - - {headerRow.cells.map((cell) => { - const column = table - .getAllColumns() - .find((col) => col.id === cell.field); - - const canSort = column?.getCanSort(); - const sortingState = column?.getIsSorted(); - - return ( - - ); - })} - - ))} - {table.getHeaderGroups().map((headerGroup) => ( - {headerGroup.headers.map((header) => { - let cellContent = flexRender( - header.column.columnDef.header, - header.getContext() - ); - - if (onCustomHeaderCellRender) { - cellContent = onCustomHeaderCellRender( - cellContent, - header.column, - headerGroup - ); - } - - return ( - - ); - })} + {header.column.getCanSort() && ( +
+ + +
+ )} + + + ))} ))} @@ -383,7 +266,6 @@ const Table = ({ ))} - {renderFooter && footerContent}
-
- {cell.content} - - {canSort && ( -
- - -
- )} -
-
( + +
+ {flexRender( + header.column.columnDef.header, + header.getContext() )} - > -
- {cellContent} - {header.column.getCanSort() && ( -
- - -
- )} -
-
diff --git a/src/components/pages/closing/sale/SalesReportTable.tsx b/src/components/pages/closing/sale/SalesReportTable.tsx index a473dd14..3218d1d8 100644 --- a/src/components/pages/closing/sale/SalesReportTable.tsx +++ b/src/components/pages/closing/sale/SalesReportTable.tsx @@ -2,7 +2,7 @@ import React, { useMemo } from 'react'; import { ColumnDef } from '@tanstack/react-table'; -import Table, { CustomHeaderRow } from '@/components/Table'; +import Table from '@/components/Table'; import Card from '@/components/Card'; import Badge from '@/components/Badge'; import { formatCurrency, formatNumber, formatDate } from '@/lib/helper'; @@ -16,101 +16,6 @@ interface SalesReportTableProps { initialValues?: BaseClosingSales; } -interface HeaderCell { - id: string; - content: React.ReactNode; - colSpan?: number; - rowSpan?: number; - className: string; - field?: string; -} - -const generateCustomHeaders = (template: { - groups: Array<{ - label: string; - field?: string; - rowSpan?: number; - colSpan?: number; - subLabels?: string[]; - }>; -}): CustomHeaderRow[] => { - const mainRow: Array<{ - id: string; - content: React.ReactNode; - colSpan?: number; - rowSpan?: number; - className: string; - }> = []; - const subRow: Array<{ - id: string; - content: React.ReactNode; - colSpan?: number; - rowSpan?: number; - className: string; - }> = []; - let subColumnIndex = 0; - - template.groups.forEach((group) => { - if (group.subLabels) { - const mainCell: HeaderCell = { - id: `${group.field || 'group'}-${subColumnIndex}`, - content: group.label, - colSpan: group.colSpan, - className: - 'px-4 py-3 text-xs font-semibold text-gray-700 text-center whitespace-nowrap border border-gray-200', - }; - - mainRow.push(mainCell); - - group.subLabels.forEach((subLabel) => { - const subCell: HeaderCell = { - id: `sub-${subColumnIndex}`, - content: subLabel, - className: - 'px-4 py-3 text-xs font-semibold text-gray-700 text-left whitespace-nowrap border border-gray-200', - }; - - if (group.label === 'Jumlah') { - subCell.field = subLabel === 'Kuantitas' ? 'quantity' : 'weight'; - } - - subRow.push(subCell); - subColumnIndex++; - }); - } else { - const mainCell: HeaderCell = { - id: `${group.field}-header`, - content: group.label, - rowSpan: group.rowSpan, - className: - 'px-4 py-3 text-xs font-semibold text-gray-700 text-left whitespace-nowrap border border-gray-200', - }; - - mainCell.field = group.field; - - mainRow.push(mainCell); - } - }); - - const rows: CustomHeaderRow[] = [ - { - id: 'main-header', - cells: mainRow, - className: 'bg-gray-50', - }, - ]; - - if (subRow.length > 0) { - rows.push({ - id: 'sub-header', - cells: subRow, - className: 'bg-gray-50', - }); - } - - return rows; -}; - const SalesReportTable = ({ type = 'detail', initialValues, @@ -310,7 +215,7 @@ const SalesReportTable = ({ }; return ( - + {status || '-'} ); @@ -320,33 +225,6 @@ const SalesReportTable = ({ [] ); - const headerTemplate = { - groups: [ - { label: 'Tanggal Realisasi', field: 'realization_date', rowSpan: 2 }, - { label: 'Umur', field: 'age', rowSpan: 2 }, - { label: 'No. DO', field: 'do_number', rowSpan: 2 }, - { label: 'Produk', field: 'product', rowSpan: 2 }, - { label: 'Customer', field: 'customer', rowSpan: 2 }, - { - label: 'Jumlah', - colSpan: 2, - subLabels: ['Qty', 'Kg'], - }, - { label: 'AVG (Kg)', field: 'avg_weight', rowSpan: 2 }, - { label: 'Harga Mitra (Rp)', field: 'price_partner', rowSpan: 2 }, - { label: 'Total Mitra (Rp)', field: 'total_mitra', rowSpan: 2 }, - { label: 'Harga Act (Rp)', field: 'price_act', rowSpan: 2 }, - { label: 'Total Act (Rp)', field: 'total_act', rowSpan: 2 }, - { label: 'Kandang', field: 'kandang', rowSpan: 2 }, - { label: 'Status Pembayaran', field: 'payment_status', rowSpan: 2 }, - ], - }; - - const salesCustomHeaderRows = useMemo( - () => generateCustomHeaders(headerTemplate), - [] - ); - return ( <>
@@ -361,8 +239,6 @@ const SalesReportTable = ({ 0} footerContent={ @@ -374,13 +250,13 @@ const SalesReportTable = ({ - - -
+ {formatNumber(totals.totalQuantity)} + {formatNumber(totals.totalWeight)} + {formatNumber(totals.avgWeight)} @@ -403,7 +279,9 @@ const SalesReportTable = ({ className={{ tableWrapperClassName: 'overflow-x-auto', tableClassName: 'w-full table-auto text-sm', - headerRowClassName: 'hidden', + 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: