Compare commits

...

3 commits

Author SHA1 Message Date
radishsoups
99b95749a9
Merge d331d8ed46 into 8dfd1d0b12 2026-04-29 23:35:03 -07:00
8dfd1d0b12 fix: unable to submit 3ds miis 2026-04-29 16:29:02 +01:00
radishsoups
d331d8ed46 Adding prisma generate to scripts in package.json 2026-04-27 19:24:54 -04:00
7 changed files with 809 additions and 72 deletions

View file

@ -8,7 +8,8 @@
"build": "next build", "build": "next build",
"start": "next start", "start": "next start",
"lint": "next lint", "lint": "next lint",
"postinstall": "prisma generate" "postinstall": "prisma generate",
"prisma": "prisma generate"
}, },
"dependencies": { "dependencies": {
"@2toad/profanity": "^3.3.0", "@2toad/profanity": "^3.3.0",
@ -50,4 +51,4 @@
".": "./src/types.d.ts" ".": "./src/types.d.ts"
}, },
"types": "./src/types.d.ts" "types": "./src/types.d.ts"
} }

View file

@ -38,7 +38,7 @@ const submitSchema = z.object({
.trim() .trim()
.transform((val) => (val === "" ? null : val)) .transform((val) => (val === "" ? null : val))
.refine((val) => val === null || /^[a-zA-Z0-9_-]{11}$/.test(val), "Invalid YouTube video ID") .refine((val) => val === null || /^[a-zA-Z0-9_-]{11}$/.test(val), "Invalid YouTube video ID")
.optional(), .nullish(),
way: z.enum(["savedata", "manual"]).optional(), way: z.enum(["savedata", "manual"]).optional(),
@ -102,8 +102,8 @@ export async function POST(request: NextRequest) {
gender: formData.get("gender") ?? undefined, // ZOD MOMENT gender: formData.get("gender") ?? undefined, // ZOD MOMENT
makeup: formData.get("makeup") ?? undefined, makeup: formData.get("makeup") ?? undefined,
miiPortraitImage: formData.get("miiPortraitImage"), miiPortraitImage: formData.get("miiPortraitImage"),
youtubeId: formData.get("youtubeId"), youtubeId: formData.get("youtubeId") ?? undefined,
way: formData.get("way"), way: formData.get("way") ?? undefined,
miiDataFile: formData.get("miiDataFile") ?? undefined, miiDataFile: formData.get("miiDataFile") ?? undefined,

View file

@ -31,6 +31,7 @@
"react-image-crop": "^11.0.10", "react-image-crop": "^11.0.10",
"react-router": "^7.14.1", "react-router": "^7.14.1",
"tailwindcss": "^4.2.2", "tailwindcss": "^4.2.2",
"vite-plugin-node-polyfills": "^0.26.0",
"zod": "^4.3.6" "zod": "^4.3.6"
}, },
"devDependencies": { "devDependencies": {

View file

@ -1,54 +1,54 @@
import { useState } from "react"; import { useState } from "react";
import { createPortal } from "react-dom"; import { createPortal } from "react-dom";
import { Icon } from "@iconify/react"; import { Icon } from "@iconify/react";
import Tutorial from "."; import Tutorial from ".";
export default function ThreeDsScanTutorialButton() { export default function ThreeDsScanTutorialButton() {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
return ( return (
<> <>
<button aria-label="Tutorial" type="button" onClick={() => setIsOpen(true)} className="text-3xl cursor-pointer"> <button aria-label="Tutorial" type="button" onClick={() => setIsOpen(true)} className="text-3xl cursor-pointer">
<Icon icon="fa:question-circle" /> <Icon icon="fa:question-circle" />
<span>Tutorial</span> <span>Tutorial</span>
</button> </button>
{isOpen && {isOpen &&
createPortal( createPortal(
<Tutorial <Tutorial
tutorials={[ tutorials={[
{ {
title: "Adding Mii", title: "Adding Mii",
steps: [ steps: [
{ {
text: "1. Enter the town hall", text: "1. Enter the town hall",
imageSrc: "/tutorial/3ds/step1.png", imageSrc: "/tutorial/3ds/step1.png",
}, },
{ {
text: "2. Go into 'QR Code'", text: "2. Go into 'QR Code'",
imageSrc: "/tutorial/3ds/adding-mii/step2.png", imageSrc: "/tutorial/3ds/adding-mii/step2.png",
}, },
{ {
text: "3. Press 'Scan QR Code'", text: "3. Press 'Scan QR Code'",
imageSrc: "/tutorial/3ds/adding-mii/step3.png", imageSrc: "/tutorial/3ds/adding-mii/step3.png",
}, },
{ {
text: "4. Click on the QR code below the Mii's image", text: "4. Click on the QR code below the Mii's image",
imageSrc: "/tutorial/3ds/adding-mii/step4.png", imageSrc: "/tutorial/3ds/adding-mii/step4.png",
}, },
{ {
text: "5. Scan with your 3DS", text: "5. Scan with your 3DS",
imageSrc: "/tutorial/3ds/adding-mii/step5.png", imageSrc: "/tutorial/3ds/adding-mii/step5.png",
}, },
{ type: "finish" }, { type: "finish" },
], ],
}, },
]} ]}
isOpen={isOpen} isOpen={isOpen}
setIsOpen={setIsOpen} setIsOpen={setIsOpen}
/>, />,
document.body, document.body,
)} )}
</> </>
); );
} }

View file

@ -23,7 +23,7 @@ import SwitchFileUpload from "../components/submit-form/switch-file-upload";
import SwitchSubmitTutorialButton from "../components/tutorial/switch-submit"; import SwitchSubmitTutorialButton from "../components/tutorial/switch-submit";
import QrUpload from "../components/submit-form/qr-upload"; import QrUpload from "../components/submit-form/qr-upload";
import Camera from "../components/submit-form/camera"; import Camera from "../components/submit-form/camera";
import ThreeDsScanTutorialButton from "../components/tutorial/3ds-scan"; import ThreeDsSubmitTutorialButton from "../components/tutorial/3ds-submit";
import Dropzone from "../components/dropzone"; import Dropzone from "../components/dropzone";
import ImageList from "../components/submit-form/image-list"; import ImageList from "../components/submit-form/image-list";
import SubmitButton from "../components/submit-button"; import SubmitButton from "../components/submit-button";
@ -472,7 +472,7 @@ export default function SubmitPage() {
Use your camera Use your camera
</button> </button>
<Camera isOpen={isQrScannerOpen} setIsOpen={setIsQrScannerOpen} setQrBytesRaw={setQrBytesRaw} /> <Camera isOpen={isQrScannerOpen} setIsOpen={setIsQrScannerOpen} setQrBytesRaw={setQrBytesRaw} />
<ThreeDsScanTutorialButton /> <ThreeDsSubmitTutorialButton />
<span className="text-xs text-zinc-400">For emulators, aes_keys.txt is required.</span> <span className="text-xs text-zinc-400">For emulators, aes_keys.txt is required.</span>
</div> </div>
</div> </div>

View file

@ -1,8 +1,20 @@
import { defineConfig } from "vite"; import { defineConfig } from "vite";
import react from "@vitejs/plugin-react"; import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite"; import tailwindcss from "@tailwindcss/vite";
import { nodePolyfills } from "vite-plugin-node-polyfills";
// https://vite.dev/config/ // https://vite.dev/config/
export default defineConfig({ export default defineConfig(({ command }) => ({
plugins: [react(), tailwindcss()], plugins: [react(), tailwindcss(), nodePolyfills()],
}); resolve: {
alias:
command === "build"
? [
{
find: "vite-plugin-node-polyfills/shims/buffer",
replacement: require.resolve("vite-plugin-node-polyfills/shims/buffer"),
},
]
: [],
},
}));

File diff suppressed because it is too large Load diff