chore: update packages

This commit is contained in:
trafficlunar 2025-10-29 19:46:33 +00:00
parent b806f2c958
commit f0df04d47c
42 changed files with 1466 additions and 1331 deletions

View file

@ -4,7 +4,7 @@
"private": true,
"packageManager": "pnpm@10.14.0",
"scripts": {
"dev": "next dev --turbopack",
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
@ -12,49 +12,49 @@
"test": "vitest"
},
"dependencies": {
"@2toad/profanity": "^3.1.1",
"@auth/prisma-adapter": "2.10.0",
"@2toad/profanity": "^3.2.0",
"@auth/prisma-adapter": "2.11.1",
"@bprogress/next": "^3.2.12",
"@hello-pangea/dnd": "^18.0.1",
"@prisma/client": "^6.16.1",
"@prisma/client": "^6.18.0",
"bit-buffer": "^0.2.5",
"canvas-confetti": "^1.9.3",
"canvas-confetti": "^1.9.4",
"dayjs": "^1.11.18",
"downshift": "^9.0.10",
"embla-carousel-react": "^8.6.0",
"file-type": "^21.0.0",
"ioredis": "^5.7.0",
"ioredis": "^5.8.2",
"jsqr": "^1.4.0",
"next": "15.5.3",
"next-auth": "5.0.0-beta.25",
"next": "16.0.1",
"next-auth": "5.0.0-beta.30",
"qrcode-generator": "^2.0.4",
"react": "^19.1.1",
"react-dom": "^19.1.1",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"react-dropzone": "^14.3.8",
"react-webcam": "^7.2.0",
"satori": "^0.18.2",
"satori": "^0.18.3",
"seedrandom": "^3.0.5",
"sharp": "^0.34.3",
"sharp": "^0.34.4",
"sjcl-with-all": "1.0.8",
"swr": "^2.3.6",
"zod": "^4.1.8"
"zod": "^4.1.12"
},
"devDependencies": {
"@eslint/eslintrc": "^3.3.1",
"@iconify/react": "^6.0.1",
"@tailwindcss/postcss": "^4.1.13",
"@iconify/react": "^6.0.2",
"@tailwindcss/postcss": "^4.1.16",
"@types/canvas-confetti": "^1.9.0",
"@types/node": "^24.3.1",
"@types/react": "^19.1.12",
"@types/react-dom": "^19.1.9",
"@types/node": "^24.9.2",
"@types/react": "^19.2.2",
"@types/react-dom": "^19.2.2",
"@types/seedrandom": "^3.0.8",
"@types/sjcl": "^1.0.34",
"eslint": "^9.35.0",
"eslint-config-next": "15.5.3",
"prisma": "^6.16.1",
"eslint": "^9.38.0",
"eslint-config-next": "16.0.1",
"prisma": "^6.18.0",
"schema-dts": "^1.1.5",
"tailwindcss": "^4.1.13",
"typescript": "^5.9.2",
"vitest": "^3.2.4"
"tailwindcss": "^4.1.16",
"typescript": "^5.9.3",
"vitest": "^4.0.5"
}
}

File diff suppressed because it is too large Load diff

View file

