/ frontend / src / components / ui / DataTable.tsx
DataTable.tsx
 1  import { cn } from '@/lib/utils'
 2  
 3  interface Column<T> {
 4    key: string
 5    header: string
 6    render: (row: T) => React.ReactNode
 7    className?: string
 8  }
 9  
10  interface DataTableProps<T> {
11    columns: Column<T>[]
12    data: T[]
13    keyExtractor: (row: T) => string | number
14    emptyMessage?: string
15    className?: string
16  }
17  
18  export function DataTable<T>({
19    columns,
20    data,
21    keyExtractor,
22    emptyMessage = 'No data',
23    className,
24  }: DataTableProps<T>) {
25    return (
26      <table className={cn('w-full border-collapse text-sm', className)}>
27        <thead>
28          <tr>
29            {columns.map(col => (
30              <th
31                key={col.key}
32                className={cn(
33                  'px-4 py-3 text-left font-semibold text-xs uppercase tracking-wider text-[#8b949e] border-b border-[#30363d]',
34                  col.className,
35                )}
36              >
37                {col.header}
38              </th>
39            ))}
40          </tr>
41        </thead>
42        <tbody>
43          {data.length === 0 ? (
44            <tr>
45              <td
46                colSpan={columns.length}
47                className="px-4 py-8 text-center text-[#6e7681]"
48              >
49                {emptyMessage}
50              </td>
51            </tr>
52          ) : (
53            data.map(row => (
54              <tr
55                key={keyExtractor(row)}
56                className="border-b border-[#30363d] last:border-b-0 hover:bg-[#21262d] transition-colors"
57              >
58                {columns.map(col => (
59                  <td key={col.key} className={cn('px-4 py-3', col.className)}>
60                    {col.render(row)}
61                  </td>
62                ))}
63              </tr>
64            ))
65          )}
66        </tbody>
67      </table>
68    )
69  }