From 590607ac10b22803e2543362dda0fe2d49429410 Mon Sep 17 00:00:00 2001 From: Luke Berndt Date: Sun, 25 Jun 2023 21:58:30 -0400 Subject: [PATCH] Get Email for Active System Owners --- admin/server/controllers/systems.js | 36 +++++++++++++++++++++++++++ admin/server/index.js | 1 + admin/src/ActiveUsers/ActiveUsers.js | 37 ++++++++++++++++++++++++++++ admin/src/App/App.js | 2 ++ admin/src/App/Navigation.js | 4 +++ admin/src/features/api/apiSlice.js | 6 ++++- 6 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 admin/src/ActiveUsers/ActiveUsers.js diff --git a/admin/server/controllers/systems.js b/admin/server/controllers/systems.js index 190f1ca..6075de4 100644 --- a/admin/server/controllers/systems.js +++ b/admin/server/controllers/systems.js @@ -13,6 +13,42 @@ exports.isLoggedIn = function (req, res, next) { // ------------------------------------------- +exports.listActiveUsers = async function (req,res,next) { + if (!req.user.admin) { + res.status(401); + res.json({ success: false, message: "Not Authorized" }); + return; + } + let users = {}; + let fromDate = new Date(Date.now() - 60 * 60 * 24 * 30 * 1000); + const systems = await System.find({lastActive: {$gte: fromDate}}).populate('userId', "screenName").catch( err => { + console.error("Error - get_systems: " + err.message); + res.json({ + success: false, + message: err + }); + return; + }); + for (let index = 0; index < systems.length; index++) { + const system = systems[index]; + + if (!users.hasOwnProperty(system.userId.toString())) { + const user = await User.findById(system.userId, "_id email firstName lastName lastLogin"); + users[system.userId.toString()] = user.email; + } + + } + + let list = []; + for (const id in users) { + list.push(users[id]); + } + + res.json(list); + return; +} + + exports.listUserSystems = async function (req,res,next) { if (!req.user.admin) { res.status(401); diff --git a/admin/server/index.js b/admin/server/index.js index d6ddb96..8033f75 100644 --- a/admin/server/index.js +++ b/admin/server/index.js @@ -153,6 +153,7 @@ app.get("/groups/:shortName/:groupId?", isLoggedIn, groups.getGroups); app.delete("/groups/:shortName/:groupId", isLoggedIn, groups.deleteGroup); app.get("/systems", isLoggedIn, systems.listSystems) app.get("/admin/systems", isAdmin, systems.listAllSystems) +app.get("/admin/users/active", isAdmin, systems.listActiveUsers) app.get("/admin/users", isAdmin, systems.listUserSystems) app.delete("/systems/:shortName", isLoggedIn, systems.deleteSystem) app.post("/systems/:shortName", [isLoggedIn, systems.ownSystem, systems.validateSystem, systems.updateSystem]) diff --git a/admin/src/ActiveUsers/ActiveUsers.js b/admin/src/ActiveUsers/ActiveUsers.js new file mode 100644 index 0000000..7facb25 --- /dev/null +++ b/admin/src/ActiveUsers/ActiveUsers.js @@ -0,0 +1,37 @@ +import { + Container, + Header, + Table, + Icon +} from "semantic-ui-react"; +import { useGetActiveUsersQuery, } from '../features/api/apiSlice' + + + +// ---------------------------------------------------- +const ActiveUsers = () => { + const { data: users, isSuccess } = useGetActiveUsersQuery(); + + +//https://stackoverflow.com/questions/36559661/how-can-i-dispatch-from-child-components-in-react-redux +//https://stackoverflow.com/questions/42597602/react-onclick-pass-event-with-parameter + + return ( +
+ +
Email of Active Users
+ + + {users && + users.map((user) => + + {user}, + )} + +
+
+ ); + +} + +export default ActiveUsers; diff --git a/admin/src/App/App.js b/admin/src/App/App.js index 8d5a75e..e818162 100644 --- a/admin/src/App/App.js +++ b/admin/src/App/App.js @@ -9,6 +9,7 @@ import AllSystems from "../AllSystems/AllSystems" import ListSystems from "../System/ListSystems" import UpdateSystem from "../System/UpdateSystem" import CreateSystem from "../System/CreateSystem" +import ActiveUsers from "../ActiveUsers/ActiveUsers" const App = (params) => { @@ -22,6 +23,7 @@ const App = (params) => { } /> } /> } /> + } /> } /> (
Miss
)} /> diff --git a/admin/src/App/Navigation.js b/admin/src/App/Navigation.js index e58fc72..8fee9c1 100644 --- a/admin/src/App/Navigation.js +++ b/admin/src/App/Navigation.js @@ -24,6 +24,10 @@ const Navigation = (props) => { {process.env.REACT_APP_SITE_NAME} + {admin && + + Active Users + } {admin && All Systems diff --git a/admin/src/features/api/apiSlice.js b/admin/src/features/api/apiSlice.js index 3af13dc..2edd0a0 100644 --- a/admin/src/features/api/apiSlice.js +++ b/admin/src/features/api/apiSlice.js @@ -140,6 +140,10 @@ export const apiSlice = createApi({ // The URL for the request is '/fakeApi/posts' query: () => ({ url: `/admin/users`, credentials: "include" }) }), + getActiveUsers: builder.query({ + // The URL for the request is '/fakeApi/posts' + query: () => ({ url: `/admin/users/active`, credentials: "include" }) + }), createSystem: builder.mutation({ query: (system) => ({ url: `/systems`, @@ -202,4 +206,4 @@ export const apiSlice = createApi({ }) // Export the auto-generated hook for the `getPosts` query endpoint -export const { useGetGroupsQuery, useGetSystemsQuery, useGetAllSystemsQuery, useGetTalkgroupsQuery, useGetErrorsQuery, useDeleteGroupMutation, useCreateGroupMutation, useCreateSystemMutation, useUpdateSystemMutation, useDeleteSystemMutation, useSaveGroupOrderMutation, useUpdateGroupMutation, useImportTalkgroupsMutation } = apiSlice +export const { useGetGroupsQuery, useGetSystemsQuery, useGetAllSystemsQuery, useGetActiveUsersQuery, useGetTalkgroupsQuery, useGetErrorsQuery, useDeleteGroupMutation, useCreateGroupMutation, useCreateSystemMutation, useUpdateSystemMutation, useDeleteSystemMutation, useSaveGroupOrderMutation, useUpdateGroupMutation, useImportTalkgroupsMutation } = apiSlice