Skip to content

Commit 55a08ee

Browse files
hanyugeongxxrxn
authored andcommitted
[#581] [모임 생성] 모임 생성 퍼널 페이지 작성 (#582)
* chore: 책 선택 스텝 경로 수정 * feat: useFunnel 커스텀훅에 currentStep 조회 기능 추가 * feat: 모임 생성 퍼널 작성 * feat: 모임 상세 퍼널 뒤로가기 버튼 기능 구현 * refactor: Funnel.tsx 경로 변경 및 공통 interface 정의 * refactor: 모임 생성 퍼널 코드 스플리팅 * chore: 모임 생성 퍼널 스텝 stories 경로 변경 * refactor: index 파일 정리 * refactor: formValues 타입 정리 * chore: 스토리북 import 경로 수정 * feat: 모임 생성 mutation 함수 작성 * feat: 독서 모임 생성 기능 구현 * chore: import문 수정 * refactor: StepFormValues 타입명 통일 (리뷰 반영) * feat: SwitchIsPublicField에서 isComment 값에 따른 안내 문구 표시 * chore: CreateBookGroupFunnel 컴포넌트 이름 수정 * feat: 독서 모임 생성시 독서 모임 상세 페이지로 이동
1 parent e7798f7 commit 55a08ee

24 files changed

+289
-488
lines changed

src/apis/group/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const groupAPI = {
1414
`/service-api/book-groups?pageSize=10&groupCursorId=` + pageParam
1515
),
1616

17-
createGroup: ({ group }: { group: APICreateGroup }) =>
17+
createGroup: (group: APICreateGroup) =>
1818
publicApi.post('/service-api/book-groups', group),
1919

2020
getGroupDetailInfo: ({

src/app/group/create/page.tsx

+4-16
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,7 @@
1-
'use client';
1+
import CreateBookGroupFunnel from '@/v1/bookGroup/create/CreateBookGroupFunnel';
22

3-
import AddGroupForm from '@/ui/Group/AddGroupForm';
4-
import { VStack } from '@chakra-ui/react';
5-
import TopNavigation from '@/ui/common/TopNavigation';
6-
import AuthRequired from '@/ui/AuthRequired';
7-
8-
const GroupCreatePage = () => {
9-
return (
10-
<AuthRequired>
11-
<VStack justify="center" align="center">
12-
<TopNavigation pageTitle="모임 생성" />
13-
<AddGroupForm />
14-
</VStack>
15-
</AuthRequired>
16-
);
3+
const GroupCreateFunnelPage = () => {
4+
return <CreateBookGroupFunnel />;
175
};
186

19-
export default GroupCreatePage;
7+
export default GroupCreateFunnelPage;

src/hooks/useFunnel.tsx

+12-7
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
'use client';
22

33
import { useEffect, useMemo, useRef } from 'react';
4+
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
45

5-
import type { FunnelProps, StepProps } from '@/v1/base/Funnel/Funnel';
66
import { assert } from '@/utils/assert';
77

8-
import { Funnel, Step } from '@/v1/base/Funnel/Funnel';
9-
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
8+
import type { FunnelProps, StepProps } from '@/v1/base/Funnel';
9+
import { Funnel, Step } from '@/v1/base/Funnel';
1010

1111
export type NonEmptyArray<T> = readonly [T, ...T[]];
1212

@@ -34,7 +34,11 @@ export const useFunnel = <Steps extends NonEmptyArray<string>>(
3434
initialStep?: Steps[number];
3535
onStepChange?: (name: Steps[number]) => void;
3636
}
37-
): readonly [FunnelComponent<Steps>, (step: Steps[number]) => void] => {
37+
): readonly [
38+
FunnelComponent<Steps>,
39+
(step: Steps[number]) => void,
40+
Steps[number]
41+
] => {
3842
const router = useRouter();
3943
const searchParams = useSearchParams();
4044
const pathname = usePathname();
@@ -78,11 +82,12 @@ export const useFunnel = <Steps extends NonEmptyArray<string>>(
7882
const params = new URLSearchParams(searchParams.toString());
7983
params.set('funnel-step', `${step}`);
8084

81-
return router.replace(`?${params.toString()}`);
85+
return router.replace(`?${params.toString()}`, { shallow: true });
8286
};
8387

84-
return [FunnelComponent, setStep] as unknown as readonly [
88+
return [FunnelComponent, setStep, step] as unknown as readonly [
8589
FunnelComponent<Steps>,
86-
(step: Steps[number]) => Promise<void>
90+
(step: Steps[number]) => Promise<void>,
91+
Steps[number]
8792
];
8893
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { useMutation } from '@tanstack/react-query';
2+
3+
import type { APICreateGroup } from '@/types/group';
4+
import groupAPI from '@/apis/group';
5+
6+
const useCreateBookGroupMutation = () => {
7+
return useMutation({
8+
mutationFn: (formData: APICreateGroup) =>
9+
groupAPI.createGroup(formData).then(({ data }) => data),
10+
});
11+
};
12+
13+
export default useCreateBookGroupMutation;

src/stories/bookGroup/create/funnel/EnterTitleStep.stories.tsx src/stories/bookGroup/create/steps/EnterTitleStep.stories.tsx

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import { Meta, StoryObj } from '@storybook/react';
2-
import { appLayoutMeta } from '@/stories/meta';
32
import { FormProvider, useForm } from 'react-hook-form';
43

5-
import {
6-
EnterTitleStep,
7-
type EnterTitleStepValues,
8-
} from '@/v1/bookGroup/create/steps/EnterTitleStep';
4+
import type { EnterTitleStepFormValues } from '@/v1/bookGroup/create/types';
5+
6+
import { appLayoutMeta } from '@/stories/meta';
7+
import { EnterTitleStep } from '@/v1/bookGroup/create/steps';
98

109
const meta: Meta<typeof EnterTitleStep> = {
1110
title: 'bookGroup/create/steps/EnterTitleStep',
@@ -18,7 +17,7 @@ export default meta;
1817
type Story = StoryObj<typeof EnterTitleStep>;
1918

2019
const EnterTitleForm = () => {
21-
const methods = useForm<EnterTitleStepValues>({
20+
const methods = useForm<EnterTitleStepFormValues>({
2221
mode: 'all',
2322
defaultValues: {
2423
title: '',

src/stories/bookGroup/create/funnel/SelectBookStep.stories.tsx src/stories/bookGroup/create/steps/SelectBookStep.stories.tsx

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { Meta, StoryObj } from '@storybook/react';
22
import { FormProvider, useForm } from 'react-hook-form';
33

4+
import type { SelectBookStepFormValues } from '@/v1/bookGroup/create/types';
5+
46
import { appLayoutMeta } from '@/stories/meta';
5-
import SelectBookStep, {
6-
SelectBookFormValue,
7-
} from '@/v1/bookGroup/create/funnel/SelectBookStep';
7+
import { SelectBookStep } from '@/v1/bookGroup/create/steps';
88

99
const meta: Meta<typeof SelectBookStep> = {
10-
title: 'bookGroup/funnel/SelectBookStep',
10+
title: 'bookGroup/create/steps/SelectBookStep',
1111
component: SelectBookStep,
1212
...appLayoutMeta,
1313
};
@@ -17,7 +17,7 @@ export default meta;
1717
type Story = StoryObj<typeof SelectBookStep>;
1818

1919
const RenderSelectBookStep = () => {
20-
const methods = useForm<SelectBookFormValue>();
20+
const methods = useForm<SelectBookStepFormValues>();
2121

2222
const goNextStep = () => {
2323
const book = methods.getValues('book');

src/stories/bookGroup/create/steps/SelectJoinTypeStep.stories.tsx

+7-8
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import { Meta, StoryObj } from '@storybook/react';
22
import { FormProvider, useForm } from 'react-hook-form';
3-
import { appLayoutMeta } from '@/stories/meta';
43

5-
import {
6-
SelectJoinTypeStep,
7-
SelectJoinTypeStepFormValues,
8-
} from '@/v1/bookGroup/create/steps/SelectJoinTypeStep';
4+
import type { SelectJoinTypeStepFormValues } from '@/v1/bookGroup/create/types';
5+
6+
import { appLayoutMeta } from '@/stories/meta';
7+
import { SelectJoinTypeStep } from '@/v1/bookGroup/create/steps';
98

109
const meta: Meta<typeof SelectJoinTypeStep> = {
1110
title: 'bookGroup/create/steps/SelectJoinTypeStep',
@@ -20,15 +19,15 @@ type Story = StoryObj<typeof SelectJoinTypeStep>;
2019
const RenderSelectJoinTypeStep = () => {
2120
const methods = useForm<SelectJoinTypeStepFormValues>({
2221
defaultValues: {
23-
hasJoinPasswd: 'false',
22+
hasJoinPassword: 'false',
2423
},
2524
mode: 'all',
2625
});
2726

2827
const onSubmit = () => {
29-
const { hasJoinPasswd, joinPasswd, joinQuestion } = methods.getValues();
28+
const { hasJoinPassword, joinPassword, joinQuestion } = methods.getValues();
3029
alert(
31-
`가입 문제 유무: ${hasJoinPasswd}\n가입 문제: ${joinQuestion}\n정답: ${joinPasswd}`
30+
`가입 문제 유무: ${hasJoinPassword}\n가입 문제: ${joinQuestion}\n정답: ${joinPassword}`
3231
);
3332
};
3433

src/stories/bookGroup/create/steps/SetUpDetailStep.stories.tsx

+5-11
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
import { appLayoutMeta } from '@/stories/meta';
21
import { Meta, StoryObj } from '@storybook/react';
32
import { FormProvider, useForm } from 'react-hook-form';
43

4+
import type { SetUpDetailStepFormValues } from '@/v1/bookGroup/create/types';
5+
56
import { getTodayDate } from '@/utils/date';
67

7-
import {
8-
SetUpDetailStep,
9-
type SetUpDetailStepValues,
10-
} from '@/v1/bookGroup/create/steps/SetUpDetailStep';
8+
import { appLayoutMeta } from '@/stories/meta';
9+
import { SetUpDetailStep } from '@/v1/bookGroup/create/steps';
1110

1211
const meta: Meta<typeof SetUpDetailStep> = {
1312
title: 'bookGroup/create/steps/SetUpDetailStep',
@@ -20,19 +19,14 @@ export default meta;
2019
type Story = StoryObj<typeof SetUpDetailStep>;
2120

2221
const SetUpDetailForm = () => {
23-
const methods = useForm<SetUpDetailStepValues>({
22+
const methods = useForm<SetUpDetailStepFormValues>({
2423
mode: 'all',
2524
defaultValues: {
2625
title: '',
2726
book: {
2827
bookId: 23,
2928
},
30-
introduce: '',
31-
maxMemberCount: '',
32-
customMemberCount: '',
3329
startDate: getTodayDate(),
34-
endDate: '',
35-
isPublic: false,
3630
},
3731
});
3832

0 commit comments

Comments
 (0)