'use client'; import React, { useCallback, useState, useEffect } from 'react'; import useSWR from 'swr'; import { Icon } from '@iconify/react'; import { CellContext, ColumnDef, SortingState } from '@tanstack/react-table'; import { cn } from '@/lib/helper'; import Button from '@/components/Button'; import UniformityChart from '@/components/pages/uniformity/UniformityChart'; import UniformityStat from '@/components/pages/uniformity/UniformityStat'; import { useTableFilter } from '@/services/hooks/useTableFilter'; import { UniformityApi } from '@/services/api/uniformity'; import { type Uniformity } from '@/types/api/uniformity/uniformity'; import { isResponseSuccess } from '@/lib/api-helper'; import Table from '@/components/Table'; import Badge from '@/components/Badge'; import CheckboxInput from '@/components/input/CheckboxInput'; import RowDropdownOptions from '@/components/table/RowDropdownOptions'; import RowCollapseOptions from '@/components/table/RowCollapseOptions'; import RowOptionsMenuWrapper from '@/components/table/RowOptionsMenuWrapper'; import { useModal } from '@/components/Modal'; import ConfirmationModal from '@/components/modal/ConfirmationModal'; import toast from 'react-hot-toast'; import Card from '@/components/Card'; const RowOptionsMenu = ({ type = 'dropdown', props, deleteClickHandler, }: { type: 'dropdown' | 'collapse'; props: CellContext; deleteClickHandler: () => void; }) => { return ( ); }; const UniformityTable = ({ refresh }: { refresh?: () => void }) => { const { state: tableFilterState, setPage, toQueryString: getTableFilterQueryString, } = useTableFilter({ initial: { search: '', }, paramMap: { page: 'page', pageSize: 'limit', search: 'search', }, }); const [sorting, setSorting] = useState([]); const [rowSelection, setRowSelection] = useState>({}); const [selectedUniformity, setSelectedUniformity] = useState< Uniformity | undefined >(undefined); const [isDeleteLoading, setIsDeleteLoading] = useState(false); const singleDeleteModal = useModal(); const { data: uniformities, isLoading, mutate: refreshUniformities, } = useSWR( `${UniformityApi.basePath}${getTableFilterQueryString()}`, UniformityApi.getAllFetcher ); const isUniformityLocked = useCallback((uniformity: Uniformity): boolean => { return uniformity.status === 'APPROVED' || uniformity.status === 'REJECTED'; }, []); const singleDeleteHandler = async () => { setIsDeleteLoading(true); await UniformityApi.delete(selectedUniformity?.id as number); refreshUniformities(); singleDeleteModal.closeModal(); toast.success('Successfully delete Uniformity!'); setIsDeleteLoading(false); }; useEffect(() => { if (isResponseSuccess(uniformities) && uniformities.data) { const newSelection: Record = {}; Object.entries(rowSelection).forEach(([rowId, isSelected]) => { if (isSelected) { const uniformity = uniformities.data.find( (r) => r.id === parseInt(rowId) ); if (uniformity && !isUniformityLocked(uniformity)) { newSelection[rowId] = true; } } }); if ( Object.keys(newSelection).length !== Object.keys(rowSelection).length ) { setRowSelection(newSelection); } } }, [uniformities, rowSelection, isUniformityLocked, setRowSelection]); const getStatusColor = (status: string) => { switch (status) { case 'APPROVED': return 'success'; case 'REJECTED': return 'error'; case 'CREATED': return 'info'; default: return 'info'; } }; const getStatusText = (status: string) => { switch (status) { case 'APPROVED': return 'Disetujui'; case 'REJECTED': return 'Ditolak'; case 'CREATED': return 'Pengajuan'; default: return status; } }; // ===== TABLE COLUMNS DEFINITION ===== const uniformityColumns: ColumnDef[] = [ { id: 'select', header: ({ table }) => { const allRows = table.getRowModel().rows; const selectableRows = allRows.filter((row) => { const uniformity = row.original; return !isUniformityLocked(uniformity); }); const hasNoSelectableRows = selectableRows.length === 0; const handleSelectAll = () => { const isAllSelected = selectableRows.every((row) => row.getIsSelected() ); selectableRows.forEach((row) => { row.toggleSelected(!isAllSelected); }); }; const isAllSelected = selectableRows.length > 0 && selectableRows.every((row) => row.getIsSelected()); const isSomeSelected = selectableRows.some((row) => row.getIsSelected() ); return (
); }, cell: ({ row }) => { const uniformity = row.original; const isDisabled = isUniformityLocked(uniformity); return (
); }, }, { header: 'Lokasi', cell: (props) => props.row.original.location.name || '-', }, { header: 'Flock', cell: (props) => `Flock ${props.row.original.project_flock_kandang_id}`, }, { header: 'Kandang', cell: (props) => props.row.original.kandang.name || '-', }, { header: 'Tanggal (Week)', cell: (props) => `Week ${props.row.original.week}`, }, { header: 'Status', cell: (props) => { const status = props.row.original.status; return ( {getStatusText(status)} ); }, }, { header: 'Uniformity', cell: (props) => { const uniformity = props.row.original.uniformity; return {uniformity}%; }, }, { header: 'Aksi', cell: (props: CellContext) => { const currentPageSize = props.table.getPaginationRowModel().rows.length; const currentPageRows = props.table.getPaginationRowModel().flatRows; const currentRowRelativeIndex = currentPageRows.findIndex((r) => r.id === props.row.id) + 1; const isLast2Rows = currentRowRelativeIndex > currentPageSize - 2; const deleteClickHandler = () => { setSelectedUniformity(props.row.original); singleDeleteModal.openModal(); }; return ( <> {currentPageSize > 2 && ( )} {currentPageSize <= 2 && ( )} ); }, }, ]; return ( <>
data={isResponseSuccess(uniformities) ? uniformities?.data : []} columns={uniformityColumns} pageSize={tableFilterState.pageSize} page={isResponseSuccess(uniformities) ? uniformities?.meta?.page : 0} totalItems={ isResponseSuccess(uniformities) ? uniformities?.meta?.total_results : 0 } onPageChange={setPage} isLoading={isLoading} sorting={sorting} setSorting={setSorting} rowSelection={rowSelection} setRowSelection={setRowSelection} className={{ containerClassName: cn({ 'mb-20': isResponseSuccess(uniformities) && uniformities?.data?.length === 0, }), tableWrapperClassName: 'overflow-x-auto min-h-full overflow-visible!', tableClassName: 'font-inter w-full table-auto min-h-full!', headerRowClassName: 'border-b border-b-gray-200', headerColumnClassName: 'px-6 py-3 text-xs font-semibold text-gray-500 last:flex last:flex-row last:justify-end', bodyRowClassName: 'border-b border-b-gray-200', bodyColumnClassName: 'px-6 py-3 last:flex last:flex-row last:justify-end', }} /> ); }; export default UniformityTable;