diff --git a/package.json b/package.json index 271f1c5..63a6a2a 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.1.0", "private": true, "scripts": { - "dev": "next dev", + "dev": "next dev --turbopack", "build": "next build", "start": "next start", "lint": "next lint", @@ -27,6 +27,7 @@ "react-dropzone": "^14.3.8", "react-webcam": "^7.2.0", "sharp": "^0.34.1", + "swr": "^2.3.3", "zod": "^3.24.2" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 03dc676..1fb8ae8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -59,6 +59,9 @@ importers: sharp: specifier: ^0.34.1 version: 0.34.1 + swr: + specifier: ^2.3.3 + version: 2.3.3(react@19.1.0) zod: specifier: ^3.24.2 version: 3.24.2 @@ -1142,6 +1145,10 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + detect-libc@2.0.3: resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} engines: {node: '>=8'} @@ -2140,6 +2147,11 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + swr@2.3.3: + resolution: {integrity: sha512-dshNvs3ExOqtZ6kJBaAsabhPdHyeY4P2cKwRCniDVifBMoG/SVI7tfLWqPXriVspf2Rg4tPzXJTnwaihIeFw2A==} + peerDependencies: + react: ^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + tailwindcss@4.1.3: resolution: {integrity: sha512-2Q+rw9vy1WFXu5cIxlvsabCwhU2qUwodGq03ODhLJ0jW4ek5BUtoCsnLB0qG+m8AHgEsSJcJGDSDe06FXlP74g==} @@ -3148,6 +3160,8 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 + dequal@2.0.3: {} + detect-libc@2.0.3: {} doctrine@2.1.0: @@ -4379,6 +4393,12 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + swr@2.3.3(react@19.1.0): + dependencies: + dequal: 2.0.3 + react: 19.1.0 + use-sync-external-store: 1.5.0(react@19.1.0) + tailwindcss@4.1.3: {} tapable@2.2.1: {} diff --git a/src/app/components/mii-list/index.tsx b/src/app/components/mii-list/index.tsx index a9ca06f..d786e40 100644 --- a/src/app/components/mii-list/index.tsx +++ b/src/app/components/mii-list/index.tsx @@ -2,7 +2,7 @@ import { useSearchParams } from "next/navigation"; import Link from "next/link"; -import { useEffect, useState } from "react"; +import useSWR from "swr"; import SortSelect from "./sort-select"; import Carousel from "../carousel"; @@ -36,29 +36,11 @@ interface ApiResponse { }[]; } +const fetcher = (url: string) => fetch(url).then((res) => res.json()); + export default function MiiList({ isLoggedIn, userId }: Props) { const searchParams = useSearchParams(); - - const [data, setData] = useState(); - const [error, setError] = useState(); - - const getData = async () => { - const response = await fetch(`/api/mii/list?${searchParams.toString()}`); - const data = await response.json(); - - if (!response.ok) { - setError(data.error); - return; - } - - setData(data); - }; - - useEffect(() => { - getData(); - }, [searchParams.toString()]); - - // todo: show skeleton when data is undefined + const { data, error } = useSWR(`/api/mii/list?${searchParams.toString()}`, fetcher); return (