Skip to content

Commit 9fa4b37

Browse files
authored
chore: added search to mod log
1 parent 7ba3c35 commit 9fa4b37

File tree

3 files changed

+121
-63
lines changed

3 files changed

+121
-63
lines changed

react_main/src/components/ReportDetail.jsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { NameWithAvatar } from "pages/User/User";
2828
import { UserContext, SiteInfoContext } from "../Contexts";
2929
import ReportTypology from "./ReportTypology";
3030
import { useViolations } from "../hooks/useViolations";
31+
import RapSheet from "./RapSheet";
3132

3233
export default function ReportDetail({
3334
report: initialReport,
@@ -258,6 +259,7 @@ export default function ReportDetail({
258259
avatar={report.reportedUserAvatar}
259260
/>
260261
</Box>
262+
<RapSheet userId={report.reportedUserId} />
261263
{report.gameId && (
262264
<Box>
263265
<Typography variant="caption" color="textSecondary">

react_main/src/pages/Policy/Moderation/ModActions.jsx

Lines changed: 97 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import React, { useState, useEffect } from "react";
22
import axios from "axios";
3-
import { Box, Stack, Typography } from "@mui/material";
3+
import {
4+
Autocomplete,
5+
Box,
6+
Stack,
7+
TextField,
8+
Typography,
9+
} from "@mui/material";
410

511
import { useErrorAlert } from "components/Alerts";
612
import { getPageNavFilterArg, PageNav } from "components/Nav";
@@ -12,21 +18,63 @@ import { COMMAND_COLOR, useModCommands } from "./commands";
1218
export function ModActions(props) {
1319
const [page, setPage] = useState(1);
1420
const [actions, setActions] = useState([]);
21+
const [staffNameFilter, setStaffNameFilter] = useState("");
22+
const [actionTypeFilter, setActionTypeFilter] = useState("");
1523

1624
const modCommands = useModCommands({}, () => {}, props.setResults);
1725
const errorAlert = useErrorAlert();
1826

27+
const actionTypeOptions = Object.keys(modCommands).sort();
28+
1929
useEffect(() => {
20-
onPageNav(1);
21-
}, []);
30+
loadActions(1);
31+
}, [staffNameFilter, actionTypeFilter]);
32+
33+
function loadActions(_page) {
34+
const params = new URLSearchParams();
35+
36+
if (_page > 1 && actions.length > 0) {
37+
params.append("last", actions[actions.length - 1].date);
38+
}
39+
40+
if (staffNameFilter) {
41+
params.append("staffName", staffNameFilter);
42+
}
43+
if (actionTypeFilter) {
44+
params.append("actionType", actionTypeFilter);
45+
}
46+
47+
axios
48+
.get(`/api/mod/actions?${params.toString()}`)
49+
.then((res) => {
50+
if (res.data.length > 0 || _page === 1) {
51+
setActions(res.data);
52+
setPage(_page);
53+
}
54+
})
55+
.catch(errorAlert);
56+
}
2257

2358
function onPageNav(_page) {
24-
var filterArg = getPageNavFilterArg(_page, page, actions, "date");
59+
if (_page === page) return;
60+
61+
const params = new URLSearchParams();
2562

26-
if (filterArg == null) return;
63+
if (_page > page && actions.length > 0) {
64+
params.append("last", actions[actions.length - 1].date);
65+
} else if (_page < page && actions.length > 0) {
66+
params.append("first", actions[0].date);
67+
}
68+
69+
if (staffNameFilter) {
70+
params.append("staffName", staffNameFilter);
71+
}
72+
if (actionTypeFilter) {
73+
params.append("actionType", actionTypeFilter);
74+
}
2775

2876
axios
29-
.get(`/api/mod/actions?${filterArg}`)
77+
.get(`/api/mod/actions?${params.toString()}`)
3078
.then((res) => {
3179
if (res.data.length > 0) {
3280
setActions(res.data);
@@ -111,9 +159,50 @@ export function ModActions(props) {
111159
return (
112160
<div className="box-panel">
113161
<Typography variant="h3">Mod Actions</Typography>
114-
<Stack direction="column" spacing={1}>
162+
<Stack direction="column" spacing={2}>
163+
<Stack
164+
direction={{ xs: "column", sm: "row" }}
165+
spacing={2}
166+
sx={{ mb: 1 }}
167+
>
168+
<TextField
169+
label="Search by Staff Name"
170+
variant="outlined"
171+
size="small"
172+
value={staffNameFilter}
173+
onChange={(e) => {
174+
setStaffNameFilter(e.target.value);
175+
setPage(1);
176+
}}
177+
sx={{ minWidth: 200 }}
178+
/>
179+
<Autocomplete
180+
options={actionTypeOptions}
181+
value={actionTypeFilter || null}
182+
onChange={(e, newValue) => {
183+
setActionTypeFilter(newValue || "");
184+
setPage(1);
185+
}}
186+
renderInput={(params) => (
187+
<TextField
188+
{...params}
189+
label="Filter by Action Type"
190+
variant="outlined"
191+
size="small"
192+
/>
193+
)}
194+
sx={{ minWidth: 250 }}
195+
clearOnEscape
196+
/>
197+
</Stack>
115198
{pageNav}
116-
{actionRows}
199+
{actions.length === 0 ? (
200+
<Typography variant="body2" color="textSecondary" sx={{ py: 2, textAlign: "center" }}>
201+
No actions found.
202+
</Typography>
203+
) : (
204+
actionRows
205+
)}
117206
{pageNav}
118207
</Stack>
119208
</div>

routes/mod.js

Lines changed: 22 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,60 +1019,6 @@ router.get("/flagged", async (req, res) => {
10191019
}
10201020
});
10211021

1022-
router.get("/bans", async (req, res) => {
1023-
try {
1024-
var userId = await routeUtils.verifyLoggedIn(req);
1025-
var userIdToCheck = String(req.query.userId || "").trim();
1026-
var perm = "seeModPanel";
1027-
1028-
if (!(await routeUtils.verifyPermission(res, userId, perm))) return;
1029-
1030-
if (!userIdToCheck) {
1031-
res.status(400);
1032-
res.send("User ID required.");
1033-
return;
1034-
}
1035-
1036-
var user = await models.User.findOne({
1037-
id: userIdToCheck,
1038-
}).select("id");
1039-
1040-
if (!user) {
1041-
res.status(404);
1042-
res.send("User does not exist.");
1043-
return;
1044-
}
1045-
1046-
const activeBans = await models.Ban.find({
1047-
userId: userIdToCheck,
1048-
$or: [{ expires: 0 }, { expires: { $gt: Date.now() } }],
1049-
}).select("type expires");
1050-
1051-
const banTypeLabels = {
1052-
forum: "Forum",
1053-
chat: "Chat",
1054-
game: "Game",
1055-
playRanked: "Ranked",
1056-
playCompetitive: "Competitive",
1057-
site: "Site",
1058-
ipFlag: "IP Flag",
1059-
gameAuto: "Game (Auto)",
1060-
};
1061-
1062-
const formattedBans = activeBans.map((ban) => ({
1063-
type: banTypeLabels[ban.type] || ban.type,
1064-
expires: ban.expires,
1065-
permanent: ban.expires === 0,
1066-
}));
1067-
1068-
res.send(formattedBans);
1069-
} catch (e) {
1070-
logger.error(e);
1071-
res.status(500);
1072-
res.send("Error loading bans.");
1073-
}
1074-
});
1075-
10761022
router.post("/clearSetupName", async (req, res) => {
10771023
res.setHeader("Content-Type", "application/json");
10781024
try {
@@ -2289,10 +2235,31 @@ router.get("/actions", async function (req, res) {
22892235
try {
22902236
var last = Number(req.query.last);
22912237
var first = Number(req.query.first);
2238+
var staffName = req.query.staffName ? String(req.query.staffName).trim() : "";
2239+
var actionType = req.query.actionType ? String(req.query.actionType).trim() : "";
2240+
2241+
var query = {};
2242+
2243+
if (actionType) {
2244+
query.name = actionType;
2245+
}
2246+
2247+
if (staffName) {
2248+
const staffUsers = await models.User.find({
2249+
name: { $regex: staffName, $options: "i" },
2250+
}).select("id");
2251+
const staffIds = staffUsers.map((u) => u.id);
2252+
if (staffIds.length > 0) {
2253+
query.modId = { $in: staffIds };
2254+
} else {
2255+
res.send([]);
2256+
return;
2257+
}
2258+
}
22922259

22932260
var actions = await routeUtils.modelPageQuery(
22942261
models.ModAction,
2295-
{},
2262+
query,
22962263
"date",
22972264
last,
22982265
first,

0 commit comments

Comments
 (0)