From 751c72ea1250b7079251431167ab87f44b517baa Mon Sep 17 00:00:00 2001 From: ericsheng495 Date: Thu, 21 Sep 2023 10:08:34 -0400 Subject: [PATCH] feat: update adminGetUsers to return totalUsers --- backend/server/mongodb/actions/User.ts | 30 ++++++++++------- backend/src/pages/api/admin/user.ts | 12 +++++-- mobile/screens/Admin/AdminUserListScreen.tsx | 34 +++++++++++++------- 3 files changed, 52 insertions(+), 24 deletions(-) diff --git a/backend/server/mongodb/actions/User.ts b/backend/server/mongodb/actions/User.ts index 8e9ab5c..37bec82 100644 --- a/backend/server/mongodb/actions/User.ts +++ b/backend/server/mongodb/actions/User.ts @@ -102,17 +102,20 @@ export async function adminGetUsers( }), }; + let query: any; + if (!filter || filter === UserFilter.NONPROFIT_USERS) { - return UserModel.find({ + query = { ...searchQuery, roles: { $nin: [Role.NONPROFIT_ADMIN] }, - }).limit(pageSize); + }; } if (filter === UserFilter.UNVERIFIED_USERS) { - return UserModel.find({ ...searchQuery, verifiedByAdmin: false }).limit( - pageSize - ); + query = { + ...searchQuery, + verifiedByAdmin: false, + }; } // Hours is on the Animal, not the users @@ -121,12 +124,12 @@ export async function adminGetUsers( totalHours: { $gte: 800 }, }).select("handler"); - return UserModel.find({ + query = { _id: { ...(afterId && { $gt: afterId }), $in: handlers.map((item) => item.handler), }, - }).limit(pageSize); + }; } if (filter === UserFilter.WITHOUT_800_HOURS_USERS) { @@ -134,22 +137,27 @@ export async function adminGetUsers( totalHours: { $gte: 800 }, }).select("handler"); - return UserModel.find({ + query = { _id: { ...(afterId && { $gt: afterId }), // some verified users do not have an animal $nin: handlers.map((item) => item.handler), }, verifiedByAdmin: true, - }).limit(pageSize); + }; } if (filter === UserFilter.NONPROFIT_ADMINS) { - return UserModel.find({ + query = { ...searchQuery, roles: { $in: [Role.NONPROFIT_ADMIN] }, - }).limit(pageSize); + }; } + + const users = await UserModel.find(query).limit(pageSize); + const totalCount = await UserModel.countDocuments(query); + + return { users, totalCount }; } export async function verifyUserEmail(userId: Types.ObjectId) { diff --git a/backend/src/pages/api/admin/user.ts b/backend/src/pages/api/admin/user.ts index eb0fe7f..b0c4217 100644 --- a/backend/src/pages/api/admin/user.ts +++ b/backend/src/pages/api/admin/user.ts @@ -19,9 +19,17 @@ export default APIWrapper({ | undefined; const searchText: string = req.body.searchText as string; - const users = await adminGetUsers(pageSize, afterId, filter, searchText); + const { users, totalCount } = await adminGetUsers( + pageSize, + afterId, + filter, + searchText + ); - return users; + return { + users, + totalCount, + }; }, }, }); diff --git a/mobile/screens/Admin/AdminUserListScreen.tsx b/mobile/screens/Admin/AdminUserListScreen.tsx index ea2cb03..87dffde 100644 --- a/mobile/screens/Admin/AdminUserListScreen.tsx +++ b/mobile/screens/Admin/AdminUserListScreen.tsx @@ -1,5 +1,5 @@ import React, { useState, useEffect } from "react"; -import { StyleSheet, View, TextInput, BackHandler } from "react-native"; +import { StyleSheet, View, TextInput, Text, BackHandler } from "react-native"; import UserEntry from "../../components/UserEntry"; import { ButtonDirection, Screens, User, UserFilter } from "../../utils/types"; import { adminGetUsers } from "../../actions/Admin"; @@ -16,6 +16,7 @@ export default function AdminUserList(props: any) { const [currentPage, setCurrentPage] = useState(0); const [error, setError] = useState(""); const [searchText, setSearchText] = useState(""); + const [totalUserCount, setTotalUserCount] = useState(0); const removeUserFromList = (errorMessage: string, userId: Types.ObjectId) => { if (errorMessage) { @@ -30,12 +31,16 @@ export default function AdminUserList(props: any) { }; async function loadUsers() { - const users = await ErrorWrapper({ + const result = await ErrorWrapper({ functionToExecute: adminGetUsers, errorHandler: setError, parameters: [PAGE_SIZE, undefined, filter, searchText], }); - setAllUsers([users]); + + if (result) { + setAllUsers([[...result.users]]); + setTotalUserCount(result.totalCount); + } } useEffect(() => { @@ -45,32 +50,38 @@ export default function AdminUserList(props: any) { }); loadUsers().catch().then(); }, []); + const processNext = async (direction: ButtonDirection) => { + let newPage = currentPage; + if (direction === ButtonDirection.BUTTON_BACKWARD) { - setCurrentPage(Math.max(currentPage - 1, 0)); + newPage = Math.max(currentPage - 1, 0); } if (direction === ButtonDirection.BUTTON_FORWARD) { // If we are on last page and have a full page of users, we want to load more users const lastPage = allUsers.length - 1; - if (currentPage === lastPage) { + + // If we are on the last page and it's full, fetch more users + if (currentPage === lastPage && allUsers[lastPage].length === PAGE_SIZE) { const afterId = allUsers[lastPage][allUsers[lastPage].length - 1]._id; const newUsers = await ErrorWrapper({ functionToExecute: adminGetUsers, errorHandler: setError, - parameters: [PAGE_SIZE, afterId, filter], + parameters: [PAGE_SIZE, afterId, filter, searchText], }); - if (newUsers && newUsers.length > 0) { - allUsers.push(newUsers); - setAllUsers(allUsers); - setCurrentPage(currentPage + 1); + + if (newUsers && newUsers.users.length > 0) { + setAllUsers([...allUsers, newUsers.users]); + newPage = currentPage + 1; } } else if (currentPage !== lastPage) { // We are in a page in the middle - setCurrentPage(currentPage + 1); + newPage = currentPage + 1; } } + setCurrentPage(newPage); }; return ( @@ -112,6 +123,7 @@ export default function AdminUserList(props: any) { onEndEditing={loadUsers} /> + Total Users: {totalUserCount} {allUsers.length > 0 && allUsers[currentPage].map((user, index) => { return (