diff --git a/.gitignore b/.gitignore
index 4d29575de..0bfb20f6d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,3 +21,5 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*
+
+.next/
diff --git a/next-env.d.ts b/next-env.d.ts
new file mode 100644
index 000000000..52e831b43
--- /dev/null
+++ b/next-env.d.ts
@@ -0,0 +1,5 @@
+///
+///
+
+// NOTE: This file should not be edited
+// see https://nextjs.org/docs/pages/api-reference/config/typescript for more information.
diff --git a/next.config.js b/next.config.js
new file mode 100644
index 000000000..2544c5e7c
--- /dev/null
+++ b/next.config.js
@@ -0,0 +1,13 @@
+/** @type {import('next').NextConfig} */
+const nextConfig = {
+ reactStrictMode: true,
+ images: {
+ domains: [
+ "image.hanatour.com",
+ "sprint-fe-project.s3.ap-northeast-2.amazonaws.com",
+ "example.com",
+ ],
+ },
+};
+
+module.exports = nextConfig;
diff --git a/package-lock.json b/package-lock.json
index 1d4e4dada..76411f5b8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,11 +11,18 @@
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
- "react": "^18.2.0",
- "react-dom": "^18.2.0",
+ "axios": "^1.7.9",
+ "next": "^15.1.7",
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1",
"react-router-dom": "^7.0.1",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
+ },
+ "devDependencies": {
+ "@types/node": "^22.13.5",
+ "@types/react": "^19.0.10",
+ "typescript": "^5.7.3"
}
},
"node_modules/@aashutoshrathi/word-wrap": {
@@ -2271,6 +2278,16 @@
"postcss-selector-parser": "^6.0.10"
}
},
+ "node_modules/@emnapi/runtime": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz",
+ "integrity": "sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/@eslint-community/eslint-utils": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
@@ -2394,6 +2411,367 @@
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA=="
},
+ "node_modules/@img/sharp-darwin-arm64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz",
+ "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-arm64": "1.0.4"
+ }
+ },
+ "node_modules/@img/sharp-darwin-x64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz",
+ "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-x64": "1.0.4"
+ }
+ },
+ "node_modules/@img/sharp-libvips-darwin-arm64": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz",
+ "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-darwin-x64": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz",
+ "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-arm": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz",
+ "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-arm64": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz",
+ "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-s390x": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz",
+ "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-x64": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz",
+ "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linuxmusl-arm64": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz",
+ "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linuxmusl-x64": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz",
+ "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-linux-arm": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz",
+ "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm": "1.0.5"
+ }
+ },
+ "node_modules/@img/sharp-linux-arm64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz",
+ "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm64": "1.0.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-s390x": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz",
+ "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-s390x": "1.0.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-x64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz",
+ "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-x64": "1.0.4"
+ }
+ },
+ "node_modules/@img/sharp-linuxmusl-arm64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz",
+ "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-arm64": "1.0.4"
+ }
+ },
+ "node_modules/@img/sharp-linuxmusl-x64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz",
+ "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-x64": "1.0.4"
+ }
+ },
+ "node_modules/@img/sharp-wasm32": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz",
+ "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==",
+ "cpu": [
+ "wasm32"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/runtime": "^1.2.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-ia32": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz",
+ "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-x64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz",
+ "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
"node_modules/@istanbuljs/load-nyc-config": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
@@ -3133,6 +3511,140 @@
"resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz",
"integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A=="
},
+ "node_modules/@next/env": {
+ "version": "15.1.7",
+ "resolved": "https://registry.npmjs.org/@next/env/-/env-15.1.7.tgz",
+ "integrity": "sha512-d9jnRrkuOH7Mhi+LHav2XW91HOgTAWHxjMPkXMGBc9B2b7614P7kjt8tAplRvJpbSt4nbO1lugcT/kAaWzjlLQ==",
+ "license": "MIT"
+ },
+ "node_modules/@next/swc-darwin-arm64": {
+ "version": "15.1.7",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.1.7.tgz",
+ "integrity": "sha512-hPFwzPJDpA8FGj7IKV3Yf1web3oz2YsR8du4amKw8d+jAOHfYHYFpMkoF6vgSY4W6vB29RtZEklK9ayinGiCmQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-darwin-x64": {
+ "version": "15.1.7",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.1.7.tgz",
+ "integrity": "sha512-2qoas+fO3OQKkU0PBUfwTiw/EYpN+kdAx62cePRyY1LqKtP09Vp5UcUntfZYajop5fDFTjSxCHfZVRxzi+9FYQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-arm64-gnu": {
+ "version": "15.1.7",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.1.7.tgz",
+ "integrity": "sha512-sKLLwDX709mPdzxMnRIXLIT9zaX2w0GUlkLYQnKGoXeWUhcvpCrK+yevcwCJPdTdxZEUA0mOXGLdPsGkudGdnA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-arm64-musl": {
+ "version": "15.1.7",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.1.7.tgz",
+ "integrity": "sha512-zblK1OQbQWdC8fxdX4fpsHDw+VSpBPGEUX4PhSE9hkaWPrWoeIJn+baX53vbsbDRaDKd7bBNcXRovY1hEhFd7w==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-x64-gnu": {
+ "version": "15.1.7",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.1.7.tgz",
+ "integrity": "sha512-GOzXutxuLvLHFDAPsMP2zDBMl1vfUHHpdNpFGhxu90jEzH6nNIgmtw/s1MDwpTOiM+MT5V8+I1hmVFeAUhkbgQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-x64-musl": {
+ "version": "15.1.7",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.1.7.tgz",
+ "integrity": "sha512-WrZ7jBhR7ATW1z5iEQ0ZJfE2twCNSXbpCSaAunF3BKcVeHFADSI/AW1y5Xt3DzTqPF1FzQlwQTewqetAABhZRQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-win32-arm64-msvc": {
+ "version": "15.1.7",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.1.7.tgz",
+ "integrity": "sha512-LDnj1f3OVbou1BqvvXVqouJZKcwq++mV2F+oFHptToZtScIEnhNRJAhJzqAtTE2dB31qDYL45xJwrc+bLeKM2Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-win32-x64-msvc": {
+ "version": "15.1.7",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.1.7.tgz",
+ "integrity": "sha512-dC01f1quuf97viOfW05/K8XYv2iuBgAxJZl7mbCKEjMgdQl5JjAKJ0D2qMKZCgPWDeFbFT0Q0nYWwytEW0DWTQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
"node_modules/@nicolo-ribaudo/eslint-scope-5-internals": {
"version": "5.1.1-v1",
"resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz",
@@ -3560,6 +4072,21 @@
"url": "https://github.com/sponsors/gregberge"
}
},
+ "node_modules/@swc/counter": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
+ "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@swc/helpers": {
+ "version": "0.5.15",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
+ "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.8.0"
+ }
+ },
"node_modules/@testing-library/dom": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.1.tgz",
@@ -4304,9 +4831,13 @@
"integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw=="
},
"node_modules/@types/node": {
- "version": "20.5.9",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.9.tgz",
- "integrity": "sha512-PcGNd//40kHAS3sTlzKB9C9XL4K0sTup8nbG5lC14kzEteTNuAFh9u5nA0o5TWnSG2r/JNPRXFVcHJIIeRlmqQ=="
+ "version": "22.13.5",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.5.tgz",
+ "integrity": "sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg==",
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.20.0"
+ }
},
"node_modules/@types/parse-json": {
"version": "4.0.0",
@@ -4318,11 +4849,6 @@
"resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz",
"integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA=="
},
- "node_modules/@types/prop-types": {
- "version": "15.7.5",
- "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
- "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
- },
"node_modules/@types/q": {
"version": "1.5.6",
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.6.tgz",
@@ -4339,12 +4865,11 @@
"integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw=="
},
"node_modules/@types/react": {
- "version": "18.2.21",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.21.tgz",
- "integrity": "sha512-neFKG/sBAwGxHgXiIxnbm3/AAVQ/cMRS93hvBpg8xYRbeQSPVABp9U2bRnPf0iI4+Ucdv3plSxKK+3CW2ENJxA==",
+ "version": "19.0.10",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.10.tgz",
+ "integrity": "sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==",
+ "license": "MIT",
"dependencies": {
- "@types/prop-types": "*",
- "@types/scheduler": "*",
"csstype": "^3.0.2"
}
},
@@ -4369,11 +4894,6 @@
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
"integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA=="
},
- "node_modules/@types/scheduler": {
- "version": "0.16.3",
- "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
- "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ=="
- },
"node_modules/@types/semver": {
"version": "7.5.1",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.1.tgz",
@@ -5292,6 +5812,32 @@
"node": ">=4"
}
},
+ "node_modules/axios": {
+ "version": "1.7.9",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz",
+ "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==",
+ "license": "MIT",
+ "dependencies": {
+ "follow-redirects": "^1.15.6",
+ "form-data": "^4.0.0",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
+ "node_modules/axios/node_modules/form-data": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz",
+ "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==",
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/axobject-query": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz",
@@ -5777,6 +6323,17 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/busboy": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
+ "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
+ "dependencies": {
+ "streamsearch": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=10.16.0"
+ }
+ },
"node_modules/bytes": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
@@ -5797,6 +6354,19 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@@ -5845,9 +6415,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001528",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001528.tgz",
- "integrity": "sha512-0Db4yyjR9QMNlsxh+kKWzQtkyflkG/snYheSzkjmvdEtEXB1+jt7A2HmSEiO6XIJPIbo92lHNGNySvE5pZcs5Q==",
+ "version": "1.0.30001700",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001700.tgz",
+ "integrity": "sha512-2S6XIXwaE7K7erT8dY+kLQcpa5ms63XlRkMkReXjle+kf6c5g38vyMl+Z5y8dSxOFDhcFe+nxnn261PLxBSQsQ==",
"funding": [
{
"type": "opencollective",
@@ -5861,7 +6431,8 @@
"type": "github",
"url": "https://github.com/sponsors/ai"
}
- ]
+ ],
+ "license": "CC-BY-4.0"
},
"node_modules/case-sensitive-paths-webpack-plugin": {
"version": "2.4.0",
@@ -5980,6 +6551,12 @@
"node": ">=0.10.0"
}
},
+ "node_modules/client-only": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
+ "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
+ "license": "MIT"
+ },
"node_modules/cliui": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
@@ -6017,6 +6594,20 @@
"resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz",
"integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q=="
},
+ "node_modules/color": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
+ "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "color-convert": "^2.0.1",
+ "color-string": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=12.5.0"
+ }
+ },
"node_modules/color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@@ -6030,6 +6621,37 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
},
+ "node_modules/color-string": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
+ "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "color-name": "^1.0.0",
+ "simple-swizzle": "^0.2.2"
+ }
+ },
+ "node_modules/color/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "license": "MIT",
+ "optional": true
+ },
"node_modules/colord": {
"version": "2.9.3",
"resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz",
@@ -6798,6 +7420,16 @@
"npm": "1.2.8000 || >= 1.4.16"
}
},
+ "node_modules/detect-libc": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
+ "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/detect-newline": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
@@ -7001,6 +7633,20 @@
"resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz",
"integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA=="
},
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/duplexer": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
@@ -7155,6 +7801,24 @@
"resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz",
"integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA=="
},
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/es-get-iterator": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz",
@@ -7200,14 +7864,28 @@
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz",
"integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA=="
},
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/es-set-tostringtag": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz",
- "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "license": "MIT",
"dependencies": {
- "get-intrinsic": "^1.1.3",
- "has": "^1.0.3",
- "has-tostringtag": "^1.0.0"
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -8301,15 +8979,16 @@
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ=="
},
"node_modules/follow-redirects": {
- "version": "1.15.2",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
- "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
+ "version": "1.15.9",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
+ "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
+ "license": "MIT",
"engines": {
"node": ">=4.0"
},
@@ -8561,9 +9240,13 @@
}
},
"node_modules/function-bind": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
- "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
},
"node_modules/function.prototype.name": {
"version": "1.1.6",
@@ -8607,14 +9290,24 @@
}
},
"node_modules/get-intrinsic": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
- "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "license": "MIT",
"dependencies": {
- "function-bind": "^1.1.1",
- "has": "^1.0.3",
- "has-proto": "^1.0.1",
- "has-symbols": "^1.0.3"
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -8633,6 +9326,19 @@
"node": ">=8.0.0"
}
},
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/get-stream": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
@@ -8771,11 +9477,12 @@
}
},
"node_modules/gopd": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
- "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
- "dependencies": {
- "get-intrinsic": "^1.1.3"
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -8865,9 +9572,10 @@
}
},
"node_modules/has-symbols": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
- "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
},
@@ -8876,11 +9584,12 @@
}
},
"node_modules/has-tostringtag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
- "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "license": "MIT",
"dependencies": {
- "has-symbols": "^1.0.2"
+ "has-symbols": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
@@ -8889,6 +9598,18 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/he": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
@@ -12193,6 +12914,15 @@
"tmpl": "1.0.5"
}
},
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/mdn-data": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz",
@@ -12470,6 +13200,60 @@
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
},
+ "node_modules/next": {
+ "version": "15.1.7",
+ "resolved": "https://registry.npmjs.org/next/-/next-15.1.7.tgz",
+ "integrity": "sha512-GNeINPGS9c6OZKCvKypbL8GTsT5GhWPp4DM0fzkXJuXMilOO2EeFxuAY6JZbtk6XIl6Ws10ag3xRINDjSO5+wg==",
+ "license": "MIT",
+ "dependencies": {
+ "@next/env": "15.1.7",
+ "@swc/counter": "0.1.3",
+ "@swc/helpers": "0.5.15",
+ "busboy": "1.6.0",
+ "caniuse-lite": "^1.0.30001579",
+ "postcss": "8.4.31",
+ "styled-jsx": "5.1.6"
+ },
+ "bin": {
+ "next": "dist/bin/next"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^19.8.0 || >= 20.0.0"
+ },
+ "optionalDependencies": {
+ "@next/swc-darwin-arm64": "15.1.7",
+ "@next/swc-darwin-x64": "15.1.7",
+ "@next/swc-linux-arm64-gnu": "15.1.7",
+ "@next/swc-linux-arm64-musl": "15.1.7",
+ "@next/swc-linux-x64-gnu": "15.1.7",
+ "@next/swc-linux-x64-musl": "15.1.7",
+ "@next/swc-win32-arm64-msvc": "15.1.7",
+ "@next/swc-win32-x64-msvc": "15.1.7",
+ "sharp": "^0.33.5"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.1.0",
+ "@playwright/test": "^1.41.2",
+ "babel-plugin-react-compiler": "*",
+ "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0",
+ "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0",
+ "sass": "^1.3.0"
+ },
+ "peerDependenciesMeta": {
+ "@opentelemetry/api": {
+ "optional": true
+ },
+ "@playwright/test": {
+ "optional": true
+ },
+ "babel-plugin-react-compiler": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ }
+ }
+ },
"node_modules/no-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
@@ -13092,9 +13876,9 @@
}
},
"node_modules/postcss": {
- "version": "8.4.29",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz",
- "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==",
+ "version": "8.4.31",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
+ "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
"funding": [
{
"type": "opencollective",
@@ -13109,6 +13893,7 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"dependencies": {
"nanoid": "^3.3.6",
"picocolors": "^1.0.0",
@@ -14382,6 +15167,12 @@
"node": ">= 0.10"
}
},
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+ "license": "MIT"
+ },
"node_modules/psl": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
@@ -14500,9 +15291,10 @@
}
},
"node_modules/react": {
- "version": "18.2.0",
- "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
- "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
+ "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
+ "license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0"
},
@@ -14649,15 +15441,16 @@
}
},
"node_modules/react-dom": {
- "version": "18.2.0",
- "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
- "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
+ "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
+ "license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0",
- "scheduler": "^0.23.0"
+ "scheduler": "^0.23.2"
},
"peerDependencies": {
- "react": "^18.2.0"
+ "react": "^18.3.1"
}
},
"node_modules/react-error-overlay": {
@@ -15333,9 +16126,10 @@
}
},
"node_modules/scheduler": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
- "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "version": "0.23.2",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
+ "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
+ "license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0"
}
@@ -15374,12 +16168,10 @@
}
},
"node_modules/semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
+ "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
+ "license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
@@ -15387,22 +16179,6 @@
"node": ">=10"
}
},
- "node_modules/semver/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/semver/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
- },
"node_modules/send": {
"version": "0.18.0",
"resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
@@ -15547,6 +16323,46 @@
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
},
+ "node_modules/sharp": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz",
+ "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "color": "^4.2.3",
+ "detect-libc": "^2.0.3",
+ "semver": "^7.6.3"
+ },
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-darwin-arm64": "0.33.5",
+ "@img/sharp-darwin-x64": "0.33.5",
+ "@img/sharp-libvips-darwin-arm64": "1.0.4",
+ "@img/sharp-libvips-darwin-x64": "1.0.4",
+ "@img/sharp-libvips-linux-arm": "1.0.5",
+ "@img/sharp-libvips-linux-arm64": "1.0.4",
+ "@img/sharp-libvips-linux-s390x": "1.0.4",
+ "@img/sharp-libvips-linux-x64": "1.0.4",
+ "@img/sharp-libvips-linuxmusl-arm64": "1.0.4",
+ "@img/sharp-libvips-linuxmusl-x64": "1.0.4",
+ "@img/sharp-linux-arm": "0.33.5",
+ "@img/sharp-linux-arm64": "0.33.5",
+ "@img/sharp-linux-s390x": "0.33.5",
+ "@img/sharp-linux-x64": "0.33.5",
+ "@img/sharp-linuxmusl-arm64": "0.33.5",
+ "@img/sharp-linuxmusl-x64": "0.33.5",
+ "@img/sharp-wasm32": "0.33.5",
+ "@img/sharp-win32-ia32": "0.33.5",
+ "@img/sharp-win32-x64": "0.33.5"
+ }
+ },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -15592,6 +16408,23 @@
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
},
+ "node_modules/simple-swizzle": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+ "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "is-arrayish": "^0.3.1"
+ }
+ },
+ "node_modules/simple-swizzle/node_modules/is-arrayish": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
+ "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
+ "license": "MIT",
+ "optional": true
+ },
"node_modules/sisteransi": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
@@ -15854,6 +16687,14 @@
"node": ">= 0.4"
}
},
+ "node_modules/streamsearch": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
+ "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
"node_modules/string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
@@ -16042,6 +16883,29 @@
"webpack": "^5.0.0"
}
},
+ "node_modules/styled-jsx": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz",
+ "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==",
+ "license": "MIT",
+ "dependencies": {
+ "client-only": "0.0.1"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "peerDependencies": {
+ "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0"
+ },
+ "peerDependenciesMeta": {
+ "@babel/core": {
+ "optional": true
+ },
+ "babel-plugin-macros": {
+ "optional": true
+ }
+ }
+ },
"node_modules/stylehacks": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz",
@@ -16551,9 +17415,10 @@
}
},
"node_modules/tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "license": "0BSD"
},
"node_modules/tsutils": {
"version": "3.21.0",
@@ -16692,16 +17557,16 @@
}
},
"node_modules/typescript": {
- "version": "4.9.5",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
- "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
- "peer": true,
+ "version": "5.7.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz",
+ "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==",
+ "license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
- "node": ">=4.2.0"
+ "node": ">=14.17"
}
},
"node_modules/unbox-primitive": {
@@ -16723,6 +17588,12 @@
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz",
"integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw=="
},
+ "node_modules/undici-types": {
+ "version": "6.20.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
+ "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
+ "license": "MIT"
+ },
"node_modules/unicode-canonical-property-names-ecmascript": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
diff --git a/package.json b/package.json
index 30d5af03c..edfa013d7 100644
--- a/package.json
+++ b/package.json
@@ -6,15 +6,18 @@
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
- "react": "^18.2.0",
- "react-dom": "^18.2.0",
+ "axios": "^1.7.9",
+ "next": "^15.1.7",
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1",
"react-router-dom": "^7.0.1",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
- "start": "react-scripts start",
- "build": "react-scripts build",
+ "dev": "next dev",
+ "build": "next build",
+ "start": "next start",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
@@ -35,5 +38,10 @@
"last 1 firefox version",
"last 1 safari version"
]
+ },
+ "devDependencies": {
+ "@types/node": "^22.13.5",
+ "@types/react": "^19.0.10",
+ "typescript": "^5.7.3"
}
}
diff --git a/src/pages/Additem.css b/pages/Additem.module.css
similarity index 56%
rename from src/pages/Additem.css
rename to pages/Additem.module.css
index c5d85a876..2e631abb3 100644
--- a/src/pages/Additem.css
+++ b/pages/Additem.module.css
@@ -1,4 +1,4 @@
-form {
+.edit {
@media (max-width: 1199px) {
padding-left: 24px;
padding-right: 24px;
@@ -10,16 +10,29 @@ form {
}
}
-.Additem .edit {
+.additem .edit {
max-width: 1201px;
width: 100%;
margin: 0 auto;
}
.edit_title {
- margin: 24px 0;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
height: 42px;
+ white-space: nowrap;
+ margin: 24px 0;
font-size: 20px;
font-weight: 700;
line-height: 32px;
}
+
+.titleBtn {
+ height: 42px;
+ border: none;
+ border-radius: 8px;
+ padding: 12px 23px;
+ background-color: #9ca3af;
+ color: #f3f4f6;
+}
diff --git a/pages/Additem.tsx b/pages/Additem.tsx
new file mode 100644
index 000000000..772f319f7
--- /dev/null
+++ b/pages/Additem.tsx
@@ -0,0 +1,66 @@
+import styles from "./Additem.module.css";
+import Nav from "../src/components/Nav";
+import Editsection from "../src/components/Editsection";
+import Editinput from "../src/components/Editinput";
+
+export default function Additem() {
+ return (
+
+
+ {/* 아래는 상품등록 페이지 구현 */}
+
+
+ );
+}
diff --git a/pages/Home.module.css b/pages/Home.module.css
new file mode 100644
index 000000000..d0f745b69
--- /dev/null
+++ b/pages/Home.module.css
@@ -0,0 +1,139 @@
+.hero_info_title {
+ font-size: 40px;
+ font-weight: 700;
+ line-height: 56px;
+
+ @media (max-width: 767px) {
+ font-size: 32px;
+ line-height: 45px;
+ }
+}
+
+.homeContainer {
+ color: #374151;
+ max-width: 1920px;
+ word-break: keep-all;
+}
+
+.logo {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ align-items: center;
+ padding: 9px 0;
+
+ @media (max-width: 1920px) {
+ margin-left: 200px;
+ margin-right: 200px;
+ }
+ @media (max-width: 1199px) {
+ margin-left: 24px;
+ margin-right: 24px;
+ }
+ @media (max-width: 767px) {
+ margin-left: 16px;
+ margin-right: 16px;
+ }
+}
+
+.hero_backgroundcolor {
+ background-color: #cfe5ff;
+ max-width: 1920vh;
+ height: 540px;
+ position: relative;
+
+ @media (max-width: 1199px) {
+ height: 771px;
+ }
+ @media (max-width: 767px) {
+ height: 540px;
+ }
+}
+
+.hero_container {
+ display: flex;
+ position: absolute;
+ bottom: 0;
+ left: 50%;
+ transform: translate(-50%);
+
+ @media (max-width: 1199px) {
+ flex-direction: column;
+ align-items: center;
+ }
+}
+
+.hero_info {
+ display: flex;
+ flex-direction: column;
+ margin: 40px 0;
+
+ @media (max-width: 1199px) {
+ margin: 84px 0 211px;
+ align-items: center;
+ }
+ @media (max-width: 767px) {
+ margin: 48px 67px 0;
+ }
+}
+
+.hero_info > h1 {
+ font-size: 40px;
+ font-weight: 700;
+ line-height: 56px;
+ margin-bottom: 32px;
+
+ @media (max-width: 1199px) {
+ text-align: center;
+ margin-bottom: 24px;
+ }
+ @media (max-width: 767px) {
+ font-size: 32px;
+ line-height: 45px;
+ width: 240px;
+ }
+}
+
+.display {
+ padding: 24px;
+ width: 100%;
+
+ @media (max-width: 767px) {
+ padding: 52px 16px;
+ }
+}
+
+.footerContainer {
+ background-color: #111827;
+ height: 160px;
+ padding: 32px 0;
+}
+
+.footerBox {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ align-items: center;
+ max-width: 1110px;
+ margin: 0 auto;
+}
+
+.codeit {
+ color: #9ca3af;
+ margin: 0.5px 0 0.5px;
+}
+
+.sitelink {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-around;
+ gap: 30px;
+ margin: 0.5px 0 0.5px;
+}
+
+.sns_link {
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-end;
+ gap: 12px;
+}
diff --git a/pages/Home.tsx b/pages/Home.tsx
new file mode 100644
index 000000000..135239724
--- /dev/null
+++ b/pages/Home.tsx
@@ -0,0 +1,157 @@
+import Button from "../src/components/Button";
+import styles from "./Home.module.css";
+import HomePageSection from "../src/components/HomePageSection";
+import Link from "next/link";
+import Image from "next/image";
+
+export default function Home() {
+ return (
+
+
+
+
+
+
+
+ 일상의 모든 물건을 거래해 보세요
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 믿을 수 있는 판다마켓 중고 거래
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/pages/Items.module.css b/pages/Items.module.css
new file mode 100644
index 000000000..c34489b94
--- /dev/null
+++ b/pages/Items.module.css
@@ -0,0 +1,212 @@
+.items_title {
+ font-size: 20px;
+ font-weight: 700;
+ line-height: 32px;
+}
+
+.container {
+ max-width: 1200px;
+ margin: 0 auto;
+
+ @media (max-width: 1199px) {
+ padding: 0 24px;
+ }
+
+ @media (max-width: 767px) {
+ padding: 0 16px;
+ }
+}
+
+.bestItems {
+ margin-top: 24px;
+}
+
+.itemFavorit {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ font-size: 12px;
+ font-weight: 500;
+ line-height: 18px;
+}
+
+.totalItems {
+ margin-top: 40px;
+}
+
+.item_bar {
+ display: flex;
+ align-content: center;
+ gap: 12px;
+ margin-bottom: 24px;
+ white-space: nowrap;
+ flex-wrap: wrap;
+ align-items: stretch;
+
+ @media (max-width: 767px) {
+ display: grid;
+ grid-template-rows: repeat((2, 1fr));
+ grid-template-columns: 1fr 135px;
+ }
+}
+
+.item:nth-child(1) {
+ flex: 1;
+
+ @media (max-width: 767px) {
+ order: 1;
+ }
+}
+
+.item:nth-child(2) {
+ @media (max-width: 767px) {
+ order: 3;
+ flex: 1;
+ }
+}
+
+.item:nth-child(3) {
+ @media (max-width: 767px) {
+ order: 2;
+ }
+}
+
+.item:nth-child(4) {
+ @media (max-width: 767px) {
+ order: 4;
+ }
+}
+
+.item_input {
+ width: 325px;
+ height: 42px;
+ padding: 9px 20px 9px 44px;
+ border: none;
+ border-radius: 12px;
+ background-color: #f3f4f6;
+ font-weight: 400;
+ font-size: 16px;
+ line-height: 26px;
+ @media (max-width: 767px) {
+ width: 100%;
+ }
+}
+
+.searchBox {
+ position: relative;
+}
+
+.search_icon {
+ position: absolute;
+ top: 13px;
+ left: 20px;
+}
+
+.itemAdd_button {
+ display: flex;
+ align-items: center;
+ height: 42px;
+ padding: 12px 23px;
+ border: none;
+ border-radius: 8px;
+ background-color: #3692ff;
+ color: #f3f4f6;
+ font-weight: 600;
+ font-size: 16px;
+ line-height: 26px;
+ cursor: pointer;
+}
+
+.select {
+ width: 130px;
+ height: 42px;
+ border-radius: 12px;
+ border: 1px solid #e5e7eb;
+}
+
+.item_select {
+ border: 1px solid #e5e7eb;
+ border-radius: 12px;
+ width: 130px;
+ height: 42px;
+ padding: 12px 20px;
+}
+
+.totalItemsBox {
+ display: grid;
+ grid-template-rows: 2fr;
+ grid-template-columns: repeat(5, 1fr);
+ gap: 24px;
+
+ @media (max-width: 1199px) {
+ grid-template-columns: repeat(3, 1fr);
+ .totalItemsContainer:nth-child(n + 7) {
+ display: none;
+ }
+ }
+ @media (max-width: 767px) {
+ grid-template-columns: repeat(2, 1fr);
+ .totalItemsContainer:nth-child(n + 5) {
+ display: none;
+ }
+ }
+}
+
+.totalItemsContainer {
+ cursor: pointer;
+}
+
+.totalItemsBox > div {
+ display: flex;
+ flex-direction: column;
+}
+
+.totalItemsBox .itemTotal {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ font-size: 12px;
+ font-weight: 500;
+ line-height: 18px;
+}
+
+.totalItemsBox .totalItemsContainer > div {
+ margin-bottom: 6px;
+}
+
+.totalItemsBox {
+ @media (max-width: 1199px) {
+ .totalItem:nth-child(n + 7) {
+ display: none;
+ }
+ }
+
+ @media (max-width: 767px) {
+ .totalItem:nth-child(n + 5) {
+ display: none;
+ }
+ }
+}
+
+/* .pagenation_box {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 4px;
+ padding: 43px 0 53px;
+}
+
+.page_button {
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ border: 1px solid #e5e7eb;
+ outline: none;
+ color: #6b7280;
+ cursor: pointer;
+}
+
+.active {
+ background-color: #2f80ed;
+ color: #f9fafb;
+} */
diff --git a/pages/Items.tsx b/pages/Items.tsx
new file mode 100644
index 000000000..a24cfea75
--- /dev/null
+++ b/pages/Items.tsx
@@ -0,0 +1,102 @@
+import { useEffect, useState } from "react";
+import { getProductData } from "../src/api/api";
+import Nav from "../src/components/Nav";
+import ItemCard from "../src/components/ItemCard";
+import Bestitem from "../src/components/Bestitem";
+import styles from "./Items.module.css";
+import Link from "next/link";
+import Image from "next/image";
+
+interface Item {
+ id: number;
+ name: string;
+ price: number;
+ images: string[];
+ favoriteCount?: number;
+}
+
+interface ProductResponse {
+ list: Item[];
+}
+
+export default function Items() {
+ const [itemList, setItemList] = useState- ([]);
+
+ useEffect(() => {
+ const fetchProduct = async () => {
+ try {
+ const products: ProductResponse = await getProductData({
+ orderBy: "recent",
+ });
+ setItemList(products.list);
+ } catch (error) {
+ console.error("Error fetching products:", error);
+ }
+ };
+
+ fetchProduct();
+ }, []);
+
+ return (
+
+
+
+
+
+
+
+ 전체 상품
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {itemList?.map((item) => (
+
+ ))}
+
+
+
+ {/* 페이지네이션 영역 구현하지않음 */}
+ {/*
+
+
+
+ */}
+
+ );
+}
diff --git a/pages/Login.module.css b/pages/Login.module.css
new file mode 100644
index 000000000..a7f182e48
--- /dev/null
+++ b/pages/Login.module.css
@@ -0,0 +1,148 @@
+/* * {
+ font-family: "Pretendard", sans-serif;
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+ word-break: keep-all;
+} */
+
+.container {
+ margin: 0 auto;
+ padding: 16px;
+ color: #1f2937;
+
+ @media (min-width: 768px) {
+ max-width: 640px;
+ padding: 53px;
+ }
+}
+
+.header {
+ display: block;
+ text-align: center;
+ margin-bottom: 24px;
+
+ @media (min-width: 768px) {
+ margin-bottom: 40px;
+ }
+}
+
+.logo {
+ width: 198px;
+ height: 66px;
+
+ @media (min-width: 768px) {
+ width: 396px;
+ height: 132px;
+ }
+}
+
+.formDiv {
+ display: block;
+ position: relative;
+ margin-bottom: 16px;
+
+ @media (min-width: 768px) {
+ margin-bottom: 24px;
+ }
+}
+
+.formLabel {
+ font-weight: 700;
+ font-size: 14px;
+ line-height: 17px;
+ color: #1f2937;
+
+ @media (min-width: 768px) {
+ font-size: 18px;
+ line-height: 21px;
+ }
+}
+
+.formInput {
+ background-color: #f3f4f6;
+ width: 100%;
+ margin-top: 8px;
+ padding: 16px 24px;
+ border: none;
+ border-radius: 12px;
+ font-weight: 400;
+ font-size: 16px;
+ line-height: 26px;
+
+ @media (min-width: 768px) {
+ margin-top: 16px;
+ }
+}
+
+.toggleTag {
+ position: absolute;
+ top: 43px;
+ right: 24px;
+
+ @media (min-width: 768px) {
+ top: 53px;
+ }
+}
+
+.toggleImg {
+ cursor: pointer;
+ width: 24px;
+ height: 24px;
+}
+
+.button {
+ display: flex;
+ justify-content: center;
+ cursor: pointer;
+ background-color: #9ca3af;
+ width: 100%;
+ padding: 16px 124px;
+ border: none;
+ border-radius: 40px;
+ font-weight: 600;
+ font-size: 20px;
+ line-height: 32px;
+ color: #f3f4f6;
+ margin-bottom: 24px;
+}
+
+.disabled {
+ background-color: #3692ff;
+}
+
+.loginBox {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ background-color: #e6f2ff;
+ border: none;
+ border-radius: 8px;
+ padding: 16px 24px;
+ margin-bottom: 25px;
+}
+
+.loginImgBox {
+ display: flex;
+ gap: 16px;
+}
+
+.loginLink {
+ font-weight: 500;
+ font-size: 14px;
+ line-height: 24px;
+ text-align: center;
+}
+
+.errorMessage {
+ margin-top: 8px;
+ padding-left: 16px;
+ font-weight: 600;
+ font-size: 14px;
+ line-height: 24px;
+ color: #f74747;
+}
+
+.errorInput {
+ border: 1px solid #f74747;
+}
diff --git a/pages/Login.tsx b/pages/Login.tsx
new file mode 100644
index 000000000..57d2268bb
--- /dev/null
+++ b/pages/Login.tsx
@@ -0,0 +1,195 @@
+import { ChangeEvent, FormEvent, useEffect, useState } from "react";
+import styles from "./Login.module.css";
+import Link from "next/link";
+import { useRouter } from "next/router";
+import { postUserLoginData } from "../src/api/api";
+import Image from "next/image";
+
+const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
+const PASSWORD_MIN_LEN = 8;
+
+export default function Signup() {
+ const [email, setEmail] = useState("");
+ const [password, setPassword] = useState("");
+ const [emailError, setEmailError] = useState(null);
+ const [passwordError, setPasswordError] = useState(null);
+ const [isButtonDisabled, setIsButtonDisabled] = useState(true);
+ const [isPasswordVisible, setIsPasswordVisible] = useState(false);
+ const router = useRouter();
+
+ // 이메일 값 체크
+ const emailCheck = (email: string): string | null => {
+ if (!email.trim()) return "이메일을 입력해주세요";
+ if (!emailRegex.test(email)) return "잘못된 이메일 형식입니다";
+
+ return null;
+ };
+
+ const onChangeEmail = (e: ChangeEvent) => {
+ const value = e.target.value;
+ setEmail(value);
+ setEmailError(emailCheck(value));
+ };
+
+ // 비밀번호 값 체크
+ const passwordCheck = (password: string): string | null => {
+ if (!password.trim()) return `패스워드를 입력해주세요`;
+ if (password.length < PASSWORD_MIN_LEN)
+ return `패스워드를 ${PASSWORD_MIN_LEN}자 이상입력해주세요`;
+
+ return null;
+ };
+
+ const onChangePassword = (e: ChangeEvent) => {
+ const nextPassword = e.target.value;
+ setPassword(nextPassword);
+ setPasswordError(passwordCheck(nextPassword));
+ };
+
+ // 로그인 버튼 활성화
+ useEffect(() => {
+ const isValidForm = !emailError && !passwordError && email && password;
+ setIsButtonDisabled(!isValidForm);
+ }, [emailError, passwordError, email, password]);
+
+ // 비밀번호 타입 토글
+ const togglePasswordVisibility = () => {
+ setIsPasswordVisible((prevState) => !prevState);
+ };
+
+ // 서버에 post 요청
+ const handleSignIn = async (e: FormEvent) => {
+ e.preventDefault();
+
+ const userData = {
+ email: email,
+ password: password,
+ };
+ console.log(userData);
+
+ try {
+ const result = await postUserLoginData(userData);
+
+ if (result.success) {
+ console.log(result);
+ router.push("/Items");
+ } else {
+ alert(result.message || "로그인에 실패했습니다.");
+ }
+ } catch (error) {
+ console.error("로그인 오류:", error);
+ alert("로그인 중 오류가 발생했습니다. 다시 시도해 주세요.");
+ }
+ };
+
+ return (
+
+
+
+
+
+ 판다마켓이 처음이신가요?
+
+ 회원가입
+
+
+
+ );
+}
diff --git a/pages/Notfound.tsx b/pages/Notfound.tsx
new file mode 100644
index 000000000..b94e56317
--- /dev/null
+++ b/pages/Notfound.tsx
@@ -0,0 +1,3 @@
+export default function Notfound() {
+ return Notfound
;
+}
diff --git a/pages/Signup.module.css b/pages/Signup.module.css
new file mode 100644
index 000000000..25883b35e
--- /dev/null
+++ b/pages/Signup.module.css
@@ -0,0 +1,140 @@
+.container {
+ margin: 0 auto;
+ padding: 16px;
+ color: #1f2937;
+
+ @media (min-width: 768px) {
+ max-width: 640px;
+ padding: 53px;
+ }
+}
+
+.header {
+ display: block;
+ text-align: center;
+ margin-bottom: 24px;
+
+ @media (min-width: 768px) {
+ margin-bottom: 40px;
+ }
+}
+
+.logo {
+ width: 198px;
+ height: 66px;
+
+ @media (min-width: 768px) {
+ width: 396px;
+ height: 132px;
+ }
+}
+
+.formDiv {
+ display: block;
+ position: relative;
+ margin-bottom: 16px;
+
+ @media (min-width: 768px) {
+ margin-bottom: 24px;
+ }
+}
+
+.formLabel {
+ font-weight: 700;
+ font-size: 14px;
+ line-height: 17px;
+ color: #1f2937;
+
+ @media (min-width: 768px) {
+ font-size: 18px;
+ line-height: 21px;
+ }
+}
+
+.formInput {
+ background-color: #f3f4f6;
+ width: 100%;
+ margin-top: 8px;
+ padding: 16px 24px;
+ border: none;
+ border-radius: 12px;
+ font-weight: 400;
+ font-size: 16px;
+ line-height: 26px;
+
+ @media (min-width: 768px) {
+ margin-top: 16px;
+ }
+}
+
+.toggleTag {
+ position: absolute;
+ top: 43px;
+ right: 24px;
+
+ @media (min-width: 768px) {
+ top: 53px;
+ }
+}
+
+.toggleImg {
+ cursor: pointer;
+ width: 24px;
+ height: 24px;
+}
+
+.button {
+ display: flex;
+ justify-content: center;
+ cursor: pointer;
+ background-color: #9ca3af;
+ width: 100%;
+ padding: 16px 124px;
+ border: none;
+ border-radius: 40px;
+ font-weight: 600;
+ font-size: 20px;
+ line-height: 32px;
+ color: #f3f4f6;
+ margin-bottom: 24px;
+}
+
+.disabled {
+ background-color: #3692ff;
+}
+
+.loginBox {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ background-color: #e6f2ff;
+ border: none;
+ border-radius: 8px;
+ padding: 16px 24px;
+ margin-bottom: 25px;
+}
+
+.loginImgBox {
+ display: flex;
+ gap: 16px;
+}
+
+.loginLink {
+ font-weight: 500;
+ font-size: 14px;
+ line-height: 24px;
+ text-align: center;
+}
+
+.errorMessage {
+ margin-top: 8px;
+ padding-left: 16px;
+ font-weight: 600;
+ font-size: 14px;
+ line-height: 24px;
+ color: #f74747;
+}
+
+.errorInput {
+ border: 1px solid #f74747;
+}
diff --git a/pages/Signup.tsx b/pages/Signup.tsx
new file mode 100644
index 000000000..9c0660a96
--- /dev/null
+++ b/pages/Signup.tsx
@@ -0,0 +1,294 @@
+import { ChangeEvent, FormEvent, useEffect, useState } from "react";
+import styles from "./Signup.module.css";
+import Link from "next/link";
+import { postUserData } from "../src/api/api";
+import { useRouter } from "next/router";
+import Image from "next/image";
+
+const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
+const PASSWORD_MIN_LEN = 8;
+
+export default function Signup() {
+ const [email, setEmail] = useState("");
+ const [nickName, setNickName] = useState("");
+ const [password, setPassword] = useState("");
+ const [passwordMatch, setPasswordMatch] = useState("");
+ const [emailError, setEmailError] = useState(null);
+ const [nickNameError, setNickNameError] = useState(null);
+ const [passwordError, setPasswordError] = useState(null);
+ const [passwordMatchError, setPasswordMatchError] = useState(
+ null
+ );
+ const [isButtonDisabled, setIsButtonDisabled] = useState(true);
+ const [isPasswordVisible, setIsPasswordVisible] = useState(false);
+ const router = useRouter();
+
+ // 이메일 값 체크
+ const emailCheck = (email: string): string | null => {
+ if (!email.trim()) return "이메일을 입력해주세요";
+ if (!emailRegex.test(email)) return "잘못된 이메일 형식입니다";
+
+ return null;
+ };
+
+ const onChangeEmail = (e: ChangeEvent) => {
+ const value = e.target.value;
+ setEmail(value);
+ setEmailError(emailCheck(value));
+ };
+
+ // 닉네임 값 체크
+ const nickNameCheck = (nickName: string): string | null => {
+ if (!nickName.trim()) return "닉네임을 입력해주세요";
+
+ return null;
+ };
+
+ const onChangeNickName = (e: ChangeEvent) => {
+ const value = e.target.value;
+ setNickName(value);
+ setNickNameError(nickNameCheck(value));
+ };
+
+ // 비밀번호 값 체크
+ const passwordCheck = (password: string): string | null => {
+ if (!password.trim()) return `패스워드를 입력해주세요`;
+ if (password.length < PASSWORD_MIN_LEN)
+ return `패스워드를 ${PASSWORD_MIN_LEN}자 이상입력해주세요`;
+
+ return null;
+ };
+
+ const onChangePassword = (e: ChangeEvent) => {
+ const nextPassword = e.target.value;
+ setPassword(nextPassword);
+ setPasswordError(passwordCheck(nextPassword));
+ };
+
+ // 비밀번호 확인 값 체크
+ const PasswordMatch = (
+ password: string,
+ passwordMatch: string
+ ): string | null => {
+ if (password !== passwordMatch) return "비밀번호가 일치하지 않습니다.";
+
+ return null;
+ };
+
+ const onChangePasswordMatch = (e: ChangeEvent) => {
+ const nextPasswordMatch = e.target.value;
+ setPasswordMatch(nextPasswordMatch);
+ setPasswordMatchError(PasswordMatch(password, nextPasswordMatch));
+ };
+
+ // 회원가입 버튼 활성화 여부 판단
+ useEffect(() => {
+ const isNoError =
+ !emailError && !nickNameError && !passwordError && !passwordMatchError;
+ const hasAllInput = email && nickName && password && passwordMatch;
+
+ const isValidForm = isNoError && hasAllInput;
+
+ setIsButtonDisabled(!isValidForm);
+ }, [
+ email,
+ nickName,
+ password,
+ passwordMatch,
+ emailError,
+ nickNameError,
+ passwordError,
+ passwordMatchError,
+ ]);
+
+ // 비밀번호 타입 토글
+ const togglePasswordVisibility = () => {
+ setIsPasswordVisible((prevState) => !prevState);
+ };
+
+ const handleSignUp = async (e: FormEvent) => {
+ e.preventDefault();
+
+ const userData = {
+ email: email,
+ nickname: nickName,
+ password: password,
+ passwordConfirmation: passwordMatch,
+ };
+
+ try {
+ const result = await postUserData(userData);
+
+ if (result.success) {
+ console.log(result);
+ router.push("/");
+ } else {
+ alert(result.message || "회원가입에 실패했습니다.");
+ }
+ } catch (error) {
+ console.error("회원가입 오류:", error);
+ alert("회원가입 중 오류가 발생했습니다. 다시 시도해 주세요.");
+ }
+ };
+
+ return (
+
+
+
+
+
+ 이미 회원이신가요?
+
+ 로그인
+
+
+
+ );
+}
diff --git a/pages/_app.js b/pages/_app.js
new file mode 100644
index 000000000..3844f9651
--- /dev/null
+++ b/pages/_app.js
@@ -0,0 +1,5 @@
+import "../styles/globals.css";
+
+export default function MyApp({ Component, pageProps }) {
+ return ;
+}
diff --git a/pages/_document.js b/pages/_document.js
new file mode 100644
index 000000000..1ced44fc4
--- /dev/null
+++ b/pages/_document.js
@@ -0,0 +1,13 @@
+import { Html, Head, Main, NextScript } from "next/document";
+
+export default function MyDocument() {
+ return (
+
+
+
+
+
+
+
+ );
+}
diff --git a/pages/index.js b/pages/index.js
new file mode 100644
index 000000000..a77df5c61
--- /dev/null
+++ b/pages/index.js
@@ -0,0 +1,5 @@
+import Home from "./Home";
+
+export default function Index() {
+ return ;
+}
diff --git a/public/fonts/PretendardVariable.woff2 b/public/fonts/PretendardVariable.woff2
new file mode 100644
index 000000000..49c54b515
Binary files /dev/null and b/public/fonts/PretendardVariable.woff2 differ
diff --git a/public/image/HomePageLogoImg.png b/public/image/HomePageLogoImg.png
new file mode 100644
index 000000000..9d5f8ef38
Binary files /dev/null and b/public/image/HomePageLogoImg.png differ
diff --git a/public/image/Img_home_01.png b/public/image/Img_home_01.png
new file mode 100644
index 000000000..249652e34
Binary files /dev/null and b/public/image/Img_home_01.png differ
diff --git a/public/image/Img_home_02.png b/public/image/Img_home_02.png
new file mode 100644
index 000000000..84d8629f1
Binary files /dev/null and b/public/image/Img_home_02.png differ
diff --git a/public/image/Img_home_03.png b/public/image/Img_home_03.png
new file mode 100644
index 000000000..eb0d6cd26
Binary files /dev/null and b/public/image/Img_home_03.png differ
diff --git a/public/image/NavLogo.svg b/public/image/NavLogo.svg
new file mode 100644
index 000000000..bdc9b3ae1
--- /dev/null
+++ b/public/image/NavLogo.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/image/NavLogoMobile.svg b/public/image/NavLogoMobile.svg
new file mode 100644
index 000000000..1866199e1
--- /dev/null
+++ b/public/image/NavLogoMobile.svg
@@ -0,0 +1,3 @@
+
diff --git a/public/image/NavUser.svg b/public/image/NavUser.svg
new file mode 100644
index 000000000..81a20bb97
--- /dev/null
+++ b/public/image/NavUser.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/image/Property 1=md.png b/public/image/Property 1=md.png
new file mode 100644
index 000000000..9ad262959
Binary files /dev/null and b/public/image/Property 1=md.png differ
diff --git a/public/image/SearchIcon.svg b/public/image/SearchIcon.svg
new file mode 100644
index 000000000..38064afc6
--- /dev/null
+++ b/public/image/SearchIcon.svg
@@ -0,0 +1,3 @@
+
diff --git a/public/image/bottomImg.png b/public/image/bottomImg.png
new file mode 100644
index 000000000..58b29043e
Binary files /dev/null and b/public/image/bottomImg.png differ
diff --git a/public/image/btn_visibility_off.png b/public/image/btn_visibility_off.png
new file mode 100644
index 000000000..5dc09fbe1
Binary files /dev/null and b/public/image/btn_visibility_off.png differ
diff --git a/public/image/btn_visibility_off.svg b/public/image/btn_visibility_off.svg
new file mode 100644
index 000000000..92fda8aa0
--- /dev/null
+++ b/public/image/btn_visibility_off.svg
@@ -0,0 +1,3 @@
+
diff --git a/public/image/btn_visibility_on.png b/public/image/btn_visibility_on.png
new file mode 100644
index 000000000..32765f0b2
Binary files /dev/null and b/public/image/btn_visibility_on.png differ
diff --git a/public/image/btn_visibility_on.svg b/public/image/btn_visibility_on.svg
new file mode 100644
index 000000000..2d656582a
--- /dev/null
+++ b/public/image/btn_visibility_on.svg
@@ -0,0 +1,3 @@
+
diff --git a/public/image/facebookIcon.svg b/public/image/facebookIcon.svg
new file mode 100644
index 000000000..06460299b
--- /dev/null
+++ b/public/image/facebookIcon.svg
@@ -0,0 +1,3 @@
+
diff --git a/public/image/favorite.svg b/public/image/favorite.svg
new file mode 100644
index 000000000..cad016c13
--- /dev/null
+++ b/public/image/favorite.svg
@@ -0,0 +1,3 @@
+
diff --git a/public/image/googleLogin.png b/public/image/googleLogin.png
new file mode 100644
index 000000000..f75dc7616
Binary files /dev/null and b/public/image/googleLogin.png differ
diff --git a/public/image/heroImage.png b/public/image/heroImage.png
new file mode 100644
index 000000000..7ce56caaa
Binary files /dev/null and b/public/image/heroImage.png differ
diff --git a/src/assets/img_up.png b/public/image/img_upload.png
similarity index 100%
rename from src/assets/img_up.png
rename to public/image/img_upload.png
diff --git a/public/image/instarIcon.svg b/public/image/instarIcon.svg
new file mode 100644
index 000000000..1198c4741
--- /dev/null
+++ b/public/image/instarIcon.svg
@@ -0,0 +1,3 @@
+
diff --git a/public/image/kakaoLogin.png b/public/image/kakaoLogin.png
new file mode 100644
index 000000000..bd7678005
Binary files /dev/null and b/public/image/kakaoLogin.png differ
diff --git a/public/image/loginLogo.png b/public/image/loginLogo.png
new file mode 100644
index 000000000..af01f7150
Binary files /dev/null and b/public/image/loginLogo.png differ
diff --git a/public/image/no-image.png b/public/image/no-image.png
new file mode 100644
index 000000000..0812274a2
Binary files /dev/null and b/public/image/no-image.png differ
diff --git a/public/image/twitterIcon.svg b/public/image/twitterIcon.svg
new file mode 100644
index 000000000..ad45285ac
--- /dev/null
+++ b/public/image/twitterIcon.svg
@@ -0,0 +1,3 @@
+
diff --git a/public/image/youtubeIcon.svg b/public/image/youtubeIcon.svg
new file mode 100644
index 000000000..beffba93f
--- /dev/null
+++ b/public/image/youtubeIcon.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/App.css b/src/App.css
deleted file mode 100644
index e69de29bb..000000000
diff --git a/src/App.js b/src/App.js
deleted file mode 100644
index 97d30f925..000000000
--- a/src/App.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import './App.css';
-import { Routes, Route } from 'react-router-dom';
-import Home from './pages/Home.jsx';
-import Additem from './pages/Additem.jsx';
-import Notfound from './pages/Notfound.jsx';
-
-function App() {
- return (
- <>
-
- {/* } /> */}
- } />
- } />
- } />
-
- >
- );
-}
-
-export default App;
diff --git a/src/api/api.js b/src/api/api.js
new file mode 100644
index 000000000..c2d72bba6
--- /dev/null
+++ b/src/api/api.js
@@ -0,0 +1,70 @@
+import axios from "axios";
+
+const BASE_URL = "https://panda-market-api.vercel.app";
+
+export const getProductData = async (params = {}) => {
+ const query = new URLSearchParams(params).toString();
+ try {
+ const response = await axios.get(`${BASE_URL}/products?${query}`);
+ return response.data;
+ } catch (error) {
+ console.error("Error fetching data:", error.message);
+ return error.message;
+ }
+};
+
+export const postUserData = async ({
+ email,
+ nickname,
+ password,
+ passwordConfirmation,
+}) => {
+ try {
+ const response = await axios.post(`${BASE_URL}/auth/signUp`, {
+ email,
+ nickname,
+ password,
+ passwordConfirmation,
+ });
+
+ if (response.status === 201) {
+ // 성공적인 회원가입
+ return { success: true, message: "회원가입이 완료되었습니다." };
+ } else {
+ // 실패 처리
+ return {
+ success: false,
+ message: response.data.message || "회원가입에 실패했습니다.",
+ };
+ }
+ } catch (error) {
+ console.error("Error fetching data:", error.message);
+ return {
+ success: false,
+ message: error.message || "서버 오류가 발생했습니다.",
+ };
+ }
+};
+
+export const postUserLoginData = async ({ email, password }) => {
+ try {
+ const response = await axios.post(`${BASE_URL}/auth/signIn`, {
+ email,
+ password,
+ });
+ if (response.status === 200) {
+ return { success: true, message: "로그인이 완료되었습니다." };
+ } else {
+ return {
+ success: false,
+ message: response.data.message || "로그인에 실패했습니다.",
+ };
+ }
+ } catch (error) {
+ console.error("Error fetching data:", error.message);
+ return {
+ success: false,
+ message: error.message || "서버 오류가 발생했습니다.",
+ };
+ }
+};
diff --git a/src/assets/NavLogoMobile.png b/src/assets/NavLogoMobile.png
new file mode 100644
index 000000000..33ebb81e2
Binary files /dev/null and b/src/assets/NavLogoMobile.png differ
diff --git a/src/assets/heart_favorit.png b/src/assets/heart_favorit.png
deleted file mode 100644
index 0d2e8e4c2..000000000
Binary files a/src/assets/heart_favorit.png and /dev/null differ
diff --git a/src/assets/ic_sort.svg b/src/assets/ic_sort.svg
new file mode 100644
index 000000000..657b44f93
--- /dev/null
+++ b/src/assets/ic_sort.svg
@@ -0,0 +1,6 @@
+
diff --git a/src/assets/nav_panda_logo_img.png b/src/assets/nav_panda_logo_img.png
deleted file mode 100644
index 1fa247eda..000000000
Binary files a/src/assets/nav_panda_logo_img.png and /dev/null differ
diff --git a/src/assets/nav_user_img.png b/src/assets/nav_user_img.png
deleted file mode 100644
index 3e28565b1..000000000
Binary files a/src/assets/nav_user_img.png and /dev/null differ
diff --git a/src/components/BestItem.css b/src/components/BestItem.css
deleted file mode 100644
index 1a5b264d9..000000000
--- a/src/components/BestItem.css
+++ /dev/null
@@ -1,70 +0,0 @@
-.Bestitem {
- display: grid;
- grid-template-rows: 1fr;
- grid-template-columns: repeat(4, 1fr);
- gap: 24px;
- margin-top: 16px;
-
- @media (max-width: 1199px) {
- grid-template-columns: repeat(2, 1fr);
- .BestiemContainer:nth-child(n + 3) {
- display: none;
- }
- padding-left: 24px;
- padding-right: 24px;
- }
-
- @media (max-width: 767px) {
- grid-template-columns: repeat(1, 1fr);
- .BestiemContainer:nth-child(n + 2) {
- display: none;
- }
- padding-left: 16px;
- padding-right: 16px;
- }
-}
-
-.Bestitem > div {
- display: flex;
- flex-direction: column;
-}
-
-.BestiemContainer .itemImg {
- cursor: pointer;
-}
-
-.Bestitem .itemImg img {
- width: 100%;
- height: auto;
- border-radius: 16px;
- margin-bottom: 10px;
- object-fit: cover;
- aspect-ratio: 1;
- /* overflow: hidden; */
-}
-
-.itemName {
- font-size: 14px;
- font-weight: 500;
- line-height: 24px;
- cursor: pointer;
-}
-
-.itemPrice {
- font-size: 16px;
- font-weight: 700;
- line-height: 26px;
-}
-
-.Bestitem .itemFavorit {
- display: flex;
- align-items: center;
- gap: 4px;
- font-size: 12px;
- font-weight: 500;
- line-height: 18px;
-}
-
-.Bestitem .BestiemContainer div {
- margin-bottom: 6px;
-}
diff --git a/src/components/BestItem.module.css b/src/components/BestItem.module.css
new file mode 100644
index 000000000..49edc0cc4
--- /dev/null
+++ b/src/components/BestItem.module.css
@@ -0,0 +1,38 @@
+.bestItemsBox {
+ display: grid;
+ /* grid-template-rows: 1fr; */
+ grid-template-columns: repeat(4, 1fr);
+
+ gap: 24px;
+ margin-top: 16px;
+
+ @media (max-width: 1920px) {
+ .item:nth-child(n + 5) {
+ display: none;
+ }
+ }
+ @media (max-width: 1199px) {
+ grid-template-columns: repeat(2, 1fr);
+ .item:nth-child(n + 3) {
+ display: none;
+ }
+ }
+ @media (max-width: 767px) {
+ grid-template-columns: repeat(1, 1fr);
+ .item:nth-child(n + 2) {
+ display: none;
+ }
+ }
+}
+
+.bestItemsBox > img {
+ width: 100%;
+}
+
+.bestItemsContainer {
+ cursor: pointer;
+}
+
+.bestItemsContainer:nth-child(n + 5) {
+ display: none;
+}
diff --git a/src/components/Bestitem.jsx b/src/components/Bestitem.jsx
deleted file mode 100644
index 9f4de7803..000000000
--- a/src/components/Bestitem.jsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import favorit_img from '../assets/heart_favorit.png';
-import './BestItem.css';
-
-const Bestitem = ({ items }) => {
- const limiteData = items.slice(0, 4);
-
- return (
-
- {limiteData.map((item) => {
- return (
-
-
{

}
-
{item.name}
-
{item.price.toLocaleString()}원
-
-

- {item.favoriteCount}
-
-
- );
- })}
-
- );
-};
-
-export default Bestitem;
diff --git a/src/components/Bestitem.tsx b/src/components/Bestitem.tsx
new file mode 100644
index 000000000..98e0215ee
--- /dev/null
+++ b/src/components/Bestitem.tsx
@@ -0,0 +1,47 @@
+import ItemCard from "./ItemCard";
+import { useEffect, useState } from "react";
+import { getProductData } from "../api/api";
+import styles from "./BestItem.module.css";
+
+interface Item {
+ id: number;
+ name: string;
+ price: number;
+ images: string[];
+ favoriteCount?: number;
+}
+
+interface ProductResponse {
+ list: Item[];
+}
+
+export default function Bestitem() {
+ const [itemList, setItemList] = useState- ([]);
+
+ useEffect(() => {
+ const fetchProduct = async () => {
+ try {
+ const products: ProductResponse = await getProductData({
+ orderBy: "favorite",
+ });
+ setItemList(products.list);
+ } catch (error) {
+ console.error("Error fetching products:", error);
+ }
+ };
+
+ fetchProduct();
+ }, []);
+
+ return (
+
+ {itemList?.map((item) => (
+
+ ))}
+
+ );
+}
diff --git a/src/components/Button.jsx b/src/components/Button.jsx
deleted file mode 100644
index f3f8287e1..000000000
--- a/src/components/Button.jsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import './Button.css';
-
-const Button = ({ text, type }) => {
- return (
-
- );
-};
-
-export default Button;
diff --git a/src/components/Button.css b/src/components/Button.module.css
similarity index 51%
rename from src/components/Button.css
rename to src/components/Button.module.css
index baf648946..d014fd97d 100644
--- a/src/components/Button.css
+++ b/src/components/Button.module.css
@@ -1,4 +1,4 @@
-.Button {
+.button {
display: flex;
align-items: center;
justify-content: center;
@@ -7,34 +7,51 @@
background-color: #ffffff;
font-size: 18px;
line-height: 26px;
- font-weight: 700px;
+ font-weight: 700;
cursor: pointer;
}
-/* Nav 컴포넌트에서 사용할 버튼 */
-.Button_nav_activate {
- color: #3692ff;
-}
-
-/*type ItemAdd = 상품 등록하기에 쓸 버튼*/
-.Button_ItemAdd {
+/* 홈페이지 로그인에 사용할 버튼 */
+.button_Home {
+ width: 128px;
+ height: 48px;
background-color: #3692ff;
- color: #ffffff;
border-radius: 8px;
+ color: #fef4f6;
font-size: 16px;
font-weight: 600;
- line-height: 26px;
- padding: 8px 26px;
+}
+
+/* 홈페이지 구경하러가기에 사용할 버튼 */
+.button_itemsMove {
+ width: 357px;
+ height: 56px;
+ background-color: #3692ff;
+ border-radius: 40px;
+ margin-bottom: 60px;
+ color: #fef4f6;
+
+ @media (max-width: 1199px) {
+ margin-bottom: 0;
+ }
+ @media (max-width: 767px) {
+ width: 240px;
+ height: 48px;
+ }
+}
+
+/* Nav 컴포넌트에서 사용할 버튼 */
+.button_nav_activate {
+ color: #3692ff;
}
/* Additem페이지에서 사용할 등록 버튼 */
-.Button_register {
+.button_register {
background-color: #9ca3af;
color: #f3f4f6;
height: 42px;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
- line-height: 26px;
padding: 12px 23px;
}
diff --git a/src/components/Button.tsx b/src/components/Button.tsx
new file mode 100644
index 000000000..7c1c73807
--- /dev/null
+++ b/src/components/Button.tsx
@@ -0,0 +1,21 @@
+import styles from "./Button.module.css";
+
+interface Props {
+ className?: string;
+ text: string;
+ useType: string;
+}
+
+const Button = ({ className, text, useType }: Props) => {
+ return (
+
+ );
+};
+
+export default Button;
diff --git a/src/components/Editinput.jsx b/src/components/Editinput.jsx
deleted file mode 100644
index a5a5424af..000000000
--- a/src/components/Editinput.jsx
+++ /dev/null
@@ -1,62 +0,0 @@
-import './Editinput.css';
-import img_up from '../assets/img_up.png';
-import { useRef, useState } from 'react';
-
-const Editinput = ({ type, info, placeholder }) => {
- const [imgFile, setImgFile] = useState('');
- const imgRef = useRef();
-
- const saveImgFile = () => {
- if (!imgRef.current || !imgRef.current.files[0]) {
- console.error('파일이 선택되지 않았습니다.');
- return;
- }
-
- const file = imgRef.current.files[0];
- const reader = new FileReader();
-
- reader.readAsDataURL(file);
-
- reader.onloadend = () => {
- if (reader.result) {
- setImgFile(reader.result); // reader.result는 base64 데이터 URL
- }
- };
-
- reader.onerror = () => {
- console.error('파일을 읽는 도중 에러가 발생했습니다.');
- };
- };
-
- if (type === 'img') {
- return (
-
-
-
-
-
-
-

-
-
- );
- } else {
- return (
-
- );
- }
-};
-
-export default Editinput;
diff --git a/src/components/Editinput.css b/src/components/Editinput.module.css
similarity index 78%
rename from src/components/Editinput.css
rename to src/components/Editinput.module.css
index 4670cf008..aa3797a38 100644
--- a/src/components/Editinput.css
+++ b/src/components/Editinput.module.css
@@ -1,4 +1,4 @@
-.Editinput {
+.editinput {
max-width: 1200px;
width: 100%;
background-color: #f3f4f6;
@@ -8,13 +8,13 @@
resize: none;
}
-.Editinput_name,
-.Editinput_price,
-.Editinput_tag {
+.editinput_name,
+.editinput_price,
+.editinput_tag {
height: 56px;
}
-.Editinput_info {
+.editinput_info {
height: 282px;
}
@@ -27,6 +27,11 @@
position: relative;
width: 282px;
height: 282px;
+
+ @media (max-width: 767px) {
+ width: 168px;
+ height: 168px;
+ }
}
.image_preview img {
@@ -48,6 +53,11 @@
height: 282px;
cursor: pointer;
border-radius: 12px;
+
+ @media (max-width: 767px) {
+ width: 168px;
+ height: 168px;
+ }
}
.upload_input {
diff --git a/src/components/Editinput.tsx b/src/components/Editinput.tsx
new file mode 100644
index 000000000..a0d372a07
--- /dev/null
+++ b/src/components/Editinput.tsx
@@ -0,0 +1,78 @@
+import styles from "./Editinput.module.css";
+import { useRef, useState } from "react";
+import Image from "next/image";
+
+interface Props {
+ type: "img" | "text";
+ info?: string;
+ placeholder?: string;
+}
+
+const Editinput = ({ type, info, placeholder }: Props) => {
+ const [imgFile, setImgFile] = useState("");
+ const imgRef = useRef(null);
+
+ const saveImgFile = () => {
+ if (!imgRef.current || !imgRef.current.files[0]) {
+ console.error("파일이 선택되지 않았습니다.");
+ return;
+ }
+
+ const file = imgRef.current.files[0];
+ const reader = new FileReader();
+
+ reader.readAsDataURL(file);
+
+ reader.onloadend = () => {
+ if (reader.result === "string") {
+ setImgFile(reader.result); // reader.result는 base64 데이터 URL
+ }
+ };
+
+ reader.onerror = () => {
+ console.error("파일을 읽는 도중 에러가 발생했습니다.");
+ };
+ };
+
+ if (type === "img") {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+ } else {
+ return (
+
+ );
+ }
+};
+
+export default Editinput;
diff --git a/src/components/Editsection.jsx b/src/components/Editsection.jsx
deleted file mode 100644
index f406689c5..000000000
--- a/src/components/Editsection.jsx
+++ /dev/null
@@ -1,13 +0,0 @@
-import './Editsection.css';
-
-const Editsection = ({ topChlid, center, bottonChild }) => {
- return (
-
-
-
{center}
-
{bottonChild}
-
- );
-};
-
-export default Editsection;
diff --git a/src/components/Editsection.css b/src/components/Editsection.module.css
similarity index 78%
rename from src/components/Editsection.css
rename to src/components/Editsection.module.css
index 70a97dcce..3652c17d9 100644
--- a/src/components/Editsection.css
+++ b/src/components/Editsection.module.css
@@ -1,10 +1,10 @@
-.Editsection {
+.editsection {
display: flex;
flex-direction: column;
margin-bottom: 32px;
}
-.Editsection .edit_text {
+.editsection .edit_text {
margin-bottom: 16px;
font-size: 18px;
font-weight: 700;
diff --git a/src/components/Editsection.tsx b/src/components/Editsection.tsx
new file mode 100644
index 000000000..abdeb6af7
--- /dev/null
+++ b/src/components/Editsection.tsx
@@ -0,0 +1,19 @@
+import styles from "./Editsection.module.css";
+
+interface Props {
+ topChild: string;
+ center: React.ReactNode;
+ bottonChild?: string[];
+}
+
+const Editsection = ({ topChild, center, bottonChild }: Props) => {
+ return (
+
+
+
{center}
+
{bottonChild}
+
+ );
+};
+
+export default Editsection;
diff --git a/src/components/HomePageSection.module.css b/src/components/HomePageSection.module.css
new file mode 100644
index 000000000..73168561f
--- /dev/null
+++ b/src/components/HomePageSection.module.css
@@ -0,0 +1,101 @@
+.section_container {
+ margin-top: 138px;
+ margin-bottom: 138px;
+
+ @media (max-width: 1199px) {
+ margin-top: 0;
+ margin-bottom: 52px;
+ }
+ @media (max-width: 1199px) {
+ margin-bottom: 40px;
+ }
+}
+
+.container {
+ background-color: #fcfcfc;
+ border-radius: 12px;
+}
+
+.forward {
+ display: flex;
+ flex-direction: row;
+ gap: 64px;
+ justify-content: center;
+ align-items: center;
+
+ @media (max-width: 1199px) {
+ flex-direction: column;
+ align-items: normal;
+ gap: 24px;
+ }
+}
+
+.reverse {
+ display: flex;
+ flex-direction: row-reverse;
+ gap: 64px;
+ justify-content: center;
+ align-items: center;
+ text-align: right;
+
+ @media (max-width: 1199px) {
+ flex-direction: column;
+ align-items: normal;
+ gap: 24px;
+ }
+}
+
+.photo {
+ width: 50%;
+
+ @media (max-width: 1199px) {
+ width: 100%;
+ }
+}
+
+.item_info {
+ display: flex;
+ flex-direction: column;
+}
+
+.item_info > span {
+ color: #3692ff;
+ font-weight: 700;
+ line-height: 26px;
+ margin-bottom: 12px;
+
+ @media (max-width: 1199px) {
+ margin-bottom: 16px;
+ }
+ @media (max-width: 767px) {
+ font-size: 16px;
+ margin-bottom: 8px;
+ }
+}
+
+.item_info > h2 {
+ @media (max-width: 1199px) {
+ font-size: 32px;
+ line-height: 42px;
+ }
+ @media (max-width: 767px) {
+ font-size: 24px;
+ line-height: 32px;
+ }
+}
+
+.item_info > div {
+ font-weight: 500px;
+ font-size: 24px;
+ line-height: 32px;
+ margin-top: 24px;
+
+ @media (max-width: 1199px) {
+ font-size: 18px;
+ line-height: 26px;
+ }
+ @media (max-width: 767px) {
+ font-size: 16px;
+ margin-top: 16px;
+ }
+}
diff --git a/src/components/HomePageSection.tsx b/src/components/HomePageSection.tsx
new file mode 100644
index 000000000..d748d3ac1
--- /dev/null
+++ b/src/components/HomePageSection.tsx
@@ -0,0 +1,27 @@
+import styles from "./HomePageSection.module.css";
+
+interface Props {
+ image: string;
+ alt: string;
+ info: string;
+ title: string;
+ text: string;
+ useType: string;
+}
+
+const HomePageSection = ({ image, alt, info, title, text, useType }: Props) => {
+ return (
+
+
+

+
+
{info}
+
{title}
+
{text}
+
+
+
+ );
+};
+
+export default HomePageSection;
diff --git a/src/components/ItemCard.module.css b/src/components/ItemCard.module.css
new file mode 100644
index 000000000..50d894f4a
--- /dev/null
+++ b/src/components/ItemCard.module.css
@@ -0,0 +1,28 @@
+.itemImg {
+ width: 100%;
+ height: auto;
+ border-radius: 16px;
+ margin-bottom: 10px;
+ object-fit: cover;
+ aspect-ratio: 1;
+}
+
+.itemName {
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 24px;
+}
+
+.itemPrice {
+ font-size: 16px;
+ font-weight: 700;
+ line-height: 26px;
+}
+
+.favorite {
+ display: flex;
+ align-items: center;
+ font-weight: 500;
+ font-size: 12px;
+ line-height: 18px;
+}
diff --git a/src/components/ItemCard.tsx b/src/components/ItemCard.tsx
new file mode 100644
index 000000000..7c42d9ad8
--- /dev/null
+++ b/src/components/ItemCard.tsx
@@ -0,0 +1,47 @@
+import React, { useMemo } from "react";
+import styles from "./ItemCard.module.css";
+import Image from "next/image";
+
+const thumbnailUrl = "https://example.com/..." as const;
+
+interface Item {
+ name: string;
+ price: number;
+ images: string[];
+ favoriteCount?: number;
+}
+
+interface Props {
+ className: string;
+ item: Item;
+}
+
+export default function ItemCard({ className, item }: Props) {
+ const imageSource = useMemo(
+ () =>
+ item.images.some((image) => image === thumbnailUrl)
+ ? "/image/no-image.png"
+ : item.images[0] || "/image/no-image.png",
+ [item.images]
+ );
+
+ return (
+
+
+
+
{item.name}
+
{item.price.toLocaleString()}원
+
+
+ {item.favoriteCount || 0}
+
+
+
+ );
+}
diff --git a/src/components/Itemtitle.jsx b/src/components/Itemtitle.jsx
deleted file mode 100644
index fd505d9f5..000000000
--- a/src/components/Itemtitle.jsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import './Itemtitle.css';
-
-const Itemtitle = ({ leftChild, searchInput, searchBtn, rightChild }) => {
- return (
-
-
{leftChild}
-
{searchInput}
-
{searchBtn}
-
{rightChild}
-
- );
-};
-
-export default Itemtitle;
diff --git a/src/components/Itemtitle.css b/src/components/Itemtitle.module.css
similarity index 73%
rename from src/components/Itemtitle.css
rename to src/components/Itemtitle.module.css
index e7299e847..5c7dd99a0 100644
--- a/src/components/Itemtitle.css
+++ b/src/components/Itemtitle.module.css
@@ -1,4 +1,4 @@
-.Itemtitle {
+.itemtitle {
display: flex;
align-items: center;
gap: 12px;
@@ -12,27 +12,27 @@
.search {
height: 92px;
}
- .Item_text:nth-child(1) {
+ .item_text:nth-child(1) {
order: 1;
}
- .Item_input:nth-child(2) {
+ .item_input:nth-child(2) {
order: 3;
}
- .Item_button:nth-child(3) {
+ .item_button:nth-child(3) {
order: 2;
}
- .Item_select:nth-child(4) {
+ .item_select:nth-child(4) {
order: 4;
}
}
-.Itemtitle .Item_text {
+.itemtitle .item_text {
flex: 1;
}
-.Itemtitle .Item_input input {
+.itemtitle .item_input input {
width: 325px;
height: 42px;
padding: 9px 20px;
@@ -45,7 +45,7 @@
line-height: 26px;
}
-.Itemtitle .Item_select select {
+.itemtitle .item_select select {
border: 1px solid #e5e7eb;
border-radius: 12px;
width: 130px;
diff --git a/src/components/Itemtitle.tsx b/src/components/Itemtitle.tsx
new file mode 100644
index 000000000..3469297fe
--- /dev/null
+++ b/src/components/Itemtitle.tsx
@@ -0,0 +1,26 @@
+import styles from "./Itemtitle.module.css";
+
+interface Props {
+ leftChild: React.ReactNode;
+ searchInput?: React.ReactNode;
+ searchBtn?: React.ReactNode;
+ rightChild: React.ReactNode;
+}
+
+const Itemtitle = ({
+ leftChild,
+ searchInput,
+ searchBtn,
+ rightChild,
+}: Props) => {
+ return (
+
+
{leftChild}
+ {searchInput &&
{searchInput}
}
+ {searchBtn &&
{searchBtn}
}
+
{rightChild}
+
+ );
+};
+
+export default Itemtitle;
diff --git a/src/components/Nav.css b/src/components/Nav.css
deleted file mode 100644
index f5b84841e..000000000
--- a/src/components/Nav.css
+++ /dev/null
@@ -1,38 +0,0 @@
-.Nav {
- display: flex;
- align-items: center;
- border-bottom: 1px solid #dfdfdf;
- gap: 47px;
- padding: 10px 200px 9px 200px;
-
- @media (max-width: 1199px) {
- padding-left: 24px;
- padding-right: 24px;
- }
- @media (max-width: 767px) {
- padding-left: 16px;
- padding-right: 16px;
- }
-}
-
-.Nav .nav_button {
- display: flex;
- gap: 30px;
-}
-
-.Nav .nav_logo {
- justify-content: flex-start;
- cursor: pointer;
-}
-
-.Nav .nav_center {
- flex: 1;
- padding: 11px 0 12px;
- white-space: nowrap;
-}
-
-.Nav .nav_user {
- justify-content: flex-end;
- padding: 5px 0 6px;
- cursor: pointer;
-}
diff --git a/src/components/Nav.jsx b/src/components/Nav.jsx
deleted file mode 100644
index 45a1e9e03..000000000
--- a/src/components/Nav.jsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import './Nav.css';
-import Button from './Button';
-import Nav_logo from '../assets/nav_panda_logo_img.png';
-import Nav_user from '../assets/nav_user_img.png';
-import { Link } from 'react-router-dom';
-
-const Nav = () => {
- return (
-
-

-
-
-
-
-
-
-

-
- );
-};
-
-export default Nav;
diff --git a/src/components/Nav.module.css b/src/components/Nav.module.css
new file mode 100644
index 000000000..3571489df
--- /dev/null
+++ b/src/components/Nav.module.css
@@ -0,0 +1,64 @@
+.nav {
+ display: flex;
+ align-items: center;
+ border-bottom: 1px solid #dfdfdf;
+ padding-left: 200px;
+ padding-right: 200px;
+ gap: 32px;
+
+ @media (max-width: 1199px) {
+ padding-left: 24px;
+ padding-right: 24px;
+ gap: 20px;
+ }
+ @media (max-width: 767px) {
+ margin: 0;
+ padding-left: 16px;
+ padding-right: 16px;
+ gap: 8px;
+ }
+}
+
+.logoImage {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ @media (max-width: 767px) {
+ content: url("/image/NavLogoMobile.svg");
+ width: 80px;
+ }
+}
+
+.nav_center {
+ display: flex;
+ flex: 1;
+ align-items: center;
+
+ @media (max-width: 767px) {
+ gap: 8px;
+ }
+}
+
+.nav_button {
+ background-color: #ffffff;
+ border: none;
+ padding: 21px 15px;
+ font-weight: 700;
+ font-size: 18px;
+ line-height: 26px;
+ color: #4b5563;
+
+ @media (max-width: 1199px) {
+ padding: 21px 15px;
+ }
+ @media (max-width: 767px) {
+ padding: 25px 0px;
+ font-size: 16px;
+ }
+}
+
+.nav_user > img {
+ width: 40px;
+ height: 40px;
+}
diff --git a/src/components/Nav.tsx b/src/components/Nav.tsx
new file mode 100644
index 000000000..d54bf9c25
--- /dev/null
+++ b/src/components/Nav.tsx
@@ -0,0 +1,37 @@
+import styles from "./Nav.module.css";
+import Link from "next/link";
+import Image from "next/image";
+
+export default function Nav() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/Totalitem.css b/src/components/Totalitem.css
deleted file mode 100644
index 7540b9d21..000000000
--- a/src/components/Totalitem.css
+++ /dev/null
@@ -1,69 +0,0 @@
-.Totalitems {
- display: grid;
- grid-template-rows: 2fr;
- grid-template-columns: repeat(5, 1fr);
- gap: 24px;
- margin-top: 16px;
-
- @media (max-width: 1199px) {
- grid-template-columns: repeat(3, 1fr);
- .TotaliemContainer:nth-child(n + 7) {
- display: none;
- }
- padding-left: 24px;
- padding-right: 24px;
- }
-
- @media (max-width: 767px) {
- grid-template-columns: repeat(2, 1fr);
- .TotaliemContainer:nth-child(n + 5) {
- display: none;
- }
- padding-left: 16px;
- padding-right: 16px;
- }
-}
-
-.Totalitems > div {
- display: flex;
- flex-direction: column;
-}
-
-.TotaliemContainer .itemImg {
- cursor: pointer;
-}
-
-.Totalitems .itemImg img {
- width: 100%;
- height: auto;
- border-radius: 16px;
- margin-bottom: 10px;
- object-fit: cover;
- aspect-ratio: 1;
-}
-
-.itemName {
- font-size: 14px;
- font-weight: 500;
- line-height: 24px;
- cursor: pointer;
-}
-
-.itemPrice {
- font-size: 16px;
- font-weight: 700;
- line-height: 26px;
-}
-
-.Totalitems .itemTotal {
- display: flex;
- align-items: center;
- gap: 4px;
- font-size: 12px;
- font-weight: 500;
- line-height: 18px;
-}
-
-.Totalitems .TotaliemContainer div {
- margin-bottom: 6px;
-}
diff --git a/src/components/Totalitem.jsx b/src/components/Totalitem.jsx
deleted file mode 100644
index a2ba7ed7c..000000000
--- a/src/components/Totalitem.jsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import './Totalitem.css';
-import favorit_img from '../assets/heart_favorit.png';
-
-const Totalitem = ({ totalitems }) => {
- return (
-
- {totalitems.map((item) => {
- return (
-
-
{

}
-
{item.name}
-
{item.price.toLocaleString()}원
-
-

- {item.favoriteCount}
-
-
- );
- })}
-
- );
-};
-
-export default Totalitem;
diff --git a/src/index.css b/src/index.css
deleted file mode 100644
index 7125638ab..000000000
--- a/src/index.css
+++ /dev/null
@@ -1,15 +0,0 @@
-html {
- font-family: Pretendard, sans-serif;
-}
-
-* {
- box-sizing: border-box;
-}
-
-body {
- margin: 0;
-}
-
-#root {
- max-width: 1920px;
-}
diff --git a/src/index.js b/src/index.js
deleted file mode 100644
index 5c473efdd..000000000
--- a/src/index.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import React from 'react';
-import ReactDOM from 'react-dom/client';
-import './index.css';
-import App from './App';
-import { BrowserRouter } from 'react-router-dom';
-
-const root = ReactDOM.createRoot(document.getElementById('root'));
-root.render(
-
-
-
-);
diff --git a/src/pages/Additem.jsx b/src/pages/Additem.jsx
deleted file mode 100644
index 2b5e7ade7..000000000
--- a/src/pages/Additem.jsx
+++ /dev/null
@@ -1,62 +0,0 @@
-import './Additem.css';
-import Nav from '../components/Nav';
-import Button from '../components/Button';
-import Itemtitle from '../components/Itemtitle';
-import Editsection from '../components/Editsection';
-import Editinput from '../components/Editinput';
-
-const Additem = () => {
- return (
-
-
- {/* 아래는 상품등록 페이지 구현 */}
-
-
- );
-};
-
-export default Additem;
diff --git a/src/pages/Home.css b/src/pages/Home.css
deleted file mode 100644
index 123509e68..000000000
--- a/src/pages/Home.css
+++ /dev/null
@@ -1,47 +0,0 @@
-.item_title {
- margin-top: 24px;
- font-size: 20px;
- font-weight: 700;
- line-height: 32px;
-
- @media (max-width: 1199px) {
- padding: 0 24px;
- }
-
- @media (max-width: 767px) {
- padding: 0 16px;
- }
-}
-
-.Home .item {
- max-width: 1201px;
- width: 100%;
- margin: 0 auto;
-}
-
-a:link {
- text-decoration: none;
-}
-
-.pagenation_box {
- display: flex;
- align-items: center;
- justify-content: center;
- gap: 4px;
- padding: 43px 0 53px;
-}
-
-.page_button {
- width: 40px;
- height: 40px;
- border-radius: 50%;
- border: 1px solid #e5e7eb;
- outline: none;
- color: #6b7280;
- cursor: pointer;
-}
-
-.active {
- background-color: #2f80ed;
- color: #f9fafb;
-}
diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx
deleted file mode 100644
index 1c84827b3..000000000
--- a/src/pages/Home.jsx
+++ /dev/null
@@ -1,78 +0,0 @@
-import './Home.css';
-import Button from '../components/Button';
-import Nav from '../components/Nav';
-import Bestitem from '../components/Bestitem';
-import Totalitem from '../components/Totalitem';
-import items from '../mockdata.json';
-import totalitems from '../totalitems_data.json';
-import Itemtitle from '../components/Itemtitle';
-import { Link } from 'react-router-dom';
-import { useState } from 'react';
-import arrowLeft from '../assets/arrow_left.svg';
-import arrowRight from '../assets/arrow_right.svg';
-
-const Home = () => {
- const [sort, setSort] = useState('new');
-
- const onChangeSort = (e) => {
- setSort(e.target.value);
- };
-
- const getSortData = () => {
- return totalitems.toSorted((a, b) => {
- if (sort === 'new') {
- return Number(b.createdAt) - Number(a.createdAt);
- } else {
- return Number(b.favoriteCount) - Number(a.favoriteCount);
- }
- });
- };
- const sortData = getSortData();
-
- return (
-
-
- {/* 아래는 상품 */}
-
-
-
-
-
-
- }
- searchBtn={
-
-
-
- }
- rightChild={
-
- }
- />
-
-
-
- {/* 페이지네이션 영역 */}
-
-
-
-
-
-
-
-
-
-
- );
-};
-
-export default Home;
diff --git a/src/pages/Notfound.jsx b/src/pages/Notfound.jsx
deleted file mode 100644
index d61307fb8..000000000
--- a/src/pages/Notfound.jsx
+++ /dev/null
@@ -1,5 +0,0 @@
-const Notfound = () => {
- return Notfound
;
-};
-
-export default Notfound;
diff --git a/styles/globals.css b/styles/globals.css
new file mode 100644
index 000000000..bc203d3a5
--- /dev/null
+++ b/styles/globals.css
@@ -0,0 +1,33 @@
+@font-face {
+ font-family: "Pretendard";
+ src: url("/fonts/PretendardVariable.woff2") format("woff2");
+ font-weight: 45 920;
+ font-style: normal;
+ font-display: swap;
+}
+
+* {
+ font-family: "Pretendard", sans-serif;
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+ word-break: keep-all;
+}
+
+body {
+ font-family: "Pretendard", sans-serif;
+ margin: 0;
+}
+
+a:link {
+ text-decoration: none;
+ cursor: pointer;
+}
+
+::placeholder {
+ color: #9ca3af;
+}
+
+#root {
+ max-width: 1920px;
+}
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 000000000..c3208e20a
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,29 @@
+{
+ "compilerOptions": {
+ "target": "ES2017",
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "esnext"
+ ],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": false,
+ "noEmit": true,
+ "incremental": true,
+ "module": "esnext",
+ "esModuleInterop": true,
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve"
+ },
+ "include": [
+ "next-env.d.ts",
+ "**/*.ts",
+ "**/*.tsx"
+ ],
+ "exclude": [
+ "node_modules"
+ ]
+}