diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx
index 2485128..095a695 100644
--- a/src/app/admin/page.tsx
+++ b/src/app/admin/page.tsx
@@ -10,6 +10,7 @@ import { auth } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import BannerForm from "@/components/admin/banner-form";
+import ControlCenter from "@/components/admin/control-center";
export const metadata: Metadata = {
title: "Admin - TomodachiShare",
@@ -56,6 +57,15 @@ export default async function AdminPage() {
+ {/* Separator */}
+
diff --git a/src/app/api/admin/can-submit/route.ts b/src/app/api/admin/can-submit/route.ts
new file mode 100644
index 0000000..6623dc7
--- /dev/null
+++ b/src/app/api/admin/can-submit/route.ts
@@ -0,0 +1,23 @@
+import { NextRequest, NextResponse } from "next/server";
+import { z } from "zod";
+import { auth } from "@/lib/auth";
+
+let canSubmit = true;
+
+export async function GET() {
+ return NextResponse.json({ success: true, value: canSubmit });
+}
+
+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 validatedCanSubmit = z.boolean().safeParse(body);
+ if (!validatedCanSubmit.success) return NextResponse.json({ error: "Failed to validate body" }, { status: 400 });
+
+ canSubmit = validatedCanSubmit.data;
+ return NextResponse.json({ success: true });
+}
diff --git a/src/app/api/submit/route.ts b/src/app/api/submit/route.ts
index 8bdf4d2..6266402 100644
--- a/src/app/api/submit/route.ts
+++ b/src/app/api/submit/route.ts
@@ -41,6 +41,11 @@ export async function POST(request: NextRequest) {
const check = await rateLimit.handle();
if (check) return check;
+ const response = await fetch(`${process.env.BASE_URL}/api/admin/can-submit`);
+ const { value } = await response.json();
+ if (!value) return rateLimit.sendResponse({ error: "Submissions are disabled" }, 409);
+
+ // Parse data
const formData = await request.formData();
let rawTags: string[];
diff --git a/src/app/submit/page.tsx b/src/app/submit/page.tsx
index 9e4b838..7490f2f 100644
--- a/src/app/submit/page.tsx
+++ b/src/app/submit/page.tsx
@@ -1,5 +1,9 @@
import { Metadata } from "next";
import { redirect } from "next/navigation";
+import Link from "next/link";
+
+import { Icon } from "@iconify/react";
+
import { auth } from "@/lib/auth";
import SubmitForm from "@/components/submit-form";
@@ -18,5 +22,23 @@ export default async function SubmitPage() {
if (!session) redirect("/login");
if (!session.user.username) redirect("/create-username");
+ // Check if submissions are disabled
+ const response = await fetch(`${process.env.BASE_URL}/api/admin/can-submit`);
+ const { value } = await response.json();
+
+ if (!value)
+ return (
+
+
+
Sorry
+
Submissions are disabled
+
+
+ Return Home
+
+
+
+ );
+
return
;
}
diff --git a/src/components/admin/control-center.tsx b/src/components/admin/control-center.tsx
new file mode 100644
index 0000000..258b0bf
--- /dev/null
+++ b/src/components/admin/control-center.tsx
@@ -0,0 +1,44 @@
+"use client";
+
+import { useEffect, useState } from "react";
+
+export default function ControlCenter() {
+ const [canSubmit, setCanSubmit] = useState(true);
+
+ const onClickSet = async () => {
+ await fetch("/api/admin/can-submit", { method: "PATCH", body: JSON.stringify(canSubmit) });
+ };
+
+ useEffect(() => {
+ const check = async () => {
+ const response = await fetch("/api/admin/can-submit");
+ const { value } = await response.json();
+
+ setCanSubmit(value);
+ };
+
+ check();
+ }, []);
+
+ return (
+
+
+
+ setCanSubmit(e.target.checked)}
+ />
+
+
+
+
+
+
+ );
+}