car-crushers-portal/components/NewInfractionModal.tsx
2023-10-19 16:50:21 -04:00

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>
);
}