import { Badge, Box, Button, Container, Flex, Heading, SkeletonText, Table, TableContainer, Tbody, Td, Th, Thead, Tr, } from "@chakra-ui/react" import { useQuery, useQueryClient } from "@tanstack/react-query" import { createFileRoute, useNavigate } from "@tanstack/react-router" import { useEffect } from "react" import { z } from "zod" import { type UserPublic, UsersService } from "../../client" import AddUser from "../../components/Admin/AddUser" import ActionsMenu from "../../components/Common/ActionsMenu" import Navbar from "../../components/Common/Navbar" const usersSearchSchema = z.object({ page: z.number().catch(1), }) export const Route = createFileRoute("/_layout/admin")({ component: Admin, validateSearch: (search) => usersSearchSchema.parse(search), }) const PER_PAGE = 5 function getUsersQueryOptions({ page }: { page: number }) { return { queryFn: () => UsersService.readUsers({ skip: (page - 1) * PER_PAGE, limit: PER_PAGE }), queryKey: ["users", { page }], } } function UsersTable() { const queryClient = useQueryClient() const currentUser = queryClient.getQueryData(["currentUser"]) const { page } = Route.useSearch() const navigate = useNavigate({ from: Route.fullPath }) const setPage = (page: number) => navigate({ search: (prev) => ({ ...prev, page }) }) const { data: users, isPending, isPlaceholderData, } = useQuery({ ...getUsersQueryOptions({ page }), placeholderData: (prevData) => prevData, }) const hasNextPage = !isPlaceholderData && users?.data.length === PER_PAGE const hasPreviousPage = page > 1 useEffect(() => { if (hasNextPage) { queryClient.prefetchQuery(getUsersQueryOptions({ page: page + 1 })) } }, [page, queryClient, hasNextPage]) return ( <> {isPending ? ( {new Array(4).fill(null).map((_, index) => ( ))} ) : ( {users?.data.map((user) => ( ))} )}
Full name Email Role Status Actions
{user.full_name || "N/A"} {currentUser?.id === user.id && ( You )} {user.email} {user.is_superuser ? "Superuser" : "User"} {user.is_active ? "Active" : "Inactive"}
Page {page} ) } function Admin() { return ( Users Management ) }