Skip to content

Commit 484a165

Browse files
authored
게스트 모집글 작성 페이지 리팩터링 (#243)
* refactor: 게스트 모집글 생성 페이지에 사용되는 상수들 페이지 디렉토리에 포함 * refactor: 게스트 모집글 생성 페이지 상태,로직 분리 * refactor: 크루 만들기 페이지 문자열 상수화 * feat: input에서 scroll blur 처리
1 parent 7093868 commit 484a165

File tree

4 files changed

+200
-107
lines changed

4 files changed

+200
-107
lines changed

src/components/ConditionalFormInput/ConditionalFormInput.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export const ConditionalFormInput = ({
4444
{...register(inputLabel, { required: isRequired })}
4545
{...inputProps}
4646
onChange={(event) => inputOnChange && inputOnChange(event.target.value)}
47+
onWheel={(event) => event.currentTarget.blur()}
4748
/>
4849
{isContainModal && (
4950
<Modal

src/pages/CreateGamePage/CreateGamePage.tsx

+57-107
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1-
import { useState } from 'react';
2-
import { FormProvider, useForm } from 'react-hook-form';
3-
import { useNavigate } from 'react-router-dom';
1+
import { FormProvider } from 'react-hook-form';
2+
3+
import {
4+
CREATE_GAME_STRINGS,
5+
MAX_MEMBER_COUNT_LIST,
6+
PLAY_TIME_LIST,
7+
START_TIME_HOUR_LIST,
8+
START_TIME_MINUTES_LIST,
9+
} from '@pages/CreateGamePage/consts/createGameOptions';
410

511
import { CalendarComponent } from '@components/Calendar';
612
import { ConditionalFormInput } from '@components/ConditionalFormInput';
@@ -11,24 +17,10 @@ import { Button } from '@components/shared/Button';
1117
import { Text } from '@components/shared/Text';
1218
import { VirtualScroll } from '@components/shared/VirtualScroll';
1319

14-
import { useGameMutation } from '@hooks/mutations/useGameMutation';
1520
import { useHeaderTitle } from '@hooks/useHeaderTitle';
1621

1722
import { theme } from '@styles/theme';
1823

19-
import { useLoginInfoStore } from '@stores/loginInfo.store';
20-
21-
import { PostGameRequest } from '@type/api/games';
22-
import { Position } from '@type/models/Position';
23-
24-
import {
25-
MAX_MEMBER_COUNT_LIST,
26-
PLAY_TIME_LIST,
27-
START_TIME_HOUR_LIST,
28-
START_TIME_MINUTES_LIST,
29-
} from '@consts/createGameOptions';
30-
import { PATH_NAME } from '@consts/pathName';
31-
3224
import {
3325
PageLayout,
3426
PageWrapper,
@@ -39,103 +31,61 @@ import {
3931
StyledTimeSelector,
4032
StyledTitle,
4133
} from './CreateGamePage.styles';
34+
import { useCreateGamePage } from './useCreateGamePage';
4235

4336
export const CreateGamePage = () => {
44-
const navigate = useNavigate();
45-
46-
const loginInfo = useLoginInfoStore((state) => state.loginInfo);
47-
if (!loginInfo?.id) {
48-
throw new Error('로그인이 필요한 서비스입니다.');
49-
}
50-
51-
const { mutate } = useGameMutation();
52-
const methods = useForm();
37+
const {
38+
state,
39+
methods,
40+
onSubmit,
41+
handleAddressSelect,
42+
handleCost,
43+
toggleGuestCountModal,
44+
toggleMatchDateModal,
45+
toggleStartTimeModal,
46+
togglePlayTimeModal,
47+
setMaxMemberCount,
48+
setPlayDate,
49+
setPlayStartTimeHours,
50+
setPlayStartTimeMinutes,
51+
setPlayTimeMinutes,
52+
setPositions,
53+
setDetailAddress,
54+
setContent,
55+
} = useCreateGamePage();
5356

5457
const { entryRef, showHeaderTitle } = useHeaderTitle<HTMLDivElement>();
5558

56-
const [maxMemberCount, setMaxMemberCount] = useState<string>('');
57-
const [playDate, setPlayDate] = useState<string>('');
58-
const [playStartTimeHours, setStartTimeHours] = useState<string>('');
59-
const [playStartTimeMinutes, setStartTimeMinutes] = useState<string>('');
60-
const [playTimeMinutes, setPlayTimeMinutes] = useState<string>('');
61-
const [positions, setPositions] = useState<Position[]>([]);
62-
const [mainAddress, setMainAddress] = useState<string>('');
63-
const [detailAddress, setDetailAddress] = useState<string>('');
64-
const [cost, setCost] = useState<string>('0');
65-
const [content, setContent] = useState<string>('');
66-
67-
const [isGuestCountModalOpen, setIsGuestCountModalOpen] = useState(false);
68-
const [isMatchDateModalOpen, setIsMatchDateModalOpen] = useState(false);
69-
const [isStartTimeModalOpen, setIsStartTimeModalOpen] = useState(false);
70-
const [isPlayTimeModalOpen, setIsPlayTimeModalOpen] = useState(false);
71-
72-
const onSubmit = () => {
73-
const gameData: PostGameRequest = {
74-
maxMemberCount: parseInt(maxMemberCount),
75-
playDate,
76-
playStartTime: `${playStartTimeHours}:${playStartTimeMinutes}`,
77-
playTimeMinutes: parseInt(playTimeMinutes),
78-
positions,
79-
mainAddress,
80-
detailAddress,
81-
cost: parseInt(cost),
82-
content,
83-
};
84-
85-
mutate(gameData, {
86-
onSuccess: ({ gameId }) => {
87-
navigate(PATH_NAME.GET_GAMES_PATH(String(gameId)));
88-
},
89-
});
90-
};
91-
92-
const handleAddressSelect = () => {
93-
new daum.Postcode({
94-
oncomplete: ({ address }: { address: string }) => {
95-
setMainAddress(address);
96-
},
97-
}).open();
98-
};
99-
100-
const handleCost = (item: string) => {
101-
if (parseInt(item) < 0) {
102-
setCost('0');
103-
} else if (parseInt(item) > 100000) {
104-
setCost('100000');
105-
} else setCost(item);
106-
};
107-
108-
const toggleGuestCountModal = () => {
109-
setIsGuestCountModalOpen((prev) => !prev);
110-
};
111-
112-
const toggleMatchDateModal = () => {
113-
setIsMatchDateModalOpen((prev) => !prev);
114-
};
115-
116-
const toggleStartTimeModal = () => {
117-
setIsStartTimeModalOpen((prev) => !prev);
118-
};
119-
120-
const togglePlayTimeModal = () => {
121-
setIsPlayTimeModalOpen((prev) => !prev);
122-
};
59+
const {
60+
maxMemberCount,
61+
playDate,
62+
playStartTimeHours,
63+
playStartTimeMinutes,
64+
playTimeMinutes,
65+
mainAddress,
66+
detailAddress,
67+
cost,
68+
isGuestCountModalOpen,
69+
isMatchDateModalOpen,
70+
isStartTimeModalOpen,
71+
isPlayTimeModalOpen,
72+
} = state;
12373

12474
return (
12575
<PageLayout>
12676
<PageWrapper>
127-
<Header title={showHeaderTitle ? '게스트 모집하기' : ''} />
77+
<Header title={showHeaderTitle ? CREATE_GAME_STRINGS.TITLE : ''} />
12878
<FormProvider {...methods}>
12979
<StyledCreateForm onSubmit={methods.handleSubmit(onSubmit)}>
13080
<StyledTitle>
13181
<div ref={entryRef}>
13282
<Text size={20} weight={700}>
133-
게스트 모집하기
83+
{CREATE_GAME_STRINGS.TITLE}
13484
</Text>
13585
</div>
13686
</StyledTitle>
13787
<ConditionalFormInput
138-
title="게스트 인원을 선택해 주세요!"
88+
title={CREATE_GAME_STRINGS.GUEST_COUNT}
13989
readOnly={true}
14090
isContainModal={true}
14191
inputLabel="guest-count"
@@ -151,7 +101,7 @@ export const CreateGamePage = () => {
151101
/>
152102
</ConditionalFormInput>
153103
<ConditionalFormInput
154-
title="경기 날짜를 선택해 주세요!"
104+
title={CREATE_GAME_STRINGS.MATCH_DATE}
155105
readOnly={true}
156106
isContainModal={true}
157107
inputLabel="match-date"
@@ -163,7 +113,7 @@ export const CreateGamePage = () => {
163113
<CalendarComponent setDate={setPlayDate} />
164114
</ConditionalFormInput>
165115
<ConditionalFormInput
166-
title="경기 시작 시간을 선택해 주세요!"
116+
title={CREATE_GAME_STRINGS.START_TIME}
167117
readOnly={true}
168118
isContainModal={true}
169119
inputLabel="start-time"
@@ -176,18 +126,18 @@ export const CreateGamePage = () => {
176126
<VirtualScroll
177127
width="20%"
178128
list={[...START_TIME_HOUR_LIST]}
179-
onItemSelected={setStartTimeHours}
129+
onItemSelected={setPlayStartTimeHours}
180130
/>
181131
<StyledTimeColon>{':'}</StyledTimeColon>
182132
<VirtualScroll
183133
width="20%"
184134
list={[...START_TIME_MINUTES_LIST]}
185-
onItemSelected={setStartTimeMinutes}
135+
onItemSelected={setPlayStartTimeMinutes}
186136
/>
187137
</StyledTimeSelector>
188138
</ConditionalFormInput>
189139
<ConditionalFormInput
190-
title="경기 플레이타임을 선택해 주세요!"
140+
title={CREATE_GAME_STRINGS.PLAY_TIME}
191141
readOnly={true}
192142
isContainModal={true}
193143
inputLabel="play-time"
@@ -203,13 +153,13 @@ export const CreateGamePage = () => {
203153
/>
204154
</ConditionalFormInput>
205155
<Text size={16} weight={300}>
206-
선호하는 포지션을 선택해 주세요!
156+
{CREATE_GAME_STRINGS.POSITION}
207157
</Text>
208158
<StyledPositionsWrapper>
209159
<SelectPosition setPositions={setPositions} />
210160
</StyledPositionsWrapper>
211161
<ConditionalFormInput
212-
title="주소를 입력해 주세요!"
162+
title={CREATE_GAME_STRINGS.MAIN_ADDRESS}
213163
isRequired={true}
214164
readOnly={true}
215165
isContainModal={false}
@@ -219,14 +169,14 @@ export const CreateGamePage = () => {
219169
/>
220170
<ConditionalFormInput
221171
isRequired={true}
222-
title="상세장소를 입력해 주세요!"
172+
title={CREATE_GAME_STRINGS.DETAIL_ADDRESS}
223173
isContainModal={false}
224174
inputLabel="address-detail"
225175
inputOnChange={setDetailAddress}
226176
value={detailAddress}
227177
/>
228178
<ConditionalFormInput
229-
title="참가비용을 입력해 주세요!"
179+
title={CREATE_GAME_STRINGS.COST}
230180
isContainModal={false}
231181
inputLabel="cost"
232182
inputOnChange={handleCost}
@@ -238,7 +188,7 @@ export const CreateGamePage = () => {
238188
max={'100000'}
239189
/>
240190
<TextArea
241-
title="상세설명을 입력해 주세요!"
191+
title={CREATE_GAME_STRINGS.CONTENT}
242192
inputLabel="content"
243193
inputOnChange={setContent}
244194
/>
@@ -251,7 +201,7 @@ export const CreateGamePage = () => {
251201
backgroundColor={theme.PALETTE.RED_600}
252202
type="submit"
253203
>
254-
모집하기
204+
{CREATE_GAME_STRINGS.CREATE}
255205
</Button>
256206
<StyledEmptyContainer />
257207
</StyledCreateForm>

src/consts/createGameOptions.ts src/pages/CreateGamePage/consts/createGameOptions.ts

+14
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,17 @@ export const PLAY_TIME_LIST = [
5959
'330분',
6060
'360분',
6161
] as const;
62+
63+
export const CREATE_GAME_STRINGS = {
64+
TITLE: '게스트 모집하기',
65+
GUEST_COUNT: '게스트 인원을 선택해 주세요!',
66+
MATCH_DATE: '경기 날짜를 선택해 주세요!',
67+
START_TIME: '경기 시작 시간을 선택해 주세요!',
68+
PLAY_TIME: '경기 플레이타임을 선택해 주세요!',
69+
POSITION: '선호하는 포지션을 선택해 주세요!',
70+
MAIN_ADDRESS: '주소를 입력해 주세요!',
71+
DETAIL_ADDRESS: '상세장소를 입력해 주세요!',
72+
COST: '참가비용을 입력해 주세요!',
73+
CONTENT: '상세설명을 입력해 주세요!',
74+
CREATE: '모집하기',
75+
} as const;

0 commit comments

Comments
 (0)