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, "private": true,
"packageManager": "pnpm@10.14.0", "packageManager": "pnpm@10.14.0",
"scripts": { "scripts": {
"dev": "next dev --turbopack", "dev": "next dev",
"build": "next build", "build": "next build",
"start": "next start", "start": "next start",
"lint": "next lint", "lint": "next lint",
@ -12,49 +12,49 @@
"test": "vitest" "test": "vitest"
}, },
"dependencies": { "dependencies": {
"@2toad/profanity": "^3.1.1", "@2toad/profanity": "^3.2.0",
"@auth/prisma-adapter": "2.10.0", "@auth/prisma-adapter": "2.11.1",
"@bprogress/next": "^3.2.12", "@bprogress/next": "^3.2.12",
"@hello-pangea/dnd": "^18.0.1", "@hello-pangea/dnd": "^18.0.1",
"@prisma/client": "^6.16.1", "@prisma/client": "^6.18.0",
"bit-buffer": "^0.2.5", "bit-buffer": "^0.2.5",
"canvas-confetti": "^1.9.3", "canvas-confetti": "^1.9.4",
"dayjs": "^1.11.18", "dayjs": "^1.11.18",
"downshift": "^9.0.10", "downshift": "^9.0.10",
"embla-carousel-react": "^8.6.0", "embla-carousel-react": "^8.6.0",
"file-type": "^21.0.0", "file-type": "^21.0.0",
"ioredis": "^5.7.0", "ioredis": "^5.8.2",
"jsqr": "^1.4.0", "jsqr": "^1.4.0",
"next": "15.5.3", "next": "16.0.1",
"next-auth": "5.0.0-beta.25", "next-auth": "5.0.0-beta.30",
"qrcode-generator": "^2.0.4", "qrcode-generator": "^2.0.4",
"react": "^19.1.1", "react": "^19.2.0",
"react-dom": "^19.1.1", "react-dom": "^19.2.0",
"react-dropzone": "^14.3.8", "react-dropzone": "^14.3.8",
"react-webcam": "^7.2.0", "react-webcam": "^7.2.0",
"satori": "^0.18.2", "satori": "^0.18.3",
"seedrandom": "^3.0.5", "seedrandom": "^3.0.5",
"sharp": "^0.34.3", "sharp": "^0.34.4",
"sjcl-with-all": "1.0.8", "sjcl-with-all": "1.0.8",
"swr": "^2.3.6", "swr": "^2.3.6",
"zod": "^4.1.8" "zod": "^4.1.12"
}, },
"devDependencies": { "devDependencies": {
"@eslint/eslintrc": "^3.3.1", "@eslint/eslintrc": "^3.3.1",
"@iconify/react": "^6.0.1", "@iconify/react": "^6.0.2",
"@tailwindcss/postcss": "^4.1.13", "@tailwindcss/postcss": "^4.1.16",
"@types/canvas-confetti": "^1.9.0", "@types/canvas-confetti": "^1.9.0",
"@types/node": "^24.3.1", "@types/node": "^24.9.2",
"@types/react": "^19.1.12", "@types/react": "^19.2.2",
"@types/react-dom": "^19.1.9", "@types/react-dom": "^19.2.2",
"@types/seedrandom": "^3.0.8", "@types/seedrandom": "^3.0.8",
"@types/sjcl": "^1.0.34", "@types/sjcl": "^1.0.34",
"eslint": "^9.35.0", "eslint": "^9.38.0",
"eslint-config-next": "15.5.3", "eslint-config-next": "16.0.1",
"prisma": "^6.16.1", "prisma": "^6.18.0",
"schema-dts": "^1.1.5", "schema-dts": "^1.1.5",
"tailwindcss": "^4.1.13", "tailwindcss": "^4.1.16",
"typescript": "^5.9.2", "typescript": "^5.9.3",
"vitest": "^3.2.4" "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 */} {/* Separator */}
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium my-1"> <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> <span>Banners</span>
<hr className="flex-grow border-zinc-300" /> <hr className="grow border-zinc-300" />
</div> </div>
<BannerForm /> <BannerForm />
{/* Separator */} {/* Separator */}
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium my-1"> <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> <span>Control Center</span>
<hr className="flex-grow border-zinc-300" /> <hr className="grow border-zinc-300" />
</div> </div>
<ControlCenter /> <ControlCenter />
{/* Separator */} {/* Separator */}
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium my-1"> <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> <span>User Management</span>
<hr className="flex-grow border-zinc-300" /> <hr className="grow border-zinc-300" />
</div> </div>
<UserManagement /> <UserManagement />
{/* Separator */} {/* Separator */}
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium my-1"> <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> <span>Reports</span>
<hr className="flex-grow border-zinc-300" /> <hr className="grow border-zinc-300" />
</div> </div>
<Reports /> <Reports />

View file

@ -21,14 +21,14 @@ export default async function CreateUsernamePage() {
} }
return ( 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"> <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> <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"> <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> <span>Please create a username</span>
<hr className="flex-grow border-zinc-300" /> <hr className="grow border-zinc-300" />
</div> </div>
<UsernameForm /> <UsernameForm />

View file

@ -92,7 +92,7 @@ export default function RootLayout({
<Providers> <Providers>
<Header /> <Header />
<AdminBanner /> <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 /> <Footer />
</Providers> </Providers>
</body> </body>

View file

@ -17,14 +17,14 @@ export default async function LoginPage() {
} }
return ( 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"> <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> <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"> <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> <span>Choose your login method</span>
<hr className="flex-grow border-zinc-300" /> <hr className="grow border-zinc-300" />
</div> </div>
<LoginButtons /> <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="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"> <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 */} {/* 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 <ImageViewer
src={`/mii/${mii.id}/image?type=mii`} src={`/mii/${mii.id}/image?type=mii`}
alt="mii headshot" 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> From: <span className="text-right font-medium">{mii.islandName} Island</span>
</li> </li>
<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> </li>
</ul> </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="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"> <div className="flex justify-between items-start">
{/* Submission name */} {/* 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 */} {/* Like button */}
<LikeButton <LikeButton
likes={mii._count.likedBy ?? 0} likes={mii._count.likedBy ?? 0}
@ -248,7 +248,7 @@ export default async function MiiPage({ params }: Props) {
{images.map((src, index) => ( {images.map((src, index) => (
<div <div
key={index} 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 <Image
src={src} src={src}
@ -263,7 +263,7 @@ export default async function MiiPage({ params }: Props) {
alt="mii screenshot" alt="mii screenshot"
width={256} width={256}
height={170} 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} images={images}
/> />
</div> </div>

View file

@ -9,7 +9,7 @@ export const metadata: Metadata = {
export default function NotFound() { export default function NotFound() {
return ( 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"> <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> <h2 className="text-7xl font-black">404</h2>
<p>Page not found - you swam off the island!</p> <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)); const duration = activePunishment.type === "TEMP_EXILE" && Math.ceil(expiresAt.diff(createdAt, "days", true));
return ( 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"> <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"> <h2 className="text-4xl font-black mb-2">
{activePunishment.type === "PERM_EXILE" {activePunishment.type === "PERM_EXILE"
@ -78,9 +78,9 @@ export default async function ExiledPage() {
</p> </p>
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium mt-4"> <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> <span>Violating Items</span>
<hr className="flex-grow border-zinc-300" /> <hr className="grow border-zinc-300" />
</div> </div>
<div className="flex flex-col gap-2 p-4"> <div className="flex flex-col gap-2 p-4">

View file

@ -37,7 +37,7 @@ export default async function SubmitPage() {
if (!value) if (!value)
return ( 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"> <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> <h2 className="text-5xl font-black">Sorry</h2>
<p className="mt-1">Submissions are disabled</p> <p className="mt-1">Submissions are disabled</p>

View file

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

View file

@ -55,7 +55,7 @@ export default function PunishmentDeletionDialog({ punishmentId }: Props) {
{isOpen && {isOpen &&
createPortal( 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 <div
onClick={close} onClick={close}
className={`z-40 absolute inset-0 backdrop-brightness-75 backdrop-blur-xs transition-opacity duration-300 ${ 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} disabled={hasExpired}
checked={isChecked} checked={isChecked}
onChange={(e) => setIsChecked(e.target.checked)} 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"}`}> <label htmlFor="agreement" className={`${hasExpired && "text-zinc-500"}`}>
I Agree I Agree

View file

@ -238,7 +238,7 @@ export default function Punishments() {
rows={2} rows={2}
maxLength={256} maxLength={256}
placeholder="Type notes here for the punishment..." placeholder="Type notes here for the punishment..."
className="pill input !rounded-xl resize-none" className="pill input rounded-xl! resize-none"
value={notes} value={notes}
onChange={(e) => setNotes(e.target.value)} onChange={(e) => setNotes(e.target.value)}
/> />
@ -249,7 +249,7 @@ export default function Punishments() {
rows={2} rows={2}
maxLength={256} maxLength={256}
placeholder="Type profile-related reasons here for the punishment..." 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} value={reasons}
onChange={(e) => setReasons(e.target.value)} onChange={(e) => setReasons(e.target.value)}
/> />
@ -273,7 +273,7 @@ export default function Punishments() {
value={newMii.reason} value={newMii.reason}
onChange={(e) => setNewMii({ ...newMii, reason: e.target.value })} 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" /> <Icon icon="ic:baseline-plus" className="size-4" />
</button> </button>
</div> </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={`overflow-hidden rounded-xl bg-zinc-300 ${className ?? ""}`} ref={emblaRef}>
<div className="flex"> <div className="flex">
{images.map((src, index) => ( {images.map((src, index) => (
<div key={index} className="flex-shrink-0 w-full"> <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} /> <ImageViewer src={src} alt="mii image" width={480} height={320} className="w-full h-auto aspect-3/2 object-contain" images={images} />
</div> </div>
))} ))}
</div> </div>

View file

@ -69,7 +69,7 @@ export default function DeleteMiiButton({ miiId, miiName, likes, inMiiPage }: Pr
{isOpen && {isOpen &&
createPortal( 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 <div
onClick={close} onClick={close}
className={`z-40 absolute inset-0 backdrop-brightness-75 backdrop-blur-xs transition-opacity duration-300 ${ 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"> <button onClick={close} className="pill button">
Cancel Cancel
</button> </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> </div>
</div>, </div>,

View file

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

View file

@ -9,7 +9,7 @@ export default function LoginButtons() {
<button <button
onClick={() => signIn("discord", { redirectTo: "/create-username" })} onClick={() => signIn("discord", { redirectTo: "/create-username" })}
aria-label="Login with Discord" 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} /> <Icon icon="ic:baseline-discord" fontSize={32} />
Login with Discord Login with Discord
@ -17,7 +17,7 @@ export default function LoginButtons() {
<button <button
onClick={() => signIn("github", { redirectTo: "/create-username" })} onClick={() => signIn("github", { redirectTo: "/create-username" })}
aria-label="Login with GitHub" 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} /> <Icon icon="mdi:github" fontSize={32} />
Login with GitHub Login with GitHub

View file

@ -6,7 +6,7 @@ import { signOut } from "next-auth/react";
export default function LogoutButton() { export default function LogoutButton() {
return ( return (
<li title="Logout"> <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} /> <Icon icon="ic:round-logout" fontSize={24} />
</button> </button>
</li> </li>

View file

@ -4,6 +4,7 @@ import { MiiGender, Prisma } from "@prisma/client";
import { Icon } from "@iconify/react"; import { Icon } from "@iconify/react";
import { z } from "zod"; import { z } from "zod";
import crypto from "crypto";
import seedrandom from "seedrandom"; import seedrandom from "seedrandom";
import { querySchema } from "@/lib/schemas"; import { querySchema } from "@/lib/schemas";
@ -125,7 +126,7 @@ export default async function MiiList({ searchParams, userId, inLikesPage }: Pro
if (sort === "random") { if (sort === "random") {
// Use seed for consistent random results // 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 // Get all IDs that match the where conditions
const matchingIds = await prisma.mii.findMany({ 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-label="Go to First Page"
aria-disabled={page === 1} aria-disabled={page === 1}
tabIndex={page === 1 ? -1 : undefined} tabIndex={page === 1 ? -1 : undefined}
className={`pill button !bg-orange-100 !p-0.5 aspect-square text-2xl ${ className={`pill button bg-orange-100! p-0.5! aspect-square text-2xl ${
page === 1 ? "pointer-events-none opacity-50" : "hover:!bg-orange-400" page === 1 ? "pointer-events-none opacity-50" : "hover:bg-orange-400!"
}`} }`}
> >
<Icon icon="stash:chevron-double-left" /> <Icon icon="stash:chevron-double-left" />
@ -57,7 +57,7 @@ export default function Pagination({ lastPage }: Props) {
aria-label="Go to Previous Page" aria-label="Go to Previous Page"
aria-disabled={page === 1} aria-disabled={page === 1}
tabIndex={page === 1 ? -1 : undefined} 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" /> <Icon icon="stash:chevron-left" />
</Link> </Link>
@ -70,7 +70,7 @@ export default function Pagination({ lastPage }: Props) {
href={createPageUrl(number)} href={createPageUrl(number)}
aria-label={`Go to Page ${number}`} aria-label={`Go to Page ${number}`}
aria-current={number === page ? "page" : undefined} 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} {number}
</Link> </Link>
@ -83,8 +83,8 @@ export default function Pagination({ lastPage }: Props) {
aria-label="Go to Next Page" aria-label="Go to Next Page"
aria-disabled={page === lastPage} aria-disabled={page === lastPage}
tabIndex={page === lastPage ? -1 : undefined} tabIndex={page === lastPage ? -1 : undefined}
className={`pill button !bg-orange-100 !p-0.5 aspect-square text-2xl ${ className={`pill button bg-orange-100! p-0.5! aspect-square text-2xl ${
page === lastPage ? "pointer-events-none opacity-50" : "hover:!bg-orange-400" page === lastPage ? "pointer-events-none opacity-50" : "hover:bg-orange-400!"
}`} }`}
> >
<Icon icon="stash:chevron-right" /> <Icon icon="stash:chevron-right" />
@ -96,8 +96,8 @@ export default function Pagination({ lastPage }: Props) {
aria-label="Go to Last Page" aria-label="Go to Last Page"
aria-disabled={page === lastPage} aria-disabled={page === lastPage}
tabIndex={page === lastPage ? -1 : undefined} tabIndex={page === lastPage ? -1 : undefined}
className={`pill button !bg-orange-100 !p-0.5 aspect-square text-2xl ${ className={`pill button bg-orange-100! p-0.5! aspect-square text-2xl ${
page === lastPage ? "pointer-events-none opacity-50" : "hover:!bg-orange-400" page === lastPage ? "pointer-events-none opacity-50" : "hover:bg-orange-400!"
}`} }`}
> >
<Icon icon="stash:chevron-double-right" /> <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"> <div key={index} className="flex flex-col bg-zinc-50 rounded-3xl border-2 border-zinc-300 shadow-lg p-3">
{/* Carousel Skeleton */} {/* Carousel Skeleton */}
<div className="relative rounded-xl bg-zinc-300 border-2 border-zinc-300 mb-1"> <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> </div>
{/* Content */} {/* Content */}

View file

@ -38,7 +38,7 @@ export default function SortSelect() {
return ( return (
<div className="relative w-fit"> <div className="relative w-fit">
{/* Toggle button to open the dropdown */} {/* 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> <span>Sort by </span>
{selectedItem || "Select a way to sort"} {selectedItem || "Select a way to sort"}
<Icon icon="tabler:chevron-down" className="ml-2 size-5" /> <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 */} {/* User information */}
<div className="flex flex-col w-full relative py-3"> <div className="flex flex-col w-full relative py-3">
<div className="flex items-center gap-2"> <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 && ( {isAdmin && (
<div data-tooltip="Admin" className="text-orange-400"> <div data-tooltip="Admin" className="text-orange-400">
<Icon icon="mdi:shield-moon" className="text-2xl" /> <Icon icon="mdi:shield-moon" className="text-2xl" />
@ -46,7 +46,7 @@ export default async function ProfileInformation({ userId, page }: Props) {
</div> </div>
)} )}
</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"> <div className="mt-auto text-sm flex gap-8">
<h4 title={`${user.createdAt.toLocaleTimeString("en-GB", { timeZone: "UTC" })} UTC`}> <h4 title={`${user.createdAt.toLocaleTimeString("en-GB", { timeZone: "UTC" })} UTC`}>

View file

@ -10,7 +10,7 @@ export default async function ProfileOverview() {
<Link <Link
href={`/profile/${session?.user.id}`} href={`/profile/${session?.user.id}`}
aria-label="Go to profile" 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" data-tooltip="Your Profile"
> >
<Image <Image

View file

@ -42,14 +42,14 @@ export default function DeleteAccount() {
<button <button
name="deletion" name="deletion"
onClick={() => setIsOpen(true)} 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 Delete Account
</button> </button>
{isOpen && {isOpen &&
createPortal( 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 <div
onClick={close} onClick={close}
className={`z-40 absolute inset-0 backdrop-brightness-75 backdrop-blur-xs transition-opacity duration-300 ${ 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"> <button onClick={close} className="pill button">
Cancel Cancel
</button> </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> </div>
</div>, </div>,

View file

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

View file

@ -5,7 +5,7 @@ import { Icon } from "@iconify/react";
export default function RandomLink() { export default function RandomLink() {
return ( 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} /> <Icon icon="mdi:dice-3" fontSize={28} />
</Link> </Link>
); );

View file

@ -67,7 +67,7 @@ export default function ReportMiiForm({ mii, likes }: Props) {
rows={3} rows={3}
maxLength={256} maxLength={256}
placeholder="Type notes here for the report..." 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} value={notes}
onChange={(e) => setNotes(e.target.value)} onChange={(e) => setNotes(e.target.value)}
/> />

View file

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

View file

@ -65,7 +65,7 @@ export default function ReportUserForm({ user }: Props) {
rows={3} rows={3}
maxLength={256} maxLength={256}
placeholder="Type notes here for the report..." 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} value={notes}
onChange={(e) => setNotes(e.target.value)} onChange={(e) => setNotes(e.target.value)}
/> />

View file

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

View file

@ -106,7 +106,7 @@ export default function EditForm({ mii, likes }: Props) {
return ( return (
<form className="flex justify-center gap-4 w-full max-lg:flex-col max-lg:items-center"> <form className="flex justify-center gap-4 w-full max-lg:flex-col max-lg:items-center">
<div className="flex justify-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 <Carousel
images={[`/mii/${mii.id}/image?type=mii`, `/mii/${mii.id}/image?type=qr-code`, ...files.map((file) => URL.createObjectURL(file))]} 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 */} {/* Separator */}
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium my-1"> <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> <span>Info</span>
<hr className="flex-grow border-zinc-300" /> <hr className="grow border-zinc-300" />
</div> </div>
<div className="w-full grid grid-cols-3 items-center"> <div className="w-full grid grid-cols-3 items-center">
@ -175,7 +175,7 @@ export default function EditForm({ mii, likes }: Props) {
rows={3} rows={3}
maxLength={256} maxLength={256}
placeholder="(optional) Type a description..." 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 ?? ""} value={description ?? ""}
onChange={(e) => setDescription(e.target.value)} onChange={(e) => setDescription(e.target.value)}
/> />
@ -183,9 +183,9 @@ export default function EditForm({ mii, likes }: Props) {
{/* Separator */} {/* Separator */}
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium mt-8 mb-2"> <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> <span>Custom images</span>
<hr className="flex-grow border-zinc-300" /> <hr className="grow border-zinc-300" />
</div> </div>
<div className="max-w-md w-full self-center"> <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} alt={file.name}
width={96} width={96}
height={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"> <div className="flex flex-col justify-center w-full min-w-0">
<span className="font-semibold overflow-hidden text-ellipsis">{file.name}</span> <span className="font-semibold overflow-hidden text-ellipsis">{file.name}</span>
<button <button
onClick={() => handleDelete(index)} 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 Delete
</button> </button>

View file

@ -126,7 +126,7 @@ export default function SubmitForm() {
return ( return (
<form className="flex justify-center gap-4 w-full max-lg:flex-col max-lg:items-center"> <form className="flex justify-center gap-4 w-full max-lg:flex-col max-lg:items-center">
<div className="flex justify-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))]} /> <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"> <div className="p-4 flex flex-col gap-1 h-full">
@ -157,9 +157,9 @@ export default function SubmitForm() {
{/* Separator */} {/* Separator */}
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium my-1"> <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> <span>Info</span>
<hr className="flex-grow border-zinc-300" /> <hr className="grow border-zinc-300" />
</div> </div>
<div className="w-full grid grid-cols-3 items-center"> <div className="w-full grid grid-cols-3 items-center">
@ -193,7 +193,7 @@ export default function SubmitForm() {
rows={3} rows={3}
maxLength={256} maxLength={256}
placeholder="(optional) Type a description..." 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} value={description}
onChange={(e) => setDescription(e.target.value)} onChange={(e) => setDescription(e.target.value)}
/> />
@ -201,9 +201,9 @@ export default function SubmitForm() {
{/* Separator */} {/* Separator */}
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium mt-8 mb-2"> <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> <span>QR Code</span>
<hr className="flex-grow border-zinc-300" /> <hr className="grow border-zinc-300" />
</div> </div>
<div className="flex flex-col items-center gap-2"> <div className="flex flex-col items-center gap-2">
@ -223,9 +223,9 @@ export default function SubmitForm() {
{/* Separator */} {/* Separator */}
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium mt-6 mb-2"> <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> <span>Custom images</span>
<hr className="flex-grow border-zinc-300" /> <hr className="grow border-zinc-300" />
</div> </div>
<div className="max-w-md w-full self-center"> <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; if (!isOpen) return null;
return ( 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 <div
onClick={close} onClick={close}
className={`z-40 absolute inset-0 backdrop-brightness-75 backdrop-blur-xs transition-opacity duration-300 ${ 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" type="button"
aria-label="Select camera dropdown" aria-label="Select camera dropdown"
{...getToggleButtonProps({}, { suppressRefError: true })} {...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"} {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"> <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-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> <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 Request Permission
</button> </button>
</div> </div>

View file

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

View file

@ -35,7 +35,7 @@ export default function TutorialPage({ text, imageSrc, carouselIndex, finishInde
}, [carouselIndex, finishIndex]); }, [carouselIndex, finishIndex]);
return ( 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 ? ( {!finishIndex ? (
<> <>
<p className="text-sm text-zinc-500 mb-2 text-center">{text}</p> <p className="text-sm text-zinc-500 mb-2 text-center">{text}</p>

View file

@ -43,7 +43,7 @@ export default function ScanTutorialButton() {
{isOpen && {isOpen &&
createPortal( 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 <div
onClick={close} onClick={close}
className={`z-40 absolute inset-0 backdrop-brightness-75 backdrop-blur-xs transition-opacity duration-300 ${ 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 <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" isVisible ? "scale-100 opacity-100" : "scale-75 opacity-0"
}`} }`}
> >
@ -79,7 +79,7 @@ export default function ScanTutorialButton() {
<button <button
onClick={() => emblaApi?.scrollPrev()} onClick={() => emblaApi?.scrollPrev()}
aria-label="Scroll Carousel Left" 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" /> <Icon icon="tabler:chevron-left" />
</button> </button>
@ -89,7 +89,7 @@ export default function ScanTutorialButton() {
<button <button
onClick={() => emblaApi?.scrollNext()} onClick={() => emblaApi?.scrollNext()}
aria-label="Scroll Carousel Right" 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" /> <Icon icon="tabler:chevron-right" />
</button> </button>

View file

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

View file

@ -46,7 +46,7 @@ export default function SubmitTutorialButton() {
{isOpen && {isOpen &&
createPortal( 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 <div
onClick={close} onClick={close}
className={`z-40 absolute inset-0 backdrop-brightness-75 backdrop-blur-xs transition-opacity duration-300 ${ 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 <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" isVisible ? "scale-100 opacity-100" : "scale-75 opacity-0"
}`} }`}
> >
@ -104,7 +104,7 @@ export default function SubmitTutorialButton() {
<button <button
onClick={() => emblaApi?.scrollPrev()} onClick={() => emblaApi?.scrollPrev()}
disabled={isStartingPage} 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" aria-label="Scroll Carousel Left"
> >
<Icon icon="tabler:chevron-left" /> <Icon icon="tabler:chevron-left" />
@ -115,7 +115,7 @@ export default function SubmitTutorialButton() {
<button <button
onClick={() => emblaApi?.scrollNext()} onClick={() => emblaApi?.scrollNext()}
disabled={isStartingPage} 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" aria-label="Scroll Carousel Right"
> >
<Icon icon="tabler:chevron-right" /> <Icon icon="tabler:chevron-right" />

View file

@ -11,7 +11,7 @@
"moduleResolution": "bundler", "moduleResolution": "bundler",
"resolveJsonModule": true, "resolveJsonModule": true,
"isolatedModules": true, "isolatedModules": true,
"jsx": "preserve", "jsx": "react-jsx",
"incremental": true, "incremental": true,
"plugins": [ "plugins": [
{ {
@ -23,6 +23,6 @@
"sjcl-with-all": ["./node_modules/@types/sjcl"] "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"] "exclude": ["node_modules"]
} }