diff --git a/package.json b/package.json index 48b89e2d..6f0e98c0 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ ] }, "dependencies": { + "@rehookify/datepicker": "^6.6.8", "@tanstack/react-form": "^1.27.0", "@tanstack/react-query": "^5.90.3", "@tanstack/react-query-devtools": "^5.90.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b401ceba..288cb58b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: dependencies: + '@rehookify/datepicker': + specifier: ^6.6.8 + version: 6.6.8(react@19.2.0) '@tanstack/react-form': specifier: ^1.27.0 version: 1.27.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -28,10 +31,10 @@ importers: version: 2.1.1 motion: specifier: ^12.23.24 - version: 12.23.24(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + version: 12.23.24(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) next: specifier: 16.0.1 - version: 16.0.1(@babel/core@7.28.4)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + version: 16.0.1(@babel/core@7.28.4)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react: specifier: 19.2.0 version: 19.2.0 @@ -68,7 +71,7 @@ importers: version: 10.0.5(@types/react@19.2.2)(esbuild@0.25.11)(storybook@10.0.6(@testing-library/dom@10.4.1)(msw@2.11.5(@types/node@20.19.21)(typescript@5.9.3))(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(webpack@5.102.1(esbuild@0.25.11)) '@storybook/nextjs': specifier: ^10.0.6 - version: 10.0.6(@types/webpack@5.28.5(esbuild@0.25.11))(esbuild@0.25.11)(next@16.0.1(@babel/core@7.28.4)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@10.0.6(@testing-library/dom@10.4.1)(msw@2.11.5(@types/node@20.19.21)(typescript@5.9.3))(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(type-fest@4.41.0)(typescript@5.9.3)(webpack-hot-middleware@2.26.1)(webpack@5.102.1(esbuild@0.25.11)) + version: 10.0.6(@types/webpack@5.28.5(esbuild@0.25.11))(babel-plugin-macros@3.1.0)(esbuild@0.25.11)(next@16.0.1(@babel/core@7.28.4)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@10.0.6(@testing-library/dom@10.4.1)(msw@2.11.5(@types/node@20.19.21)(typescript@5.9.3))(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(type-fest@4.41.0)(typescript@5.9.3)(webpack-hot-middleware@2.26.1)(webpack@5.102.1(esbuild@0.25.11)) '@svgr/webpack': specifier: ^8.1.0 version: 8.1.0(typescript@5.9.3) @@ -140,7 +143,7 @@ importers: version: 9.1.7 jest: specifier: ^30.2.0 - version: 30.2.0(@types/node@20.19.21) + version: 30.2.0(@types/node@20.19.21)(babel-plugin-macros@3.1.0) jest-environment-jsdom: specifier: ^30.2.0 version: 30.2.0 @@ -173,7 +176,7 @@ importers: version: 4.1.14 ts-jest: specifier: ^29.4.5 - version: 29.4.5(@babel/core@7.28.4)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.4))(esbuild@0.25.11)(jest-util@30.2.0)(jest@30.2.0(@types/node@20.19.21))(typescript@5.9.3) + version: 29.4.5(@babel/core@7.28.4)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.4))(esbuild@0.25.11)(jest-util@30.2.0)(jest@30.2.0(@types/node@20.19.21)(babel-plugin-macros@3.1.0))(typescript@5.9.3) typescript: specifier: ^5 version: 5.9.3 @@ -969,6 +972,12 @@ packages: '@emnapi/wasi-threads@1.1.0': resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + '@emotion/is-prop-valid@1.4.0': + resolution: {integrity: sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==} + + '@emotion/memoize@0.9.0': + resolution: {integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==} + '@esbuild/aix-ppc64@0.25.11': resolution: {integrity: sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==} engines: {node: '>=18'} @@ -1659,6 +1668,12 @@ packages: webpack-plugin-serve: optional: true + '@rehookify/datepicker@6.6.8': + resolution: {integrity: sha512-s/KFkVZSLWTICeFOshlhgAGiRTzuSXSQOJHoXWcihqX8Nz8ZctgGaskd5+ybxSrcndSYGGts4XsL4A7P9kimBQ==} + engines: {node: '>=16'} + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 + '@resvg/resvg-js-android-arm-eabi@2.6.2': resolution: {integrity: sha512-FrJibrAk6v29eabIPgcTUMPXiEz8ssrAk7TXxsiZzww9UTQ1Z5KAbFJs+Z0Ez+VZTYgnE5IQJqBcoSiMebtPHA==} engines: {node: '>= 10'} @@ -2269,6 +2284,9 @@ packages: '@types/node@20.19.21': resolution: {integrity: sha512-CsGG2P3I5y48RPMfprQGfy4JPRZ6csfC3ltBZSRItG3ngggmNY/qs2uZKp4p9VbrpqNNSMzUZNFZKzgOGnd/VA==} + '@types/parse-json@4.0.2': + resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} + '@types/react-dom@19.2.2': resolution: {integrity: sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==} peerDependencies: @@ -2779,6 +2797,10 @@ packages: resolution: {integrity: sha512-ftzhzSGMUnOzcCXd6WHdBGMyuwy15Wnn0iyyWGKgBDLxf9/s5ABuraCSpBX2uG0jUg4rqJnxsLc5+oYBqoxVaA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + babel-plugin-macros@3.1.0: + resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} + engines: {node: '>=10', npm: '>=6'} + babel-plugin-polyfill-corejs2@0.4.14: resolution: {integrity: sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==} peerDependencies: @@ -3147,6 +3169,10 @@ packages: cosmiconfig: '>=9' typescript: '>=5' + cosmiconfig@7.1.0: + resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} + engines: {node: '>=10'} + cosmiconfig@8.3.6: resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} engines: {node: '>=14'} @@ -7572,6 +7598,14 @@ snapshots: tslib: 2.8.1 optional: true + '@emotion/is-prop-valid@1.4.0': + dependencies: + '@emotion/memoize': 0.9.0 + optional: true + + '@emotion/memoize@0.9.0': + optional: true + '@esbuild/aix-ppc64@0.25.11': optional: true @@ -7887,7 +7921,7 @@ snapshots: jest-util: 30.2.0 slash: 3.0.0 - '@jest/core@30.2.0': + '@jest/core@30.2.0(babel-plugin-macros@3.1.0)': dependencies: '@jest/console': 30.2.0 '@jest/pattern': 30.0.1 @@ -7902,7 +7936,7 @@ snapshots: exit-x: 0.2.2 graceful-fs: 4.2.11 jest-changed-files: 30.2.0 - jest-config: 30.2.0(@types/node@20.19.21) + jest-config: 30.2.0(@types/node@20.19.21)(babel-plugin-macros@3.1.0) jest-haste-map: 30.2.0 jest-message-util: 30.2.0 jest-regex-util: 30.0.1 @@ -8323,6 +8357,10 @@ snapshots: type-fest: 4.41.0 webpack-hot-middleware: 2.26.1 + '@rehookify/datepicker@6.6.8(react@19.2.0)': + dependencies: + react: 19.2.0 + '@resvg/resvg-js-android-arm-eabi@2.6.2': optional: true @@ -8639,7 +8677,7 @@ snapshots: react: 19.2.0 react-dom: 19.2.0(react@19.2.0) - '@storybook/nextjs@10.0.6(@types/webpack@5.28.5(esbuild@0.25.11))(esbuild@0.25.11)(next@16.0.1(@babel/core@7.28.4)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@10.0.6(@testing-library/dom@10.4.1)(msw@2.11.5(@types/node@20.19.21)(typescript@5.9.3))(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(type-fest@4.41.0)(typescript@5.9.3)(webpack-hot-middleware@2.26.1)(webpack@5.102.1(esbuild@0.25.11))': + '@storybook/nextjs@10.0.6(@types/webpack@5.28.5(esbuild@0.25.11))(babel-plugin-macros@3.1.0)(esbuild@0.25.11)(next@16.0.1(@babel/core@7.28.4)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@10.0.6(@testing-library/dom@10.4.1)(msw@2.11.5(@types/node@20.19.21)(typescript@5.9.3))(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(type-fest@4.41.0)(typescript@5.9.3)(webpack-hot-middleware@2.26.1)(webpack@5.102.1(esbuild@0.25.11))': dependencies: '@babel/core': 7.28.4 '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.28.4) @@ -8663,7 +8701,7 @@ snapshots: css-loader: 6.11.0(webpack@5.102.1(esbuild@0.25.11)) image-size: 2.0.2 loader-utils: 3.3.1 - next: 16.0.1(@babel/core@7.28.4)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + next: 16.0.1(@babel/core@7.28.4)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) node-polyfill-webpack-plugin: 2.0.1(webpack@5.102.1(esbuild@0.25.11)) postcss: 8.5.6 postcss-loader: 8.2.0(postcss@8.5.6)(typescript@5.9.3)(webpack@5.102.1(esbuild@0.25.11)) @@ -8675,7 +8713,7 @@ snapshots: semver: 7.7.3 storybook: 10.0.6(@testing-library/dom@10.4.1)(msw@2.11.5(@types/node@20.19.21)(typescript@5.9.3))(prettier@3.6.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) style-loader: 3.3.4(webpack@5.102.1(esbuild@0.25.11)) - styled-jsx: 5.1.6(@babel/core@7.28.4)(react@19.2.0) + styled-jsx: 5.1.6(@babel/core@7.28.4)(babel-plugin-macros@3.1.0)(react@19.2.0) tsconfig-paths: 4.2.0 tsconfig-paths-webpack-plugin: 4.2.0 optionalDependencies: @@ -9103,6 +9141,9 @@ snapshots: dependencies: undici-types: 6.21.0 + '@types/parse-json@4.0.2': + optional: true + '@types/react-dom@19.2.2(@types/react@19.2.2)': dependencies: '@types/react': 19.2.2 @@ -9665,6 +9706,13 @@ snapshots: dependencies: '@types/babel__core': 7.20.5 + babel-plugin-macros@3.1.0: + dependencies: + '@babel/runtime': 7.28.4 + cosmiconfig: 7.1.0 + resolve: 1.22.10 + optional: true + babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.28.4): dependencies: '@babel/compat-data': 7.28.4 @@ -10030,6 +10078,15 @@ snapshots: jiti: 2.6.1 typescript: 5.9.3 + cosmiconfig@7.1.0: + dependencies: + '@types/parse-json': 4.0.2 + import-fresh: 3.3.1 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.2 + optional: true + cosmiconfig@8.3.6(typescript@5.9.3): dependencies: import-fresh: 3.3.1 @@ -10217,7 +10274,9 @@ snapshots: dedent@0.7.0: {} - dedent@1.7.0: {} + dedent@1.7.0(babel-plugin-macros@3.1.0): + optionalDependencies: + babel-plugin-macros: 3.1.0 deep-eql@5.0.2: {} @@ -10963,12 +11022,13 @@ snapshots: hasown: 2.0.2 mime-types: 2.1.35 - framer-motion@12.23.24(react-dom@19.2.0(react@19.2.0))(react@19.2.0): + framer-motion@12.23.24(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: motion-dom: 12.23.23 motion-utils: 12.23.6 tslib: 2.8.1 optionalDependencies: + '@emotion/is-prop-valid': 1.4.0 react: 19.2.0 react-dom: 19.2.0(react@19.2.0) @@ -11482,7 +11542,7 @@ snapshots: jest-util: 30.2.0 p-limit: 3.1.0 - jest-circus@30.2.0: + jest-circus@30.2.0(babel-plugin-macros@3.1.0): dependencies: '@jest/environment': 30.2.0 '@jest/expect': 30.2.0 @@ -11491,7 +11551,7 @@ snapshots: '@types/node': 20.19.21 chalk: 4.1.2 co: 4.6.0 - dedent: 1.7.0 + dedent: 1.7.0(babel-plugin-macros@3.1.0) is-generator-fn: 2.1.0 jest-each: 30.2.0 jest-matcher-utils: 30.2.0 @@ -11508,15 +11568,15 @@ snapshots: - babel-plugin-macros - supports-color - jest-cli@30.2.0(@types/node@20.19.21): + jest-cli@30.2.0(@types/node@20.19.21)(babel-plugin-macros@3.1.0): dependencies: - '@jest/core': 30.2.0 + '@jest/core': 30.2.0(babel-plugin-macros@3.1.0) '@jest/test-result': 30.2.0 '@jest/types': 30.2.0 chalk: 4.1.2 exit-x: 0.2.2 import-local: 3.2.0 - jest-config: 30.2.0(@types/node@20.19.21) + jest-config: 30.2.0(@types/node@20.19.21)(babel-plugin-macros@3.1.0) jest-util: 30.2.0 jest-validate: 30.2.0 yargs: 17.7.2 @@ -11527,7 +11587,7 @@ snapshots: - supports-color - ts-node - jest-config@30.2.0(@types/node@20.19.21): + jest-config@30.2.0(@types/node@20.19.21)(babel-plugin-macros@3.1.0): dependencies: '@babel/core': 7.28.4 '@jest/get-type': 30.1.0 @@ -11540,7 +11600,7 @@ snapshots: deepmerge: 4.3.1 glob: 10.4.5 graceful-fs: 4.2.11 - jest-circus: 30.2.0 + jest-circus: 30.2.0(babel-plugin-macros@3.1.0) jest-docblock: 30.2.0 jest-environment-node: 30.2.0 jest-regex-util: 30.0.1 @@ -11792,12 +11852,12 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 - jest@30.2.0(@types/node@20.19.21): + jest@30.2.0(@types/node@20.19.21)(babel-plugin-macros@3.1.0): dependencies: - '@jest/core': 30.2.0 + '@jest/core': 30.2.0(babel-plugin-macros@3.1.0) '@jest/types': 30.2.0 import-local: 3.2.0 - jest-cli: 30.2.0(@types/node@20.19.21) + jest-cli: 30.2.0(@types/node@20.19.21)(babel-plugin-macros@3.1.0) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -12187,11 +12247,12 @@ snapshots: motion-utils@12.23.6: {} - motion@12.23.24(react-dom@19.2.0(react@19.2.0))(react@19.2.0): + motion@12.23.24(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: - framer-motion: 12.23.24(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + framer-motion: 12.23.24(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) tslib: 2.8.1 optionalDependencies: + '@emotion/is-prop-valid': 1.4.0 react: 19.2.0 react-dom: 19.2.0(react@19.2.0) @@ -12238,7 +12299,7 @@ snapshots: neo-async@2.6.2: {} - next@16.0.1(@babel/core@7.28.4)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0): + next@16.0.1(@babel/core@7.28.4)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: '@next/env': 16.0.1 '@swc/helpers': 0.5.15 @@ -12246,7 +12307,7 @@ snapshots: postcss: 8.4.31 react: 19.2.0 react-dom: 19.2.0(react@19.2.0) - styled-jsx: 5.1.6(@babel/core@7.28.4)(react@19.2.0) + styled-jsx: 5.1.6(@babel/core@7.28.4)(babel-plugin-macros@3.1.0)(react@19.2.0) optionalDependencies: '@next/swc-darwin-arm64': 16.0.1 '@next/swc-darwin-x64': 16.0.1 @@ -13326,12 +13387,13 @@ snapshots: dependencies: webpack: 5.102.1(esbuild@0.25.11) - styled-jsx@5.1.6(@babel/core@7.28.4)(react@19.2.0): + styled-jsx@5.1.6(@babel/core@7.28.4)(babel-plugin-macros@3.1.0)(react@19.2.0): dependencies: client-only: 0.0.1 react: 19.2.0 optionalDependencies: '@babel/core': 7.28.4 + babel-plugin-macros: 3.1.0 supports-color@7.2.0: dependencies: @@ -13526,12 +13588,12 @@ snapshots: ts-dedent@2.2.0: {} - ts-jest@29.4.5(@babel/core@7.28.4)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.4))(esbuild@0.25.11)(jest-util@30.2.0)(jest@30.2.0(@types/node@20.19.21))(typescript@5.9.3): + ts-jest@29.4.5(@babel/core@7.28.4)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.4))(esbuild@0.25.11)(jest-util@30.2.0)(jest@30.2.0(@types/node@20.19.21)(babel-plugin-macros@3.1.0))(typescript@5.9.3): dependencies: bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 handlebars: 4.7.8 - jest: 30.2.0(@types/node@20.19.21) + jest: 30.2.0(@types/node@20.19.21)(babel-plugin-macros@3.1.0) json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 diff --git a/src/app/post-meetup/page.tsx b/src/app/post-meetup/page.tsx index dc8b9c17..bd6502f6 100644 --- a/src/app/post-meetup/page.tsx +++ b/src/app/post-meetup/page.tsx @@ -18,7 +18,10 @@ const PostMeetupPage = () => { defaultValues: { title: '', address: '', - date: '', + dateAndTime: { + date: '', + time: '', + }, cap: 0, images: {}, detail: '', @@ -40,7 +43,7 @@ const PostMeetupPage = () => {
} name='title' /> } name='address' /> - } name='date' /> + } name='dateAndTime' /> } name='cap' /> } name='images' /> } name='detail' /> diff --git a/src/components/pages/post-meetup/fields/address-field/index.tsx b/src/components/pages/post-meetup/fields/address-field/index.tsx index 92cee659..b04056d4 100644 --- a/src/components/pages/post-meetup/fields/address-field/index.tsx +++ b/src/components/pages/post-meetup/fields/address-field/index.tsx @@ -31,6 +31,7 @@ export const MeetupAddressField = ({ field }: Props) => { type='text' value={field.state.value} onChange={(e) => field.handleChange(e.target.value)} + onClick={() => console.log('address clicked!')} /> ); diff --git a/src/components/pages/post-meetup/fields/date-field/index.tsx b/src/components/pages/post-meetup/fields/date-field/index.tsx index 86e9e565..217e3b97 100644 --- a/src/components/pages/post-meetup/fields/date-field/index.tsx +++ b/src/components/pages/post-meetup/fields/date-field/index.tsx @@ -3,35 +3,39 @@ import { AnyFieldApi } from '@tanstack/react-form'; import { Icon } from '@/components/icon'; -import { Input, Label } from '@/components/ui'; +import { DatePickerModal } from '@/components/pages/post-meetup/modals/date-picker-modal'; +import { Label } from '@/components/ui'; +import { useModal } from '@/components/ui'; interface Props { field: AnyFieldApi; } export const MeetupDateField = ({ field }: Props) => { + const { open } = useModal(); + + const value = field.state.value.date + field.state.value.time; + return (
- - } - placeholder='날짜와 시간을 선택해주세요' - required - type='text' - value={field.state.value} - onChange={(e) => field.handleChange(e.target.value)} - /> +
); }; diff --git a/src/components/pages/post-meetup/fields/tags-field/index.tsx b/src/components/pages/post-meetup/fields/tags-field/index.tsx index bd5f436c..176f85d3 100644 --- a/src/components/pages/post-meetup/fields/tags-field/index.tsx +++ b/src/components/pages/post-meetup/fields/tags-field/index.tsx @@ -1,5 +1,7 @@ 'use client'; +import { useState } from 'react'; + import { AnyFieldApi } from '@tanstack/react-form'; import { Icon } from '@/components/icon'; @@ -10,6 +12,18 @@ interface Props { } export const MeetupTagsField = ({ field }: Props) => { + const [inputValue, setInputValue] = useState(''); + + const onEnter = (e: React.KeyboardEvent) => { + if (e.code !== 'Enter' && e.code !== 'NumpadEnter') return; + + const hasDupe = field.state.value.includes(inputValue); + + if (!hasDupe && inputValue.trim()) field.pushValue(inputValue); + + setInputValue(''); + }; + return (
@@ -26,14 +40,21 @@ export const MeetupTagsField = ({ field }: Props) => { } placeholder='입력 후 Enter' type='text' - value={field.state.value} - onChange={(e) => field.handleChange(e.target.value)} + value={inputValue} + onChange={(e) => setInputValue(e.target.value)} + onKeyDown={onEnter} /> -
    -
  • -

    #태그

    - -
  • +
      + {field.state.value.map((tag: string, idx: number) => ( +
    • field.removeValue(idx)} + > +

      #{tag}

      + +
    • + ))}
); diff --git a/src/components/pages/post-meetup/modals/date-picker-modal/date-picker/index.tsx b/src/components/pages/post-meetup/modals/date-picker-modal/date-picker/index.tsx new file mode 100644 index 00000000..d04fbbc5 --- /dev/null +++ b/src/components/pages/post-meetup/modals/date-picker-modal/date-picker/index.tsx @@ -0,0 +1,91 @@ +import { useEffect, useState } from 'react'; + +import { useDatePicker } from '@rehookify/datepicker'; +import clsx from 'clsx'; + +import { Icon } from '@/components/icon'; + +interface Props { + currentTab: 'date' | 'time'; + handleDateChange: (date: string) => void; +} + +export const DatePicker = ({ currentTab, handleDateChange }: Props) => { + const nowDate = new Date(); + const [selectedDates, onDatesChange] = useState([nowDate]); + + useEffect(() => { + handleDateChange(selectedDates.toString()); + }, [selectedDates]); + + const { + data: { weekDays, calendars }, + propGetters: { dayButton, addOffset, subtractOffset }, + } = useDatePicker({ + selectedDates, + onDatesChange, + locale: { + day: 'numeric', + weekday: 'short', + monthName: 'numeric', + }, + dates: { + minDate: nowDate, + maxDate: new Date(nowDate.getFullYear() + 1, 12, 0), + }, + calendar: { + mode: 'fluid', + }, + }); + + const { year, month, days } = calendars[0]; + + return ( +
+
+ + +
+ +
+
    + {weekDays.map((day) => ( +
  • + {day} +
  • + ))} +
+
    + {days.map((d) => ( +
  • + +
  • + ))} +
+
+ +
+ {year}년 + + {month}월 {selectedDates[0].getDate()}일 + + 12:20 + AM + PM +
+
+ ); +}; diff --git a/src/components/pages/post-meetup/modals/date-picker-modal/index.tsx b/src/components/pages/post-meetup/modals/date-picker-modal/index.tsx new file mode 100644 index 00000000..30cbe6f7 --- /dev/null +++ b/src/components/pages/post-meetup/modals/date-picker-modal/index.tsx @@ -0,0 +1,68 @@ +'use client'; + +import { useState } from 'react'; + +import { AnyFieldApi } from '@tanstack/react-form'; +import clsx from 'clsx'; + +import { Icon } from '@/components/icon'; +import { DatePicker } from '@/components/pages/post-meetup/modals/date-picker-modal/date-picker'; +import { ModalContent, ModalTitle, useModal } from '@/components/ui'; + +interface Props { + field: AnyFieldApi; +} + +export const DatePickerModal = ({ field }: Props) => { + const [tabMenu, setTabMenu] = useState<'date' | 'time'>('date'); + const { close } = useModal(); + + return ( + + 모달임 +
+ + + field.handleChange({ ...field.state.value, date })} + /> + +
+ + +
+
+
+ ); +}; + +const DATE_MODAL_TAB_MENU = [ + { name: 'date', iconId: 'calendar-1' }, + { name: 'time', iconId: 'clock' }, +] as const; diff --git a/src/components/pages/post-meetup/post-button/index.tsx b/src/components/pages/post-meetup/post-button/index.tsx index 0b797ed1..76190974 100644 --- a/src/components/pages/post-meetup/post-button/index.tsx +++ b/src/components/pages/post-meetup/post-button/index.tsx @@ -2,7 +2,7 @@ import { Button } from '@/components/ui'; export const MeetupSubmitButton = () => { return ( -
+
); diff --git a/src/styles/globals.css b/src/styles/globals.css index ae8d85a8..b1cf57c3 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -27,3 +27,7 @@ body { background: var(--background); color: var(--foreground); } + +button { + cursor: pointer; +}