mirror of
https://github.com/trafficlunar/tomodachi-share.git
synced 2026-05-13 13:17:45 +00:00
Compare commits
No commits in common. "c1f3eacd03577582bd73e4a158b3e1670c2f4aa3" and "1bf83e4cae88ad09def4b2b6e43afcad54d5350d" have entirely different histories.
c1f3eacd03
...
1bf83e4cae
13 changed files with 79 additions and 54 deletions
|
|
@ -4,7 +4,34 @@ import type { NextConfig } from "next";
|
||||||
const nextConfig: NextConfig = {
|
const nextConfig: NextConfig = {
|
||||||
output: "standalone",
|
output: "standalone",
|
||||||
images: {
|
images: {
|
||||||
unoptimized: true,
|
localPatterns: [
|
||||||
|
{
|
||||||
|
pathname: "/mii/*/image",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pathname: "/profile/*/picture",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pathname: "/tutorial/**",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pathname: "/guest.png",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
remotePatterns: [
|
||||||
|
{
|
||||||
|
hostname: "avatars.githubusercontent.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hostname: "cdn.discordapp.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hostname: "studio.mii.nintendo.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hostname: "*.googleusercontent.com",
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,7 @@ export async function PATCH(request: NextRequest, { params }: { params: Promise<
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
images.map(async (image, index) => {
|
images.map(async (image, index) => {
|
||||||
const buffer = Buffer.from(await image.arrayBuffer());
|
const buffer = Buffer.from(await image.arrayBuffer());
|
||||||
const pngBuffer = await sharp(buffer).resize({ height: 800, fit: "inside", withoutEnlargement: true }).png({ quality: 85 }).toBuffer();
|
const pngBuffer = await sharp(buffer).png({ quality: 85 }).toBuffer();
|
||||||
const fileLocation = path.join(miiUploadsDirectory, `image${index}.png`);
|
const fileLocation = path.join(miiUploadsDirectory, `image${index}.png`);
|
||||||
|
|
||||||
await fs.writeFile(fileLocation, pngBuffer);
|
await fs.writeFile(fileLocation, pngBuffer);
|
||||||
|
|
|
||||||
|
|
@ -313,7 +313,7 @@ export async function POST(request: NextRequest) {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
customImages.map(async (image, index) => {
|
customImages.map(async (image, index) => {
|
||||||
const buffer = Buffer.from(await image.arrayBuffer());
|
const buffer = Buffer.from(await image.arrayBuffer());
|
||||||
const pngBuffer = await sharp(buffer).resize({ height: 800, fit: "inside", withoutEnlargement: true }).png({ quality: 85 }).toBuffer();
|
const pngBuffer = await sharp(buffer).png({ quality: 85 }).toBuffer();
|
||||||
const fileLocation = path.join(miiUploadsDirectory, `image${index}.png`);
|
const fileLocation = path.join(miiUploadsDirectory, `image${index}.png`);
|
||||||
|
|
||||||
await fs.writeFile(fileLocation, pngBuffer);
|
await fs.writeFile(fileLocation, pngBuffer);
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ const searchParamsSchema = z.object({
|
||||||
});
|
});
|
||||||
|
|
||||||
export async function GET(request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
|
export async function GET(request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
|
||||||
const rateLimit = new RateLimit(request, 20000, "/mii/image");
|
const rateLimit = new RateLimit(request, 200, "/mii/image");
|
||||||
const check = await rateLimit.handle();
|
const check = await rateLimit.handle();
|
||||||
if (check) return check;
|
if (check) return check;
|
||||||
|
|
||||||
|
|
@ -110,6 +110,6 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{
|
||||||
return rateLimit.sendResponse(buffer, 200, {
|
return rateLimit.sendResponse(buffer, 200, {
|
||||||
"Content-Type": "image/png",
|
"Content-Type": "image/png",
|
||||||
"X-Robots-Tag": "noindex, noimageindex, nofollow",
|
"X-Robots-Tag": "noindex, noimageindex, nofollow",
|
||||||
"Cache-Control": "public, max-age=31536000, immutable",
|
"Cache-Control": "no-store",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ interface Props {
|
||||||
export default function AuthorButtons({ mii }: Props) {
|
export default function AuthorButtons({ mii }: Props) {
|
||||||
const session = useSession();
|
const session = useSession();
|
||||||
|
|
||||||
if (!session.data || (Number(session.data.user?.id) !== mii.userId && Number(session.data.user?.id) !== Number(process.env.NEXT_PUBLIC_ADMIN_USER_ID)))
|
if (!session.data || Number(session.data.user?.id) !== mii.userId || Number(session.data.user?.id) !== Number(process.env.NEXT_PUBLIC_ADMIN_USER_ID))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -121,13 +121,18 @@ export default function FilterMenu() {
|
||||||
<>
|
<>
|
||||||
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium w-full mt-2 mb-1">
|
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium w-full mt-2 mb-1">
|
||||||
<hr className="grow border-zinc-300" />
|
<hr className="grow border-zinc-300" />
|
||||||
<span>Face Paint</span>
|
<span>Makeup</span>
|
||||||
<hr className="grow border-zinc-300" />
|
<hr className="grow border-zinc-300" />
|
||||||
</div>
|
</div>
|
||||||
<MakeupSelect />
|
<MakeupSelect />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium w-full mt-2 mb-1">
|
||||||
|
<hr className="grow border-zinc-300" />
|
||||||
|
<span>Other</span>
|
||||||
|
<hr className="grow border-zinc-300" />
|
||||||
|
</div>
|
||||||
<OtherFilters />
|
<OtherFilters />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
import { Prisma } from "@prisma/client";
|
import { Prisma } from "@prisma/client";
|
||||||
|
import { Icon } from "@iconify/react";
|
||||||
|
|
||||||
import crypto from "crypto";
|
import crypto from "crypto";
|
||||||
import seedrandom from "seedrandom";
|
import seedrandom from "seedrandom";
|
||||||
|
|
@ -8,6 +11,9 @@ import { auth } from "@/lib/auth";
|
||||||
import { prisma } from "@/lib/prisma";
|
import { prisma } from "@/lib/prisma";
|
||||||
|
|
||||||
import SortSelect from "./sort-select";
|
import SortSelect from "./sort-select";
|
||||||
|
import Carousel from "../../carousel";
|
||||||
|
import LikeButton from "../../like-button";
|
||||||
|
import DeleteMiiButton from "../delete-mii-button";
|
||||||
import Pagination from "./pagination";
|
import Pagination from "./pagination";
|
||||||
import FilterMenu from "./filter-menu";
|
import FilterMenu from "./filter-menu";
|
||||||
import MiiGrid from "./mii-grid";
|
import MiiGrid from "./mii-grid";
|
||||||
|
|
@ -55,7 +61,7 @@ export default async function MiiList({ searchParams, userId, inLikesPage }: Pro
|
||||||
// Makeup
|
// Makeup
|
||||||
...(makeup && { makeup: { equals: makeup } }),
|
...(makeup && { makeup: { equals: makeup } }),
|
||||||
// Quarantined
|
// Quarantined
|
||||||
...(!quarantined && !userId && { quarantined: false }),
|
...(!quarantined && { quarantined: false }),
|
||||||
// Profiles
|
// Profiles
|
||||||
...(userId && { userId }),
|
...(userId && { userId }),
|
||||||
};
|
};
|
||||||
|
|
@ -183,7 +189,7 @@ export default async function MiiList({ searchParams, userId, inLikesPage }: Pro
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<MiiGrid miis={miis} userId={userId} />
|
<MiiGrid miis={miis} />
|
||||||
<Pagination lastPage={lastPage} />
|
<Pagination lastPage={lastPage} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -35,39 +35,39 @@ export default function MakeupSelect() {
|
||||||
{/* Full Makeup */}
|
{/* Full Makeup */}
|
||||||
<button
|
<button
|
||||||
onClick={() => handleClick("FULL")}
|
onClick={() => handleClick("FULL")}
|
||||||
aria-label="Filter for Full Face Paint"
|
aria-label="Filter for Full Makeup"
|
||||||
data-tooltip-span
|
data-tooltip-span
|
||||||
className={`cursor-pointer rounded-xl flex justify-center items-center size-13 text-5xl border-2 transition-all ${
|
className={`cursor-pointer rounded-xl flex justify-center items-center size-13 text-5xl border-2 transition-all ${
|
||||||
selected === "FULL" ? "bg-pink-100 border-pink-400 shadow-md" : "bg-white border-gray-300 hover:border-gray-400"
|
selected === "FULL" ? "bg-pink-100 border-pink-400 shadow-md" : "bg-white border-gray-300 hover:border-gray-400"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="tooltip bg-pink-400! border-pink-400! before:border-b-pink-400!">Full Face Paint</div>
|
<div className="tooltip bg-pink-400! border-pink-400! before:border-b-pink-400!">Full Makeup</div>
|
||||||
<Icon icon="mdi:palette" className="text-pink-400" />
|
<Icon icon="mdi:palette" className="text-pink-400" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{/* Partial Makeup */}
|
{/* Partial Makeup */}
|
||||||
<button
|
<button
|
||||||
onClick={() => handleClick("PARTIAL")}
|
onClick={() => handleClick("PARTIAL")}
|
||||||
aria-label="Filter for Partial Face Paint"
|
aria-label="Filter for Partial Makeup"
|
||||||
data-tooltip-span
|
data-tooltip-span
|
||||||
className={`cursor-pointer rounded-xl flex justify-center items-center size-13 text-5xl border-2 transition-all ${
|
className={`cursor-pointer rounded-xl flex justify-center items-center size-13 text-5xl border-2 transition-all ${
|
||||||
selected === "PARTIAL" ? "bg-purple-100 border-purple-400 shadow-md" : "bg-white border-gray-300 hover:border-gray-400"
|
selected === "PARTIAL" ? "bg-purple-100 border-purple-400 shadow-md" : "bg-white border-gray-300 hover:border-gray-400"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="tooltip bg-purple-400! border-purple-400! before:border-b-purple-400!">Partial Face Paint</div>
|
<div className="tooltip bg-purple-400! border-purple-400! before:border-b-purple-400!">Partial Makeup</div>
|
||||||
<Icon icon="mdi:lipstick" className="text-purple-400" />
|
<Icon icon="mdi:lipstick" className="text-purple-400" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{/* No Makeup */}
|
{/* No Makeup */}
|
||||||
<button
|
<button
|
||||||
onClick={() => handleClick("NONE")}
|
onClick={() => handleClick("NONE")}
|
||||||
aria-label="Filter for No Face Paint"
|
aria-label="Filter for No Makeup"
|
||||||
data-tooltip-span
|
data-tooltip-span
|
||||||
className={`cursor-pointer rounded-xl flex justify-center items-center size-13 text-5xl border-2 transition-all ${
|
className={`cursor-pointer rounded-xl flex justify-center items-center size-13 text-5xl border-2 transition-all ${
|
||||||
selected === "NONE" ? "bg-gray-200 border-gray-400 shadow-md" : "bg-white border-gray-300 hover:border-gray-400"
|
selected === "NONE" ? "bg-gray-200 border-gray-400 shadow-md" : "bg-white border-gray-300 hover:border-gray-400"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="tooltip bg-gray-400! border-gray-400! before:border-b-gray-400!">No Face Paint</div>
|
<div className="tooltip bg-gray-400! border-gray-400! before:border-b-gray-400!">No Makeup</div>
|
||||||
<Icon icon="codex:cross" className="text-gray-400" />
|
<Icon icon="codex:cross" className="text-gray-400" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
|
import { Icon } from "@iconify/react";
|
||||||
import { MiiPlatform } from "@prisma/client";
|
import { MiiPlatform } from "@prisma/client";
|
||||||
import { usePathname, useRouter, useSearchParams } from "next/navigation";
|
import { useRouter, useSearchParams } from "next/navigation";
|
||||||
import { ChangeEvent, useState, useTransition } from "react";
|
import { ChangeEvent, useState, useTransition } from "react";
|
||||||
|
|
||||||
export default function OtherFilters() {
|
export default function OtherFilters() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
const pathname = usePathname();
|
|
||||||
const [, startTransition] = useTransition();
|
const [, startTransition] = useTransition();
|
||||||
|
|
||||||
const platform = (searchParams.get("platform") as MiiPlatform) || undefined;
|
const platform = (searchParams.get("platform") as MiiPlatform) || undefined;
|
||||||
|
|
@ -48,35 +48,22 @@ export default function OtherFilters() {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const showAllowCopying = platform !== "SWITCH";
|
|
||||||
const showQuarantined = !pathname.startsWith("/profile");
|
|
||||||
|
|
||||||
if (!showAllowCopying && !showQuarantined) return null;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium w-full mt-2 mb-1">
|
{platform === "THREE_DS" && (
|
||||||
<hr className="grow border-zinc-300" />
|
<div className="flex justify-between items-center w-full">
|
||||||
<span>Other</span>
|
|
||||||
<hr className="grow border-zinc-300" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{showAllowCopying && (
|
|
||||||
<div className="flex justify-between items-center w-full mb-1">
|
|
||||||
<label htmlFor="allowCopying" className="text-sm">
|
<label htmlFor="allowCopying" className="text-sm">
|
||||||
Allow Copying
|
Allow Copying
|
||||||
</label>
|
</label>
|
||||||
<input type="checkbox" id="allowCopying" className="checkbox-alt" checked={allowCopying} onChange={handleChangeAllowCopying} />
|
<input type="checkbox" id="allowCopying" className="checkbox-alt" checked={allowCopying} onChange={handleChangeAllowCopying} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{showQuarantined && (
|
<div className="flex justify-between items-center w-full">
|
||||||
<div className="flex justify-between items-center w-full">
|
<label htmlFor="quarantined" className="text-sm">
|
||||||
<label htmlFor="quarantined" className="text-sm">
|
Show Controversial Miis
|
||||||
Show Controversial Miis
|
</label>
|
||||||
</label>
|
<input type="checkbox" id="quarantined" className="checkbox-alt" checked={quarantined} onChange={handleChangeQuarantined} />
|
||||||
<input type="checkbox" id="quarantined" className="checkbox-alt" checked={quarantined} onChange={handleChangeQuarantined} />
|
</div>
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -268,7 +268,7 @@ export default function EditForm({ mii, likes }: Props) {
|
||||||
<>
|
<>
|
||||||
<div className="w-full grid grid-cols-3 items-start">
|
<div className="w-full grid grid-cols-3 items-start">
|
||||||
<label htmlFor="makeup" className="font-semibold py-2">
|
<label htmlFor="makeup" className="font-semibold py-2">
|
||||||
Face Paint
|
Makeup
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div className="col-span-2 flex gap-1">
|
<div className="col-span-2 flex gap-1">
|
||||||
|
|
@ -276,8 +276,8 @@ export default function EditForm({ mii, likes }: Props) {
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setMakeup("FULL")}
|
onClick={() => setMakeup("FULL")}
|
||||||
aria-label="Full Face Paint"
|
aria-label="Full makeup"
|
||||||
data-tooltip="Full Face Paint"
|
data-tooltip="Full Makeup"
|
||||||
className={`cursor-pointer rounded-xl flex justify-center items-center size-11 text-4xl border-2 transition-all after:bg-pink-400! after:border-pink-400! before:border-b-pink-400! ${
|
className={`cursor-pointer rounded-xl flex justify-center items-center size-11 text-4xl border-2 transition-all after:bg-pink-400! after:border-pink-400! before:border-b-pink-400! ${
|
||||||
makeup === "FULL" ? "bg-pink-100 border-pink-400 shadow-md" : "bg-white border-gray-300 hover:border-gray-400"
|
makeup === "FULL" ? "bg-pink-100 border-pink-400 shadow-md" : "bg-white border-gray-300 hover:border-gray-400"
|
||||||
}`}
|
}`}
|
||||||
|
|
@ -289,8 +289,8 @@ export default function EditForm({ mii, likes }: Props) {
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setMakeup("PARTIAL")}
|
onClick={() => setMakeup("PARTIAL")}
|
||||||
aria-label="Partial Face Paint"
|
aria-label="Partial makeup"
|
||||||
data-tooltip="Partial Face Paint"
|
data-tooltip="Partial Makeup"
|
||||||
className={`cursor-pointer rounded-xl flex justify-center items-center size-11 text-4xl border-2 transition-all after:bg-purple-400! after:border-purple-400! before:border-b-purple-400! ${
|
className={`cursor-pointer rounded-xl flex justify-center items-center size-11 text-4xl border-2 transition-all after:bg-purple-400! after:border-purple-400! before:border-b-purple-400! ${
|
||||||
makeup === "PARTIAL" ? "bg-purple-100 border-purple-400 shadow-md" : "bg-white border-gray-300 hover:border-gray-400"
|
makeup === "PARTIAL" ? "bg-purple-100 border-purple-400 shadow-md" : "bg-white border-gray-300 hover:border-gray-400"
|
||||||
}`}
|
}`}
|
||||||
|
|
@ -302,8 +302,8 @@ export default function EditForm({ mii, likes }: Props) {
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setMakeup("NONE")}
|
onClick={() => setMakeup("NONE")}
|
||||||
aria-label="No Face Paint"
|
aria-label="No makeup"
|
||||||
data-tooltip="No Face Paint"
|
data-tooltip="No Makeup"
|
||||||
className={`cursor-pointer rounded-xl flex justify-center items-center size-11 text-4xl border-2 transition-all after:bg-gray-400! after:border-gray-400! before:border-b-gray-400! ${
|
className={`cursor-pointer rounded-xl flex justify-center items-center size-11 text-4xl border-2 transition-all after:bg-gray-400! after:border-gray-400! before:border-b-gray-400! ${
|
||||||
makeup === "NONE" ? "bg-gray-200 border-gray-400 shadow-md" : "bg-white border-gray-300 hover:border-gray-400"
|
makeup === "NONE" ? "bg-gray-200 border-gray-400 shadow-md" : "bg-white border-gray-300 hover:border-gray-400"
|
||||||
}`}
|
}`}
|
||||||
|
|
|
||||||
|
|
@ -332,7 +332,7 @@ export default function SubmitForm() {
|
||||||
{/* Makeup (switch only) */}
|
{/* Makeup (switch only) */}
|
||||||
<div className={`w-full grid grid-cols-3 items-start ${platform === "SWITCH" ? "" : "hidden"}`}>
|
<div className={`w-full grid grid-cols-3 items-start ${platform === "SWITCH" ? "" : "hidden"}`}>
|
||||||
<label htmlFor="makeup" className="font-semibold py-2">
|
<label htmlFor="makeup" className="font-semibold py-2">
|
||||||
Face Paint
|
Makeup
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div className="col-span-2 flex gap-1">
|
<div className="col-span-2 flex gap-1">
|
||||||
|
|
@ -340,8 +340,8 @@ export default function SubmitForm() {
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setMakeup("FULL")}
|
onClick={() => setMakeup("FULL")}
|
||||||
aria-label="Full Face Paint"
|
aria-label="Full makeup"
|
||||||
data-tooltip="Full Face Paint"
|
data-tooltip="Full Makeup"
|
||||||
className={`cursor-pointer rounded-xl flex justify-center items-center size-11 text-4xl border-2 transition-all after:bg-pink-400! after:border-pink-400! before:border-b-pink-400! ${
|
className={`cursor-pointer rounded-xl flex justify-center items-center size-11 text-4xl border-2 transition-all after:bg-pink-400! after:border-pink-400! before:border-b-pink-400! ${
|
||||||
makeup === "FULL" ? "bg-pink-100 border-pink-400 shadow-md" : "bg-white border-gray-300 hover:border-gray-400"
|
makeup === "FULL" ? "bg-pink-100 border-pink-400 shadow-md" : "bg-white border-gray-300 hover:border-gray-400"
|
||||||
}`}
|
}`}
|
||||||
|
|
@ -353,8 +353,8 @@ export default function SubmitForm() {
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setMakeup("PARTIAL")}
|
onClick={() => setMakeup("PARTIAL")}
|
||||||
aria-label="Partial Face Paint"
|
aria-label="Partial makeup"
|
||||||
data-tooltip="Partial Face Paint"
|
data-tooltip="Partial Makeup"
|
||||||
className={`cursor-pointer rounded-xl flex justify-center items-center size-11 text-4xl border-2 transition-all after:bg-purple-400! after:border-purple-400! before:border-b-purple-400! ${
|
className={`cursor-pointer rounded-xl flex justify-center items-center size-11 text-4xl border-2 transition-all after:bg-purple-400! after:border-purple-400! before:border-b-purple-400! ${
|
||||||
makeup === "PARTIAL" ? "bg-purple-100 border-purple-400 shadow-md" : "bg-white border-gray-300 hover:border-gray-400"
|
makeup === "PARTIAL" ? "bg-purple-100 border-purple-400 shadow-md" : "bg-white border-gray-300 hover:border-gray-400"
|
||||||
}`}
|
}`}
|
||||||
|
|
@ -366,8 +366,8 @@ export default function SubmitForm() {
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setMakeup("NONE")}
|
onClick={() => setMakeup("NONE")}
|
||||||
aria-label="No Face Paint"
|
aria-label="No makeup"
|
||||||
data-tooltip="No Face Paint"
|
data-tooltip="No Makeup"
|
||||||
className={`cursor-pointer rounded-xl flex justify-center items-center size-11 text-4xl border-2 transition-all after:bg-gray-400! after:border-gray-400! before:border-b-gray-400! ${
|
className={`cursor-pointer rounded-xl flex justify-center items-center size-11 text-4xl border-2 transition-all after:bg-gray-400! after:border-gray-400! before:border-b-gray-400! ${
|
||||||
makeup === "NONE" ? "bg-gray-200 border-gray-400 shadow-md" : "bg-white border-gray-300 hover:border-gray-400"
|
makeup === "NONE" ? "bg-gray-200 border-gray-400 shadow-md" : "bg-white border-gray-300 hover:border-gray-400"
|
||||||
}`}
|
}`}
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ export default function HeadTab({ instructions }: Props) {
|
||||||
type="number"
|
type="number"
|
||||||
id="age"
|
id="age"
|
||||||
min={1}
|
min={1}
|
||||||
max={1000}
|
max={100}
|
||||||
className="pill input text-sm py-1! px-3! w-full"
|
className="pill input text-sm py-1! px-3! w-full"
|
||||||
value={birthday.age ?? undefined}
|
value={birthday.age ?? undefined}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
|
|
|
||||||
|
|
@ -288,7 +288,7 @@ export const switchMiiInstructionsSchema = z
|
||||||
.object({
|
.object({
|
||||||
day: z.number().int().min(1).max(31).optional(),
|
day: z.number().int().min(1).max(31).optional(),
|
||||||
month: z.number().int().min(1).max(12).optional(),
|
month: z.number().int().min(1).max(12).optional(),
|
||||||
age: z.number().int().min(1).max(1000).optional(),
|
age: z.number().int().min(1).max(100).optional(),
|
||||||
dontAge: z.boolean().optional(),
|
dontAge: z.boolean().optional(),
|
||||||
})
|
})
|
||||||
.optional(),
|
.optional(),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue