From 56242d37885c46fbf145af97a5f7fda1398a24d2 Mon Sep 17 00:00:00 2001 From: Jiseung Date: Fri, 24 Nov 2023 00:46:34 +0900 Subject: [PATCH 1/9] =?UTF-8?q?=F0=9F=8E=A8=20=EB=AA=A8=EA=B0=81=EC=BD=94?= =?UTF-8?q?=20=EC=B0=B8=EC=84=9D/=EC=B0=B8=EC=84=9D=20=EC=B7=A8=EC=86=8C?= =?UTF-8?q?=20=EA=B4=80=EB=A0=A8=20query=20hook=20=EB=B0=8F=20query=20key?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/frontend/src/mocks/mogaco.ts | 2 +- app/frontend/src/queries/hooks/mogaco.ts | 29 ++++++++++++++++++++++-- app/frontend/src/queries/mogaco.ts | 3 ++- app/frontend/src/services/mogaco.ts | 8 +++++-- 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/app/frontend/src/mocks/mogaco.ts b/app/frontend/src/mocks/mogaco.ts index 8f43e91de..34b9ef70e 100644 --- a/app/frontend/src/mocks/mogaco.ts +++ b/app/frontend/src/mocks/mogaco.ts @@ -61,6 +61,7 @@ const participantsList = [ export const mogacoAPIHandlers = [ http.get('/mogaco', () => HttpResponse.json(mogacoList)), + http.delete('/mogaco/:id', () => HttpResponse.json(null, { status: 200 })), http.get('/mogaco/:id', ({ params: { id } }) => HttpResponse.json(mogacoList[Number(id) - 1]), ), @@ -81,5 +82,4 @@ export const mogacoAPIHandlers = [ ); return HttpResponse.json(null, { status: 200 }); }), - http.delete('/mogaco/:id', () => HttpResponse.json(null, { status: 200 })), ]; diff --git a/app/frontend/src/queries/hooks/mogaco.ts b/app/frontend/src/queries/hooks/mogaco.ts index 2957aa4b1..0967f8f31 100644 --- a/app/frontend/src/queries/hooks/mogaco.ts +++ b/app/frontend/src/queries/hooks/mogaco.ts @@ -1,9 +1,8 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { queryKeys } from '@/queries'; import { mogaco } from '@/services'; -import { queryKeys } from '..'; - export const useDeleteMogacoQuery = () => { const queryClient = useQueryClient(); @@ -16,3 +15,29 @@ export const useDeleteMogacoQuery = () => { }, }); }; + +export const useJoinMogacoQuery = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: (postId: string) => mogaco.join(postId), + onSuccess: (data, postId) => { + queryClient.invalidateQueries({ + queryKey: queryKeys.mogaco.participants(postId).queryKey, + }); + }, + }); +}; + +export const useQuitMogacoQuery = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: (postId: string) => mogaco.delete(postId), + onSuccess: (data, postId) => { + queryClient.invalidateQueries({ + queryKey: queryKeys.mogaco.participants(postId).queryKey, + }); + }, + }); +}; diff --git a/app/frontend/src/queries/mogaco.ts b/app/frontend/src/queries/mogaco.ts index 5ed5141ed..61399d162 100644 --- a/app/frontend/src/queries/mogaco.ts +++ b/app/frontend/src/queries/mogaco.ts @@ -1,4 +1,4 @@ -// eslint-disable-next-line import/no-extraneous-dependencies + import { createQueryKeys } from '@lukemorales/query-key-factory'; import { mogaco } from '@/services'; @@ -9,4 +9,5 @@ export const mogacoKeys = createQueryKeys('mogaco', { queryFn: () => mogaco.list(), }), detail: (id: string) => [id], + participants: (id: string) => [id], }); diff --git a/app/frontend/src/services/mogaco.ts b/app/frontend/src/services/mogaco.ts index 7499ad040..c04264a1e 100644 --- a/app/frontend/src/services/mogaco.ts +++ b/app/frontend/src/services/mogaco.ts @@ -26,10 +26,14 @@ export const mogaco = { return data; }, join: async (id: string) => { - await morakAPI.post(`${mogaco.endPoint.index}/${id}/join`); + const response = await morakAPI.post(`${mogaco.endPoint.index}/${id}/join`); + return response; }, quit: async (id: string) => { - await morakAPI.delete(`${mogaco.endPoint.index}/${id}/join`); + const response = await morakAPI.delete( + `${mogaco.endPoint.index}/${id}/join`, + ); + return response; }, delete: async (id: string) => { const response = await morakAPI.delete(`${mogaco.endPoint.index}/${id}`); From 21d5f64d0d30b7954d79c8be56bed73a2710595c Mon Sep 17 00:00:00 2001 From: Jiseung Date: Fri, 24 Nov 2023 01:15:53 +0900 Subject: [PATCH 2/9] =?UTF-8?q?=E2=9C=A8=20detail,=20participants=20?= =?UTF-8?q?=EC=BF=BC=EB=A6=AC=20=ED=82=A4=20=EC=88=98=EC=A0=95=20=EB=B0=8F?= =?UTF-8?q?=20member=20=EC=BF=BC=EB=A6=AC=20=ED=82=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/frontend/src/queries/index.ts | 5 +++-- app/frontend/src/queries/member.ts | 7 +++++++ app/frontend/src/queries/mogaco.ts | 11 ++++++++--- 3 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 app/frontend/src/queries/member.ts diff --git a/app/frontend/src/queries/index.ts b/app/frontend/src/queries/index.ts index 519c343e3..aa4001cb6 100644 --- a/app/frontend/src/queries/index.ts +++ b/app/frontend/src/queries/index.ts @@ -1,6 +1,7 @@ -// eslint-disable-next-line import/no-extraneous-dependencies + import { mergeQueryKeys } from '@lukemorales/query-key-factory'; +import { memberKeys } from './member'; import { mogacoKeys } from './mogaco'; -export const queryKeys = mergeQueryKeys(mogacoKeys); +export const queryKeys = mergeQueryKeys(mogacoKeys, memberKeys); diff --git a/app/frontend/src/queries/member.ts b/app/frontend/src/queries/member.ts new file mode 100644 index 000000000..a0cae2f09 --- /dev/null +++ b/app/frontend/src/queries/member.ts @@ -0,0 +1,7 @@ +import { createQueryKeys } from '@lukemorales/query-key-factory'; + +import { member } from '@/services'; + +export const memberKeys = createQueryKeys('member', { + me: () => ({ queryKey: ['me'], queryFn: () => member.myInfo() }), +}); diff --git a/app/frontend/src/queries/mogaco.ts b/app/frontend/src/queries/mogaco.ts index 61399d162..56da1104d 100644 --- a/app/frontend/src/queries/mogaco.ts +++ b/app/frontend/src/queries/mogaco.ts @@ -1,4 +1,3 @@ - import { createQueryKeys } from '@lukemorales/query-key-factory'; import { mogaco } from '@/services'; @@ -8,6 +7,12 @@ export const mogacoKeys = createQueryKeys('mogaco', { queryKey: [{ filters }], queryFn: () => mogaco.list(), }), - detail: (id: string) => [id], - participants: (id: string) => [id], + detail: (id: string) => ({ + queryKey: [id], + queryFn: () => mogaco.detail(id), + }), + participants: (id: string) => ({ + queryKey: [id], + queryFn: () => mogaco.participants(id), + }), }); From a335df2ca5bd4b52e4b5c0f70ef14953f3892b00 Mon Sep 17 00:00:00 2001 From: Jiseung Date: Fri, 24 Nov 2023 01:26:49 +0900 Subject: [PATCH 3/9] =?UTF-8?q?=F0=9F=8F=B7=EF=B8=8F=20=ED=83=80=EC=9E=85?= =?UTF-8?q?=20UserInfo=20->=20Member=EB=A1=9C=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/MogacoDetail/DetailHeader.tsx | 6 +++--- app/frontend/src/services/member.ts | 8 ++++---- app/frontend/src/stores/user.ts | 4 ++-- app/frontend/src/types/index.ts | 2 +- app/frontend/src/types/{user.ts => member.ts} | 2 +- app/frontend/src/types/mogaco.ts | 9 +++------ 6 files changed, 14 insertions(+), 17 deletions(-) rename app/frontend/src/types/{user.ts => member.ts} (77%) diff --git a/app/frontend/src/components/MogacoDetail/DetailHeader.tsx b/app/frontend/src/components/MogacoDetail/DetailHeader.tsx index 255173943..34487ef33 100644 --- a/app/frontend/src/components/MogacoDetail/DetailHeader.tsx +++ b/app/frontend/src/components/MogacoDetail/DetailHeader.tsx @@ -3,7 +3,7 @@ import { useState, useEffect } from 'react'; import { UserChip } from '@/components'; import { member } from '@/services'; import { sansBold24 } from '@/styles/font.css'; -import { UserInfo } from '@/types'; +import { Member } from '@/types'; import { DetailHeaderButtons } from './DetailHeaderButtons'; import * as styles from './index.css'; @@ -25,7 +25,7 @@ export function DetailHeader({ userHosted, userParticipated, }: DetailHeaderProps) { - const [hostUser, setHostUser] = useState(null); + const [hostUser, setHostUser] = useState(null); useEffect(() => { if (hostUser) { @@ -33,7 +33,7 @@ export function DetailHeader({ } const getUser = async () => { - const data = await member.userInfoById(memberId); + const data = await member.infoById(memberId); setHostUser(data); }; diff --git a/app/frontend/src/services/member.ts b/app/frontend/src/services/member.ts index 66c4da2dc..0174aaa1b 100644 --- a/app/frontend/src/services/member.ts +++ b/app/frontend/src/services/member.ts @@ -1,4 +1,4 @@ -import { UserInfo } from '@/types'; +import { Member } from '@/types'; import { morakAPI } from './morakAPI'; @@ -9,12 +9,12 @@ export const member = { }, myInfo: async () => { - const { data } = await morakAPI.get(member.endPoint.me); + const { data } = await morakAPI.get(member.endPoint.me); return data; }, - userInfoById: async (id: string) => { - const { data } = await morakAPI.get( + infoById: async (id: string) => { + const { data } = await morakAPI.get( `${member.endPoint.default}/${id}`, ); return data; diff --git a/app/frontend/src/stores/user.ts b/app/frontend/src/stores/user.ts index 8e1cfec8d..ef7829dd3 100644 --- a/app/frontend/src/stores/user.ts +++ b/app/frontend/src/stores/user.ts @@ -1,6 +1,6 @@ import { atom, useAtom } from 'jotai'; -import { UserInfo } from '@/types'; +import { Member } from '@/types'; -const userStore = atom(null); +const userStore = atom(null); export const useUserAtom = () => useAtom(userStore); diff --git a/app/frontend/src/types/index.ts b/app/frontend/src/types/index.ts index 3c2485f26..d345d022b 100644 --- a/app/frontend/src/types/index.ts +++ b/app/frontend/src/types/index.ts @@ -1,3 +1,3 @@ export * from './chatting'; +export * from './member'; export * from './mogaco'; -export * from './user'; diff --git a/app/frontend/src/types/user.ts b/app/frontend/src/types/member.ts similarity index 77% rename from app/frontend/src/types/user.ts rename to app/frontend/src/types/member.ts index 0ef668185..9cc212a1b 100644 --- a/app/frontend/src/types/user.ts +++ b/app/frontend/src/types/member.ts @@ -1,4 +1,4 @@ -export type UserInfo = { +export type Member = { providerId: string; email: string; nickname: string; diff --git a/app/frontend/src/types/mogaco.ts b/app/frontend/src/types/mogaco.ts index a263f1e10..f5273e0c5 100644 --- a/app/frontend/src/types/mogaco.ts +++ b/app/frontend/src/types/mogaco.ts @@ -1,3 +1,5 @@ +import { Member } from './member'; + interface MogacoTypes { id: string; groupId: number; @@ -23,7 +25,7 @@ export type Mogaco = Pick< | 'maxHumanCount' | 'address' | 'status' ->; +> & { member: Member }; export type MogacoPostForm = Pick< MogacoTypes, @@ -47,8 +49,3 @@ export type MogacoPostRequest = Pick< | 'address' | 'status' >; - -export type Participant = Pick< - MogacoTypes, - 'id' | 'nickname' | 'profilePicture' ->; From cb91c077b923b5c02085ca3647f9a4de873136b7 Mon Sep 17 00:00:00 2001 From: Jiseung Date: Fri, 24 Nov 2023 02:19:53 +0900 Subject: [PATCH 4/9] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20=EC=83=81=EC=84=B8=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20props=20=EC=9E=AC=EC=A0=95=EC=9D=98=20=EB=B0=8F=20?= =?UTF-8?q?=EC=BF=BC=EB=A6=AC=20=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기존 Participant 타입을 Member 타입으로 대체 --- .../MogacoDetail/DetailContents.tsx | 7 -- .../components/MogacoDetail/DetailHeader.tsx | 54 ++++-------- .../MogacoDetail/DetailHeaderButtons.tsx | 45 +++++----- .../components/MogacoDetail/DetailInfo.tsx | 24 ++---- .../src/components/MogacoDetail/index.tsx | 83 ++++++------------- app/frontend/src/pages/MogacoDetail/index.tsx | 50 +---------- app/frontend/src/services/mogaco.ts | 4 +- app/frontend/src/types/mogaco.ts | 1 - 8 files changed, 78 insertions(+), 190 deletions(-) delete mode 100644 app/frontend/src/components/MogacoDetail/DetailContents.tsx diff --git a/app/frontend/src/components/MogacoDetail/DetailContents.tsx b/app/frontend/src/components/MogacoDetail/DetailContents.tsx deleted file mode 100644 index 5e2a06ef3..000000000 --- a/app/frontend/src/components/MogacoDetail/DetailContents.tsx +++ /dev/null @@ -1,7 +0,0 @@ -type DetailContentsProps = { - contents: string; -}; - -export function DetailContents({ contents }: DetailContentsProps) { - return
{contents}
; -} diff --git a/app/frontend/src/components/MogacoDetail/DetailHeader.tsx b/app/frontend/src/components/MogacoDetail/DetailHeader.tsx index 34487ef33..ff1f83912 100644 --- a/app/frontend/src/components/MogacoDetail/DetailHeader.tsx +++ b/app/frontend/src/components/MogacoDetail/DetailHeader.tsx @@ -1,65 +1,41 @@ -import { useState, useEffect } from 'react'; - import { UserChip } from '@/components'; -import { member } from '@/services'; import { sansBold24 } from '@/styles/font.css'; -import { Member } from '@/types'; +import { Member, Mogaco } from '@/types'; import { DetailHeaderButtons } from './DetailHeaderButtons'; import * as styles from './index.css'; type DetailHeaderProps = { id: string; - memberId: string; - title: string; - status: '모집 중' | '마감' | '종료'; - userHosted: boolean; - userParticipated: boolean; + currentUser: Member; + mogacoData: Mogaco; + participantList: Member[]; }; export function DetailHeader({ id, - memberId, - title, - status, - userHosted, - userParticipated, + currentUser, + mogacoData, + participantList, }: DetailHeaderProps) { - const [hostUser, setHostUser] = useState(null); - - useEffect(() => { - if (hostUser) { - return; - } - - const getUser = async () => { - const data = await member.infoById(memberId); - setHostUser(data); - }; - - getUser(); - }, [hostUser, memberId]); - return (
-
{title}
+
{mogacoData.title}
- {hostUser && ( - - )} + 부스트캠프 웹·모바일 8기
diff --git a/app/frontend/src/components/MogacoDetail/DetailHeaderButtons.tsx b/app/frontend/src/components/MogacoDetail/DetailHeaderButtons.tsx index 74cba2488..bb9a580fd 100644 --- a/app/frontend/src/components/MogacoDetail/DetailHeaderButtons.tsx +++ b/app/frontend/src/components/MogacoDetail/DetailHeaderButtons.tsx @@ -1,32 +1,39 @@ -import { useNavigate, useParams } from 'react-router-dom'; +import { useNavigate } from 'react-router-dom'; import { Button } from '@/components'; -import { useDeleteMogacoQuery } from '@/queries/hooks'; -import { mogaco } from '@/services'; +import { + useDeleteMogacoQuery, + useJoinMogacoQuery, + useQuitMogacoQuery, +} from '@/queries/hooks'; +import { Member, Mogaco } from '@/types'; type DetailHeaderButtonsProps = { id: string; - userHosted: boolean; - userParticipated: boolean; - status: '모집 중' | '마감' | '종료'; + currentUser: Member; + mogacoData: Mogaco; + participantList: Member[]; }; export function DetailHeaderButtons({ id, - userHosted, - userParticipated, - status, + currentUser, + mogacoData, + participantList, }: DetailHeaderButtonsProps) { const navigate = useNavigate(); - const { id: postId } = useParams(); - const { mutateAsync } = useDeleteMogacoQuery(); - const handleDelete = async () => { - if (!postId) { - return; - } + const deleteMogaco = useDeleteMogacoQuery(); + const joinMogaco = useJoinMogacoQuery(); + const quitMogaco = useQuitMogacoQuery(); - const res = await mutateAsync(id); + const userHosted = mogacoData.member.providerId === currentUser.providerId; + const userParticipated = participantList.find( + (participant) => participant.providerId === currentUser.providerId, + ); + + const handleDelete = async () => { + const res = await deleteMogaco.mutateAsync(id!); if (res.status === 200) { navigate('/mogaco'); } @@ -41,11 +48,11 @@ export function DetailHeaderButtons({ }; const onClickJoin = async () => { - await mogaco.join(id); + await joinMogaco.mutateAsync(id!); }; const onClickQuit = async () => { - await mogaco.quit(id); + await quitMogaco.mutateAsync(id!); }; if (userHosted) { @@ -66,7 +73,7 @@ export function DetailHeaderButtons({ ); } - if (status === '모집 중') { + if (mogacoData.status === '모집 중') { return userParticipated ? ( <>