'use client'; import { useCallback, useEffect, useMemo, useState } from 'react'; import useSWR from 'swr'; import { Icon } from '@iconify/react'; import { ColumnDef, ColumnSort, SortingState } from '@tanstack/react-table'; import Button from '@/components/Button'; import Table from '@/components/Table'; import RequirePermission from '@/components/helper/RequirePermission'; import { isResponseSuccess } from '@/lib/api-helper'; import { cn, formatNumber, formatDate, formatCurrency } from '@/lib/helper'; import { InventoryAdjustmentApi } from '@/services/api/inventory'; import { useTableFilter } from '@/services/hooks/useTableFilter'; import { InventoryAdjustment } from '@/types/api/inventory/adjustment'; import StatusBadge from '@/components/helper/StatusBadge'; import InventoryAdjustmentTableSkeleton from '@/components/pages/inventory/adjustment/skeleton/InventoryAdjustmentTableSkeleton'; const InventoryAdjustmentTable = () => { const { state: tableFilterState, updateFilter, setPage, setPageSize, toQueryString: getTableFilterQueryString, } = useTableFilter({ initial: { search: '', productCategorySort: '', productSort: '', warehouseSort: '', stockSort: '', }, paramMap: { page: 'page', pageSize: 'limit', productCategorySort: 'sort_product_category', productSort: 'sort_product', warehouseSort: 'sort_warehouse', stockSort: 'sort_stock', }, }); const { data: inventoryAdjustments, isLoading } = useSWR( `${InventoryAdjustmentApi.basePath}${getTableFilterQueryString()}`, InventoryAdjustmentApi.getAllFetcher ); const [sorting, setSorting] = useState([]); const inventoryAdjustmentsColumns: ColumnDef[] = useMemo( () => [ { id: 'adj_number', header: 'No. Referensi', accessorFn: (row) => row.adj_number ?? '-', }, { id: 'location', header: 'Lokasi', accessorFn: (row) => row.location?.name ?? '-', }, { id: 'project_flock', header: 'Flock', accessorFn: (row) => row.project_flock?.flock_name ?? '-', }, { id: 'warehouse_name', header: 'Gudang', accessorFn: (row) => row.product_warehouse?.warehouse?.name ?? '-', }, { id: 'product_name', header: 'Nama Produk', accessorFn: (row) => row.product_warehouse?.product?.name ?? '-', }, { id: 'quantity', header: 'Kuantitas', accessorFn: (row) => row.qty ?? '-', cell: (row) => { const value = row.row.original.increase + row.row.original.decrease; return
{formatNumber(value)}
; }, }, { id: 'price', header: 'Harga', accessorFn: (row) => (row.price ? formatCurrency(row.price) : '-'), }, { id: 'grand_total', header: 'Grand Total', accessorFn: (row) => row.grand_total ? formatCurrency(row.grand_total) : '-', }, { id: 'transaction_type', header: 'Tipe Transaksi', accessorFn: (row) => row.transaction_subtype ?? '-', cell: (row) => { const subtype = row.row.original.transaction_subtype; const increase = row.row.original.increase; const subtypeLabelMap: Record = { PURCHASE_IN: 'Pembelian', MARKETING_OUT: 'Penjualan', RECORDING_STOCK_OUT: 'Recording Stock', RECORDING_DEPLETION_OUT: 'Recording Depletion', RECORDING_EGG_IN: 'Recording Egg', ADJUSTMENT_OUT: 'Penyesuaian', }; const label = subtypeLabelMap[subtype] || subtype || '-'; return ( 0 ? 'success' : increase <= 0 ? 'error' : 'neutral' } text={label} className={{ badge: 'whitespace-nowrap', }} /> ); }, }, { id: 'created_at', header: 'Tanggal', accessorFn: (row) => row.created_at ? formatDate(row.created_at, 'DD MMM YYYY') : '-', }, { id: 'created_by', header: 'Oleh', accessorFn: (row) => row.created_user?.name ?? '-', }, ], [tableFilterState.pageSize, tableFilterState.page] ); const updateSortingFilter = useCallback( ( sortName: Exclude, sortFilter: ColumnSort | undefined ) => { if (!sortFilter) { updateFilter(sortName, ''); } else { updateFilter(sortName, sortFilter.desc ? 'desc' : 'asc'); } }, [updateFilter] ); useEffect(() => { const productCategorySortFilter = sorting.find( (sortItem) => sortItem.id === 'productCategory' ); const productSortFilter = sorting.find( (sortItem) => sortItem.id === 'product' ); const warehouseSortFilter = sorting.find( (sortItem) => sortItem.id === 'warehouse' ); const stockSortFilter = sorting.find((sortItem) => sortItem.id === 'stock'); updateSortingFilter('productCategorySort', productCategorySortFilter); updateSortingFilter('productSort', productSortFilter); updateSortingFilter('warehouseSort', warehouseSortFilter); updateSortingFilter('stockSort', stockSortFilter); }, [sorting, updateSortingFilter]); return (
{/* Header Section */}
{/* Table Section */}
{isLoading ? (
) : !isResponseSuccess(inventoryAdjustments) || inventoryAdjustments.data?.length === 0 ? (
} />
) : ( data={ isResponseSuccess(inventoryAdjustments) ? inventoryAdjustments?.data : [] } columns={inventoryAdjustmentsColumns} pageSize={tableFilterState.pageSize} page={ isResponseSuccess(inventoryAdjustments) ? inventoryAdjustments?.meta?.page : 0 } totalItems={ isResponseSuccess(inventoryAdjustments) ? inventoryAdjustments?.meta?.total_results : 0 } onPageChange={setPage} onPageSizeChange={setPageSize} isLoading={isLoading} sorting={sorting} setSorting={setSorting} className={{ containerClassName: cn('p-3 mb-0'), headerColumnClassName: 'text-nowrap', }} /> )}
); }; export default InventoryAdjustmentTable;