From 0a4ad7792daa0efc05001b95268b11164585115c Mon Sep 17 00:00:00 2001 From: regalijan Date: Thu, 19 Oct 2023 16:50:58 -0400 Subject: [PATCH] Oh yeah I forgot the other half --- app/routes/appeals.tsx | 13 +++++++++++-- app/routes/data-transfer/start.tsx | 5 +++++ app/routes/report.tsx | 23 +++++++++++++++++++---- components/AppealCard.tsx | 7 +++++++ components/GameAppealCard.tsx | 7 +++++++ components/InactivityNoticeCard.tsx | 9 +++++++++ components/NewGameBan.tsx | 13 ++++++++++++- components/NewInactivityNotice.tsx | 18 ++++++++++++++++-- components/NewInfractionModal.tsx | 2 ++ components/ReportCard.tsx | 6 ++++++ components/Success.tsx | 6 ++---- 11 files changed, 96 insertions(+), 13 deletions(-) diff --git a/app/routes/appeals.tsx b/app/routes/appeals.tsx index 793f19a..09ffb3c 100644 --- a/app/routes/appeals.tsx +++ b/app/routes/appeals.tsx @@ -64,9 +64,11 @@ export default function () { const pageProps = useLoaderData(); const { isOpen, onClose, onOpen } = useDisclosure(); const [showSuccess, setShowSuccess] = useState(false); + const [loading, setLoading] = useState(false) const toast = useToast(); async function submit() { + setLoading(true) const learned = (document.getElementById("learned") as HTMLInputElement) .value; const whyBanned = (document.getElementById("whyBanned") as HTMLInputElement) @@ -86,7 +88,8 @@ export default function () { method: "POST", }).catch(() => {}); - if (!submitReq) + if (!submitReq) { + setLoading(false) return toast({ description: "Please check your internet and try again", duration: 10000, @@ -94,8 +97,10 @@ export default function () { status: "error", title: "Request Failed", }); + } - if (!submitReq.ok) + if (!submitReq.ok) { + setLoading(false) return toast({ description: ((await submitReq.json()) as { error: string }).error, duration: 10000, @@ -103,8 +108,10 @@ export default function () { status: "error", title: "Error", }); + } setShowSuccess(true); + setLoading(false) } async function toggle(active: boolean) { @@ -232,6 +239,8 @@ export default function () { diff --git a/app/routes/data-transfer/start.tsx b/app/routes/data-transfer/start.tsx index 2ad1f4d..ee2694a 100644 --- a/app/routes/data-transfer/start.tsx +++ b/app/routes/data-transfer/start.tsx @@ -13,6 +13,7 @@ import { useState } from "react"; export default function () { const [showCookieBox, setShowCookieBox] = useState(false); + const [loading, setLoading] = useState(false) return ( Let's get started @@ -31,6 +32,7 @@ export default function () { /> diff --git a/app/routes/report.tsx b/app/routes/report.tsx index 248e8df..3320ef1 100644 --- a/app/routes/report.tsx +++ b/app/routes/report.tsx @@ -42,6 +42,7 @@ export default function () { const [supportsRequestStreams, setSupportsRequestStreams] = useState(false); const toast = useToast(); const [uploading, setUploading] = useState(false); + const [loading, setLoading] = useState(false) const fileTypes: { [k: string]: string } = { gif: "image/gif", m4v: "video/x-m4v", @@ -75,6 +76,7 @@ export default function () { const { logged_in, site_key } = useLoaderData(); async function submit() { + setLoading(true) const usernames = ( document.getElementById("usernames") as HTMLInputElement ).value @@ -83,29 +85,35 @@ export default function () { const files = (document.getElementById("evidence") as HTMLInputElement) .files; - if (!usernames.length) + if (!usernames.length) { + setLoading(false) return toast({ description: "Must provide at least one username", isClosable: true, status: "error", title: "Error", }); + } - if (!files?.length) + if (!files?.length) { + setLoading(false) return toast({ description: "Must attach at least one file", isClosable: true, status: "error", title: "Error", }); + } - if (usernames.length > 20) + if (usernames.length > 20) { + setLoading(false) return toast({ description: "Only up to twenty users can be reported at a time", isClosable: true, status: "error", title: "Too Many Usernames", }); + } let turnstileToken = ""; @@ -114,13 +122,15 @@ export default function () { .getElementsByName("cf-turnstile-response") .item(0) as HTMLInputElement; - if (!tokenElem.value) + if (!tokenElem.value) { + setLoading(false) return toast({ description: "Please complete the captcha and try again", isClosable: true, status: "error", title: "Captcha not completed", }); + } turnstileToken = tokenElem.value; } @@ -150,6 +160,7 @@ export default function () { }); if (!submitReq.ok) { + setLoading(false) if (!logged_in) { try { // @ts-expect-error @@ -224,6 +235,7 @@ export default function () { } if (shouldRecall) { + setLoading(false) await fetch("/api/reports/recall", { body: JSON.stringify({ id }), headers: { @@ -252,6 +264,7 @@ export default function () { }); setShowSuccess(true); + setLoading(false) } useEffect(() => { @@ -319,6 +332,8 @@ export default function () { disabled={uploading} mr="8px" onClick={async () => await submit()} + loadingText='Submitting' + isLoading={loading} > Submit diff --git a/components/AppealCard.tsx b/components/AppealCard.tsx index 03fd29f..de16e36 100644 --- a/components/AppealCard.tsx +++ b/components/AppealCard.tsx @@ -27,6 +27,7 @@ export default function (props: AppealCardProps) { ); const [action, setAction] = useState(""); const [feedback, setFeedback] = useState(""); + const [loading, setLoading] = useState(false) const toast = useToast(); useEffect(() => { @@ -41,6 +42,7 @@ export default function (props: AppealCardProps) { } async function takeAction(action: string) { + setLoading(true) const actionReq = await fetch(`/api/appeals/${props.id}/${action}`, { body: feedback ? JSON.stringify({ feedback }) : "{}", headers: { @@ -50,6 +52,7 @@ export default function (props: AppealCardProps) { }); if (actionReq.ok) { + setLoading(false) toast({ description: `Appeal ${action === "accept" ? "accepted" : "denied"}`, duration: 5000, @@ -59,6 +62,7 @@ export default function (props: AppealCardProps) { document.getElementById(`appeal_${props.id}`)?.remove(); } else { + setLoading(false) toast({ description: ((await actionReq.json()) as { error: string }).error, duration: 10000, @@ -68,6 +72,7 @@ export default function (props: AppealCardProps) { } onClose(); + setLoading(false) } return ( @@ -86,6 +91,8 @@ export default function (props: AppealCardProps) { diff --git a/components/GameAppealCard.tsx b/components/GameAppealCard.tsx index 97a0c6c..72af496 100644 --- a/components/GameAppealCard.tsx +++ b/components/GameAppealCard.tsx @@ -18,9 +18,12 @@ import { useDisclosure, useToast, } from "@chakra-ui/react"; +import { useState } from "react"; export default function (props: GameAppealProps) { + const [loading, setLoading] = useState(false) async function performAction(action: "accept" | "deny"): Promise { + setLoading(true) const statsReduction = parseInt( (document.getElementById("reductPercentage") as HTMLInputElement).value, ); @@ -51,6 +54,8 @@ export default function (props: GameAppealProps) { title: "An error occurred...", }, ); + + setLoading(false) } const { isOpen, onClose, onOpen } = useDisclosure(); @@ -108,6 +113,8 @@ export default function (props: GameAppealProps) { colorScheme="blue" ml="8px" onClick={async () => await performAction("accept")} + isLoading={loading} + loadingText='Submitting...' > Submit diff --git a/components/InactivityNoticeCard.tsx b/components/InactivityNoticeCard.tsx index b108a70..49a0010 100644 --- a/components/InactivityNoticeCard.tsx +++ b/components/InactivityNoticeCard.tsx @@ -13,11 +13,14 @@ import { UnorderedList, useToast } from "@chakra-ui/react"; +import { useState } from "react"; export default function(props: InactivityNoticeProps) { const toast = useToast(); + const [loading, setLoading] = useState(false) async function makeDecision(accepted: boolean) { + setLoading(true) const decisionReq = await fetch(`/api/inactivity/${props.id}`, { body: JSON.stringify({ accepted }), headers: { @@ -27,6 +30,7 @@ export default function(props: InactivityNoticeProps) { }); if (!decisionReq.ok) { + setLoading(false) toast({ description: ((await decisionReq.json()) as { error: string }).error, isClosable: true, @@ -44,6 +48,7 @@ export default function(props: InactivityNoticeProps) { title: "Success" }); + setLoading(false) location.reload(); } @@ -103,6 +108,8 @@ export default function(props: InactivityNoticeProps) { @@ -110,6 +117,8 @@ export default function(props: InactivityNoticeProps) { colorScheme="blue" ml="8px" onClick={async () => await makeDecision(true)} + isLoading={loading} + loadingText='Processing...' > Accept diff --git a/components/NewGameBan.tsx b/components/NewGameBan.tsx index a8a6e47..c217cc7 100644 --- a/components/NewGameBan.tsx +++ b/components/NewGameBan.tsx @@ -27,6 +27,7 @@ import { useState } from "react"; export default function(props: { isOpen: boolean; onClose: () => void }) { const actionMap: { [k: string]: number } = {}; const [users, setUsers] = useState([] as string[]); + const [loading, setLoading] = useState(true) const toast = useToast(); const fileTypes: { [k: string]: string } = { gif: "image/gif", @@ -79,6 +80,7 @@ export default function(props: { isOpen: boolean; onClose: () => void }) { } async function submit() { + setLoading(true) const actions: number[] = []; const usernames: string[] = []; @@ -92,7 +94,10 @@ export default function(props: { isOpen: boolean; onClose: () => void }) { const files = (document.getElementById("evidence") as HTMLInputElement) .files; - if (!files) return; + if (!files) { + setLoading(false) + return + } const [evidence] = files; @@ -111,6 +116,7 @@ export default function(props: { isOpen: boolean; onClose: () => void }) { }); if (!submitReq.ok) { + setLoading(false) toast({ description: ((await submitReq.json()) as { error: string }).error, status: "error", @@ -135,6 +141,7 @@ export default function(props: { isOpen: boolean; onClose: () => void }) { }); if (!fileUpload.ok) { + setLoading(false) await fetch("/api/reports/recall", { body: JSON.stringify({ id }), headers: { @@ -165,6 +172,8 @@ export default function(props: { isOpen: boolean; onClose: () => void }) { status: "success", title: "Success" }); + + setLoading(false) } return ( @@ -276,6 +285,8 @@ export default function(props: { isOpen: boolean; onClose: () => void }) { } ml="8px" onClick={async () => await submit()} + isLoading={loading} + loadingText='Submitting...' > Submit diff --git a/components/NewInactivityNotice.tsx b/components/NewInactivityNotice.tsx index 9c32d8c..c26466f 100644 --- a/components/NewInactivityNotice.tsx +++ b/components/NewInactivityNotice.tsx @@ -22,6 +22,7 @@ export default function(props: { onClose: () => void; }) { const [departments, setDepartments] = useState([] as string[]); + const [loading, setLoading] = useState(false) const toast = useToast(); function reset() { @@ -33,13 +34,22 @@ export default function(props: { } async function submit() { + setLoading(true) const start = (document.getElementById("start") as HTMLInputElement).value; const end = (document.getElementById("start") as HTMLInputElement).value; const reason = (document.getElementById("reason") as HTMLTextAreaElement) .value; - if (!departments.length) - return alert("You need to select at least one department!"); + if (!departments.length) { + toast({ + title: 'Validation Error', + description: 'You need to select at least one department', + status: "error" + }) + + setLoading(false) + return; + } const inactivityPost = await fetch("/api/inactivity/new", { body: JSON.stringify({ @@ -55,6 +65,7 @@ export default function(props: { }); if (!inactivityPost.ok) { + setLoading(false) toast({ description: ((await inactivityPost.json()) as { error: string }).error, duration: 10000, @@ -74,6 +85,7 @@ export default function(props: { title: "Success" }); + setLoading(true) props.onClose(); } @@ -116,6 +128,8 @@ export default function(props: { colorScheme="blue" ml="8px" onClick={async () => await submit()} + isLoading={loading} + loadingText='Submitting...' > Submit diff --git a/components/NewInfractionModal.tsx b/components/NewInfractionModal.tsx index 4a362bf..d701491 100644 --- a/components/NewInfractionModal.tsx +++ b/components/NewInfractionModal.tsx @@ -157,6 +157,8 @@ export default function (props: { isOpen: boolean; onClose: () => void }) { colorScheme="blue" ml="8px" onClick={async () => await submit()} + isLoading={loading} + loadingText="Submitting..." > Submit diff --git a/components/ReportCard.tsx b/components/ReportCard.tsx index 23ceabb..29ee037 100644 --- a/components/ReportCard.tsx +++ b/components/ReportCard.tsx @@ -18,6 +18,7 @@ import { useState } from "react"; export default function (props: ReportCardProps) { const [attachmentIdx, setAttachmentIdx] = useState(0); + const [loading, setLoading] = useState(false) const toast = useToast(); const targetMap: { [k: number]: string } = {}; const [attachmentsReady, setAttachmentReady] = useState( @@ -43,6 +44,7 @@ export default function (props: ReportCardProps) { } async function submitActions() { + setLoading(true) const submitReq = await fetch(`/api/reports/${props.id}/action`, { body: JSON.stringify(actionMap), headers: { @@ -52,6 +54,7 @@ export default function (props: ReportCardProps) { }); if (!submitReq.ok) { + setLoading(false) toast({ description: ((await submitReq.json()) as { error: string }).error, status: "error", @@ -66,6 +69,7 @@ export default function (props: ReportCardProps) { status: "success", title: "Success", }); + setLoading(false) } return ( @@ -187,6 +191,8 @@ export default function (props: ReportCardProps) { diff --git a/components/Success.tsx b/components/Success.tsx index 1e6aa63..3d68d62 100644 --- a/components/Success.tsx +++ b/components/Success.tsx @@ -35,12 +35,10 @@ export default function ({ -

- {heading} + {heading}
- {message} -
+ {message}
); }