Spaces:
Sleeping
Sleeping
import React from 'react'; | |
import Pagination from './Pagination'; | |
type TableProps<T> = { | |
data: T[]; | |
columns: { | |
key: keyof T; | |
label: string; | |
render?: (value: T[keyof T], row: T) => React.ReactNode; | |
}[]; | |
orderBy?: keyof T; | |
onOrderByChange?: (key: keyof T) => void; | |
pageSize?: number; | |
currentPage: number; | |
onPageChange: (page: number) => void; | |
}; | |
export default function Table<T>({ data, columns, orderBy, onOrderByChange, pageSize = 100, currentPage, onPageChange }: TableProps<T>) { | |
const totalPages = Math.ceil(data.length / pageSize); | |
const paginatedData = data.slice( | |
(currentPage - 1) * pageSize, | |
currentPage * pageSize | |
); | |
return ( | |
<> | |
<table className="table-auto border-collapse w-full"> | |
<thead> | |
<tr> | |
{columns.map((column) => ( | |
<th | |
key={column.key as string} | |
className={`px-4 py-2 bg-gray-100 dark:bg-gray-800 text-left ${ | |
onOrderByChange ? 'cursor-pointer' : '' | |
}`} | |
onClick={() => onOrderByChange && onOrderByChange(column.key)} | |
> | |
{column.label} {orderBy === column.key && '▼'} | |
</th> | |
))} | |
</tr> | |
</thead> | |
<tbody> | |
{paginatedData.map((item, index) => ( | |
<tr key={index} className="border-t border-gray-200 dark:border-gray-700"> | |
{columns.map((column) => ( | |
<td key={column.key as string} className="px-4 py-2"> | |
{column.render ? column.render(item[column.key], item) : String(item[column.key])} | |
</td> | |
))} | |
</tr> | |
))} | |
</tbody> | |
</table> | |
<Pagination | |
currentPage={currentPage} | |
totalPages={totalPages} | |
onPageChange={onPageChange} | |
/> | |
</> | |
); | |
} | |