car-crushers-portal/components/GameAppealCard.tsx

120 lines
3.0 KiB
TypeScript

import {
Box,
Button,
Card,
CardBody,
CardFooter,
CardHeader,
Heading,
Input,
Modal,
ModalBody,
ModalContent,
ModalFooter,
ModalHeader,
Stack,
StackDivider,
Text,
useDisclosure,
useToast,
} from "@chakra-ui/react";
export default function (props: GameAppealProps) {
async function performAction(action: "accept" | "deny"): Promise<void> {
const statsReduction = parseInt(
(document.getElementById("reductPercentage") as HTMLInputElement).value
);
const actionResponse = await fetch(`/api/game-appeals/${props.roblox_id}`, {
body: JSON.stringify({
statsReduction: isNaN(statsReduction) ? 0 : statsReduction,
}),
headers: {
"content-type": "application/json",
},
method: "POST",
});
useToast()(
actionResponse.ok
? {
duration: 5000,
status: "success",
title: `Appeal ${action === "accept" ? "accepted" : "denied"}`,
}
: {
description: `${
((await actionResponse.json()) as { error: string }).error
}`,
duration: 10000,
status: "error",
title: "An error occurred...",
}
);
}
const { isOpen, onClose, onOpen } = useDisclosure();
return (
<Card w="100%">
<CardHeader>
<Heading size="md">Game Ban Appeal for {props.roblox_username}</Heading>
<Text fontSize="xs">ID: {props.roblox_id}</Text>
</CardHeader>
<CardBody>
<Stack divider={<StackDivider />}>
<Box>
<Heading size="xs">Response: Explanation of Ban</Heading>
<Text>{props.whatHappened}</Text>
</Box>
<Box>
<Heading size="xs">Response: Reasoning for Unban</Heading>
<Text>{props.reasonForUnban}</Text>
</Box>
</Stack>
</CardBody>
<CardFooter pb="4px">
<Box>
<Button colorScheme="red">Deny</Button>
<Button colorScheme="blue" ml="8px">
Accept
</Button>
</Box>
</CardFooter>
<Modal isOpen={isOpen} onClose={onClose}>
<ModalContent>
<ModalHeader>
<Heading>
How much should this player's stats be reduced by?
</Heading>
</ModalHeader>
<ModalBody>
<Input
id="reductPercentage"
onBeforeInput={(e) => {
const value = (e.target as EventTarget & { value: string })
.value;
return !value.match(/\D/);
}}
placeholder="Number between 0 and 100"
/>
</ModalBody>
<ModalFooter>
<Button colorScheme="red" onClick={onClose}>
Cancel
</Button>
<Button
colorScheme="blue"
ml="8px"
onClick={async () => await performAction("accept")}
>
Submit
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</Card>
);
}