From 22a8e6c560fa1ba58d6852d25a22006619d5764d Mon Sep 17 00:00:00 2001 From: hiwon-lee <84234411+hiwon-lee@users.noreply.github.com> Date: Thu, 26 Dec 2024 15:31:26 +0900 Subject: [PATCH 01/30] =?UTF-8?q?=F0=9F=9B=A0=EF=B8=8F=20build:=20=20init?= =?UTF-8?q?=20project?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitattributes | 9 + .gitignore | 41 + README.md | 36 + eslint.config.mjs | 21 + next.config.ts | 7 + package-lock.json | 4920 +++++++++++++++++ package.json | 28 + prettier.config.js | 7 + src/app/favicon.ico | Bin 0 -> 25931 bytes src/app/globals.css | 42 + src/app/layout.tsx | 26 + src/app/page.module.css | 168 + src/app/page.tsx | 7 + src/assets/DownChevronIcon.tsx | 16 + src/assets/EmailIcon.tsx | 16 + src/assets/LeftChevronIcon.tsx | 16 + src/assets/PasswordIcon.tsx | 16 + src/assets/RightChevronIcon.tsx | 16 + src/assets/SearchIcon.tsx | 16 + src/assets/bnb/BNBProfileIcon.tsx | 20 + src/assets/bnb/BNB_CalendarIcon.tsx | 20 + src/assets/bnb/BNB_HomeIcon.tsx | 16 + src/assets/bnb/BNB_MapIcon.tsx | 16 + src/assets/bnb/BNB_PhotographerIcon.tsx | 20 + src/components/BNB/index.tsx | 62 + src/components/BNB/styles.ts | 34 + src/components/Card/card.css | 28 + src/components/Card/index.tsx | 50 + src/components/ScreenWrapper/index.tsx | 17 + src/components/ScreenWrapper/styles.ts | 15 + src/components/TNB/Back.tsx | 36 + src/components/TNB/Main.tsx | 11 + src/components/TNB/SubTitle.tsx | 12 + src/components/TNB/Title.tsx | 12 + src/components/TNB/index.tsx | 13 + src/components/TNB/styles.tsx | 14 + src/components/atoms/CTAButton/index.tsx | 60 + src/components/atoms/MediumButton/index.tsx | 34 + src/components/atoms/SmallButton/Primary.tsx | 33 + .../atoms/SmallButton/Secondary.tsx | 21 + src/components/atoms/SmallButton/Tertiary.tsx | 26 + src/components/atoms/SmallButton/index.tsx | 11 + src/components/atoms/SmallButton/styles.tsx | 13 + src/components/atoms/Tag/index.tsx | 38 + src/components/atoms/Text/index.tsx | 28 + src/lib/registry.tsx | 96 + src/styles/constants.ts | 3 + src/styles/convertSize.ts | 10 + src/styles/theme.ts | 124 + tsconfig.json | 28 + 50 files changed, 6329 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 README.md create mode 100644 eslint.config.mjs create mode 100644 next.config.ts create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 prettier.config.js create mode 100644 src/app/favicon.ico create mode 100644 src/app/globals.css create mode 100644 src/app/layout.tsx create mode 100644 src/app/page.module.css create mode 100644 src/app/page.tsx create mode 100644 src/assets/DownChevronIcon.tsx create mode 100644 src/assets/EmailIcon.tsx create mode 100644 src/assets/LeftChevronIcon.tsx create mode 100644 src/assets/PasswordIcon.tsx create mode 100644 src/assets/RightChevronIcon.tsx create mode 100644 src/assets/SearchIcon.tsx create mode 100644 src/assets/bnb/BNBProfileIcon.tsx create mode 100644 src/assets/bnb/BNB_CalendarIcon.tsx create mode 100644 src/assets/bnb/BNB_HomeIcon.tsx create mode 100644 src/assets/bnb/BNB_MapIcon.tsx create mode 100644 src/assets/bnb/BNB_PhotographerIcon.tsx create mode 100644 src/components/BNB/index.tsx create mode 100644 src/components/BNB/styles.ts create mode 100644 src/components/Card/card.css create mode 100644 src/components/Card/index.tsx create mode 100644 src/components/ScreenWrapper/index.tsx create mode 100644 src/components/ScreenWrapper/styles.ts create mode 100644 src/components/TNB/Back.tsx create mode 100644 src/components/TNB/Main.tsx create mode 100644 src/components/TNB/SubTitle.tsx create mode 100644 src/components/TNB/Title.tsx create mode 100644 src/components/TNB/index.tsx create mode 100644 src/components/TNB/styles.tsx create mode 100644 src/components/atoms/CTAButton/index.tsx create mode 100644 src/components/atoms/MediumButton/index.tsx create mode 100644 src/components/atoms/SmallButton/Primary.tsx create mode 100644 src/components/atoms/SmallButton/Secondary.tsx create mode 100644 src/components/atoms/SmallButton/Tertiary.tsx create mode 100644 src/components/atoms/SmallButton/index.tsx create mode 100644 src/components/atoms/SmallButton/styles.tsx create mode 100644 src/components/atoms/Tag/index.tsx create mode 100644 src/components/atoms/Text/index.tsx create mode 100644 src/lib/registry.tsx create mode 100644 src/styles/constants.ts create mode 100644 src/styles/convertSize.ts create mode 100644 src/styles/theme.ts create mode 100644 tsconfig.json diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9f2d411 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,9 @@ +text eol=lf +*.js eol=lf +*.jsx eol=lf +*.ts eol=lf +*.tsx eol=lf +*.json eol=lf +*.html eol=lf +*.css eol=lf +*.scss eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ef6a52 --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files (can opt-in for committing if needed) +.env* + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/README.md b/README.md new file mode 100644 index 0000000..e215bc4 --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). + +## Getting Started + +First, run the development server: + +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +# or +bun dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. + +This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..05f41a0 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,21 @@ +import { dirname } from "path"; +import { fileURLToPath } from "url"; +import { FlatCompat } from "@eslint/eslintrc"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +const compat = new FlatCompat({ + baseDirectory: __dirname, +}); + +const eslintConfig = [ + ...compat.extends("next/core-web-vitals", "next/typescript"), + { + rules: { + ...prettier.rules, // Prettier 규칙 추가 + }, + }, +]; + +export default eslintConfig; diff --git a/next.config.ts b/next.config.ts new file mode 100644 index 0000000..e9ffa30 --- /dev/null +++ b/next.config.ts @@ -0,0 +1,7 @@ +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = { + /* config options here */ +}; + +export default nextConfig; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..1dcbf9d --- /dev/null +++ b/package-lock.json @@ -0,0 +1,4920 @@ +{ + "name": "my-app", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "my-app", + "version": "0.1.0", + "dependencies": { + "next": "15.1.2", + "react": "^19.0.0", + "react-dom": "^19.0.0" + }, + "devDependencies": { + "@eslint/eslintrc": "^3", + "@types/node": "^20", + "@types/react": "^19", + "@types/react-dom": "^19", + "eslint": "^9", + "eslint-config-next": "15.1.2", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.2.1", + "prettier": "^3.4.2", + "typescript": "^5" + } + }, + "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.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.1.tgz", + "integrity": "sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.5", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.9.1.tgz", + "integrity": "sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", + "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "9.17.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.17.0.tgz", + "integrity": "sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.5.tgz", + "integrity": "sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.4.tgz", + "integrity": "sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "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/@next/env": { + "version": "15.1.2", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.1.2.tgz", + "integrity": "sha512-Hm3jIGsoUl6RLB1vzY+dZeqb+/kWPZ+h34yiWxW0dV87l8Im/eMOwpOA+a0L78U0HM04syEjXuRlCozqpwuojQ==", + "license": "MIT" + }, + "node_modules/@next/eslint-plugin-next": { + "version": "15.1.2", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-15.1.2.tgz", + "integrity": "sha512-sgfw3+WdaYOGPKCvM1L+UucBmRfh8V2Ygefp7ELON0+0vY7uohQwXXnVWg3rY7mXDKharQR3o7uedpfvnU2hlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-glob": "3.3.1" + } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "15.1.2", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.1.2.tgz", + "integrity": "sha512-b9TN7q+j5/7+rGLhFAVZiKJGIASuo8tWvInGfAd8wsULjB1uNGRCj1z1WZwwPWzVQbIKWFYqc+9L7W09qwt52w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "15.1.2", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.1.2.tgz", + "integrity": "sha512-caR62jNDUCU+qobStO6YJ05p9E+LR0EoXh1EEmyU69cYydsAy7drMcOlUlRtQihM6K6QfvNwJuLhsHcCzNpqtA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "15.1.2", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.1.2.tgz", + "integrity": "sha512-fHHXBusURjBmN6VBUtu6/5s7cCeEkuGAb/ZZiGHBLVBXMBy4D5QpM8P33Or8JD1nlOjm/ZT9sEE5HouQ0F+hUA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "15.1.2", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.1.2.tgz", + "integrity": "sha512-9CF1Pnivij7+M3G74lxr+e9h6o2YNIe7QtExWq1KUK4hsOLTBv6FJikEwCaC3NeYTflzrm69E5UfwEAbV2U9/g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "15.1.2", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.1.2.tgz", + "integrity": "sha512-tINV7WmcTUf4oM/eN3Yuu/f8jQ5C6AkueZPKeALs/qfdfX57eNv4Ij7rt0SA6iZ8+fMobVfcFVv664Op0caCCg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "15.1.2", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.1.2.tgz", + "integrity": "sha512-jf2IseC4WRsGkzeUw/cK3wci9pxR53GlLAt30+y+B+2qAQxMw6WAC3QrANIKxkcoPU3JFh/10uFfmoMDF9JXKg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "15.1.2", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.1.2.tgz", + "integrity": "sha512-wvg7MlfnaociP7k8lxLX4s2iBJm4BrNiNFhVUY+Yur5yhAJHfkS8qPPeDEUH8rQiY0PX3u/P7Q/wcg6Mv6GSAA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "15.1.2", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.1.2.tgz", + "integrity": "sha512-D3cNA8NoT3aWISWmo7HF5Eyko/0OdOO+VagkoJuiTk7pyX3P/b+n8XA/MYvyR+xSVcbKn68B1rY9fgqjNISqzQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nolyfill/is-core-module": { + "version": "1.0.39", + "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", + "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.4.0" + } + }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.4.tgz", + "integrity": "sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==", + "dev": true, + "license": "MIT" + }, + "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/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.17.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.10.tgz", + "integrity": "sha512-/jrvh5h6NXhEauFFexRin69nA0uHJ5gwk4iDivp/DeoEua3uwCUto6PC86IpRITBOs4+6i2I56K5x5b6WYGXHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/react": { + "version": "19.0.2", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.2.tgz", + "integrity": "sha512-USU8ZI/xyKJwFTpjSVIrSeHBVAGagkHQKPNbxeWwql/vDmnTIBgx+TJnhFnj1NXgz8XfprU0egV2dROLGpsBEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.0.2", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.0.2.tgz", + "integrity": "sha512-c1s+7TKFaDRRxr1TxccIX2u7sfCnc3RxkVyBIUA2lCpyqCF+QoAwQ/CBg7bsMdVwP120HEH143VQezKtef5nCg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.18.2.tgz", + "integrity": "sha512-adig4SzPLjeQ0Tm+jvsozSGiCliI2ajeURDGHjZ2llnA+A67HihCQ+a3amtPhUakd1GlwHxSRvzOZktbEvhPPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.18.2", + "@typescript-eslint/type-utils": "8.18.2", + "@typescript-eslint/utils": "8.18.2", + "@typescript-eslint/visitor-keys": "8.18.2", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.18.2.tgz", + "integrity": "sha512-y7tcq4StgxQD4mDr9+Jb26dZ+HTZ/SkfqpXSiqeUXZHxOUyjWDKsmwKhJ0/tApR08DgOhrFAoAhyB80/p3ViuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.18.2", + "@typescript-eslint/types": "8.18.2", + "@typescript-eslint/typescript-estree": "8.18.2", + "@typescript-eslint/visitor-keys": "8.18.2", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.18.2.tgz", + "integrity": "sha512-YJFSfbd0CJjy14r/EvWapYgV4R5CHzptssoag2M7y3Ra7XNta6GPAJPPP5KGB9j14viYXyrzRO5GkX7CRfo8/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.18.2", + "@typescript-eslint/visitor-keys": "8.18.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.18.2.tgz", + "integrity": "sha512-AB/Wr1Lz31bzHfGm/jgbFR0VB0SML/hd2P1yxzKDM48YmP7vbyJNHRExUE/wZsQj2wUCvbWH8poNHFuxLqCTnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "8.18.2", + "@typescript-eslint/utils": "8.18.2", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.18.2.tgz", + "integrity": "sha512-Z/zblEPp8cIvmEn6+tPDIHUbRu/0z5lqZ+NvolL5SvXWT5rQy7+Nch83M0++XzO0XrWRFWECgOAyE8bsJTl1GQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.18.2.tgz", + "integrity": "sha512-WXAVt595HjpmlfH4crSdM/1bcsqh+1weFRWIa9XMTx/XHZ9TCKMcr725tLYqWOgzKdeDrqVHxFotrvWcEsk2Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.18.2", + "@typescript-eslint/visitor-keys": "8.18.2", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.18.2.tgz", + "integrity": "sha512-Cr4A0H7DtVIPkauj4sTSXVl+VBWewE9/o40KcF3TV9aqDEOWoXF3/+oRXNby3DYzZeCATvbdksYsGZzplwnK/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.18.2", + "@typescript-eslint/types": "8.18.2", + "@typescript-eslint/typescript-estree": "8.18.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.18.2.tgz", + "integrity": "sha512-zORcwn4C3trOWiCqFQP1x6G3xTRyZ1LYydnj51cRnJ6hxBlr/cKPckk+PKPUw/fXmvfKTcw7bwY3w9izgx5jZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.18.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.2.tgz", + "integrity": "sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "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/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", + "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001690", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz", + "integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "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/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": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "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==", + "devOptional": true, + "license": "MIT" + }, + "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/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true, + "license": "MIT" + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "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/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/enhanced-resolve": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.0.tgz", + "integrity": "sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/es-abstract": { + "version": "1.23.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.7.tgz", + "integrity": "sha512-OygGC8kIcDhXX+6yAZRGLqwi2CmEXCbLQixeGUgYeR+Qwlppqmo7DIDr8XibtEBZp+fJcoYpoatp5qwLMEdcqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.2.6", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-regex": "^1.2.1", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.0", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "regexp.prototype.flags": "^1.5.3", + "safe-array-concat": "^1.1.3", + "safe-regex-test": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.18" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", + "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.6", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.4", + "safe-array-concat": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.17.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.17.0.tgz", + "integrity": "sha512-evtlNcpJg+cZLcnVKwsai8fExnqjGPicK7gnUtlNuzu+Fv9bI0aLpND5T44VLQtoMEnI57LoXO9XAkIXwohKrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.0", + "@eslint/core": "^0.9.0", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "9.17.0", + "@eslint/plugin-kit": "^0.2.3", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-next": { + "version": "15.1.2", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-15.1.2.tgz", + "integrity": "sha512-PrMm1/4zWSJ689wd/ypWIR5ZF1uvmp3EkgpgBV1Yu6PhEobBjXMGgT8bVNelwl17LXojO8D5ePFRiI4qXjsPRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@next/eslint-plugin-next": "15.1.2", + "@rushstack/eslint-patch": "^1.10.3", + "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-import-resolver-typescript": "^3.5.2", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-jsx-a11y": "^6.10.0", + "eslint-plugin-react": "^7.37.0", + "eslint-plugin-react-hooks": "^5.0.0" + }, + "peerDependencies": { + "eslint": "^7.23.0 || ^8.0.0 || ^9.0.0", + "typescript": ">=3.3.1" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.7.0.tgz", + "integrity": "sha512-Vrwyi8HHxY97K5ebydMtffsWAn1SCR9eol49eCd5fJS4O1WV7PaAjbcjmbfJJSMz/t4Mal212Uz/fQZrOB8mow==", + "dev": true, + "license": "ISC", + "dependencies": { + "@nolyfill/is-core-module": "1.0.39", + "debug": "^4.3.7", + "enhanced-resolve": "^5.15.0", + "fast-glob": "^3.3.2", + "get-tsconfig": "^4.7.5", + "is-bun-module": "^1.0.2", + "is-glob": "^4.0.3", + "stable-hash": "^0.0.4" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } + } + }, + "node_modules/eslint-import-resolver-typescript/node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/eslint-import-resolver-typescript/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", + "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", + "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.8", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", + "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "aria-query": "^5.3.2", + "array-includes": "^3.1.8", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "hasown": "^2.0.2", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.1" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", + "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.9.1" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": "*", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.3.tgz", + "integrity": "sha512-DomWuTQPFYZwF/7c9W2fkKkStqZmBd3uugfqBYLdkZ3Hii23WzZuOLUskGxB8qkSKqftxEeGL1TB2kMhrce0jA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0.tgz", + "integrity": "sha512-mpJRtPgHN2tNAvZ35AMfqeB3Xqeo273QxrHJsbBEPWODRM4r0yB6jfoROqKEYrOn27UtRPpcpHc2UqyBSuUNTw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-scope": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", + "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", + "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", + "dev": true, + "license": "ISC" + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.6.tgz", + "integrity": "sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "dunder-proto": "^1.0.0", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "function-bind": "^1.1.2", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz", + "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.1.tgz", + "integrity": "sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bun-module": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-1.3.0.tgz", + "integrity": "sha512-DgXeu5UWI0IsMQundYb5UAOzm6G2eVnarJ0byP6Tm55iZNKceD59LNPA2L4VvsScTtHcw0yEkVwSf7PC+QoLSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.6.3" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.0.tgz", + "integrity": "sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/iterator.prototype": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.4.tgz", + "integrity": "sha512-x4WH0BWmrMmg4oHHl+duwubhrvczGlyuGAZu3nvrf0UXOfPu8IhZObFEr7DE/iv01YgVZrsOiRcqw2srkKEDIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "reflect.getprototypeof": "^1.0.8", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "license": "MIT", + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/next": { + "version": "15.1.2", + "resolved": "https://registry.npmjs.org/next/-/next-15.1.2.tgz", + "integrity": "sha512-nLJDV7peNy+0oHlmY2JZjzMfJ8Aj0/dd3jCwSZS8ZiO5nkQfcZRqDrRN3U5rJtqVTQneIOGZzb6LCNrk7trMCQ==", + "license": "MIT", + "dependencies": { + "@next/env": "15.1.2", + "@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.2", + "@next/swc-darwin-x64": "15.1.2", + "@next/swc-linux-arm64-gnu": "15.1.2", + "@next/swc-linux-arm64-musl": "15.1.2", + "@next/swc-linux-x64-gnu": "15.1.2", + "@next/swc-linux-x64-musl": "15.1.2", + "@next/swc-win32-arm64-msvc": "15.1.2", + "@next/swc-win32-x64-msvc": "15.1.2", + "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/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", + "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/react": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz", + "integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz", + "integrity": "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.25.0" + }, + "peerDependencies": { + "react": "^19.0.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.9.tgz", + "integrity": "sha512-r0Ay04Snci87djAsI4U+WNRcSw5S4pOH7qFjd/veA5gC7TbqESR3tcj28ia95L/fYUDw11JKP7uqUKUAfVvV5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "dunder-proto": "^1.0.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", + "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/scheduler": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0.tgz", + "integrity": "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "devOptional": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stable-hash": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.4.tgz", + "integrity": "sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==", + "dev": true, + "license": "MIT" + }, + "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.prototype.includes": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", + "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/synckit": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", + "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", + "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "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/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz", + "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..be45566 --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "name": "my-app", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev --turbopack", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "next": "15.1.2", + "react": "^19.0.0", + "react-dom": "^19.0.0" + }, + "devDependencies": { + "@eslint/eslintrc": "^3", + "@types/node": "^20", + "@types/react": "^19", + "@types/react-dom": "^19", + "eslint": "^9", + "eslint-config-next": "15.1.2", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.2.1", + "prettier": "^3.4.2", + "typescript": "^5" + } +} diff --git a/prettier.config.js b/prettier.config.js new file mode 100644 index 0000000..c941a99 --- /dev/null +++ b/prettier.config.js @@ -0,0 +1,7 @@ +module.exports = { + semi: true, // 세미콜론 추가 여부 + singleQuote: true, // 작은따옴표 사용 여부 + trailingComma: "all", // 객체나 배열 마지막에 콤마 추가 + printWidth: 80, // 한 줄 최대 길이 + tabWidth: 2, // 탭 간격 +}; diff --git a/src/app/favicon.ico b/src/app/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..718d6fea4835ec2d246af9800eddb7ffb276240c GIT binary patch literal 25931 zcmeHv30#a{`}aL_*G&7qml|y<+KVaDM2m#dVr!KsA!#An?kSQM(q<_dDNCpjEux83 zLb9Z^XxbDl(w>%i@8hT6>)&Gu{h#Oeyszu?xtw#Zb1mO{pgX9699l+Qppw7jXaYf~-84xW z)w4x8?=youko|}Vr~(D$UXIbiXABHh`p1?nn8Po~fxRJv}|0e(BPs|G`(TT%kKVJAdg5*Z|x0leQq0 zkdUBvb#>9F()jo|T~kx@OM8$9wzs~t2l;K=woNssA3l6|sx2r3+kdfVW@e^8e*E}v zA1y5{bRi+3Z`uD3{F7LgFJDdvm;nJilkzDku>BwXH(8ItVCXk*-lSJnR?-2UN%hJ){&rlvg`CDTj z)Bzo!3v7Ou#83zEDEFcKt(f1E0~=rqeEbTnMvWR#{+9pg%7G8y>u1OVRUSoox-ovF z2Ydma(;=YuBY(eI|04{hXzZD6_f(v~H;C~y5=DhAC{MMS>2fm~1H_t2$56pc$NH8( z5bH|<)71dV-_oCHIrzrT`2s-5w_+2CM0$95I6X8p^r!gHp+j_gd;9O<1~CEQQGS8) zS9Qh3#p&JM-G8rHekNmKVewU;pJRcTAog68KYo^dRo}(M>36U4Us zfgYWSiHZL3;lpWT=zNAW>Dh#mB!_@Lg%$ms8N-;aPqMn+C2HqZgz&9~Eu z4|Kp<`$q)Uw1R?y(~S>ePdonHxpV1#eSP1B;Ogo+-Pk}6#0GsZZ5!||ev2MGdh}_m z{DeR7?0-1^zVs&`AV6Vt;r3`I`OI_wgs*w=eO%_#7Kepl{B@xiyCANc(l zzIyd4y|c6PXWq9-|KM8(zIk8LPk(>a)zyFWjhT!$HJ$qX1vo@d25W<fvZQ2zUz5WRc(UnFMKHwe1| zWmlB1qdbiA(C0jmnV<}GfbKtmcu^2*P^O?MBLZKt|As~ge8&AAO~2K@zbXelK|4T<{|y4`raF{=72kC2Kn(L4YyenWgrPiv z@^mr$t{#X5VuIMeL!7Ab6_kG$&#&5p*Z{+?5U|TZ`B!7llpVmp@skYz&n^8QfPJzL z0G6K_OJM9x+Wu2gfN45phANGt{7=C>i34CV{Xqlx(fWpeAoj^N0Biu`w+MVcCUyU* zDZuzO0>4Z6fbu^T_arWW5n!E45vX8N=bxTVeFoep_G#VmNlQzAI_KTIc{6>c+04vr zx@W}zE5JNSU>!THJ{J=cqjz+4{L4A{Ob9$ZJ*S1?Ggg3klFp!+Y1@K+pK1DqI|_gq z5ZDXVpge8-cs!o|;K73#YXZ3AShj50wBvuq3NTOZ`M&qtjj#GOFfgExjg8Gn8>Vq5 z`85n+9|!iLCZF5$HJ$Iu($dm?8~-ofu}tEc+-pyke=3!im#6pk_Wo8IA|fJwD&~~F zc16osQ)EBo58U7XDuMexaPRjU@h8tXe%S{fA0NH3vGJFhuyyO!Uyl2^&EOpX{9As0 zWj+P>{@}jxH)8|r;2HdupP!vie{sJ28b&bo!8`D^x}TE$%zXNb^X1p@0PJ86`dZyj z%ce7*{^oo+6%&~I!8hQy-vQ7E)0t0ybH4l%KltWOo~8cO`T=157JqL(oq_rC%ea&4 z2NcTJe-HgFjNg-gZ$6!Y`SMHrlj}Etf7?r!zQTPPSv}{so2e>Fjs1{gzk~LGeesX%r(Lh6rbhSo_n)@@G-FTQy93;l#E)hgP@d_SGvyCp0~o(Y;Ee8{ zdVUDbHm5`2taPUOY^MAGOw*>=s7=Gst=D+p+2yON!0%Hk` zz5mAhyT4lS*T3LS^WSxUy86q&GnoHxzQ6vm8)VS}_zuqG?+3td68_x;etQAdu@sc6 zQJ&5|4(I?~3d-QOAODHpZ=hlSg(lBZ!JZWCtHHSj`0Wh93-Uk)_S%zsJ~aD>{`A0~ z9{AG(e|q3g5B%wYKRxiL2Y$8(4w6bzchKuloQW#e&S3n+P- z8!ds-%f;TJ1>)v)##>gd{PdS2Oc3VaR`fr=`O8QIO(6(N!A?pr5C#6fc~Ge@N%Vvu zaoAX2&(a6eWy_q&UwOhU)|P3J0Qc%OdhzW=F4D|pt0E4osw;%<%Dn58hAWD^XnZD= z>9~H(3bmLtxpF?a7su6J7M*x1By7YSUbxGi)Ot0P77`}P3{)&5Un{KD?`-e?r21!4vTTnN(4Y6Lin?UkSM z`MXCTC1@4A4~mvz%Rh2&EwY))LeoT=*`tMoqcEXI>TZU9WTP#l?uFv+@Dn~b(>xh2 z;>B?;Tz2SR&KVb>vGiBSB`@U7VIWFSo=LDSb9F{GF^DbmWAfpms8Sx9OX4CnBJca3 zlj9(x!dIjN?OG1X4l*imJNvRCk}F%!?SOfiOq5y^mZW)jFL@a|r-@d#f7 z2gmU8L3IZq0ynIws=}~m^#@&C%J6QFo~Mo4V`>v7MI-_!EBMMtb%_M&kvAaN)@ZVw z+`toz&WG#HkWDjnZE!6nk{e-oFdL^$YnbOCN}JC&{$#$O27@|Tn-skXr)2ml2~O!5 zX+gYoxhoc7qoU?C^3~&!U?kRFtnSEecWuH0B0OvLodgUAi}8p1 zrO6RSXHH}DMc$&|?D004DiOVMHV8kXCP@7NKB zgaZq^^O<7PoKEp72kby@W0Z!Y*Ay{&vfg#C&gG@YVR9g?FEocMUi1gSN$+V+ayF45{a zuDZDTN}mS|;BO%gEf}pjBfN2-gIrU#G5~cucA;dokXW89%>AyXJJI z9X4UlIWA|ZYHgbI z5?oFk@A=Ik7lrEQPDH!H+b`7_Y~aDb_qa=B2^Y&Ow41cU=4WDd40dp5(QS-WMN-=Y z9g;6_-JdNU;|6cPwf$ak*aJIcwL@1n$#l~zi{c{EW?T;DaW*E8DYq?Umtz{nJ&w-M zEMyTDrC&9K$d|kZe2#ws6)L=7K+{ zQw{XnV6UC$6-rW0emqm8wJoeZK)wJIcV?dST}Z;G0Arq{dVDu0&4kd%N!3F1*;*pW zR&qUiFzK=@44#QGw7k1`3t_d8&*kBV->O##t|tonFc2YWrL7_eqg+=+k;!F-`^b8> z#KWCE8%u4k@EprxqiV$VmmtiWxDLgnGu$Vs<8rppV5EajBXL4nyyZM$SWVm!wnCj-B!Wjqj5-5dNXukI2$$|Bu3Lrw}z65Lc=1G z^-#WuQOj$hwNGG?*CM_TO8Bg-1+qc>J7k5c51U8g?ZU5n?HYor;~JIjoWH-G>AoUP ztrWWLbRNqIjW#RT*WqZgPJXU7C)VaW5}MiijYbABmzoru6EmQ*N8cVK7a3|aOB#O& zBl8JY2WKfmj;h#Q!pN%9o@VNLv{OUL?rixHwOZuvX7{IJ{(EdPpuVFoQqIOa7giLVkBOKL@^smUA!tZ1CKRK}#SSM)iQHk)*R~?M!qkCruaS!#oIL1c z?J;U~&FfH#*98^G?i}pA{ z9Jg36t4=%6mhY(quYq*vSxptes9qy|7xSlH?G=S@>u>Ebe;|LVhs~@+06N<4CViBk zUiY$thvX;>Tby6z9Y1edAMQaiH zm^r3v#$Q#2T=X>bsY#D%s!bhs^M9PMAcHbCc0FMHV{u-dwlL;a1eJ63v5U*?Q_8JO zT#50!RD619#j_Uf))0ooADz~*9&lN!bBDRUgE>Vud-i5ck%vT=r^yD*^?Mp@Q^v+V zG#-?gKlr}Eeqifb{|So?HM&g91P8|av8hQoCmQXkd?7wIJwb z_^v8bbg`SAn{I*4bH$u(RZ6*xUhuA~hc=8czK8SHEKTzSxgbwi~9(OqJB&gwb^l4+m`k*Q;_?>Y-APi1{k zAHQ)P)G)f|AyjSgcCFps)Fh6Bca*Xznq36!pV6Az&m{O8$wGFD? zY&O*3*J0;_EqM#jh6^gMQKpXV?#1?>$ml1xvh8nSN>-?H=V;nJIwB07YX$e6vLxH( zqYwQ>qxwR(i4f)DLd)-$P>T-no_c!LsN@)8`e;W@)-Hj0>nJ-}Kla4-ZdPJzI&Mce zv)V_j;(3ERN3_@I$N<^|4Lf`B;8n+bX@bHbcZTopEmDI*Jfl)-pFDvo6svPRoo@(x z);_{lY<;);XzT`dBFpRmGrr}z5u1=pC^S-{ce6iXQlLGcItwJ^mZx{m$&DA_oEZ)B{_bYPq-HA zcH8WGoBG(aBU_j)vEy+_71T34@4dmSg!|M8Vf92Zj6WH7Q7t#OHQqWgFE3ARt+%!T z?oLovLVlnf?2c7pTc)~cc^($_8nyKwsN`RA-23ed3sdj(ys%pjjM+9JrctL;dy8a( z@en&CQmnV(()bu|Y%G1-4a(6x{aLytn$T-;(&{QIJB9vMox11U-1HpD@d(QkaJdEb zG{)+6Dos_L+O3NpWo^=gR?evp|CqEG?L&Ut#D*KLaRFOgOEK(Kq1@!EGcTfo+%A&I z=dLbB+d$u{sh?u)xP{PF8L%;YPPW53+@{>5W=Jt#wQpN;0_HYdw1{ksf_XhO4#2F= zyPx6Lx2<92L-;L5PD`zn6zwIH`Jk($?Qw({erA$^bC;q33hv!d!>%wRhj# zal^hk+WGNg;rJtb-EB(?czvOM=H7dl=vblBwAv>}%1@{}mnpUznfq1cE^sgsL0*4I zJ##!*B?=vI_OEVis5o+_IwMIRrpQyT_Sq~ZU%oY7c5JMIADzpD!Upz9h@iWg_>>~j zOLS;wp^i$-E?4<_cp?RiS%Rd?i;f*mOz=~(&3lo<=@(nR!_Rqiprh@weZlL!t#NCc zO!QTcInq|%#>OVgobj{~ixEUec`E25zJ~*DofsQdzIa@5^nOXj2T;8O`l--(QyU^$t?TGY^7#&FQ+2SS3B#qK*k3`ye?8jUYSajE5iBbJls75CCc(m3dk{t?- zopcER9{Z?TC)mk~gpi^kbbu>b-+a{m#8-y2^p$ka4n60w;Sc2}HMf<8JUvhCL0B&Btk)T`ctE$*qNW8L$`7!r^9T+>=<=2qaq-;ll2{`{Rg zc5a0ZUI$oG&j-qVOuKa=*v4aY#IsoM+1|c4Z)<}lEDvy;5huB@1RJPquU2U*U-;gu z=En2m+qjBzR#DEJDO`WU)hdd{Vj%^0V*KoyZ|5lzV87&g_j~NCjwv0uQVqXOb*QrQ zy|Qn`hxx(58c70$E;L(X0uZZ72M1!6oeg)(cdKO ze0gDaTz+ohR-#d)NbAH4x{I(21yjwvBQfmpLu$)|m{XolbgF!pmsqJ#D}(ylp6uC> z{bqtcI#hT#HW=wl7>p!38sKsJ`r8}lt-q%Keqy%u(xk=yiIJiUw6|5IvkS+#?JTBl z8H5(Q?l#wzazujH!8o>1xtn8#_w+397*_cy8!pQGP%K(Ga3pAjsaTbbXJlQF_+m+-UpUUent@xM zg%jqLUExj~o^vQ3Gl*>wh=_gOr2*|U64_iXb+-111aH}$TjeajM+I20xw(((>fej-@CIz4S1pi$(#}P7`4({6QS2CaQS4NPENDp>sAqD z$bH4KGzXGffkJ7R>V>)>tC)uax{UsN*dbeNC*v}#8Y#OWYwL4t$ePR?VTyIs!wea+ z5Urmc)X|^`MG~*dS6pGSbU+gPJoq*^a=_>$n4|P^w$sMBBy@f*Z^Jg6?n5?oId6f{ z$LW4M|4m502z0t7g<#Bx%X;9<=)smFolV&(V^(7Cv2-sxbxopQ!)*#ZRhTBpx1)Fc zNm1T%bONzv6@#|dz(w02AH8OXe>kQ#1FMCzO}2J_mST)+ExmBr9cva-@?;wnmWMOk z{3_~EX_xadgJGv&H@zK_8{(x84`}+c?oSBX*Ge3VdfTt&F}yCpFP?CpW+BE^cWY0^ zb&uBN!Ja3UzYHK-CTyA5=L zEMW{l3Usky#ly=7px648W31UNV@K)&Ub&zP1c7%)`{);I4b0Q<)B}3;NMG2JH=X$U zfIW4)4n9ZM`-yRj67I)YSLDK)qfUJ_ij}a#aZN~9EXrh8eZY2&=uY%2N0UFF7<~%M zsB8=erOWZ>Ct_#^tHZ|*q`H;A)5;ycw*IcmVxi8_0Xk}aJA^ath+E;xg!x+As(M#0=)3!NJR6H&9+zd#iP(m0PIW8$ z1Y^VX`>jm`W!=WpF*{ioM?C9`yOR>@0q=u7o>BP-eSHqCgMDj!2anwH?s%i2p+Q7D zzszIf5XJpE)IG4;d_(La-xenmF(tgAxK`Y4sQ}BSJEPs6N_U2vI{8=0C_F?@7<(G; zo$~G=8p+076G;`}>{MQ>t>7cm=zGtfbdDXm6||jUU|?X?CaE?(<6bKDYKeHlz}DA8 zXT={X=yp_R;HfJ9h%?eWvQ!dRgz&Su*JfNt!Wu>|XfU&68iRikRrHRW|ZxzRR^`eIGt zIeiDgVS>IeExKVRWW8-=A=yA`}`)ZkWBrZD`hpWIxBGkh&f#ijr449~m`j6{4jiJ*C!oVA8ZC?$1RM#K(_b zL9TW)kN*Y4%^-qPpMP7d4)o?Nk#>aoYHT(*g)qmRUb?**F@pnNiy6Fv9rEiUqD(^O zzyS?nBrX63BTRYduaG(0VVG2yJRe%o&rVrLjbxTaAFTd8s;<<@Qs>u(<193R8>}2_ zuwp{7;H2a*X7_jryzriZXMg?bTuegABb^87@SsKkr2)0Gyiax8KQWstw^v#ix45EVrcEhr>!NMhprl$InQMzjSFH54x5k9qHc`@9uKQzvL4ihcq{^B zPrVR=o_ic%Y>6&rMN)hTZsI7I<3&`#(nl+3y3ys9A~&^=4?PL&nd8)`OfG#n zwAMN$1&>K++c{^|7<4P=2y(B{jJsQ0a#U;HTo4ZmWZYvI{+s;Td{Yzem%0*k#)vjpB zia;J&>}ICate44SFYY3vEelqStQWFihx%^vQ@Do(sOy7yR2@WNv7Y9I^yL=nZr3mb zXKV5t@=?-Sk|b{XMhA7ZGB@2hqsx}4xwCW!in#C zI@}scZlr3-NFJ@NFaJlhyfcw{k^vvtGl`N9xSo**rDW4S}i zM9{fMPWo%4wYDG~BZ18BD+}h|GQKc-g^{++3MY>}W_uq7jGHx{mwE9fZiPCoxN$+7 zrODGGJrOkcPQUB(FD5aoS4g~7#6NR^ma7-!>mHuJfY5kTe6PpNNKC9GGRiu^L31uG z$7v`*JknQHsYB!Tm_W{a32TM099djW%5e+j0Ve_ct}IM>XLF1Ap+YvcrLV=|CKo6S zb+9Nl3_YdKP6%Cxy@6TxZ>;4&nTneadr z_ES90ydCev)LV!dN=#(*f}|ZORFdvkYBni^aLbUk>BajeWIOcmHP#8S)*2U~QKI%S zyrLmtPqb&TphJ;>yAxri#;{uyk`JJqODDw%(Z=2`1uc}br^V%>j!gS)D*q*f_-qf8&D;W1dJgQMlaH5er zN2U<%Smb7==vE}dDI8K7cKz!vs^73o9f>2sgiTzWcwY|BMYHH5%Vn7#kiw&eItCqa zIkR2~Q}>X=Ar8W|^Ms41Fm8o6IB2_j60eOeBB1Br!boW7JnoeX6Gs)?7rW0^5psc- zjS16yb>dFn>KPOF;imD}e!enuIniFzv}n$m2#gCCv4jM#ArwlzZ$7@9&XkFxZ4n!V zj3dyiwW4Ki2QG{@i>yuZXQizw_OkZI^-3otXC{!(lUpJF33gI60ak;Uqitp74|B6I zgg{b=Iz}WkhCGj1M=hu4#Aw173YxIVbISaoc z-nLZC*6Tgivd5V`K%GxhBsp@SUU60-rfc$=wb>zdJzXS&-5(NRRodFk;Kxk!S(O(a0e7oY=E( zAyS;Ow?6Q&XA+cnkCb{28_1N8H#?J!*$MmIwLq^*T_9-z^&UE@A(z9oGYtFy6EZef LrJugUA?W`A8`#=m literal 0 HcmV?d00001 diff --git a/src/app/globals.css b/src/app/globals.css new file mode 100644 index 0000000..e3734be --- /dev/null +++ b/src/app/globals.css @@ -0,0 +1,42 @@ +:root { + --background: #ffffff; + --foreground: #171717; +} + +@media (prefers-color-scheme: dark) { + :root { + --background: #0a0a0a; + --foreground: #ededed; + } +} + +html, +body { + max-width: 100vw; + overflow-x: hidden; +} + +body { + color: var(--foreground); + background: var(--background); + font-family: Arial, Helvetica, sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +* { + box-sizing: border-box; + padding: 0; + margin: 0; +} + +a { + color: inherit; + text-decoration: none; +} + +@media (prefers-color-scheme: dark) { + html { + color-scheme: dark; + } +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx new file mode 100644 index 0000000..5f3e71f --- /dev/null +++ b/src/app/layout.tsx @@ -0,0 +1,26 @@ +import React, { ReactNode } from 'react'; +import type { Metadata } from 'next'; +import StyledComponentsRegistry from '@/lib/registry'; +import ScreenWrapper from '@components/ScreenWrapper'; + +// [todo] description 등 meta data 변경 +export const metadata: Metadata = { + title: 'Photo Ground', + description: '행복한 순간을 사진으로', +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: ReactNode; +}>) { + return ( + + + + {children} + + + + ); +} diff --git a/src/app/page.module.css b/src/app/page.module.css new file mode 100644 index 0000000..ee9b8e6 --- /dev/null +++ b/src/app/page.module.css @@ -0,0 +1,168 @@ +.page { + --gray-rgb: 0, 0, 0; + --gray-alpha-200: rgba(var(--gray-rgb), 0.08); + --gray-alpha-100: rgba(var(--gray-rgb), 0.05); + + --button-primary-hover: #383838; + --button-secondary-hover: #f2f2f2; + + display: grid; + grid-template-rows: 20px 1fr 20px; + align-items: center; + justify-items: center; + min-height: 100svh; + padding: 80px; + gap: 64px; + font-family: var(--font-geist-sans); +} + +@media (prefers-color-scheme: dark) { + .page { + --gray-rgb: 255, 255, 255; + --gray-alpha-200: rgba(var(--gray-rgb), 0.145); + --gray-alpha-100: rgba(var(--gray-rgb), 0.06); + + --button-primary-hover: #ccc; + --button-secondary-hover: #1a1a1a; + } +} + +.main { + display: flex; + flex-direction: column; + gap: 32px; + grid-row-start: 2; +} + +.main ol { + font-family: var(--font-geist-mono); + padding-left: 0; + margin: 0; + font-size: 14px; + line-height: 24px; + letter-spacing: -0.01em; + list-style-position: inside; +} + +.main li:not(:last-of-type) { + margin-bottom: 8px; +} + +.main code { + font-family: inherit; + background: var(--gray-alpha-100); + padding: 2px 4px; + border-radius: 4px; + font-weight: 600; +} + +.ctas { + display: flex; + gap: 16px; +} + +.ctas a { + appearance: none; + border-radius: 128px; + height: 48px; + padding: 0 20px; + border: none; + border: 1px solid transparent; + transition: + background 0.2s, + color 0.2s, + border-color 0.2s; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + font-size: 16px; + line-height: 20px; + font-weight: 500; +} + +a.primary { + background: var(--foreground); + color: var(--background); + gap: 8px; +} + +a.secondary { + border-color: var(--gray-alpha-200); + min-width: 180px; +} + +.footer { + grid-row-start: 3; + display: flex; + gap: 24px; +} + +.footer a { + display: flex; + align-items: center; + gap: 8px; +} + +.footer img { + flex-shrink: 0; +} + +/* Enable hover only on non-touch devices */ +@media (hover: hover) and (pointer: fine) { + a.primary:hover { + background: var(--button-primary-hover); + border-color: transparent; + } + + a.secondary:hover { + background: var(--button-secondary-hover); + border-color: transparent; + } + + .footer a:hover { + text-decoration: underline; + text-underline-offset: 4px; + } +} + +@media (max-width: 600px) { + .page { + padding: 32px; + padding-bottom: 80px; + } + + .main { + align-items: center; + } + + .main ol { + text-align: center; + } + + .ctas { + flex-direction: column; + } + + .ctas a { + font-size: 14px; + height: 40px; + padding: 0 16px; + } + + a.secondary { + min-width: auto; + } + + .footer { + flex-wrap: wrap; + align-items: center; + justify-content: center; + } +} + +@media (prefers-color-scheme: dark) { + .logo { + filter: invert(); + } +} diff --git a/src/app/page.tsx b/src/app/page.tsx new file mode 100644 index 0000000..78d9a8d --- /dev/null +++ b/src/app/page.tsx @@ -0,0 +1,7 @@ +'use client'; + +import React from 'react'; + +export default function Home() { + return
; +} diff --git a/src/assets/DownChevronIcon.tsx b/src/assets/DownChevronIcon.tsx new file mode 100644 index 0000000..bba2925 --- /dev/null +++ b/src/assets/DownChevronIcon.tsx @@ -0,0 +1,16 @@ +export default function DownChevronIcon() { + return ( + + + + ); +} diff --git a/src/assets/EmailIcon.tsx b/src/assets/EmailIcon.tsx new file mode 100644 index 0000000..ad0491d --- /dev/null +++ b/src/assets/EmailIcon.tsx @@ -0,0 +1,16 @@ +export default function EmailIcon({ size }: { size: string }) { + return ( + + + + ); +} diff --git a/src/assets/LeftChevronIcon.tsx b/src/assets/LeftChevronIcon.tsx new file mode 100644 index 0000000..f3eed4e --- /dev/null +++ b/src/assets/LeftChevronIcon.tsx @@ -0,0 +1,16 @@ +export default function LeftChevronIcon() { + return ( + + + + ); +} diff --git a/src/assets/PasswordIcon.tsx b/src/assets/PasswordIcon.tsx new file mode 100644 index 0000000..535e296 --- /dev/null +++ b/src/assets/PasswordIcon.tsx @@ -0,0 +1,16 @@ +export default function PasswordIcon({ size }: { size: string }) { + return ( + + + + ); +} diff --git a/src/assets/RightChevronIcon.tsx b/src/assets/RightChevronIcon.tsx new file mode 100644 index 0000000..282f546 --- /dev/null +++ b/src/assets/RightChevronIcon.tsx @@ -0,0 +1,16 @@ +export default function RightChevronIcon() { + return ( + + + + ); +} diff --git a/src/assets/SearchIcon.tsx b/src/assets/SearchIcon.tsx new file mode 100644 index 0000000..9c0198e --- /dev/null +++ b/src/assets/SearchIcon.tsx @@ -0,0 +1,16 @@ +export default function SearchIcon() { + return ( + + + + ); +} diff --git a/src/assets/bnb/BNBProfileIcon.tsx b/src/assets/bnb/BNBProfileIcon.tsx new file mode 100644 index 0000000..3009eb8 --- /dev/null +++ b/src/assets/bnb/BNBProfileIcon.tsx @@ -0,0 +1,20 @@ +export default function BNBProfileIcon({ + color = '#8C8C8C', +}: { + color: string; +}) { + return ( + + + + ); +} diff --git a/src/assets/bnb/BNB_CalendarIcon.tsx b/src/assets/bnb/BNB_CalendarIcon.tsx new file mode 100644 index 0000000..043879e --- /dev/null +++ b/src/assets/bnb/BNB_CalendarIcon.tsx @@ -0,0 +1,20 @@ +export default function BNBCalendarIcon({ + color = '#8C8C8C', +}: { + color: string; +}) { + return ( + + + + ); +} diff --git a/src/assets/bnb/BNB_HomeIcon.tsx b/src/assets/bnb/BNB_HomeIcon.tsx new file mode 100644 index 0000000..8fb8556 --- /dev/null +++ b/src/assets/bnb/BNB_HomeIcon.tsx @@ -0,0 +1,16 @@ +export default function BNBHomeIcon({ color = '#8C8C8C' }: { color: string }) { + return ( + + + + ); +} diff --git a/src/assets/bnb/BNB_MapIcon.tsx b/src/assets/bnb/BNB_MapIcon.tsx new file mode 100644 index 0000000..419cd86 --- /dev/null +++ b/src/assets/bnb/BNB_MapIcon.tsx @@ -0,0 +1,16 @@ +export default function BNBMapIcon({ color = '#8C8C8C' }: { color: string }) { + return ( + + + + ); +} diff --git a/src/assets/bnb/BNB_PhotographerIcon.tsx b/src/assets/bnb/BNB_PhotographerIcon.tsx new file mode 100644 index 0000000..7d64a8e --- /dev/null +++ b/src/assets/bnb/BNB_PhotographerIcon.tsx @@ -0,0 +1,20 @@ +export default function BNBPhotographerIcon({ + color = '#8C8C8C', +}: { + color: string; +}) { + return ( + + + + ); +} diff --git a/src/components/BNB/index.tsx b/src/components/BNB/index.tsx new file mode 100644 index 0000000..f896c01 --- /dev/null +++ b/src/components/BNB/index.tsx @@ -0,0 +1,62 @@ +'use client'; + +import { usePathname } from 'next/navigation'; + +import theme from '@/styles/theme'; +import BNBPhotographerIcon from '@/assets/bnb/BNB_PhotographerIcon'; +import BNBMapIcon from '@/assets/bnb/BNB_MapIcon'; +import BNBHomeIcon from '@/assets/bnb/BNB_HomeIcon'; +import BNBCalendarIcon from '@/assets/bnb/BNB_CalendarIcon'; +import BNBProfileIcon from '@/assets/bnb/BNBProfileIcon'; +import { Container, Tab, TabText } from './styles'; + +// 고객 뷰일 경우 +const MENU_LIST = [ + { title: '사진작가', route: '/photographer', icon: BNBPhotographerIcon }, + { title: '포토스팟', route: '/map', icon: BNBMapIcon }, + { title: '홈', route: '/', icon: BNBHomeIcon }, + { title: '예약', route: '/book', icon: BNBCalendarIcon }, + { title: '마이페이지', route: '/my', icon: BNBProfileIcon }, +]; + +// [todo] 이후 고객/작가 구분하게 될 때 활성화하기 +// const MENU_LIST = [ +// { title: '사진작가', route: '/photographer' }, +// { title: '포토스팟', route: '/map' }, +// { title: '홈', route: '/' }, +// { title: '예약', route: '/book' }, +// { title: '마이페이지', route: '/profile' }, +// ]; + +export default function BottomNavigationBar() { + const pathname = usePathname(); + + if ( + pathname === '/splash' || + pathname === '/onboarding' || + pathname === '/signin' + ) { + return null; + } + + return ( + + {MENU_LIST.map((menu) => { + const isSelected = pathname === menu.route; + + return ( + + + + {menu.title} + + + ); + })} + + ); +} diff --git a/src/components/BNB/styles.ts b/src/components/BNB/styles.ts new file mode 100644 index 0000000..736f2c9 --- /dev/null +++ b/src/components/BNB/styles.ts @@ -0,0 +1,34 @@ +import Link from 'next/link'; +import styled from 'styled-components'; +import BREAK_POINT from '@/styles/constants'; +import Text from '../atoms/Text'; + +export const Container = styled.nav` + position: fixed; + bottom: 0; + + display: flex; + align-items: center; + justify-content: space-between; + + width: 100%; + max-width: ${BREAK_POINT}px; + padding: 1rem 1.25rem; + background: #0e0e0ecc; + border-top: 1px solid ${({ theme }) => theme.colors.gray[800]}; + backdrop-filter: blur(25px); +`; + +export const Tab = styled(Link)` + display: flex; + flex-direction: column; + align-items: center; + gap: 0.25rem; + + text-decoration: none; +`; + +export const TabText = styled(Text)<{ $isSelected: boolean }>` + color: ${({ theme, $isSelected }) => + $isSelected ? theme.colors.primary[100] : theme.colors.gray[300]}; +`; diff --git a/src/components/Card/card.css b/src/components/Card/card.css new file mode 100644 index 0000000..c5f7d6d --- /dev/null +++ b/src/components/Card/card.css @@ -0,0 +1,28 @@ +/* 버튼 크기 */ +.card.small { + img { + width: 7.5rem; + height: 7.5rem; + } +} + +.card.medium { + img { + width: 10.625rem; + height: 10.625rem; + } +} + +/* todo : 크기 수정해야함 */ +.card.large { + font-size: 16px; + padding: 12px 20px; +} + +/* todo : masonry에 들어갈 동적 크기 card */ +.card.dynamic { + img { + width: 100%; + height: auto; + } +} diff --git a/src/components/Card/index.tsx b/src/components/Card/index.tsx new file mode 100644 index 0000000..c7e3b24 --- /dev/null +++ b/src/components/Card/index.tsx @@ -0,0 +1,50 @@ +import React from 'react'; +import styled from 'styled-components'; +import Text from '../atoms/Text'; + +import './card.css'; + +export interface CardProps { + /** How large should the card be? */ + size?: 'small' | 'medium' | 'large' | 'dynamic'; + /** What card image to use */ + src: string; + /** Card Title */ + title?: string; + /** Card Content */ + content?: string; + /** Optional click handler */ + onClick?: () => void; +} + +const CardWrapper = styled.div` + display: flex; + flex-direction: column; + cursor: pointer; +`; + +const CardImage = styled.img` + object-fit: cover; + margin-bottom: 0.5rem; + border-radius: 0.125rem; +`; + +const CardContent = styled(Text)` + color: ${({ theme }) => theme.colors.gray[200]}; +`; + +export default function Card({ + size, + src, + title, + content, + onClick, +}: CardProps) { + return ( + + + {title} + {content} + + ); +} diff --git a/src/components/ScreenWrapper/index.tsx b/src/components/ScreenWrapper/index.tsx new file mode 100644 index 0000000..e7f30cb --- /dev/null +++ b/src/components/ScreenWrapper/index.tsx @@ -0,0 +1,17 @@ +'use client'; + +import { ReactNode } from 'react'; + +import BottomNavigationBar from '@/components/BNB'; +import { Container, FullPage } from './styles'; + +export default function ScreenWrapper({ children }: { children: ReactNode }) { + return ( + + + {children} + + + + ); +} diff --git a/src/components/ScreenWrapper/styles.ts b/src/components/ScreenWrapper/styles.ts new file mode 100644 index 0000000..1078e59 --- /dev/null +++ b/src/components/ScreenWrapper/styles.ts @@ -0,0 +1,15 @@ +import BREAK_POINT from '@/styles/constants'; +import styled from 'styled-components'; + +export const FullPage = styled.div` + height: 100dvh; +`; + +export const Container = styled.div` + position: relative; + width: 100%; + max-width: ${BREAK_POINT}px; + height: 100dvh; + margin: auto; + overflow: auto; +`; diff --git a/src/components/TNB/Back.tsx b/src/components/TNB/Back.tsx new file mode 100644 index 0000000..c904bf7 --- /dev/null +++ b/src/components/TNB/Back.tsx @@ -0,0 +1,36 @@ +import { useCallback } from 'react'; +import { useRouter } from 'next/navigation'; +import styled from 'styled-components'; +import Text from '@/components/atoms/Text'; +import LeftChevronIcon from '@/assets/LeftChevronIcon'; +import { BorderedHeader } from './styles'; + +const IconWrapper = styled.button` + position: absolute; + left: 1.25rem; + + background: transparent; + border: none; + outline: none; + + cursor: pointer; +`; + +export default function Back({ text }: { text: string }) { + const router = useRouter(); + + const goBack = useCallback(() => { + router.back(); + }, [router]); + + return ( + + + + + + {text} + + + ); +} diff --git a/src/components/TNB/Main.tsx b/src/components/TNB/Main.tsx new file mode 100644 index 0000000..a22d21d --- /dev/null +++ b/src/components/TNB/Main.tsx @@ -0,0 +1,11 @@ +import Text from '@/components/atoms/Text'; +import { Header } from './styles'; + +// [todo] 로고가 생기면 로고로 교체해주세요~ +export default function Main() { + return ( +
+ PHOTO GROUND +
+ ); +} diff --git a/src/components/TNB/SubTitle.tsx b/src/components/TNB/SubTitle.tsx new file mode 100644 index 0000000..97f04ce --- /dev/null +++ b/src/components/TNB/SubTitle.tsx @@ -0,0 +1,12 @@ +import Text from '@/components/atoms/Text'; +import { BorderedHeader } from './styles'; + +export default function SubTitle({ text }: { text: string }) { + return ( + + + {text} + + + ); +} diff --git a/src/components/TNB/Title.tsx b/src/components/TNB/Title.tsx new file mode 100644 index 0000000..5c62b04 --- /dev/null +++ b/src/components/TNB/Title.tsx @@ -0,0 +1,12 @@ +import Text from '@/components/atoms/Text'; +import { Header } from './styles'; + +export default function Title({ text }: { text: string }) { + return ( +
+ + {text} + +
+ ); +} diff --git a/src/components/TNB/index.tsx b/src/components/TNB/index.tsx new file mode 100644 index 0000000..1293214 --- /dev/null +++ b/src/components/TNB/index.tsx @@ -0,0 +1,13 @@ +import Main from './Main'; +import Title from './Title'; +import SubTitle from './SubTitle'; +import Back from './Back'; + +const TNB = { + Main, + Title, + SubTitle, + Back, +}; + +export default TNB; diff --git a/src/components/TNB/styles.tsx b/src/components/TNB/styles.tsx new file mode 100644 index 0000000..566660d --- /dev/null +++ b/src/components/TNB/styles.tsx @@ -0,0 +1,14 @@ +import styled from 'styled-components'; + +export const Header = styled.header` + position: relative; + display: flex; + align-items: center; + justify-content: center; + + height: 4rem; +`; + +export const BorderedHeader = styled(Header)` + border-bottom: 1px solid ${({ theme }) => theme.colors.gray[600]}; +`; diff --git a/src/components/atoms/CTAButton/index.tsx b/src/components/atoms/CTAButton/index.tsx new file mode 100644 index 0000000..ffeff4e --- /dev/null +++ b/src/components/atoms/CTAButton/index.tsx @@ -0,0 +1,60 @@ +import styled, { DefaultTheme } from 'styled-components'; +import Text from '@/components/atoms/Text'; + +type Variant = 'primary' | 'secondary'; + +const getBackgroundColor = ({ + theme, + variant, + disabled, +}: { + theme: DefaultTheme; + variant: Variant; + disabled: boolean; +}) => { + if (disabled) { + return theme.colors.gray[600]; + } + if (variant === 'primary') { + return theme.colors.primary[100]; + } + return theme.colors.gray[900]; +}; + +const Button = styled.button<{ variant: Variant; disabled: boolean }>` + width: 100%; + padding: 1rem 0; + background: ${(props) => getBackgroundColor(props)}; + + outline: none; + border: none; + border-radius: 0.5rem; + + cursor: pointer; +`; + +const ButtonText = styled(Text)` + color: ${({ theme }) => theme.colors.gray[200]}; +`; + +export default function CTAButton({ + text, + variant = 'primary', + disabled = false, + onClick = () => {}, +}: { + text: string; + variant?: Variant; + disabled?: boolean; + onClick?: () => void; +}) { + return ( + + ); +} diff --git a/src/components/atoms/MediumButton/index.tsx b/src/components/atoms/MediumButton/index.tsx new file mode 100644 index 0000000..02dcba9 --- /dev/null +++ b/src/components/atoms/MediumButton/index.tsx @@ -0,0 +1,34 @@ +import styled from 'styled-components'; +import Text from '@/components/atoms/Text'; + +type Variant = 'primary' | 'secondary'; + +const Button = styled.button<{ variant: Variant }>` + padding: 0.688rem 1.25rem; + background: ${({ theme, variant }) => + variant === 'primary' ? theme.colors.primary[100] : theme.colors.gray[900]}; + + outline: none; + border: none; + border-radius: 1.5rem; + + cursor: pointer; +`; + +export default function MediumButton({ + text, + variant = 'primary', + onClick = () => {}, +}: { + text: string; + variant?: Variant; + onClick?: () => void; +}) { + return ( + + ); +} diff --git a/src/components/atoms/SmallButton/Primary.tsx b/src/components/atoms/SmallButton/Primary.tsx new file mode 100644 index 0000000..c66cc0d --- /dev/null +++ b/src/components/atoms/SmallButton/Primary.tsx @@ -0,0 +1,33 @@ +import styled from 'styled-components'; +import Text from '@/components/atoms/Text'; +import Button from './styles'; + +const PrimaryButton = styled(Button)<{ disabled: boolean }>` + background: ${({ theme, disabled }) => + disabled ? theme.colors.gray[600] : theme.colors.primary[100]}; + cursor: ${({ disabled }) => (disabled ? 'auto' : 'cursor')}; +`; + +const DisabledText = styled(Text)` + color: ${({ theme }) => theme.colors.gray[200]}; +`; + +export default function Primary({ + text, + disabled = false, + onClick = () => {}, +}: { + text: string; + disabled?: boolean; + onClick?: () => void; +}) { + return ( + + {disabled ? ( + {text} + ) : ( + {text} + )} + + ); +} diff --git a/src/components/atoms/SmallButton/Secondary.tsx b/src/components/atoms/SmallButton/Secondary.tsx new file mode 100644 index 0000000..4838738 --- /dev/null +++ b/src/components/atoms/SmallButton/Secondary.tsx @@ -0,0 +1,21 @@ +import styled from 'styled-components'; +import Text from '@/components/atoms/Text'; +import Button from './styles'; + +const SecondaryButton = styled(Button)` + background: ${({ theme }) => theme.colors.gray[900]}; +`; + +export default function Secondary({ + text, + onClick = () => {}, +}: { + text: string; + onClick?: () => void; +}) { + return ( + + {text} + + ); +} diff --git a/src/components/atoms/SmallButton/Tertiary.tsx b/src/components/atoms/SmallButton/Tertiary.tsx new file mode 100644 index 0000000..f4f3660 --- /dev/null +++ b/src/components/atoms/SmallButton/Tertiary.tsx @@ -0,0 +1,26 @@ +import styled from 'styled-components'; +import Text from '@/components/atoms/Text'; +import Button from './styles'; + +const TertiaryButton = styled(Button)` + background: transparent; + border: 1px solid ${({ theme }) => theme.colors.primary[100]}; +`; + +const ButtonText = styled(Text)` + color: ${({ theme }) => theme.colors.primary[100]}; +`; + +export default function Tertiary({ + text, + onClick = () => {}, +}: { + text: string; + onClick?: () => void; +}) { + return ( + + {text} + + ); +} diff --git a/src/components/atoms/SmallButton/index.tsx b/src/components/atoms/SmallButton/index.tsx new file mode 100644 index 0000000..28a6645 --- /dev/null +++ b/src/components/atoms/SmallButton/index.tsx @@ -0,0 +1,11 @@ +import Primary from './Primary'; +import Secondary from './Secondary'; +import Tertiary from './Tertiary'; + +const SmallButton = { + Primary, + Secondary, + Tertiary, +}; + +export default SmallButton; diff --git a/src/components/atoms/SmallButton/styles.tsx b/src/components/atoms/SmallButton/styles.tsx new file mode 100644 index 0000000..5b10e56 --- /dev/null +++ b/src/components/atoms/SmallButton/styles.tsx @@ -0,0 +1,13 @@ +import styled from 'styled-components'; + +const Button = styled.button` + padding: 0.438rem 1.25rem; + + outline: none; + border: none; + border-radius: 1.5rem; + + cursor: pointer; +`; + +export default Button; diff --git a/src/components/atoms/Tag/index.tsx b/src/components/atoms/Tag/index.tsx new file mode 100644 index 0000000..5751a03 --- /dev/null +++ b/src/components/atoms/Tag/index.tsx @@ -0,0 +1,38 @@ +import styled from 'styled-components'; +import Text from '@/components/atoms/Text'; + +type Variant = 'primary' | 'secondary'; + +const TagContainer = styled.div<{ variant: Variant }>` + width: fit-content; + padding: 0.375rem 1rem; + background: ${({ theme, variant }) => + variant === 'primary' ? theme.colors.gray[100] : theme.colors.gray[900]}; + border-radius: 1.5rem; +`; + +const PrimaryText = styled(Text)` + color: ${({ theme }) => theme.colors.gray[900]}; +`; + +const SecondaryText = styled(Text)` + color: ${({ theme }) => theme.colors.gray[200]}; +`; + +export default function Tag({ + text, + variant, +}: { + text: string; + variant: Variant; +}) { + return ( + + {variant === 'primary' ? ( + {text} + ) : ( + {text} + )} + + ); +} diff --git a/src/components/atoms/Text/index.tsx b/src/components/atoms/Text/index.tsx new file mode 100644 index 0000000..a471800 --- /dev/null +++ b/src/components/atoms/Text/index.tsx @@ -0,0 +1,28 @@ +import styled from 'styled-components'; + +type Variant = + | 'header1' + | 'header2' + | 'header3' + | 'title1_sb' + | 'title1_rg' + | 'title2' + | 'title3' + | 'body1_md' + | 'body1_rg' + | 'body2_md' + | 'body2_rg' + | 'body3' + | 'caption1_md' + | 'caption1_rg' + | 'caption2' + | 'caption3'; + +const Text = styled.p<{ variant: Variant }>` + font-size: ${({ theme, variant }) => theme.typography[variant].fontSize}; + font-weight: ${({ theme, variant }) => theme.typography[variant].fontWeight}; + line-height: ${({ theme, variant }) => theme.typography[variant].lineHeight}; + color: ${({ theme }) => theme.colors.white}; +`; + +export default Text; diff --git a/src/lib/registry.tsx b/src/lib/registry.tsx new file mode 100644 index 0000000..bb4ea04 --- /dev/null +++ b/src/lib/registry.tsx @@ -0,0 +1,96 @@ +'use client'; + +import React, { useState } from 'react'; +import { useServerInsertedHTML } from 'next/navigation'; +import { + createGlobalStyle, + ServerStyleSheet, + StyleSheetManager, + ThemeProvider, +} from 'styled-components'; +import theme from '@/styles/theme'; + +const GlobalStyle = createGlobalStyle` + /* http://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) + */ + + html, body, div, span, applet, object, iframe, + h1, h2, h3, h4, h5, h6, p, blockquote, pre, + a, abbr, acronym, address, big, cite, code, + del, dfn, em, img, ins, kbd, q, s, samp, + small, strike, strong, sub, sup, tt, var, + b, u, i, center, + dl, dt, dd, ol, ul, li, + fieldset, form, label, legend, + table, caption, tbody, tfoot, thead, tr, th, td, + article, aside, canvas, details, embed, + figure, figcaption, footer, header, hgroup, + menu, nav, output, ruby, section, summary, + time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; + } + /* HTML5 display-role reset for older browsers */ + article, aside, details, figcaption, figure, + footer, header, hgroup, menu, nav, section { + display: block; + } + body { + line-height: 1; + background: ${theme.colors.background.primary}; + } + ol, ul { + list-style: none; + } + blockquote, q { + quotes: none; + } + blockquote:before, blockquote:after, + q:before, q:after { + content: ''; + content: none; + } + table { + border-collapse: collapse; + border-spacing: 0; + } + + * { + box-sizing: border-box; + color: ${theme.colors.white} + } +`; + +export default function StyledComponentsRegistry({ + children, +}: { + children: React.ReactNode; +}) { + // Only create stylesheet once with lazy initial state + // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state + const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet()); + + useServerInsertedHTML(() => { + const styles = styledComponentsStyleSheet.getStyleElement(); + styledComponentsStyleSheet.instance.clearTag(); + return styles; + }); + + if (typeof window !== 'undefined') + return {children}; + + return ( + + + + {children} + + + ); +} diff --git a/src/styles/constants.ts b/src/styles/constants.ts new file mode 100644 index 0000000..875ae05 --- /dev/null +++ b/src/styles/constants.ts @@ -0,0 +1,3 @@ +const BREAK_POINT = 786; + +export default BREAK_POINT; diff --git a/src/styles/convertSize.ts b/src/styles/convertSize.ts new file mode 100644 index 0000000..33daad4 --- /dev/null +++ b/src/styles/convertSize.ts @@ -0,0 +1,10 @@ +const BASE_SCREEN_WIDTH = 390; +const BASE_SCREEN_HEIGHT = 844; + +export function convertToViewportWidth(px: number) { + return `${(px / BASE_SCREEN_WIDTH) * 100}dvw`; +} + +export function convertToViewportHeight(px: number) { + return `${(px / BASE_SCREEN_HEIGHT) * 100}dvh`; +} diff --git a/src/styles/theme.ts b/src/styles/theme.ts new file mode 100644 index 0000000..ba565be --- /dev/null +++ b/src/styles/theme.ts @@ -0,0 +1,124 @@ +const theme = { + colors: { + primary: { + 100: '#FF4000', + 80: '#FF612B', + 70: '#FF855C', + 60: '#FFA67D', + }, + + secondary: { + surface: '#007C29', + alpha: '#007C2947', + }, + + black: '#0E0E0E', + white: '#F5F5F5', + + gray: { + 900: '#212121', + 800: '#262626', + 700: '#333333', + 600: '#404040', + 500: '#595959', + 400: '#737373', + 300: '#8C8C8C', + 200: '#A6A6A6', + 100: '#BFBFBF', + }, + + system: { + warning: '#ED4245', + }, + + background: { + // [todo] 디자인 시스템에 없는데 사용되고 있어서 문의해봐야함 + primary: '#0e0e0e', + }, + }, + + typography: { + header1: { + fontSize: '1.5rem', + fontWeight: 600, + lineHeight: '2rem', + }, + header2: { + fontSize: '1.5rem', + fontWeight: 500, + lineHeight: '2rem', + }, + header3: { + fontSize: '1.125rem', + fontWeight: 500, + lineHeight: '2rem', + }, + title1_sb: { + fontSize: '1.25rem', + fontWeight: 600, + lineHeight: '1.75rem', + }, + title1_rg: { + fontSize: '1.25rem', + fontWeight: 400, + lineHeight: '1.75rem', + }, + title2: { + fontSize: '1.125rem', + fontWeight: 600, + lineHeight: '1.5rem', + }, + title3: { + fontSize: '1rem', + fontWeight: 600, + lineHeight: '1.375rem', + }, + body1_md: { + fontSize: '1rem', + fontWeight: 500, + lineHeight: '1.375rem', + }, + body1_rg: { + fontSize: '1rem', + fontWeight: 400, + lineHeight: '1.375rem', + }, + body2_md: { + fontSize: '0.938rem', + fontWeight: 500, + lineHeight: '1.375rem', + }, + body2_rg: { + fontSize: '0.938rem', + fontWeight: 400, + lineHeight: '1.375rem', + }, + body3: { + fontSize: '0.875rem', + fontWeight: 400, + lineHeight: '1.25rem', + }, + caption1_md: { + fontSize: '0.875rem', + fontWeight: 500, + lineHeight: '1.25rem', + }, + caption1_rg: { + fontSize: '0.875rem', + fontWeight: 400, + lineHeight: '1.25rem', + }, + caption2: { + fontSize: '0.813rem', + fontWeight: 400, + lineHeight: '1.25rem', + }, + caption3: { + fontSize: '0.625rem', + fontWeight: 400, + lineHeight: '0.75rem', + }, + }, +}; + +export default theme; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..fb10e21 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "target": "ES2017", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@components/*": ["./src/components/*"], + "@/*": ["./src/*"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +} From 8d759cbe9019b9bee1ab0f5dd2f309ff43e795e6 Mon Sep 17 00:00:00 2001 From: hiwon-lee <84234411+hiwon-lee@users.noreply.github.com> Date: Thu, 26 Dec 2024 17:35:52 +0900 Subject: [PATCH 02/30] =?UTF-8?q?=F0=9F=9B=A0=EF=B8=8F=20build:=20=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EB=AA=A8=EB=93=88=20=EC=84=A4=EC=B9=98?= =?UTF-8?q?=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 886 +++++++++++++++++++++++++++++++++++++++++++++- package.json | 6 +- tsconfig.json | 5 +- 3 files changed, 885 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1dcbf9d..2048394 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,15 +8,19 @@ "name": "my-app", "version": "0.1.0", "dependencies": { + "msw": "^2.7.0", "next": "15.1.2", + "next-auth": "^4.24.11", "react": "^19.0.0", - "react-dom": "^19.0.0" + "react-dom": "^19.0.0", + "styled-components": "^6.1.13" }, "devDependencies": { "@eslint/eslintrc": "^3", "@types/node": "^20", "@types/react": "^19", "@types/react-dom": "^19", + "@types/styled-components": "^5.1.34", "eslint": "^9", "eslint-config-next": "15.1.2", "eslint-config-prettier": "^9.1.0", @@ -25,6 +29,46 @@ "typescript": "^5" } }, + "node_modules/@babel/runtime": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bundled-es-modules/cookie": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/cookie/-/cookie-2.0.1.tgz", + "integrity": "sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==", + "license": "ISC", + "dependencies": { + "cookie": "^0.7.2" + } + }, + "node_modules/@bundled-es-modules/statuses": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/statuses/-/statuses-1.0.1.tgz", + "integrity": "sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==", + "license": "ISC", + "dependencies": { + "statuses": "^2.0.1" + } + }, + "node_modules/@bundled-es-modules/tough-cookie": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/tough-cookie/-/tough-cookie-0.1.6.tgz", + "integrity": "sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==", + "license": "ISC", + "dependencies": { + "@types/tough-cookie": "^4.0.5", + "tough-cookie": "^4.1.4" + } + }, "node_modules/@emnapi/runtime": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz", @@ -35,6 +79,27 @@ "tslib": "^2.4.0" } }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", + "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==", + "license": "MIT" + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==", + "license": "MIT" + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", @@ -589,6 +654,80 @@ "url": "https://opencollective.com/libvips" } }, + "node_modules/@inquirer/confirm": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.1.tgz", + "integrity": "sha512-vVLSbGci+IKQvDOtzpPTCOiEJCNidHcAq9JYVoWTW0svb5FiwSLotkM+JXNXejfjnzVYV9n0DTBythl9+XgTxg==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/core": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.2.tgz", + "integrity": "sha512-bHd96F3ezHg1mf/J0Rb4CV8ndCN0v28kUlrHqP7+ECm1C/A+paB7Xh2lbMk6x+kweQC+rZOxM/YeKikzxco8bQ==", + "license": "MIT", + "dependencies": { + "@inquirer/figures": "^1.0.9", + "@inquirer/type": "^3.0.2", + "ansi-escapes": "^4.3.2", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.9.tgz", + "integrity": "sha512-BXvGj0ehzrngHTPTDqUoDT3NXL8U0RxUk2zJm2A66RhCEIWdtU1v6GuUqNAgArW4PQ9CinqIWyHdQgdwOj06zQ==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/type": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.2.tgz", + "integrity": "sha512-ZhQ4TvhwHZF+lGhQ2O/rsjo80XoZR5/5qhOY3t6FJuX5XBg5Be8YzYTvaUGJnc12AUGI2nr4QSUE4PhKSigx7g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@mswjs/interceptors": { + "version": "0.37.3", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.37.3.tgz", + "integrity": "sha512-USvgCL/uOGFtVa6SVyRrC8kIAedzRohxIXN5LISlg5C5vLZCn7dgMFVSNhSF9cuBEFrm/O2spDWEZeMnw4ZXYg==", + "license": "MIT", + "dependencies": { + "@open-draft/deferred-promise": "^2.2.0", + "@open-draft/logger": "^0.3.0", + "@open-draft/until": "^2.0.0", + "is-node-process": "^1.2.0", + "outvariant": "^1.4.3", + "strict-event-emitter": "^0.5.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@next/env": { "version": "15.1.2", "resolved": "https://registry.npmjs.org/@next/env/-/env-15.1.2.tgz", @@ -781,6 +920,37 @@ "node": ">=12.4.0" } }, + "node_modules/@open-draft/deferred-promise": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz", + "integrity": "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==", + "license": "MIT" + }, + "node_modules/@open-draft/logger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@open-draft/logger/-/logger-0.3.0.tgz", + "integrity": "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==", + "license": "MIT", + "dependencies": { + "is-node-process": "^1.2.0", + "outvariant": "^1.4.0" + } + }, + "node_modules/@open-draft/until": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@open-draft/until/-/until-2.1.0.tgz", + "integrity": "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==", + "license": "MIT" + }, + "node_modules/@panva/hkdf": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.2.1.tgz", + "integrity": "sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/@pkgr/core": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", @@ -823,6 +993,12 @@ "tslib": "^2.8.0" } }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", @@ -830,6 +1006,17 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.6.tgz", + "integrity": "sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -848,7 +1035,6 @@ "version": "20.17.10", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.10.tgz", "integrity": "sha512-/jrvh5h6NXhEauFFexRin69nA0uHJ5gwk4iDivp/DeoEua3uwCUto6PC86IpRITBOs4+6i2I56K5x5b6WYGXHA==", - "dev": true, "license": "MIT", "dependencies": { "undici-types": "~6.19.2" @@ -874,6 +1060,36 @@ "@types/react": "^19.0.0" } }, + "node_modules/@types/statuses": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-2.0.5.tgz", + "integrity": "sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==", + "license": "MIT" + }, + "node_modules/@types/styled-components": { + "version": "5.1.34", + "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.34.tgz", + "integrity": "sha512-mmiVvwpYklFIv9E8qfxuPyIt/OuyIrn6gMOAMOFUO3WJfSrSE+sGUoa4PiZj77Ut7bKZpaa6o1fBKS/4TOEvnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hoist-non-react-statics": "*", + "@types/react": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/stylis": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz", + "integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==", + "license": "MIT" + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "license": "MIT" + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.18.2", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.18.2.tgz", @@ -1150,11 +1366,46 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -1485,6 +1736,15 @@ "node": ">=6" } }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001690", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz", @@ -1522,12 +1782,52 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, "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": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/color": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", @@ -1546,7 +1846,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "devOptional": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -1559,7 +1858,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "devOptional": true, "license": "MIT" }, "node_modules/color-string": { @@ -1580,6 +1878,15 @@ "dev": true, "license": "MIT" }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -1595,11 +1902,30 @@ "node": ">= 8" } }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "license": "MIT", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true, "license": "MIT" }, "node_modules/damerau-levenshtein": { @@ -1949,6 +2275,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -2645,6 +2980,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, "node_modules/get-intrinsic": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.6.tgz", @@ -2771,6 +3115,15 @@ "dev": true, "license": "MIT" }, + "node_modules/graphql": { + "version": "16.10.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.10.0.tgz", + "integrity": "sha512-AjqGKbDGUFRKIRCP9tCKiIGHyriz2oHEbPIbEtcSLSs4YjReZOIPQQWek4+6hjw62H9QShXHyaGivGiYVLeYFQ==", + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, "node_modules/has-bigints": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", @@ -2865,6 +3218,22 @@ "node": ">= 0.4" } }, + "node_modules/headers-polyfill": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-4.0.3.tgz", + "integrity": "sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==", + "license": "MIT" + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -3091,6 +3460,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-generator-function": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", @@ -3133,6 +3511,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-node-process": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz", + "integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==", + "license": "MIT" + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -3337,6 +3721,15 @@ "node": ">= 0.4" } }, + "node_modules/jose": { + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", + "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -3487,6 +3880,18 @@ "loose-envify": "cli.js" } }, + "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==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -3551,6 +3956,59 @@ "dev": true, "license": "MIT" }, + "node_modules/msw": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/msw/-/msw-2.7.0.tgz", + "integrity": "sha512-BIodwZ19RWfCbYTxWTUfTXc+sg4OwjCAgxU1ZsgmggX/7S3LdUifsbUPJs61j0rWb19CZRGY5if77duhc0uXzw==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@bundled-es-modules/cookie": "^2.0.1", + "@bundled-es-modules/statuses": "^1.0.1", + "@bundled-es-modules/tough-cookie": "^0.1.6", + "@inquirer/confirm": "^5.0.0", + "@mswjs/interceptors": "^0.37.0", + "@open-draft/deferred-promise": "^2.2.0", + "@open-draft/until": "^2.1.0", + "@types/cookie": "^0.6.0", + "@types/statuses": "^2.0.4", + "graphql": "^16.8.1", + "headers-polyfill": "^4.0.2", + "is-node-process": "^1.2.0", + "outvariant": "^1.4.3", + "path-to-regexp": "^6.3.0", + "picocolors": "^1.1.1", + "strict-event-emitter": "^0.5.1", + "type-fest": "^4.26.1", + "yargs": "^17.7.2" + }, + "bin": { + "msw": "cli/index.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/mswjs" + }, + "peerDependencies": { + "typescript": ">= 4.8.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/nanoid": { "version": "3.3.8", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", @@ -3630,6 +4088,44 @@ } } }, + "node_modules/next-auth": { + "version": "4.24.11", + "resolved": "https://registry.npmjs.org/next-auth/-/next-auth-4.24.11.tgz", + "integrity": "sha512-pCFXzIDQX7xmHFs4KVH4luCjaCbuPRtZ9oBUjUhOk84mZ9WVPf94n87TxYI4rSRf9HmfHEF8Yep3JrYDVOo3Cw==", + "license": "ISC", + "dependencies": { + "@babel/runtime": "^7.20.13", + "@panva/hkdf": "^1.0.2", + "cookie": "^0.7.0", + "jose": "^4.15.5", + "oauth": "^0.9.15", + "openid-client": "^5.4.0", + "preact": "^10.6.3", + "preact-render-to-string": "^5.1.19", + "uuid": "^8.3.2" + }, + "peerDependencies": { + "@auth/core": "0.34.2", + "next": "^12.2.5 || ^13 || ^14 || ^15", + "nodemailer": "^6.6.5", + "react": "^17.0.2 || ^18 || ^19", + "react-dom": "^17.0.2 || ^18 || ^19" + }, + "peerDependenciesMeta": { + "@auth/core": { + "optional": true + }, + "nodemailer": { + "optional": true + } + } + }, + "node_modules/oauth": { + "version": "0.9.15", + "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", + "integrity": "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==", + "license": "MIT" + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -3640,6 +4136,15 @@ "node": ">=0.10.0" } }, + "node_modules/object-hash": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", + "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, "node_modules/object-inspect": { "version": "1.13.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", @@ -3752,6 +4257,30 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/oidc-token-hash": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz", + "integrity": "sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw==", + "license": "MIT", + "engines": { + "node": "^10.13.0 || >=12.0.0" + } + }, + "node_modules/openid-client": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.7.1.tgz", + "integrity": "sha512-jDBPgSVfTnkIh71Hg9pRvtJc6wTwqjRkN88+gCFtYWrlP4Yx2Dsrow8uPi3qLr/aeymPF3o2+dS+wOpglK04ew==", + "license": "MIT", + "dependencies": { + "jose": "^4.15.9", + "lru-cache": "^6.0.0", + "object-hash": "^2.2.0", + "oidc-token-hash": "^5.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -3770,6 +4299,12 @@ "node": ">= 0.8.0" } }, + "node_modules/outvariant": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.3.tgz", + "integrity": "sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==", + "license": "MIT" + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -3842,6 +4377,12 @@ "dev": true, "license": "MIT" }, + "node_modules/path-to-regexp": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", + "license": "MIT" + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -3899,6 +4440,34 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "license": "MIT" + }, + "node_modules/preact": { + "version": "10.25.3", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.25.3.tgz", + "integrity": "sha512-dzQmIFtM970z+fP9ziQ3yG4e3ULIbwZzJ734vaMVUTaKQ2+Ru1Ou/gjshOYVHCcd1rpAelC6ngjvjDXph98unQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "node_modules/preact-render-to-string": { + "version": "5.2.6", + "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.6.tgz", + "integrity": "sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==", + "license": "MIT", + "dependencies": { + "pretty-format": "^3.8.0" + }, + "peerDependencies": { + "preact": ">=10" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -3938,6 +4507,12 @@ "node": ">=6.0.0" } }, + "node_modules/pretty-format": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz", + "integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==", + "license": "MIT" + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -3950,16 +4525,33 @@ "react-is": "^16.13.1" } }, + "node_modules/psl": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "license": "MIT" + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -4032,6 +4624,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" + }, "node_modules/regexp.prototype.flags": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", @@ -4051,6 +4649,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "license": "MIT" + }, "node_modules/resolve": { "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", @@ -4218,6 +4831,12 @@ "node": ">= 0.4" } }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "license": "MIT" + }, "node_modules/sharp": { "version": "0.33.5", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", @@ -4357,6 +4976,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", @@ -4383,6 +5014,15 @@ "dev": true, "license": "MIT" }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", @@ -4391,6 +5031,32 @@ "node": ">=10.0.0" } }, + "node_modules/strict-event-emitter": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz", + "integrity": "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==", + "license": "MIT" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, "node_modules/string.prototype.includes": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", @@ -4504,6 +5170,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -4527,6 +5205,68 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/styled-components": { + "version": "6.1.13", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.13.tgz", + "integrity": "sha512-M0+N2xSnAtwcVAQeFEsGWFFxXDftHUD7XrKla06QbpUMmbmtFBMMTcKWvFXtWxuD5qQkB8iU5gk6QASlx2ZRMw==", + "license": "MIT", + "dependencies": { + "@emotion/is-prop-valid": "1.2.2", + "@emotion/unitless": "0.8.1", + "@types/stylis": "4.2.5", + "css-to-react-native": "3.2.0", + "csstype": "3.1.3", + "postcss": "8.4.38", + "shallowequal": "1.1.0", + "stylis": "4.3.2", + "tslib": "2.6.2" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/styled-components" + }, + "peerDependencies": { + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0" + } + }, + "node_modules/styled-components/node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/styled-components/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "license": "0BSD" + }, "node_modules/styled-jsx": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", @@ -4550,6 +5290,12 @@ } } }, + "node_modules/stylis": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", + "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==", + "license": "MIT" + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -4616,6 +5362,21 @@ "node": ">=8.0" } }, + "node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/ts-api-utils": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", @@ -4661,6 +5422,18 @@ "node": ">= 0.8.0" } }, + "node_modules/type-fest": { + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.31.0.tgz", + "integrity": "sha512-yCxltHW07Nkhv/1F6wWBr8kz+5BGMfP+RbRSYFnegVb0qV/UMT0G0ElBloPVerqn4M2ZV80Ir1FtCcYv1cT6vQ==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/typed-array-buffer": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", @@ -4743,7 +5516,7 @@ "version": "5.7.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -4776,9 +5549,17 @@ "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "dev": true, "license": "MIT" }, + "node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -4789,6 +5570,25 @@ "punycode": "^2.1.0" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "license": "MIT", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -4903,6 +5703,62 @@ "node": ">=0.10.0" } }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -4915,6 +5771,18 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", + "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/package.json b/package.json index be45566..316ae72 100644 --- a/package.json +++ b/package.json @@ -9,15 +9,19 @@ "lint": "next lint" }, "dependencies": { + "msw": "^2.7.0", "next": "15.1.2", + "next-auth": "^4.24.11", "react": "^19.0.0", - "react-dom": "^19.0.0" + "react-dom": "^19.0.0", + "styled-components": "^6.1.13" }, "devDependencies": { "@eslint/eslintrc": "^3", "@types/node": "^20", "@types/react": "^19", "@types/react-dom": "^19", + "@types/styled-components": "^5.1.34", "eslint": "^9", "eslint-config-next": "15.1.2", "eslint-config-prettier": "^9.1.0", diff --git a/tsconfig.json b/tsconfig.json index fb10e21..bf6bbd1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,8 +19,9 @@ } ], "paths": { - "@components/*": ["./src/components/*"], - "@/*": ["./src/*"] + "@/*": ["./src/*"], + "@/components/*": ["./src/app/_components/*"], + "@/styles/*": ["./src/styles/*"] } }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], From 28c755303b1a7fd82667823f412c67d96e75321b Mon Sep 17 00:00:00 2001 From: hiwon-lee <84234411+hiwon-lee@users.noreply.github.com> Date: Thu, 26 Dec 2024 17:38:59 +0900 Subject: [PATCH 03/30] =?UTF-8?q?=E2=9C=A8=20feat:=20=20=ED=9A=8C=EC=9B=90?= =?UTF-8?q?=EA=B0=80=EC=9E=85=20=EC=9A=94=EC=86=8C=20=EA=B5=AC=ED=98=84?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../(beforeLogin)/_components/EmailInput.tsx | 93 ++++++++++++++ src/app/(beforeLogin)/_components/Form.tsx | 51 ++++++++ .../(beforeLogin)/_components/GenderInput.tsx | 67 ++++++++++ .../(beforeLogin)/_components/InputList.tsx | 48 +++++++ src/app/(beforeLogin)/_components/Main.tsx | 47 +++++++ .../(beforeLogin)/_components/NameInput.tsx | 26 ++++ .../_components/PasswordInput.tsx | 33 +++++ .../(beforeLogin)/_components/PhoneInput.tsx | 32 +++++ src/app/(beforeLogin)/_components/Tabs.tsx | 75 +++++++++++ .../(beforeLogin)/_components/UnivInput.tsx | 120 ++++++++++++++++++ src/app/(beforeLogin)/_components/styles.ts | 24 ++++ src/app/(beforeLogin)/i/flow/login/page.tsx | 7 + src/app/(beforeLogin)/i/flow/signup/page.tsx | 7 + src/app/(beforeLogin)/page.tsx | 16 +++ src/app/(beforeLogin)/signin/page.tsx | 17 +++ src/app/(beforeLogin)/signup/page.tsx | 47 +++++++ src/app/(beforeLogin)/signup/styles.ts | 24 ++++ 17 files changed, 734 insertions(+) create mode 100644 src/app/(beforeLogin)/_components/EmailInput.tsx create mode 100644 src/app/(beforeLogin)/_components/Form.tsx create mode 100644 src/app/(beforeLogin)/_components/GenderInput.tsx create mode 100644 src/app/(beforeLogin)/_components/InputList.tsx create mode 100644 src/app/(beforeLogin)/_components/Main.tsx create mode 100644 src/app/(beforeLogin)/_components/NameInput.tsx create mode 100644 src/app/(beforeLogin)/_components/PasswordInput.tsx create mode 100644 src/app/(beforeLogin)/_components/PhoneInput.tsx create mode 100644 src/app/(beforeLogin)/_components/Tabs.tsx create mode 100644 src/app/(beforeLogin)/_components/UnivInput.tsx create mode 100644 src/app/(beforeLogin)/_components/styles.ts create mode 100644 src/app/(beforeLogin)/i/flow/login/page.tsx create mode 100644 src/app/(beforeLogin)/i/flow/signup/page.tsx create mode 100644 src/app/(beforeLogin)/page.tsx create mode 100644 src/app/(beforeLogin)/signin/page.tsx create mode 100644 src/app/(beforeLogin)/signup/page.tsx create mode 100644 src/app/(beforeLogin)/signup/styles.ts diff --git a/src/app/(beforeLogin)/_components/EmailInput.tsx b/src/app/(beforeLogin)/_components/EmailInput.tsx new file mode 100644 index 0000000..45e538b --- /dev/null +++ b/src/app/(beforeLogin)/_components/EmailInput.tsx @@ -0,0 +1,93 @@ +"use client"; + +import { useState } from "react"; +import styled from "styled-components"; + +import EmailIcon from "@/assets/EmailIcon"; +import Text from "@/components/atoms/Text"; +import { Input, InputContainer } from "@/styles/input"; + +const Container = styled.div` + display: flex; + flex-direction: column; + gap: 0.5rem; + + margin-top: 1.5rem; + margin-bottom: 1.5rem; + width: 100%; +`; + +const InputWrapper = styled.div` + display: grid; + grid-template-columns: 1fr 7.125rem; + gap: 0.75rem; + width: 100%; +`; + +const PasskeyInputContainer = styled(InputContainer)` + padding: 0; + padding-left: 0.5rem; +`; + +const ConfirmButton = styled.button` + height: 100%; + padding: 0 1rem; + background: transparent; + white-space: nowrap; + + border: none; + border-left: 1px solid ${({ theme }) => theme.colors.gray[600]}; + outline: none; +`; + +const Button = styled.button<{ $disabled?: boolean }>` + background: transparent; + padding: 0.5rem 0; + white-space: nowrap; + + border: 1px solid + ${({ theme, $disabled }) => theme.colors.gray[$disabled ? 600 : 200]}; + border-radius: 0.5rem; + outline: none; +`; + +const ButtonText = styled(Text)<{ $disabled?: boolean }>` + color: ${({ theme, $disabled }) => theme.colors.gray[$disabled ? 600 : 200]}; +`; + +export default function EmailInput() { + const [isSent, setIsSent] = useState(false); + + const sendMail = () => { + setIsSent(true); + }; + + return ( + + + + + + + + + + {isSent && ( + + + + + 확인 + + + + )} + + ); +} diff --git a/src/app/(beforeLogin)/_components/Form.tsx b/src/app/(beforeLogin)/_components/Form.tsx new file mode 100644 index 0000000..59efe99 --- /dev/null +++ b/src/app/(beforeLogin)/_components/Form.tsx @@ -0,0 +1,51 @@ +import CTAButton from "@/components/atoms/CTAButton"; +import Text from "@/components/atoms/Text"; +import { convertToViewportHeight } from "@/styles/convertSize"; +import Link from "next/link"; +import styled from "styled-components"; +import InputList from "./InputList"; + +const Form = styled.form` + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-between; + + width: 100%; + height: 100%; + margin-top: ${convertToViewportHeight(48)}; +`; + +const Wrapper = styled.div` + display: flex; + flex-direction: column; + align-items: center; + width: 100%; + padding: 0 1.25rem; +`; + +const StyledLink = styled(Link)` + width: fit-content; + text-decoration-color: ${({ theme }) => theme.colors.gray[300]}; +`; +const SignUpText = styled(Text)` + color: ${({ theme }) => theme.colors.gray[300]}; + margin-top: ${convertToViewportHeight(24)}; +`; + +export default function SignInForm() { + return ( +
+ + + + {/* [todo] 링크 변경 */} + + 회원가입 + + + + + + ); +} diff --git a/src/app/(beforeLogin)/_components/GenderInput.tsx b/src/app/(beforeLogin)/_components/GenderInput.tsx new file mode 100644 index 0000000..f231a91 --- /dev/null +++ b/src/app/(beforeLogin)/_components/GenderInput.tsx @@ -0,0 +1,67 @@ +'use client'; + +import Text from '@/components/atoms/Text'; +import { useState } from 'react'; +import styled from 'styled-components'; + +type Value = 'male' | 'female'; + +const OPTION_LIST: { title: string; value: Value }[] = [ + { title: '남성', value: 'male' }, + { title: '여성', value: 'female' }, +]; + +const Container = styled.div` + display: flex; + gap: 0.75rem; + + margin-top: 1.5rem; + margin-bottom: 1rem; +`; + +const Button = styled.button<{ $isSelected: boolean }>` + display: flex; + justify-content: center; + + width: 100%; + padding: 0.5rem; + background: transparent; + + border: 1px solid + ${({ theme, $isSelected }) => + $isSelected ? theme.colors.white : theme.colors.gray[600]}; + border-radius: 0.5rem; + + cursor: pointer; +`; + +const ButtonText = styled(Text)<{ $isSelected: boolean }>` + color: ${({ theme, $isSelected }) => + $isSelected ? theme.colors.white : theme.colors.gray[400]}; +`; + +export default function GenderInput() { + const [value, setValue] = useState(null); + + return ( + + {OPTION_LIST.map((option) => { + const isSelected = value === option.value; + return ( + + ); + })} + + ); +} diff --git a/src/app/(beforeLogin)/_components/InputList.tsx b/src/app/(beforeLogin)/_components/InputList.tsx new file mode 100644 index 0000000..5d12fb1 --- /dev/null +++ b/src/app/(beforeLogin)/_components/InputList.tsx @@ -0,0 +1,48 @@ +import styled from 'styled-components'; +import EmailIcon from '@/assets/EmailIcon'; +import PasswordIcon from '@/assets/PasswordIcon'; + +const Container = styled.div` + display: flex; + flex-direction: column; + gap: 1rem; + width: 100%; +`; + +const InputContainer = styled.div` + display: flex; + align-items: center; + gap: 1rem; + + padding: 0.5rem 1rem; + background: ${({ theme }) => theme.colors.gray[900]}; + border-radius: 0.5rem; +`; + +const Input = styled.input` + flex: 1; + + background: transparent; + border: none; + outline: none; + + font-size: ${({ theme }) => theme.typography.body2_rg.fontSize}; + font-weight: ${({ theme }) => theme.typography.body2_rg.fontWeight}; + line-height: ${({ theme }) => theme.typography.body2_rg.lineHeight}; + color: ${({ theme }) => theme.colors.white}; +`; + +export default function InputList() { + return ( + + + + + + + + + + + ); +} diff --git a/src/app/(beforeLogin)/_components/Main.tsx b/src/app/(beforeLogin)/_components/Main.tsx new file mode 100644 index 0000000..b1b67a5 --- /dev/null +++ b/src/app/(beforeLogin)/_components/Main.tsx @@ -0,0 +1,47 @@ +"use client"; + +import CTAButton from "@/components/atoms/CTAButton"; +import Text from "@/components/atoms/Text"; +import TNB from "@/components/TNB"; +import { + AccountSection, + ButtonWrapper, + DivideLine, + UserSection, +} from "./styles"; +import EmailInput from "./EmailInput"; +import PasswordInput from "./PasswordInput"; +import PhoneInput from "./PhoneInput"; +import GenderInput from "./GenderInput"; +import UnivInput from "./UnivInput"; +import NameInput from "./NameInput"; + +export default function Main() { + return ( +
+ + +
+ + 계정 정보 + + + + + + + + 회원 정보 + + + + + + + + + + +
+ ); +} diff --git a/src/app/(beforeLogin)/_components/NameInput.tsx b/src/app/(beforeLogin)/_components/NameInput.tsx new file mode 100644 index 0000000..319de6a --- /dev/null +++ b/src/app/(beforeLogin)/_components/NameInput.tsx @@ -0,0 +1,26 @@ +"use client"; + +import styled from "styled-components"; + +import { Input, InputContainer } from "@/styles/input"; +import PersonIcon from "@/assets/PersonIcon"; + +const Container = styled.div` + display: flex; + flex-direction: column; + gap: 0.25rem; + + margin-top: 1.5rem; + margin-bottom: 1rem; +`; + +export default function NameInput() { + return ( + + + + + + + ); +} diff --git a/src/app/(beforeLogin)/_components/PasswordInput.tsx b/src/app/(beforeLogin)/_components/PasswordInput.tsx new file mode 100644 index 0000000..5f369e9 --- /dev/null +++ b/src/app/(beforeLogin)/_components/PasswordInput.tsx @@ -0,0 +1,33 @@ +"use client"; + +import styled from "styled-components"; + +import PasswordIcon from "@/assets/PasswordIcon"; +import PasswordConfirmIcon from "@/assets/PasswordConfirmIcon"; +import { Input, InputContainer } from "@/styles/input"; + +const Container = styled.div` + display: flex; + flex-direction: column; + gap: 1rem; + + margin-top: 1.5rem; + margin-bottom: 1.5rem; + width: 100%; +`; + +export default function PasswordInput() { + return ( + + + + + + + + + + + + ); +} diff --git a/src/app/(beforeLogin)/_components/PhoneInput.tsx b/src/app/(beforeLogin)/_components/PhoneInput.tsx new file mode 100644 index 0000000..2780847 --- /dev/null +++ b/src/app/(beforeLogin)/_components/PhoneInput.tsx @@ -0,0 +1,32 @@ +"use client"; + +import styled from "styled-components"; + +import { Input, InputContainer } from "@/styles/input"; +import PhoneIcon from "@/assets/PhoneIcon"; +import Text from "@/components/atoms/Text"; + +const Container = styled.div` + display: flex; + flex-direction: column; + gap: 0.25rem; + + margin-bottom: 1rem; +`; + +const Message = styled(Text)` + padding-left: 1rem; + color: ${({ theme }) => theme.colors.gray[400]}; +`; + +export default function PhoneInput() { + return ( + + + + + + {`'-' 없이 입력해주세요`} + + ); +} diff --git a/src/app/(beforeLogin)/_components/Tabs.tsx b/src/app/(beforeLogin)/_components/Tabs.tsx new file mode 100644 index 0000000..bda9076 --- /dev/null +++ b/src/app/(beforeLogin)/_components/Tabs.tsx @@ -0,0 +1,75 @@ +import { ReactNode, useState } from 'react'; +import styled from 'styled-components'; +import Text from '@/components/atoms/Text'; +import SignInForm from './Form'; + +type TabType = 'customer' | 'photographer'; + +const Wrapper = styled.div` + display: flex; + flex-direction: column; + align-items: center; + + height: 100%; +`; + +const TabHeaderWrapper = styled.div` + display: flex; + width: 100%; + padding: 0 1.25rem; + border: 1px solid black; +`; +const TabHeader = styled.button` + flex: 1; + background: transparent; + padding: 0.625rem 0; + border: 1px solid ${({ theme }) => theme.colors.gray[100]}; + text-align: center; +`; +const SelectedTabHeader = styled(TabHeader)` + border-bottom-color: transparent; + border-top-left-radius: 0.5rem; + border-top-right-radius: 0.5rem; +`; +const UnSelectedTabHeader = styled(TabHeader)` + border-color: transparent; + border-bottom-color: ${({ theme }) => theme.colors.gray[100]}; +`; +const UnSelectedText = styled(Text)` + color: ${({ theme }) => theme.colors.gray[300]}; +`; + +export default function Tabs() { + const [currentTab, setCurrentTab] = useState('customer'); + const tabList: { id: TabType; title: string; content: ReactNode }[] = [ + { id: 'customer', title: '일반 로그인', content: }, + { id: 'photographer', title: '작가 로그인', content: }, + ]; + + function onChangeTab(tabId: TabType) { + setCurrentTab(tabId); + } + + return ( + + + {tabList.map((tab) => + tab.id === currentTab ? ( + onChangeTab(tab.id)}> + {tab.title} + + ) : ( + onChangeTab(tab.id)} + > + {tab.title} + + ), + )} + + + {tabList.find((tab) => tab.id === currentTab)!.content} + + ); +} diff --git a/src/app/(beforeLogin)/_components/UnivInput.tsx b/src/app/(beforeLogin)/_components/UnivInput.tsx new file mode 100644 index 0000000..57856a4 --- /dev/null +++ b/src/app/(beforeLogin)/_components/UnivInput.tsx @@ -0,0 +1,120 @@ +import { useRef, useState } from 'react'; +import styled from 'styled-components'; +import DownChevronIcon from '@/assets/DownChevronIcon'; +import Text from '@/components/atoms/Text'; + +export interface Option { + value: string; + label: string; +} + +const Container = styled.div<{ $isOpen: boolean }>` + display: flex; + align-items: center; + justify-content: space-between; + gap: 0.125rem; + + padding: 0.5rem 1rem; + background: transparent; + border: 1px solid ${({ theme }) => theme.colors.gray[200]}; + border-radius: ${({ $isOpen }) => ($isOpen ? '0.5rem 0.5rem 0 0' : '0.5rem')}; +`; + +const FilterText = styled(Text)` + color: ${({ theme }) => theme.colors.gray[200]}; +`; + +const Backdrop = styled.div` + position: fixed; + top: 0; + left: 0; + background: transparent; + width: 100%; + height: 100%; + + z-index: 20; // 임의로 설정 +`; + +const OptionWrapper = styled.div` + position: absolute; + display: flex; + flex-direction: column; + align-items: flex-start; + + width: 100%; + background: ${({ theme }) => theme.colors.background.primary}; + border: 1px solid ${({ theme }) => theme.colors.gray[200]}; + border-top: none; + border-radius: 0 0 0.5rem 0.5rem; + + z-index: 21; // 임의로 설정 +`; +const OptionItem = styled.button` + width: 100%; + padding: 0.5rem 1rem; + + background: transparent; + border: none; + outline: none; + + text-align: start; + + cursor: pointer; +`; + +type Value = 'sogang' | 'yonsei' | 'ewha' | 'hongik'; + +const OPTION_LIST: { label: string; value: Value }[] = [ + { label: '서강대학교', value: 'sogang' }, + { label: '연세대학교', value: 'yonsei' }, + { label: '이화여자대학교', value: 'ewha' }, + { label: '홍익대학교', value: 'hongik' }, +]; + +export default function UnivInput() { + const [value, setValue] = useState(null); + const [isOpen, setIsOpen] = useState(false); + const selectorRef = useRef(null); + const optionRef = useRef(null); + + const onOpen = () => { + setIsOpen(true); + }; + const onClose = () => { + setIsOpen(false); + }; + + const currentLabel = OPTION_LIST.find( + (option) => option.value === value, + )?.label; + + return ( +
+ + + {currentLabel || '학교 선택'} + + + + + {isOpen && ( + <> + + + {OPTION_LIST.map((option) => ( + { + setValue(option.value); + onClose(); + }} + > + {option.label} + + ))} + + + )} +
+ ); +} diff --git a/src/app/(beforeLogin)/_components/styles.ts b/src/app/(beforeLogin)/_components/styles.ts new file mode 100644 index 0000000..8ae7ff3 --- /dev/null +++ b/src/app/(beforeLogin)/_components/styles.ts @@ -0,0 +1,24 @@ +import styled from "styled-components"; + +const Section = styled.section` + padding-left: 1.25rem; + padding-right: 1.25rem; +`; + +export const AccountSection = styled(Section)` + padding-top: 2.5rem; + padding-bottom: 3rem; +`; + +export const UserSection = styled(Section)` + padding-top: 3rem; + padding-bottom: 4rem; +`; + +export const ButtonWrapper = styled.div` + padding: 0 1.25rem 1rem 1.25rem; +`; + +export const DivideLine = styled.div` + border-bottom: 1px solid ${({ theme }) => theme.colors.gray[800]}; +`; diff --git a/src/app/(beforeLogin)/i/flow/login/page.tsx b/src/app/(beforeLogin)/i/flow/login/page.tsx new file mode 100644 index 0000000..755f0b3 --- /dev/null +++ b/src/app/(beforeLogin)/i/flow/login/page.tsx @@ -0,0 +1,7 @@ +import LoginModal from "@/app/(beforeLogin)/_component/LoginModal"; + +export default function Page() { + return ( + + ); +} \ No newline at end of file diff --git a/src/app/(beforeLogin)/i/flow/signup/page.tsx b/src/app/(beforeLogin)/i/flow/signup/page.tsx new file mode 100644 index 0000000..ac7372a --- /dev/null +++ b/src/app/(beforeLogin)/i/flow/signup/page.tsx @@ -0,0 +1,7 @@ +import SignupModal from "@/app/(beforeLogin)/_component/SignupModal"; + +export default function Signup() { + return ( + + ) +} diff --git a/src/app/(beforeLogin)/page.tsx b/src/app/(beforeLogin)/page.tsx new file mode 100644 index 0000000..b294317 --- /dev/null +++ b/src/app/(beforeLogin)/page.tsx @@ -0,0 +1,16 @@ +import styles from "@/app/(beforeLogin)/_component/main.module.css"; + +import { redirect } from "next/navigation"; +import Main from "./_components/Main"; +import { getSession } from "@/lib/session"; +export default async function Home() { + // 로그인 페이지로 리다이렉트 + const session = await getSession(); + + // 유저가 있으면 홈으로 리다이렉트 (after login 상태) + if (session?.user) { + redirect("/home"); + return null; + } + return
; +} diff --git a/src/app/(beforeLogin)/signin/page.tsx b/src/app/(beforeLogin)/signin/page.tsx new file mode 100644 index 0000000..9f25ce8 --- /dev/null +++ b/src/app/(beforeLogin)/signin/page.tsx @@ -0,0 +1,17 @@ +"use client"; + +import { useRouter } from "next/navigation"; +import Main from "../_components/Main"; +import { useSession } from "next-auth/react"; + +export default function Login() { + const router = useRouter(); + const { data: session } = useSession(); + + if (session?.user) { + router.replace("/home"); + return null; + } + router.replace("/i/flow/login"); + return
; +} diff --git a/src/app/(beforeLogin)/signup/page.tsx b/src/app/(beforeLogin)/signup/page.tsx new file mode 100644 index 0000000..e64008d --- /dev/null +++ b/src/app/(beforeLogin)/signup/page.tsx @@ -0,0 +1,47 @@ +"use client"; + +import CTAButton from "@/components/atoms/CTAButton"; +import Text from "@/components/atoms/Text"; +import TNB from "@/components/TNB"; +import { + AccountSection, + ButtonWrapper, + DivideLine, + UserSection, +} from "./styles"; +import EmailInput from "../_components/EmailInput"; +import PasswordInput from "../_components/PasswordInput"; +import PhoneInput from "../_components/PhoneInput"; +import GenderInput from "../_components/GenderInput"; +import UnivInput from "../_components/UnivInput"; +import NameInput from "../_components/NameInput"; + +export default function SignUpPage() { + return ( +
+ + +
+ + 계정 정보 + + + + + + + + 회원 정보 + + + + + + + + + + +
+ ); +} diff --git a/src/app/(beforeLogin)/signup/styles.ts b/src/app/(beforeLogin)/signup/styles.ts new file mode 100644 index 0000000..8b69ba3 --- /dev/null +++ b/src/app/(beforeLogin)/signup/styles.ts @@ -0,0 +1,24 @@ +import styled from 'styled-components'; + +const Section = styled.section` + padding-left: 1.25rem; + padding-right: 1.25rem; +`; + +export const AccountSection = styled(Section)` + padding-top: 2.5rem; + padding-bottom: 3rem; +`; + +export const UserSection = styled(Section)` + padding-top: 3rem; + padding-bottom: 4rem; +`; + +export const ButtonWrapper = styled.div` + padding: 0 1.25rem 1rem 1.25rem; +`; + +export const DivideLine = styled.div` + border-bottom: 1px solid ${({ theme }) => theme.colors.gray[800]}; +`; From 70d03eac07335859edcf14a6f860e66f90e9071c Mon Sep 17 00:00:00 2001 From: hiwon-lee <84234411+hiwon-lee@users.noreply.github.com> Date: Thu, 26 Dec 2024 17:40:41 +0900 Subject: [PATCH 04/30] =?UTF-8?q?=E2=9C=A8=20feat:=20=20=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EC=BB=B4=ED=8D=BC=EB=84=8C=ED=8A=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_components}/BNB/index.tsx | 34 ++++++------- .../_components}/BNB/styles.ts | 8 +-- src/app/_components/ScreenWrapper/index.tsx | 13 +++++ .../_components}/ScreenWrapper/styles.ts | 4 +- .../_components}/TNB/Back.tsx | 12 ++--- .../_components}/TNB/Main.tsx | 4 +- .../_components}/TNB/SubTitle.tsx | 4 +- .../_components}/TNB/Title.tsx | 4 +- .../_components}/TNB/index.tsx | 0 .../_components}/TNB/styles.tsx | 0 .../_components}/atoms/CTAButton/index.tsx | 10 ++-- .../_components}/atoms/Tag/index.tsx | 10 ++-- .../_components}/atoms/Text/index.tsx | 0 src/assets/bnb/BNBProfileIcon.tsx | 20 -------- src/assets/bnb/BNB_CalendarIcon.tsx | 20 -------- src/assets/bnb/BNB_HomeIcon.tsx | 16 ------ src/assets/bnb/BNB_MapIcon.tsx | 16 ------ src/assets/bnb/BNB_PhotographerIcon.tsx | 20 -------- src/components/Card/card.css | 28 ----------- src/components/Card/index.tsx | 50 ------------------- src/components/ScreenWrapper/index.tsx | 17 ------- src/components/atoms/MediumButton/index.tsx | 34 ------------- src/components/atoms/SmallButton/Primary.tsx | 33 ------------ .../atoms/SmallButton/Secondary.tsx | 21 -------- src/components/atoms/SmallButton/Tertiary.tsx | 26 ---------- src/components/atoms/SmallButton/index.tsx | 11 ---- src/components/atoms/SmallButton/styles.tsx | 13 ----- 27 files changed, 58 insertions(+), 370 deletions(-) rename src/{components => app/_components}/BNB/index.tsx (55%) rename src/{components => app/_components}/BNB/styles.ts (81%) create mode 100644 src/app/_components/ScreenWrapper/index.tsx rename src/{components => app/_components}/ScreenWrapper/styles.ts (71%) rename src/{components => app/_components}/TNB/Back.tsx (66%) rename src/{components => app/_components}/TNB/Main.tsx (69%) rename src/{components => app/_components}/TNB/SubTitle.tsx (67%) rename src/{components => app/_components}/TNB/Title.tsx (67%) rename src/{components => app/_components}/TNB/index.tsx (100%) rename src/{components => app/_components}/TNB/styles.tsx (100%) rename src/{components => app/_components}/atoms/CTAButton/index.tsx (83%) rename src/{components => app/_components}/atoms/Tag/index.tsx (75%) rename src/{components => app/_components}/atoms/Text/index.tsx (100%) delete mode 100644 src/assets/bnb/BNBProfileIcon.tsx delete mode 100644 src/assets/bnb/BNB_CalendarIcon.tsx delete mode 100644 src/assets/bnb/BNB_HomeIcon.tsx delete mode 100644 src/assets/bnb/BNB_MapIcon.tsx delete mode 100644 src/assets/bnb/BNB_PhotographerIcon.tsx delete mode 100644 src/components/Card/card.css delete mode 100644 src/components/Card/index.tsx delete mode 100644 src/components/ScreenWrapper/index.tsx delete mode 100644 src/components/atoms/MediumButton/index.tsx delete mode 100644 src/components/atoms/SmallButton/Primary.tsx delete mode 100644 src/components/atoms/SmallButton/Secondary.tsx delete mode 100644 src/components/atoms/SmallButton/Tertiary.tsx delete mode 100644 src/components/atoms/SmallButton/index.tsx delete mode 100644 src/components/atoms/SmallButton/styles.tsx diff --git a/src/components/BNB/index.tsx b/src/app/_components/BNB/index.tsx similarity index 55% rename from src/components/BNB/index.tsx rename to src/app/_components/BNB/index.tsx index f896c01..4345bad 100644 --- a/src/components/BNB/index.tsx +++ b/src/app/_components/BNB/index.tsx @@ -1,22 +1,22 @@ -'use client'; +"use client"; -import { usePathname } from 'next/navigation'; +import { usePathname } from "next/navigation"; -import theme from '@/styles/theme'; -import BNBPhotographerIcon from '@/assets/bnb/BNB_PhotographerIcon'; -import BNBMapIcon from '@/assets/bnb/BNB_MapIcon'; -import BNBHomeIcon from '@/assets/bnb/BNB_HomeIcon'; -import BNBCalendarIcon from '@/assets/bnb/BNB_CalendarIcon'; -import BNBProfileIcon from '@/assets/bnb/BNBProfileIcon'; -import { Container, Tab, TabText } from './styles'; +import theme from "@/styles/theme"; +import BNBPhotographerIcon from "@/assets/bnb/BNB_PhotographerIcon"; +import BNBMapIcon from "@/assets/bnb/BNB_MapIcon"; +import BNBHomeIcon from "@/assets/bnb/BNB_HomeIcon"; +import BNBCalendarIcon from "@/assets/bnb/BNB_CalendarIcon"; +import BNBProfileIcon from "@/assets/bnb/BNBProfileIcon"; +import { Container, Tab, TabText } from "./styles"; // 고객 뷰일 경우 const MENU_LIST = [ - { title: '사진작가', route: '/photographer', icon: BNBPhotographerIcon }, - { title: '포토스팟', route: '/map', icon: BNBMapIcon }, - { title: '홈', route: '/', icon: BNBHomeIcon }, - { title: '예약', route: '/book', icon: BNBCalendarIcon }, - { title: '마이페이지', route: '/my', icon: BNBProfileIcon }, + { title: "사진작가", route: "/photographer", icon: BNBPhotographerIcon }, + { title: "포토스팟", route: "/map", icon: BNBMapIcon }, + { title: "홈", route: "/", icon: BNBHomeIcon }, + { title: "예약", route: "/book", icon: BNBCalendarIcon }, + { title: "마이페이지", route: "/my", icon: BNBProfileIcon }, ]; // [todo] 이후 고객/작가 구분하게 될 때 활성화하기 @@ -32,9 +32,9 @@ export default function BottomNavigationBar() { const pathname = usePathname(); if ( - pathname === '/splash' || - pathname === '/onboarding' || - pathname === '/signin' + pathname === "/splash" || + pathname === "/onboarding" || + pathname === "/signin" ) { return null; } diff --git a/src/components/BNB/styles.ts b/src/app/_components/BNB/styles.ts similarity index 81% rename from src/components/BNB/styles.ts rename to src/app/_components/BNB/styles.ts index 736f2c9..26aac00 100644 --- a/src/components/BNB/styles.ts +++ b/src/app/_components/BNB/styles.ts @@ -1,7 +1,7 @@ -import Link from 'next/link'; -import styled from 'styled-components'; -import BREAK_POINT from '@/styles/constants'; -import Text from '../atoms/Text'; +import Link from "next/link"; +import styled from "styled-components"; +import BREAK_POINT from "@/styles/constants"; +import Text from "../atoms/Text"; export const Container = styled.nav` position: fixed; diff --git a/src/app/_components/ScreenWrapper/index.tsx b/src/app/_components/ScreenWrapper/index.tsx new file mode 100644 index 0000000..55cfb2e --- /dev/null +++ b/src/app/_components/ScreenWrapper/index.tsx @@ -0,0 +1,13 @@ +"use client"; + +import { ReactNode } from "react"; + +import { Container, FullPage } from "./styles"; + +export default function ScreenWrapper({ children }: { children: ReactNode }) { + return ( + + {children} + + ); +} diff --git a/src/components/ScreenWrapper/styles.ts b/src/app/_components/ScreenWrapper/styles.ts similarity index 71% rename from src/components/ScreenWrapper/styles.ts rename to src/app/_components/ScreenWrapper/styles.ts index 1078e59..ca28947 100644 --- a/src/components/ScreenWrapper/styles.ts +++ b/src/app/_components/ScreenWrapper/styles.ts @@ -1,5 +1,5 @@ -import BREAK_POINT from '@/styles/constants'; -import styled from 'styled-components'; +import BREAK_POINT from "@/styles/constants"; +import styled from "styled-components"; export const FullPage = styled.div` height: 100dvh; diff --git a/src/components/TNB/Back.tsx b/src/app/_components/TNB/Back.tsx similarity index 66% rename from src/components/TNB/Back.tsx rename to src/app/_components/TNB/Back.tsx index c904bf7..a02d7a0 100644 --- a/src/components/TNB/Back.tsx +++ b/src/app/_components/TNB/Back.tsx @@ -1,9 +1,9 @@ -import { useCallback } from 'react'; -import { useRouter } from 'next/navigation'; -import styled from 'styled-components'; -import Text from '@/components/atoms/Text'; -import LeftChevronIcon from '@/assets/LeftChevronIcon'; -import { BorderedHeader } from './styles'; +import { useCallback } from "react"; +import { useRouter } from "next/navigation"; +import styled from "styled-components"; +import Text from "@/app/_components/atoms/Text"; +import LeftChevronIcon from "@/assets/LeftChevronIcon"; +import { BorderedHeader } from "./styles"; const IconWrapper = styled.button` position: absolute; diff --git a/src/components/TNB/Main.tsx b/src/app/_components/TNB/Main.tsx similarity index 69% rename from src/components/TNB/Main.tsx rename to src/app/_components/TNB/Main.tsx index a22d21d..25db24b 100644 --- a/src/components/TNB/Main.tsx +++ b/src/app/_components/TNB/Main.tsx @@ -1,5 +1,5 @@ -import Text from '@/components/atoms/Text'; -import { Header } from './styles'; +import Text from "@/app/_components/atoms/Text"; +import { Header } from "./styles"; // [todo] 로고가 생기면 로고로 교체해주세요~ export default function Main() { diff --git a/src/components/TNB/SubTitle.tsx b/src/app/_components/TNB/SubTitle.tsx similarity index 67% rename from src/components/TNB/SubTitle.tsx rename to src/app/_components/TNB/SubTitle.tsx index 97f04ce..2ae6cfc 100644 --- a/src/components/TNB/SubTitle.tsx +++ b/src/app/_components/TNB/SubTitle.tsx @@ -1,5 +1,5 @@ -import Text from '@/components/atoms/Text'; -import { BorderedHeader } from './styles'; +import Text from "@/app/_components/atoms/Text"; +import { BorderedHeader } from "./styles"; export default function SubTitle({ text }: { text: string }) { return ( diff --git a/src/components/TNB/Title.tsx b/src/app/_components/TNB/Title.tsx similarity index 67% rename from src/components/TNB/Title.tsx rename to src/app/_components/TNB/Title.tsx index 5c62b04..8427623 100644 --- a/src/components/TNB/Title.tsx +++ b/src/app/_components/TNB/Title.tsx @@ -1,5 +1,5 @@ -import Text from '@/components/atoms/Text'; -import { Header } from './styles'; +import Text from "@/app/_components/atoms/Text"; +import { Header } from "./styles"; export default function Title({ text }: { text: string }) { return ( diff --git a/src/components/TNB/index.tsx b/src/app/_components/TNB/index.tsx similarity index 100% rename from src/components/TNB/index.tsx rename to src/app/_components/TNB/index.tsx diff --git a/src/components/TNB/styles.tsx b/src/app/_components/TNB/styles.tsx similarity index 100% rename from src/components/TNB/styles.tsx rename to src/app/_components/TNB/styles.tsx diff --git a/src/components/atoms/CTAButton/index.tsx b/src/app/_components/atoms/CTAButton/index.tsx similarity index 83% rename from src/components/atoms/CTAButton/index.tsx rename to src/app/_components/atoms/CTAButton/index.tsx index ffeff4e..0ded0ec 100644 --- a/src/components/atoms/CTAButton/index.tsx +++ b/src/app/_components/atoms/CTAButton/index.tsx @@ -1,7 +1,7 @@ -import styled, { DefaultTheme } from 'styled-components'; -import Text from '@/components/atoms/Text'; +import styled, { DefaultTheme } from "styled-components"; +import Text from "@/app/_components/atoms/Text"; -type Variant = 'primary' | 'secondary'; +type Variant = "primary" | "secondary"; const getBackgroundColor = ({ theme, @@ -15,7 +15,7 @@ const getBackgroundColor = ({ if (disabled) { return theme.colors.gray[600]; } - if (variant === 'primary') { + if (variant === "primary") { return theme.colors.primary[100]; } return theme.colors.gray[900]; @@ -39,7 +39,7 @@ const ButtonText = styled(Text)` export default function CTAButton({ text, - variant = 'primary', + variant = "primary", disabled = false, onClick = () => {}, }: { diff --git a/src/components/atoms/Tag/index.tsx b/src/app/_components/atoms/Tag/index.tsx similarity index 75% rename from src/components/atoms/Tag/index.tsx rename to src/app/_components/atoms/Tag/index.tsx index 5751a03..282008f 100644 --- a/src/components/atoms/Tag/index.tsx +++ b/src/app/_components/atoms/Tag/index.tsx @@ -1,13 +1,13 @@ -import styled from 'styled-components'; -import Text from '@/components/atoms/Text'; +import styled from "styled-components"; +import Text from "@/app/_components/atoms/Text"; -type Variant = 'primary' | 'secondary'; +type Variant = "primary" | "secondary"; const TagContainer = styled.div<{ variant: Variant }>` width: fit-content; padding: 0.375rem 1rem; background: ${({ theme, variant }) => - variant === 'primary' ? theme.colors.gray[100] : theme.colors.gray[900]}; + variant === "primary" ? theme.colors.gray[100] : theme.colors.gray[900]}; border-radius: 1.5rem; `; @@ -28,7 +28,7 @@ export default function Tag({ }) { return ( - {variant === 'primary' ? ( + {variant === "primary" ? ( {text} ) : ( {text} diff --git a/src/components/atoms/Text/index.tsx b/src/app/_components/atoms/Text/index.tsx similarity index 100% rename from src/components/atoms/Text/index.tsx rename to src/app/_components/atoms/Text/index.tsx diff --git a/src/assets/bnb/BNBProfileIcon.tsx b/src/assets/bnb/BNBProfileIcon.tsx deleted file mode 100644 index 3009eb8..0000000 --- a/src/assets/bnb/BNBProfileIcon.tsx +++ /dev/null @@ -1,20 +0,0 @@ -export default function BNBProfileIcon({ - color = '#8C8C8C', -}: { - color: string; -}) { - return ( - - - - ); -} diff --git a/src/assets/bnb/BNB_CalendarIcon.tsx b/src/assets/bnb/BNB_CalendarIcon.tsx deleted file mode 100644 index 043879e..0000000 --- a/src/assets/bnb/BNB_CalendarIcon.tsx +++ /dev/null @@ -1,20 +0,0 @@ -export default function BNBCalendarIcon({ - color = '#8C8C8C', -}: { - color: string; -}) { - return ( - - - - ); -} diff --git a/src/assets/bnb/BNB_HomeIcon.tsx b/src/assets/bnb/BNB_HomeIcon.tsx deleted file mode 100644 index 8fb8556..0000000 --- a/src/assets/bnb/BNB_HomeIcon.tsx +++ /dev/null @@ -1,16 +0,0 @@ -export default function BNBHomeIcon({ color = '#8C8C8C' }: { color: string }) { - return ( - - - - ); -} diff --git a/src/assets/bnb/BNB_MapIcon.tsx b/src/assets/bnb/BNB_MapIcon.tsx deleted file mode 100644 index 419cd86..0000000 --- a/src/assets/bnb/BNB_MapIcon.tsx +++ /dev/null @@ -1,16 +0,0 @@ -export default function BNBMapIcon({ color = '#8C8C8C' }: { color: string }) { - return ( - - - - ); -} diff --git a/src/assets/bnb/BNB_PhotographerIcon.tsx b/src/assets/bnb/BNB_PhotographerIcon.tsx deleted file mode 100644 index 7d64a8e..0000000 --- a/src/assets/bnb/BNB_PhotographerIcon.tsx +++ /dev/null @@ -1,20 +0,0 @@ -export default function BNBPhotographerIcon({ - color = '#8C8C8C', -}: { - color: string; -}) { - return ( - - - - ); -} diff --git a/src/components/Card/card.css b/src/components/Card/card.css deleted file mode 100644 index c5f7d6d..0000000 --- a/src/components/Card/card.css +++ /dev/null @@ -1,28 +0,0 @@ -/* 버튼 크기 */ -.card.small { - img { - width: 7.5rem; - height: 7.5rem; - } -} - -.card.medium { - img { - width: 10.625rem; - height: 10.625rem; - } -} - -/* todo : 크기 수정해야함 */ -.card.large { - font-size: 16px; - padding: 12px 20px; -} - -/* todo : masonry에 들어갈 동적 크기 card */ -.card.dynamic { - img { - width: 100%; - height: auto; - } -} diff --git a/src/components/Card/index.tsx b/src/components/Card/index.tsx deleted file mode 100644 index c7e3b24..0000000 --- a/src/components/Card/index.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import React from 'react'; -import styled from 'styled-components'; -import Text from '../atoms/Text'; - -import './card.css'; - -export interface CardProps { - /** How large should the card be? */ - size?: 'small' | 'medium' | 'large' | 'dynamic'; - /** What card image to use */ - src: string; - /** Card Title */ - title?: string; - /** Card Content */ - content?: string; - /** Optional click handler */ - onClick?: () => void; -} - -const CardWrapper = styled.div` - display: flex; - flex-direction: column; - cursor: pointer; -`; - -const CardImage = styled.img` - object-fit: cover; - margin-bottom: 0.5rem; - border-radius: 0.125rem; -`; - -const CardContent = styled(Text)` - color: ${({ theme }) => theme.colors.gray[200]}; -`; - -export default function Card({ - size, - src, - title, - content, - onClick, -}: CardProps) { - return ( - - - {title} - {content} - - ); -} diff --git a/src/components/ScreenWrapper/index.tsx b/src/components/ScreenWrapper/index.tsx deleted file mode 100644 index e7f30cb..0000000 --- a/src/components/ScreenWrapper/index.tsx +++ /dev/null @@ -1,17 +0,0 @@ -'use client'; - -import { ReactNode } from 'react'; - -import BottomNavigationBar from '@/components/BNB'; -import { Container, FullPage } from './styles'; - -export default function ScreenWrapper({ children }: { children: ReactNode }) { - return ( - - - {children} - - - - ); -} diff --git a/src/components/atoms/MediumButton/index.tsx b/src/components/atoms/MediumButton/index.tsx deleted file mode 100644 index 02dcba9..0000000 --- a/src/components/atoms/MediumButton/index.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import styled from 'styled-components'; -import Text from '@/components/atoms/Text'; - -type Variant = 'primary' | 'secondary'; - -const Button = styled.button<{ variant: Variant }>` - padding: 0.688rem 1.25rem; - background: ${({ theme, variant }) => - variant === 'primary' ? theme.colors.primary[100] : theme.colors.gray[900]}; - - outline: none; - border: none; - border-radius: 1.5rem; - - cursor: pointer; -`; - -export default function MediumButton({ - text, - variant = 'primary', - onClick = () => {}, -}: { - text: string; - variant?: Variant; - onClick?: () => void; -}) { - return ( - - ); -} diff --git a/src/components/atoms/SmallButton/Primary.tsx b/src/components/atoms/SmallButton/Primary.tsx deleted file mode 100644 index c66cc0d..0000000 --- a/src/components/atoms/SmallButton/Primary.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import styled from 'styled-components'; -import Text from '@/components/atoms/Text'; -import Button from './styles'; - -const PrimaryButton = styled(Button)<{ disabled: boolean }>` - background: ${({ theme, disabled }) => - disabled ? theme.colors.gray[600] : theme.colors.primary[100]}; - cursor: ${({ disabled }) => (disabled ? 'auto' : 'cursor')}; -`; - -const DisabledText = styled(Text)` - color: ${({ theme }) => theme.colors.gray[200]}; -`; - -export default function Primary({ - text, - disabled = false, - onClick = () => {}, -}: { - text: string; - disabled?: boolean; - onClick?: () => void; -}) { - return ( - - {disabled ? ( - {text} - ) : ( - {text} - )} - - ); -} diff --git a/src/components/atoms/SmallButton/Secondary.tsx b/src/components/atoms/SmallButton/Secondary.tsx deleted file mode 100644 index 4838738..0000000 --- a/src/components/atoms/SmallButton/Secondary.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import styled from 'styled-components'; -import Text from '@/components/atoms/Text'; -import Button from './styles'; - -const SecondaryButton = styled(Button)` - background: ${({ theme }) => theme.colors.gray[900]}; -`; - -export default function Secondary({ - text, - onClick = () => {}, -}: { - text: string; - onClick?: () => void; -}) { - return ( - - {text} - - ); -} diff --git a/src/components/atoms/SmallButton/Tertiary.tsx b/src/components/atoms/SmallButton/Tertiary.tsx deleted file mode 100644 index f4f3660..0000000 --- a/src/components/atoms/SmallButton/Tertiary.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import styled from 'styled-components'; -import Text from '@/components/atoms/Text'; -import Button from './styles'; - -const TertiaryButton = styled(Button)` - background: transparent; - border: 1px solid ${({ theme }) => theme.colors.primary[100]}; -`; - -const ButtonText = styled(Text)` - color: ${({ theme }) => theme.colors.primary[100]}; -`; - -export default function Tertiary({ - text, - onClick = () => {}, -}: { - text: string; - onClick?: () => void; -}) { - return ( - - {text} - - ); -} diff --git a/src/components/atoms/SmallButton/index.tsx b/src/components/atoms/SmallButton/index.tsx deleted file mode 100644 index 28a6645..0000000 --- a/src/components/atoms/SmallButton/index.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import Primary from './Primary'; -import Secondary from './Secondary'; -import Tertiary from './Tertiary'; - -const SmallButton = { - Primary, - Secondary, - Tertiary, -}; - -export default SmallButton; diff --git a/src/components/atoms/SmallButton/styles.tsx b/src/components/atoms/SmallButton/styles.tsx deleted file mode 100644 index 5b10e56..0000000 --- a/src/components/atoms/SmallButton/styles.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import styled from 'styled-components'; - -const Button = styled.button` - padding: 0.438rem 1.25rem; - - outline: none; - border: none; - border-radius: 1.5rem; - - cursor: pointer; -`; - -export default Button; From b5890b48e2d01bc80a7e287b45ac54f57fe6101e Mon Sep 17 00:00:00 2001 From: hiwon-lee <84234411+hiwon-lee@users.noreply.github.com> Date: Thu, 26 Dec 2024 17:41:23 +0900 Subject: [PATCH 05/30] =?UTF-8?q?=F0=9F=93=9D=20docs:=20=20assets=EC=B6=94?= =?UTF-8?q?=EA=B0=80=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/ArrowRightIcon.tsx | 16 +++++++++++++++ src/assets/CheckIcon.tsx | 16 +++++++++++++++ src/assets/CopyIcon.tsx | 28 +++++++++++++++++++++++++++ src/assets/CurrentReservationIcon.tsx | 16 +++++++++++++++ src/assets/DownChevronIcon copy.tsx | 16 +++++++++++++++ src/assets/EmailIcon copy.tsx | 16 +++++++++++++++ src/assets/InfoIcon.tsx | 16 +++++++++++++++ src/assets/LargeStarEmptyIcon.tsx | 18 +++++++++++++++++ src/assets/LargeStarIcon.tsx | 18 +++++++++++++++++ src/assets/LeftChevronIcon copy.tsx | 16 +++++++++++++++ src/assets/LocationIcon.tsx | 16 +++++++++++++++ src/assets/NotificationIcon.tsx | 16 +++++++++++++++ src/assets/PasswordConfirmIcon.tsx | 20 +++++++++++++++++++ src/assets/PasswordIcon copy.tsx | 16 +++++++++++++++ src/assets/PeopleIcon.tsx | 16 +++++++++++++++ src/assets/PersonIcon.tsx | 16 +++++++++++++++ src/assets/PhoneIcon.tsx | 16 +++++++++++++++ src/assets/PhotographerIcon.tsx | 16 +++++++++++++++ src/assets/PrevReservationIcon.tsx | 16 +++++++++++++++ src/assets/RightChevronIcon copy.tsx | 22 +++++++++++++++++++++ src/assets/SearchIcon copy.tsx | 16 +++++++++++++++ src/assets/TaskIcon.tsx | 16 +++++++++++++++ src/assets/TimeIcon.tsx | 18 +++++++++++++++++ 23 files changed, 396 insertions(+) create mode 100644 src/assets/ArrowRightIcon.tsx create mode 100644 src/assets/CheckIcon.tsx create mode 100644 src/assets/CopyIcon.tsx create mode 100644 src/assets/CurrentReservationIcon.tsx create mode 100644 src/assets/DownChevronIcon copy.tsx create mode 100644 src/assets/EmailIcon copy.tsx create mode 100644 src/assets/InfoIcon.tsx create mode 100644 src/assets/LargeStarEmptyIcon.tsx create mode 100644 src/assets/LargeStarIcon.tsx create mode 100644 src/assets/LeftChevronIcon copy.tsx create mode 100644 src/assets/LocationIcon.tsx create mode 100644 src/assets/NotificationIcon.tsx create mode 100644 src/assets/PasswordConfirmIcon.tsx create mode 100644 src/assets/PasswordIcon copy.tsx create mode 100644 src/assets/PeopleIcon.tsx create mode 100644 src/assets/PersonIcon.tsx create mode 100644 src/assets/PhoneIcon.tsx create mode 100644 src/assets/PhotographerIcon.tsx create mode 100644 src/assets/PrevReservationIcon.tsx create mode 100644 src/assets/RightChevronIcon copy.tsx create mode 100644 src/assets/SearchIcon copy.tsx create mode 100644 src/assets/TaskIcon.tsx create mode 100644 src/assets/TimeIcon.tsx diff --git a/src/assets/ArrowRightIcon.tsx b/src/assets/ArrowRightIcon.tsx new file mode 100644 index 0000000..3e30a5a --- /dev/null +++ b/src/assets/ArrowRightIcon.tsx @@ -0,0 +1,16 @@ +export default function ArrowRightIcon() { + return ( + + + + ); +} diff --git a/src/assets/CheckIcon.tsx b/src/assets/CheckIcon.tsx new file mode 100644 index 0000000..5b09460 --- /dev/null +++ b/src/assets/CheckIcon.tsx @@ -0,0 +1,16 @@ +export default function CheckIcon() { + return ( + + + + ); +} diff --git a/src/assets/CopyIcon.tsx b/src/assets/CopyIcon.tsx new file mode 100644 index 0000000..aecd825 --- /dev/null +++ b/src/assets/CopyIcon.tsx @@ -0,0 +1,28 @@ +export default function CopyIcon() { + return ( + + + + + + + + + ); +} diff --git a/src/assets/CurrentReservationIcon.tsx b/src/assets/CurrentReservationIcon.tsx new file mode 100644 index 0000000..cc754f5 --- /dev/null +++ b/src/assets/CurrentReservationIcon.tsx @@ -0,0 +1,16 @@ +export default function CurrentReservationIcon() { + return ( + + + + ); +} diff --git a/src/assets/DownChevronIcon copy.tsx b/src/assets/DownChevronIcon copy.tsx new file mode 100644 index 0000000..bba2925 --- /dev/null +++ b/src/assets/DownChevronIcon copy.tsx @@ -0,0 +1,16 @@ +export default function DownChevronIcon() { + return ( + + + + ); +} diff --git a/src/assets/EmailIcon copy.tsx b/src/assets/EmailIcon copy.tsx new file mode 100644 index 0000000..ad0491d --- /dev/null +++ b/src/assets/EmailIcon copy.tsx @@ -0,0 +1,16 @@ +export default function EmailIcon({ size }: { size: string }) { + return ( + + + + ); +} diff --git a/src/assets/InfoIcon.tsx b/src/assets/InfoIcon.tsx new file mode 100644 index 0000000..b72b852 --- /dev/null +++ b/src/assets/InfoIcon.tsx @@ -0,0 +1,16 @@ +export default function InfoIcon() { + return ( + + + + ); +} diff --git a/src/assets/LargeStarEmptyIcon.tsx b/src/assets/LargeStarEmptyIcon.tsx new file mode 100644 index 0000000..feee915 --- /dev/null +++ b/src/assets/LargeStarEmptyIcon.tsx @@ -0,0 +1,18 @@ +export default function LargeStarEmptyIcon() { + return ( + + + + ); +} diff --git a/src/assets/LargeStarIcon.tsx b/src/assets/LargeStarIcon.tsx new file mode 100644 index 0000000..49302ed --- /dev/null +++ b/src/assets/LargeStarIcon.tsx @@ -0,0 +1,18 @@ +export default function LargeStarIcon() { + return ( + + + + ); +} diff --git a/src/assets/LeftChevronIcon copy.tsx b/src/assets/LeftChevronIcon copy.tsx new file mode 100644 index 0000000..f3eed4e --- /dev/null +++ b/src/assets/LeftChevronIcon copy.tsx @@ -0,0 +1,16 @@ +export default function LeftChevronIcon() { + return ( + + + + ); +} diff --git a/src/assets/LocationIcon.tsx b/src/assets/LocationIcon.tsx new file mode 100644 index 0000000..24d5adb --- /dev/null +++ b/src/assets/LocationIcon.tsx @@ -0,0 +1,16 @@ +export default function LocationIcon() { + return ( + + + + ); +} diff --git a/src/assets/NotificationIcon.tsx b/src/assets/NotificationIcon.tsx new file mode 100644 index 0000000..075e0e8 --- /dev/null +++ b/src/assets/NotificationIcon.tsx @@ -0,0 +1,16 @@ +export default function NotificationIcon() { + return ( + + + + ); +} diff --git a/src/assets/PasswordConfirmIcon.tsx b/src/assets/PasswordConfirmIcon.tsx new file mode 100644 index 0000000..d9e13d4 --- /dev/null +++ b/src/assets/PasswordConfirmIcon.tsx @@ -0,0 +1,20 @@ +export default function PasswordConfirmIcon({ size }: { size: string }) { + return ( + + + + + ); +} diff --git a/src/assets/PasswordIcon copy.tsx b/src/assets/PasswordIcon copy.tsx new file mode 100644 index 0000000..535e296 --- /dev/null +++ b/src/assets/PasswordIcon copy.tsx @@ -0,0 +1,16 @@ +export default function PasswordIcon({ size }: { size: string }) { + return ( + + + + ); +} diff --git a/src/assets/PeopleIcon.tsx b/src/assets/PeopleIcon.tsx new file mode 100644 index 0000000..775bbeb --- /dev/null +++ b/src/assets/PeopleIcon.tsx @@ -0,0 +1,16 @@ +export default function PeopleIcon({ color = '#ffffff' }: { color?: string }) { + return ( + + + + ); +} diff --git a/src/assets/PersonIcon.tsx b/src/assets/PersonIcon.tsx new file mode 100644 index 0000000..48b0fb1 --- /dev/null +++ b/src/assets/PersonIcon.tsx @@ -0,0 +1,16 @@ +export default function PersonIcon() { + return ( + + + + ); +} diff --git a/src/assets/PhoneIcon.tsx b/src/assets/PhoneIcon.tsx new file mode 100644 index 0000000..15b0fde --- /dev/null +++ b/src/assets/PhoneIcon.tsx @@ -0,0 +1,16 @@ +export default function PhoneIcon({ size }: { size: string }) { + return ( + + + + ); +} diff --git a/src/assets/PhotographerIcon.tsx b/src/assets/PhotographerIcon.tsx new file mode 100644 index 0000000..5824136 --- /dev/null +++ b/src/assets/PhotographerIcon.tsx @@ -0,0 +1,16 @@ +export default function PhotographerIcon() { + return ( + + + + ); +} diff --git a/src/assets/PrevReservationIcon.tsx b/src/assets/PrevReservationIcon.tsx new file mode 100644 index 0000000..925dbbf --- /dev/null +++ b/src/assets/PrevReservationIcon.tsx @@ -0,0 +1,16 @@ +export default function PrevReservationIcon() { + return ( + + + + ); +} diff --git a/src/assets/RightChevronIcon copy.tsx b/src/assets/RightChevronIcon copy.tsx new file mode 100644 index 0000000..3ba0c95 --- /dev/null +++ b/src/assets/RightChevronIcon copy.tsx @@ -0,0 +1,22 @@ +export default function RightChevronIcon({ + size = '28px', + color = '#F5F5F5', +}: { + size?: string; + color?: string; +}) { + return ( + + + + ); +} diff --git a/src/assets/SearchIcon copy.tsx b/src/assets/SearchIcon copy.tsx new file mode 100644 index 0000000..338dc71 --- /dev/null +++ b/src/assets/SearchIcon copy.tsx @@ -0,0 +1,16 @@ +export default function SearchIcon({ size }: { size: string }) { + return ( + + + + ); +} diff --git a/src/assets/TaskIcon.tsx b/src/assets/TaskIcon.tsx new file mode 100644 index 0000000..ee0350c --- /dev/null +++ b/src/assets/TaskIcon.tsx @@ -0,0 +1,16 @@ +export default function TaskIcon() { + return ( + + + + ); +} diff --git a/src/assets/TimeIcon.tsx b/src/assets/TimeIcon.tsx new file mode 100644 index 0000000..6eeafb1 --- /dev/null +++ b/src/assets/TimeIcon.tsx @@ -0,0 +1,18 @@ +export default function TimeIcon() { + return ( + + + + ); +} From c362ca466ac8f048acb79bb946fe327ea372bb2d Mon Sep 17 00:00:00 2001 From: hiwon-lee <84234411+hiwon-lee@users.noreply.github.com> Date: Thu, 26 Dec 2024 17:42:11 +0900 Subject: [PATCH 06/30] =?UTF-8?q?=E2=9C=A8=20feat:=20=20route=EC=97=B0?= =?UTF-8?q?=EA=B2=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/api/auth/[...nextauth]/route.ts | 4 ++ src/auth.ts | 48 ++++++++++++++++++ src/lib/registry.tsx | 12 ++--- src/lib/session.ts | 6 +++ src/mocks/browser.ts | 7 +++ src/mocks/handlers.ts | 65 +++++++++++++++++++++++++ src/mocks/http.ts | 12 +++++ 7 files changed, 148 insertions(+), 6 deletions(-) create mode 100644 src/app/api/auth/[...nextauth]/route.ts create mode 100644 src/auth.ts create mode 100644 src/lib/session.ts create mode 100644 src/mocks/browser.ts create mode 100644 src/mocks/handlers.ts create mode 100644 src/mocks/http.ts diff --git a/src/app/api/auth/[...nextauth]/route.ts b/src/app/api/auth/[...nextauth]/route.ts new file mode 100644 index 0000000..4ccea33 --- /dev/null +++ b/src/app/api/auth/[...nextauth]/route.ts @@ -0,0 +1,4 @@ +import NextAuth from "next-auth"; +import { authOptions } from "@/auth"; + +export default NextAuth(authOptions); diff --git a/src/auth.ts b/src/auth.ts new file mode 100644 index 0000000..f69393b --- /dev/null +++ b/src/auth.ts @@ -0,0 +1,48 @@ +import CredentialsProvider from "next-auth/providers/credentials"; +import type { NextAuthOptions } from "next-auth"; + +export const authOptions: NextAuthOptions = { + pages: { + signIn: "/i/flow/login", + newUser: "/i/flow/signup", + }, + providers: [ + CredentialsProvider({ + credentials: { + username: { label: "Username", type: "text" }, + password: { label: "Password", type: "password" }, + }, + async authorize(credentials) { + if (!credentials) { + throw new Error("No credentials provided"); + } + + const authResponse = await fetch( + `${process.env.NEXT_PUBLIC_BASE_URL}/api/login`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + id: credentials.username, + password: credentials.password, + }), + }, + ); + + if (!authResponse.ok) { + throw new Error("Authentication failed"); + } + + const user = await authResponse.json(); + return { + email: user.id, + name: user.nickname, + image: user.image, + ...user, + }; + }, + }), + ], +}; diff --git a/src/lib/registry.tsx b/src/lib/registry.tsx index bb4ea04..4438537 100644 --- a/src/lib/registry.tsx +++ b/src/lib/registry.tsx @@ -1,14 +1,14 @@ -'use client'; +"use client"; -import React, { useState } from 'react'; -import { useServerInsertedHTML } from 'next/navigation'; +import React, { useState } from "react"; +import { useServerInsertedHTML } from "next/navigation"; import { createGlobalStyle, ServerStyleSheet, StyleSheetManager, ThemeProvider, -} from 'styled-components'; -import theme from '@/styles/theme'; +} from "styled-components"; +import theme from "@/styles/theme"; const GlobalStyle = createGlobalStyle` /* http://meyerweb.com/eric/tools/css/reset/ @@ -82,7 +82,7 @@ export default function StyledComponentsRegistry({ return styles; }); - if (typeof window !== 'undefined') + if (typeof window !== "undefined") return {children}; return ( diff --git a/src/lib/session.ts b/src/lib/session.ts new file mode 100644 index 0000000..86627eb --- /dev/null +++ b/src/lib/session.ts @@ -0,0 +1,6 @@ +import { getServerSession } from "next-auth"; +import { authOptions } from "@/auth"; + +export async function getSession() { + return await getServerSession(authOptions); +} diff --git a/src/mocks/browser.ts b/src/mocks/browser.ts new file mode 100644 index 0000000..783fea6 --- /dev/null +++ b/src/mocks/browser.ts @@ -0,0 +1,7 @@ +import { setupWorker } from 'msw/browser' +import { handlers } from './handlers' + +// This configures a Service Worker with the given request handlers. +const worker = setupWorker(...handlers) + +export default worker; \ No newline at end of file diff --git a/src/mocks/handlers.ts b/src/mocks/handlers.ts new file mode 100644 index 0000000..5672338 --- /dev/null +++ b/src/mocks/handlers.ts @@ -0,0 +1,65 @@ +import { http, HttpResponse, StrictResponse } from "msw"; +// import { faker } from "@faker-js/faker"; + +function generateDate() { + const lastWeek = new Date(Date.now()); + lastWeek.setDate(lastWeek.getDate() - 7); + // return faker.date.between({ + // from: lastWeek, + // to: Date.now(), + // }); +} +const User = [ + { id: "elonmusk", nickname: "Elon Musk", image: "/yRsRRjGO.jpg" }, + { id: "zerohch0", nickname: "제로초", image: "/5Udwvqim.jpg" }, + // { id: "leoturtle", nickname: "레오", image: faker.image.avatar() }, +]; +const Posts = []; +const delay = (ms: number) => + new Promise((res) => { + setTimeout(res, ms); + }); + +export const handlers = [ + http.post("/api/login", () => { + console.log("로그인"); + return HttpResponse.json(User[1], { + headers: { + "Set-Cookie": "connect.sid=msw-cookie;HttpOnly;Path=/", + }, + }); + }), + http.post("/api/logout", () => { + console.log("로그아웃"); + return new HttpResponse(null, { + headers: { + "Set-Cookie": "connect.sid=;HttpOnly;Path=/;Max-Age=0", + }, + }); + }), + http.post("/api/users", async ({ request }) => { + console.log("회원가입"); + // return HttpResponse.text(JSON.stringify('user_exists'), { + // status: 403, + // }) + return HttpResponse.text(JSON.stringify("ok"), { + headers: { + "Set-Cookie": "connect.sid=msw-cookie;HttpOnly;Path=/", + }, + }); + }), + + http.get("/api/users/:userId", ({ request, params }): StrictResponse => { + const { userId } = params; + const found = User.find((v) => v.id === userId); + if (found) { + return HttpResponse.json(found); + } + return HttpResponse.json( + { message: "no_such_user" }, + { + status: 404, + }, + ); + }), +]; diff --git a/src/mocks/http.ts b/src/mocks/http.ts new file mode 100644 index 0000000..1fef0c6 --- /dev/null +++ b/src/mocks/http.ts @@ -0,0 +1,12 @@ +import { createMiddleware } from '@mswjs/http-middleware'; +import express from 'express'; +import cors from 'cors'; +import { handlers } from './handlers'; + +const app = express(); +const port = 9090; + +app.use(cors({ origin: 'http://localhost:3000', optionsSuccessStatus: 200, credentials: true })); +app.use(express.json()); +app.use(createMiddleware(...handlers)); +app.listen(port, () => console.log(`Mock server is running on port: ${port}`)); \ No newline at end of file From b7004ce98c83073317817fb11f97121c054fac03 Mon Sep 17 00:00:00 2001 From: hiwon-lee <84234411+hiwon-lee@users.noreply.github.com> Date: Thu, 26 Dec 2024 17:43:09 +0900 Subject: [PATCH 07/30] =?UTF-8?q?=F0=9F=92=84=20ui:=20=20layout,=20style?= =?UTF-8?q?=EC=B6=94=EA=B0=80=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/globals.css | 42 ---------- src/app/layout.tsx | 12 +-- src/app/page.module.css | 168 ---------------------------------------- src/app/page.tsx | 7 -- src/styles/input.ts | 25 ++++++ 5 files changed, 31 insertions(+), 223 deletions(-) delete mode 100644 src/app/globals.css delete mode 100644 src/app/page.module.css delete mode 100644 src/app/page.tsx create mode 100644 src/styles/input.ts diff --git a/src/app/globals.css b/src/app/globals.css deleted file mode 100644 index e3734be..0000000 --- a/src/app/globals.css +++ /dev/null @@ -1,42 +0,0 @@ -:root { - --background: #ffffff; - --foreground: #171717; -} - -@media (prefers-color-scheme: dark) { - :root { - --background: #0a0a0a; - --foreground: #ededed; - } -} - -html, -body { - max-width: 100vw; - overflow-x: hidden; -} - -body { - color: var(--foreground); - background: var(--background); - font-family: Arial, Helvetica, sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -* { - box-sizing: border-box; - padding: 0; - margin: 0; -} - -a { - color: inherit; - text-decoration: none; -} - -@media (prefers-color-scheme: dark) { - html { - color-scheme: dark; - } -} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 5f3e71f..f10dfd1 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,12 +1,12 @@ -import React, { ReactNode } from 'react'; -import type { Metadata } from 'next'; -import StyledComponentsRegistry from '@/lib/registry'; -import ScreenWrapper from '@components/ScreenWrapper'; +import React, { ReactNode } from "react"; +import type { Metadata } from "next"; +import StyledComponentsRegistry from "@/lib/registry"; +import ScreenWrapper from "@/app/_components/ScreenWrapper"; // [todo] description 등 meta data 변경 export const metadata: Metadata = { - title: 'Photo Ground', - description: '행복한 순간을 사진으로', + title: "Photo Ground", + description: "행복한 순간을 사진으로", }; export default function RootLayout({ diff --git a/src/app/page.module.css b/src/app/page.module.css deleted file mode 100644 index ee9b8e6..0000000 --- a/src/app/page.module.css +++ /dev/null @@ -1,168 +0,0 @@ -.page { - --gray-rgb: 0, 0, 0; - --gray-alpha-200: rgba(var(--gray-rgb), 0.08); - --gray-alpha-100: rgba(var(--gray-rgb), 0.05); - - --button-primary-hover: #383838; - --button-secondary-hover: #f2f2f2; - - display: grid; - grid-template-rows: 20px 1fr 20px; - align-items: center; - justify-items: center; - min-height: 100svh; - padding: 80px; - gap: 64px; - font-family: var(--font-geist-sans); -} - -@media (prefers-color-scheme: dark) { - .page { - --gray-rgb: 255, 255, 255; - --gray-alpha-200: rgba(var(--gray-rgb), 0.145); - --gray-alpha-100: rgba(var(--gray-rgb), 0.06); - - --button-primary-hover: #ccc; - --button-secondary-hover: #1a1a1a; - } -} - -.main { - display: flex; - flex-direction: column; - gap: 32px; - grid-row-start: 2; -} - -.main ol { - font-family: var(--font-geist-mono); - padding-left: 0; - margin: 0; - font-size: 14px; - line-height: 24px; - letter-spacing: -0.01em; - list-style-position: inside; -} - -.main li:not(:last-of-type) { - margin-bottom: 8px; -} - -.main code { - font-family: inherit; - background: var(--gray-alpha-100); - padding: 2px 4px; - border-radius: 4px; - font-weight: 600; -} - -.ctas { - display: flex; - gap: 16px; -} - -.ctas a { - appearance: none; - border-radius: 128px; - height: 48px; - padding: 0 20px; - border: none; - border: 1px solid transparent; - transition: - background 0.2s, - color 0.2s, - border-color 0.2s; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - font-size: 16px; - line-height: 20px; - font-weight: 500; -} - -a.primary { - background: var(--foreground); - color: var(--background); - gap: 8px; -} - -a.secondary { - border-color: var(--gray-alpha-200); - min-width: 180px; -} - -.footer { - grid-row-start: 3; - display: flex; - gap: 24px; -} - -.footer a { - display: flex; - align-items: center; - gap: 8px; -} - -.footer img { - flex-shrink: 0; -} - -/* Enable hover only on non-touch devices */ -@media (hover: hover) and (pointer: fine) { - a.primary:hover { - background: var(--button-primary-hover); - border-color: transparent; - } - - a.secondary:hover { - background: var(--button-secondary-hover); - border-color: transparent; - } - - .footer a:hover { - text-decoration: underline; - text-underline-offset: 4px; - } -} - -@media (max-width: 600px) { - .page { - padding: 32px; - padding-bottom: 80px; - } - - .main { - align-items: center; - } - - .main ol { - text-align: center; - } - - .ctas { - flex-direction: column; - } - - .ctas a { - font-size: 14px; - height: 40px; - padding: 0 16px; - } - - a.secondary { - min-width: auto; - } - - .footer { - flex-wrap: wrap; - align-items: center; - justify-content: center; - } -} - -@media (prefers-color-scheme: dark) { - .logo { - filter: invert(); - } -} diff --git a/src/app/page.tsx b/src/app/page.tsx deleted file mode 100644 index 78d9a8d..0000000 --- a/src/app/page.tsx +++ /dev/null @@ -1,7 +0,0 @@ -'use client'; - -import React from 'react'; - -export default function Home() { - return
; -} diff --git a/src/styles/input.ts b/src/styles/input.ts new file mode 100644 index 0000000..fe6fabf --- /dev/null +++ b/src/styles/input.ts @@ -0,0 +1,25 @@ +import styled from "styled-components"; + +export const InputContainer = styled.div` + display: flex; + align-items: center; + gap: 1rem; + + width: 100%; + padding: 0.5rem 1rem; + background: ${({ theme }) => theme.colors.gray[900]}; + border-radius: 0.5rem; +`; + +export const Input = styled.input` + flex: 1; + + background: transparent; + border: none; + outline: none; + + font-size: ${({ theme }) => theme.typography.body2_rg.fontSize}; + font-weight: ${({ theme }) => theme.typography.body2_rg.fontWeight}; + line-height: ${({ theme }) => theme.typography.body2_rg.lineHeight}; + color: ${({ theme }) => theme.colors.white}; +`; From ad9d384a9be37e988e55672bb5a39c13590561d0 Mon Sep 17 00:00:00 2001 From: hiwon-lee <84234411+hiwon-lee@users.noreply.github.com> Date: Thu, 26 Dec 2024 17:43:28 +0900 Subject: [PATCH 08/30] =?UTF-8?q?=F0=9F=93=9D=20docs:=20=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=EC=9E=90=20model=EC=B6=94=EA=B0=80=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/model/User.ts | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/model/User.ts diff --git a/src/model/User.ts b/src/model/User.ts new file mode 100644 index 0000000..1434580 --- /dev/null +++ b/src/model/User.ts @@ -0,0 +1,5 @@ +export interface User { + id: string; + nickname: string; + image: string; +} From 0abcdd21a29c3fb78fbb0cdb8e451c043dbfb88f Mon Sep 17 00:00:00 2001 From: hiwon-lee <84234411+hiwon-lee@users.noreply.github.com> Date: Fri, 27 Dec 2024 01:23:07 +0900 Subject: [PATCH 09/30] =?UTF-8?q?=E2=9C=A8=20feat:=20=20mocks=EB=A1=9C=20s?= =?UTF-8?q?ignup=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../(beforeLogin)/_components/EmailInput.tsx | 2 +- src/app/(beforeLogin)/_components/Main.tsx | 69 ++++++------ .../(beforeLogin)/_components/NameInput.tsx | 2 +- .../_components/PasswordInput.tsx | 9 +- .../(beforeLogin)/_components/UnivInput.tsx | 105 +++++++++--------- src/app/(beforeLogin)/_components/styles.ts | 1 - src/app/(beforeLogin)/_lib/signup.ts | 68 ++++++++++++ src/app/(beforeLogin)/signin/InputList.tsx | 48 ++++++++ src/app/(beforeLogin)/signin/page.tsx | 100 ++++++++++++++--- src/app/(beforeLogin)/signup/page.tsx | 101 ++++++++++++++--- src/app/_components/TNB/Main.tsx | 2 +- src/auth.ts | 6 + src/mocks/db.json | 29 +++++ 13 files changed, 417 insertions(+), 125 deletions(-) create mode 100644 src/app/(beforeLogin)/_lib/signup.ts create mode 100644 src/app/(beforeLogin)/signin/InputList.tsx create mode 100644 src/mocks/db.json diff --git a/src/app/(beforeLogin)/_components/EmailInput.tsx b/src/app/(beforeLogin)/_components/EmailInput.tsx index 45e538b..fa68c7b 100644 --- a/src/app/(beforeLogin)/_components/EmailInput.tsx +++ b/src/app/(beforeLogin)/_components/EmailInput.tsx @@ -67,7 +67,7 @@ export default function EmailInput() { - + - ); -} diff --git a/src/app/_components/atoms/Tag/index.tsx b/src/app/_components/atoms/Tag/index.tsx deleted file mode 100644 index 282008f..0000000 --- a/src/app/_components/atoms/Tag/index.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import styled from "styled-components"; -import Text from "@/app/_components/atoms/Text"; - -type Variant = "primary" | "secondary"; - -const TagContainer = styled.div<{ variant: Variant }>` - width: fit-content; - padding: 0.375rem 1rem; - background: ${({ theme, variant }) => - variant === "primary" ? theme.colors.gray[100] : theme.colors.gray[900]}; - border-radius: 1.5rem; -`; - -const PrimaryText = styled(Text)` - color: ${({ theme }) => theme.colors.gray[900]}; -`; - -const SecondaryText = styled(Text)` - color: ${({ theme }) => theme.colors.gray[200]}; -`; - -export default function Tag({ - text, - variant, -}: { - text: string; - variant: Variant; -}) { - return ( - - {variant === "primary" ? ( - {text} - ) : ( - {text} - )} - - ); -} diff --git a/src/app/_components/atoms/Text/index.tsx b/src/app/_components/atoms/Text/index.tsx deleted file mode 100644 index a471800..0000000 --- a/src/app/_components/atoms/Text/index.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import styled from 'styled-components'; - -type Variant = - | 'header1' - | 'header2' - | 'header3' - | 'title1_sb' - | 'title1_rg' - | 'title2' - | 'title3' - | 'body1_md' - | 'body1_rg' - | 'body2_md' - | 'body2_rg' - | 'body3' - | 'caption1_md' - | 'caption1_rg' - | 'caption2' - | 'caption3'; - -const Text = styled.p<{ variant: Variant }>` - font-size: ${({ theme, variant }) => theme.typography[variant].fontSize}; - font-weight: ${({ theme, variant }) => theme.typography[variant].fontWeight}; - line-height: ${({ theme, variant }) => theme.typography[variant].lineHeight}; - color: ${({ theme }) => theme.colors.white}; -`; - -export default Text; diff --git a/src/app/(beforeLogin)/_components/styles.ts b/src/app/_components/styles.ts similarity index 100% rename from src/app/(beforeLogin)/_components/styles.ts rename to src/app/_components/styles.ts diff --git a/src/app/(beforeLogin)/_lib/signup.ts b/src/app/_lib/signup.ts similarity index 97% rename from src/app/(beforeLogin)/_lib/signup.ts rename to src/app/_lib/signup.ts index cd981f5..d5b066b 100644 --- a/src/app/(beforeLogin)/_lib/signup.ts +++ b/src/app/_lib/signup.ts @@ -1,5 +1,6 @@ "use server"; +// [회원 가입 처리] const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:4000"; // type 합치기(signup) type FormState = { @@ -41,6 +42,7 @@ export default async function onSubmit( "Content-Type": "application/json", }, }); + console.log(response); if (response.status === 403) { return { message: "user_exists", formData: null }; diff --git a/src/app/api/auth/[...nextauth]/route.ts b/src/app/api/auth/[...nextauth]/route.ts index 4ccea33..daa958a 100644 --- a/src/app/api/auth/[...nextauth]/route.ts +++ b/src/app/api/auth/[...nextauth]/route.ts @@ -1,4 +1,5 @@ import NextAuth from "next-auth"; import { authOptions } from "@/auth"; -export default NextAuth(authOptions); +export const GET = NextAuth(authOptions); // GET 메서드 명시 +export const POST = NextAuth(authOptions); // POST 메서드 명시 diff --git a/src/app/home/page.ts b/src/app/home/page.ts new file mode 100644 index 0000000..feb616d --- /dev/null +++ b/src/app/home/page.ts @@ -0,0 +1,4 @@ +export default function Home() { + return (
); + } + \ No newline at end of file diff --git a/src/app/(beforeLogin)/page.tsx b/src/app/page.tsx similarity index 100% rename from src/app/(beforeLogin)/page.tsx rename to src/app/page.tsx diff --git a/src/app/(beforeLogin)/signin/InputList.tsx b/src/app/signin/InputList.tsx similarity index 100% rename from src/app/(beforeLogin)/signin/InputList.tsx rename to src/app/signin/InputList.tsx diff --git a/src/app/(beforeLogin)/signin/page.tsx b/src/app/signin/page.tsx similarity index 61% rename from src/app/(beforeLogin)/signin/page.tsx rename to src/app/signin/page.tsx index 4a9218f..7665c8b 100644 --- a/src/app/(beforeLogin)/signin/page.tsx +++ b/src/app/signin/page.tsx @@ -6,6 +6,9 @@ import Text from "@/components/atoms/Text"; import { convertToViewportHeight } from "@/styles/convertSize"; import Link from "next/link"; import CTAButton from "@/app/_components/atoms/CTAButton"; +import { useRouter } from "next/navigation"; +import { useState } from "react"; +import { signIn } from "next-auth/react"; const Container = styled.div` display: flex; @@ -68,14 +71,50 @@ const SignUpText = styled(Text)` `; export default function SignInPage() { + const [id, setId] = useState(""); + const [password, setPassword] = useState(""); + const router = useRouter(); + + const handleLogin = async (e: React.FormEvent) => { + e.preventDefault(); + + const result = await signIn("credentials", { + redirect: false, // 서버 리다이렉션 방지 + id, + password, + }); + + console.log(result); + router.replace("/home"); + + if (result?.error) { + alert("로그인 실패: 아이디 또는 비밀번호를 확인하세요."); + } else { + // 로그인 성공 시 홈으로 이동 + // router.push("/home"); + } + }; + + const handleIdChange = (e: React.ChangeEvent) => { + setId(e.target.value); + }; + + const handlePasswordChange = (e: React.ChangeEvent) => { + setPassword(e.target.value); + }; return ( SIGN IN! -
+ - - + + diff --git a/src/app/(beforeLogin)/signup/page.tsx b/src/app/signup/page.tsx similarity index 100% rename from src/app/(beforeLogin)/signup/page.tsx rename to src/app/signup/page.tsx diff --git a/src/app/(beforeLogin)/signup/styles.ts b/src/app/signup/styles.ts similarity index 100% rename from src/app/(beforeLogin)/signup/styles.ts rename to src/app/signup/styles.ts diff --git a/src/auth.ts b/src/auth.ts index b97082f..5822982 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -5,14 +5,14 @@ import { signIn as nextSignIn } from "next-auth/react"; export const authOptions: NextAuthOptions = { pages: { - signIn: "/i/flow/login", - newUser: "/i/flow/signup", + signIn: "/signin", + newUser: "/signup", }, providers: [ CredentialsProvider({ credentials: { - username: { label: "Username", type: "text" }, - password: { label: "Password", type: "password" }, + id: { label: "id", type: "text" }, + password: { label: "password", type: "password" }, }, async authorize(credentials) { if (!credentials) { @@ -20,14 +20,14 @@ export const authOptions: NextAuthOptions = { } const authResponse = await fetch( - `${process.env.NEXT_PUBLIC_BASE_URL}/api/login`, + `${process.env.NEXT_PUBLIC_BASE_URL}/signin`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ - id: credentials.username, + id: credentials.id, password: credentials.password, }), }, diff --git a/src/mocks/db.json b/src/mocks/db.json index 73f9e77..1afaf99 100644 --- a/src/mocks/db.json +++ b/src/mocks/db.json @@ -24,6 +24,35 @@ "id": "asdf", "password": "dajksl;f", "email": "asjdl" + }, + { + "id": "2171087", + "password": "asdf", + "email": "hiiwonii1012@gmail.com" + }, + { + "id": "2171087", + "password": "asdf", + "email": "hiiwonii1012@gmail.com" + }, + { + "id": "2171087", + "password": "asdf", + "email": "hiiwonii1012@gmail.com" + }, + { + "id": "2171087", + "password": "asdf", + "email": "hiiwonii1012@gmail.com" + }, + { + "id": "ㅁ", + "password": "a" + }, + { + "id": "elonmusk", + "password": "elonmusk", + "email": "elonmusk" } ] } \ No newline at end of file diff --git a/src/mocks/handlers.ts b/src/mocks/handlers.ts index 5672338..7020b4c 100644 --- a/src/mocks/handlers.ts +++ b/src/mocks/handlers.ts @@ -10,9 +10,18 @@ function generateDate() { // }); } const User = [ - { id: "elonmusk", nickname: "Elon Musk", image: "/yRsRRjGO.jpg" }, - { id: "zerohch0", nickname: "제로초", image: "/5Udwvqim.jpg" }, - // { id: "leoturtle", nickname: "레오", image: faker.image.avatar() }, + { + id: "elonmusk", + nickname: "Elon Musk", + image: "/yRsRRjGO.jpg", + password: "1234", + }, + { + id: "zerohch0", + nickname: "제로초", + image: "/5Udwvqim.jpg", + password: "1234", + }, ]; const Posts = []; const delay = (ms: number) => @@ -21,13 +30,20 @@ const delay = (ms: number) => }); export const handlers = [ - http.post("/api/login", () => { + http.post("/signin", async ({ request }) => { console.log("로그인"); - return HttpResponse.json(User[1], { - headers: { - "Set-Cookie": "connect.sid=msw-cookie;HttpOnly;Path=/", - }, - }); + const body = (await request.json()) as { id: string; password: string }; + const { id, password } = body; + + const user = User.find((u) => u.id === id && u.password === password); + if (user) { + return HttpResponse.json(user, { + headers: { + "Set-Cookie": "session=mock-session; HttpOnly; Path=/", + }, + }); + } + return HttpResponse.text("Invalid credentials", { status: 401 }); }), http.post("/api/logout", () => { console.log("로그아웃"); From 10d81f28454b20dc337111abd014bec423663d6b Mon Sep 17 00:00:00 2001 From: hiwon-lee <84234411+hiwon-lee@users.noreply.github.com> Date: Mon, 30 Dec 2024 01:36:48 +0900 Subject: [PATCH 12/30] =?UTF-8?q?=F0=9F=9A=9A=20move:=20=20=EC=A7=80?= =?UTF-8?q?=EC=9A=B4=ED=8C=8C=EC=9D=BC=EB=B3=B5=EC=9B=90=EC=9B=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/home/page.ts | 100 +++++++++++++++++- src/components/Card/card.css | 28 +++++ src/components/Card/index.tsx | 50 +++++++++ src/components/ScreenWrapper/index.tsx | 17 +++ src/components/ScreenWrapper/styles.ts | 15 +++ src/components/TNB/Back.tsx | 36 +++++++ src/components/TNB/Main.tsx | 11 ++ src/components/TNB/SubTitle.tsx | 12 +++ src/components/TNB/Title.tsx | 12 +++ src/components/TNB/index.tsx | 13 +++ src/components/TNB/styles.tsx | 14 +++ src/components/atoms/CTAButton/index.tsx | 60 +++++++++++ src/components/atoms/MediumButton/index.tsx | 34 ++++++ src/components/atoms/SmallButton/Primary.tsx | 33 ++++++ .../atoms/SmallButton/Secondary.tsx | 21 ++++ src/components/atoms/SmallButton/Tertiary.tsx | 26 +++++ src/components/atoms/SmallButton/index.tsx | 11 ++ src/components/atoms/SmallButton/styles.tsx | 13 +++ src/components/atoms/Tag/index.tsx | 38 +++++++ src/components/atoms/Text/index.tsx | 28 +++++ 20 files changed, 569 insertions(+), 3 deletions(-) create mode 100644 src/components/Card/card.css create mode 100644 src/components/Card/index.tsx create mode 100644 src/components/ScreenWrapper/index.tsx create mode 100644 src/components/ScreenWrapper/styles.ts create mode 100644 src/components/TNB/Back.tsx create mode 100644 src/components/TNB/Main.tsx create mode 100644 src/components/TNB/SubTitle.tsx create mode 100644 src/components/TNB/Title.tsx create mode 100644 src/components/TNB/index.tsx create mode 100644 src/components/TNB/styles.tsx create mode 100644 src/components/atoms/CTAButton/index.tsx create mode 100644 src/components/atoms/MediumButton/index.tsx create mode 100644 src/components/atoms/SmallButton/Primary.tsx create mode 100644 src/components/atoms/SmallButton/Secondary.tsx create mode 100644 src/components/atoms/SmallButton/Tertiary.tsx create mode 100644 src/components/atoms/SmallButton/index.tsx create mode 100644 src/components/atoms/SmallButton/styles.tsx create mode 100644 src/components/atoms/Tag/index.tsx create mode 100644 src/components/atoms/Text/index.tsx diff --git a/src/app/home/page.ts b/src/app/home/page.ts index feb616d..929021a 100644 --- a/src/app/home/page.ts +++ b/src/app/home/page.ts @@ -1,4 +1,98 @@ +"use client"; + +import styled from "styled-components"; + +import { convertToViewportHeight } from "@/styles/convertSize"; +import Link from "next/link"; +import { useRouter } from "next/navigation"; +import { useState } from "react"; +import { signIn } from "next-auth/react"; +import Text +const Container = styled.div` + display: flex; + flex-direction: column; + justify-content: center; + height: 100vh; + margin: 0 1rem; + gap: 1rem; +`; +const Header = styled.div` + gap: ${convertToViewportHeight(160)}; +`; +const InputContainer = styled.div` + display: flex; + flex-direction: column; + gap: 1rem; + width: 100%; + margin-bottom: 2rem; +`; + +const Input = styled.input` + flex: 1; + + background: transparent; + border: none; + outline: none; + display: flex; + align-items: center; + + padding: 0.5rem 1rem; + background: ${({ theme }) => theme.colors.gray[900]}; + border-radius: 0.5rem; + + font-size: ${({ theme }) => theme.typography.body2_rg.fontSize}; + font-weight: ${({ theme }) => theme.typography.body2_rg.fontWeight}; + line-height: ${({ theme }) => theme.typography.body2_rg.lineHeight}; + color: ${({ theme }) => theme.colors.white}; +`; + +const SloganArea = styled.header` + text-align: center; + padding: 1rem 1.25rem; +`; +const StyledLink = styled(Link)` + text-decoration-color: ${({ theme }) => theme.colors.gray[300]}; +`; + +const Form = styled.form` + display: flex; + flex-direction: column; + align-items: center; + + width: 100%; +`; + +const SignUpText = styled(Text)` + color: ${({ theme }) => theme.colors.gray[300]}; + margin-top: ${convertToViewportHeight(24)}; + text-align: center; +`; + export default function Home() { - return (
); - } - \ No newline at end of file + const router = useRouter(); + + + return ( + + 파트장 / 데모데이 투표 + + + + + + + + + + {/* [todo] 링크 변경 */} + + 회원가입 + + + ); +} diff --git a/src/components/Card/card.css b/src/components/Card/card.css new file mode 100644 index 0000000..c5f7d6d --- /dev/null +++ b/src/components/Card/card.css @@ -0,0 +1,28 @@ +/* 버튼 크기 */ +.card.small { + img { + width: 7.5rem; + height: 7.5rem; + } +} + +.card.medium { + img { + width: 10.625rem; + height: 10.625rem; + } +} + +/* todo : 크기 수정해야함 */ +.card.large { + font-size: 16px; + padding: 12px 20px; +} + +/* todo : masonry에 들어갈 동적 크기 card */ +.card.dynamic { + img { + width: 100%; + height: auto; + } +} diff --git a/src/components/Card/index.tsx b/src/components/Card/index.tsx new file mode 100644 index 0000000..c7e3b24 --- /dev/null +++ b/src/components/Card/index.tsx @@ -0,0 +1,50 @@ +import React from 'react'; +import styled from 'styled-components'; +import Text from '../atoms/Text'; + +import './card.css'; + +export interface CardProps { + /** How large should the card be? */ + size?: 'small' | 'medium' | 'large' | 'dynamic'; + /** What card image to use */ + src: string; + /** Card Title */ + title?: string; + /** Card Content */ + content?: string; + /** Optional click handler */ + onClick?: () => void; +} + +const CardWrapper = styled.div` + display: flex; + flex-direction: column; + cursor: pointer; +`; + +const CardImage = styled.img` + object-fit: cover; + margin-bottom: 0.5rem; + border-radius: 0.125rem; +`; + +const CardContent = styled(Text)` + color: ${({ theme }) => theme.colors.gray[200]}; +`; + +export default function Card({ + size, + src, + title, + content, + onClick, +}: CardProps) { + return ( + + + {title} + {content} + + ); +} diff --git a/src/components/ScreenWrapper/index.tsx b/src/components/ScreenWrapper/index.tsx new file mode 100644 index 0000000..e7f30cb --- /dev/null +++ b/src/components/ScreenWrapper/index.tsx @@ -0,0 +1,17 @@ +'use client'; + +import { ReactNode } from 'react'; + +import BottomNavigationBar from '@/components/BNB'; +import { Container, FullPage } from './styles'; + +export default function ScreenWrapper({ children }: { children: ReactNode }) { + return ( + + + {children} + + + + ); +} diff --git a/src/components/ScreenWrapper/styles.ts b/src/components/ScreenWrapper/styles.ts new file mode 100644 index 0000000..1078e59 --- /dev/null +++ b/src/components/ScreenWrapper/styles.ts @@ -0,0 +1,15 @@ +import BREAK_POINT from '@/styles/constants'; +import styled from 'styled-components'; + +export const FullPage = styled.div` + height: 100dvh; +`; + +export const Container = styled.div` + position: relative; + width: 100%; + max-width: ${BREAK_POINT}px; + height: 100dvh; + margin: auto; + overflow: auto; +`; diff --git a/src/components/TNB/Back.tsx b/src/components/TNB/Back.tsx new file mode 100644 index 0000000..c904bf7 --- /dev/null +++ b/src/components/TNB/Back.tsx @@ -0,0 +1,36 @@ +import { useCallback } from 'react'; +import { useRouter } from 'next/navigation'; +import styled from 'styled-components'; +import Text from '@/components/atoms/Text'; +import LeftChevronIcon from '@/assets/LeftChevronIcon'; +import { BorderedHeader } from './styles'; + +const IconWrapper = styled.button` + position: absolute; + left: 1.25rem; + + background: transparent; + border: none; + outline: none; + + cursor: pointer; +`; + +export default function Back({ text }: { text: string }) { + const router = useRouter(); + + const goBack = useCallback(() => { + router.back(); + }, [router]); + + return ( + + + + + + {text} + + + ); +} diff --git a/src/components/TNB/Main.tsx b/src/components/TNB/Main.tsx new file mode 100644 index 0000000..a22d21d --- /dev/null +++ b/src/components/TNB/Main.tsx @@ -0,0 +1,11 @@ +import Text from '@/components/atoms/Text'; +import { Header } from './styles'; + +// [todo] 로고가 생기면 로고로 교체해주세요~ +export default function Main() { + return ( +
+ PHOTO GROUND +
+ ); +} diff --git a/src/components/TNB/SubTitle.tsx b/src/components/TNB/SubTitle.tsx new file mode 100644 index 0000000..97f04ce --- /dev/null +++ b/src/components/TNB/SubTitle.tsx @@ -0,0 +1,12 @@ +import Text from '@/components/atoms/Text'; +import { BorderedHeader } from './styles'; + +export default function SubTitle({ text }: { text: string }) { + return ( + + + {text} + + + ); +} diff --git a/src/components/TNB/Title.tsx b/src/components/TNB/Title.tsx new file mode 100644 index 0000000..5c62b04 --- /dev/null +++ b/src/components/TNB/Title.tsx @@ -0,0 +1,12 @@ +import Text from '@/components/atoms/Text'; +import { Header } from './styles'; + +export default function Title({ text }: { text: string }) { + return ( +
+ + {text} + +
+ ); +} diff --git a/src/components/TNB/index.tsx b/src/components/TNB/index.tsx new file mode 100644 index 0000000..1293214 --- /dev/null +++ b/src/components/TNB/index.tsx @@ -0,0 +1,13 @@ +import Main from './Main'; +import Title from './Title'; +import SubTitle from './SubTitle'; +import Back from './Back'; + +const TNB = { + Main, + Title, + SubTitle, + Back, +}; + +export default TNB; diff --git a/src/components/TNB/styles.tsx b/src/components/TNB/styles.tsx new file mode 100644 index 0000000..566660d --- /dev/null +++ b/src/components/TNB/styles.tsx @@ -0,0 +1,14 @@ +import styled from 'styled-components'; + +export const Header = styled.header` + position: relative; + display: flex; + align-items: center; + justify-content: center; + + height: 4rem; +`; + +export const BorderedHeader = styled(Header)` + border-bottom: 1px solid ${({ theme }) => theme.colors.gray[600]}; +`; diff --git a/src/components/atoms/CTAButton/index.tsx b/src/components/atoms/CTAButton/index.tsx new file mode 100644 index 0000000..ffeff4e --- /dev/null +++ b/src/components/atoms/CTAButton/index.tsx @@ -0,0 +1,60 @@ +import styled, { DefaultTheme } from 'styled-components'; +import Text from '@/components/atoms/Text'; + +type Variant = 'primary' | 'secondary'; + +const getBackgroundColor = ({ + theme, + variant, + disabled, +}: { + theme: DefaultTheme; + variant: Variant; + disabled: boolean; +}) => { + if (disabled) { + return theme.colors.gray[600]; + } + if (variant === 'primary') { + return theme.colors.primary[100]; + } + return theme.colors.gray[900]; +}; + +const Button = styled.button<{ variant: Variant; disabled: boolean }>` + width: 100%; + padding: 1rem 0; + background: ${(props) => getBackgroundColor(props)}; + + outline: none; + border: none; + border-radius: 0.5rem; + + cursor: pointer; +`; + +const ButtonText = styled(Text)` + color: ${({ theme }) => theme.colors.gray[200]}; +`; + +export default function CTAButton({ + text, + variant = 'primary', + disabled = false, + onClick = () => {}, +}: { + text: string; + variant?: Variant; + disabled?: boolean; + onClick?: () => void; +}) { + return ( + + ); +} diff --git a/src/components/atoms/MediumButton/index.tsx b/src/components/atoms/MediumButton/index.tsx new file mode 100644 index 0000000..02dcba9 --- /dev/null +++ b/src/components/atoms/MediumButton/index.tsx @@ -0,0 +1,34 @@ +import styled from 'styled-components'; +import Text from '@/components/atoms/Text'; + +type Variant = 'primary' | 'secondary'; + +const Button = styled.button<{ variant: Variant }>` + padding: 0.688rem 1.25rem; + background: ${({ theme, variant }) => + variant === 'primary' ? theme.colors.primary[100] : theme.colors.gray[900]}; + + outline: none; + border: none; + border-radius: 1.5rem; + + cursor: pointer; +`; + +export default function MediumButton({ + text, + variant = 'primary', + onClick = () => {}, +}: { + text: string; + variant?: Variant; + onClick?: () => void; +}) { + return ( + + ); +} diff --git a/src/components/atoms/SmallButton/Primary.tsx b/src/components/atoms/SmallButton/Primary.tsx new file mode 100644 index 0000000..c66cc0d --- /dev/null +++ b/src/components/atoms/SmallButton/Primary.tsx @@ -0,0 +1,33 @@ +import styled from 'styled-components'; +import Text from '@/components/atoms/Text'; +import Button from './styles'; + +const PrimaryButton = styled(Button)<{ disabled: boolean }>` + background: ${({ theme, disabled }) => + disabled ? theme.colors.gray[600] : theme.colors.primary[100]}; + cursor: ${({ disabled }) => (disabled ? 'auto' : 'cursor')}; +`; + +const DisabledText = styled(Text)` + color: ${({ theme }) => theme.colors.gray[200]}; +`; + +export default function Primary({ + text, + disabled = false, + onClick = () => {}, +}: { + text: string; + disabled?: boolean; + onClick?: () => void; +}) { + return ( + + {disabled ? ( + {text} + ) : ( + {text} + )} + + ); +} diff --git a/src/components/atoms/SmallButton/Secondary.tsx b/src/components/atoms/SmallButton/Secondary.tsx new file mode 100644 index 0000000..4838738 --- /dev/null +++ b/src/components/atoms/SmallButton/Secondary.tsx @@ -0,0 +1,21 @@ +import styled from 'styled-components'; +import Text from '@/components/atoms/Text'; +import Button from './styles'; + +const SecondaryButton = styled(Button)` + background: ${({ theme }) => theme.colors.gray[900]}; +`; + +export default function Secondary({ + text, + onClick = () => {}, +}: { + text: string; + onClick?: () => void; +}) { + return ( + + {text} + + ); +} diff --git a/src/components/atoms/SmallButton/Tertiary.tsx b/src/components/atoms/SmallButton/Tertiary.tsx new file mode 100644 index 0000000..f4f3660 --- /dev/null +++ b/src/components/atoms/SmallButton/Tertiary.tsx @@ -0,0 +1,26 @@ +import styled from 'styled-components'; +import Text from '@/components/atoms/Text'; +import Button from './styles'; + +const TertiaryButton = styled(Button)` + background: transparent; + border: 1px solid ${({ theme }) => theme.colors.primary[100]}; +`; + +const ButtonText = styled(Text)` + color: ${({ theme }) => theme.colors.primary[100]}; +`; + +export default function Tertiary({ + text, + onClick = () => {}, +}: { + text: string; + onClick?: () => void; +}) { + return ( + + {text} + + ); +} diff --git a/src/components/atoms/SmallButton/index.tsx b/src/components/atoms/SmallButton/index.tsx new file mode 100644 index 0000000..28a6645 --- /dev/null +++ b/src/components/atoms/SmallButton/index.tsx @@ -0,0 +1,11 @@ +import Primary from './Primary'; +import Secondary from './Secondary'; +import Tertiary from './Tertiary'; + +const SmallButton = { + Primary, + Secondary, + Tertiary, +}; + +export default SmallButton; diff --git a/src/components/atoms/SmallButton/styles.tsx b/src/components/atoms/SmallButton/styles.tsx new file mode 100644 index 0000000..5b10e56 --- /dev/null +++ b/src/components/atoms/SmallButton/styles.tsx @@ -0,0 +1,13 @@ +import styled from 'styled-components'; + +const Button = styled.button` + padding: 0.438rem 1.25rem; + + outline: none; + border: none; + border-radius: 1.5rem; + + cursor: pointer; +`; + +export default Button; diff --git a/src/components/atoms/Tag/index.tsx b/src/components/atoms/Tag/index.tsx new file mode 100644 index 0000000..5751a03 --- /dev/null +++ b/src/components/atoms/Tag/index.tsx @@ -0,0 +1,38 @@ +import styled from 'styled-components'; +import Text from '@/components/atoms/Text'; + +type Variant = 'primary' | 'secondary'; + +const TagContainer = styled.div<{ variant: Variant }>` + width: fit-content; + padding: 0.375rem 1rem; + background: ${({ theme, variant }) => + variant === 'primary' ? theme.colors.gray[100] : theme.colors.gray[900]}; + border-radius: 1.5rem; +`; + +const PrimaryText = styled(Text)` + color: ${({ theme }) => theme.colors.gray[900]}; +`; + +const SecondaryText = styled(Text)` + color: ${({ theme }) => theme.colors.gray[200]}; +`; + +export default function Tag({ + text, + variant, +}: { + text: string; + variant: Variant; +}) { + return ( + + {variant === 'primary' ? ( + {text} + ) : ( + {text} + )} + + ); +} diff --git a/src/components/atoms/Text/index.tsx b/src/components/atoms/Text/index.tsx new file mode 100644 index 0000000..a471800 --- /dev/null +++ b/src/components/atoms/Text/index.tsx @@ -0,0 +1,28 @@ +import styled from 'styled-components'; + +type Variant = + | 'header1' + | 'header2' + | 'header3' + | 'title1_sb' + | 'title1_rg' + | 'title2' + | 'title3' + | 'body1_md' + | 'body1_rg' + | 'body2_md' + | 'body2_rg' + | 'body3' + | 'caption1_md' + | 'caption1_rg' + | 'caption2' + | 'caption3'; + +const Text = styled.p<{ variant: Variant }>` + font-size: ${({ theme, variant }) => theme.typography[variant].fontSize}; + font-weight: ${({ theme, variant }) => theme.typography[variant].fontWeight}; + line-height: ${({ theme, variant }) => theme.typography[variant].lineHeight}; + color: ${({ theme }) => theme.colors.white}; +`; + +export default Text; From 5bfe41bc34ebc8eac4cbbed37da33c25f81421d2 Mon Sep 17 00:00:00 2001 From: hiwon-lee <84234411+hiwon-lee@users.noreply.github.com> Date: Mon, 30 Dec 2024 01:52:06 +0900 Subject: [PATCH 13/30] =?UTF-8?q?=F0=9F=90=9B=20fix:=20=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=9D=B4=EB=8F=99=ED=95=98=EB=A9=B4=EC=84=9C=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=EB=82=98=EB=8A=94=20=EB=B6=80=EB=B6=84=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/home/{page.ts => page.tsx} | 37 +++++++++++--------------- src/app/layout.tsx | 12 ++++----- src/app/signin/page.tsx | 28 +++++++++---------- src/components/Card/card.css | 15 +++++------ src/components/Card/index.tsx | 18 ++----------- src/components/ScreenWrapper/index.tsx | 6 +---- tsconfig.json | 4 +-- 7 files changed, 46 insertions(+), 74 deletions(-) rename src/app/home/{page.ts => page.tsx} (71%) diff --git a/src/app/home/page.ts b/src/app/home/page.tsx similarity index 71% rename from src/app/home/page.ts rename to src/app/home/page.tsx index 929021a..98a7fe8 100644 --- a/src/app/home/page.ts +++ b/src/app/home/page.tsx @@ -1,13 +1,16 @@ -"use client"; +'use client'; -import styled from "styled-components"; +import styled from 'styled-components'; + +import Text from '@/components/atoms/Text'; +import { convertToViewportHeight } from '@/styles/convertSize'; +import Link from 'next/link'; +import { useRouter } from 'next/navigation'; +import { useState } from 'react'; +import { signIn } from 'next-auth/react'; +import CTAButton from '@/components/atoms/CTAButton'; +import Card from '@/components/Card'; -import { convertToViewportHeight } from "@/styles/convertSize"; -import Link from "next/link"; -import { useRouter } from "next/navigation"; -import { useState } from "react"; -import { signIn } from "next-auth/react"; -import Text const Container = styled.div` display: flex; flex-direction: column; @@ -69,26 +72,16 @@ const SignUpText = styled(Text)` `; export default function Home() { + const [id, setId] = useState(''); + const [password, setPassword] = useState(''); const router = useRouter(); - return ( 파트장 / 데모데이 투표 -
- - - - - - - + + {/* [todo] 링크 변경 */} 회원가입 diff --git a/src/app/layout.tsx b/src/app/layout.tsx index f10dfd1..d184cff 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,12 +1,12 @@ -import React, { ReactNode } from "react"; -import type { Metadata } from "next"; -import StyledComponentsRegistry from "@/lib/registry"; -import ScreenWrapper from "@/app/_components/ScreenWrapper"; +import React, { ReactNode } from 'react'; +import type { Metadata } from 'next'; +import StyledComponentsRegistry from '@/lib/registry'; +import ScreenWrapper from '@/components/ScreenWrapper'; // [todo] description 등 meta data 변경 export const metadata: Metadata = { - title: "Photo Ground", - description: "행복한 순간을 사진으로", + title: 'Photo Ground', + description: '행복한 순간을 사진으로', }; export default function RootLayout({ diff --git a/src/app/signin/page.tsx b/src/app/signin/page.tsx index 7665c8b..0a7dc28 100644 --- a/src/app/signin/page.tsx +++ b/src/app/signin/page.tsx @@ -1,14 +1,14 @@ -"use client"; +'use client'; -import styled from "styled-components"; +import styled from 'styled-components'; -import Text from "@/components/atoms/Text"; -import { convertToViewportHeight } from "@/styles/convertSize"; -import Link from "next/link"; -import CTAButton from "@/app/_components/atoms/CTAButton"; -import { useRouter } from "next/navigation"; -import { useState } from "react"; -import { signIn } from "next-auth/react"; +import Text from '@/components/atoms/Text'; +import { convertToViewportHeight } from '@/styles/convertSize'; +import Link from 'next/link'; +import { useRouter } from 'next/navigation'; +import { useState } from 'react'; +import { signIn } from 'next-auth/react'; +import CTAButton from '@/components/atoms/CTAButton'; const Container = styled.div` display: flex; @@ -71,24 +71,24 @@ const SignUpText = styled(Text)` `; export default function SignInPage() { - const [id, setId] = useState(""); - const [password, setPassword] = useState(""); + const [id, setId] = useState(''); + const [password, setPassword] = useState(''); const router = useRouter(); const handleLogin = async (e: React.FormEvent) => { e.preventDefault(); - const result = await signIn("credentials", { + const result = await signIn('credentials', { redirect: false, // 서버 리다이렉션 방지 id, password, }); console.log(result); - router.replace("/home"); + router.replace('/home'); if (result?.error) { - alert("로그인 실패: 아이디 또는 비밀번호를 확인하세요."); + alert('로그인 실패: 아이디 또는 비밀번호를 확인하세요.'); } else { // 로그인 성공 시 홈으로 이동 // router.push("/home"); diff --git a/src/components/Card/card.css b/src/components/Card/card.css index c5f7d6d..ba6db4d 100644 --- a/src/components/Card/card.css +++ b/src/components/Card/card.css @@ -1,22 +1,21 @@ /* 버튼 크기 */ .card.small { - img { - width: 7.5rem; - height: 7.5rem; - } + width: 12rem; + height: 5rem; } .card.medium { img { - width: 10.625rem; - height: 10.625rem; + width: 16rem; + height: 6rem; } } /* todo : 크기 수정해야함 */ .card.large { - font-size: 16px; - padding: 12px 20px; + width: 18rem; + height: 18rem; + /* padding: 12px 20px; */ } /* todo : masonry에 들어갈 동적 크기 card */ diff --git a/src/components/Card/index.tsx b/src/components/Card/index.tsx index c7e3b24..856fc8a 100644 --- a/src/components/Card/index.tsx +++ b/src/components/Card/index.tsx @@ -7,8 +7,7 @@ import './card.css'; export interface CardProps { /** How large should the card be? */ size?: 'small' | 'medium' | 'large' | 'dynamic'; - /** What card image to use */ - src: string; + /** Card Title */ title?: string; /** Card Content */ @@ -23,26 +22,13 @@ const CardWrapper = styled.div` cursor: pointer; `; -const CardImage = styled.img` - object-fit: cover; - margin-bottom: 0.5rem; - border-radius: 0.125rem; -`; - const CardContent = styled(Text)` color: ${({ theme }) => theme.colors.gray[200]}; `; -export default function Card({ - size, - src, - title, - content, - onClick, -}: CardProps) { +export default function Card({ size, title, content, onClick }: CardProps) { return ( - {title} {content} diff --git a/src/components/ScreenWrapper/index.tsx b/src/components/ScreenWrapper/index.tsx index e7f30cb..a979a13 100644 --- a/src/components/ScreenWrapper/index.tsx +++ b/src/components/ScreenWrapper/index.tsx @@ -2,16 +2,12 @@ import { ReactNode } from 'react'; -import BottomNavigationBar from '@/components/BNB'; import { Container, FullPage } from './styles'; export default function ScreenWrapper({ children }: { children: ReactNode }) { return ( - - {children} - - + {children} ); } diff --git a/tsconfig.json b/tsconfig.json index bf6bbd1..c133409 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,9 +19,7 @@ } ], "paths": { - "@/*": ["./src/*"], - "@/components/*": ["./src/app/_components/*"], - "@/styles/*": ["./src/styles/*"] + "@/*": ["./src/*"] } }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], From 6622ddcc611a78977c0821c5e3b9a93634aab41d Mon Sep 17 00:00:00 2001 From: hiwon-lee <84234411+hiwon-lee@users.noreply.github.com> Date: Mon, 30 Dec 2024 03:10:29 +0900 Subject: [PATCH 14/30] =?UTF-8?q?=F0=9F=9A=9A=20move:=20=20=EC=95=88?= =?UTF-8?q?=EC=93=B0=EB=8A=94=20=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/_components/GenderInput.tsx | 67 --------------- src/app/_components/UnivInput.tsx | 121 ---------------------------- 2 files changed, 188 deletions(-) delete mode 100644 src/app/_components/GenderInput.tsx delete mode 100644 src/app/_components/UnivInput.tsx diff --git a/src/app/_components/GenderInput.tsx b/src/app/_components/GenderInput.tsx deleted file mode 100644 index f231a91..0000000 --- a/src/app/_components/GenderInput.tsx +++ /dev/null @@ -1,67 +0,0 @@ -'use client'; - -import Text from '@/components/atoms/Text'; -import { useState } from 'react'; -import styled from 'styled-components'; - -type Value = 'male' | 'female'; - -const OPTION_LIST: { title: string; value: Value }[] = [ - { title: '남성', value: 'male' }, - { title: '여성', value: 'female' }, -]; - -const Container = styled.div` - display: flex; - gap: 0.75rem; - - margin-top: 1.5rem; - margin-bottom: 1rem; -`; - -const Button = styled.button<{ $isSelected: boolean }>` - display: flex; - justify-content: center; - - width: 100%; - padding: 0.5rem; - background: transparent; - - border: 1px solid - ${({ theme, $isSelected }) => - $isSelected ? theme.colors.white : theme.colors.gray[600]}; - border-radius: 0.5rem; - - cursor: pointer; -`; - -const ButtonText = styled(Text)<{ $isSelected: boolean }>` - color: ${({ theme, $isSelected }) => - $isSelected ? theme.colors.white : theme.colors.gray[400]}; -`; - -export default function GenderInput() { - const [value, setValue] = useState(null); - - return ( - - {OPTION_LIST.map((option) => { - const isSelected = value === option.value; - return ( - - ); - })} - - ); -} diff --git a/src/app/_components/UnivInput.tsx b/src/app/_components/UnivInput.tsx deleted file mode 100644 index 4f0fed0..0000000 --- a/src/app/_components/UnivInput.tsx +++ /dev/null @@ -1,121 +0,0 @@ -import { useState } from "react"; -import styled from "styled-components"; -import DownChevronIcon from "@/assets/DownChevronIcon"; -import Text from "@/components/atoms/Text"; - -export interface Option { - value: string; - label: string; -} - -const Container = styled.div` - display: flex; - flex-direction: column; - position: relative; - width: 100%; -`; - -const FilterWrapper = styled.div<{ $isOpen: boolean }>` - display: flex; - align-items: center; - justify-content: space-between; - padding: 0.5rem 1rem; - background: transparent; - border: 1px solid ${({ theme }) => theme.colors.gray[200]}; - border-radius: ${({ $isOpen }) => ($isOpen ? "0.5rem 0.5rem 0 0" : "0.5rem")}; - cursor: pointer; -`; - -const FilterText = styled(Text)` - color: ${({ theme }) => theme.colors.gray[200]}; -`; - -const Backdrop = styled.div` - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: transparent; - z-index: 20; -`; - -const OptionWrapper = styled.div` - position: absolute; - top: 100%; - left: 0; - width: 100%; - background: ${({ theme }) => theme.colors.background.primary}; - border: 1px solid ${({ theme }) => theme.colors.gray[200]}; - border-top: none; - border-radius: 0 0 0.5rem 0.5rem; - z-index: 21; -`; - -const OptionItem = styled.button` - width: 100%; - padding: 0.5rem 1rem; - background: transparent; - border: none; - text-align: start; - cursor: pointer; - - &:hover { - background-color: ${({ theme }) => theme.colors.gray[100]}; - } -`; - -interface DropdownProps { - options: Option[]; - placeholder?: string; - onSelect: (value: string) => void; -} - -export default function Dropdown({ - options, - placeholder = "Select an option", - onSelect, -}: DropdownProps) { - const [isOpen, setIsOpen] = useState(false); - const [selectedValue, setSelectedValue] = useState(null); - - const handleOpen = () => setIsOpen(true); - const handleClose = () => setIsOpen(false); - - const handleSelect = (value: string) => { - setSelectedValue(value); - onSelect(value); - handleClose(); - }; - - const currentLabel = options.find( - (option) => option.value === selectedValue, - )?.label; - - return ( - - - - {currentLabel || placeholder} - - - - - {isOpen && ( - <> - - - {options.map((option) => ( - handleSelect(option.value)} - > - {option.label} - - ))} - - - )} - - ); -} From 92d2d720e618494e330f36bf4d17e4d9cee18d02 Mon Sep 17 00:00:00 2001 From: hiwon-lee <84234411+hiwon-lee@users.noreply.github.com> Date: Mon, 30 Dec 2024 03:11:07 +0900 Subject: [PATCH 15/30] =?UTF-8?q?=E2=9C=A8=20feat:=20=20=EC=B9=B4=EB=93=9C?= =?UTF-8?q?=20=EC=BB=B4=ED=8D=BC=EB=84=8C=ED=8A=B8=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Card/card.css | 17 ++---------- src/components/Card/index.tsx | 52 +++++++++++++++++++++++++---------- 2 files changed, 39 insertions(+), 30 deletions(-) diff --git a/src/components/Card/card.css b/src/components/Card/card.css index ba6db4d..0404f8d 100644 --- a/src/components/Card/card.css +++ b/src/components/Card/card.css @@ -1,27 +1,14 @@ -/* 버튼 크기 */ .card.small { width: 12rem; height: 5rem; } .card.medium { - img { - width: 16rem; - height: 6rem; - } + width: 16rem; + height: 6rem; } -/* todo : 크기 수정해야함 */ .card.large { width: 18rem; height: 18rem; - /* padding: 12px 20px; */ -} - -/* todo : masonry에 들어갈 동적 크기 card */ -.card.dynamic { - img { - width: 100%; - height: auto; - } } diff --git a/src/components/Card/index.tsx b/src/components/Card/index.tsx index 856fc8a..affc9bb 100644 --- a/src/components/Card/index.tsx +++ b/src/components/Card/index.tsx @@ -1,36 +1,58 @@ import React from 'react'; -import styled from 'styled-components'; +import styled, { css } from 'styled-components'; import Text from '../atoms/Text'; -import './card.css'; - export interface CardProps { - /** How large should the card be? */ - size?: 'small' | 'medium' | 'large' | 'dynamic'; - - /** Card Title */ + size?: 'small' | 'medium' | 'large'; title?: string; - /** Card Content */ content?: string; - /** Optional click handler */ + voteCount?: number; // 투표 수 표시 + selected?: boolean; // 선택된 카드인지 여부 onClick?: () => void; } -const CardWrapper = styled.div` +const CardWrapper = styled.div<{ selected?: boolean }>` display: flex; flex-direction: column; + align-items: center; + justify-content: center; + // width: 100%; cursor: pointer; + border: 2px solid ${({ theme }) => theme.colors.primary[100]}; + border-radius: 8px; + padding: 1rem; + transition: all 0.3s ease; + + &:hover { + background-color: ${({ theme }) => theme.colors.primary[100]}; + } `; -const CardContent = styled(Text)` - color: ${({ theme }) => theme.colors.gray[200]}; +const VoteCount = styled(Text)` + margin-top: 0.5rem; + font-weight: bold; + color: ${({ theme }) => theme.colors.gray[600]}; `; -export default function Card({ size, title, content, onClick }: CardProps) { +export default function Card({ + size, + title, + content, + voteCount, + selected, + onClick, +}: CardProps) { return ( - + {title} - {content} + {content && {content}} + {voteCount !== undefined && ( + Votes: {voteCount} + )} ); } From a6dd5e3494d7db09ec12acd9f8187849679eded9 Mon Sep 17 00:00:00 2001 From: hiwon-lee <84234411+hiwon-lee@users.noreply.github.com> Date: Mon, 30 Dec 2024 03:11:27 +0900 Subject: [PATCH 16/30] =?UTF-8?q?=F0=9F=93=9D=20docs:=20=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EC=B6=94=EA=B0=80=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/data/candidates.ts | 38 ++++++++++++++++++++++++++++++++++++++ src/data/types.ts | 8 ++++++++ 2 files changed, 46 insertions(+) create mode 100644 src/data/candidates.ts create mode 100644 src/data/types.ts diff --git a/src/data/candidates.ts b/src/data/candidates.ts new file mode 100644 index 0000000..9ebbbcf --- /dev/null +++ b/src/data/candidates.ts @@ -0,0 +1,38 @@ +import { Candidate, ThemeType } from './types'; + +// 내림차순으로 정렬된 데이터 +export const candidateData: Record = { + 'front-end': [ + { id: 1, name: '최지원' }, + { id: 2, name: '유선' }, + { id: 3, name: '윤영준' }, + { id: 4, name: '박지수' }, + { id: 5, name: '이희원' }, + { id: 6, name: '강다혜' }, + { id: 7, name: '류원' }, + { id: 8, name: '이가빈' }, + { id: 9, name: '지민재' }, + { id: 10, name: '권혜인' }, + ].sort((a, b) => b.name.localeCompare(a.name)), // 이름 내림차순 정렬 + + 'back-end': [ + { id: 11, name: '황서아' }, + { id: 12, name: '최서지' }, + { id: 13, name: '임가현' }, + { id: 14, name: '이한슬' }, + { id: 15, name: '이채원' }, + { id: 16, name: '유지민' }, + { id: 17, name: '문서영' }, + { id: 18, name: '남승현' }, + { id: 19, name: '나혜인' }, + { id: 20, name: '김연수' }, + ].sort((a, b) => b.name.localeCompare(a.name)), // 이름 내림차순 정렬 + + 'demo-day': [ + { id: 21, name: '페달지니' }, + { id: 22, name: '케이크웨이' }, + { id: 23, name: '커피딜' }, + { id: 24, name: '엔젤브릿지' }, + { id: 25, name: '포토그라운드' }, + ].sort((a, b) => b.name.localeCompare(a.name)), // 이름 내림차순 정렬 +}; diff --git a/src/data/types.ts b/src/data/types.ts new file mode 100644 index 0000000..6fb7376 --- /dev/null +++ b/src/data/types.ts @@ -0,0 +1,8 @@ +// 테마 타입 정의 +export type ThemeType = 'front-end' | 'back-end' | 'demo-day'; + +// 후보 데이터 타입 정의 +export interface Candidate { + id: number; + name: string; +} From 75737c31f7b46920ddcca53f1ece3f66069ee18d Mon Sep 17 00:00:00 2001 From: hiwon-lee <84234411+hiwon-lee@users.noreply.github.com> Date: Mon, 30 Dec 2024 03:12:01 +0900 Subject: [PATCH 17/30] =?UTF-8?q?=E2=9C=A8=20feat:=20=20=ED=88=AC=ED=91=9C?= =?UTF-8?q?=20=EC=A0=88=EC=B0=A8=20=EC=97=B0=EA=B2=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/_components/Vote.tsx | 28 ++++++ src/app/home/page.tsx | 80 +++++----------- src/app/signup/page.tsx | 54 +++++------ src/app/vote/[theme]/page.tsx | 133 +++++++++++++++++++++++++++ src/app/vote/[theme]/result/page.tsx | 114 +++++++++++++++++++++++ src/app/vote/part/page.tsx | 52 +++++++++++ 6 files changed, 375 insertions(+), 86 deletions(-) create mode 100644 src/app/_components/Vote.tsx create mode 100644 src/app/vote/[theme]/page.tsx create mode 100644 src/app/vote/[theme]/result/page.tsx create mode 100644 src/app/vote/part/page.tsx diff --git a/src/app/_components/Vote.tsx b/src/app/_components/Vote.tsx new file mode 100644 index 0000000..616fa67 --- /dev/null +++ b/src/app/_components/Vote.tsx @@ -0,0 +1,28 @@ +import Card from '@/components/Card'; +import React, { useState } from 'react'; + +export default function VotingUI() { + const [selectedCard, setSelectedCard] = useState(null); + const [votes, setVotes] = useState([0, 0, 0]); // 초기 투표 수 + + const handleVote = (index: number) => { + const newVotes = [...votes]; + newVotes[index] += 1; + setVotes(newVotes); + setSelectedCard(index); + }; + + return ( +
+ {['Frontend', 'Backend', 'Design'].map((title, index) => ( + handleVote(index)} + size="medium" + /> + ))} +
+ ); +} diff --git a/src/app/home/page.tsx b/src/app/home/page.tsx index 98a7fe8..dbdffb0 100644 --- a/src/app/home/page.tsx +++ b/src/app/home/page.tsx @@ -19,73 +19,35 @@ const Container = styled.div` margin: 0 1rem; gap: 1rem; `; -const Header = styled.div` - gap: ${convertToViewportHeight(160)}; -`; -const InputContainer = styled.div` +const CardWrapper = styled.div` display: flex; - flex-direction: column; + flex-wrap: wrap; gap: 1rem; - width: 100%; - margin-bottom: 2rem; -`; - -const Input = styled.input` - flex: 1; - - background: transparent; - border: none; - outline: none; - display: flex; - align-items: center; - - padding: 0.5rem 1rem; - background: ${({ theme }) => theme.colors.gray[900]}; - border-radius: 0.5rem; - - font-size: ${({ theme }) => theme.typography.body2_rg.fontSize}; - font-weight: ${({ theme }) => theme.typography.body2_rg.fontWeight}; - line-height: ${({ theme }) => theme.typography.body2_rg.lineHeight}; - color: ${({ theme }) => theme.colors.white}; -`; - -const SloganArea = styled.header` - text-align: center; - padding: 1rem 1.25rem; -`; -const StyledLink = styled(Link)` - text-decoration-color: ${({ theme }) => theme.colors.gray[300]}; -`; - -const Form = styled.form` - display: flex; - flex-direction: column; - align-items: center; - - width: 100%; -`; - -const SignUpText = styled(Text)` - color: ${({ theme }) => theme.colors.gray[300]}; - margin-top: ${convertToViewportHeight(24)}; - text-align: center; + justify-content: center; `; - export default function Home() { - const [id, setId] = useState(''); - const [password, setPassword] = useState(''); const router = useRouter(); + const handleNavigation = (path: string) => { + router.push(`/vote/${path}`); + }; + return ( - 파트장 / 데모데이 투표 - - - - {/* [todo] 링크 변경 */} - - 회원가입 - + 투표 카테고리를 선택하세요 + + handleNavigation('part')} + /> + + handleNavigation('demo-day')} + /> + ); } diff --git a/src/app/signup/page.tsx b/src/app/signup/page.tsx index ddbcbfe..cb8c203 100644 --- a/src/app/signup/page.tsx +++ b/src/app/signup/page.tsx @@ -1,20 +1,20 @@ -"use client"; +'use client'; -import { useState } from "react"; -import CTAButton from "@/components/atoms/CTAButton"; -import Text from "@/components/atoms/Text"; +import { useState } from 'react'; +import CTAButton from '@/components/atoms/CTAButton'; +import Text from '@/components/atoms/Text'; import { AccountSection, ButtonWrapper, DivideLine, UserSection, -} from "../_components/styles"; -import EmailInput from "../_components/EmailInput"; -import PasswordInput from "../_components/PasswordInput"; -import NameInput from "../_components/NameInput"; -import Dropdown from "../_components/UnivInput"; -import styled from "styled-components"; -import onSubmit from "../_lib/signup"; +} from '../_components/styles'; +import EmailInput from '../_components/EmailInput'; +import PasswordInput from '../_components/PasswordInput'; +import NameInput from '../_components/NameInput'; +import Dropdown from '../_components/Dropdown'; +import styled from 'styled-components'; +import onSubmit from '../_lib/signup'; const DropdownContainer = styled.div` display: flex; @@ -49,12 +49,12 @@ export default function Main() { try { const result = await onSubmit(state, formData); // 수정된 타입에 맞게 호출 setState(result); - if (result.message === "signup_success") { - console.log("Signup successful!"); + if (result.message === 'signup_success') { + console.log('Signup successful!'); console.log(result.formData); } } catch (error) { - console.error("Error during signup:", error); + console.error('Error during signup:', error); } finally { setPending(false); } @@ -70,12 +70,12 @@ export default function Main() { {state.message && ( - - {state.message === "no_id" && "아이디를 입력해주세요"} - {state.message === "no_password" && "비밀번호를 입력해주세요"} - {state.message === "no_email" && "이메일을 입력해주세요"} - {state.message === "user_exists" && "이미 존재하는 사용자입니다"} - {state.message === "server_error" && "서버 오류가 발생했습니다"} + + {state.message === 'no_id' && '아이디를 입력해주세요'} + {state.message === 'no_password' && '비밀번호를 입력해주세요'} + {state.message === 'no_email' && '이메일을 입력해주세요'} + {state.message === 'user_exists' && '이미 존재하는 사용자입니다'} + {state.message === 'server_error' && '서버 오류가 발생했습니다'} )} @@ -85,21 +85,21 @@ export default function Main() { console.log("Selected:", value)} + onSelect={(value) => console.log('Selected:', value)} /> console.log("Selected:", value)} + onSelect={(value) => console.log('Selected:', value)} /> diff --git a/src/app/vote/[theme]/page.tsx b/src/app/vote/[theme]/page.tsx new file mode 100644 index 0000000..30145f4 --- /dev/null +++ b/src/app/vote/[theme]/page.tsx @@ -0,0 +1,133 @@ +'use client'; + +import styled from 'styled-components'; +import { useRouter } from 'next/navigation'; +import { useParams } from 'next/navigation'; +import { useState } from 'react'; +import Text from '@/components/atoms/Text'; +import Card from '@/components/Card'; +import CTAButton from '@/components/atoms/CTAButton'; +import { ThemeType, Candidate } from '@/data/types'; +import { candidateData } from '@/data/candidates'; +// 스타일 컴포넌트 정의 +const Container = styled.div` + display: flex; + flex-direction: column; + justify-content: center; + height: 100vh; + margin: 0 1rem; + gap: 1rem; +`; + +const CardWrapper = styled.div` + display: flex; + flex-wrap: wrap; + gap: 1rem; + justify-content: center; +`; + +// StyledCard: Card를 확장하여 스타일링 +const StyledCard = styled(Card).withConfig({ + shouldForwardProp: (prop) => !['isSelected'].includes(prop), +})<{ isSelected: boolean }>` + display: flex; + align-items: center; + justify-content: center; + width: 10rem; + height: 6rem; + border: 1px solid + ${({ isSelected, theme }) => + isSelected ? theme.colors.primary : theme.colors.gray[300]}; + border-radius: 8px; + background-color: ${({ isSelected, theme }) => + isSelected ? theme.colors.primaryLight : '#fff'}; + cursor: pointer; + transition: + background-color 0.3s, + border-color 0.3s; + + &:hover { + background-color: ${({ theme }) => theme.colors.primaryLight}; + } +`; + +const ButtonWrapper = styled.div` + display: flex; + gap: 1rem; + justify-content: center; +`; + +const ActionButton = styled.button` + padding: 0.5rem 1rem; + background-color: ${({ theme }) => theme.colors.primary}; + color: #fff; + border: none; + border-radius: 5px; + cursor: pointer; + + &:disabled { + background-color: ${({ theme }) => theme.colors.gray[300]}; + cursor: not-allowed; + } +`; + +export default function VotePage() { + const router = useRouter(); + const params = useParams(); // 동적 라우트 매개변수 접근 + const [selectedCandidate, setSelectedCandidate] = useState( + null, + ); + const [voteConfirmed, setVoteConfirmed] = useState(false); + + const handleBack = () => { + router.push('/'); + }; + + const handleVoteResult = () => { + router.push(`/vote/${params.theme}/result`); + }; + + const handleVote = () => { + if (selectedCandidate) { + alert(`${selectedCandidate.name}에게 투표되었습니다.`); + setVoteConfirmed(true); + } + }; + + const selectedTheme = Array.isArray(params.theme) + ? params.theme[0] + : params.theme; + + const candidates = candidateData[selectedTheme as ThemeType]; + const pageTitle = + selectedTheme === 'front-end' + ? 'FE 파트장 투표' + : selectedTheme === 'back-end' + ? 'BE 파트장 투표' + : '데모데이 투표'; + + return ( + + {pageTitle} + + {candidates.map((candidate) => ( + setSelectedCandidate(candidate)} + /> + ))} + + + + + + + ); +} diff --git a/src/app/vote/[theme]/result/page.tsx b/src/app/vote/[theme]/result/page.tsx new file mode 100644 index 0000000..86d38ed --- /dev/null +++ b/src/app/vote/[theme]/result/page.tsx @@ -0,0 +1,114 @@ +'use client'; + +import styled from 'styled-components'; +import { useRouter } from 'next/navigation'; +import { useParams } from 'next/navigation'; +import { ThemeType, Candidate } from '@/data/types'; + +const Container = styled.div` + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + height: 100vh; + margin: 0 1rem; + gap: 1rem; +`; + +const Header = styled.div` + text-align: center; + margin-bottom: 1rem; +`; + +const ResultList = styled.ul` + list-style: none; + padding: 0; + margin: 0; + width: 100%; + max-width: 500px; +`; + +const ResultItem = styled.li` + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.5rem 1rem; + border: 1px solid ${({ theme }) => theme.colors.gray[300]}; + border-radius: 5px; + margin-bottom: 0.5rem; + background-color: ${({ theme }) => theme.colors.gray[50]}; +`; + +const TotalVotes = styled.div` + margin-top: 1rem; + font-size: 1.2rem; + font-weight: bold; +`; + +const BackButton = styled.button` + margin-top: 2rem; + padding: 0.5rem 1rem; + background-color: ${({ theme }) => theme.colors.primary}; + color: #fff; + border: none; + border-radius: 5px; + cursor: pointer; +`; + +export default function VoteResultPage() { + const router = useRouter(); + const params = useParams(); + + // 임시 투표 결과 데이터 (테마별) + const resultData: Record = { + 'front-end': [ + { name: '최지원', votes: 10 }, + { name: '유선', votes: 8 }, + { name: '윤영준', votes: 6 }, + { name: '박지수', votes: 5 }, + ], + 'back-end': [ + { name: '황서아', votes: 12 }, + { name: '최서지', votes: 9 }, + { name: '임가현', votes: 7 }, + { name: '이한슬', votes: 4 }, + ], + 'demo-day': [ + { name: '페달지니', votes: 15 }, + { name: '케이크웨이', votes: 12 }, + { name: '커피딜', votes: 8 }, + { name: '엔젤브릿지', votes: 6 }, + { name: '포토그라운드', votes: 4 }, + ], + }; + + const selectedTheme = params.theme as ThemeType; + const results = resultData[selectedTheme] || []; + const totalVotes = results.reduce((sum, item) => sum + item.votes, 0); + + return ( + +
+

+ {selectedTheme === 'front-end' + ? 'FE 파트장 투표 결과' + : selectedTheme === 'back-end' + ? 'BE 파트장 투표 결과' + : '데모데이 투표 결과'} +

+
+ + {results.map((result, index) => ( + + {result.name} + {result.votes}표 + + ))} + + 총 투표 수: {totalVotes} + router.push(`/vote/${params.theme}`)}> + 투표 페이지로 돌아가기 + +
+ ); +} diff --git a/src/app/vote/part/page.tsx b/src/app/vote/part/page.tsx new file mode 100644 index 0000000..d600088 --- /dev/null +++ b/src/app/vote/part/page.tsx @@ -0,0 +1,52 @@ +'use client'; + +import styled from 'styled-components'; +import { useRouter } from 'next/navigation'; +import { useParams } from 'next/navigation'; +import Text from '@/components/atoms/Text'; +import Card from '@/components/Card'; + +// 스타일 컴포넌트 정의 +const Container = styled.div` + display: flex; + flex-direction: column; + justify-content: center; + height: 100vh; + margin: 0 1rem; + gap: 1rem; +`; + +const CardWrapper = styled.div` + display: flex; + flex-wrap: wrap; + gap: 1rem; + justify-content: center; +`; + +export default function VotePage() { + const router = useRouter(); + const params = useParams(); // 동적 라우트 매개변수 접근 + + const pageTitle = '파트장 투표'; + const handleNavigation = (path: string) => { + router.push(`/vote/${path}`); + }; + return ( + + {pageTitle} + + handleNavigation('front-end')} + /> + + handleNavigation('back-end')} + /> + + + ); +} From 16dc1a73eee0c212d39d7243aac057775d1920e7 Mon Sep 17 00:00:00 2001 From: hiwon-lee <84234411+hiwon-lee@users.noreply.github.com> Date: Mon, 30 Dec 2024 03:12:29 +0900 Subject: [PATCH 18/30] =?UTF-8?q?=F0=9F=9A=9A=20move:=20=20=EB=93=9C?= =?UTF-8?q?=EB=A1=AD=EB=8B=A4=EC=9A=B4=EB=B0=95=EC=8A=A4=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EB=B3=80=EA=B2=BD=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/_components/Dropdown.tsx | 121 +++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 src/app/_components/Dropdown.tsx diff --git a/src/app/_components/Dropdown.tsx b/src/app/_components/Dropdown.tsx new file mode 100644 index 0000000..4f0fed0 --- /dev/null +++ b/src/app/_components/Dropdown.tsx @@ -0,0 +1,121 @@ +import { useState } from "react"; +import styled from "styled-components"; +import DownChevronIcon from "@/assets/DownChevronIcon"; +import Text from "@/components/atoms/Text"; + +export interface Option { + value: string; + label: string; +} + +const Container = styled.div` + display: flex; + flex-direction: column; + position: relative; + width: 100%; +`; + +const FilterWrapper = styled.div<{ $isOpen: boolean }>` + display: flex; + align-items: center; + justify-content: space-between; + padding: 0.5rem 1rem; + background: transparent; + border: 1px solid ${({ theme }) => theme.colors.gray[200]}; + border-radius: ${({ $isOpen }) => ($isOpen ? "0.5rem 0.5rem 0 0" : "0.5rem")}; + cursor: pointer; +`; + +const FilterText = styled(Text)` + color: ${({ theme }) => theme.colors.gray[200]}; +`; + +const Backdrop = styled.div` + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: transparent; + z-index: 20; +`; + +const OptionWrapper = styled.div` + position: absolute; + top: 100%; + left: 0; + width: 100%; + background: ${({ theme }) => theme.colors.background.primary}; + border: 1px solid ${({ theme }) => theme.colors.gray[200]}; + border-top: none; + border-radius: 0 0 0.5rem 0.5rem; + z-index: 21; +`; + +const OptionItem = styled.button` + width: 100%; + padding: 0.5rem 1rem; + background: transparent; + border: none; + text-align: start; + cursor: pointer; + + &:hover { + background-color: ${({ theme }) => theme.colors.gray[100]}; + } +`; + +interface DropdownProps { + options: Option[]; + placeholder?: string; + onSelect: (value: string) => void; +} + +export default function Dropdown({ + options, + placeholder = "Select an option", + onSelect, +}: DropdownProps) { + const [isOpen, setIsOpen] = useState(false); + const [selectedValue, setSelectedValue] = useState(null); + + const handleOpen = () => setIsOpen(true); + const handleClose = () => setIsOpen(false); + + const handleSelect = (value: string) => { + setSelectedValue(value); + onSelect(value); + handleClose(); + }; + + const currentLabel = options.find( + (option) => option.value === selectedValue, + )?.label; + + return ( + + + + {currentLabel || placeholder} + + + + + {isOpen && ( + <> + + + {options.map((option) => ( + handleSelect(option.value)} + > + {option.label} + + ))} + + + )} + + ); +} From 322c725aac18f3843b02dc8f2e739759acd30396 Mon Sep 17 00:00:00 2001 From: Dahye Date: Thu, 2 Jan 2025 20:27:08 +0900 Subject: [PATCH 19/30] =?UTF-8?q?=F0=9F=92=84=20ui:=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EB=86=92=EC=9D=B4=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/_components/Main.tsx | 21 ++++++++------------- src/app/page.tsx | 11 ++++------- src/app/signin/page.tsx | 2 +- 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/src/app/_components/Main.tsx b/src/app/_components/Main.tsx index 754808b..ccdadea 100644 --- a/src/app/_components/Main.tsx +++ b/src/app/_components/Main.tsx @@ -1,33 +1,28 @@ -"use client"; +'use client'; -import CTAButton from "@/components/atoms/CTAButton"; -import Text from "@/components/atoms/Text"; -import { useRouter } from "next/navigation"; -import styled from "styled-components"; +import CTAButton from '@/components/atoms/CTAButton'; +import Text from '@/components/atoms/Text'; +import { useRouter } from 'next/navigation'; +import styled from 'styled-components'; const Container = styled.div` display: flex; flex-direction: column; justify-content: center; - height: 100vh; + height: 100%; margin: 0 1rem; gap: 1rem; `; -const DropdownContainer = styled.div` - display: flex; - gap: 0.5rem; - padding: 1rem 0; -`; export default function Main() { const router = useRouter(); const handleSignupClick = () => { - router.push("/signup"); + router.push('/signup'); }; const handleSigninClick = () => { - router.push("/signin"); + router.push('/signin'); }; return ( diff --git a/src/app/page.tsx b/src/app/page.tsx index b294317..b447e3f 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,16 +1,13 @@ -import styles from "@/app/(beforeLogin)/_component/main.module.css"; - -import { redirect } from "next/navigation"; -import Main from "./_components/Main"; -import { getSession } from "@/lib/session"; +import { redirect } from 'next/navigation'; +import Main from './_components/Main'; +import { getSession } from '@/lib/session'; export default async function Home() { // 로그인 페이지로 리다이렉트 const session = await getSession(); // 유저가 있으면 홈으로 리다이렉트 (after login 상태) if (session?.user) { - redirect("/home"); - return null; + redirect('/home'); } return
; } diff --git a/src/app/signin/page.tsx b/src/app/signin/page.tsx index 0a7dc28..b5f72f8 100644 --- a/src/app/signin/page.tsx +++ b/src/app/signin/page.tsx @@ -14,7 +14,7 @@ const Container = styled.div` display: flex; flex-direction: column; justify-content: center; - height: 100vh; + height: 100%; margin: 0 1rem; gap: 1rem; `; From 3afaadcb8dfb23f37437147bf9bfa936eed269fa Mon Sep 17 00:00:00 2001 From: Dahye Date: Thu, 2 Jan 2025 20:30:55 +0900 Subject: [PATCH 20/30] =?UTF-8?q?=F0=9F=90=9B=20fix:=20Input=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/signin/InputList.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/signin/InputList.tsx b/src/app/signin/InputList.tsx index 10be756..deab9ce 100644 --- a/src/app/signin/InputList.tsx +++ b/src/app/signin/InputList.tsx @@ -1,6 +1,6 @@ -import styled from "styled-components"; -import EmailIcon from "@/assets/EmailIcon"; -import PasswordIcon from "@/assets/PasswordIcon"; +import styled from 'styled-components'; +import EmailIcon from '@/assets/EmailIcon'; +import PasswordIcon from '@/assets/PasswordIcon'; const Container = styled.div` display: flex; @@ -37,7 +37,7 @@ export default function InputList() { - + From f3d0f1caaacafe17f6b1ec0baa9456369a28145b Mon Sep 17 00:00:00 2001 From: Dahye Date: Fri, 3 Jan 2025 05:21:03 +0900 Subject: [PATCH 21/30] =?UTF-8?q?=E2=9C=A8=20feat:=20=ED=9A=8C=EC=9B=90?= =?UTF-8?q?=EA=B0=80=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/_components/styles.ts | 14 +- src/app/_lib/signup.ts | 77 +++------- src/app/signup/page.tsx | 187 ++++++++++++++--------- src/components/atoms/CTAButton/index.tsx | 4 +- 4 files changed, 143 insertions(+), 139 deletions(-) diff --git a/src/app/_components/styles.ts b/src/app/_components/styles.ts index 6660887..780187a 100644 --- a/src/app/_components/styles.ts +++ b/src/app/_components/styles.ts @@ -1,18 +1,16 @@ -import styled from "styled-components"; +import styled from 'styled-components'; const Section = styled.section` - padding-left: 1.25rem; - padding-right: 1.25rem; + padding: 1.25rem; `; export const AccountSection = styled(Section)` - padding-top: 2.5rem; + display: flex; + flex-direction: column; + gap: 1rem; `; -export const UserSection = styled(Section)` - padding-top: 3rem; - padding-bottom: 4rem; -`; +export const UserSection = styled(Section)``; export const ButtonWrapper = styled.div` padding: 0 1.25rem 1rem 1.25rem; diff --git a/src/app/_lib/signup.ts b/src/app/_lib/signup.ts index d5b066b..187318d 100644 --- a/src/app/_lib/signup.ts +++ b/src/app/_lib/signup.ts @@ -1,70 +1,35 @@ -"use server"; +'use server'; + +import { redirect } from 'next/navigation'; // [회원 가입 처리] -const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:4000"; -// type 합치기(signup) -type FormState = { - message: string | null; - formData: { - id: string; - password: string; - email: string; - } | null; -}; -export default async function onSubmit( - prevState: FormState, - formData: FormData, -): Promise { - if (!formData.get("id") || !(formData.get("id") as string)?.trim()) { - return { message: "no_id", formData: null }; - } - if ( - !formData.get("password") || - !(formData.get("password") as string)?.trim() - ) { - return { message: "no_password", formData: null }; - } - if (!formData.get("email") || !(formData.get("email") as string)?.trim()) { - return { message: "no_email", formData: null }; - } +const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:4000'; - let shouldRedirect = false; +export default async function signUp( + formData: FormData, +): Promise<{ message?: string }> { try { - console.log(BASE_URL); - const response = await fetch(`${BASE_URL}/users`, { - method: "POST", + const response = await fetch(`${BASE_URL}/api/member/join`, { + method: 'POST', body: JSON.stringify({ - id: formData.get("id"), - password: formData.get("password"), - email: formData.get("email"), + name: formData.get('name'), + username: formData.get('username'), + password: formData.get('password'), + email: formData.get('email'), + part: formData.get('part'), + team: formData.get('team'), }), - headers: { - "Content-Type": "application/json", - }, + headers: { 'Content-Type': 'application/json' }, }); - console.log(response); - if (response.status === 403) { - return { message: "user_exists", formData: null }; - } + console.log(response); if (!response.ok) { - throw new Error("Failed to sign up"); + throw new Error('Failed to sign up'); } - - shouldRedirect = true; - - // 회원가입 성공 - return { - message: "signup_success", - formData: { - id: formData.get("id") as string, - password: formData.get("password") as string, - email: formData.get("email") as string, - }, - }; } catch (err) { - console.error("Sign-up Error:", err); - return { ...prevState, message: "server_error" }; + return { message: 'server_error' }; } + + return redirect('/signin'); } diff --git a/src/app/signup/page.tsx b/src/app/signup/page.tsx index cb8c203..10cb4ef 100644 --- a/src/app/signup/page.tsx +++ b/src/app/signup/page.tsx @@ -1,20 +1,20 @@ 'use client'; -import { useState } from 'react'; +import { ReactNode, useState } from 'react'; import CTAButton from '@/components/atoms/CTAButton'; import Text from '@/components/atoms/Text'; import { AccountSection, ButtonWrapper, - DivideLine, UserSection, } from '../_components/styles'; -import EmailInput from '../_components/EmailInput'; -import PasswordInput from '../_components/PasswordInput'; -import NameInput from '../_components/NameInput'; import Dropdown from '../_components/Dropdown'; import styled from 'styled-components'; -import onSubmit from '../_lib/signup'; +import signUp from '../_lib/signup'; +import { Input, InputContainer } from '@/styles/input'; +import PersonIcon from '@/assets/PersonIcon'; +import PasswordIcon from '@/assets/PasswordIcon'; +import EmailIcon from '@/assets/EmailIcon'; const DropdownContainer = styled.div` display: flex; @@ -22,20 +22,18 @@ const DropdownContainer = styled.div` padding: 1rem 0; `; -type FormState = { - message: string | null; - formData: { - id: string; - password: string; - email: string; - } | null; -}; - export default function Main() { - // 초기 상태에 formData를 null로 설정 - const [state, setState] = useState({ - message: null, - formData: null, + // const [state, setState] = useState({ + // message: null, + // }); + + const [data, setData] = useState({ + username: '', + password: '', + email: '', + name: '', + team: '', + part: '', }); const [pending, setPending] = useState(false); @@ -43,16 +41,17 @@ export default function Main() { const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); - const formData = new FormData(e.currentTarget); + const formData = new FormData(); + formData.set('username', data.username); + formData.set('password', data.password); + formData.set('email', data.email); + formData.set('team', data.team); + formData.set('part', data.part); setPending(true); + try { - const result = await onSubmit(state, formData); // 수정된 타입에 맞게 호출 - setState(result); - if (result.message === 'signup_success') { - console.log('Signup successful!'); - console.log(result.formData); - } + await signUp(formData); } catch (error) { console.error('Error during signup:', error); } finally { @@ -60,54 +59,94 @@ export default function Main() { } }; + const FIELD_LIST: { + field: 'username' | 'password' | 'email' | 'name'; + placeholder: string; + type: string; + icon: ({ size }: { size: string }) => ReactNode; + }[] = [ + { + field: 'name', + placeholder: '이름', + type: 'text', + icon: PersonIcon, + }, + { + field: 'username', + placeholder: '아이디', + type: 'text', + icon: PersonIcon, + }, + { + field: 'password', + placeholder: '비밀번호', + type: 'password', + icon: PasswordIcon, + }, + { + field: 'email', + placeholder: '이메일', + type: 'email', + icon: EmailIcon, + }, + ]; + return ( -
-
- - SIGN UP! - - - - - {state.message && ( - - {state.message === 'no_id' && '아이디를 입력해주세요'} - {state.message === 'no_password' && '비밀번호를 입력해주세요'} - {state.message === 'no_email' && '이메일을 입력해주세요'} - {state.message === 'user_exists' && '이미 존재하는 사용자입니다'} - {state.message === 'server_error' && '서버 오류가 발생했습니다'} - - )} - - - - 팀 명 / 파트 - - console.log('Selected:', value)} - /> - - console.log('Selected:', value)} - /> - - - - - - - -
+
+ + SIGN UP! + + {FIELD_LIST.map((fieldItem) => { + const { placeholder, field, type } = fieldItem; + const value = data[field]; + + return ( + + + { + const newData = { ...data }; + newData[field] = event.target.value; + setData(newData); + }} + placeholder={placeholder} + type={type} + required + /> + + ); + })} + + + + + setData({ ...data, team: value })} + /> + + setData({ ...data, part: value })} + /> + + + + + + +
); } diff --git a/src/components/atoms/CTAButton/index.tsx b/src/components/atoms/CTAButton/index.tsx index ffeff4e..2ca81d3 100644 --- a/src/components/atoms/CTAButton/index.tsx +++ b/src/components/atoms/CTAButton/index.tsx @@ -38,18 +38,20 @@ const ButtonText = styled(Text)` `; export default function CTAButton({ + type = 'button', text, variant = 'primary', disabled = false, onClick = () => {}, }: { + type: 'button' | 'submit'; text: string; variant?: Variant; disabled?: boolean; onClick?: () => void; }) { return ( -