import { Box, Button, Card, CardBody, CardFooter, CardHeader, Heading, HStack, Radio, RadioGroup, Spacer, Stack, Text, useToast, VStack, } from "@chakra-ui/react"; import { useState } from "react"; export default function (props: ReportCardProps & { port?: MessagePort }) { const [attachmentIdx, setAttachmentIdx] = useState(0); const [loading, setLoading] = useState(false); const toast = useToast(); const targetMap: { [k: number]: string } = {}; const actionMap: { [k: number]: number } = {}; for (let i = 0; i < props.target_ids.length; i++) targetMap[props.target_ids[i]] = props.target_usernames[i]; async function submitActions() { setLoading(true); const submitReq = await fetch(`/api/reports/${props.id}/action`, { body: JSON.stringify(actionMap), headers: { "content-type": "application/json", }, method: "POST", }); if (!submitReq.ok) { setLoading(false); toast({ description: ((await submitReq.json()) as { error: string }).error, status: "error", title: "S̸̯̜̈́o̴̳̅̾̏̽m̴͔͕̈́̋ē̴̙͓̯̍̃ț̸͖̘̀h̶̛̳̝̐i̵̋͘͜ņ̷̙̤͌g̴̭̻̓̈́ ̴̘͍̦̪̆w̸̡̏̑̊é̸̠̖̹̂͜n̴̖̳̤̕t̴͚̊̊̕ ̸̛͙̺̬̎́w̴͈͑̋͊r̷̢̛o̵̱̩̍͋ͅṇ̸̝̰̮́g̵̡̢̦͕͂", }); return; } toast({ description: "Actions were successfully applied", status: "success", title: "Success", }); setLoading(false); props.port?.postMessage(`report_${props.id}`); } return ( <Card key={props.id} w="100%"> <CardHeader> <Heading size="lg"> Report for {props.target_usernames.toString()} </Heading> <Text fontSize="xs">ID(s): {props.target_ids.toString()}</Text> </CardHeader> <CardBody> <div style={{ position: "relative" }}> <video controls={true} width="100%"> <source src={`/api/uploads/${props.attachments[attachmentIdx]}`} /> <source src="/files/processing.webm" /> </video> <HStack pos="absolute" top="50%" transform="translate(5%, -50%)" w="90%" zIndex="1" > <Button borderRadius="50%" h="16" onClick={() => setAttachmentIdx(attachmentIdx - 1)} visibility={attachmentIdx > 0 ? "visible" : "hidden"} w="16" > <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" viewBox="0 0 16 16" > <path fillRule="evenodd" d="M12 8a.5.5 0 0 1-.5.5H5.707l2.147 2.146a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708l3-3a.5.5 0 1 1 .708.708L5.707 7.5H11.5a.5.5 0 0 1 .5.5z" /> </svg> </Button> <Spacer /> <Button borderRadius="50%" h="16" onClick={() => setAttachmentIdx(attachmentIdx + 1)} visibility={ props.attachments.length > attachmentIdx + 1 ? "visible" : "hidden" } w="16" > <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" viewBox="0 0 16 16" > <path fillRule="evenodd" d="M4 8a.5.5 0 0 1 .5-.5h5.793L8.146 5.354a.5.5 0 1 1 .708-.708l3 3a.5.5 0 0 1 0 .708l-3 3a.5.5 0 0 1-.708-.708L10.293 8.5H4.5A.5.5 0 0 1 4 8z" /> </svg> </Button> </HStack> </div> <br /> <Text my="16px">{props.description}</Text> </CardBody> <CardFooter display={props.open ? undefined : "none"}> <Stack direction="column" gap="16px"> {(function () { const radioGroups = []; for (let i = 0; i < props.target_ids.length; i++) { radioGroups.push( <RadioGroup name={props.target_ids[i].toString()} onChange={(val) => { actionMap[props.target_ids[i]] = parseInt(val); }} > <VStack alignItems="flex-start"> <Text>{props.target_usernames[i]}</Text> <Radio key={0} value="0"> Ignore </Radio> <Radio key={1} value="1"> Hide from Leaderboards </Radio> <Radio key={2} value="2"> Ban </Radio> </VStack> </RadioGroup>, ); } return radioGroups; })()} <Box pt="16px"> <Button colorScheme="blue" onClick={async () => await submitActions()} isLoading={loading} loadingText="Submitting..." > Submit </Button> </Box> </Stack> </CardFooter> </Card> ); }