From 7df80a0cf174a97a71fbea415017944918b3175a Mon Sep 17 00:00:00 2001 From: Seok93 Date: Thu, 5 Sep 2024 15:35:07 +0900 Subject: [PATCH 1/5] =?UTF-8?q?Feat:=20#109=20=ED=94=84=EB=A1=9C=EC=A0=9D?= =?UTF-8?q?=ED=8A=B8=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20API?= =?UTF-8?q?=EB=A5=BC=20=EC=9C=84=ED=95=9C=20React=20Query=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/query/useProjectQuery.ts | 22 ++++++++++++++++++++++ src/services/projectService.ts | 21 ++++++++++++++++++--- 2 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 src/hooks/query/useProjectQuery.ts diff --git a/src/hooks/query/useProjectQuery.ts b/src/hooks/query/useProjectQuery.ts new file mode 100644 index 00000000..e2893ff2 --- /dev/null +++ b/src/hooks/query/useProjectQuery.ts @@ -0,0 +1,22 @@ +import { useQuery } from '@tanstack/react-query'; +import { getProjectList } from '@services/projectService'; + +import type { Team } from '@/types/TeamType'; + +// Todo: Project Query CUD로직 작성하기 +export default function useReadProjects(teamId: Team['teamId']) { + const { + data: projectList = [], + isLoading: isProjectLoading, + isError: isProjectError, + error: projectError, + } = useQuery({ + queryKey: ['teams', teamId, 'projects'], + queryFn: async () => { + const { data } = await getProjectList(teamId); + return data; + }, + }); + + return { projectList, isProjectLoading, isProjectError, projectError }; +} diff --git a/src/services/projectService.ts b/src/services/projectService.ts index b89aa788..402b99b6 100644 --- a/src/services/projectService.ts +++ b/src/services/projectService.ts @@ -1,15 +1,17 @@ import { authAxios } from '@services/axiosProvider'; + import type { AxiosRequestConfig } from 'axios'; -import type { User, UserWithRole } from '@/types/UserType'; +import type { Team } from '@/types/TeamType'; import type { Project } from '@/types/ProjectType'; +import type { User, UserWithRole } from '@/types/UserType'; /** * 프로젝트에 속한 유저 목록을 검색하는 API * * @export * @async - * @param {Project['projectId']} projectId - 프로젝트 아이디 - * @param {User['nickname']} nickname - 유저 닉네임 + * @param {Project['projectId']} projectId - 프로젝트 ID + * @param {User['nickname']} nickname - 유저 닉네임 * @param {AxiosRequestConfig} [axiosConfig={}] - axios 요청 옵션 설정 객체 * @returns {Promise>} */ @@ -20,3 +22,16 @@ export async function findUserByProject( ) { return authAxios.get(`project/${projectId}/user/search?nickname=${nickname}`, axiosConfig); } + +/** + * 프로젝트 목록 조회 API + * + * @export + * @async + * @param {Team['teamId']} teamId - 팀 ID + * @param {AxiosRequestConfig} axiosConfig - axios 요청 옵션 설정 객체 + * @returns {Promise>} + */ +export async function getProjectList(teamId: Team['teamId'], axiosConfig: AxiosRequestConfig = {}) { + return authAxios.get(`team/${teamId}/project`, axiosConfig); +} From 9b1e1bfabffc8987f482ccbe815bf8482f201f67 Mon Sep 17 00:00:00 2001 From: Seok93 Date: Thu, 5 Sep 2024 15:36:23 +0900 Subject: [PATCH 2/5] =?UTF-8?q?Feat:=20#109=20=ED=94=84=EB=A1=9C=EC=A0=9D?= =?UTF-8?q?=ED=8A=B8=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20API=20MSW?= =?UTF-8?q?=20=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mocks/services/projectServiceHandler.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/mocks/services/projectServiceHandler.ts b/src/mocks/services/projectServiceHandler.ts index 333a6e0f..f8277183 100644 --- a/src/mocks/services/projectServiceHandler.ts +++ b/src/mocks/services/projectServiceHandler.ts @@ -1,5 +1,5 @@ import { http, HttpResponse } from 'msw'; -import { PROJECT_USER_DUMMY, ROLE_DUMMY, USER_DUMMY } from '@mocks/mockData'; +import { PROJECT_DUMMY, PROJECT_USER_DUMMY, ROLE_DUMMY, USER_DUMMY } from '@mocks/mockData'; import type { Role } from '@/types/RoleType'; import type { User } from '@/types/UserType'; @@ -35,6 +35,17 @@ const projectServiceHandler = [ return HttpResponse.json(matchedUserList); }), + // 프로젝트 목록 조회 API + http.get(`${BASE_URL}/team/:teamId/project`, ({ request, params }) => { + const accessToken = request.headers.get('Authorization'); + const { teamId } = params; + + if (!accessToken) return new HttpResponse(null, { status: 401 }); + + const projectList = PROJECT_DUMMY.filter((project) => project.teamId === Number(teamId)); + + return HttpResponse.json(projectList); + }), ]; export default projectServiceHandler; From cf631c88d8eb587ed19b03c340669d272622f65c Mon Sep 17 00:00:00 2001 From: Seok93 Date: Thu, 5 Sep 2024 15:38:10 +0900 Subject: [PATCH 3/5] =?UTF-8?q?Feat:=20#109=20=ED=94=84=EB=A1=9C=EC=A0=9D?= =?UTF-8?q?=ED=8A=B8=20=EB=AA=A9=EB=A1=9D=20=EC=82=AC=EC=9D=B4=EB=93=9C?= =?UTF-8?q?=EB=B0=94=20=EB=85=B8=EC=B6=9C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/layouts/page/ProjectLayout.tsx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/layouts/page/ProjectLayout.tsx b/src/layouts/page/ProjectLayout.tsx index 00e94da9..0bf3eefc 100644 --- a/src/layouts/page/ProjectLayout.tsx +++ b/src/layouts/page/ProjectLayout.tsx @@ -1,21 +1,23 @@ import { useMemo } from 'react'; import { Navigate, NavLink, Outlet, useParams } from 'react-router-dom'; +import { RiSettings5Fill } from 'react-icons/ri'; +import { ProjectContext } from '@hooks/useProjectContext'; import useModal from '@hooks/useModal'; +import useReadProjects from '@hooks/query/useProjectQuery'; import ListSidebar from '@components/sidebar/ListSidebar'; import ListProject from '@components/sidebar/ListProject'; import CreateModalTask from '@components/modal/task/CreateModalTask'; import CreateModalProjectStatus from '@components/modal/project-status/CreateModalProjectStatus'; -import { ProjectContext } from '@hooks/useProjectContext'; -import { PROJECT_DUMMY } from '@mocks/mockData'; -import { RiSettings5Fill } from 'react-icons/ri'; export default function ProjectLayout() { - const { projectId } = useParams(); + const { teamId, projectId } = useParams(); + const { projectList } = useReadProjects(Number(teamId)); const { showModal: showTaskModal, openModal: openTaskModal, closeModal: closeTaskModal } = useModal(); const { showModal: showStatusModal, openModal: openStatusModal, closeModal: closeStatusModal } = useModal(); + const project = useMemo( - () => PROJECT_DUMMY.find((project) => project.projectId.toString() === projectId), - [projectId], + () => projectList?.find((project) => project.projectId.toString() === projectId), + [projectList, projectId], ); if (!project) return ; @@ -24,7 +26,7 @@ export default function ProjectLayout() { <>
- +
From bbcb385d91c3dedeb21118c0e542c990ebaef63c Mon Sep 17 00:00:00 2001 From: Seok93 Date: Thu, 5 Sep 2024 16:46:50 +0900 Subject: [PATCH 4/5] =?UTF-8?q?Feat:=20#109=20=EB=84=A4=ED=8A=B8=EC=9B=8C?= =?UTF-8?q?=ED=81=AC=20=ED=86=B5=EC=8B=A0=20=EB=8C=80=EA=B8=B0=EC=8B=9C=20?= =?UTF-8?q?Spinner=20UI=20=EB=85=B8=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/Spinner.tsx | 6 +++++- .../modal/project-status/ModalProjectStatusForm.tsx | 8 +------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/components/common/Spinner.tsx b/src/components/common/Spinner.tsx index 9770f344..818956dd 100644 --- a/src/components/common/Spinner.tsx +++ b/src/components/common/Spinner.tsx @@ -1,3 +1,7 @@ export default function Spinner() { - return
; + return ( +
+
+
+ ); } diff --git a/src/components/modal/project-status/ModalProjectStatusForm.tsx b/src/components/modal/project-status/ModalProjectStatusForm.tsx index ef4b0bfb..f91810cc 100644 --- a/src/components/modal/project-status/ModalProjectStatusForm.tsx +++ b/src/components/modal/project-status/ModalProjectStatusForm.tsx @@ -38,13 +38,7 @@ export default function ModalProjectStatusForm({ formId, project, statusId, onSu reset(initialValue); }, [initialValue, reset]); - if (isStatusLoading) { - return ( -
- -
- ); - } + if (isStatusLoading) return ; return (
From fdca4c1dcabc2f4822853d4cc031b9890a07be83 Mon Sep 17 00:00:00 2001 From: Seok93 Date: Thu, 5 Sep 2024 16:47:57 +0900 Subject: [PATCH 5/5] =?UTF-8?q?Chore:=20#109=20Spinner=20UI=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=EC=9C=BC=EB=A1=9C=20=EB=8B=A4=EB=A5=B8=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/modal/task/ModalTaskForm.tsx | 8 +------- src/layouts/page/ProjectLayout.tsx | 5 ++++- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/components/modal/task/ModalTaskForm.tsx b/src/components/modal/task/ModalTaskForm.tsx index 3270885d..74d04d48 100644 --- a/src/components/modal/task/ModalTaskForm.tsx +++ b/src/components/modal/task/ModalTaskForm.tsx @@ -170,13 +170,7 @@ export default function ModalTaskForm({ formId, project, taskId, onSubmit }: Mod updateFiles(files); }; - if (isStatusLoading) { - return ( -
- -
- ); - } + if (isStatusLoading) return ; return ( diff --git a/src/layouts/page/ProjectLayout.tsx b/src/layouts/page/ProjectLayout.tsx index 0bf3eefc..a23a19d1 100644 --- a/src/layouts/page/ProjectLayout.tsx +++ b/src/layouts/page/ProjectLayout.tsx @@ -4,6 +4,7 @@ import { RiSettings5Fill } from 'react-icons/ri'; import { ProjectContext } from '@hooks/useProjectContext'; import useModal from '@hooks/useModal'; import useReadProjects from '@hooks/query/useProjectQuery'; +import Spinner from '@components/common/Spinner'; import ListSidebar from '@components/sidebar/ListSidebar'; import ListProject from '@components/sidebar/ListProject'; import CreateModalTask from '@components/modal/task/CreateModalTask'; @@ -11,7 +12,7 @@ import CreateModalProjectStatus from '@components/modal/project-status/CreateMod export default function ProjectLayout() { const { teamId, projectId } = useParams(); - const { projectList } = useReadProjects(Number(teamId)); + const { projectList, isProjectLoading } = useReadProjects(Number(teamId)); const { showModal: showTaskModal, openModal: openTaskModal, closeModal: closeTaskModal } = useModal(); const { showModal: showStatusModal, openModal: openStatusModal, closeModal: closeStatusModal } = useModal(); @@ -20,6 +21,8 @@ export default function ProjectLayout() { [projectList, projectId], ); + if (isProjectLoading) return ; + if (!project) return ; return (