import { useState } from "react"; import { ColumnDef, flexRender, getCoreRowModel, getPaginationRowModel, useReactTable, SortingState, getSortedRowModel, ColumnFiltersState, getFilteredRowModel, } from "@tanstack/react-table"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, } from "@/components/ui/pagination"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { Search } from "lucide-react"; interface DataTableProps { columns: ColumnDef[]; data: TData[]; searchKey?: string; searchPlaceholder?: string; } export function DataTable({ columns, data, searchKey, searchPlaceholder = "Search...", }: DataTableProps) { const [sorting, setSorting] = useState([]); const [columnFilters, setColumnFilters] = useState([]); const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 5, }); const table = useReactTable({ data, columns, getCoreRowModel: getCoreRowModel(), getPaginationRowModel: getPaginationRowModel(), onPaginationChange: setPagination, state: { sorting, columnFilters, pagination, }, onSortingChange: setSorting, onColumnFiltersChange: setColumnFilters, getSortedRowModel: getSortedRowModel(), getFilteredRowModel: getFilteredRowModel(), }); return (
{searchKey && (
table.getColumn(searchKey)?.setFilterValue(event.target.value) } className="max-w-sm pl-10" />
)}
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( {header.isPlaceholder ? null : flexRender( header.column.columnDef.header, header.getContext() )} ); })} ))} {table.getRowModel().rows?.length ? ( table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => ( {flexRender( cell.column.columnDef.cell, cell.getContext() )} ))} )) ) : ( No results found. )}
{/* Pagination */}
{table.getFilteredRowModel().rows.length > 0 && (
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}{" "} results
)}
table.previousPage()} disabled={!table.getCanPreviousPage()} className={!table.getCanPreviousPage() ? "opacity-50 cursor-not-allowed" : ""} /> {/* Page numbers */} {Array.from( { length: Math.min(5, table.getPageCount()) }, (_, i) => { const pageIndex = i; const isCurrentPage = pageIndex === table.getState().pagination.pageIndex; if (table.getPageCount() > 5 && pageIndex === 3) { return ( ); } else if (table.getPageCount() > 5 && pageIndex === 4) { const lastPageIndex = table.getPageCount() - 1; return ( table.setPageIndex(lastPageIndex)} isActive={lastPageIndex === table.getState().pagination.pageIndex} > {lastPageIndex + 1} ); } else { return ( table.setPageIndex(pageIndex)} isActive={isCurrentPage} > {pageIndex + 1} ); } } )} table.nextPage()} disabled={!table.getCanNextPage()} className={!table.getCanNextPage() ? "opacity-50 cursor-not-allowed" : ""} />
); }