Adding simple pagination to the admin user's view

This commit is contained in:
Keith Stevens
2023-01-08 20:11:26 +09:00
parent 15a88309f8
commit 39485c6ced
2 changed files with 73 additions and 30 deletions
+61 -29
View File
@@ -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 (
<TableContainer>
<Table variant="simple">
<TableCaption>Users</TableCaption>
<Thead>
<Tr>
<Th>Id</Th>
<Th>Email</Th>
<Th>Name</Th>
<Th>Role</Th>
<Th>Update</Th>
</Tr>
</Thead>
<Tbody>
{users.map((user, index) => (
<Tr key={index}>
<Td>{user.id}</Td>
<Td>{user.email}</Td>
<Td>{user.name}</Td>
<Td>{user.role}</Td>
<Td>
<Link href={`/admin/manage_user/${user.id}`}>Manage</Link>
</Td>
<Stack>
<Flex p="2">
<Button onClick={toPreviousPage}>Previous</Button>
<Spacer />
<Button onClick={toNextPage}>Next</Button>
</Flex>
<TableContainer>
<Table variant="simple">
<TableCaption>Users</TableCaption>
<Thead>
<Tr>
<Th>Id</Th>
<Th>Email</Th>
<Th>Name</Th>
<Th>Role</Th>
<Th>Update</Th>
</Tr>
))}
</Tbody>
</Table>
</TableContainer>
</Thead>
<Tbody>
{users.map((user, index) => (
<Tr key={index}>
<Td>{user.id}</Td>
<Td>{user.email}</Td>
<Td>{user.name}</Td>
<Td>{user.role}</Td>
<Td>
<Link href={`/admin/manage_user/${user.id}`}>Manage</Link>
</Td>
</Tr>
))}
</Tbody>
</Table>
</TableContainer>
</Stack>
);
};
+12 -1
View File
@@ -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);