From 702635d9339468c906d6067d20f0d9e26817f40a Mon Sep 17 00:00:00 2001 From: Mitch J Date: Wed, 17 Apr 2024 19:08:14 -0400 Subject: [PATCH] split users into categories on users page --- staff-frontend/pages/users.jsx | 152 ++++++++++++++++++++++++--------- 1 file changed, 110 insertions(+), 42 deletions(-) diff --git a/staff-frontend/pages/users.jsx b/staff-frontend/pages/users.jsx index b3843bc..945100a 100644 --- a/staff-frontend/pages/users.jsx +++ b/staff-frontend/pages/users.jsx @@ -4,41 +4,21 @@ import KHELayout from "../layouts/layout"; import { User } from "../../global-includes/users"; import style from "./users.module.css"; -import { Button, Card, Layout, Modal, Row, Col, Divider, Tooltip, Grid } from "antd"; +import { Button, Card, Layout, Modal, Row, Col, Divider, Tooltip, Menu } from "antd"; import { Email, EmailTemplates } from "../../global-includes/email-address"; -const { Content } = Layout; +import { useQueryState, parseAsString } from "nuqs"; +const { Content, Sider } = Layout; export default function UsersManager() { const [users, setUsers] = useState([]); const [viewing, setViewing] = useState(null); const [loading, setLoading] = useState(false); - const repo = remult.repo(User); + const userRepo = remult.repo(User); const showReview = (user) => setViewing(user); const closeReview = () => setViewing(null); - const approveUser = async (user) => { - setLoading(true); - await repo.save({ id: user.id, applicationApproved: true }); - await Email.sendTemplateEmail(EmailTemplates.Approved, user.email || user.registration.email) - closeReview(); - setLoading(false); - loadUsers(); - } - - const checkInUser = async (user) => { - setLoading(true); - await repo.save({ id: user.id, checkedIn: true }); - closeReview(); - setLoading(false); - loadUsers(); - } - - const loadUsers = () => { - repo.find().then(setUsers); - } - const getActions = (user) => { const checkedIn = user.checkedIn; const actions = []; @@ -49,34 +29,122 @@ export default function UsersManager() { return actions; } - useEffect(loadUsers, []); - const cardStyle = { width: 350, margin: 6 } + const userStatuses = { + accountCreated: { + label: "Account Created", + filter: { + applicationApproved: false, + submittedApplication: false, + checkedIn: false + } + }, + applicationReceived: { + label: "Application Received", + filter: { + submittedApplication: true, + applicationApproved: false, + checkedIn: false + } + }, + approved: { + label: "Application Approved", + filter: { + submittedApplication: true, + applicationApproved: true, + checkedIn: false + } + }, + checkedIn: { + label: "Checked In", + filter: { + checkedIn: true + } + } + }; + + const [userStatusCounts, setUserStatusCounts] = useState({}); + + const userStatusMenuItems = Object.keys(userStatuses).map( + key => { + const count = userStatusCounts[key] ? ` (${userStatusCounts[key]})` : ""; + const label = userStatuses[key].label + count; + return { label, key }; + } + ); + + const [viewingStatus, setViewingStatus] = useQueryState( + "status", + parseAsString.withDefault("applicationReceived") + ); + + const navigateStatuses = (clickedItem) => { + setViewingStatus(clickedItem.key); + }; + + const loadUsers = () => { + userRepo + .find({where: userStatuses[viewingStatus].filter}) + .then(setUsers); + for (const status of Object.keys(userStatuses)){ + userRepo + .count(userStatuses[status].filter) + .then(count => setUserStatusCounts(c => ({...c, [status]: count}))); + } + } + + useEffect(loadUsers, [viewingStatus]); + + const approveUser = async (user) => { + setLoading(true); + await userRepo.save({ id: user.id, applicationApproved: true }); + await Email.sendTemplateEmail(EmailTemplates.Approved, user.email || user.registration.email) + closeReview(); + setLoading(false); + loadUsers(); + } + + const checkInUser = async (user) => { + setLoading(true); + await userRepo.save({ id: user.id, checkedIn: true }); + closeReview(); + setLoading(false); + loadUsers(); + } + return - -
- {users.map((user, i) => - {user.roles.join(", ")}} - actions={getActions(user)} - style={cardStyle}> - {user.submittedApplication && !user.applicationApproved && This user is awaiting approval!} -

This account is registered with {user.method}. It was created on {user.createdAt.toLocaleDateString()}.

-
- )} -
-
+ + + + + +
+ {users.map((user, i) => + {user.roles.join(", ")}} + actions={getActions(user)} + style={cardStyle}> + {user.submittedApplication && !user.applicationApproved && This user is awaiting approval!} +

This account is registered with {user.method}. It was created on {user.createdAt.toLocaleDateString()}.

+
+ )} +
+
+
{/* TODO: really do not like this really long JSON access syntax (viewing.registration.someotherlongname), - this should become it's own component at some point + this should become its own component at some point */}