152 lines
4.0 KiB
TypeScript
152 lines
4.0 KiB
TypeScript
import {
|
|
Button,
|
|
Input,
|
|
Modal,
|
|
ModalBody,
|
|
ModalCloseButton,
|
|
ModalContent,
|
|
ModalFooter,
|
|
ModalHeader,
|
|
ModalOverlay,
|
|
Select,
|
|
Text,
|
|
useToast,
|
|
} from "@chakra-ui/react";
|
|
|
|
export default function (props: { isOpen: boolean; onClose: () => void }) {
|
|
function pasteHandler(e: ClipboardEvent) {
|
|
if (!props.isOpen) return;
|
|
|
|
const evidenceElement = document.getElementById(
|
|
"evidence"
|
|
) as HTMLInputElement;
|
|
|
|
if (!evidenceElement.files && e.clipboardData?.files) {
|
|
evidenceElement.files = e.clipboardData.files;
|
|
return;
|
|
}
|
|
|
|
if (!evidenceElement.files || !e.clipboardData?.files.length) return;
|
|
|
|
if (typeof window["DataTransfer"] === "undefined")
|
|
return alert("Your browser is too old to paste images in.");
|
|
|
|
const dataTransfer = new DataTransfer();
|
|
|
|
for (const file of evidenceElement.files) dataTransfer.items.add(file);
|
|
|
|
dataTransfer.items.add(e.clipboardData.files[0]);
|
|
|
|
evidenceElement.files = dataTransfer.files;
|
|
}
|
|
|
|
addEventListener("paste", pasteHandler);
|
|
|
|
function reset() {
|
|
removeEventListener("paste", pasteHandler);
|
|
(
|
|
document.getElementById("punishment") as unknown as HTMLSelectElement
|
|
).selectedIndex = -1;
|
|
(document.getElementById("user") as HTMLInputElement).value = "";
|
|
(document.getElementById("evidence") as HTMLInputElement).files = null;
|
|
|
|
props.onClose();
|
|
}
|
|
async function submit() {
|
|
const form = new FormData();
|
|
const { files } = document.getElementById("evidence") as HTMLInputElement;
|
|
const punishment = (
|
|
document.getElementById("punishment") as unknown as HTMLSelectElement
|
|
).item(0)?.value as string;
|
|
const { value: user } = document.getElementById("user") as HTMLInputElement;
|
|
|
|
form.append("user", user);
|
|
form.append("punishment", punishment);
|
|
|
|
if (files) {
|
|
for (let i = 0; i < files.length; i++)
|
|
form.append(`file${i}`, files[i], files[i].name);
|
|
}
|
|
|
|
const postReq = await fetch("/api/infractions/new", {
|
|
body: form,
|
|
method: "POST",
|
|
});
|
|
|
|
if (postReq.ok) {
|
|
useToast()({
|
|
description: "Infraction created",
|
|
duration: 5000,
|
|
isClosable: true,
|
|
status: "success",
|
|
title: "Success",
|
|
});
|
|
|
|
props.onClose();
|
|
|
|
return;
|
|
}
|
|
|
|
useToast()({
|
|
description: `Failed to create infraction (${
|
|
((await postReq.json()) as { error: string }).error
|
|
})`,
|
|
duration: 5000,
|
|
isClosable: true,
|
|
status: "error",
|
|
title: "Error",
|
|
});
|
|
}
|
|
|
|
return (
|
|
<Modal
|
|
closeOnEsc={false}
|
|
closeOnOverlayClick={false}
|
|
isCentered
|
|
isOpen={props.isOpen}
|
|
onClose={props.onClose}
|
|
>
|
|
<ModalOverlay />
|
|
<ModalContent>
|
|
<ModalHeader>New Infraction</ModalHeader>
|
|
<ModalCloseButton />
|
|
<ModalBody>
|
|
<Text>User ID</Text>
|
|
<Input id="user" placeholder="1234567890987654321" />
|
|
<br />
|
|
<br />
|
|
<Text>Punishment</Text>
|
|
<Select id="punishment" placeholder="Select punishment">
|
|
<option value="verbal">Verbal Warning</option>
|
|
<option value="warn">Warning</option>
|
|
<option value="mute">Mute</option>
|
|
<option value="ban_temp">Temporary Ban</option>
|
|
<option value="ban_perm">Permanent Ban</option>
|
|
<option value="ban_unappealable">Unappealable Permanent Ban</option>
|
|
</Select>
|
|
<br />
|
|
<br />
|
|
<Text>Evidence</Text>
|
|
<Button
|
|
onClick={() => document.getElementById("evidence")?.click()}
|
|
mr="8px"
|
|
>
|
|
Select Files
|
|
</Button>
|
|
<input id="evidence" multiple type="file" />
|
|
</ModalBody>
|
|
<ModalFooter>
|
|
<Button onClick={reset}>Cancel</Button>
|
|
<Button
|
|
colorScheme="blue"
|
|
ml="8px"
|
|
onClick={async () => await submit()}
|
|
>
|
|
Submit
|
|
</Button>
|
|
</ModalFooter>
|
|
</ModalContent>
|
|
</Modal>
|
|
);
|
|
}
|