← full-stack-fastapi-template  /  frontend/src/routes/_layout/admin.tsx

1
import { useSuspenseQuery } from "@tanstack/react-query"
2
import { createFileRoute, redirect } from "@tanstack/react-router"
3
import { Suspense } from "react"
4
5
import { type UserPublic, UsersService } from "@/client"
6
import AddUser from "@/components/Admin/AddUser"
7
import { columns, type UserTableData } from "@/components/Admin/columns"
8
import { DataTable } from "@/components/Common/DataTable"
9
import PendingUsers from "@/components/Pending/PendingUsers"
10
import useAuth from "@/hooks/useAuth"
11
12
function getUsersQueryOptions() {
13
  return {
14
    queryFn: () => UsersService.readUsers({ skip: 0, limit: 100 }),
15
    queryKey: ["users"],
16
  }
17
}
18
19
export const Route = createFileRoute("/_layout/admin")({
20
  component: Admin,
21
  beforeLoad: async () => {
22
    const user = await UsersService.readUserMe()
23
    if (!user.is_superuser) {
24
      throw redirect({
25
        to: "/",
26
      })
27
    }
28
  },
29
  head: () => ({
30
    meta: [
31
      {
32
        title: "Admin - FastAPI Template",
33
      },
34
    ],
35
  }),
36
})
37
38
function UsersTableContent() {
39
  const { user: currentUser } = useAuth()
40
  const { data: users } = useSuspenseQuery(getUsersQueryOptions())
41
42
  const tableData: UserTableData[] = users.data.map((user: UserPublic) => ({
43
    ...user,
44
    isCurrentUser: currentUser?.id === user.id,
45
  }))
46
47
  return <DataTable columns={columns} data={tableData} />
48
}
49
50
function UsersTable() {
51
  return (
52
    <Suspense fallback={<PendingUsers />}>
53
      <UsersTableContent />
54
    </Suspense>
55
  )
56
}
57
58
function Admin() {
59
  return (
60
    <div className="flex flex-col gap-6">
61
      <div className="flex items-center justify-between">
62
        <div>
63
          <h1 className="text-2xl font-bold tracking-tight">Users</h1>
64
          <p className="text-muted-foreground">
65
            Manage user accounts and permissions
66
          </p>
67
        </div>
68
        <AddUser />
69
      </div>
70
      <UsersTable />
71
    </div>
72
  )
73
}
74