import { Metadata } from "next"; import Image from "next/image"; import Link from "next/link"; import { redirect } from "next/navigation"; import { Icon } from "@iconify/react"; import { auth } from "@/lib/auth"; import { prisma } from "@/lib/prisma"; import { MiiPlatform } from "@prisma/client"; import LikeButton from "@/components/like-button"; import ImageViewer from "@/components/image-viewer"; import AuthorButtons from "@/components/mii/author-buttons"; import ShareMiiButton from "@/components/mii/share-mii-button"; import ThreeDsScanTutorialButton from "@/components/tutorial/3ds-scan"; import SwitchScanTutorialButton from "@/components/tutorial/switch-add-mii"; import Description from "@/components/description"; import MiiInstructions from "@/components/mii/instructions"; import { SwitchMiiInstructions } from "@/types"; import { settings } from "@/lib/settings"; interface Props { params: Promise<{ id: string }>; } export async function generateMetadata({ params }: Props): Promise { const { id } = await params; const mii = await prisma.mii.findUnique({ where: { id: Number(id), }, include: { user: { select: { name: true, }, }, _count: { select: { likedBy: true }, // Get total like count }, }, }); // Bots get redirected anyways if (!mii) return {}; const metadataImageUrl = `/mii/${mii.id}/image?type=metadata`; const name = `@${mii.user.name}`; return { metadataBase: new URL(process.env.NEXT_PUBLIC_BASE_URL!), title: `${mii.name} - TomodachiShare`, description: `Check out '${mii.name}', a ${mii.platform === MiiPlatform.SWITCH ? "Switch Living the Dream" : "3DS"} Tomodachi Life Mii created by ${mii.name} on TomodachiShare with ${mii._count.likedBy} likes.`, keywords: ["mii", "tomodachi life", "nintendo", "tomodachishare", "tomodachi-share", "mii creator", "mii collection", ...mii.tags], creator: name, openGraph: { type: "article", title: `${mii.name} - TomodachiShare`, description: `Check out '${mii.name}', a ${mii.platform === MiiPlatform.SWITCH ? "Switch Living the Dream" : "3DS"} Tomodachi Life Mii created by ${mii.name} on TomodachiShare with ${mii._count.likedBy} likes.`, images: [ { url: metadataImageUrl, alt: `${mii.name}, ${mii.tags.join(", ")} ${mii.gender} Mii character`, }, ], publishedTime: mii.createdAt.toISOString(), authors: name, }, twitter: { card: "summary_large_image", title: `${mii.name} - TomodachiShare`, description: `Check out '${mii.name}', a ${mii.platform === MiiPlatform.SWITCH ? "Switch Living the Dream" : "3DS"} Tomodachi Life Mii created by ${mii.name} on TomodachiShare with ${mii._count.likedBy} likes.`, images: [ { url: metadataImageUrl, alt: `${mii.name}, ${mii.tags.join(", ")} ${mii.gender} Mii character`, }, ], creator: mii.user.name!, }, alternates: { canonical: `/mii/${mii.id}`, }, }; } export default async function MiiPage({ params }: Props) { const { id } = await params; const session = await auth(); const mii = await prisma.mii.findUnique({ where: { id: Number(id), }, include: { user: { select: { name: true, }, }, likedBy: session?.user ? { where: { userId: Number(session.user.id), }, select: { userId: true }, } : false, _count: { select: { likedBy: true }, // Get total like count }, }, }); if (!mii) redirect("/404"); const images = [...Array.from({ length: mii.imageCount }, (_, index) => `/mii/${mii.id}/image?type=image${index}`)]; return (
{mii.quarantined && (

This Mii is flagged as controversial and only appears when the filter is enabled

)} {mii.in_queue && (

This Mii is waiting to be manually reviewed and is hidden from the main page. The review could take between a few hours and a few days.
Despite that, you can still share the Mii through the URL!

)}
{/* Mii Image */}
{/* QR Code */} {mii.platform === "THREE_DS" ? (
) : ( !mii.miiData && ( ) )}
{/* Mii Info */} {mii.platform === "THREE_DS" && (
  • Name:{" "} {mii.firstName} {mii.lastName}
  • From: {mii.islandName} Island
  • Allowed Copying:
)} {/* Mii Platform */}

Platform
{mii.platform === "THREE_DS" ? "3DS" : "Switch"}
{/* Mii Gender */}

Gender
{mii.gender === "MALE" ? "Male" : mii.gender === "FEMALE" ? "Female" : "Nonbinary"}
{mii.platform !== "THREE_DS" && (
)}
{/* Makeup */} {mii.platform === "SWITCH" && ( <>

Makeup
{/* Tooltip */}
{mii.makeup === "FULL" ? "Full Makeup" : mii.makeup === "PARTIAL" ? "Partial Makeup" : "No Makeup"}
{/* Full Makeup */}
{/* Partial Makeup */}
{/* No Makeup */}
)}
{/* Information */}
{/* Submission name */}

{mii.name}

{/* Like button */} 0} big />
{/* Tags */}
{mii.tags.map((tag) => ( {tag} ))}
{/* Author and Created date */}
By {mii.user.name}

Created:{" "} {mii.createdAt.toLocaleString("en-GB", { day: "2-digit", month: "long", year: "numeric", hour: "2-digit", minute: "2-digit", second: "2-digit", timeZone: "UTC", })}{" "} UTC

{/* Description */} {mii.description && }
{/* Buttons */}
{mii.miiData && ( Download )} Report {mii.platform === "THREE_DS" ? : }
{/* Instructions */} {mii.platform === "SWITCH" && (

Instructions

All instructions are based off of the default Male Mii.
{mii.miiData && "If you're on modded/emulator, you can download the .ltd file above."}

{mii.youtubeId && ( )} } isUsingSaveFile={mii.miiData !== null} />
)}
{/* Images */}

Gallery

{images.length > 0 ? (
{images.map((src, index) => (
mii screenshot background blur
))}
) : (

There is nothing here...

)}
); }