import { Button, Container, Divider, Heading, Link, Modal, ModalBody, ModalCloseButton, ModalContent, ModalHeader, ModalOverlay, Table, TableCaption, TableContainer, Tbody, Td, Text, Th, Thead, Tr, useDisclosure, useToast, } from "@chakra-ui/react"; import { type Dispatch, type SetStateAction, useEffect, useState } from "react"; import { useLoaderData } from "@remix-run/react"; export async function loader({ context }: { context: RequestContext }) { const { current_user: currentUser } = context.data; if (!currentUser) throw new Response(null, { status: 401 }); const d1Promises = []; for (const itemType of ["appeals", "inactivity_notices", "reports"]) d1Promises.push( context.env.D1.prepare( `SELECT * FROM ${itemType} WHERE json_extract(user, '$.id') = ? ORDER BY created_at DESC;`, ) .bind(currentUser.id) .all(), ); const settledPromises = await Promise.allSettled(d1Promises); let etData: { [k: string]: any } | null = null; if (currentUser.permissions & (1 << 3)) { etData = await context.env.D1.prepare( "SELECT name, points, roblox_id FROM et_members WHERE id = ?;", ) .bind(currentUser.id) .first(); if (etData) { const now = new Date(); const pointsData = await context.env.D1.prepare( "SELECT answered_at, approved, day, month, performed_at, reached_minimum_player_count, type, year FROM events WHERE created_by = ? AND month = ? AND year = ?;", ) .bind(currentUser.id, now.getUTCMonth(), now.getUTCFullYear()) .all(); for (const row of pointsData.results as Record[]) { if (row.performed_at) etData.points += 10; if (row.type === "gamenight" && row.reached_minimum_player_count) etData.points += 10; if ( row.type === "rotw" && row.answered_at - row.performed_at >= 86400000 ) etData.points += 10; if (!row.performed_at && row.day < now.getUTCDate()) etData.points -= 5; } } } return { etData, items: settledPromises.map((p) => { if (p.status === "fulfilled") return p.value.results; return null; }) as any as ({ [k: string]: any }[] | null)[], permissions: currentUser.permissions as number, }; } export default function () { const data: { etData: { [k: string]: any } | null; items: ({ [k: string]: any }[] | null)[]; permissions: number; } = useLoaderData(); const timeStates: { [k: number]: { data: string; set: Dispatch> }; } = {}; const toast = useToast(); for (const result of data.items) { if (!result) continue; for (const row of result) { const [data, set] = useState(new Date(row.created_at).toUTCString()); timeStates[row.created_at] = { data, set, }; useEffect(() => { timeStates[row.created_at].set( new Date(row.created_at).toLocaleString(), ); }, [row.created_at]); } } async function fetchItem(id: string, type: string) { const itemResp = await fetch(`/api/me/items/${type}/${id}`); if (!itemResp.ok) { let error: string; try { error = ((await itemResp.json()) as { error: string }).error; } catch { error = "Unknown error"; } toast({ description: error, isClosable: true, status: "error", title: "Oops", }); return; } const data: { [k: string]: any } = await itemResp.json(); switch (type) { case "appeal": setModalBody( View Appeal Why were you banned?
{data.ban_reason}

Why should we unban you?
{data.reason_for_unban}

What have you learned from your mistake?
{data.learned}
, ); break; case "inactivity": setModalBody( View Inactivity Notice Reason for Inactivity
{data.reason}

Start Date
{new Date(data.start).toLocaleDateString()}

End Date
{new Date(data.end).toLocaleDateString()}
, ); break; case "report": setModalBody( View Report Username(s)
{data.target_usernames.toString()}

Description
{data.description ?? "No description"}

Media Links
{data.resolved_attachments.map((attachment: string) => ( View media here ))}
, ); break; default: setModalBody(); break; } onOpen(); } const { isOpen, onClose, onOpen } = useDisclosure(); const [modalBody, setModalBody] = useState(); function resetModal() { onClose(); setModalBody(); } return ( {modalBody} My Data

{data.permissions & (1 << 3) ? ( <> Events Team Info Reach out to ETM if this info is incorrect
Name Points Roblox ID
{data.etData?.name} {data.etData?.points} {data.etData?.roblox_id}
) : null} Discord Appeals {data.items[0]?.map((result) => { return ( ); })}
Date ID Status View
{timeStates[result.created_at].data} {result.id} {result.open ? "Pending" : typeof result.approved === "number" ? `${result.approved ? "Accepted" : "Denied"}` : "Unknown"}

{[1 << 2, 1 << 3, 1 << 9, 1 << 10].find((p) => data.permissions & p) ? ( <> Inactivity Notices {data.items[1]?.map((result) => { return ( ); })}
Date ID Status View
{timeStates[result.created_at].data} {result.id} {result.open ? "Pending" : result.approved ? "Approved" : "Denied"}

) : null} Reports {data.items[2]?.map((result) => { return ( ); })}
Date ID Status View
{timeStates[result.created_at].data} {result.id} {result.open ? "Pending" : "Reviewed"}
); }