From d1271ed9fffa2ce2e681aa53b8cec6d7971bdc84 Mon Sep 17 00:00:00 2001 From: harry kim <73218463+hanyugeon@users.noreply.github.com> Date: Mon, 6 May 2024 15:11:05 +0900 Subject: [PATCH] =?UTF-8?q?[#561]=20[=EB=AA=A8=EC=9E=84=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1]=20=EB=AA=A8=EC=9E=84=20=EC=83=81=EC=84=B8=20?= =?UTF-8?q?=ED=8D=BC=EB=84=90=20=EA=B0=9C=EC=84=A0=20(#567)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: Input 컴포넌트 type="number" 일때 표시되는 버튼 제거 * refactor: 모임 상세 퍼널 스텝 스타일 수정, 성능개선, 기능 추가 - CustomMemberCountField의 Input 컴포넌트 after 스타일 추가 - watch를 useWatch()로 대체 - SetUpDetailStepValues에 FormValues 추가(book, queryKeyword) - SelectedBookInfoField에 bookId 받을 수 있도록 수정 * refactor: 폴더 구조 변경 * fix: 모임 상세 퍼널 스토리 수정 * chore: /bookGroup/create/funnel/index.ts 변경사항 업데이트 - 불필요한 코드이지만 컨플릭트날것을 대비하여 우선 업데이트 합니다. - 이후 Funnel 작업 시 제거합니다. * fix: 모임상세 스텝 스토리 수정 - FormValues에 누락 된 customMemberCount 추가 - onNextStep 이벤트에 alert 추가 * fix: 불필요한 코드 삭제 및 수정 --- .../create/funnel/SetUpDetailStep.stories.tsx | 50 ------------- .../create/steps/SetUpDetailStep.stories.tsx | 72 +++++++++++++++++++ src/styles/global.css | 13 ++++ src/v1/bookGroup/create/funnel/index.ts | 2 +- .../SetUpDetailStep}/SetUpDetailStep.tsx | 62 ++++++++++------ .../create/steps/SetUpDetailStep/index.ts | 2 + 6 files changed, 129 insertions(+), 72 deletions(-) delete mode 100644 src/stories/bookGroup/create/funnel/SetUpDetailStep.stories.tsx create mode 100644 src/stories/bookGroup/create/steps/SetUpDetailStep.stories.tsx rename src/v1/bookGroup/create/{funnel => steps/SetUpDetailStep}/SetUpDetailStep.tsx (83%) create mode 100644 src/v1/bookGroup/create/steps/SetUpDetailStep/index.ts diff --git a/src/stories/bookGroup/create/funnel/SetUpDetailStep.stories.tsx b/src/stories/bookGroup/create/funnel/SetUpDetailStep.stories.tsx deleted file mode 100644 index 007ecf14..00000000 --- a/src/stories/bookGroup/create/funnel/SetUpDetailStep.stories.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { FormProvider, useForm } from 'react-hook-form'; -import type { APICreateGroup } from '@/types/group'; -import { getTodayDate } from '@/utils/date'; - -import { SetUpDetailStep } from '@/v1/bookGroup/create/funnel'; -import { Meta, StoryObj } from '@storybook/react'; -import { appLayoutMeta } from '@/stories/meta'; - -const meta: Meta = { - title: 'bookGroup/funnel/SetUpDetailStep', - component: SetUpDetailStep, - ...appLayoutMeta, -}; - -export default meta; - -type Story = StoryObj; -interface FunnelFormValues extends APICreateGroup { - customMemberCount: string | number; -} - -const SetUpDetailForm = () => { - const methods = useForm({ - mode: 'all', - defaultValues: { - bookId: 23, - title: '', - introduce: '', - maxMemberCount: 9999, - startDate: getTodayDate(), - endDate: '', - isPublic: false, - hasJoinPasswd: false, - joinQuestion: '', - joinPasswd: '', - }, - }); - - return ( - -
- - -
- ); -}; - -export const Default: Story = { - render: () => , -}; diff --git a/src/stories/bookGroup/create/steps/SetUpDetailStep.stories.tsx b/src/stories/bookGroup/create/steps/SetUpDetailStep.stories.tsx new file mode 100644 index 00000000..6f04bed7 --- /dev/null +++ b/src/stories/bookGroup/create/steps/SetUpDetailStep.stories.tsx @@ -0,0 +1,72 @@ +import { appLayoutMeta } from '@/stories/meta'; +import { Meta, StoryObj } from '@storybook/react'; +import { FormProvider, useForm } from 'react-hook-form'; + +import { getTodayDate } from '@/utils/date'; + +import { + SetUpDetailStep, + type SetUpDetailStepValues, +} from '@/v1/bookGroup/create/steps/SetUpDetailStep'; + +const meta: Meta = { + title: 'bookGroup/create/steps/SetUpDetailStep', + component: SetUpDetailStep, + ...appLayoutMeta, +}; + +export default meta; + +type Story = StoryObj; + +const SetUpDetailForm = () => { + const methods = useForm({ + mode: 'all', + defaultValues: { + title: '', + book: { + bookId: 23, + }, + introduce: '', + maxMemberCount: '', + customMemberCount: '', + startDate: getTodayDate(), + endDate: '', + isPublic: false, + }, + }); + + const onNextStep = () => { + const { + book, + title, + introduce, + maxMemberCount, + customMemberCount, + startDate, + endDate, + isPublic, + } = methods.getValues(); + alert(` + bookId: ${book.bookId}, + title: ${title}, + introduce: ${introduce}, + maxMemberCount: ${maxMemberCount}, + customMemberCount: ${customMemberCount}, + startDate: ${startDate}, + endDate: ${endDate}, + isPublic: ${isPublic}`); + }; + + return ( + +
+ + +
+ ); +}; + +export const Default: Story = { + render: () => , +}; diff --git a/src/styles/global.css b/src/styles/global.css index 2e94c2c7..16f6c152 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -31,6 +31,8 @@ max-width: 43rem; margin: 0 auto !important; } + + /* DatePicker Calendar 스타일링 */ input[type='date']::-webkit-calendar-picker-indicator { background-image: none; position: absolute; @@ -42,6 +44,17 @@ padding: 0; cursor: pointer; } + + /* Input type=number 버튼 제거 */ + /* Chrome, Safari, Edge, Opera */ + input::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; + } + /* FireFox */ + input[type='number'] { + -moz-appearance: textfield; + } } @layer utilities { diff --git a/src/v1/bookGroup/create/funnel/index.ts b/src/v1/bookGroup/create/funnel/index.ts index a2e2c66e..217d1205 100644 --- a/src/v1/bookGroup/create/funnel/index.ts +++ b/src/v1/bookGroup/create/funnel/index.ts @@ -1,2 +1,2 @@ // export { default as SelectBookStep } from './SelectBookStep'; -export { default as SetUpDetailStep } from './SetUpDetailStep'; +export { default as SetUpDetailStep } from '../steps/SetUpDetailStep/SetUpDetailStep'; diff --git a/src/v1/bookGroup/create/funnel/SetUpDetailStep.tsx b/src/v1/bookGroup/create/steps/SetUpDetailStep/SetUpDetailStep.tsx similarity index 83% rename from src/v1/bookGroup/create/funnel/SetUpDetailStep.tsx rename to src/v1/bookGroup/create/steps/SetUpDetailStep/SetUpDetailStep.tsx index 483fda81..37960689 100644 --- a/src/v1/bookGroup/create/funnel/SetUpDetailStep.tsx +++ b/src/v1/bookGroup/create/steps/SetUpDetailStep/SetUpDetailStep.tsx @@ -1,9 +1,10 @@ -import { useFormContext } from 'react-hook-form'; +import { useFormContext, useWatch } from 'react-hook-form'; +import type { SearchedBookWithId } from '@/types/book'; import type { APICreateGroup } from '@/types/group'; -import { getTodayDate } from '@/utils/date'; import { MAX_MEMBER_COUNT_OPTIONS } from '@/constants'; +import { getTodayDate } from '@/utils/date'; import BottomActionButton from '@/v1/base/BottomActionButton'; import DatePicker from '@/v1/base/DatePicker'; @@ -13,7 +14,7 @@ import InputLength from '@/v1/base/InputLength'; import RadioButton from '@/v1/base/RadioButton'; import Switch from '@/v1/base/Switch'; import TextArea from '@/v1/base/TextArea'; -import BookInfoCard from '../../BookInfoCard'; +import BookInfoCard from '@/v1/bookGroup/BookInfoCard'; interface MoveFunnelStepProps { onPrevStep?: () => void; @@ -21,17 +22,24 @@ interface MoveFunnelStepProps { onSubmit?: () => void; } -interface SetUpDetailStepValues +/** + * @todo + * Field 컴포넌트 분리 + * goToSelectBookStep 받도록 수정 + */ + +export interface SetUpDetailStepValues extends Pick< APICreateGroup, 'bookId' | 'title' | 'introduce' | 'startDate' | 'endDate' | 'isPublic' > { + book: SearchedBookWithId; maxMemberCount: string; customMemberCount: string; } const SetUpDetailStep = ({ - // FIXME: goToSelectBookStep, + // goToSelectBookStep, onNextStep, }: MoveFunnelStepProps) => { const { handleSubmit, getValues } = useFormContext(); @@ -39,9 +47,9 @@ const SetUpDetailStep = ({ return (
- - + +
@@ -71,14 +79,13 @@ type SetUpDetailFieldProps = { const TitleField = ({ name }: SetUpDetailFieldProps) => { const { register, - watch, + control, formState: { errors }, } = useFormContext(); - const watchedName = watch(name); - const currentLength = - typeof watchedName === 'string' ? watchedName.length : 0; - + const titleValue = useWatch({ control, name: name }); + const titleValueLength = + typeof titleValue === 'string' ? titleValue.length : 0; const titleErrors = errors[name]; return ( @@ -95,7 +102,7 @@ const TitleField = ({ name }: SetUpDetailFieldProps) => { />
@@ -151,7 +158,7 @@ const MaxMemberCountField = ({ name }: SetUpDetailFieldProps) => { return ( <>

최대 인원

-
+
{MAX_MEMBER_COUNT_OPTIONS.map(option => ( { })} /> ))} -
+ {maxMemberCountErrors?.message} ); @@ -171,12 +178,13 @@ const MaxMemberCountField = ({ name }: SetUpDetailFieldProps) => { const CustomMemberCountField = ({ name }: SetUpDetailFieldProps) => { const { register, - watch, + control, formState: { errors }, } = useFormContext(); + const maxMemberCount = useWatch({ control, name: 'maxMemberCount' }); + const isCustomInputCount = maxMemberCount === 'custom'; const customMemberCountErrors = errors[name]; - const isCustomInputCount = watch('maxMemberCount') === 'custom'; return ( <> @@ -185,6 +193,8 @@ const CustomMemberCountField = ({ name }: SetUpDetailFieldProps) => { { const PickStartDateField = ({ name }: SetUpDetailFieldProps) => { const { register, + control, formState: { errors }, } = useFormContext(); const startDateErrors = errors[name]; + const endDate = useWatch({ control, name: 'endDate' }); + const todayDate = getTodayDate(); return (
@@ -217,9 +230,13 @@ const PickStartDateField = ({ name }: SetUpDetailFieldProps) => { {...register(name, { required: '모임 시작일을 선택해주세요', min: { - value: getTodayDate(), + value: todayDate, message: '모임 시작일은 오늘 혹은 그 이후로 선택해주세요', }, + max: { + value: endDate, + message: '모임 시작일은 종료일 보다 빨라야해요', + }, })} />
@@ -231,10 +248,13 @@ const PickStartDateField = ({ name }: SetUpDetailFieldProps) => { const PickEndDateField = ({ name }: SetUpDetailFieldProps) => { const { register, - watch, + control, formState: { errors }, } = useFormContext(); + const startDate = useWatch({ control, name: 'startDate' }); + const todayDate = getTodayDate(); + const endDateErrors = errors[name]; return ( @@ -245,8 +265,8 @@ const PickEndDateField = ({ name }: SetUpDetailFieldProps) => { {...register(name, { required: '모임 종료일을 선택해주세요', min: { - value: watch('startDate'), - message: '모임 종료일은 시작일보다 늦어야해요', + value: startDate || todayDate, + message: '모임 종료일은 시작일과 오늘 이후여야 해요', }, })} /> diff --git a/src/v1/bookGroup/create/steps/SetUpDetailStep/index.ts b/src/v1/bookGroup/create/steps/SetUpDetailStep/index.ts new file mode 100644 index 00000000..38128075 --- /dev/null +++ b/src/v1/bookGroup/create/steps/SetUpDetailStep/index.ts @@ -0,0 +1,2 @@ +export type { SetUpDetailStepValues } from './SetUpDetailStep'; +export { default as SetUpDetailStep } from './SetUpDetailStep';