diff --git a/src/components/pages/expense/ExpensesTable.tsx b/src/components/pages/expense/ExpensesTable.tsx index 9df40afc..6ce84900 100644 --- a/src/components/pages/expense/ExpensesTable.tsx +++ b/src/components/pages/expense/ExpensesTable.tsx @@ -1,18 +1,13 @@ 'use client'; -import { - ChangeEventHandler, - useCallback, - useEffect, - useMemo, - useState, -} from 'react'; +import { ChangeEventHandler, useCallback, useMemo, useState } from 'react'; import useSWR from 'swr'; import { CellContext, ColumnDef, Row, SortingState, + Updater, } from '@tanstack/react-table'; import toast from 'react-hot-toast'; @@ -47,7 +42,8 @@ import { BaseApiResponse } from '@/types/api/api-general'; type ExpenseTableFilters = { search: string; - nameSort: string; + sort_by: string; + order_by: string; transactionDate: string; realizationDate: string; locationId: string; @@ -242,7 +238,8 @@ const ExpensesTable = () => { page: 1, pageSize: 10, search: '', - nameSort: '', + sort_by: '', + order_by: '', transactionDate: '', realizationDate: '', locationId: '', @@ -261,7 +258,8 @@ const ExpensesTable = () => { paramMap: { page: 'page', pageSize: 'limit', - nameSort: 'sort_name', + sort_by: 'sort_by', + order_by: 'sort_order', transactionDate: 'transaction_date', realizationDate: 'realization_date', locationId: 'location_id', @@ -319,7 +317,26 @@ const ExpensesTable = () => { const [exportProgressStartDate, setExportProgressStartDate] = useState(''); const [exportProgressEndDate, setExportProgressEndDate] = useState(''); - const [sorting, setSorting] = useState([]); + const sorting: SortingState = tableFilterState.sort_by + ? [ + { + id: tableFilterState.sort_by, + desc: tableFilterState.order_by === 'desc', + }, + ] + : []; + + const handleSortingChange = (updater: Updater) => { + const next = typeof updater === 'function' ? updater(sorting) : updater; + if (next.length > 0) { + updateFilter('sort_by', next[0].id, true); + updateFilter('order_by', next[0].desc ? 'desc' : 'asc', true); + } else { + updateFilter('sort_by', '', true); + updateFilter('order_by', '', true); + } + }; + const [rowSelection, setRowSelection] = useState>({}); const selectedRowIds = Object.keys(rowSelection).map((item) => parseInt(item) @@ -437,10 +454,12 @@ const ExpensesTable = () => { cell: (props) => props.row.original.location?.name ?? '-', }, { + accessorKey: 'created_user', accessorFn: (row) => row.created_user.name ?? '-', header: 'Nama Pengaju', }, { + accessorKey: 'supplier', accessorFn: (row) => row.supplier.name ?? '-', header: 'Uraian', }, @@ -454,17 +473,20 @@ const ExpensesTable = () => { }, { header: 'Status Pencairan', + enableSorting: false, cell: (props) => ( ), }, { header: 'Status BOP', + enableSorting: false, cell: (props) => ( ), }, { + accessorKey: 'is_paid', header: 'Status Lunas', cell: (props) => { return ( @@ -478,6 +500,14 @@ const ExpensesTable = () => { ); }, }, + { + accessorKey: 'created_at', + header: 'Tanggal Dibuat', + cell: (props) => + props.row.original.created_at + ? formatDate(props.row.original.created_at, 'DD MMM YYYY') + : '-', + }, { header: 'Aksi', cell: (props) => { @@ -882,17 +912,6 @@ const ExpensesTable = () => { } }, [getTableFilterQueryString]); - // track sorting - useEffect(() => { - const isNameSorted = sorting.find((sortItem) => sortItem.id === 'name'); - - if (!isNameSorted) { - updateFilter('nameSort', '', false); - } else { - updateFilter('nameSort', isNameSorted.desc ? 'desc' : 'asc'); - } - }, [sorting, updateFilter]); - return ( <>
@@ -1051,7 +1070,8 @@ const ExpensesTable = () => { 'page', 'pageSize', 'search', - 'nameSort', + 'sort_by', + 'order_by', 'userId', 'locationName', 'vendorName', @@ -1152,7 +1172,8 @@ const ExpensesTable = () => { onPageSizeChange={setPageSize} isLoading={isLoading} sorting={sorting} - setSorting={setSorting} + setSorting={handleSortingChange} + manualSorting rowSelection={rowSelection} setRowSelection={setRowSelection} enableRowSelection={tableEnableRowSelectionHandler} diff --git a/src/components/pages/purchase/PurchaseTable.tsx b/src/components/pages/purchase/PurchaseTable.tsx index 781fb2cf..b5d1a1f6 100644 --- a/src/components/pages/purchase/PurchaseTable.tsx +++ b/src/components/pages/purchase/PurchaseTable.tsx @@ -2,7 +2,12 @@ import { ChangeEventHandler, useCallback, useMemo, useState } from 'react'; import useSWR from 'swr'; -import { CellContext, ColumnDef, SortingState } from '@tanstack/react-table'; +import { + CellContext, + ColumnDef, + SortingState, + Updater, +} from '@tanstack/react-table'; import toast from 'react-hot-toast'; import Link from 'next/link'; @@ -34,6 +39,8 @@ import { PURCHASE_ORDER_APPROVAL_LINE } from '@/config/approval-line'; type PurchaseTableFilters = { search: string; + sort_by: string; + order_by: string; po_date: string; approval_status: string; product_category_id: string; @@ -157,18 +164,6 @@ const RowOptionsMenu = ({ }; const PurchaseTable = () => { - // ===== STATE MANAGEMENT ===== - const [isDeleteLoading, setIsDeleteLoading] = useState(false); - const [isLoadingExportingToExcel, setIsLoadingExportingToExcel] = - useState(false); - const [isExportProgressLoading, setIsExportProgressLoading] = useState(false); - const [selectedPurchase, setSelectedPurchase] = useState( - null - ); - const [exportProgressStartDate, setExportProgressStartDate] = useState(''); - const [exportProgressEndDate, setExportProgressEndDate] = useState(''); - const [sorting, setSorting] = useState([]); - // ===== TABLE FILTER STATE ===== const { state: tableFilterState, @@ -180,6 +175,8 @@ const PurchaseTable = () => { } = useTableFilter({ initial: { search: '', + sort_by: '', + order_by: '', po_date: '', approval_status: '', product_category_id: '', @@ -198,6 +195,8 @@ const PurchaseTable = () => { paramMap: { page: 'page', pageSize: 'limit', + sort_by: 'sort_by', + order_by: 'sort_order', po_date: 'po_date', approval_status: 'approval_status', product_category_id: 'product_category_id', @@ -219,6 +218,36 @@ const PurchaseTable = () => { storeName: 'purchase-table', }); + // ===== STATE MANAGEMENT ===== + const [isDeleteLoading, setIsDeleteLoading] = useState(false); + const [isLoadingExportingToExcel, setIsLoadingExportingToExcel] = + useState(false); + const [isExportProgressLoading, setIsExportProgressLoading] = useState(false); + const [selectedPurchase, setSelectedPurchase] = useState( + null + ); + const [exportProgressStartDate, setExportProgressStartDate] = useState(''); + const [exportProgressEndDate, setExportProgressEndDate] = useState(''); + const sorting: SortingState = tableFilterState.sort_by + ? [ + { + id: tableFilterState.sort_by, + desc: tableFilterState.order_by === 'desc', + }, + ] + : []; + + const handleSortingChange = (updater: Updater) => { + const next = typeof updater === 'function' ? updater(sorting) : updater; + if (next.length > 0) { + updateFilter('sort_by', next[0].id, true); + updateFilter('order_by', next[0].desc ? 'desc' : 'asc', true); + } else { + updateFilter('sort_by', '', true); + updateFilter('order_by', '', true); + } + }; + // ===== MODAL HOOKS ===== const filterModal = useModal(); const deleteModal = useModal(); @@ -238,6 +267,7 @@ const PurchaseTable = () => { const purchaseColumns: ColumnDef[] = [ { header: 'No. PR/PO', + enableSorting: false, cell: (props) => { const { pr_number, po_number } = props.row.original; return po_number ? po_number : pr_number; @@ -278,7 +308,7 @@ const PurchaseTable = () => { cell: (props) => props.row.original.requester_name || '-', }, { - accessorKey: 'products.name', + accessorKey: 'products', header: 'Produk', cell: (props) => { const products = props.row.original.products; @@ -293,7 +323,7 @@ const PurchaseTable = () => { }, }, { - accessorKey: 'location.name', + accessorKey: 'location', header: 'Lokasi', cell: (props) => props.row.original.location?.name || '-', }, @@ -323,6 +353,7 @@ const PurchaseTable = () => { }, { header: 'Aging', + enableSorting: false, cell: (props) => { const purchase = props.row.original; if (!purchase.po_date) return '-'; @@ -334,6 +365,7 @@ const PurchaseTable = () => { }, }, { + accessorKey: 'status', header: 'Status Approval', cell: (props) => { const approval = props.row.original.latest_approval; @@ -378,6 +410,14 @@ const PurchaseTable = () => { ); }, }, + { + accessorKey: 'created_at', + header: 'Tanggal Dibuat', + cell: (props) => + props.row.original.created_at + ? formatDate(props.row.original.created_at, 'DD MMM YYYY') + : '-', + }, { header: 'Aksi', cell: (props) => { @@ -658,6 +698,7 @@ const PurchaseTable = () => { 'search', 'filter_by', 'sort_by', + 'order_by', 'product_category_name', 'supplier_name', 'area_name', @@ -771,7 +812,8 @@ const PurchaseTable = () => { onPageSizeChange={setPageSize} isLoading={isLoading} sorting={sorting} - setSorting={setSorting} + setSorting={handleSortingChange} + manualSorting className={{ containerClassName: cn('p-3 mb-0'), headerColumnClassName: 'text-nowrap',