1import {
2 ColumnDef,
3 flexRender,
4} from "@tanstack/react-table";
5import {
6 Table,
7 TableBody,
8 TableCell,
9 TableHead,
10 TableHeader,
11 TableRow,
12 Skeleton
13} from "@marzneshin/components";
14import { useTranslation } from "react-i18next";
15import { useEntityTableContext } from "@marzneshin/features/entity-table/contexts";
16import { type FC } from "react";
17
18interface DataTableProps<TData, TValue> {
19 columns: ColumnDef<TData, TValue>[]
20 onRowClick?: (object: TData) => void
21}
22
23const Headers = () => {
24 const { table } = useEntityTableContext();
25 return (
26 table.getHeaderGroups().map(headerGroup => (
27 <TableRow key={headerGroup.id}>
28 {headerGroup.headers.map(header => (
29 <TableHead key={header.id}>
30 {!header.isPlaceholder && flexRender(header.column.columnDef.header, header.getContext())}
31 </TableHead>
32 ))}
33 </TableRow>
34 ))
35 )
36};
37
38const Rows: FC<Readonly<DataTableProps<any, any>>> = ({
39 columns,
40 onRowClick
41}) => {
42 const { table } = useEntityTableContext();
43 const { t } = useTranslation();
44
45 return (table.getRowModel().rows.length ? (
46 table.getRowModel().rows.map(row => (
47 <TableRow
48 key={row.id}
49 data-state={row.getIsSelected() ? "selected" : undefined}
50 data-testid="entity-table-row"
51 onClick={() => onRowClick?.(row.original)}
52 >
53 {row.getVisibleCells().map(cell => (
54 <TableCell key={cell.id}>
55 {flexRender(cell.column.columnDef.cell, cell.getContext())}
56 </TableCell>
57 ))}
58 </TableRow>
59 ))
60 ) : (
61 <TableRow>
62 <TableCell colSpan={columns.length} className="h-24 text-center">
63 {t('table.no-result')}
64 </TableCell>
65 </TableRow>
66 ))
67};
68
69export function EntityDataTable<TData, TValue>({
70 columns,
71 onRowClick,
72}: Readonly<DataTableProps<TData, TValue>>) {
73 const { isLoading } = useEntityTableContext();
74
75 const Loading = () => (
76 <>
77 {Array.from({ length: 5 }).map((_, rowIndex) => (
78 <TableRow key={`skeleton-row-${rowIndex}`} className="w-full">
79 {columns.map((column, cellIndex) => (
80 <TableCell key={`${column.cell}-skeleton-cell-${rowIndex}-${cellIndex}`} className="h-12">
81 <Skeleton className="w-full h-full" />
82 </TableCell>
83 ))}
84 </TableRow>
85 ))}
86 </>
87 );
88
89 return (
90 <Table className="w-full">
91 <TableHeader> <Headers /> </TableHeader>
92 <TableBody>
93 {isLoading ? <Loading /> : <Rows onRowClick={onRowClick} columns={columns} />}
94 </TableBody>
95 </Table>
96 );
97}