"use client"; import React from "react"; import { ColumnDef, SortingState, flexRender, getCoreRowModel, useReactTable, getSortedRowModel, getPaginationRowModel, } from "@tanstack/react-table"; import { Table, TableBody, TableCell, TableRow } from "@/components/ui/table"; import { Skeleton } from "@/components/ui/skeleton"; import { Button } from "@/components/ui/button"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; import { Edit2, Trash2 } from "lucide-react"; import TopHeader from "./Header"; import TableHeader from "./TableHeader"; import { TableFooter } from "./Footer"; import { cn } from "@/lib/utils"; export interface DataTableProps { columns: ColumnDef[]; data: TData[]; title?: string; onAddNew?: () => void; addButtonText?: string; isLoading?: boolean; onEdit?: (item: TData) => void; onDelete?: (item: TData) => void; pagination?: { skip: number; limit: number; totalItems?: number; onPageChange: (newSkip: number) => void; onLimitChange: (newLimit: number) => void; }; } export function DataTable({ columns: initialColumns, data, title, onAddNew, addButtonText, isLoading = false, onEdit, onDelete, pagination, }: DataTableProps) { const [rowSelection, setRowSelection] = React.useState({}); const [sorting, setSorting] = React.useState([]); const columns = React.useMemo(() => { const cols = [...initialColumns]; if (onEdit || onDelete) { cols.push({ id: "actions", header: () =>
Actions
, cell: ({ row }) => { const item = row.original; return (
{onEdit && ( )} {onDelete && ( )}
); }, }); } return cols; }, [initialColumns, onEdit, onDelete]); const table = useReactTable({ data, columns, getCoreRowModel: getCoreRowModel(), onRowSelectionChange: setRowSelection, onSortingChange: setSorting, getSortedRowModel: getSortedRowModel(), getPaginationRowModel: getPaginationRowModel(), manualPagination: !!pagination, pageCount: pagination?.totalItems ? Math.ceil(pagination.totalItems / pagination.limit) : -1, state: { rowSelection, sorting, pagination: pagination ? { pageIndex: Math.floor(pagination.skip / pagination.limit), pageSize: pagination.limit, } : undefined, }, onPaginationChange: (updater) => { if (typeof updater === 'function' && pagination) { const newState = updater({ pageIndex: Math.floor(pagination.skip / pagination.limit), pageSize: pagination.limit, }); pagination.onLimitChange(newState.pageSize); pagination.onPageChange(newState.pageIndex * newState.pageSize); } }, initialState: { pagination: { pageSize: 10, pageIndex: 0, }, }, }); return (
{isLoading ? ( Array.from({ length: 5 }).map((_, idx) => ( {columns.map((_, colIdx) => ( ))} )) ) : table.getRowModel().rows?.length ? ( table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => ( {flexRender( cell.column.columnDef.cell, cell.getContext() )} ))} )) ) : ( No results found. )}
); }