OverviewTable.tsx 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import { Loader2 } from 'lucide-react'
  2. import { ReactNode } from 'react'
  3. import { cn, Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from 'ui'
  4. import NoDataPlaceholder from '@/components/ui/Charts/NoDataPlaceholder'
  5. export type OverviewTableColumn<T> = {
  6. key: keyof T | string
  7. header: string
  8. render?: (row: T) => ReactNode
  9. className?: string
  10. }
  11. export interface OverviewTable<T> {
  12. columns: OverviewTableColumn<T>[]
  13. data: T[]
  14. isLoading?: boolean
  15. emptyMessage?: string
  16. }
  17. export function OverviewTable<T>({ columns, data, isLoading, emptyMessage }: OverviewTable<T>) {
  18. const hasData = !isLoading && data.length > 0
  19. return (
  20. <Table className="border-t mt-4">
  21. {hasData && (
  22. <TableHeader>
  23. <TableRow>
  24. {columns.map((col) => (
  25. <TableHead key={String(col.key)} className={cn(col.className)}>
  26. {col.header}
  27. </TableHead>
  28. ))}
  29. </TableRow>
  30. </TableHeader>
  31. )}
  32. <TableBody className="text-foreground">
  33. {isLoading ? (
  34. <TableRow className="[&>td]:hover:bg-transparent">
  35. <TableCell colSpan={columns.length} className="text-center text-foreground-light">
  36. <div className="flex items-center justify-center gap-2 py-4">
  37. <Loader2 className="size-4 animate-spin" />
  38. </div>
  39. </TableCell>
  40. </TableRow>
  41. ) : data.length === 0 ? (
  42. <TableRow className="[&>td]:hover:bg-transparent">
  43. <TableCell colSpan={columns.length} className="text-center text-foreground-light">
  44. <div className="p-2 pt-0">
  45. <NoDataPlaceholder
  46. size="normal"
  47. message={emptyMessage || 'No data available'}
  48. isFullHeight
  49. />
  50. </div>
  51. </TableCell>
  52. </TableRow>
  53. ) : (
  54. (data as unknown as T[]).map((row, idx) => (
  55. <TableRow key={idx}>
  56. {columns.map((col) => (
  57. <TableCell key={String(col.key)} className={cn(col.className)}>
  58. {col.render ? col.render(row) : (row as any)[col.key as string]}
  59. </TableCell>
  60. ))}
  61. </TableRow>
  62. ))
  63. )}
  64. </TableBody>
  65. </Table>
  66. )
  67. }