diff --git a/website/src/components/UsersCell.tsx b/website/src/components/UsersCell.tsx index 3cf2f1e5..fc93215f 100644 --- a/website/src/components/UsersCell.tsx +++ b/website/src/components/UsersCell.tsx @@ -1,4 +1,17 @@ -import { Table, TableCaption, TableContainer, Tbody, Td, Th, Thead, Tr } from "@chakra-ui/react"; +import { + Button, + Flex, + Spacer, + Stack, + Table, + TableCaption, + TableContainer, + Tbody, + Td, + Th, + Thead, + Tr, +} from "@chakra-ui/react"; import Link from "next/link"; import { useState } from "react"; import fetcher from "src/lib/fetcher"; @@ -8,41 +21,60 @@ import useSWR from "swr"; * Fetches users from the users api route and then presents them in a simple Chakra table. */ const UsersCell = () => { - // Fetch and save the users. + const [pageIndex, setPageIndex] = useState(0); const [users, setUsers] = useState([]); - const { isLoading } = useSWR("/api/admin/users", fetcher, { + + // Fetch and save the users. + // This follows useSWR's recommendation for simple pagination: + // https://swr.vercel.app/docs/pagination#when-to-use-useswr + const { isLoading } = useSWR(`/api/admin/users?pageIndex=${pageIndex}`, fetcher, { onSuccess: setUsers, }); + const toPreviousPage = () => { + setPageIndex(Math.max(0, pageIndex - 1)); + }; + + const toNextPage = () => { + setPageIndex(pageIndex + 1); + }; + // Present users in a naive table. return ( - - - Users - - - - - - - - - - - {users.map((user, index) => ( - - - - - - + + + + + + + +
IdEmailNameRoleUpdate
{user.id}{user.email}{user.name}{user.role} - Manage -
+ Users + + + + + + + - ))} - -
IdEmailNameRoleUpdate
-
+ + + {users.map((user, index) => ( + + {user.id} + {user.email} + {user.name} + {user.role} + + Manage + + + ))} + + + + ); }; diff --git a/website/src/pages/api/admin/users.ts b/website/src/pages/api/admin/users.ts index 1490522a..3418e5e1 100644 --- a/website/src/pages/api/admin/users.ts +++ b/website/src/pages/api/admin/users.ts @@ -2,11 +2,21 @@ import { getToken } from "next-auth/jwt"; import withRole from "src/lib/auth"; import prisma from "src/lib/prismadb"; +// The number of users to fetch in any request. +const PAGE_SIZE = 20; + /** * Returns a list of user results from the database when the requesting user is * a logged in admin. */ const handler = withRole("admin", async (req, res) => { + // Figure out the pagination index and skip that number of users. + // + // Note: with Prisma this isn't the most efficient but it's the only possible + // option with cuid based User IDs. + const { pageIndex } = req.query; + const skip = pageIndex * PAGE_SIZE; + // Fetch 20 users. const users = await prisma.user.findMany({ select: { @@ -15,7 +25,8 @@ const handler = withRole("admin", async (req, res) => { name: true, email: true, }, - take: 20, + skip, + take: PAGE_SIZE, }); res.status(200).json(users);