Untitled
unknown
javascript
a year ago
5.5 kB
13
Indexable
"use client"
import { useState, useEffect } from "react"
import {
type ColumnDef,
type ColumnFiltersState,
type SortingState,
type VisibilityState,
flexRender,
getCoreRowModel,
getFacetedRowModel,
getFacetedUniqueValues,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from "@tanstack/react-table"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { DataTablePagination } from "./data-table-pagination"
import { DataTableToolbar } from "./data-table-toolbar"
// Define the data type
interface User {
id: string
name: string
email: string
role: string
status: "active" | "inactive"
createdAt: string
}
// Define the props for the DataTable component
interface DataTableProps<TData, TValue> {
columns: ColumnDef<TData, TValue>[]
}
export function DataTable<TData, TValue>({ columns }: DataTableProps<TData, TValue>) {
// State for table data and loading status
const [data, setData] = useState<TData[]>([])
const [loading, setLoading] = useState(true)
const [totalRows, setTotalRows] = useState(0)
// Table state
const [sorting, setSorting] = useState<SortingState>([])
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])
const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({})
const [rowSelection, setRowSelection] = useState({})
// Pagination state
const [pagination, setPagination] = useState({
pageIndex: 0,
pageSize: 10,
})
// Global filter state
const [globalFilter, setGlobalFilter] = useState("")
// Initialize the table
const table = useReactTable({
data,
columns,
state: {
sorting,
columnFilters,
columnVisibility,
rowSelection,
pagination,
globalFilter,
},
enableRowSelection: true,
onRowSelectionChange: setRowSelection,
onSortingChange: setSorting,
onColumnFiltersChange: setColumnFilters,
onColumnVisibilityChange: setColumnVisibility,
onPaginationChange: setPagination,
onGlobalFilterChange: setGlobalFilter,
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getFacetedRowModel: getFacetedRowModel(),
getFacetedUniqueValues: getFacetedUniqueValues(),
manualPagination: true,
manualSorting: true,
manualFiltering: true,
pageCount: Math.ceil(totalRows / pagination.pageSize),
})
// Fetch data from API
useEffect(() => {
const fetchData = async () => {
setLoading(true)
try {
// Construct query parameters
const params = new URLSearchParams({
page: (pagination.pageIndex + 1).toString(),
pageSize: pagination.pageSize.toString(),
search: globalFilter,
})
// Add sorting parameters
if (sorting.length > 0) {
params.append("sortBy", sorting[0].id)
params.append("sortOrder", sorting[0].desc ? "desc" : "asc")
}
// Add filter parameters
columnFilters.forEach((filter) => {
params.append(`filter[${filter.id}]`, filter.value as string)
})
// Make the API request
const response = await fetch(`/api/users?${params.toString()}`)
const result = await response.json()
setData(result.data)
setTotalRows(result.total)
} catch (error) {
console.error("Failed to fetch data:", error)
} finally {
setLoading(false)
}
}
fetchData()
}, [pagination, sorting, columnFilters, globalFilter])
return (
<div className="space-y-4">
<DataTableToolbar table={table} />
<div className="rounded-md border">
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<TableHead key={header.id}>
{header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}
</TableHead>
))}
</TableRow>
))}
</TableHeader>
<TableBody>
{loading ? (
<TableRow>
<TableCell colSpan={columns.length} className="h-24 text-center">
Loading...
</TableCell>
</TableRow>
) : table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
<TableRow key={row.id} data-state={row.getIsSelected() && "selected"}>
{row.getVisibleCells().map((cell) => (
<TableCell key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</TableCell>
))}
</TableRow>
))
) : (
<TableRow>
<TableCell colSpan={columns.length} className="h-24 text-center">
No results.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</div>
<DataTablePagination table={table} />
</div>
)
}
Editor is loading...
Leave a Comment