"use client" import { useState } from "react" import { type ColumnDef, flexRender, getCoreRowModel, useReactTable, getSortedRowModel, type SortingState, getFilteredRowModel, type ColumnFiltersState, getPaginationRowModel, } from "@tanstack/react-table" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger } from "@/components/ui/dropdown-menu" import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight, Filter } from "lucide-react" import { Skeleton } from "@/components/ui/skeleton" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" interface DataTableProps { columns: ColumnDef[] data: TData[] loading?: boolean onRowClick?: (row: TData) => void pageSize?: number } export function DataTable({ columns, data, loading = false, onRowClick, pageSize = 5, }: DataTableProps) { const [sorting, setSorting] = useState([]) const [columnFilters, setColumnFilters] = useState([]) const [columnVisibility, setColumnVisibility] = useState({}) const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: pageSize, }) const table = useReactTable({ data, columns, getCoreRowModel: getCoreRowModel(), onSortingChange: setSorting, getSortedRowModel: getSortedRowModel(), onColumnFiltersChange: setColumnFilters, getFilteredRowModel: getFilteredRowModel(), onColumnVisibilityChange: setColumnVisibility, getPaginationRowModel: getPaginationRowModel(), onPaginationChange: setPagination, state: { sorting, columnFilters, columnVisibility, pagination, }, }) if (loading) { return (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())} ))} ))} {Array.from({ length: pagination.pageSize }).map((_, index) => ( {columns.map((_, colIndex) => ( ))} ))}
) } return (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( {header.isPlaceholder ? null : (
{flexRender(header.column.columnDef.header, header.getContext())} {{ asc: " 🔼", desc: " 🔽", }[header.column.getIsSorted() as string] ?? null}
{header.column.getCanFilter() && (
header.column.setFilterValue(e.target.value)} className="h-8" />
)}
)}
))}
))}
{table.getRowModel().rows?.length ? ( table.getRowModel().rows.map((row) => ( onRowClick && onRowClick(row.original)} > {row.getVisibleCells().map((cell) => ( {flexRender(cell.column.columnDef.cell, cell.getContext())} ))} )) ) : ( No results. )}
{/* Pagination Controls */}
Showing {table.getState().pagination.pageIndex * table.getState().pagination.pageSize + 1} to{" "} {Math.min( (table.getState().pagination.pageIndex + 1) * table.getState().pagination.pageSize, table.getFilteredRowModel().rows.length, )}{" "} of {table.getFilteredRowModel().rows.length} entries

Rows per page

Page {table.getState().pagination.pageIndex + 1} of {table.getPageCount()}
) }