File size: 1,926 Bytes
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 65 66 67 68 |
import React, { useState } from 'react';
import Pagination from './Pagination';
type TableProps<T> = {
data: T[];
columns: {
key: keyof T;
label: string;
render?: (value: T[keyof T]) => React.ReactNode;
}[];
orderBy?: keyof T;
onOrderByChange?: (key: keyof T) => void;
pageSize?: number;
};
export default function Table<T>({ data, columns, orderBy, onOrderByChange, pageSize = 100 }: TableProps<T>) {
const [currentPage, setCurrentPage] = useState(1);
const totalPages = Math.ceil(data.length / pageSize);
const paginatedData = data.slice(
(currentPage - 1) * pageSize,
currentPage * pageSize
);
const handlePageChange = (page: number) => {
setCurrentPage(page);
};
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]) : String(item[column.key])}
</td>
))}
</tr>
))}
</tbody>
</table>
<Pagination
currentPage={currentPage}
totalPages={totalPages}
onPageChange={handlePageChange}
/>
</>
);
}
|