import type { ReactNode } from "react"; import { Pagination } from "@/components/admin/Pagination"; interface ColumnDef { id: string; header: string; accessorKey?: keyof T & string; accessorFn?: (row: T) => ReactNode; cell?: (props: { row: T; value: ReactNode }) => ReactNode; className?: string; sortable?: boolean; size?: string; } interface DataTableProps { data: T[]; columns: ColumnDef[]; isLoading?: boolean; emptyMessage?: string; keyExtractor: (row: T) => string | number; page?: number; totalPages?: number; onPageChange?: (p: number) => void; sortColumn?: string; sortDirection?: "asc" | "desc"; onSort?: (column: string) => void; actions?: (row: T) => ReactNode; classNames?: { wrapper?: string; table?: string; thead?: string; th?: string; tbody?: string; td?: string; }; } function DataTableInner({ data, columns, isLoading, emptyMessage = "No data.", keyExtractor, page, totalPages, onPageChange, sortColumn, sortDirection, onSort, actions, classNames = {}, }: DataTableProps) { const cn = { wrapper: classNames.wrapper ?? "bg-[var(--pure-white)] rounded-[var(--radius-xl)] border border-[var(--oat-border)] overflow-hidden", table: classNames.table ?? "w-full text-sm", thead: classNames.thead ?? "bg-[var(--oat-light)] text-[var(--warm-charcoal)]", th: classNames.th ?? "text-left px-4 py-3 font-medium", tbody: classNames.tbody ?? "", td: classNames.td ?? "px-4 py-3", }; const colCount = columns.length + (actions ? 1 : 0); function renderCell(row: T, col: ColumnDef): ReactNode { let value: ReactNode; if (col.accessorKey !== undefined) { value = row[col.accessorKey] as ReactNode; } else if (col.accessorFn) { value = col.accessorFn(row); } else { value = null; } if (col.cell) { return col.cell({ row, value }); } return value; } return (
{columns.map((col) => ( ))} {actions && } {isLoading ? ( ) : data.length === 0 ? ( ) : ( data.map((row) => ( {columns.map((col) => ( ))} {actions && ( )} )) )}
onSort?.(col.id) : undefined} aria-sort={ sortColumn === col.id ? sortDirection === "asc" ? "ascending" : "descending" : undefined } > {col.header} {col.sortable && sortColumn === col.id && ( {sortDirection === "asc" ? "\u25B2" : "\u25BC"} )} Actions
Loading...
{emptyMessage}
{renderCell(row, col)} {actions(row)}
{page !== undefined && totalPages !== undefined && onPageChange && ( )}
); } export { DataTableInner as DataTable }; export type { ColumnDef, DataTableProps };