|
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} |
|
/> |
|
</> |
|
); |
|
} |
|
|