From bf8e8a094d54e82167eced484699b3b9469b1148 Mon Sep 17 00:00:00 2001 From: trafficlunar Date: Thu, 2 Apr 2026 11:54:34 +0100 Subject: [PATCH] feat: queue toggle in admin control center --- src/app/api/admin/can-submit/route.ts | 11 +++++----- src/app/api/admin/queue/route.ts | 22 +++++++++++++++++++ src/app/api/submit/route.ts | 10 ++++----- src/app/submit/page.tsx | 15 ++++--------- src/components/admin/control-center.tsx | 29 ++++++++++++++----------- src/lib/settings.ts | 4 ++++ 6 files changed, 55 insertions(+), 36 deletions(-) create mode 100644 src/app/api/admin/queue/route.ts create mode 100644 src/lib/settings.ts diff --git a/src/app/api/admin/can-submit/route.ts b/src/app/api/admin/can-submit/route.ts index 330a5d9..c5459b3 100644 --- a/src/app/api/admin/can-submit/route.ts +++ b/src/app/api/admin/can-submit/route.ts @@ -1,11 +1,10 @@ import { NextRequest, NextResponse } from "next/server"; import { z } from "zod"; import { auth } from "@/lib/auth"; - -let canSubmit = true; +import { settings } from "@/lib/settings"; export async function GET() { - return NextResponse.json({ success: true, value: canSubmit }); + return NextResponse.json({ success: true, value: settings.canSubmit }); } export async function PATCH(request: NextRequest) { @@ -15,9 +14,9 @@ export async function PATCH(request: NextRequest) { if (Number(session.user?.id) !== Number(process.env.NEXT_PUBLIC_ADMIN_USER_ID)) return NextResponse.json({ error: "Forbidden" }, { status: 403 }); const body = await request.json(); - const validatedCanSubmit = z.boolean().safeParse(body); - if (!validatedCanSubmit.success) return NextResponse.json({ error: "Failed to validate body" }, { status: 400 }); + const validated = z.boolean().safeParse(body); + if (!validated.success) return NextResponse.json({ error: "Failed to validate body" }, { status: 400 }); - canSubmit = validatedCanSubmit.data; + settings.canSubmit = validated.data; return NextResponse.json({ success: true }); } diff --git a/src/app/api/admin/queue/route.ts b/src/app/api/admin/queue/route.ts new file mode 100644 index 0000000..422fd7d --- /dev/null +++ b/src/app/api/admin/queue/route.ts @@ -0,0 +1,22 @@ +import { NextRequest, NextResponse } from "next/server"; +import { z } from "zod"; +import { auth } from "@/lib/auth"; +import { settings } from "@/lib/settings"; + +export async function GET() { + return NextResponse.json({ success: true, value: settings.queueEnabled }); +} + +export async function PATCH(request: NextRequest) { + const session = await auth(); + if (!session) return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + + if (Number(session.user?.id) !== Number(process.env.NEXT_PUBLIC_ADMIN_USER_ID)) return NextResponse.json({ error: "Forbidden" }, { status: 403 }); + + const body = await request.json(); + const validated = z.boolean().safeParse(body); + if (!validated.success) return NextResponse.json({ error: "Failed to validate body" }, { status: 400 }); + + settings.queueEnabled = validated.data; + return NextResponse.json({ success: true }); +} diff --git a/src/app/api/submit/route.ts b/src/app/api/submit/route.ts index 711e706..1bd95aa 100644 --- a/src/app/api/submit/route.ts +++ b/src/app/api/submit/route.ts @@ -21,6 +21,7 @@ import { ThreeDsTomodachiLifeMii } from "@/lib/three-ds-tomodachi-life-mii"; import { SwitchMiiInstructions } from "@/types"; import { minifyInstructions } from "@/lib/switch"; +import { settings } from "@/lib/settings"; const uploadsDirectory = path.join(process.cwd(), "uploads", "mii"); @@ -74,10 +75,7 @@ export async function POST(request: NextRequest) { const rateLimit = new RateLimit(request, 3); const check = await rateLimit.handle(); if (check) return check; - - const response = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/admin/can-submit`); - const { value } = await response.json(); - if (!value) return rateLimit.sendResponse({ error: "Submissions are temporarily disabled" }, 503); + if (!settings.canSubmit) return rateLimit.sendResponse({ error: "Submissions are temporarily disabled" }, 503); // Parse tags and QR code as JSON const formData = await request.formData(); @@ -199,8 +197,8 @@ export async function POST(request: NextRequest) { name, tags, description, - gender: gender ?? "MALE", - in_queue: true, + gender: gender ?? "MALE", + in_queue: settings.queueEnabled, // Automatically detect certain information if on 3DS ...(platform === "THREE_DS" diff --git a/src/app/submit/page.tsx b/src/app/submit/page.tsx index 0bcb8ad..82e0cfa 100644 --- a/src/app/submit/page.tsx +++ b/src/app/submit/page.tsx @@ -8,6 +8,7 @@ import { auth } from "@/lib/auth"; import { prisma } from "@/lib/prisma"; import SubmitForm from "@/components/submit-form"; +import { settings } from "@/lib/settings"; export const metadata: Metadata = { title: "Submit a Mii - TomodachiShare", @@ -30,16 +31,8 @@ export default async function SubmitPage() { }); if (activePunishment) redirect("/off-the-island"); - // Check if submissions are disabled - let value: boolean | null = true; - try { - const response = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/admin/can-submit`); - value = await response.json(); - } catch (error) { - return

An error occurred!

; - } - - if (!value) return ( + if (!settings.canSubmit) + return (

Sorry

@@ -50,7 +43,7 @@ export default async function SubmitPage() {
- ); + ); return ; } diff --git a/src/components/admin/control-center.tsx b/src/components/admin/control-center.tsx index b478d28..ef88035 100644 --- a/src/components/admin/control-center.tsx +++ b/src/components/admin/control-center.tsx @@ -1,25 +1,17 @@ "use client"; -import { useEffect, useState } from "react"; +import { settings } from "@/lib/settings"; +import { useState } from "react"; export default function ControlCenter() { - const [canSubmit, setCanSubmit] = useState(true); + const [canSubmit, setCanSubmit] = useState(settings.canSubmit); + const [isQueueEnabled, setIsQeueueEnabled] = useState(settings.queueEnabled); const onClickSet = async () => { await fetch("/api/admin/can-submit", { method: "PATCH", body: JSON.stringify(canSubmit) }); + await fetch("/api/admin/queue", { method: "PATCH", body: JSON.stringify(isQueueEnabled) }); }; - useEffect(() => { - const check = async () => { - const response = await fetch("/api/admin/can-submit"); - const { value } = await response.json(); - - setCanSubmit(value); - }; - - check(); - }, []); - return (
@@ -33,6 +25,17 @@ export default function ControlCenter() { />
+
+ setIsQeueueEnabled(e.target.checked)} + /> + +