Add completion and answered marking

This commit is contained in:
Regalijan 2024-03-05 17:42:38 -05:00
parent ff61311e7c
commit a4c8781f9d
Signed by: regalijan
GPG Key ID: 5D4196DA269EF520
3 changed files with 190 additions and 12 deletions

View File

@ -84,6 +84,16 @@ export default function () {
} = useLoaderData<typeof loader>(); } = useLoaderData<typeof loader>();
const [eventData, setEventData] = useState(events); const [eventData, setEventData] = useState(events);
const { isOpen, onClose, onOpen } = useDisclosure(); const { isOpen, onClose, onOpen } = useDisclosure();
const {
isOpen: isCompleteOpen,
onClose: closeComplete,
onOpen: openComplete,
} = useDisclosure();
const {
isOpen: isAnsweredOpen,
onClose: closeAnswered,
onOpen: openAnswered,
} = useDisclosure();
const toast = useToast(); const toast = useToast();
const [selectedEvent, setSelectedEvent] = useState(""); const [selectedEvent, setSelectedEvent] = useState("");
@ -160,16 +170,92 @@ export default function () {
toast({ toast({
description: "Game night certified", description: "Game night certified",
status: "success",
title: "Success", title: "Success",
}); });
const newEventData = eventData; const newEventData = eventData;
newEventData[ newEventData[
eventData.findIndex((e) => e.id === eventId) eventData.findIndex((e) => e.id === eventId)
].reached_minimum_player_count = true; ].reached_minimum_player_count = true;
setEventData([...newEventData]); setEventData([...newEventData]);
setSelectedEvent("");
}
async function markAnswered(eventId: string) {
const answerResp = await fetch(`/api/events-team/events/${eventId}/solve`, {
body: "{}",
headers: {
"content-type": "application/json",
},
method: "POST",
});
closeAnswered();
if (!answerResp.ok) {
toast({
description: "Failed to mark as solved",
status: "error",
title: "Oops",
});
return;
}
const newEventData = eventData;
newEventData[eventData.findIndex((e) => e.id === eventId)].answered_at =
Date.now();
setEventData([...newEventData]);
setSelectedEvent("");
}
async function markComplete(eventId: string) {
const completeResp = await fetch(
`/api/events-team/events/${eventId}/complete`,
{
body: "{}",
headers: {
"content-type": "application/json",
},
method: "POST",
},
);
closeComplete();
if (!completeResp.ok) {
let msg = "Unknown error";
try {
msg = ((await completeResp.json()) as { error: string }).error;
} catch {}
toast({
description: msg,
status: "error",
title: "Failed to complete",
});
return;
}
toast({
description: "Event marked as completed",
status: "success",
title: "Success",
});
const newEventData = eventData;
// Technically this won't be the same as the time in the db, but that doesn't matter since this is just to hide the button
newEventData[eventData.findIndex((e) => e.id === eventId)].performed_at =
Date.now();
setEventData([...newEventData]);
setSelectedEvent("");
} }
return ( return (
@ -202,6 +288,49 @@ export default function () {
</ModalFooter> </ModalFooter>
</ModalContent> </ModalContent>
</Modal> </Modal>
<Modal isOpen={isCompleteOpen} onClose={closeComplete}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Mark as Completed</ModalHeader>
<ModalCloseButton />
<ModalBody>
<Text>
By marking this event as completed, you confirm that the event
creator has performed this event
</Text>
</ModalBody>
<ModalFooter>
<Button onClick={closeComplete}>Cancel</Button>
<Button
colorScheme="blue"
ml="8px"
onClick={async () => await markComplete(selectedEvent)}
>
Mark as Complete
</Button>
</ModalFooter>
</ModalContent>
</Modal>
<Modal isOpen={isAnsweredOpen} onClose={closeAnswered}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Mark as Solved</ModalHeader>
<ModalCloseButton />
<ModalBody>
<Text>Are you sure you want to mark this riddle as solved?</Text>
</ModalBody>
<ModalFooter>
<Button onClick={closeAnswered}>Cancel</Button>
<Button
colorScheme="blue"
ml="8px"
onClick={async () => await markAnswered(selectedEvent)}
>
Mark Answered
</Button>
</ModalFooter>
</ModalContent>
</Modal>
<VStack spacing="8"> <VStack spacing="8">
{eventData.map((event) => { {eventData.map((event) => {
const eventCreatorName = members.find( const eventCreatorName = members.find(
@ -266,11 +395,37 @@ export default function () {
</Button> </Button>
</> </>
) : null} ) : null}
{can_approve && !event.pending && !event.performed_at ? (
<Button
colorScheme="blue"
onClick={() => {
setSelectedEvent(event.id);
openComplete();
}}
>
Mark as Completed
</Button>
) : null}
{can_approve &&
!event.pending &&
event.performed_at &&
event.type === "rotw" &&
!event.answered_at ? (
<Button
colorScheme="blue"
onClick={() => {
setSelectedEvent(event.id);
openAnswered();
}}
>
Mark as Solved
</Button>
) : null}
{can_approve && {can_approve &&
event.approved && event.approved &&
event.type === "gamenight" && event.type === "gamenight" &&
event.performed_at &&
!event.reached_minimum_player_count ? ( !event.reached_minimum_player_count ? (
<>
<Button <Button
colorScheme="blue" colorScheme="blue"
onClick={() => { onClick={() => {
@ -280,7 +435,6 @@ export default function () {
> >
Certify Game Night Certify Game Night
</Button> </Button>
</>
) : null} ) : null}
</Flex> </Flex>
<Text alignSelf="center" fontSize="sm"> <Text alignSelf="center" fontSize="sm">

View File

@ -0,0 +1,13 @@
export async function onRequestPost(context: RequestContext) {
const id = context.params.id as string;
await context.env.D1.prepare(
"UPDATE events SET performed_at = ? WHERE id = ?;",
)
.bind(Date.now(), id)
.run();
return new Response(null, {
status: 204,
});
}

View File

@ -0,0 +1,11 @@
export async function onRequestPost(context: RequestContext) {
await context.env.D1.prepare(
"UPDATE events SET answered_at = ? WHERE id = ?;",
)
.bind(Date.now(), context.params.id)
.run();
return new Response(null, {
status: 204,
});
}