Remix migration
This commit is contained in:
140
app/routes/mod-queue.tsx
Normal file
140
app/routes/mod-queue.tsx
Normal file
@ -0,0 +1,140 @@
|
||||
import {
|
||||
Box,
|
||||
Container,
|
||||
Flex,
|
||||
Select,
|
||||
useBreakpointValue,
|
||||
useToast,
|
||||
VStack,
|
||||
} from "@chakra-ui/react";
|
||||
import { lazy, useState } from "react";
|
||||
import AppealCard from "../../components/AppealCard.js";
|
||||
import Login from "../../components/Login.js";
|
||||
import { useLoaderData } from "@remix-run/react";
|
||||
|
||||
export async function loader({ context }: { context: RequestContext }) {
|
||||
const { current_user: currentUser } = context.data;
|
||||
|
||||
if (!currentUser)
|
||||
throw new Response(null, {
|
||||
status: 401,
|
||||
});
|
||||
|
||||
const newItemPermissions = {
|
||||
game_ban: [1 << 5],
|
||||
inactivity: [1 << 2, 1 << 9, 1 << 10],
|
||||
infraction: [1 << 0, 1 << 2, 1 << 6, 1 << 7],
|
||||
};
|
||||
|
||||
const newItemNames: { [k: string]: string } = {
|
||||
game_ban: "Game Ban",
|
||||
inactivity: "Inactivity Notice",
|
||||
infraction: "Infraction",
|
||||
};
|
||||
|
||||
const typePermissions = {
|
||||
appeal: [1 << 0, 1 << 1],
|
||||
gma: [1 << 5],
|
||||
report: [1 << 5],
|
||||
};
|
||||
|
||||
const typeNames: { [k: string]: string } = {
|
||||
appeal: "Discord Appeals",
|
||||
gma: "Game Appeals",
|
||||
report: "Game Reports",
|
||||
};
|
||||
|
||||
const allowedNewItems = [];
|
||||
const allowedTypes = [];
|
||||
|
||||
for (const [item, ints] of Object.entries(newItemPermissions)) {
|
||||
if (ints.find((i) => currentUser.permissions & i))
|
||||
allowedNewItems.push({ name: newItemNames[item], value: item });
|
||||
}
|
||||
|
||||
for (const [type, ints] of Object.entries(typePermissions)) {
|
||||
if (ints.find((i) => currentUser.permissions & i))
|
||||
allowedTypes.push({ name: typeNames[type], value: type });
|
||||
}
|
||||
|
||||
if (!allowedTypes.length)
|
||||
throw new Response(null, {
|
||||
status: 403,
|
||||
});
|
||||
|
||||
return {
|
||||
entry_types: allowedTypes,
|
||||
item_types: allowedNewItems,
|
||||
};
|
||||
}
|
||||
|
||||
export default function () {
|
||||
const pageProps = useLoaderData<typeof loader>();
|
||||
const isDesktop = useBreakpointValue({ base: false, lg: true });
|
||||
const entryTypes = [];
|
||||
const [entries, setEntries] = useState([] as JSX.Element[]);
|
||||
|
||||
for (const type of pageProps.entry_types)
|
||||
entryTypes.push(<option value={type.value}>{type.name}</option>);
|
||||
|
||||
async function updateQueue(
|
||||
queue_type: string,
|
||||
show_closed: boolean = false
|
||||
): Promise<void> {
|
||||
const queueReq = await fetch(
|
||||
`/api/mod-queue/list?type=${queue_type}&showClosed=${show_closed}`
|
||||
);
|
||||
|
||||
if (!queueReq.ok) {
|
||||
const errorData: { error: string } = await queueReq.json();
|
||||
|
||||
useToast()({
|
||||
description: errorData.error,
|
||||
duration: 10000,
|
||||
isClosable: true,
|
||||
status: "error",
|
||||
title: "Failed to load queue",
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const entryData: { [k: string]: any }[] = await queueReq.json();
|
||||
const newEntries = [];
|
||||
|
||||
for (const entry of entryData) {
|
||||
switch (queue_type) {
|
||||
case "appeal":
|
||||
newEntries.push(
|
||||
<AppealCard
|
||||
{...(entry as {
|
||||
ban_reason: string;
|
||||
createdAt: number;
|
||||
discriminator: string;
|
||||
id: string;
|
||||
learned: string;
|
||||
reason_for_unban: string;
|
||||
username: string;
|
||||
})}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
setEntries(newEntries);
|
||||
}
|
||||
|
||||
return (
|
||||
<Container maxW="container.lg">
|
||||
<Flex>
|
||||
<VStack w="container.md">{entries}</VStack>
|
||||
<Box display={isDesktop ? undefined : "none"} w="256px">
|
||||
<Select placeholder="Entry Type">
|
||||
<option value="">All</option>
|
||||
{entryTypes}
|
||||
</Select>
|
||||
</Box>
|
||||
</Flex>
|
||||
</Container>
|
||||
);
|
||||
}
|
Reference in New Issue
Block a user