Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add actual functionality
  • Loading branch information
regalijan committed Nov 18, 2024
1 parent 63802c4 commit 81b411f
Showing 1 changed file with 211 additions and 1 deletion.
212 changes: 211 additions & 1 deletion app/routes/events-team_.outstanding.tsx
@@ -1,7 +1,17 @@
import {
Alert,
AlertIcon,
Box,
Button,
Heading,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
StackDivider,
Table,
TableCaption,
TableContainer,
Expand All @@ -10,8 +20,12 @@ import {
Th,
Thead,
Tr,
useDisclosure,
useToast,
VStack,
} from "@chakra-ui/react";
import { useLoaderData } from "@remix-run/react";
import { useState } from "react";

export async function loader({ context }: { context: RequestContext }) {
const now = new Date();
Expand All @@ -37,6 +51,24 @@ export async function loader({ context }: { context: RequestContext }) {

export default function () {
const { events, past_cutoff } = useLoaderData<typeof loader>();
const { isOpen, onClose, onOpen } = useDisclosure();
const [eventData, setEventData] = useState({} as { [k: string]: any });
const [isBrowserSupported, setIsBrowserSupported] = useState(true);
const toast = useToast();

async function displayErrorToast(response: Response, title: string) {
let msg = "Unknown error";

try {
msg = ((await response.json()) as { error: string }).error;
} catch {}

toast({
description: msg,
status: "error",
title,
});
}

function getStatus(event: { [k: string]: string | number }) {
if (!event.performed_at) return "Approved";
Expand All @@ -47,12 +79,182 @@ export default function () {
return "Completed";
}

async function certify() {
const response = await fetch(
`/api/events-team/events/${eventData.id}/certify`,
{
body: "{}",
headers: {
"content-type": "application/json",
},
method: "POST",
},
);

if (!response.ok) {
await displayErrorToast(response, "Failed to certify game night");
return;
}

toast({
status: "success",
title: "Game night certified",
});

const newData = structuredClone(eventData);
newData.reached_minimum_player_count = 1;

setEventData(newData);
}

async function completed() {
const response = await fetch(
`/api/events-team/events/${eventData.id}/complete`,
{
body: "{}",
headers: {
"content-type": "application/json",
},
method: "POST",
},
);

if (!response.ok) {
await displayErrorToast(response, "Failed to mark as completed");
return;
}

toast({
status: "success",
title: "Event marked as complete",
});

const newData = structuredClone(eventData);
newData.performed_at = Date.now();

setEventData(newData);
}

async function forgotten() {
const response = await fetch(
`/api/events-team/events/${eventData.id}/forgotten`,
{
body: "{}",
headers: {
"content-type": "application/json",
},
method: "POST",
},
);

if (!response.ok) {
await displayErrorToast(response, "Failed to mark as forgotten");
return;
}

toast({
title: "Event marked as forgotten",
status: "success",
});

const newData = structuredClone(eventData);
newData.performed_at = 0;

setEventData(newData);
}

async function solve() {
const response = await fetch(
`/api/events-team/events/${eventData.id}/solve`,
{
body: "{}",
headers: {
"content-type": "application/json",
},
method: "POST",
},
);

if (!response.ok) {
await displayErrorToast(response, "Failed to mark as solved");
return;
}

toast({
status: "success",
title: "Riddle marked as solved",
});

const newData = structuredClone(eventData);
newData.answered_at = Date.now();

setEventData(newData);
}

return (
<>
<Alert display={past_cutoff ? undefined : "none"} status="warning">
<AlertIcon />
The cutoff period for retroactively actioning events has passed.
</Alert>
<Alert display={isBrowserSupported ? undefined : "none"} status="error">
<AlertIcon />
This browser is unsupported. Please upgrade to a browser not several
years out of date.
</Alert>
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Action Menu</ModalHeader>
<ModalCloseButton />
<ModalBody>
<VStack divider={<StackDivider />}>
<Box gap="8px">
<Heading size="xs">Completion</Heading>
<Button
disabled={typeof eventData.completed_at === "number"}
onClick={async () => await completed()}
>
Mark as Complete
</Button>
<Button
disabled={typeof eventData.completed_at === "number"}
onClick={async () => await forgotten()}
>
Mark as Forgotten
</Button>
</Box>
{eventData.type === "rotw" ? (
<Box gap="8px">
<Heading size="xs">Solved Status</Heading>
<Button
disabled={Boolean(eventData.answered_at)}
onClick={async () => await solve()}
>
{eventData.answered_at ? "Solved" : "Mark as Solved"}
</Button>
</Box>
) : null}
{eventData.type === "gamenight" ? (
<Box gap="8px">
<Heading size="xs">Certified Status</Heading>
<Button
disabled={Boolean(eventData.reached_minimum_player_count)}
onClick={async () => await certify()}
>
{eventData.reached_minimum_player_count
? "Certified"
: "Certify"}
</Button>
</Box>
) : null}
</VStack>
</ModalBody>
<ModalFooter>
<Button onClick={onClose}>Close</Button>
</ModalFooter>
</ModalContent>
</Modal>
<TableContainer>
<Table variant="simple">
<TableCaption>
Expand All @@ -73,7 +275,15 @@ export default function () {
<Td>{event.details}</Td>
<Td>{getStatus(event)}</Td>
<Td>
<Button>Action Menu</Button>
<Button
disabled={past_cutoff}
onClick={() => {
setEventData(event);
onOpen();
}}
>
Action Menu
</Button>
</Td>
</Tr>
))}
Expand Down

0 comments on commit 81b411f

Please sign in to comment.