diff --git a/src/components/pages/report/expense/tab/ReportExpenseTab.tsx b/src/components/pages/report/expense/tab/ReportExpenseTab.tsx index edd5b725..8e6b49b5 100644 --- a/src/components/pages/report/expense/tab/ReportExpenseTab.tsx +++ b/src/components/pages/report/expense/tab/ReportExpenseTab.tsx @@ -39,7 +39,7 @@ import { } from '@/services/api/master-data'; import { Supplier } from '@/types/api/master-data/supplier'; import { Nonstock } from '@/types/api/master-data/nonstock'; -import { ColumnDef } from '@tanstack/react-table'; +import { ColumnDef, SortingState, Updater } from '@tanstack/react-table'; import { httpClient } from '@/services/http/client'; import { BaseApiResponse } from '@/types/api/api-general'; import ButtonFilter from '@/components/helper/ButtonFilter'; @@ -73,6 +73,25 @@ const ReportExpenseTab = ({ tabId }: ReportExpenseTabProps) => { const [page, setPage] = useState(1); const [pageSize, setPageSize] = useState(10); + // ===== SORTING STATE ===== + const [sortBy, setSortBy] = useState(''); + const [orderBy, setOrderBy] = useState(''); + + const sorting: SortingState = sortBy + ? [{ id: sortBy, desc: orderBy === 'desc' }] + : []; + + const handleSortingChange = (updater: Updater) => { + const next = typeof updater === 'function' ? updater(sorting) : updater; + if (next.length > 0) { + setSortBy(next[0].id); + setOrderBy(next[0].desc ? 'desc' : 'asc'); + } else { + setSortBy(''); + setOrderBy(''); + } + }; + const handleFilterModalOpenRef = useRef(() => {}); const filterModal = useModal(); @@ -252,6 +271,8 @@ const ReportExpenseTab = ({ tabId }: ReportExpenseTabProps) => { if (filterParams.category) { params.append('category', filterParams.category); } + if (sortBy) params.append('sort_by', sortBy); + if (orderBy) params.append('sort_order', orderBy); Object.entries(extraParams ?? {}).forEach(([key, value]) => { params.set(key, value); @@ -259,7 +280,7 @@ const ReportExpenseTab = ({ tabId }: ReportExpenseTabProps) => { return params.toString(); }, - [filterParams] + [filterParams, sortBy, orderBy] ); // ===== DATA FETCHING ===== @@ -443,19 +464,23 @@ const ReportExpenseTab = ({ tabId }: ReportExpenseTabProps) => { return [ { header: 'No', + enableSorting: false, cell: (props) => (page - 1) * pageSize + props.row.index + 1, }, { header: 'No. PO', accessorKey: 'po_number', + enableSorting: true, }, { header: 'No. Referensi', accessorKey: 'reference_number', + enableSorting: true, }, { header: 'Tanggal Realisasi', accessorKey: 'realization_date', + enableSorting: true, cell: ({ row }) => { return formatDate(row.original?.realization_date, 'DD MMM, YYYY'); }, @@ -463,6 +488,7 @@ const ReportExpenseTab = ({ tabId }: ReportExpenseTabProps) => { { header: 'Tanggal Transaksi', accessorKey: 'transaction_date', + enableSorting: true, cell: ({ row }) => { return formatDate(row.original?.transaction_date, 'DD MMM, YYYY'); }, @@ -470,21 +496,30 @@ const ReportExpenseTab = ({ tabId }: ReportExpenseTabProps) => { { header: 'Kategori', accessorKey: 'category', + enableSorting: true, }, { header: 'Produk', + accessorKey: 'product', + enableSorting: true, accessorFn: (row) => row.pengajuan?.nonstock?.name, }, { header: 'Supplier', + accessorKey: 'supplier', + enableSorting: true, accessorFn: (row) => row.supplier?.name, }, { header: 'Lokasi', + accessorKey: 'location', + enableSorting: true, accessorFn: (row) => row.kandang?.location?.name, }, { header: 'Kandang', + accessorKey: 'kandang', + enableSorting: true, accessorFn: (row) => row.kandang?.name, }, { @@ -492,23 +527,19 @@ const ReportExpenseTab = ({ tabId }: ReportExpenseTabProps) => { columns: [ { header: 'Qty', - id: 'qty_pengajuan', - accessorFn: (row) => row.pengajuan?.qty, + accessorKey: 'qty_pengajuan', cell: ({ row }) => row.original.pengajuan?.qty?.toLocaleString('id-ID') || '0', }, { header: 'Harga', - id: 'harga_pengajuan', - accessorFn: (row) => row.pengajuan?.price, + accessorKey: 'price_pengajuan', cell: ({ row }) => formatCurrency(row.original.pengajuan?.price || 0), }, { header: 'Total', - id: 'total_pengajuan', - accessorFn: (row) => - (row.pengajuan?.qty || 0) * (row.pengajuan?.price || 0), + accessorKey: 'total_pengajuan', cell: ({ row }) => { const total = (row.original.pengajuan?.qty || 0) * @@ -523,23 +554,19 @@ const ReportExpenseTab = ({ tabId }: ReportExpenseTabProps) => { columns: [ { header: 'Qty', - id: 'qty_realisasi', - accessorFn: (row) => row.realisasi?.qty, + accessorKey: 'qty_realisasi', cell: ({ row }) => row.original.realisasi?.qty?.toLocaleString('id-ID') || '0', }, { header: 'Harga', - id: 'harga_realisasi', - accessorFn: (row) => row.realisasi?.price, + accessorKey: 'price_realisasi', cell: ({ row }) => formatCurrency(row.original.realisasi?.price || 0), }, { header: 'Total', - id: 'total_realisasi', - accessorFn: (row) => - (row.realisasi?.qty || 0) * (row.realisasi?.price || 0), + accessorKey: 'total_realisasi', cell: ({ row }) => { const total = (row.original.realisasi?.qty || 0) * @@ -550,6 +577,7 @@ const ReportExpenseTab = ({ tabId }: ReportExpenseTabProps) => { ], }, { + id: 'realization_status', header: 'Status Pencairan', cell: (props) => ( { ), }, { + id: 'bop_status', header: 'Status BOP', cell: (props) => ( @@ -602,6 +631,9 @@ const ReportExpenseTab = ({ tabId }: ReportExpenseTabProps) => { totalItems={meta?.total_results || 0} onPageChange={setPage} onPageSizeChange={setPageSize} + sorting={sorting} + setSorting={handleSortingChange} + manualSorting className={{ containerClassName: 'w-full mb-0!', tableWrapperClassName: 'overflow-x-auto',