diff --git a/.eslintrc.json b/.eslintrc.json index 786aab69..55e7e8e6 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,9 +1,10 @@ { "extends": ["next/core-web-vitals", "prettier"], - "plugins": ["prettier", "react-hooks"], + "plugins": ["prettier", "react-hooks", "@typescript-eslint"], "rules": { "prettier/prettier": "error", - "no-unused-vars": "error" + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": "error" }, "settings": { "import/resolver": { diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..5fd9f3b0 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +*.ts text eol=lf +*.tsx text eol=lf \ No newline at end of file diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml index 8eaf3b2b..10a5504a 100644 --- a/.github/workflows/chromatic.yml +++ b/.github/workflows/chromatic.yml @@ -2,7 +2,14 @@ name: 'Chromatic Deployment' # Event for the workflow -on: push +on: + push: + branches: + - develop + pull_request: + branches: + - '**' + - '!main' # List of jobs jobs: diff --git a/.github/workflows/ci-develop.yml b/.github/workflows/ci-develop.yml deleted file mode 100644 index 548bb7e7..00000000 --- a/.github/workflows/ci-develop.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: CI for develop - -on: - pull_request: - branches: - - develop - push: - branches: - - develop - -jobs: - ci-develop: - name: Lint, Test, and Build (develop) - runs-on: ubuntu-latest - strategy: - matrix: - node-version: [18, 20] - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up Node.js - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - - - name: Install dependencies - run: npm install - - - name: Run ESLint - run: npm run lint - - - name: Run Tests - run: npm test - - - name: Build Next.js app - run: npm run build - - - name: Build Storybook - run: npm run build-storybook diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..c239d990 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,91 @@ +name: CI + +on: + pull_request: + branches: + - '**' + - '!main' + push: + branches: + - develop + +jobs: + ci: + name: Lint, Test, and Build + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [18, 20] + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + + - name: Install dependencies + run: npm install + + - name: Run ESLint + run: npm run lint + + - name: Run Tests + run: npm test + + - name: Build Next.js app + run: npm run build + + - name: Build Storybook + run: npm run build-storybook + + notify-discord: + needs: ci + runs-on: ubuntu-latest + if: success() + steps: + - name: Send Discord Notification + env: + WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} + DATA: > + { + "embeds": [ + { + "title": "${{ + format('{0}', + (github.base_ref == 'develop' || github.ref_name == 'develop') + && '🚀 Develop 브랜치 CI 알림' + || '🎉 새 작업 CI 알림' + ) + }}", + "description": "${{ + format('{0}', + github.event_name == 'pull_request' + && (github.base_ref == 'develop' + && format('Develop 브랜치로 새로운 PR이 등록되었습니다! ({0} → develop)', github.head_ref) + || format('새로운 PR이 등록되었습니다! ({0} → {1})', github.head_ref, github.base_ref) + ) + || 'Develop 브랜치에 Push가 완료되었습니다!' + ) + }}", + "url": "${{ github.event.pull_request.html_url || github.event.head_commit.url }}", + "color": 5814783, + "fields": [ + { + "name": "Repository", + "value": "${{ github.repository }}" + }, + { + "name": "Branch", + "value": "${{ github.event_name == 'pull_request' && github.head_ref || github.ref_name }}" + } + ] + } + ] + } + run: | + curl -X POST \ + -H "Content-Type: application/json" \ + -d "$DATA" \ + $WEBHOOK_URL diff --git a/.github/workflows/main-deploy.yml b/.github/workflows/main-deploy.yml index 9359507a..0d2b828b 100644 --- a/.github/workflows/main-deploy.yml +++ b/.github/workflows/main-deploy.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [18.x, 20.x] # Node.js 18.x와 20.x 버전으로 테스트 + node-version: [18.x, 20.x] steps: - name: Checkout code uses: actions/checkout@v3 @@ -22,10 +22,41 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v3 with: - node-version: ${{ matrix.node-version }} # 매트릭스를 사용하여 버전 설정 + node-version: ${{ matrix.node-version }} - name: Install dependencies run: npm install - name: Build Next.js app run: npm run build + + notify-discord: + needs: deploy-production + runs-on: ubuntu-latest + if: success() + steps: + - name: Send Discord Notification + env: + WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} + DATA: > + { + "embeds": [ + { + "title": "🚀 main 브랜치 알림", + "description": "${{ github.event_name == 'pull_request' && '새로운 PR이 성공적으로 등록되었습니다!' || 'Push가 성공적으로 완료되었습니다!' }}", + "url": "${{ github.event.pull_request.html_url || github.event.head_commit.url }}", + "color": 5814783, + "fields": [ + { + "name": "Repository", + "value": "${{ github.repository }}" + } + ] + } + ] + } + run: | + curl -X POST \ + -H "Content-Type: application/json" \ + -d "$DATA" \ + $WEBHOOK_URL diff --git a/.storybook/preview.ts b/.storybook/preview.ts index 6aa6b1f8..4580843a 100644 --- a/.storybook/preview.ts +++ b/.storybook/preview.ts @@ -9,6 +9,31 @@ const preview: Preview = { date: /Date$/i, }, }, + viewport: { + viewports: { + mobile: { + name: 'Mobile', + styles: { + width: '375px', + height: '1168px', + }, + }, + tablet: { + name: 'Tablet', + styles: { + width: '744px', + height: '1343px', + }, + }, + desktop: { + name: 'Desktop', + styles: { + width: '1920px', + height: '1080px', + }, + }, + }, + }, }, }; diff --git a/global.d.ts b/global.d.ts new file mode 100644 index 00000000..776b4da1 --- /dev/null +++ b/global.d.ts @@ -0,0 +1,9 @@ +declare global { + interface Window { + daum: { + Postcode: new (config: any) => any; + }; + } +} + +export {}; diff --git a/jest.config.js b/jest.config.js index 1b1168b9..679e6597 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,9 +1,18 @@ -module.exports = { - testEnvironment: "jest-environment-jsdom", - transform: { - "^.+.tsx?$": "ts-jest", - }, - moduleNameMapper: { - "^@/(.*)$": "/$1", - }, +const nextJest = require('next/jest'); + +/** @type {import('jest').Config} */ +const createJestConfig = nextJest({ + // Provide the path to your Next.js app to load next.config.js and .env files in your test environment + dir: './', +}); + +// Add any custom config to be passed to Jest +const config = { + coverageProvider: 'v8', + testEnvironment: 'jsdom', + // Add more setup options before each test is run + // setupFilesAfterEnv: ['/jest.setup.ts'], }; + +// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async +module.exports = createJestConfig(config); diff --git a/next.config.ts b/next.config.ts index e9ffa308..0ccb0755 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,7 +1,9 @@ -import type { NextConfig } from "next"; +import type { NextConfig } from 'next'; const nextConfig: NextConfig = { - /* config options here */ + images: { + domains: ['sprint-fe-project.s3.ap-northeast-2.amazonaws.com'], + }, }; export default nextConfig; diff --git a/package-lock.json b/package-lock.json index a5a85c96..ebe27e49 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,3 +1,4 @@ + { "name": "codeit3-fe", "version": "0.1.0", @@ -9,12 +10,18 @@ "version": "0.1.0", "dependencies": { "@headlessui/react": "^2.2.0", + "@hookform/resolvers": "^3.9.1", "@tanstack/react-query": "^5.61.3", "@tanstack/react-query-devtools": "^5.61.3", + "@types/react-datepicker": "^6.2.0", "axios": "^1.7.8", "next": "15.0.3", "react": "^18.3.1", + "react-datepicker": "^7.5.0", "react-dom": "^18.3.1", + "react-hook-form": "^7.53.2", + "tailwind-merge": "^2.5.5", + "zod": "^3.23.8", "zustand": "^5.0.1" }, "devDependencies": { @@ -34,6 +41,8 @@ "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", + "@typescript-eslint/eslint-plugin": "^8.16.0", + "@typescript-eslint/parser": "^8.16.0", "autoprefixer": "^10.4.20", "chromatic": "^11.19.0", "eslint": "^8.57.1", @@ -2752,6 +2761,15 @@ "react-dom": "^18 || ^19 || ^19.0.0-rc" } }, + "node_modules/@hookform/resolvers": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.9.1.tgz", + "integrity": "sha512-ud2HqmGBM0P0IABqoskKWI6PEf6ZDDBZkFqe2Vnl+mTHCEHzr3ISjjZyCwTjC/qpL25JC9aIDkloQejvMeq0ug==", + "license": "MIT", + "peerDependencies": { + "react-hook-form": "^7.0.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", @@ -5494,20 +5512,29 @@ "version": "15.7.13", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", - "devOptional": true, "license": "MIT" }, "node_modules/@types/react": { "version": "18.3.12", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz", "integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==", - "devOptional": true, "license": "MIT", "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" } }, + "node_modules/@types/react-datepicker": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@types/react-datepicker/-/react-datepicker-6.2.0.tgz", + "integrity": "sha512-+JtO4Fm97WLkJTH8j8/v3Ldh7JCNRwjMYjRaKh4KHH0M3jJoXtwiD3JBCsdlg3tsFIw9eQSqyAPeVDN2H2oM9Q==", + "license": "MIT", + "dependencies": { + "@floating-ui/react": "^0.26.2", + "@types/react": "*", + "date-fns": "^3.3.1" + } + }, "node_modules/@types/react-dom": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz", @@ -5560,31 +5587,495 @@ "dev": true, "license": "MIT", "dependencies": { - "@types/yargs-parser": "*" + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.16.0.tgz", + "integrity": "sha512-5YTHKV8MYlyMI6BaEG7crQ9BhSc8RxzshOReKwZwRWN0+XvvTOm+L/UYLCYxFpfwYuAAqhxiq4yae0CMFwbL7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.16.0", + "@typescript-eslint/type-utils": "8.16.0", + "@typescript-eslint/utils": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0", + "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" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.16.0.tgz", + "integrity": "sha512-mwsZWubQvBki2t5565uxF0EYvG+FwdFb8bMtDuGQLdCCnGPrDEDvm1gtfynuKlnpzeBRqdFCkMf9jg1fnAK8sg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.16.0.tgz", + "integrity": "sha512-NzrHj6thBAOSE4d9bsuRNMvk+BvaQvmY4dDglgkgGC0EW/tB3Kelnp3tAKH87GEwzoxgeQn9fNGRyFJM/xd+GQ==", + "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/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.16.0.tgz", + "integrity": "sha512-E2+9IzzXMc1iaBy9zmo+UYvluE3TW7bCGWSF41hVWUE01o8nzr1rvOQYSxelxr6StUvRcTMe633eY8mXASMaNw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0", + "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" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.16.0.tgz", + "integrity": "sha512-C1zRy/mOL8Pj157GiX4kaw7iyRLKfJXBR3L82hk5kS/GyHcOFmy4YUq/zfZti72I9wnuQtA/+xzft4wCC8PJdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.16.0", + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/typescript-estree": "8.16.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" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.16.0.tgz", + "integrity": "sha512-pq19gbaMOmFE3CbL0ZB8J8BFCo2ckfHBfaIsaOZgBIF4EoISJIdLX5xRhd0FGB0LlHReNRuzoJoMGpTjq8F2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.16.0", + "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/@typescript-eslint/eslint-plugin/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/eslint-plugin/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/@typescript-eslint/eslint-plugin/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/eslint-plugin/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/eslint-plugin/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/parser": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.16.0.tgz", + "integrity": "sha512-D7DbgGFtsqIPIFMPJwCad9Gfi/hC0PWErRRHFnaCWoEDYi5tQUDiJCTmGUbBiLzjqAck4KcXt9Ayj0CNlIrF+w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "8.16.0", + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/typescript-estree": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0", + "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" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.16.0.tgz", + "integrity": "sha512-mwsZWubQvBki2t5565uxF0EYvG+FwdFb8bMtDuGQLdCCnGPrDEDvm1gtfynuKlnpzeBRqdFCkMf9jg1fnAK8sg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.16.0.tgz", + "integrity": "sha512-NzrHj6thBAOSE4d9bsuRNMvk+BvaQvmY4dDglgkgGC0EW/tB3Kelnp3tAKH87GEwzoxgeQn9fNGRyFJM/xd+GQ==", + "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/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.16.0.tgz", + "integrity": "sha512-E2+9IzzXMc1iaBy9zmo+UYvluE3TW7bCGWSF41hVWUE01o8nzr1rvOQYSxelxr6StUvRcTMe633eY8mXASMaNw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0", + "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" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.16.0.tgz", + "integrity": "sha512-pq19gbaMOmFE3CbL0ZB8J8BFCo2ckfHBfaIsaOZgBIF4EoISJIdLX5xRhd0FGB0LlHReNRuzoJoMGpTjq8F2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.16.0", + "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/@typescript-eslint/parser/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/parser/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/@typescript-eslint/parser/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/parser/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/parser/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/scope-manager": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.15.0.tgz", + "integrity": "sha512-QRGy8ADi4J7ii95xz4UoiymmmMd/zuy9azCaamnZ3FM8T5fZcex8UfJcjkiEZjJSztKfEBe3dZ5T/5RHAmw2mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.15.0", + "@typescript-eslint/visitor-keys": "8.15.0" + }, + "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.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.16.0.tgz", + "integrity": "sha512-IqZHGG+g1XCWX9NyqnI/0CX5LL8/18awQqmkZSl2ynn8F76j579dByc0jhfVSnSnhf7zv76mKBQv9HQFKvDCgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "8.16.0", + "@typescript-eslint/utils": "8.16.0", + "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" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.16.0.tgz", + "integrity": "sha512-mwsZWubQvBki2t5565uxF0EYvG+FwdFb8bMtDuGQLdCCnGPrDEDvm1gtfynuKlnpzeBRqdFCkMf9jg1fnAK8sg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.16.0.tgz", + "integrity": "sha512-NzrHj6thBAOSE4d9bsuRNMvk+BvaQvmY4dDglgkgGC0EW/tB3Kelnp3tAKH87GEwzoxgeQn9fNGRyFJM/xd+GQ==", "dev": true, - "license": "MIT" + "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/eslint-plugin": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.15.0.tgz", - "integrity": "sha512-+zkm9AR1Ds9uLWN3fkoeXgFppaQ+uEVtfOV62dDmsy9QCNqlRHWNEck4yarvRNrvRcHQLGfqBNui3cimoz8XAg==", + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.16.0.tgz", + "integrity": "sha512-E2+9IzzXMc1iaBy9zmo+UYvluE3TW7bCGWSF41hVWUE01o8nzr1rvOQYSxelxr6StUvRcTMe633eY8mXASMaNw==", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.15.0", - "@typescript-eslint/type-utils": "8.15.0", - "@typescript-eslint/utils": "8.15.0", - "@typescript-eslint/visitor-keys": "8.15.0", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0", + "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": { @@ -5594,28 +6085,23 @@ "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" - }, "peerDependenciesMeta": { "typescript": { "optional": true } } }, - "node_modules/@typescript-eslint/parser": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.15.0.tgz", - "integrity": "sha512-7n59qFpghG4uazrF9qtGKBZXn7Oz4sOMm8dwNWDQY96Xlm2oX67eipqcblDj+oY1lLCbf1oltMZFpUso66Kl1A==", + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.16.0.tgz", + "integrity": "sha512-C1zRy/mOL8Pj157GiX4kaw7iyRLKfJXBR3L82hk5kS/GyHcOFmy4YUq/zfZti72I9wnuQtA/+xzft4wCC8PJdA==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.15.0", - "@typescript-eslint/types": "8.15.0", - "@typescript-eslint/typescript-estree": "8.15.0", - "@typescript-eslint/visitor-keys": "8.15.0", - "debug": "^4.3.4" + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.16.0", + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/typescript-estree": "8.16.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5633,15 +6119,15 @@ } } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.15.0.tgz", - "integrity": "sha512-QRGy8ADi4J7ii95xz4UoiymmmMd/zuy9azCaamnZ3FM8T5fZcex8UfJcjkiEZjJSztKfEBe3dZ5T/5RHAmw2mA==", + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.16.0.tgz", + "integrity": "sha512-pq19gbaMOmFE3CbL0ZB8J8BFCo2ckfHBfaIsaOZgBIF4EoISJIdLX5xRhd0FGB0LlHReNRuzoJoMGpTjq8F2CQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.15.0", - "@typescript-eslint/visitor-keys": "8.15.0" + "@typescript-eslint/types": "8.16.0", + "eslint-visitor-keys": "^4.2.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5651,32 +6137,73 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.15.0.tgz", - "integrity": "sha512-UU6uwXDoI3JGSXmcdnP5d8Fffa2KayOhUUqr/AiBnG1Gl7+7ut/oyagVeSkh7bxQ0zSXV9ptRh/4N15nkCqnpw==", + "node_modules/@typescript-eslint/type-utils/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": { - "@typescript-eslint/typescript-estree": "8.15.0", - "@typescript-eslint/utils": "8.15.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" - }, + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils/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": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/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" }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/@typescript-eslint/type-utils/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" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "engines": { + "node": ">= 6" + } + }, + "node_modules/@typescript-eslint/type-utils/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/types": { @@ -8276,7 +8803,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "devOptional": true, "license": "MIT" }, "node_modules/damerau-levenshtein": { @@ -8355,6 +8881,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/debug": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", @@ -14014,7 +14550,6 @@ "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" @@ -15153,7 +15688,6 @@ "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", @@ -15332,6 +15866,22 @@ "node": ">=0.10.0" } }, + "node_modules/react-datepicker": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-7.5.0.tgz", + "integrity": "sha512-6MzeamV8cWSOcduwePHfGqY40acuGlS1cG//ePHT6bVbLxWyqngaStenfH03n1wbzOibFggF66kWaBTb1SbTtQ==", + "license": "MIT", + "dependencies": { + "@floating-ui/react": "^0.26.23", + "clsx": "^2.1.1", + "date-fns": "^3.6.0", + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17 || ^18", + "react-dom": "^16.9.0 || ^17 || ^18" + } + }, "node_modules/react-docgen": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-7.1.0.tgz", @@ -15377,11 +15927,26 @@ "react": "^18.3.1" } }, + "node_modules/react-hook-form": { + "version": "7.53.2", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.53.2.tgz", + "integrity": "sha512-YVel6fW5sOeedd1524pltpHX+jgU2u3DSDtXEaBORNdqiNrsX/nUI/iGXONegttg0mJVnfrIkiV0cmTU6Oo2xw==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18 || ^19" + } + }, "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/react-refresh": { @@ -16940,6 +17505,15 @@ "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==", "license": "MIT" }, + "node_modules/tailwind-merge": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.5.tgz", + "integrity": "sha512-0LXunzzAZzo0tEPxV3I297ffKZPlKDrjj7NXphC8V5ak9yHC5zRmxnOe2m/Rd/7ivsOMJe3JZ2JVocoDdQTRBA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, "node_modules/tailwindcss": { "version": "3.4.15", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.15.tgz", @@ -17581,6 +18155,97 @@ } } }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.15.0.tgz", + "integrity": "sha512-+zkm9AR1Ds9uLWN3fkoeXgFppaQ+uEVtfOV62dDmsy9QCNqlRHWNEck4yarvRNrvRcHQLGfqBNui3cimoz8XAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.15.0", + "@typescript-eslint/type-utils": "8.15.0", + "@typescript-eslint/utils": "8.15.0", + "@typescript-eslint/visitor-keys": "8.15.0", + "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" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/parser": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.15.0.tgz", + "integrity": "sha512-7n59qFpghG4uazrF9qtGKBZXn7Oz4sOMm8dwNWDQY96Xlm2oX67eipqcblDj+oY1lLCbf1oltMZFpUso66Kl1A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "8.15.0", + "@typescript-eslint/types": "8.15.0", + "@typescript-eslint/typescript-estree": "8.15.0", + "@typescript-eslint/visitor-keys": "8.15.0", + "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" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/type-utils": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.15.0.tgz", + "integrity": "sha512-UU6uwXDoI3JGSXmcdnP5d8Fffa2KayOhUUqr/AiBnG1Gl7+7ut/oyagVeSkh7bxQ0zSXV9ptRh/4N15nkCqnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "8.15.0", + "@typescript-eslint/utils": "8.15.0", + "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" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -18423,6 +19088,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, "node_modules/zustand": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.1.tgz", diff --git a/package.json b/package.json index 06ec9e28..8209897d 100644 --- a/package.json +++ b/package.json @@ -27,12 +27,18 @@ }, "dependencies": { "@headlessui/react": "^2.2.0", + "@hookform/resolvers": "^3.9.1", "@tanstack/react-query": "^5.61.3", "@tanstack/react-query-devtools": "^5.61.3", + "@types/react-datepicker": "^6.2.0", "axios": "^1.7.8", "next": "15.0.3", "react": "^18.3.1", + "react-datepicker": "^7.5.0", "react-dom": "^18.3.1", + "react-hook-form": "^7.53.2", + "tailwind-merge": "^2.5.5", + "zod": "^3.23.8", "zustand": "^5.0.1" }, "devDependencies": { @@ -52,6 +58,8 @@ "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", + "@typescript-eslint/eslint-plugin": "^8.16.0", + "@typescript-eslint/parser": "^8.16.0", "autoprefixer": "^10.4.20", "chromatic": "^11.19.0", "eslint": "^8.57.1", diff --git a/public/icons/EditIcon.tsx b/public/icons/EditIcon.tsx new file mode 100644 index 00000000..da762f81 --- /dev/null +++ b/public/icons/EditIcon.tsx @@ -0,0 +1,26 @@ +import { SVGProps } from 'react'; + +interface EditIconProps extends SVGProps { + width?: number; + height?: number; +} + +function EditIcon({ width = 7, height = 9, ...props }: EditIconProps) { + return ( + + + + ); +} + +export default EditIcon; diff --git a/public/icons/HeartIcon.tsx b/public/icons/HeartIcon.tsx new file mode 100644 index 00000000..ccabe49b --- /dev/null +++ b/public/icons/HeartIcon.tsx @@ -0,0 +1,40 @@ +import { SVGProps } from 'react'; + +interface HeartIconProps extends SVGProps { + width?: number; + height?: number; + isLiked: boolean; + onClick?: () => void; +} + +function HeartIcon({ + width = 40, + height = 40, + isLiked = false, + onClick, + ...props +}: HeartIconProps) { + return ( + + + + ); +} + +export default HeartIcon; diff --git a/public/icons/HostIcon.tsx b/public/icons/HostIcon.tsx new file mode 100644 index 00000000..9883640b --- /dev/null +++ b/public/icons/HostIcon.tsx @@ -0,0 +1,26 @@ +import { SVGProps } from 'react'; + +interface HostIconProps extends SVGProps { + width?: number; + height?: number; +} + +function HostIcon({ width = 8, height = 8, ...props }: HostIconProps) { + return ( + + + + ); +} + +export default HostIcon; diff --git a/public/icons/IcCheck.tsx b/public/icons/IcCheck.tsx new file mode 100644 index 00000000..e78d9fe7 --- /dev/null +++ b/public/icons/IcCheck.tsx @@ -0,0 +1,46 @@ +import { SVGProps } from 'react'; + +interface IcCheckProps extends SVGProps { + width?: number; + height?: number; + className?: string; + filled?: boolean; +} + +function IcCheck({ + width = 24, + height = 24, + className = '', + filled = false, + ...props +}: IcCheckProps) { + return ( + + + + + ); +} + +export default IcCheck; diff --git a/public/icons/IcClose.tsx b/public/icons/IcClose.tsx new file mode 100644 index 00000000..7ae8dd0f --- /dev/null +++ b/public/icons/IcClose.tsx @@ -0,0 +1,34 @@ +import { SVGProps } from 'react'; + +interface IcCloseProps extends SVGProps { + width?: number; + height?: number; + isActive?: boolean; + color?: string; +} + +function IcClose({ + width = 24, + height = 24, + isActive = false, + color, +}: IcCloseProps) { + return ( + + + + ); +} + +export default IcClose; diff --git a/public/icons/IcDropDown.tsx b/public/icons/IcDropDown.tsx new file mode 100644 index 00000000..7c14ec6a --- /dev/null +++ b/public/icons/IcDropDown.tsx @@ -0,0 +1,36 @@ +import { SVGProps } from 'react'; + +interface IcDropDownProps extends SVGProps { + width?: number; + height?: number; + isActive?: boolean; + color?: string; +} + +function IcDropDown({ + width = 24, + height = 24, + isActive = false, + color, +}: IcDropDownProps) { + return ( + + + + ); +} + +export default IcDropDown; diff --git a/public/icons/IcEdit.tsx b/public/icons/IcEdit.tsx new file mode 100644 index 00000000..8900b58e --- /dev/null +++ b/public/icons/IcEdit.tsx @@ -0,0 +1,29 @@ +import { SVGProps } from 'react'; + +interface IcEditProps extends SVGProps { + width?: number; + height?: number; + color?: string; +} + +export default function IcEdit({ + width = 13, + height = 17, + color = '#B4B5B6', +}: IcEditProps) { + return ( + + + + + ); +} diff --git a/public/icons/IcFiltering.tsx b/public/icons/IcFiltering.tsx new file mode 100644 index 00000000..790cc3c4 --- /dev/null +++ b/public/icons/IcFiltering.tsx @@ -0,0 +1,33 @@ +import { SVGProps } from 'react'; + +interface IcFilteringProps extends SVGProps { + width?: number; + height?: number; + isActive?: boolean; + color?: string; +} + +function IcFiltering({ + width = 24, + height = 24, + isActive = false, + color = '#111827', +}: IcFilteringProps) { + return ( + + + + ); +} + +export default IcFiltering; diff --git a/public/icons/IcSorting.tsx b/public/icons/IcSorting.tsx new file mode 100644 index 00000000..c5be40d6 --- /dev/null +++ b/public/icons/IcSorting.tsx @@ -0,0 +1,41 @@ +import { SVGProps } from 'react'; + +interface IcSortingProps extends SVGProps { + width?: number; + height?: number; + isActive?: boolean; + color?: string; +} + +function IcSorting({ + width = 24, + height = 24, + isActive = false, + color, +}: IcSortingProps) { + return ( + + + + + ); +} + +export default IcSorting; diff --git a/public/icons/LocationIcon.tsx b/public/icons/LocationIcon.tsx new file mode 100644 index 00000000..606ca39b --- /dev/null +++ b/public/icons/LocationIcon.tsx @@ -0,0 +1,34 @@ +import { SVGProps } from 'react'; + +interface LocationIconProps extends SVGProps { + width?: number; + height?: number; +} + +function LocationIcon({ + width = 24, + height = 24, + ...props +}: LocationIconProps) { + return ( + + + + + ); +} + +export default LocationIcon; diff --git a/public/icons/RatingIcon.tsx b/public/icons/RatingIcon.tsx new file mode 100644 index 00000000..14ae97b0 --- /dev/null +++ b/public/icons/RatingIcon.tsx @@ -0,0 +1,32 @@ +import { SVGProps } from 'react'; + +interface RatingIconProps extends SVGProps { + width?: number; + height?: number; + checked: boolean; +} + +function RatingIcon({ + width = 24, + height = 24, + checked = false, + ...props +}: RatingIconProps) { + const heartColor = checked ? '#00a991' : '#d8d9db'; + return ( + + + + ); +} +export default RatingIcon; diff --git a/public/icons/RightArrow.tsx b/public/icons/RightArrow.tsx new file mode 100644 index 00000000..9f79fb23 --- /dev/null +++ b/public/icons/RightArrow.tsx @@ -0,0 +1,35 @@ +import { SVGProps } from 'react'; + +interface RightArrowProps extends SVGProps { + width?: number; + height?: number; + strokeColor?: string; +} + +function RightArrow({ + width = 18, + height = 18, + strokeColor = '#EA580C', + ...props +}: RightArrowProps) { + return ( + + + + ); +} + +export default RightArrow; diff --git a/public/icons/SearchIcon.tsx b/public/icons/SearchIcon.tsx new file mode 100644 index 00000000..81a0d250 --- /dev/null +++ b/public/icons/SearchIcon.tsx @@ -0,0 +1,28 @@ +import { SVGProps } from 'react'; + +interface SearchIconProps extends SVGProps { + width?: number; + height?: number; +} + +function SearchIcon({ width = 12, height = 12, ...props }: SearchIconProps) { + return ( + + + + ); +} + +export default SearchIcon; diff --git a/public/icons/WaveIcon.tsx b/public/icons/WaveIcon.tsx new file mode 100644 index 00000000..4bf5c6b6 --- /dev/null +++ b/public/icons/WaveIcon.tsx @@ -0,0 +1,52 @@ +import { SVGProps } from 'react'; + +interface WaveIconProps extends SVGProps { + width?: number; + height?: number; +} + +function WaveIcon({ width = 20, height = 24, ...props }: WaveIconProps) { + return ( + + + + + + + + ); +} + +export default WaveIcon; diff --git a/public/icons/index.ts b/public/icons/index.ts index cb0ff5c3..a3f11b0e 100644 --- a/public/icons/index.ts +++ b/public/icons/index.ts @@ -1 +1,15 @@ -export {}; +export { default as IcCheck } from './IcCheck'; +export { default as RatingIcon } from './RatingIcon'; +export { default as IcDropDown } from './IcDropDown'; +export { default as IcSorting } from './IcSorting'; +export { default as IcFiltering } from './IcFiltering'; +export { default as HeartIcon } from './HeartIcon'; +export { default as RightArrow } from './RightArrow'; +export { default as WaveIcon } from './WaveIcon'; +export { default as VisibilityOn } from './visibility_on'; +export { default as VisibilityOff } from './visibility_off'; +export { default as LocationIcon } from './LocationIcon'; +export { default as HostIcon } from './HostIcon'; +export { default as IcClose } from './IcClose'; +export { default as EditIcon } from './EditIcon'; +export { default as IcEdit } from './IcEdit'; diff --git a/public/icons/visibility_off.tsx b/public/icons/visibility_off.tsx new file mode 100644 index 00000000..669725f1 --- /dev/null +++ b/public/icons/visibility_off.tsx @@ -0,0 +1,22 @@ +import { SVGProps } from 'react'; +interface IcCheckProps extends SVGProps { + width?: number; + height?: number; +} +function VisibilityOff({ width = 24, height = 24 }: IcCheckProps) { + return ( + + + + ); +} +export default VisibilityOff; diff --git a/public/icons/visibility_on.tsx b/public/icons/visibility_on.tsx new file mode 100644 index 00000000..408068b1 --- /dev/null +++ b/public/icons/visibility_on.tsx @@ -0,0 +1,22 @@ +import { SVGProps } from 'react'; +interface IcCheckProps extends SVGProps { + width?: number; + height?: number; +} +function VisibilityOn({ width = 24, height = 24 }: IcCheckProps) { + return ( + + + + ); +} +export default VisibilityOn; diff --git a/public/images/authImage.png b/public/images/authImage.png new file mode 100644 index 00000000..6f47a906 Binary files /dev/null and b/public/images/authImage.png differ diff --git a/public/images/profile.png b/public/images/profile.png new file mode 100644 index 00000000..d5545356 Binary files /dev/null and b/public/images/profile.png differ diff --git a/src/api/axios.ts b/src/api/axios.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/app/bookclub/[id]/page.tsx b/src/app/bookclub/[id]/page.tsx new file mode 100644 index 00000000..44e3dbf1 --- /dev/null +++ b/src/app/bookclub/[id]/page.tsx @@ -0,0 +1,11 @@ +import { BookClubDetailPage } from '@/features/club-details/components'; + +function BookClubDetail({}) { + return ( + <> + + + ); +} + +export default BookClubDetail; diff --git a/src/app/bookclub/create/page.tsx b/src/app/bookclub/create/page.tsx new file mode 100644 index 00000000..fa89244a --- /dev/null +++ b/src/app/bookclub/create/page.tsx @@ -0,0 +1,5 @@ +import { CreateBookClubPage } from '@/features/club-create/container'; + +export default function BookClubCreate() { + return ; +} diff --git a/src/app/bookclub/page.tsx b/src/app/bookclub/page.tsx index 30cbc4fa..4477773c 100644 --- a/src/app/bookclub/page.tsx +++ b/src/app/bookclub/page.tsx @@ -1,9 +1,9 @@ -import Button from '@/components/button/Button'; +import { BookClubMainPage } from '@/features/bookclub/components'; export default function Home() { return ( -
-
+ <> + + ); } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 70cc712d..f8380695 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,5 +1,7 @@ import type { Metadata } from 'next'; import ReactQueryProviders from '@/lib/utils/reactQueryProvider'; +import HeaderBar from '@/components/header/HeaderBar'; +import Script from 'next/script'; import '@/styles/globals.css'; @@ -14,9 +16,18 @@ export default function RootLayout({ children: React.ReactNode; }>) { return ( - - - {children} + + +