← full-stack-fastapi-template  /  frontend/src/components/Admin/columns.tsx

1
import type { ColumnDef } from "@tanstack/react-table"
2
3
import type { UserPublic } from "@/client"
4
import { Badge } from "@/components/ui/badge"
5
import { cn } from "@/lib/utils"
6
import { UserActionsMenu } from "./UserActionsMenu"
7
8
export type UserTableData = UserPublic & {
9
  isCurrentUser: boolean
10
}
11
12
export const columns: ColumnDef<UserTableData>[] = [
13
  {
14
    accessorKey: "full_name",
15
    header: "Full Name",
16
    cell: ({ row }) => {
17
      const fullName = row.original.full_name
18
      return (
19
        <div className="flex items-center gap-2">
20
          <span
21
            className={cn("font-medium", !fullName && "text-muted-foreground")}
22
          >
23
            {fullName || "N/A"}
24
          </span>
25
          {row.original.isCurrentUser && (
26
            <Badge variant="outline" className="text-xs">
27
              You
28
            </Badge>
29
          )}
30
        </div>
31
      )
32
    },
33
  },
34
  {
35
    accessorKey: "email",
36
    header: "Email",
37
    cell: ({ row }) => (
38
      <span className="text-muted-foreground">{row.original.email}</span>
39
    ),
40
  },
41
  {
42
    accessorKey: "is_superuser",
43
    header: "Role",
44
    cell: ({ row }) => (
45
      <Badge variant={row.original.is_superuser ? "default" : "secondary"}>
46
        {row.original.is_superuser ? "Superuser" : "User"}
47
      </Badge>
48
    ),
49
  },
50
  {
51
    accessorKey: "is_active",
52
    header: "Status",
53
    cell: ({ row }) => (
54
      <div className="flex items-center gap-2">
55
        <span
56
          className={cn(
57
            "size-2 rounded-full",
58
            row.original.is_active ? "bg-green-500" : "bg-gray-400",
59
          )}
60
        />
61
        <span className={row.original.is_active ? "" : "text-muted-foreground"}>
62
          {row.original.is_active ? "Active" : "Inactive"}
63
        </span>
64
      </div>
65
    ),
66
  },
67
  {
68
    id: "actions",
69
    header: () => <span className="sr-only">Actions</span>,
70
    cell: ({ row }) => (
71
      <div className="flex justify-end">
72
        <UserActionsMenu user={row.original} />
73
      </div>
74
    ),
75
  },
76
]
77