feat: separate DataTable component

This commit is contained in:
Hafid Nur
2025-03-28 18:17:13 +07:00
parent fd9113109c
commit 79e0d39280
5 changed files with 43 additions and 138 deletions
+2 -71
View File
@@ -1,6 +1,6 @@
import * as React from 'react';
import { FC, ReactElement, useState } from 'react';
import { FC, ReactElement } from 'react';
import {
FilterOutlined,
SearchOutlined,
@@ -9,7 +9,6 @@ import {
ArrowLeftOutlined,
} from '@ant-design/icons';
import { Button, Input } from '@imphnen-frontend-service/ui/atoms';
import { Pagination } from '@imphnen-frontend-service/ui/molecules';
import { DataTable } from '@imphnen-frontend-service/ui/organisms';
import {
@@ -130,75 +129,7 @@ export const Components: FC = (): ReactElement => {
</div>
{/* Table */}
<div className="w-full overflow-x-auto">
<table className="w-full min-w-full text-base">
<thead className="bg-primary-50 mb-3 text-left">
{table.getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<th
key={header.id}
className="py-3 px-5 font-normal first:rounded-l-lg last:rounded-r-lg"
>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
)}
</th>
))}
</tr>
))}
</thead>
<tbody className="mt-3">
{table.getRowModel().rows.map((row) => (
<tr key={row.id} className="bg-primary-100 odd:bg-white">
{row.getVisibleCells().map((cell, index) => (
<td
key={index}
className="py-3 px-5 first:rounded-l-lg last:rounded-r-lg"
>
{flexRender(
cell.column.columnDef.cell,
cell.getContext()
)}
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
{/* <DataTable
data={currentItems}
headers={[
{
label: 'No.',
render: (_, index) => index + 1 + indexOfFirstItem,
},
{ label: 'Nama Lengkap', key: 'name' },
{ label: 'Email', key: 'email' },
{ label: 'Nomor Telp', key: 'phone' },
{ label: 'Alamat Pengiriman', key: 'address' },
{
label: 'Action',
render: (item: Account) => (
<Button
variant="primary"
size="sm"
onClick={(e) => {
e.stopPropagation();
handleEdit(item.id);
}}
className="flex items-center gap-2"
>
<EditOutlined /> Edit
</Button>
),
},
]}
/> */}
<DataTable data={mockData} columns={columns} />
{/* Pagination */}
{/* <Pagination
-1
View File
@@ -1,2 +1 @@
export * from './input-form';
export * from './pagination';
+1 -1
View File
@@ -1 +1 @@
export * from './pagination';
export {};
@@ -12,12 +12,8 @@ export const Pagination: FC<PaginationProps> = ({
totalPages,
onPageChange,
}): ReactElement => {
// Generate page numbers to display
const getPageNumbers = () => {
const pages = [];
// const maxPagesToShow = 5;
// Always show first page
if (currentPage > 3) {
pages.push(1);
if (currentPage > 4) {
@@ -25,7 +21,6 @@ export const Pagination: FC<PaginationProps> = ({
}
}
// Calculate range of pages to show around current page
const startPage = Math.max(1, currentPage - 1);
const endPage = Math.min(totalPages, currentPage + 1);
@@ -33,7 +28,6 @@ export const Pagination: FC<PaginationProps> = ({
pages.push(i);
}
// Always show last page
if (currentPage < totalPages - 2) {
if (currentPage < totalPages - 3) {
pages.push('...');
+40 -59
View File
@@ -1,52 +1,57 @@
import { ReactElement, ReactNode } from 'react';
import {
PaginationState,
useReactTable,
getCoreRowModel,
getPaginationRowModel,
getFilteredRowModel,
flexRender,
ColumnDef,
} from '@tanstack/react-table';
import React from 'react';
interface DataTableProps<T> {
data: T[];
headers: {
accessorKey?: keyof T;
header: string;
cell?: (info: any) => ReactNode;
}[];
onRowClick?: (item: T) => void;
columns: ColumnDef<T>[];
pageSize?: number;
}
export const DataTable = <T extends Record<string, any>>({
export const DataTable = <T,>({
data,
headers,
onRowClick,
}: DataTableProps<T>): ReactElement => {
columns,
pageSize = 9,
}: DataTableProps<T>) => {
const [pagination, setPagination] = React.useState<PaginationState>({
pageIndex: 0,
pageSize,
});
const table = useReactTable({
data,
columns: headers.map((header) => ({
accessorKey: header.accessorKey,
header: header.header,
cell: header.cell,
})),
columns,
state: {
pagination,
},
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getFilteredRowModel: getFilteredRowModel(),
onPaginationChange: setPagination,
});
return (
<div className="w-full overflow-x-auto">
<table className="w-full min-w-full text-base">
<thead className="bg-primary-50 mb-3">
<thead className="bg-primary-50 mb-3 text-left">
{table.getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<th key={header.id}>
{header.isPlaceholder ? null : (
<div>
{typeof header.column.columnDef.header === 'function'
? header.column.columnDef.header(header.getContext())
: header.column.columnDef.header}
</div>
)}
<th
key={header.id}
className="py-3 px-5 font-normal first:rounded-l-lg last:rounded-r-lg"
>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
)}
</th>
))}
</tr>
@@ -54,43 +59,19 @@ export const DataTable = <T extends Record<string, any>>({
</thead>
<tbody className="mt-3">
{table.getRowModel().rows.map((row) => (
<tr
key={row.id}
onClick={() => onRowClick && onRowClick(row.original)}
>
{row.getVisibleCells().map((cell) => (
<td key={cell.id}>{cell.getValue() as ReactNode}</td>
<tr key={row.id} className="bg-primary-100 odd:bg-white">
{row.getVisibleCells().map((cell, index) => (
<td
key={cell.id}
className="py-3 px-5 first:rounded-l-lg last:rounded-r-lg"
>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</td>
))}
</tr>
))}
</tbody>
</table>
<div>
<button
onClick={() => table.setPageIndex(0)}
disabled={!table.getCanPreviousPage()}
>
{'<<'}
</button>
<button
onClick={() => table.previousPage()}
disabled={!table.getCanPreviousPage()}
>
{'<'}
</button>
<button
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
>
{'>'}
</button>
<button
onClick={() => table.setPageIndex(table.getPageCount() - 1)}
disabled={!table.getCanNextPage()}
>
{'>>'}
</button>
</div>
</div>
);
};