-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FE] 회원 행사 생성, 비회원 행사 생성 구현 #835
Changes from 18 commits
8312987
ade52ec
4b6eeae
13695a6
159357d
762e565
2a7b518
968f71a
c175e5b
63f21e1
2193639
6016b66
d4f71c7
01ffe9a
61ee956
26c3227
5c5abdf
db26421
910983e
230d8ab
f132106
c95fcd2
f66c76d
743ad77
4cde069
c571bd9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,7 +47,7 @@ Cypress.Commands.add('interceptAPI', ({type, delay = 0, statusCode = 200}: Inter | |
}); | ||
|
||
Cypress.Commands.add('createEventName', (eventName: string) => { | ||
cy.visit(ROUTER_URLS.createEvent); | ||
cy.visit(ROUTER_URLS.createMemberEvent); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분 충돌 날 거예요. 제 부분에서 로그인 진입점도 있어서 이 코드 수정했거든요. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 예상했습니다 ㅎㅎ 즐거운 충돌쇼 |
||
cy.get('input').type(eventName); | ||
cy.get('button').contains('다음').click(); | ||
}); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,25 @@ | ||
import {Event, EventId} from 'types/serviceType'; | ||
import {WithErrorHandlingStrategy} from '@errors/RequestGetError'; | ||
import {CreateEventArgs, EventName} from 'types/createEvent'; | ||
|
||
import {ADMIN_API_PREFIX, USER_API_PREFIX} from '@apis/endpointPrefix'; | ||
import {requestGet, requestPatch, requestPostWithResponse, requestPut} from '@apis/fetcher'; | ||
import {WithEventId} from '@apis/withId.type'; | ||
|
||
export interface RequestPostEvent { | ||
eventName: string; | ||
password: string; | ||
} | ||
export const requestPostGuestEvent = async (postEventArgs: CreateEventArgs) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. args라는 변수명 좋네요! props가 익숙해서 props로 지은 것도 많은데 함수의 파라미터이니깐 args가 더 좋은 이름인 것 같아요 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. api type 이름에 대해서 예ㅔㅔ전에 용어정리 하면서 함께 통일했던 기억이 있어요 이전에 작업한 convention은 팀과의 협업 중 불편하다고 생각되어 만들어 진 것이니까요~! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 저는 컴포넌트의 인자로 들어가는 값이면 props, 함수의 인자로 들어가는 값이면 args라고 생각하며 구현했었어요! |
||
return await requestPostWithResponse<EventId>({ | ||
endpoint: `${USER_API_PREFIX}/guest`, | ||
body: { | ||
...postEventArgs, | ||
}, | ||
}); | ||
}; | ||
|
||
export const requestPostEvent = async ({eventName, password}: RequestPostEvent) => { | ||
export const requestPostMemberEvent = async (eventName: EventName) => { | ||
return await requestPostWithResponse<EventId>({ | ||
endpoint: USER_API_PREFIX, | ||
endpoint: `${USER_API_PREFIX}/events`, | ||
body: { | ||
eventName, | ||
password, | ||
}, | ||
}); | ||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,20 @@ | ||
const EVENT = '/event'; | ||
const EVENT_WITH_EVENT_ID = `${EVENT}/:eventId`; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. event with event id 처음 들었을 때 어색하긴 했는데 어쩔 수 없는 것 같아요 id라고 줄이면 무슨 id인지 혼동할 수 있으니 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 흑흑... 더 생각해볼게요 |
||
|
||
export const ROUTER_URLS = { | ||
main: '/', | ||
createEvent: '/event/create', | ||
event: '/event', | ||
eventManage: '/event/:eventId/admin', | ||
home: '/event/:eventId/home', | ||
member: '/event/:eventId/admin/member', | ||
addBill: '/event/:eventId/admin/add-bill', | ||
editBill: '/event/:eventId/admin/edit-bill', | ||
eventEdit: 'event/:eventId/admin/edit', | ||
images: '/event/:eventId/images', | ||
addImages: '/event/:eventId/admin/add-images', | ||
send: 'event/:eventId/:memberId/send', | ||
qrCode: 'event/:eventId/qrcode', | ||
createGuestEvent: `${EVENT}/create/guest`, | ||
createMemberEvent: `${EVENT}/create/member`, | ||
eventManage: `${EVENT_WITH_EVENT_ID}/admin`, | ||
home: `${EVENT_WITH_EVENT_ID}/home`, | ||
member: `${EVENT_WITH_EVENT_ID}/admin/member`, | ||
addBill: `${EVENT_WITH_EVENT_ID}/admin/add-bill`, | ||
editBill: `${EVENT_WITH_EVENT_ID}/admin/edit-bill`, | ||
eventEdit: `${EVENT_WITH_EVENT_ID}/admin/edit`, | ||
images: `${EVENT_WITH_EVENT_ID}/images`, | ||
addImages: `${EVENT_WITH_EVENT_ID}/admin/add-images`, | ||
send: `${EVENT_WITH_EVENT_ID}/:memberId/send`, | ||
qrCode: `${EVENT_WITH_EVENT_ID}/qrcode`, | ||
event: EVENT, | ||
login: '/login', | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,20 @@ | ||
import {useState} from 'react'; | ||
|
||
import useSetEventNameStep from './useSetEventNameStep'; | ||
import {useSetNickNameStep} from './useSetNicknameStep'; | ||
|
||
// 행사 생성 페이지에서 여러 스텝에 걸쳐 사용되는 상태를 선언해 내려주는 용도의 훅입니다. | ||
const useCreateEventData = () => { | ||
const useCreateGuestEventData = () => { | ||
const eventNameProps = useSetEventNameStep(); | ||
const nickNameProps = useSetNickNameStep(); | ||
const [eventToken, setEventToken] = useState(''); | ||
|
||
return { | ||
eventNameProps, | ||
nickNameProps, | ||
eventToken, | ||
setEventToken, | ||
}; | ||
}; | ||
|
||
export default useCreateEventData; | ||
export default useCreateGuestEventData; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import {useState} from 'react'; | ||
|
||
import validateMemberName from '@utils/validate/validateMemberName'; | ||
import {NickName} from 'types/createEvent'; | ||
|
||
type UseSetNicknameStepProps = ReturnType<typeof useSetNicknameStep>; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ReturnType 좋아요! 훅의 리턴이 너무 많을 때 이렇게 쓰면 유용하더라구요 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 마자요. 자동 타입 추론을 최대한 활용하는게 이득이죵 |
||
|
||
const useSetNicknameStep = () => { | ||
const [nickname, setNickname] = useState<NickName>(''); | ||
const [errorMessage, setErrorMessage] = useState<string | null>(null); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 에러 없을 때 null 처리 좋습니다~ |
||
const [canSubmit, setCanSubmit] = useState(false); | ||
|
||
const handleNicknameChange = (event: React.ChangeEvent<HTMLInputElement>) => { | ||
const name = event.target.value; | ||
const {isValid, errorMessage: errorMessageResult} = validateMemberName(name); | ||
|
||
setErrorMessage(errorMessageResult); | ||
|
||
if (isValid) { | ||
setNickname(name); | ||
} | ||
|
||
setCanSubmit(name.length !== 0); | ||
}; | ||
|
||
return {handleNicknameChange, canSubmit, nickname, errorMessage}; | ||
}; | ||
|
||
export {useSetNicknameStep, type UseSetNicknameStepProps}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import {useMutation, useQueryClient} from '@tanstack/react-query'; | ||
|
||
import {requestPostGuestEvent} from '@apis/request/event'; | ||
import {CreateEventArgs} from 'types/createEvent'; | ||
|
||
const useRequestPostGuestEvent = () => { | ||
const queryClient = useQueryClient(); | ||
|
||
const {mutate, mutateAsync, ...rest} = useMutation({ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 여기서 mutate는 어디서 사용하나요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 안쓰이면 텍스트가 흐리게 처리되는데,, 흐리게 처리되지 않아서 확인을 못했네요. 지금은 지웠습니다. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아하 죠스입니다~~ |
||
mutationFn: ({eventName, nickname, password}: CreateEventArgs) => | ||
requestPostGuestEvent({eventName, nickname, password}), | ||
onSuccess: () => { | ||
queryClient.removeQueries(); | ||
}, | ||
}); | ||
|
||
// 실행 순서를 await으로 보장하기 위해 mutateAsync 사용 | ||
return { | ||
postEvent: mutateAsync, | ||
isPostEventPending: rest.isPending, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. pending을 내보내주는 이유는 버튼의 로딩 애니메이션을 보여주기 위한 것일까요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 어, 있던 코드를 그대로 복붙해온거라 몰랐는데 적용시키면 되겠네요. 적용 완료했습니다. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 굳뜨~~ |
||
...rest, | ||
}; | ||
}; | ||
|
||
export default useRequestPostGuestEvent; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,13 @@ | ||
import {useMutation, useQueryClient} from '@tanstack/react-query'; | ||
|
||
import {RequestPostEvent, requestPostEvent} from '@apis/request/event'; | ||
import {requestPostMemberEvent} from '@apis/request/event'; | ||
import {CreateEventArgs, EventName} from 'types/createEvent'; | ||
|
||
import QUERY_KEYS from '@constants/queryKeys'; | ||
|
||
const useRequestPostEvent = () => { | ||
const useRequestPostMemberEvent = () => { | ||
const queryClient = useQueryClient(); | ||
|
||
const {mutate, mutateAsync, ...rest} = useMutation({ | ||
mutationFn: ({eventName, password}: RequestPostEvent) => requestPostEvent({eventName, password}), | ||
mutationFn: (eventName: EventName) => requestPostMemberEvent(eventName), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이부분도 위에서 말했던, API type에 대한 convention을 지키는게 좋을 것 같습니당 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. serviceType파일에 api관련된 타입을 적으라는 의미가 맞을까요? 토달스?! 이렇게 수정해봤습니당. export type EventName = string;
export type NickName = string;
export type Password = string;
export interface EventCreationData {
eventName: EventName;
nickname: NickName;
password: Password;
}
// 원래 있던거.
export interface Event {
eventName: EventName;
bankName: string;
accountNumber: string;
} Event라는 타입은 원래 있던 타입인데, 이벤트에 왜 계좌이름과 계좌번호라는 타입이 붙어있는진 잘 모르겠으나, 의도한 게 있을 것 같아 남겨뒀어요. 그래서 이벤트 생성시에 반복적으로 사용되는 타입인 행사명, 닉네임, 비밀번호를 담아 EventCreationDara라고 만들어봤습니다. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 저희가 그때 의논한 바로는, src/apis/request 에서는 requst + post + 요청하는 method 다른 src/apis/request 파일들을 확인해 보시면, requestDeleteMember, requestPostBill 과 같이 작성된 것을 확인할 수 있을거에요~!! |
||
onSuccess: () => { | ||
queryClient.removeQueries(); | ||
}, | ||
|
@@ -22,4 +21,4 @@ const useRequestPostEvent = () => { | |
}; | ||
}; | ||
|
||
export default useRequestPostEvent; | ||
export default useRequestPostMemberEvent; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cypress를 주석처리하셨군요ㅋㅋ 테스트 보다는 구현이 먼저라 생각하기 때문에 정상적으로 돌아간다는 전제 하에 임시로 주석처리 괜찮은 것 같아요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jinhokim98 이 부분은 쿠키가 작성한 부분이 반영되면 해결되는것인가요??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 이슈 하나만 있다면 구현했을텐데, 로그인에서 해야할 이슈가 좀 많아서 임시로 해두었습니다 ㅠ.ㅠ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
쿠키 기능이 완성되면 회원과 비회원 각각의 e2e 테스트를 모두 작성해야 할 것 같네요 🙋♀️ 다만, 로그인과 행사 생성 플로우보다 프로젝트의 핵심 기능에 우선적으로 테스트를 작성하는 것이 더 효율적일 수도 있다고 생각합니다. (애초에 지금 e2e가 행사 생성 과정 말고는 없어서.. ㅜㅜ) 취준으로 인해 프로젝트에 사용할 시간이 제한적인 만큼, 무엇을 위해 테스트를 작성하는지를 명확히 정리한 후, 어떤 테스트가 더 중요한지 고민해보는 것이 좋을 것 같아요 👍