New page
This commit is contained in:
174
app/routes/gmm.tsx
Normal file
174
app/routes/gmm.tsx
Normal file
@@ -0,0 +1,174 @@
|
||||
import {
|
||||
Button,
|
||||
Container,
|
||||
FormControl,
|
||||
FormLabel,
|
||||
Input,
|
||||
Modal,
|
||||
ModalBody,
|
||||
ModalCloseButton,
|
||||
ModalContent,
|
||||
ModalFooter,
|
||||
ModalHeader,
|
||||
ModalOverlay,
|
||||
Table,
|
||||
TableCaption,
|
||||
TableContainer,
|
||||
Tbody,
|
||||
Td,
|
||||
Th,
|
||||
Thead,
|
||||
Tr,
|
||||
useDisclosure,
|
||||
useToast,
|
||||
} from "@chakra-ui/react";
|
||||
import { useLoaderData } from "@remix-run/react";
|
||||
import { useState } from "react";
|
||||
|
||||
export async function loader({ context }: { context: RequestContext }) {
|
||||
if (!context.data.current_user)
|
||||
throw new Response(null, {
|
||||
status: 401,
|
||||
});
|
||||
|
||||
if (
|
||||
![
|
||||
"165594923586945025",
|
||||
"289372404541554689",
|
||||
"396347223736057866",
|
||||
].includes(context.data.current_user.id)
|
||||
)
|
||||
throw new Response(null, {
|
||||
status: 403,
|
||||
});
|
||||
|
||||
return (await context.env.DATA.list({ prefix: "gamemod_" }))?.keys ?? [];
|
||||
}
|
||||
|
||||
export default function () {
|
||||
const data: { [k: string]: any }[] = useLoaderData<typeof loader>();
|
||||
const { isOpen, onClose, onOpen } = useDisclosure();
|
||||
const [idToAdd, setIdToAdd] = useState<string>("");
|
||||
const [nameToAdd, setNameToAdd] = useState<string>("");
|
||||
const toast = useToast();
|
||||
|
||||
async function addMod(id: string, name: string) {
|
||||
const response = await fetch("/api/gme/add", {
|
||||
body: JSON.stringify({ name, user: id }),
|
||||
headers: {
|
||||
"content-type": "application/json",
|
||||
},
|
||||
method: "POST",
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
let msg = "Unknown error";
|
||||
|
||||
try {
|
||||
msg = ((await response.json()) as { error: string }).error;
|
||||
} catch {}
|
||||
|
||||
toast({
|
||||
description: msg,
|
||||
status: "error",
|
||||
title: "Cannot add game mod",
|
||||
});
|
||||
} else {
|
||||
toast({
|
||||
description: `${name} was added as a game mod`,
|
||||
status: "success",
|
||||
title: "Game mod added",
|
||||
});
|
||||
}
|
||||
|
||||
setIdToAdd("");
|
||||
setNameToAdd("");
|
||||
}
|
||||
|
||||
return (
|
||||
<Container maxW="container.lg">
|
||||
<TableContainer>
|
||||
<Table variant="simple">
|
||||
<TableCaption>Currently active game mods</TableCaption>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th>ID</Th>
|
||||
<Th>Name</Th>
|
||||
<Th>Added At</Th>
|
||||
<Th>Added By</Th>
|
||||
<Th>Remove</Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{data.map((item) => {
|
||||
return (
|
||||
<Tr key={item.metadata.id}>
|
||||
<Td>{item.metadata.id}</Td>
|
||||
<Td>{item.metadata.name}</Td>
|
||||
<Td>{item.metadata.created_at}</Td>
|
||||
<Td>{item.metadata.created_by}</Td>
|
||||
<Td>
|
||||
<Button>Remove</Button>
|
||||
</Td>
|
||||
</Tr>
|
||||
);
|
||||
})}
|
||||
</Tbody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
<Button alignSelf="end" onClick={onOpen} pt="16px">
|
||||
Add
|
||||
</Button>
|
||||
<Modal isOpen={isOpen} onClose={onClose}>
|
||||
<ModalOverlay />
|
||||
<ModalContent>
|
||||
<ModalHeader>Add Game Mod</ModalHeader>
|
||||
<ModalCloseButton />
|
||||
<ModalBody>
|
||||
<FormControl>
|
||||
<FormLabel>Name</FormLabel>
|
||||
<Input
|
||||
maxLength={32}
|
||||
onChange={(e) => setNameToAdd(e.target.value)}
|
||||
value={nameToAdd}
|
||||
/>
|
||||
</FormControl>
|
||||
<br />
|
||||
<FormControl pt="16px">
|
||||
<FormLabel>ID</FormLabel>
|
||||
<Input
|
||||
maxLength={19}
|
||||
onChange={(e) => setIdToAdd(e.target.value)}
|
||||
value={idToAdd}
|
||||
/>
|
||||
</FormControl>
|
||||
</ModalBody>
|
||||
<ModalFooter gap="8px">
|
||||
<Button
|
||||
onClick={() => {
|
||||
setIdToAdd("");
|
||||
setNameToAdd("");
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
colorScheme="blue"
|
||||
disabled={
|
||||
idToAdd.length < 17 ||
|
||||
idToAdd.length > 19 ||
|
||||
nameToAdd.length < 1 ||
|
||||
nameToAdd.length > 32
|
||||
}
|
||||
onClick={async () => {
|
||||
await addMod(idToAdd, nameToAdd);
|
||||
}}
|
||||
>
|
||||
Add
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
import { jsonError } from "../../common.js";
|
||||
|
||||
export async function onRequestPost(context: RequestContext) {
|
||||
const { user } = context.data.body;
|
||||
const { user, name } = context.data.body;
|
||||
|
||||
if (!user) return jsonError("No user provided", 400);
|
||||
|
||||
if (typeof name !== "string" || name.length > 32)
|
||||
return jsonError("Invalid name", 400);
|
||||
|
||||
const existingUser = await context.env.DATA.get(`gamemod_${user}`);
|
||||
|
||||
if (existingUser) return jsonError("Cannot add an existing user", 400);
|
||||
@@ -21,9 +24,10 @@ export async function onRequestPost(context: RequestContext) {
|
||||
if (!user.match(/^\d{17,19}$/)) return jsonError("Invalid User ID", 400);
|
||||
|
||||
const data = {
|
||||
time: Date.now(),
|
||||
user: context.data.current_user.id,
|
||||
name: context.data.current_user.username,
|
||||
created_at: Date.now(),
|
||||
created_by: context.data.current_user.id,
|
||||
id: user,
|
||||
name,
|
||||
};
|
||||
|
||||
await context.env.DATA.put(`gamemod_${user}`, JSON.stringify(data), {
|
||||
|
||||
Reference in New Issue
Block a user