diff --git a/app/routes/events-team_.outstanding.tsx b/app/routes/events-team_.outstanding.tsx index 8579ff2..9bfb522 100644 --- a/app/routes/events-team_.outstanding.tsx +++ b/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, @@ -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(); @@ -37,6 +51,24 @@ export async function loader({ context }: { context: RequestContext }) { export default function () { const { events, past_cutoff } = useLoaderData(); + 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"; @@ -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 ( <> The cutoff period for retroactively actioning events has passed. + + + This browser is unsupported. Please upgrade to a browser not several + years out of date. + + + + + Action Menu + + + }> + + Completion + + + + {eventData.type === "rotw" ? ( + + Solved Status + + + ) : null} + {eventData.type === "gamenight" ? ( + + Certified Status + + + ) : null} + + + + + + + @@ -73,7 +275,15 @@ export default function () { ))}
{event.details} {getStatus(event)} - +