File size: 1,879 Bytes
afa132e c524dfb afa132e c524dfb afa132e c524dfb afa132e c524dfb afa132e c524dfb afa132e c524dfb |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
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}
/>
</>
);
}
|