@ -31,36 +31,36 @@ export default async function AdminPage() {
{/* Separator */}
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium my-1">
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
<span>Banners</span>
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
</div>
<BannerForm />
{/* Separator */}
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium my-1">
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
<span>Control Center</span>
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
</div>
<ControlCenter />
{/* Separator */}
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium my-1">
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
<span>User Management</span>
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
</div>
<UserManagement />
{/* Separator */}
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium my-1">
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
<span>Reports</span>
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
</div>
<Reports />

View file

@ -21,14 +21,14 @@ export default async function CreateUsernamePage() {
}
return (
<div className="flex-grow flex items-center justify-center">
<div className="grow flex items-center justify-center">
<div className="bg-amber-50 border-2 border-amber-500 rounded-2xl shadow-lg px-10 py-12 max-w-md text-center">
<h1 className="text-3xl font-bold mb-4">Welcome to the island!</h1>
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium mb-6">
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
<span>Please create a username</span>
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
</div>
<UsernameForm />

View file

@ -92,7 +92,7 @@ export default function RootLayout({
<Providers>
<Header />
<AdminBanner />
<main className="px-4 py-8 max-w-7xl w-full flex-grow flex flex-col">{children}</main>
<main className="px-4 py-8 max-w-7xl w-full grow flex flex-col">{children}</main>
<Footer />
</Providers>
</body>

View file

@ -17,14 +17,14 @@ export default async function LoginPage() {
}
return (
<div className="flex-grow flex items-center justify-center">
<div className="grow flex items-center justify-center">
<div className="bg-amber-50 border-2 border-amber-500 rounded-2xl shadow-lg px-10 py-12 max-w-md text-center">
<h1 className="text-3xl font-bold mb-4">Welcome to TomodachiShare!</h1>
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium mb-8">
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
<span>Choose your login method</span>
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
</div>
<LoginButtons />

View file

@ -109,7 +109,7 @@ export default async function MiiPage({ params }: Props) {
<div className="relative grid grid-cols-3 gap-4 max-md:grid-cols-1">
<div className="bg-amber-50 rounded-3xl border-2 border-amber-500 shadow-lg p-4 flex flex-col items-center max-w-md w-full max-md:place-self-center max-md:row-start-2">
{/* Mii Image */}
<div className="bg-gradient-to-b from-amber-100 to-amber-200 overflow-hidden rounded-xl w-full mb-4 flex justify-center">
<div className="bg-linear-to-b from-amber-100 to-amber-200 overflow-hidden rounded-xl w-full mb-4 flex justify-center">
<ImageViewer
src={`/mii/${mii.id}/image?type=mii`}
alt="mii headshot"
@ -142,7 +142,7 @@ export default async function MiiPage({ params }: Props) {
From: <span className="text-right font-medium">{mii.islandName} Island</span>
</li>
<li>
Allowed Copying: <input type="checkbox" checked={mii.allowedCopying} disabled className="checkbox !cursor-auto" />
Allowed Copying: <input type="checkbox" checked={mii.allowedCopying} disabled className="checkbox cursor-auto!" />
</li>
</ul>
@ -171,7 +171,7 @@ export default async function MiiPage({ params }: Props) {
<div className="bg-amber-50 border-2 border-amber-500 rounded-2xl shadow-lg p-4 flex flex-col gap-1">
<div className="flex justify-between items-start">
{/* Submission name */}
<h1 className="text-4xl font-extrabold break-words text-amber-700">{mii.name}</h1>
<h1 className="text-4xl font-extrabold wrap-break-word text-amber-700">{mii.name}</h1>
{/* Like button */}
<LikeButton
likes={mii._count.likedBy ?? 0}
@ -248,7 +248,7 @@ export default async function MiiPage({ params }: Props) {
{images.map((src, index) => (
<div
key={index}
className="relative aspect-[3/2] rounded-xl bg-black/65 border-2 border-amber-400 shadow-md overflow-hidden transition hover:shadow-lg shadow-black/30"
className="relative aspect-3/2 rounded-xl bg-black/65 border-2 border-amber-400 shadow-md overflow-hidden transition hover:shadow-lg shadow-black/30"
>
<Image
src={src}
@ -263,7 +263,7 @@ export default async function MiiPage({ params }: Props) {
alt="mii screenshot"
width={256}
height={170}
className="aspect-[3/2] w-full object-contain hover:scale-105 duration-300 transition-transform relative z-10"
className="aspect-3/2 w-full object-contain hover:scale-105 duration-300 transition-transform relative z-10"
images={images}
/>
</div>

View file

@ -9,7 +9,7 @@ export const metadata: Metadata = {
export default function NotFound() {
return (
<div className="flex-grow flex items-center justify-center">
<div className="grow flex items-center justify-center">
<div className="bg-amber-50 border-2 border-amber-500 rounded-2xl shadow-lg p-8 max-w-xs w-full text-center flex flex-col">
<h2 className="text-7xl font-black">404</h2>
<p>Page not found - you swam off the island!</p>

View file

@ -51,7 +51,7 @@ export default async function ExiledPage() {
const duration = activePunishment.type === "TEMP_EXILE" && Math.ceil(expiresAt.diff(createdAt, "days", true));
return (
<div className="flex-grow flex items-center justify-center">
<div className="grow flex items-center justify-center">
<div className="bg-amber-50 border-2 border-amber-500 rounded-2xl shadow-lg p-8 max-w-xl w-full flex flex-col">
<h2 className="text-4xl font-black mb-2">
{activePunishment.type === "PERM_EXILE"
@ -78,9 +78,9 @@ export default async function ExiledPage() {
</p>
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium mt-4">
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
<span>Violating Items</span>
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
</div>
<div className="flex flex-col gap-2 p-4">

View file

@ -37,7 +37,7 @@ export default async function SubmitPage() {
if (!value)
return (
<div className="flex-grow flex items-center justify-center">
<div className="grow flex items-center justify-center">
<div className="bg-amber-50 border-2 border-amber-500 rounded-2xl shadow-lg p-8 max-w-xs w-full text-center flex flex-col">
<h2 className="text-5xl font-black">Sorry</h2>
<p className="mt-1">Submissions are disabled</p>

View file

@ -26,7 +26,7 @@ export default function ControlCenter() {
<input
name="submit"
type="checkbox"
className="checkbox !size-6"
className="checkbox size-6!"
placeholder="Enter banner text"
checked={canSubmit}
onChange={(e) => setCanSubmit(e.target.checked)}

View file

@ -55,7 +55,7 @@ export default function PunishmentDeletionDialog({ punishmentId }: Props) {
{isOpen &&
createPortal(
<div className="fixed inset-0 w-full h-[calc(100%-var(--header-height))] top-[var(--header-height)] flex items-center justify-center z-40">
<div className="fixed inset-0 w-full h-[calc(100%-var(--header-height))] top-(--header-height) flex items-center justify-center z-40">
<div
onClick={close}
className={`z-40 absolute inset-0 backdrop-brightness-75 backdrop-blur-xs transition-opacity duration-300 ${

View file

@ -34,7 +34,7 @@ export default function ReturnToIsland({ hasExpired }: Props) {
disabled={hasExpired}
checked={isChecked}
onChange={(e) => setIsChecked(e.target.checked)}
className={`checkbox ${hasExpired && "text-zinc-600 !bg-zinc-100 !border-zinc-300"}`}
className={`checkbox ${hasExpired && "text-zinc-600 bg-zinc-100! border-zinc-300!"}`}
/>
<label htmlFor="agreement" className={`${hasExpired && "text-zinc-500"}`}>
I Agree

View file

@ -238,7 +238,7 @@ export default function Punishments() {
rows={2}
maxLength={256}
placeholder="Type notes here for the punishment..."
className="pill input !rounded-xl resize-none"
className="pill input rounded-xl! resize-none"
value={notes}
onChange={(e) => setNotes(e.target.value)}
/>
@ -249,7 +249,7 @@ export default function Punishments() {
rows={2}
maxLength={256}
placeholder="Type profile-related reasons here for the punishment..."
className="pill input !rounded-xl resize-none"
className="pill input rounded-xl! resize-none"
value={reasons}
onChange={(e) => setReasons(e.target.value)}
/>
@ -273,7 +273,7 @@ export default function Punishments() {
value={newMii.reason}
onChange={(e) => setNewMii({ ...newMii, reason: e.target.value })}
/>
<button type="button" aria-label="Add Mii" onClick={addMiiToList} className="pill button aspect-square !p-2.5">
<button type="button" aria-label="Add Mii" onClick={addMiiToList} className="pill button aspect-square p-2.5!">
<Icon icon="ic:baseline-plus" className="size-4" />
</button>
</div>

View file

@ -43,8 +43,8 @@ export default function Carousel({ images, className }: Props) {
<div className={`overflow-hidden rounded-xl bg-zinc-300 ${className ?? ""}`} ref={emblaRef}>
<div className="flex">
{images.map((src, index) => (
<div key={index} className="flex-shrink-0 w-full">
<ImageViewer src={src} alt="mii image" width={480} height={320} className="w-full h-auto aspect-[3/2] object-contain" images={images} />
<div key={index} className="shrink-0 w-full">
<ImageViewer src={src} alt="mii image" width={480} height={320} className="w-full h-auto aspect-3/2 object-contain" images={images} />
</div>
))}
</div>

View file

@ -69,7 +69,7 @@ export default function DeleteMiiButton({ miiId, miiName, likes, inMiiPage }: Pr
{isOpen &&
createPortal(
<div className="fixed inset-0 h-[calc(100%-var(--header-height))] top-[var(--header-height)] flex items-center justify-center z-40">
<div className="fixed inset-0 h-[calc(100%-var(--header-height))] top-(--header-height) flex items-center justify-center z-40">
<div
onClick={close}
className={`z-40 absolute inset-0 backdrop-brightness-75 backdrop-blur-xs transition-opacity duration-300 ${
@ -107,7 +107,7 @@ export default function DeleteMiiButton({ miiId, miiName, likes, inMiiPage }: Pr
<button onClick={close} className="pill button">
Cancel
</button>
<SubmitButton onClick={handleSubmit} text="Delete" className="!bg-red-400 !border-red-500 hover:!bg-red-500" />
<SubmitButton onClick={handleSubmit} text="Delete" className="bg-red-400! border-red-500! hover:bg-red-500!" />
</div>
</div>
</div>,

View file

@ -77,7 +77,7 @@ export default function ImageViewer({ src, alt, width, height, className, images
{isOpen &&
createPortal(
<div className="fixed inset-0 h-[calc(100%-var(--header-height))] top-[var(--header-height)] flex items-center justify-center z-40">
<div className="fixed inset-0 h-[calc(100%-var(--header-height))] top-(--header-height) flex items-center justify-center z-40">
<div
onClick={close}
className={`z-40 absolute inset-0 backdrop-brightness-75 backdrop-blur-xs transition-opacity duration-300 ${
@ -99,7 +99,7 @@ export default function ImageViewer({ src, alt, width, height, className, images
<div className="overflow-hidden rounded-2xl h-full" ref={emblaRef}>
<div className="flex h-full items-center">
{imagesMap.map((image, index) => (
<div key={index} className="flex-shrink-0 w-full">
<div key={index} className="shrink-0 w-full">
<Image
src={image}
alt={alt}

View file

@ -9,7 +9,7 @@ export default function LoginButtons() {
<button
onClick={() => signIn("discord", { redirectTo: "/create-username" })}
aria-label="Login with Discord"
className="pill button gap-2 !px-3 !bg-indigo-400 !border-indigo-500 hover:!bg-indigo-500"
className="pill button gap-2 px-3! bg-indigo-400! border-indigo-500! hover:bg-indigo-500!"
>
<Icon icon="ic:baseline-discord" fontSize={32} />
Login with Discord
@ -17,7 +17,7 @@ export default function LoginButtons() {
<button
onClick={() => signIn("github", { redirectTo: "/create-username" })}
aria-label="Login with GitHub"
className="pill button gap-2 !px-3 !bg-zinc-700 !border-zinc-800 hover:!bg-zinc-800 text-white"
className="pill button gap-2 px-3! bg-zinc-700! border-zinc-800! hover:bg-zinc-800! text-white"
>
<Icon icon="mdi:github" fontSize={32} />
Login with GitHub

View file

@ -6,7 +6,7 @@ import { signOut } from "next-auth/react";
export default function LogoutButton() {
return (
<li title="Logout">
<button onClick={() => signOut()} aria-label="Log Out" className="pill button !p-0 aspect-square h-full" data-tooltip="Log Out">
<button onClick={() => signOut()} aria-label="Log Out" className="pill button p-0! aspect-square h-full" data-tooltip="Log Out">
<Icon icon="ic:round-logout" fontSize={24} />
</button>
</li>

View file

@ -4,6 +4,7 @@ import { MiiGender, Prisma } from "@prisma/client";
import { Icon } from "@iconify/react";
import { z } from "zod";
import crypto from "crypto";
import seedrandom from "seedrandom";
import { querySchema } from "@/lib/schemas";
@ -125,7 +126,7 @@ export default async function MiiList({ searchParams, userId, inLikesPage }: Pro
if (sort === "random") {
// Use seed for consistent random results
const randomSeed = seed || Math.floor(Math.random() * 1_000_000_000);
const randomSeed = seed || crypto.randomInt(0, 1_000_000_000);
// Get all IDs that match the where conditions
const matchingIds = await prisma.mii.findMany({

View file

@ -44,8 +44,8 @@ export default function Pagination({ lastPage }: Props) {
aria-label="Go to First Page"
aria-disabled={page === 1}
tabIndex={page === 1 ? -1 : undefined}
className={`pill button !bg-orange-100 !p-0.5 aspect-square text-2xl ${
page === 1 ? "pointer-events-none opacity-50" : "hover:!bg-orange-400"
className={`pill button bg-orange-100! p-0.5! aspect-square text-2xl ${
page === 1 ? "pointer-events-none opacity-50" : "hover:bg-orange-400!"
}`}
>
<Icon icon="stash:chevron-double-left" />
@ -57,7 +57,7 @@ export default function Pagination({ lastPage }: Props) {
aria-label="Go to Previous Page"
aria-disabled={page === 1}
tabIndex={page === 1 ? -1 : undefined}
className={`pill !bg-orange-100 !p-0.5 aspect-square text-2xl ${page === 1 ? "pointer-events-none opacity-50" : "hover:!bg-orange-400"}`}
className={`pill bg-orange-100! p-0.5! aspect-square text-2xl ${page === 1 ? "pointer-events-none opacity-50" : "hover:bg-orange-400!"}`}
>
<Icon icon="stash:chevron-left" />
</Link>
@ -70,7 +70,7 @@ export default function Pagination({ lastPage }: Props) {
href={createPageUrl(number)}
aria-label={`Go to Page ${number}`}
aria-current={number === page ? "page" : undefined}
className={`pill !p-0 w-8 h-8 text-center !rounded-md ${number == page ? "!bg-orange-400" : "!bg-orange-100 hover:!bg-orange-400"}`}
className={`pill p-0! w-8 h-8 text-center rounded-md! ${number == page ? "bg-orange-400!" : "bg-orange-100! hover:bg-orange-400!"}`}
>
{number}
</Link>
@ -83,8 +83,8 @@ export default function Pagination({ lastPage }: Props) {
aria-label="Go to Next Page"
aria-disabled={page === lastPage}
tabIndex={page === lastPage ? -1 : undefined}
className={`pill button !bg-orange-100 !p-0.5 aspect-square text-2xl ${
page === lastPage ? "pointer-events-none opacity-50" : "hover:!bg-orange-400"
className={`pill button bg-orange-100! p-0.5! aspect-square text-2xl ${
page === lastPage ? "pointer-events-none opacity-50" : "hover:bg-orange-400!"
}`}
>
<Icon icon="stash:chevron-right" />
@ -96,8 +96,8 @@ export default function Pagination({ lastPage }: Props) {
aria-label="Go to Last Page"
aria-disabled={page === lastPage}
tabIndex={page === lastPage ? -1 : undefined}
className={`pill button !bg-orange-100 !p-0.5 aspect-square text-2xl ${
page === lastPage ? "pointer-events-none opacity-50" : "hover:!bg-orange-400"
className={`pill button bg-orange-100! p-0.5! aspect-square text-2xl ${
page === lastPage ? "pointer-events-none opacity-50" : "hover:bg-orange-400!"
}`}
>
<Icon icon="stash:chevron-double-right" />

View file

@ -21,7 +21,7 @@ export default function Skeleton() {
<div key={index} className="flex flex-col bg-zinc-50 rounded-3xl border-2 border-zinc-300 shadow-lg p-3">
{/* Carousel Skeleton */}
<div className="relative rounded-xl bg-zinc-300 border-2 border-zinc-300 mb-1">
<div className="aspect-[3/2]"></div>
<div className="aspect-3/2"></div>
</div>
{/* Content */}

View file

@ -38,7 +38,7 @@ export default function SortSelect() {
return (
<div className="relative w-fit">
{/* Toggle button to open the dropdown */}
<button type="button" {...getToggleButtonProps()} aria-label="Sort dropdown" className="pill input w-full gap-1 !justify-between text-nowrap">
<button type="button" {...getToggleButtonProps()} aria-label="Sort dropdown" className="pill input w-full gap-1 justify-between! text-nowrap">
<span>Sort by </span>
{selectedItem || "Select a way to sort"}
<Icon icon="tabler:chevron-down" className="ml-2 size-5" />

View file

@ -34,7 +34,7 @@ export default async function ProfileInformation({ userId, page }: Props) {
{/* User information */}
<div className="flex flex-col w-full relative py-3">
<div className="flex items-center gap-2">
<h1 className="text-3xl font-extrabold break-words">{user.name}</h1>
<h1 className="text-3xl font-extrabold wrap-break-word">{user.name}</h1>
{isAdmin && (
<div data-tooltip="Admin" className="text-orange-400">
<Icon icon="mdi:shield-moon" className="text-2xl" />
@ -46,7 +46,7 @@ export default async function ProfileInformation({ userId, page }: Props) {
</div>
)}
</div>
<h2 className="text-black/60 text-sm font-semibold break-words">@{user?.username}</h2>
<h2 className="text-black/60 text-sm font-semibold wrap-break-word">@{user?.username}</h2>
<div className="mt-auto text-sm flex gap-8">
<h4 title={`${user.createdAt.toLocaleTimeString("en-GB", { timeZone: "UTC" })} UTC`}>

View file

@ -10,7 +10,7 @@ export default async function ProfileOverview() {
<Link
href={`/profile/${session?.user.id}`}
aria-label="Go to profile"
className="pill button !gap-2 !p-0 h-full max-w-64"
className="pill button gap-2! p-0! h-full max-w-64"
data-tooltip="Your Profile"
>
<Image

View file

@ -42,14 +42,14 @@ export default function DeleteAccount() {
<button
name="deletion"
onClick={() => setIsOpen(true)}
className="pill button w-fit h-min ml-auto !bg-red-400 !border-red-500 hover:!bg-red-500"
className="pill button w-fit h-min ml-auto bg-red-400! border-red-500! hover:bg-red-500!"
>
Delete Account
</button>
{isOpen &&
createPortal(
<div className="fixed inset-0 h-[calc(100%-var(--header-height))] top-[var(--header-height)] flex items-center justify-center z-40">
<div className="fixed inset-0 h-[calc(100%-var(--header-height))] top-(--header-height) flex items-center justify-center z-40">
<div
onClick={close}
className={`z-40 absolute inset-0 backdrop-brightness-75 backdrop-blur-xs transition-opacity duration-300 ${
@ -79,7 +79,7 @@ export default function DeleteAccount() {
<button onClick={close} className="pill button">
Cancel
</button>
<SubmitButton onClick={handleSubmit} text="Delete" className="!bg-red-400 !border-red-500 hover:!bg-red-500" />
<SubmitButton onClick={handleSubmit} text="Delete" className="bg-red-400! border-red-500! hover:bg-red-500!" />
</div>
</div>
</div>,

View file

@ -76,9 +76,9 @@ export default function ProfileSettings() {
{/* Separator */}
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium mb-1">
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
<span>Account Info</span>
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
</div>
{/* Profile Picture */}
@ -152,9 +152,9 @@ export default function ProfileSettings() {
{/* Separator */}
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium my-1">
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
<span>Danger Zone</span>
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
</div>
{/* Delete Account */}

View file

@ -5,7 +5,7 @@ import { Icon } from "@iconify/react";
export default function RandomLink() {
return (
<Link href={"/random"} aria-label="Go to Random Link" className="pill button !p-0 h-full aspect-square" data-tooltip="Go to a Random Mii">
<Link href={"/random"} aria-label="Go to Random Link" className="pill button p-0! h-full aspect-square" data-tooltip="Go to a Random Mii">
<Icon icon="mdi:dice-3" fontSize={28} />
</Link>
);

View file

@ -67,7 +67,7 @@ export default function ReportMiiForm({ mii, likes }: Props) {
rows={3}
maxLength={256}
placeholder="Type notes here for the report..."
className="pill input !rounded-xl resize-none col-span-2"
className="pill input rounded-xl! resize-none col-span-2"
value={notes}
onChange={(e) => setNotes(e.target.value)}
/>

View file

@ -40,7 +40,7 @@ export default function ReasonSelector({ reason, setReason }: Props) {
type="button"
{...getToggleButtonProps()}
aria-label="Report reason dropdown"
className="pill input w-full gap-1 !justify-between text-nowrap"
className="pill input w-full gap-1 justify-between! text-nowrap"
>
{selectedItem?.label || <span className="text-black/40">Select a reason for the report...</span>}
<Icon icon="tabler:chevron-down" className="ml-2 size-5" />

View file

@ -65,7 +65,7 @@ export default function ReportUserForm({ user }: Props) {
rows={3}
maxLength={256}
placeholder="Type notes here for the report..."
className="pill input !rounded-xl resize-none col-span-2"
className="pill input rounded-xl! resize-none col-span-2"
value={notes}
onChange={(e) => setNotes(e.target.value)}
/>

View file

@ -67,7 +67,7 @@ export default function ShareMiiButton({ miiId }: Props) {
{isOpen &&
createPortal(
<div className="fixed inset-0 h-[calc(100%-var(--header-height))] top-[var(--header-height)] flex items-center justify-center z-40">
<div className="fixed inset-0 h-[calc(100%-var(--header-height))] top-(--header-height) flex items-center justify-center z-40">
<div
onClick={close}
className={`z-40 absolute inset-0 backdrop-brightness-75 backdrop-blur-xs transition-opacity duration-300 ${
@ -92,7 +92,7 @@ export default function ShareMiiButton({ miiId }: Props) {
{/* Copy button */}
<button
className="!absolute top-2.5 right-2.5 cursor-pointer"
className="absolute! top-2.5 right-2.5 cursor-pointer"
data-tooltip={hasCopiedUrl ? "Copied!" : "Copy URL"}
onClick={handleCopyUrl}
>
@ -118,9 +118,9 @@ export default function ShareMiiButton({ miiId }: Props) {
{/* Separator */}
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium my-4">
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
<span>or</span>
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
</div>
<div className="flex justify-center items-center p-4 w-full bg-orange-100 border border-orange-400 rounded-lg">
@ -139,7 +139,7 @@ export default function ShareMiiButton({ miiId }: Props) {
{/* Save button */}
<a
href={`/mii/${miiId}/image?type=metadata`}
className="pill button !p-0 aspect-square cursor-pointer text-xl"
className="pill button p-0! aspect-square cursor-pointer text-xl"
aria-label="Save Image"
data-tooltip="Save Image"
download={"hello.png"}
@ -149,7 +149,7 @@ export default function ShareMiiButton({ miiId }: Props) {
{/* Copy button */}
<button
className="pill button !p-0 aspect-square cursor-pointer"
className="pill button p-0! aspect-square cursor-pointer"
aria-label="Copy Image"
data-tooltip={hasCopiedImage ? "Copied!" : "Copy Image"}
onClick={handleCopyImage}

View file

@ -106,7 +106,7 @@ export default function EditForm({ mii, likes }: Props) {
return (
<form className="flex justify-center gap-4 w-full max-lg:flex-col max-lg:items-center">
<div className="flex justify-center">
<div className="w-[18.75rem] h-min flex flex-col bg-zinc-50 rounded-3xl border-2 border-zinc-300 shadow-lg p-3">
<div className="w-75 h-min flex flex-col bg-zinc-50 rounded-3xl border-2 border-zinc-300 shadow-lg p-3">
<Carousel
images={[`/mii/${mii.id}/image?type=mii`, `/mii/${mii.id}/image?type=qr-code`, ...files.map((file) => URL.createObjectURL(file))]}
/>
@ -139,9 +139,9 @@ export default function EditForm({ mii, likes }: Props) {
{/* Separator */}
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium my-1">
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
<span>Info</span>
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
</div>
<div className="w-full grid grid-cols-3 items-center">
@ -175,7 +175,7 @@ export default function EditForm({ mii, likes }: Props) {
rows={3}
maxLength={256}
placeholder="(optional) Type a description..."
className="pill input !rounded-xl resize-none col-span-2"
className="pill input rounded-xl! resize-none col-span-2"
value={description ?? ""}
onChange={(e) => setDescription(e.target.value)}
/>
@ -183,9 +183,9 @@ export default function EditForm({ mii, likes }: Props) {
{/* Separator */}
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium mt-8 mb-2">
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
<span>Custom images</span>
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
</div>
<div className="max-w-md w-full self-center">

View file

@ -43,13 +43,13 @@ export default function ImageList({ files, setFiles }: Props) {
alt={file.name}
width={96}
height={96}
className="aspect-[3/2] object-contain w-24 rounded-md bg-orange-300 border-2 border-orange-400"
className="aspect-3/2 object-contain w-24 rounded-md bg-orange-300 border-2 border-orange-400"
/>
<div className="flex flex-col justify-center w-full min-w-0">
<span className="font-semibold overflow-hidden text-ellipsis">{file.name}</span>
<button
onClick={() => handleDelete(index)}
className="pill button text-xs w-min !px-3 !py-1 !bg-red-300 !border-red-400 hover:!bg-red-400"
className="pill button text-xs w-min px-3! py-1! bg-red-300! border-red-400! hover:bg-red-400!"
>
Delete
</button>

View file

@ -126,7 +126,7 @@ export default function SubmitForm() {
return (
<form className="flex justify-center gap-4 w-full max-lg:flex-col max-lg:items-center">
<div className="flex justify-center">
<div className="w-[18.75rem] h-min flex flex-col bg-zinc-50 rounded-3xl border-2 border-zinc-300 shadow-lg p-3">
<div className="w-75 h-min flex flex-col bg-zinc-50 rounded-3xl border-2 border-zinc-300 shadow-lg p-3">
<Carousel images={[studioUrl ?? "/loading.svg", generatedQrCodeUrl ?? "/loading.svg", ...files.map((file) => URL.createObjectURL(file))]} />
<div className="p-4 flex flex-col gap-1 h-full">
@ -157,9 +157,9 @@ export default function SubmitForm() {
{/* Separator */}
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium my-1">
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
<span>Info</span>
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
</div>
<div className="w-full grid grid-cols-3 items-center">
@ -193,7 +193,7 @@ export default function SubmitForm() {
rows={3}
maxLength={256}
placeholder="(optional) Type a description..."
className="pill input !rounded-xl resize-none col-span-2"
className="pill input rounded-xl! resize-none col-span-2"
value={description}
onChange={(e) => setDescription(e.target.value)}
/>
@ -201,9 +201,9 @@ export default function SubmitForm() {
{/* Separator */}
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium mt-8 mb-2">
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
<span>QR Code</span>
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
</div>
<div className="flex flex-col items-center gap-2">
@ -223,9 +223,9 @@ export default function SubmitForm() {
{/* Separator */}
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium mt-6 mb-2">
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
<span>Custom images</span>
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
</div>
<div className="max-w-md w-full self-center">

View file

@ -130,7 +130,7 @@ export default function QrScanner({ isOpen, setIsOpen, setQrBytesRaw }: Props) {
if (!isOpen) return null;
return (
<div className="fixed inset-0 h-[calc(100%-var(--header-height))] top-[var(--header-height)] flex items-center justify-center z-40">
<div className="fixed inset-0 h-[calc(100%-var(--header-height))] top-(--header-height) flex items-center justify-center z-40">
<div
onClick={close}
className={`z-40 absolute inset-0 backdrop-brightness-75 backdrop-blur-xs transition-opacity duration-300 ${
@ -159,7 +159,7 @@ export default function QrScanner({ isOpen, setIsOpen, setQrBytesRaw }: Props) {
type="button"
aria-label="Select camera dropdown"
{...getToggleButtonProps({}, { suppressRefError: true })}
className="pill input w-full !px-2 !py-0.5 !justify-between text-sm"
className="pill input w-full px-2! py-0.5! justify-between! text-sm"
>
{selectedItem?.label || "Select a camera"}
@ -193,7 +193,7 @@ export default function QrScanner({ isOpen, setIsOpen, setQrBytesRaw }: Props) {
<div className="absolute inset-0 flex flex-col items-center justify-center rounded-2xl border-2 border-amber-500 text-center p-8">
<p className="text-red-400 font-bold text-lg mb-2">Camera access denied</p>
<p className="text-gray-600">Please allow camera access in your browser settings to scan QR codes</p>
<button type="button" onClick={requestPermission} className="pill button text-xs mt-2 !py-0.5 !px-2">
<button type="button" onClick={requestPermission} className="pill button text-xs mt-2 py-0.5! px-2!">
Request Permission
</button>
</div>

View file

@ -63,8 +63,8 @@ export default function TagSelector({ tags, setTags }: Props) {
return (
<div
className={`col-span-2 !justify-between pill input relative focus-within:ring-[3px] ring-orange-400/50 transition ${
tags.length > 0 ? "!py-1.5" : ""
className={`col-span-2 justify-between! pill input relative focus-within:ring-[3px] ring-orange-400/50 transition ${
tags.length > 0 ? "py-1.5!" : ""
}`}
>
{/* Tags */}

View file

@ -35,7 +35,7 @@ export default function TutorialPage({ text, imageSrc, carouselIndex, finishInde
}, [carouselIndex, finishIndex]);
return (
<div className="flex-shrink-0 flex flex-col w-full px-6">
<div className="shrink-0 flex flex-col w-full px-6">
{!finishIndex ? (
<>
<p className="text-sm text-zinc-500 mb-2 text-center">{text}</p>

View file

@ -43,7 +43,7 @@ export default function ScanTutorialButton() {
{isOpen &&
createPortal(
<div className="fixed inset-0 h-[calc(100%-var(--header-height))] top-[var(--header-height)] flex items-center justify-center z-40">
<div className="fixed inset-0 h-[calc(100%-var(--header-height))] top-(--header-height) flex items-center justify-center z-40">
<div
onClick={close}
className={`z-40 absolute inset-0 backdrop-brightness-75 backdrop-blur-xs transition-opacity duration-300 ${
@ -52,7 +52,7 @@ export default function ScanTutorialButton() {
/>
<div
className={`z-50 bg-orange-50 border-2 border-amber-500 rounded-2xl shadow-lg w-full max-w-md h-[30rem] transition-discrete duration-300 flex flex-col ${
className={`z-50 bg-orange-50 border-2 border-amber-500 rounded-2xl shadow-lg w-full max-w-md h-120 transition-discrete duration-300 flex flex-col ${
isVisible ? "scale-100 opacity-100" : "scale-75 opacity-0"
}`}
>
@ -79,7 +79,7 @@ export default function ScanTutorialButton() {
<button
onClick={() => emblaApi?.scrollPrev()}
aria-label="Scroll Carousel Left"
className="pill button !p-1 aspect-square text-2xl"
className="pill button p-1! aspect-square text-2xl"
>
<Icon icon="tabler:chevron-left" />
</button>
@ -89,7 +89,7 @@ export default function ScanTutorialButton() {
<button
onClick={() => emblaApi?.scrollNext()}
aria-label="Scroll Carousel Right"
className="pill button !p-1 aspect-square text-2xl"
className="pill button p-1! aspect-square text-2xl"
>
<Icon icon="tabler:chevron-right" />
</button>

View file

@ -14,12 +14,12 @@ export default function StartingPage({ emblaApi }: Props) {
};
return (
<div className="flex-shrink-0 flex flex-col w-full px-6 py-6">
<div className="shrink-0 flex flex-col w-full px-6 py-6">
{/* Separator */}
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium mb-2">
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
<span>Pick a tutorial</span>
<hr className="flex-grow border-zinc-300" />
<hr className="grow border-zinc-300" />
</div>
<div className="grid grid-cols-2 gap-4 h-full">

View file

@ -46,7 +46,7 @@ export default function SubmitTutorialButton() {
{isOpen &&
createPortal(
<div className="fixed inset-0 h-[calc(100%-var(--header-height))] top-[var(--header-height)] flex items-center justify-center z-40">
<div className="fixed inset-0 h-[calc(100%-var(--header-height))] top-(--header-height) flex items-center justify-center z-40">
<div
onClick={close}
className={`z-40 absolute inset-0 backdrop-brightness-75 backdrop-blur-xs transition-opacity duration-300 ${
@ -55,7 +55,7 @@ export default function SubmitTutorialButton() {
/>
<div
className={`z-50 bg-orange-50 border-2 border-amber-500 rounded-2xl shadow-lg w-full max-w-md h-[30rem] transition-discrete duration-300 flex flex-col ${
className={`z-50 bg-orange-50 border-2 border-amber-500 rounded-2xl shadow-lg w-full max-w-md h-120 transition-discrete duration-300 flex flex-col ${
isVisible ? "scale-100 opacity-100" : "scale-75 opacity-0"
}`}
>
@ -104,7 +104,7 @@ export default function SubmitTutorialButton() {
<button
onClick={() => emblaApi?.scrollPrev()}
disabled={isStartingPage}
className={`pill button !p-1 aspect-square text-2xl ${isStartingPage && "!cursor-auto"}`}
className={`pill button p-1! aspect-square text-2xl ${isStartingPage && "cursor-auto!"}`}
aria-label="Scroll Carousel Left"
>
<Icon icon="tabler:chevron-left" />
@ -115,7 +115,7 @@ export default function SubmitTutorialButton() {
<button
onClick={() => emblaApi?.scrollNext()}
disabled={isStartingPage}
className={`pill button !p-1 aspect-square text-2xl ${isStartingPage && "!cursor-auto"}`}
className={`pill button p-1! aspect-square text-2xl ${isStartingPage && "cursor-auto!"}`}
aria-label="Scroll Carousel Right"
>
<Icon icon="tabler:chevron-right" />

View file

@ -11,7 +11,7 @@
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"jsx": "react-jsx",
"incremental": true,
"plugins": [
{
@ -23,6 +23,6 @@
"sjcl-with-all": ["./node_modules/@types/sjcl"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", ".next/dev/types/**/*.ts"],
"exclude": ["node_modules"]
}