-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDataTable.tsx
More file actions
69 lines (66 loc) · 2.02 KB
/
Copy pathDataTable.tsx
File metadata and controls
69 lines (66 loc) · 2.02 KB
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
69
import { StatusBadge } from './StatusBadge';
export interface Column<T> {
key: keyof T | string;
label: string;
render?: (row: T) => React.ReactNode;
isStatus?: boolean;
}
export function DataTable<T extends { id: string }>({
columns,
rows,
loading,
error,
emptyLabel = 'No records yet.',
}: {
columns: Column<T>[];
rows: T[];
loading: boolean;
error: string | null;
emptyLabel?: string;
}) {
if (loading) {
return <div className="p-8 text-center text-ink-soft text-sm">Loading…</div>;
}
if (error) {
return (
<div className="p-8 text-center text-sm text-red-700 bg-red-50 rounded-xl border border-red-100">
Could not load data: {error}
</div>
);
}
if (rows.length === 0) {
return <div className="p-10 text-center text-ink-soft text-sm bg-white rounded-xl border border-ink/5">{emptyLabel}</div>;
}
return (
<div className="overflow-x-auto bg-white rounded-xl border border-ink/5">
<table className="w-full text-sm">
<thead>
<tr className="bg-surface text-left">
{columns.map((col) => (
<th key={String(col.key)} className="px-4 py-3 font-display font-semibold text-ink border-b border-ink/5">
{col.label}
</th>
))}
</tr>
</thead>
<tbody>
{rows.map((row) => (
<tr key={row.id} className="border-b border-ink/5 last:border-0 hover:bg-surface/60">
{columns.map((col) => (
<td key={String(col.key)} className="px-4 py-3 align-top">
{col.isStatus ? (
<StatusBadge status={(row as Record<string, unknown>)[col.key as string] as string} />
) : col.render ? (
col.render(row)
) : (
String((row as Record<string, unknown>)[col.key as string] ?? 'Not provided')
)}
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
);
}