import { Button, Input, Link, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalOverlay, Radio, RadioGroup, Table, TableContainer, Tbody, Text, Td, Th, Thead, Tr, VStack, useToast } from "@chakra-ui/react"; import { useState } from "react"; export default function(props: { isOpen: boolean; onClose: () => void }) { const actionMap: { [k: string]: number } = {}; const [users, setUsers] = useState([] as string[]); const toast = useToast(); const fileTypes: { [k: string]: string } = { gif: "image/gif", heic: "image/heic", heif: "image/heif", jfif: "image/jpeg", jpeg: "image/jpeg", jpg: "image/jpg", m4v: "video/x-m4v", mkv: "video/x-matroska", mov: "video/mp4", mp4: "video/mp4", png: "image/png", webp: "image/webp", webm: "video/webm", wmv: "video/x-ms-wmv" }; function addUser(user: string) { (document.getElementById("username") as HTMLInputElement).value = ""; const newUsers = [...users]; if (newUsers.includes(user)) return; newUsers.push(user); setUsers(newUsers); } function removeUser(user: string) { const newUsers = [...users]; const userIdx = newUsers.indexOf(user); if (userIdx === -1) return; newUsers.splice(userIdx, 1); setUsers(newUsers); delete actionMap[user]; } function reset() { (document.getElementById("username") as HTMLInputElement).value = ""; (document.getElementById("evidence") as HTMLInputElement).value = ""; setUsers([]); Object.keys(actionMap).forEach((k) => delete actionMap[k]); props.onClose(); } async function submit() { const actions: number[] = []; const usernames: string[] = []; for (const [u, a] of Object.entries(actionMap)) { actions.push(a); usernames.push(u); } if (!usernames.length || !actions.length) return; const files = (document.getElementById("evidence") as HTMLInputElement) .files; if (!files) return; const [evidence] = files; const submitReq = await fetch("/api/reports/submit", { body: JSON.stringify({ actions, bypass: true, filename: evidence.name, filesize: evidence.size, usernames }), headers: { "content-type": "application/json" }, method: "POST" }); if (!submitReq.ok) { toast({ description: ((await submitReq.json()) as { error: string }).error, status: "error", title: "Failed to submit report" }); return; } const { id, upload_url }: { [k: string]: string } = await submitReq.json(); const fileUpload = await fetch(upload_url, { body: evidence, headers: { "content-type": evidence.type || fileTypes[ evidence.name.split(".")[evidence.name.split(".").length - 1] ] }, method: "PUT" }); if (!fileUpload.ok) { await fetch("/api/reports/recall", { body: JSON.stringify({ id }), headers: { "content-type": "application/json" }, method: "POST" }); toast({ description: "Failed to upload file", status: "error", title: "Error" }); return; } await fetch("/api/reports/complete", { body: JSON.stringify({ id }), headers: { "content-type": "application/json" }, method: "POST" }); toast({ description: "User moderated", status: "success", title: "Success" }); } return ( New Game Ban Username(s)

{users.map((user) => ( ))}
Username Punishment  
{user} Object.defineProperty(actionMap, user, { value: parseInt(val) }) } > Do Nothing Hide from Leaderboards Ban


Evidence
); }