From a358a54c267a2531cde80facfba03deeaedc98b6 Mon Sep 17 00:00:00 2001 From: 2yunseong Date: Sun, 23 Feb 2025 22:30:32 +0900 Subject: [PATCH 01/20] =?UTF-8?q?refactor:=20=EC=BF=BC=EB=A6=AC=ED=82=A4?= =?UTF-8?q?=20=EC=A0=95=EA=B7=9C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/components/applicant/Board.tsx | 2 +- frontend/components/applicant/PageNavbar.tsx | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/frontend/components/applicant/Board.tsx b/frontend/components/applicant/Board.tsx index 56fdf87d..3ebc8670 100644 --- a/frontend/components/applicant/Board.tsx +++ b/frontend/components/applicant/Board.tsx @@ -37,7 +37,7 @@ const ApplicantBoard = ({ generation }: ApplicantBoardProps) => { isLoading, isError, } = useQuery( - ["allApplicant", pageIndex, order], + ["allApplicant", { pageIndex, order, generation }], () => getApplicantByPageWithGeneration(+pageIndex, generation, order), { enabled: !!generation, diff --git a/frontend/components/applicant/PageNavbar.tsx b/frontend/components/applicant/PageNavbar.tsx index 7bdebb19..f5f373f3 100644 --- a/frontend/components/applicant/PageNavbar.tsx +++ b/frontend/components/applicant/PageNavbar.tsx @@ -29,7 +29,7 @@ const ApplicantPageNavbar = ({ generation }: ApplicantPageNavbarProps) => { isLoading, isError, } = useQuery( - ["allApplicant", generation], + ["allApplicant", { generation, order, pageIndex }], () => getApplicantByPageWithGeneration(+pageIndex, generation, order), { enabled: !!generation, @@ -45,6 +45,7 @@ const ApplicantPageNavbar = ({ generation }: ApplicantPageNavbarProps) => { } const { maxPage } = allData; + return ( Date: Sun, 23 Feb 2025 22:31:05 +0900 Subject: [PATCH 02/20] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=ED=95=A8=EC=88=98=20=ED=98=B8=EC=B6=9C=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/components/common/Search.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/components/common/Search.tsx b/frontend/components/common/Search.tsx index c2a11917..6d2eb1f1 100644 --- a/frontend/components/common/Search.tsx +++ b/frontend/components/common/Search.tsx @@ -25,7 +25,7 @@ const Search = () => { params.delete("search"); } - replace(`${pathname}?${params.toString()}`); + replace(`${pathname}?${params}`); }); }, [debouncedSearchTerm, pathname]); From 47f7d97409ca6e0b864161bb3552c3f7a560c0c9 Mon Sep 17 00:00:00 2001 From: 2yunseong Date: Sun, 23 Feb 2025 22:31:29 +0900 Subject: [PATCH 03/20] =?UTF-8?q?feat:=20API=20=EC=8A=A4=ED=8E=99=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20=EB=8C=80=EC=9D=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/applicant/index.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/frontend/src/apis/applicant/index.ts b/frontend/src/apis/applicant/index.ts index a5e57f67..dda3ab5b 100644 --- a/frontend/src/apis/applicant/index.ts +++ b/frontend/src/apis/applicant/index.ts @@ -104,12 +104,19 @@ interface ApplicantByPageReq { export const getApplicantByPageWithGeneration = async ( page: number, generation: string, - order: string + order: string, + searchKeyword?: string ): Promise<{ maxPage: number; applicants: ApplicantReq[][] }> => { + const queryParams = new URLSearchParams({ order }); + + if (searchKeyword !== undefined) { + queryParams.append("searchKeyword", searchKeyword); + } + const { data: { pageInfo, answers }, } = await https.get( - `/page/${page}/year/${+generation}/applicants?order=${order}` + `/page/${page}/year/${+generation}/applicants?${queryParams}` ); return { From 60b4b1b7e3aa5df22b73090f4da01d0ca51d91bc Mon Sep 17 00:00:00 2001 From: 2yunseong Date: Sun, 23 Feb 2025 22:56:44 +0900 Subject: [PATCH 04/20] =?UTF-8?q?feat:=20API=20=EC=8A=A4=ED=8E=99=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기존 API에 검색기능 추가 - 따라서, 검색 전용 API가 쓸모 없어짐 --- frontend/components/applicant/Board.tsx | 64 ++++++++++++++++--------- 1 file changed, 41 insertions(+), 23 deletions(-) diff --git a/frontend/components/applicant/Board.tsx b/frontend/components/applicant/Board.tsx index 3ebc8670..f9dbb849 100644 --- a/frontend/components/applicant/Board.tsx +++ b/frontend/components/applicant/Board.tsx @@ -1,6 +1,5 @@ "use client"; -import Board from "@/components/common/board/Board"; import { getApplicantByPageWithGeneration } from "@/src/apis/applicant"; import ApplicantDetailRight from "./DetailRight.component"; import { useState } from "react"; @@ -9,10 +8,12 @@ import { applicantDataFinder } from "@/src/functions/finder"; import { useQuery } from "@tanstack/react-query"; import { useSearchParams } from "next/navigation"; import { ORDER_MENU } from "@/src/constants"; -import { useSearchQuery } from "@/src/hooks/useSearchQuery"; import { type ApplicantPassState } from "../../src/apis/kanban"; import ApplicantDetailLeft from "./_applicant/ApplicantDetailLeft"; import { findApplicantState } from "@/src/utils/applicant"; +import BoardTable from "../common/board/BoardTable"; +import useModalState from "../../src/hooks/useModalState"; +import BoardModal from "../common/board/BoardModal"; interface ApplicantBoardProps { generation: string; @@ -23,7 +24,9 @@ const ApplicantBoard = ({ generation }: ApplicantBoardProps) => { const searchParams = useSearchParams(); const pageIndex = searchParams.get("page") || "1"; const order = searchParams.get("order") || ORDER_MENU.APPLICANT[0].type; - const { createSearchData } = useSearchQuery(pageIndex); + const searchKeyword = searchParams.get("search") || undefined; + + const { isOpen, openModal, closeModal } = useModalState(); const onClick = (id: string) => { if (!allData) return; @@ -32,13 +35,24 @@ const ApplicantBoard = ({ generation }: ApplicantBoardProps) => { ); }; + const handleModalOpen = (id: string) => () => { + openModal(); + onClick && onClick(id); + }; + const { data: allData, isLoading, isError, } = useQuery( - ["allApplicant", { pageIndex, order, generation }], - () => getApplicantByPageWithGeneration(+pageIndex, generation, order), + ["allApplicant", { pageIndex, order, generation, searchKeyword }], + () => + getApplicantByPageWithGeneration( + +pageIndex, + generation, + order, + searchKeyword + ), { enabled: !!generation, } @@ -82,26 +96,30 @@ const ApplicantBoard = ({ generation }: ApplicantBoardProps) => { })); return ( - -
-
- + <> + + +
+
+ +
-
-
-
- +
+
+ +
-
- + + ); }; From 089393758e632d0027ae2cad2ee97463844d80f4 Mon Sep 17 00:00:00 2001 From: 2yunseong Date: Mon, 24 Feb 2025 00:06:23 +0900 Subject: [PATCH 05/20] =?UTF-8?q?feat:=20API=20=EC=8A=A4=ED=8E=99=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=9D=B8?= =?UTF-8?q?=ED=84=B0=EB=B7=B0(=EB=A9=B4=EC=A0=91)=20=EA=B2=80=EC=83=89=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/components/interview/Board.tsx | 49 +++++++++++++++++-------- frontend/src/apis/interview/index.ts | 14 +++++-- 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/frontend/components/interview/Board.tsx b/frontend/components/interview/Board.tsx index a9946935..1b716224 100644 --- a/frontend/components/interview/Board.tsx +++ b/frontend/components/interview/Board.tsx @@ -11,6 +11,9 @@ import { getInterviewRecordByPageWithOrder } from "@/src/apis/interview"; import { CHARACTERS, ORDER_MENU } from "@/src/constants"; import { useSearchQuery } from "@/src/hooks/useSearchQuery"; import { removeAll } from "@/src/functions/replacer"; +import BoardTable from "../common/board/BoardTable"; +import useModalState from "../../src/hooks/useModalState"; +import BoardModal from "../common/board/BoardModal"; interface InterviewBoardProps { generation: string; @@ -19,11 +22,12 @@ interface InterviewBoardProps { const InterviewBoard = ({ generation }: InterviewBoardProps) => { const [applicantId, setApplicantId] = useAtom(interViewApplicantIdState); const searchParams = useSearchParams(); + const searchKeyword = searchParams.get("search") || undefined; const pageIndex = searchParams.get("page") || "1"; const order = searchParams.get("order") || ORDER_MENU.INTERVIEW[0].type; - const { createSearchData } = useSearchQuery(pageIndex); const queryClient = useQueryClient(); + const { isOpen, openModal, closeModal } = useModalState(); const onClick = (id: string) => { setApplicantId(id); @@ -36,12 +40,16 @@ const InterviewBoard = ({ generation }: InterviewBoardProps) => { }; const { data, status } = useQuery({ - queryKey: ["allInterviewRecord", pageIndex, order, generation], + queryKey: [ + "allInterviewRecord", + { pageIndex, order, generation, searchKeyword }, + ], queryFn: () => getInterviewRecordByPageWithOrder({ page: +pageIndex, order: order, year: generation, + searchKeyword, }), }); @@ -71,23 +79,32 @@ const InterviewBoard = ({ generation }: InterviewBoardProps) => { }; }); + const handleModalOpen = (id: string) => () => { + openModal(); + onClick && onClick(id); + }; + return ( - onClick(id)} - > -
-
- + <> + + +
+
+ +
-
-
-
- +
+
+ +
-
- + + ); }; diff --git a/frontend/src/apis/interview/index.ts b/frontend/src/apis/interview/index.ts index 4751c5fe..aaf1b0ff 100644 --- a/frontend/src/apis/interview/index.ts +++ b/frontend/src/apis/interview/index.ts @@ -28,17 +28,23 @@ interface GetInterviewRecordByPageWithOrderReq { page: number; order: string; year: string; + searchKeyword?: string; } export const getInterviewRecordByPageWithOrder = async ({ page, - ...queryParams + order, + year, + searchKeyword, }: GetInterviewRecordByPageWithOrderReq) => { + const queryParams = new URLSearchParams({ order, year }); + if (searchKeyword !== undefined) { + queryParams.append("searchKeyword", searchKeyword); + } + const { data: { records, pageInfo }, - } = await https.get( - `/page/${page}/records?${new URLSearchParams(queryParams)}` - ); + } = await https.get(`/page/${page}/records?${queryParams}`); return { maxPage: pageInfo.endPage, From 8487785fc83bcfc2b3d0cdcb7d53b16dbb2c6dfd Mon Sep 17 00:00:00 2001 From: 2yunseong Date: Mon, 24 Feb 2025 00:13:08 +0900 Subject: [PATCH 06/20] =?UTF-8?q?fix:=20=EC=9E=98=EB=AA=BB=EB=90=9C=20?= =?UTF-8?q?=EC=BF=BC=EB=A6=AC=EC=9A=94=EC=B2=AD=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/components/interview/PageNavbar.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/frontend/components/interview/PageNavbar.tsx b/frontend/components/interview/PageNavbar.tsx index 5228fcfe..8a889f8c 100644 --- a/frontend/components/interview/PageNavbar.tsx +++ b/frontend/components/interview/PageNavbar.tsx @@ -17,11 +17,12 @@ const InterviewPageNavbar = ({ generation }: InterviewPageNavbarProps) => { const type = searchParams.get("type") ?? "list"; const order = searchParams.get("order") ?? ORDER_MENU.INTERVIEW[0].type; const page = searchParams.get("page") ?? "1"; - const search = searchParams.get("search") || ""; + const search = searchParams.get("search") || undefined; const { searchEndPage } = useSearchQuery(pageIndex); - const queryParams = { search, type, order }; + const queryParams = { type, order, search: search || "" }; + const { createQueryString } = useCreateQueryString(); const { @@ -29,12 +30,13 @@ const InterviewPageNavbar = ({ generation }: InterviewPageNavbarProps) => { isLoading, isError, } = useQuery( - ["allApplicant", order, generation], + ["allInterViewRecord", { generation, order, pageIndex, search }], () => getInterviewRecordByPageWithOrder({ page: +pageIndex, order: order, year: generation, + searchKeyword: search, }), { enabled: !!generation, From 8c606bf98a3bfd706295a3ec54af61ba2ca85a08 Mon Sep 17 00:00:00 2001 From: 2yunseong Date: Mon, 24 Feb 2025 00:17:26 +0900 Subject: [PATCH 07/20] =?UTF-8?q?feat:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20hook=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/components/applicant/PageNavbar.tsx | 11 ++--- frontend/components/interview/Board.tsx | 2 - frontend/components/interview/PageNavbar.tsx | 6 +-- frontend/src/apis/search/index.ts | 36 -------------- frontend/src/hooks/useSearchQuery.tsx | 52 -------------------- 5 files changed, 6 insertions(+), 101 deletions(-) delete mode 100644 frontend/src/apis/search/index.ts delete mode 100644 frontend/src/hooks/useSearchQuery.tsx diff --git a/frontend/components/applicant/PageNavbar.tsx b/frontend/components/applicant/PageNavbar.tsx index f5f373f3..9de98534 100644 --- a/frontend/components/applicant/PageNavbar.tsx +++ b/frontend/components/applicant/PageNavbar.tsx @@ -4,7 +4,6 @@ import PageNavbarComponent from "../common/PageNavbar.component"; import { useSearchParams } from "next/navigation"; import { getApplicantByPageWithGeneration } from "@/src/apis/applicant"; import { ORDER_MENU } from "@/src/constants"; -import { useSearchQuery } from "@/src/hooks/useSearchQuery"; import { useCreateQueryString } from "@/src/hooks/useCreateQueryString"; type ApplicantPageNavbarProps = { @@ -18,9 +17,6 @@ const ApplicantPageNavbar = ({ generation }: ApplicantPageNavbarProps) => { const order = searchParams.get("order") ?? ORDER_MENU.APPLICANT[0].type; const page = searchParams.get("page") ?? "1"; const search = searchParams.get("search") || ""; - - const { searchEndPage } = useSearchQuery(pageIndex); - const queryParams = { search, type, order }; const { createQueryString } = useCreateQueryString(); @@ -29,8 +25,9 @@ const ApplicantPageNavbar = ({ generation }: ApplicantPageNavbarProps) => { isLoading, isError, } = useQuery( - ["allApplicant", { generation, order, pageIndex }], - () => getApplicantByPageWithGeneration(+pageIndex, generation, order), + ["allApplicant", { generation, order, pageIndex, search }], + () => + getApplicantByPageWithGeneration(+pageIndex, generation, order, search), { enabled: !!generation, } @@ -48,7 +45,7 @@ const ApplicantPageNavbar = ({ generation }: ApplicantPageNavbarProps) => { return ( { const page = searchParams.get("page") ?? "1"; const search = searchParams.get("search") || undefined; - const { searchEndPage } = useSearchQuery(pageIndex); - const queryParams = { type, order, search: search || "" }; const { createQueryString } = useCreateQueryString(); @@ -52,9 +49,10 @@ const InterviewPageNavbar = ({ generation }: InterviewPageNavbarProps) => { } const { maxPage } = allData; + return ( { - const { - data: { answers, pageInfo }, - } = await https.get( - `/page/${page}/search/${searchTerm}/applicants` - ); - - return { - answers, - endPage: pageInfo.endPage, - }; -}; diff --git a/frontend/src/hooks/useSearchQuery.tsx b/frontend/src/hooks/useSearchQuery.tsx deleted file mode 100644 index cf1c6f98..00000000 --- a/frontend/src/hooks/useSearchQuery.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import { useQuery } from "@tanstack/react-query"; -import { useSearchParams } from "next/navigation"; -import { getSearchTerm } from "@/src/apis/search"; -import { removeAll } from "../functions/replacer"; -import { CHARACTERS } from "@/src/constants"; - -const { DOUBLE_QUOTE, SLASH, SPACE } = CHARACTERS; - -export const useSearchQuery = (pageIndex: string) => { - const searchParams = useSearchParams(); - const searchTerm = searchParams.get("search") || ""; - - const { data: search } = useQuery({ - queryKey: ["searchTerm", pageIndex, searchTerm], - queryFn: () => getSearchTerm({ page: +pageIndex, searchTerm }), - enabled: !!searchTerm, - }); - - const searchEndPage = search?.endPage; - - // TODO: Search는 대대적인 개편이 들어갈 예정이라, 따로 passState에 대한 처리를 하지 않음. - const createSearchData = (isIncludeUploadDate = false) => { - return search?.answers?.map((value) => { - const searchInterviewData = { - id: value.id, - title: `[${value.field}] ${value.name}`, - subElements: [ - removeAll(value.field1, DOUBLE_QUOTE).concat( - SLASH, - removeAll(value.field2, DOUBLE_QUOTE) - ), - removeAll(value.grade, DOUBLE_QUOTE).concat( - SPACE, - removeAll(value.semester, DOUBLE_QUOTE) - ), - ], - }; - - if (isIncludeUploadDate) { - searchInterviewData.subElements.push( - new Date(Number(value.uploadDate)).toLocaleString("ko-KR", { - dateStyle: "short", - }) - ); - } - - return searchInterviewData; - }); - }; - - return { createSearchData, searchEndPage }; -}; From 690e82a1762e13e1f38bffc8ecd4e1bbda562488 Mon Sep 17 00:00:00 2001 From: 2yunseong Date: Mon, 24 Feb 2025 00:44:44 +0900 Subject: [PATCH 08/20] =?UTF-8?q?refactor:=20=EB=B3=80=EC=88=98=EB=AA=85?= =?UTF-8?q?=20=EB=A6=AC=ED=8C=A9=ED=84=B0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/components/applicant/Board.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/frontend/components/applicant/Board.tsx b/frontend/components/applicant/Board.tsx index f9dbb849..01f09860 100644 --- a/frontend/components/applicant/Board.tsx +++ b/frontend/components/applicant/Board.tsx @@ -20,7 +20,9 @@ interface ApplicantBoardProps { } const ApplicantBoard = ({ generation }: ApplicantBoardProps) => { - const [data, setData] = useState([]); + const [selectedApplicant, setSelectedApplicant] = useState( + [] + ); const searchParams = useSearchParams(); const pageIndex = searchParams.get("page") || "1"; const order = searchParams.get("order") || ORDER_MENU.APPLICANT[0].type; @@ -30,7 +32,7 @@ const ApplicantBoard = ({ generation }: ApplicantBoardProps) => { const onClick = (id: string) => { if (!allData) return; - setData( + setSelectedApplicant( applicants?.filter((value) => applicantDataFinder(value, "id") === id)[0] ); }; @@ -108,14 +110,14 @@ const ApplicantBoard = ({ generation }: ApplicantBoardProps) => {
- +
From 69086903a927101bfad7e882312d05a4e2fb5061 Mon Sep 17 00:00:00 2001 From: 2yunseong Date: Mon, 24 Feb 2025 00:57:40 +0900 Subject: [PATCH 09/20] =?UTF-8?q?feat:=20=EB=A1=9C=EB=94=A9=20=EC=8A=A4?= =?UTF-8?q?=ED=94=BC=EB=84=88=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/components/applicant/Board.tsx | 33 ++++++---- frontend/components/common/LoadingSpinner.tsx | 66 +++++++++++++++++++ 2 files changed, 85 insertions(+), 14 deletions(-) create mode 100644 frontend/components/common/LoadingSpinner.tsx diff --git a/frontend/components/applicant/Board.tsx b/frontend/components/applicant/Board.tsx index 01f09860..a2dbd082 100644 --- a/frontend/components/applicant/Board.tsx +++ b/frontend/components/applicant/Board.tsx @@ -14,6 +14,7 @@ import { findApplicantState } from "@/src/utils/applicant"; import BoardTable from "../common/board/BoardTable"; import useModalState from "../../src/hooks/useModalState"; import BoardModal from "../common/board/BoardModal"; +import LoadingSpinner from "../common/LoadingSpinner"; interface ApplicantBoardProps { generation: string; @@ -30,18 +31,6 @@ const ApplicantBoard = ({ generation }: ApplicantBoardProps) => { const { isOpen, openModal, closeModal } = useModalState(); - const onClick = (id: string) => { - if (!allData) return; - setSelectedApplicant( - applicants?.filter((value) => applicantDataFinder(value, "id") === id)[0] - ); - }; - - const handleModalOpen = (id: string) => () => { - openModal(); - onClick && onClick(id); - }; - const { data: allData, isLoading, @@ -61,11 +50,15 @@ const ApplicantBoard = ({ generation }: ApplicantBoardProps) => { ); if (!allData || isLoading) { - return
로딩중...
; + return ( +
+ +
+ ); } if (isError) { - return
에러 발생
; + return
에러 발생
; } const { applicants } = allData; @@ -97,6 +90,18 @@ const ApplicantBoard = ({ generation }: ApplicantBoardProps) => { )}` as ApplicantPassState, })); + const onClick = (id: string) => { + if (!allData) return; + setSelectedApplicant( + applicants?.filter((value) => applicantDataFinder(value, "id") === id)[0] + ); + }; + + const handleModalOpen = (id: string) => () => { + openModal(); + onClick && onClick(id); + }; + return ( <> diff --git a/frontend/components/common/LoadingSpinner.tsx b/frontend/components/common/LoadingSpinner.tsx new file mode 100644 index 00000000..c9912697 --- /dev/null +++ b/frontend/components/common/LoadingSpinner.tsx @@ -0,0 +1,66 @@ +type TailwindSize = + | 0 + | 0.5 + | 1 + | 1.5 + | 2 + | 2.5 + | 3 + | 3.5 + | 4 + | 5 + | 6 + | 7 + | 8 + | 9 + | 10 + | 11 + | 12 + | 14 + | 16 + | 20 + | 24 + | 28 + | 32 + | 36 + | 40 + | 44 + | 48 + | 52 + | 56 + | 60 + | 64 + | 72 + | 80 + | 96; + +interface LoadingSpinnerProps { + size?: TailwindSize; +} +const LoadingSpinner = ({ size = 6 }: LoadingSpinnerProps) => { + return ( +
+ + + + +
+ ); +}; + +export default LoadingSpinner; From bb4936ecb0a18d37684d0059c3114c8674e12a9a Mon Sep 17 00:00:00 2001 From: 2yunseong Date: Mon, 24 Feb 2025 01:34:17 +0900 Subject: [PATCH 10/20] =?UTF-8?q?refactor:=20=EA=B3=B5=ED=86=B5=EB=90=9C?= =?UTF-8?q?=20parameter=20=EC=B6=94=EC=B6=9C=20=EB=A1=9C=EC=A7=81=20hook?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/components/applicant/Board.tsx | 11 +++----- frontend/components/applicant/PageNavbar.tsx | 27 ++++++++++--------- frontend/components/interview/Board.tsx | 9 +++---- frontend/components/interview/PageNavbar.tsx | 19 +++++-------- frontend/src/apis/applicant/index.ts | 2 +- frontend/src/apis/interview/index.ts | 2 +- .../applicant/useApplicantPaginationParams.ts | 14 ++++++++++ .../useInterviewerPaginationParams.ts | 14 ++++++++++ 8 files changed, 58 insertions(+), 40 deletions(-) create mode 100644 frontend/src/hooks/applicant/useApplicantPaginationParams.ts create mode 100644 frontend/src/hooks/interview/useInterviewerPaginationParams.ts diff --git a/frontend/components/applicant/Board.tsx b/frontend/components/applicant/Board.tsx index a2dbd082..ff60f4dd 100644 --- a/frontend/components/applicant/Board.tsx +++ b/frontend/components/applicant/Board.tsx @@ -6,15 +6,13 @@ import { useState } from "react"; import { ApplicantReq } from "@/src/apis/application"; import { applicantDataFinder } from "@/src/functions/finder"; import { useQuery } from "@tanstack/react-query"; -import { useSearchParams } from "next/navigation"; -import { ORDER_MENU } from "@/src/constants"; import { type ApplicantPassState } from "../../src/apis/kanban"; import ApplicantDetailLeft from "./_applicant/ApplicantDetailLeft"; -import { findApplicantState } from "@/src/utils/applicant"; import BoardTable from "../common/board/BoardTable"; import useModalState from "../../src/hooks/useModalState"; import BoardModal from "../common/board/BoardModal"; import LoadingSpinner from "../common/LoadingSpinner"; +import useApplicantPaginationParams from "../../src/hooks/applicant/useApplicantPaginationParams"; interface ApplicantBoardProps { generation: string; @@ -24,10 +22,7 @@ const ApplicantBoard = ({ generation }: ApplicantBoardProps) => { const [selectedApplicant, setSelectedApplicant] = useState( [] ); - const searchParams = useSearchParams(); - const pageIndex = searchParams.get("page") || "1"; - const order = searchParams.get("order") || ORDER_MENU.APPLICANT[0].type; - const searchKeyword = searchParams.get("search") || undefined; + const { pageIndex, order, searchKeyword } = useApplicantPaginationParams(); const { isOpen, openModal, closeModal } = useModalState(); @@ -93,7 +88,7 @@ const ApplicantBoard = ({ generation }: ApplicantBoardProps) => { const onClick = (id: string) => { if (!allData) return; setSelectedApplicant( - applicants?.filter((value) => applicantDataFinder(value, "id") === id)[0] + applicants.filter((value) => applicantDataFinder(value, "id") === id)[0] ); }; diff --git a/frontend/components/applicant/PageNavbar.tsx b/frontend/components/applicant/PageNavbar.tsx index 9de98534..c4a5c122 100644 --- a/frontend/components/applicant/PageNavbar.tsx +++ b/frontend/components/applicant/PageNavbar.tsx @@ -1,23 +1,20 @@ "use client"; import { useQuery } from "@tanstack/react-query"; import PageNavbarComponent from "../common/PageNavbar.component"; -import { useSearchParams } from "next/navigation"; import { getApplicantByPageWithGeneration } from "@/src/apis/applicant"; -import { ORDER_MENU } from "@/src/constants"; import { useCreateQueryString } from "@/src/hooks/useCreateQueryString"; +import useApplicantPaginationParams from "../../src/hooks/applicant/useApplicantPaginationParams"; type ApplicantPageNavbarProps = { generation: string; }; const ApplicantPageNavbar = ({ generation }: ApplicantPageNavbarProps) => { - const searchParams = useSearchParams(); - const pageIndex = searchParams.get("page") || "1"; - const type = searchParams.get("type") ?? "list"; - const order = searchParams.get("order") ?? ORDER_MENU.APPLICANT[0].type; - const page = searchParams.get("page") ?? "1"; - const search = searchParams.get("search") || ""; - const queryParams = { search, type, order }; + const { pageIndex, type, order, searchKeyword } = + useApplicantPaginationParams(); + + const queryParams = { search: searchKeyword, type, order }; + const { createQueryString } = useCreateQueryString(); const { @@ -25,9 +22,14 @@ const ApplicantPageNavbar = ({ generation }: ApplicantPageNavbarProps) => { isLoading, isError, } = useQuery( - ["allApplicant", { generation, order, pageIndex, search }], + ["allApplicant", { generation, order, pageIndex, search: searchKeyword }], () => - getApplicantByPageWithGeneration(+pageIndex, generation, order, search), + getApplicantByPageWithGeneration( + +pageIndex, + generation, + order, + searchKeyword + ), { enabled: !!generation, } @@ -43,10 +45,11 @@ const ApplicantPageNavbar = ({ generation }: ApplicantPageNavbarProps) => { const { maxPage } = allData; + // Search 넣어야 함!!! return ( { const [applicantId, setApplicantId] = useAtom(interViewApplicantIdState); - const searchParams = useSearchParams(); - const searchKeyword = searchParams.get("search") || undefined; - const pageIndex = searchParams.get("page") || "1"; - const order = searchParams.get("order") || ORDER_MENU.INTERVIEW[0].type; + const { pageIndex, order, searchKeyword } = useInterviewerPaginationParams(); const queryClient = useQueryClient(); const { isOpen, openModal, closeModal } = useModalState(); diff --git a/frontend/components/interview/PageNavbar.tsx b/frontend/components/interview/PageNavbar.tsx index 4f5b7804..a0f247ad 100644 --- a/frontend/components/interview/PageNavbar.tsx +++ b/frontend/components/interview/PageNavbar.tsx @@ -1,24 +1,19 @@ "use client"; import { useQuery } from "@tanstack/react-query"; import PageNavbarComponent from "../common/PageNavbar.component"; -import { useSearchParams } from "next/navigation"; import { getInterviewRecordByPageWithOrder } from "@/src/apis/interview"; -import { ORDER_MENU } from "@/src/constants"; import { useCreateQueryString } from "@/src/hooks/useCreateQueryString"; +import useInterviewerPaginationParams from "../../src/hooks/interview/useInterviewerPaginationParams"; type InterviewPageNavbarProps = { generation: string; }; const InterviewPageNavbar = ({ generation }: InterviewPageNavbarProps) => { - const searchParams = useSearchParams(); - const pageIndex = searchParams.get("page") || "1"; - const type = searchParams.get("type") ?? "list"; - const order = searchParams.get("order") ?? ORDER_MENU.INTERVIEW[0].type; - const page = searchParams.get("page") ?? "1"; - const search = searchParams.get("search") || undefined; + const { pageIndex, type, order, searchKeyword } = + useInterviewerPaginationParams(); - const queryParams = { type, order, search: search || "" }; + const queryParams = { type, order, search: searchKeyword }; const { createQueryString } = useCreateQueryString(); @@ -27,13 +22,13 @@ const InterviewPageNavbar = ({ generation }: InterviewPageNavbarProps) => { isLoading, isError, } = useQuery( - ["allInterViewRecord", { generation, order, pageIndex, search }], + ["allInterviewRecord", { generation, order, pageIndex, searchKeyword }], () => getInterviewRecordByPageWithOrder({ page: +pageIndex, order: order, year: generation, - searchKeyword: search, + searchKeyword, }), { enabled: !!generation, @@ -53,7 +48,7 @@ const InterviewPageNavbar = ({ generation }: InterviewPageNavbarProps) => { return ( => { const queryParams = new URLSearchParams({ order }); - if (searchKeyword !== undefined) { + if (searchKeyword !== undefined && searchKeyword.trim() !== "") { queryParams.append("searchKeyword", searchKeyword); } diff --git a/frontend/src/apis/interview/index.ts b/frontend/src/apis/interview/index.ts index aaf1b0ff..238b11e3 100644 --- a/frontend/src/apis/interview/index.ts +++ b/frontend/src/apis/interview/index.ts @@ -38,7 +38,7 @@ export const getInterviewRecordByPageWithOrder = async ({ searchKeyword, }: GetInterviewRecordByPageWithOrderReq) => { const queryParams = new URLSearchParams({ order, year }); - if (searchKeyword !== undefined) { + if (searchKeyword !== undefined && searchKeyword.trim() !== "") { queryParams.append("searchKeyword", searchKeyword); } diff --git a/frontend/src/hooks/applicant/useApplicantPaginationParams.ts b/frontend/src/hooks/applicant/useApplicantPaginationParams.ts new file mode 100644 index 00000000..805330d0 --- /dev/null +++ b/frontend/src/hooks/applicant/useApplicantPaginationParams.ts @@ -0,0 +1,14 @@ +import { useSearchParams } from "next/navigation"; +import { ORDER_MENU } from "../../constants"; + +const useApplicantPaginationParams = () => { + const searchParams = useSearchParams(); + const pageIndex = searchParams.get("page") || "1"; + const order = searchParams.get("order") || ORDER_MENU.APPLICANT[0].type; + const searchKeyword = searchParams.get("search") || ""; + const type = searchParams.get("type") ?? "list"; + + return { pageIndex, order, searchKeyword, type }; +}; + +export default useApplicantPaginationParams; diff --git a/frontend/src/hooks/interview/useInterviewerPaginationParams.ts b/frontend/src/hooks/interview/useInterviewerPaginationParams.ts new file mode 100644 index 00000000..9568e5cb --- /dev/null +++ b/frontend/src/hooks/interview/useInterviewerPaginationParams.ts @@ -0,0 +1,14 @@ +import { useSearchParams } from "next/navigation"; +import { ORDER_MENU } from "../../constants"; + +const useInterviewerPaginationParams = () => { + const searchParams = useSearchParams(); + const pageIndex = searchParams.get("page") || "1"; + const order = searchParams.get("order") || ORDER_MENU.INTERVIEW[0].type; + const searchKeyword = searchParams.get("search") || ""; + const type = searchParams.get("type") ?? "list"; + + return { pageIndex, order, searchKeyword, type }; +}; + +export default useInterviewerPaginationParams; From 3cc4da1850aa52eb47be410a657157d91723037f Mon Sep 17 00:00:00 2001 From: 2yunseong Date: Mon, 24 Feb 2025 01:44:57 +0900 Subject: [PATCH 11/20] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EC=B6=94=EC=83=81=ED=99=94=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../interview/[generation]/page.tsx | 6 +- frontend/components/interview/Board.tsx | 62 ++++------------ .../components/interview/InterviewerList.tsx | 74 +++++++++++++++++++ frontend/components/interview/PageNavbar.tsx | 36 ++------- 4 files changed, 94 insertions(+), 84 deletions(-) create mode 100644 frontend/components/interview/InterviewerList.tsx diff --git a/frontend/app/(WithNavbar)/interview/[generation]/page.tsx b/frontend/app/(WithNavbar)/interview/[generation]/page.tsx index 3d04b063..72e4baf6 100644 --- a/frontend/app/(WithNavbar)/interview/[generation]/page.tsx +++ b/frontend/app/(WithNavbar)/interview/[generation]/page.tsx @@ -1,8 +1,7 @@ import SortList from "@/components/common/SortList"; -import InterviewBoard from "@/components/interview/Board"; -import InterviewPageNavbar from "@/components/interview/PageNavbar"; import Search from "@/components/common/Search"; import { ORDER_MENU } from "@/src/constants"; +import InterviewerList from "../../../../components/interview/InterviewerList"; interface InterviewPageProps { params: { @@ -17,8 +16,7 @@ const InterviewPage = ({ params: { generation } }: InterviewPageProps) => {
- - +
); }; diff --git a/frontend/components/interview/Board.tsx b/frontend/components/interview/Board.tsx index 9096495a..3ee50cc5 100644 --- a/frontend/components/interview/Board.tsx +++ b/frontend/components/interview/Board.tsx @@ -2,24 +2,25 @@ import InterviewDetailLeftComponent from "./modal/DetailLeft.component"; import InterviewDetailRightComponent from "./modal/DetailRight.component"; -import { useQuery, useQueryClient } from "@tanstack/react-query"; +import { useQueryClient } from "@tanstack/react-query"; import { useAtom } from "jotai"; import { interViewApplicantIdState } from "@/src/stores/interview/Interview.atom"; -import { getInterviewRecordByPageWithOrder } from "@/src/apis/interview"; -import { CHARACTERS } from "@/src/constants"; -import { removeAll } from "@/src/functions/replacer"; import BoardTable from "../common/board/BoardTable"; import useModalState from "../../src/hooks/useModalState"; import BoardModal from "../common/board/BoardModal"; -import useInterviewerPaginationParams from "../../src/hooks/interview/useInterviewerPaginationParams"; +import { ApplicantPassState } from "../../src/apis/kanban"; interface InterviewBoardProps { - generation: string; + interviewRecords: { + id: string; + title: string; + subElements: string[]; + passState: ApplicantPassState; + }[]; } -const InterviewBoard = ({ generation }: InterviewBoardProps) => { +const InterviewBoard = ({ interviewRecords }: InterviewBoardProps) => { const [applicantId, setApplicantId] = useAtom(interViewApplicantIdState); - const { pageIndex, order, searchKeyword } = useInterviewerPaginationParams(); const queryClient = useQueryClient(); const { isOpen, openModal, closeModal } = useModalState(); @@ -34,46 +35,6 @@ const InterviewBoard = ({ generation }: InterviewBoardProps) => { }); }; - const { data, status } = useQuery({ - queryKey: [ - "allInterviewRecord", - { pageIndex, order, generation, searchKeyword }, - ], - queryFn: () => - getInterviewRecordByPageWithOrder({ - page: +pageIndex, - order: order, - year: generation, - searchKeyword, - }), - }); - - if (status === "loading") { - return
loading...
; - } - - if (status === "error") { - return
에러가 발생하였습니다. 잠시 후 다시 시도해보세요.
; - } - - const boardData = data.records.map((value) => { - return { - id: value.applicantId, - title: value.name, - subElements: [ - removeAll(value.field1, CHARACTERS.DOUBLE_QUOTE).concat( - CHARACTERS.SLASH, - removeAll(value.field2, CHARACTERS.DOUBLE_QUOTE) - ), - removeAll(value.grade, CHARACTERS.DOUBLE_QUOTE).concat( - CHARACTERS.SPACE, - removeAll(value.semester, CHARACTERS.DOUBLE_QUOTE) - ), - ], - passState: value.state.passState, - }; - }); - const handleModalOpen = (id: string) => () => { openModal(); onClick && onClick(id); @@ -81,7 +42,10 @@ const InterviewBoard = ({ generation }: InterviewBoardProps) => { return ( <> - + { + const { pageIndex, order, searchKeyword } = useInterviewerPaginationParams(); + + const { data: interview, status } = useQuery({ + queryKey: [ + "allInterviewRecord", + { pageIndex, order, generation, searchKeyword }, + ], + queryFn: () => + getInterviewRecordByPageWithOrder({ + page: +pageIndex, + order: order, + year: generation, + searchKeyword, + }), + }); + + if (status === "loading") { + return ( +
+ +
+ ); + } + + if (status === "error") { + return
에러가 발생하였습니다. 잠시 후 다시 시도해보세요.
; + } + + const interviewRecords = interview.records.map((value) => { + return { + id: value.applicantId, + title: value.name, + subElements: [ + removeAll(value.field1, CHARACTERS.DOUBLE_QUOTE).concat( + CHARACTERS.SLASH, + removeAll(value.field2, CHARACTERS.DOUBLE_QUOTE) + ), + removeAll(value.grade, CHARACTERS.DOUBLE_QUOTE).concat( + CHARACTERS.SPACE, + removeAll(value.semester, CHARACTERS.DOUBLE_QUOTE) + ), + ], + passState: value.state.passState, + }; + }); + + return ( + <> + + + + ); +}; + +export default InterviewerList; diff --git a/frontend/components/interview/PageNavbar.tsx b/frontend/components/interview/PageNavbar.tsx index a0f247ad..77821464 100644 --- a/frontend/components/interview/PageNavbar.tsx +++ b/frontend/components/interview/PageNavbar.tsx @@ -1,15 +1,17 @@ "use client"; -import { useQuery } from "@tanstack/react-query"; import PageNavbarComponent from "../common/PageNavbar.component"; -import { getInterviewRecordByPageWithOrder } from "@/src/apis/interview"; import { useCreateQueryString } from "@/src/hooks/useCreateQueryString"; import useInterviewerPaginationParams from "../../src/hooks/interview/useInterviewerPaginationParams"; type InterviewPageNavbarProps = { + maxPage: number; generation: string; }; -const InterviewPageNavbar = ({ generation }: InterviewPageNavbarProps) => { +const InterviewPageNavbar = ({ + maxPage, + generation, +}: InterviewPageNavbarProps) => { const { pageIndex, type, order, searchKeyword } = useInterviewerPaginationParams(); @@ -17,34 +19,6 @@ const InterviewPageNavbar = ({ generation }: InterviewPageNavbarProps) => { const { createQueryString } = useCreateQueryString(); - const { - data: allData, - isLoading, - isError, - } = useQuery( - ["allInterviewRecord", { generation, order, pageIndex, searchKeyword }], - () => - getInterviewRecordByPageWithOrder({ - page: +pageIndex, - order: order, - year: generation, - searchKeyword, - }), - { - enabled: !!generation, - } - ); - - if (!allData || isLoading) { - return
로딩중...
; - } - - if (isError) { - return
에러 발생
; - } - - const { maxPage } = allData; - return ( Date: Mon, 24 Feb 2025 01:58:28 +0900 Subject: [PATCH 12/20] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EC=B6=94=EC=83=81=ED=99=94=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../applicant/[generation]/page.tsx | 6 +- .../components/applicant/ApplicantList.tsx | 55 +++++++++++++++++++ frontend/components/applicant/Board.tsx | 41 +------------- frontend/components/applicant/PageNavbar.tsx | 36 ++---------- 4 files changed, 64 insertions(+), 74 deletions(-) create mode 100644 frontend/components/applicant/ApplicantList.tsx diff --git a/frontend/app/(WithNavbar)/applicant/[generation]/page.tsx b/frontend/app/(WithNavbar)/applicant/[generation]/page.tsx index 0a2964a4..dce8f435 100644 --- a/frontend/app/(WithNavbar)/applicant/[generation]/page.tsx +++ b/frontend/app/(WithNavbar)/applicant/[generation]/page.tsx @@ -1,8 +1,7 @@ -import ApplicantBoard from "@/components/applicant/Board"; -import ApplicantPageNavbar from "@/components/applicant/PageNavbar"; import SortList from "@/components/common/SortList"; import Search from "@/components/common/Search"; import { ORDER_MENU } from "@/src/constants"; +import ApplicantList from "../../../../components/applicant/ApplicantList"; interface ApplicantPageProps { params: { @@ -19,8 +18,7 @@ const ApplicantPage = ({ params }: ApplicantPageProps) => {
- - + ); }; diff --git a/frontend/components/applicant/ApplicantList.tsx b/frontend/components/applicant/ApplicantList.tsx new file mode 100644 index 00000000..e473aeec --- /dev/null +++ b/frontend/components/applicant/ApplicantList.tsx @@ -0,0 +1,55 @@ +"use client"; + +import { useQuery } from "@tanstack/react-query"; +import useApplicantPaginationParams from "../../src/hooks/applicant/useApplicantPaginationParams"; +import { getApplicantByPageWithGeneration } from "../../src/apis/applicant"; +import LoadingSpinner from "../common/LoadingSpinner"; +import ApplicantBoard from "./Board"; +import ApplicantPageNavbar from "./PageNavbar"; + +interface ApplicantListProps { + generation: string; +} + +const ApplicantList = ({ generation }: ApplicantListProps) => { + const { pageIndex, order, searchKeyword } = useApplicantPaginationParams(); + const { data: applicants, status } = useQuery( + ["allApplicant", { generation, order, pageIndex, searchKeyword }], + () => + getApplicantByPageWithGeneration( + +pageIndex, + generation, + order, + searchKeyword + ), + { + enabled: !!generation, + } + ); + + if (status === "loading") { + return ( +
+ +
+ ); + } + if (status === "error") { + return
에러 발생
; + } + + return ( + <> + + + + ); +}; + +export default ApplicantList; diff --git a/frontend/components/applicant/Board.tsx b/frontend/components/applicant/Board.tsx index ff60f4dd..b26e82d8 100644 --- a/frontend/components/applicant/Board.tsx +++ b/frontend/components/applicant/Board.tsx @@ -1,63 +1,27 @@ "use client"; -import { getApplicantByPageWithGeneration } from "@/src/apis/applicant"; import ApplicantDetailRight from "./DetailRight.component"; import { useState } from "react"; import { ApplicantReq } from "@/src/apis/application"; import { applicantDataFinder } from "@/src/functions/finder"; -import { useQuery } from "@tanstack/react-query"; import { type ApplicantPassState } from "../../src/apis/kanban"; import ApplicantDetailLeft from "./_applicant/ApplicantDetailLeft"; import BoardTable from "../common/board/BoardTable"; import useModalState from "../../src/hooks/useModalState"; import BoardModal from "../common/board/BoardModal"; -import LoadingSpinner from "../common/LoadingSpinner"; -import useApplicantPaginationParams from "../../src/hooks/applicant/useApplicantPaginationParams"; interface ApplicantBoardProps { generation: string; + applicants: ApplicantReq[][]; } -const ApplicantBoard = ({ generation }: ApplicantBoardProps) => { +const ApplicantBoard = ({ generation, applicants }: ApplicantBoardProps) => { const [selectedApplicant, setSelectedApplicant] = useState( [] ); - const { pageIndex, order, searchKeyword } = useApplicantPaginationParams(); const { isOpen, openModal, closeModal } = useModalState(); - const { - data: allData, - isLoading, - isError, - } = useQuery( - ["allApplicant", { pageIndex, order, generation, searchKeyword }], - () => - getApplicantByPageWithGeneration( - +pageIndex, - generation, - order, - searchKeyword - ), - { - enabled: !!generation, - } - ); - - if (!allData || isLoading) { - return ( -
- -
- ); - } - - if (isError) { - return
에러 발생
; - } - - const { applicants } = allData; - const boardData = applicants.map((value) => ({ id: applicantDataFinder(value, "id"), title: `[${applicantDataFinder(value, "field")}] ${applicantDataFinder( @@ -86,7 +50,6 @@ const ApplicantBoard = ({ generation }: ApplicantBoardProps) => { })); const onClick = (id: string) => { - if (!allData) return; setSelectedApplicant( applicants.filter((value) => applicantDataFinder(value, "id") === id)[0] ); diff --git a/frontend/components/applicant/PageNavbar.tsx b/frontend/components/applicant/PageNavbar.tsx index c4a5c122..19e5fe9f 100644 --- a/frontend/components/applicant/PageNavbar.tsx +++ b/frontend/components/applicant/PageNavbar.tsx @@ -1,15 +1,17 @@ "use client"; -import { useQuery } from "@tanstack/react-query"; import PageNavbarComponent from "../common/PageNavbar.component"; -import { getApplicantByPageWithGeneration } from "@/src/apis/applicant"; import { useCreateQueryString } from "@/src/hooks/useCreateQueryString"; import useApplicantPaginationParams from "../../src/hooks/applicant/useApplicantPaginationParams"; type ApplicantPageNavbarProps = { generation: string; + maxPage: number; }; -const ApplicantPageNavbar = ({ generation }: ApplicantPageNavbarProps) => { +const ApplicantPageNavbar = ({ + generation, + maxPage, +}: ApplicantPageNavbarProps) => { const { pageIndex, type, order, searchKeyword } = useApplicantPaginationParams(); @@ -17,34 +19,6 @@ const ApplicantPageNavbar = ({ generation }: ApplicantPageNavbarProps) => { const { createQueryString } = useCreateQueryString(); - const { - data: allData, - isLoading, - isError, - } = useQuery( - ["allApplicant", { generation, order, pageIndex, search: searchKeyword }], - () => - getApplicantByPageWithGeneration( - +pageIndex, - generation, - order, - searchKeyword - ), - { - enabled: !!generation, - } - ); - - if (!allData || isLoading) { - return
로딩중...
; - } - - if (isError) { - return
에러 발생
; - } - - const { maxPage } = allData; - // Search 넣어야 함!!! return ( Date: Mon, 24 Feb 2025 01:59:29 +0900 Subject: [PATCH 13/20] =?UTF-8?q?fix:=20=EB=A6=AC=ED=8C=A9=ED=84=B0?= =?UTF-8?q?=EB=A7=81=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=ED=95=A8=EC=88=98=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/components/applicant/Board.tsx | 8 ++------ frontend/components/interview/Board.tsx | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/frontend/components/applicant/Board.tsx b/frontend/components/applicant/Board.tsx index b26e82d8..2f6d8e2a 100644 --- a/frontend/components/applicant/Board.tsx +++ b/frontend/components/applicant/Board.tsx @@ -49,17 +49,13 @@ const ApplicantBoard = ({ generation, applicants }: ApplicantBoardProps) => { )}` as ApplicantPassState, })); - const onClick = (id: string) => { + const handleModalOpen = (id: string) => () => { + openModal(); setSelectedApplicant( applicants.filter((value) => applicantDataFinder(value, "id") === id)[0] ); }; - const handleModalOpen = (id: string) => () => { - openModal(); - onClick && onClick(id); - }; - return ( <> diff --git a/frontend/components/interview/Board.tsx b/frontend/components/interview/Board.tsx index 3ee50cc5..24863dfc 100644 --- a/frontend/components/interview/Board.tsx +++ b/frontend/components/interview/Board.tsx @@ -25,7 +25,8 @@ const InterviewBoard = ({ interviewRecords }: InterviewBoardProps) => { const queryClient = useQueryClient(); const { isOpen, openModal, closeModal } = useModalState(); - const onClick = (id: string) => { + const handleModalOpen = (id: string) => () => { + openModal(); setApplicantId(id); queryClient.invalidateQueries({ queryKey: ["record", applicantId], @@ -35,11 +36,6 @@ const InterviewBoard = ({ interviewRecords }: InterviewBoardProps) => { }); }; - const handleModalOpen = (id: string) => () => { - openModal(); - onClick && onClick(id); - }; - return ( <> Date: Mon, 24 Feb 2025 02:00:05 +0900 Subject: [PATCH 14/20] =?UTF-8?q?refactor:=20hard=ED=95=9C=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=84=A0=EC=96=B8=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/components/interview/Board.tsx | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/frontend/components/interview/Board.tsx b/frontend/components/interview/Board.tsx index 24863dfc..0ddfcd78 100644 --- a/frontend/components/interview/Board.tsx +++ b/frontend/components/interview/Board.tsx @@ -8,15 +8,10 @@ import { interViewApplicantIdState } from "@/src/stores/interview/Interview.atom import BoardTable from "../common/board/BoardTable"; import useModalState from "../../src/hooks/useModalState"; import BoardModal from "../common/board/BoardModal"; -import { ApplicantPassState } from "../../src/apis/kanban"; +import { BoardData } from "../common/board/Board"; interface InterviewBoardProps { - interviewRecords: { - id: string; - title: string; - subElements: string[]; - passState: ApplicantPassState; - }[]; + interviewRecords: BoardData[]; } const InterviewBoard = ({ interviewRecords }: InterviewBoardProps) => { From 03a7dba2b6718801a8e1a229f994e92fcd45fb62 Mon Sep 17 00:00:00 2001 From: 2yunseong Date: Mon, 24 Feb 2025 17:50:31 +0900 Subject: [PATCH 15/20] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/components/common/board/Board.tsx | 51 ------------------- .../components/common/board/BoardTable.tsx | 2 +- frontend/components/common/board/types.ts | 9 ++++ frontend/components/interview/Board.tsx | 2 +- 4 files changed, 11 insertions(+), 53 deletions(-) delete mode 100644 frontend/components/common/board/Board.tsx create mode 100644 frontend/components/common/board/types.ts diff --git a/frontend/components/common/board/Board.tsx b/frontend/components/common/board/Board.tsx deleted file mode 100644 index e4a43e32..00000000 --- a/frontend/components/common/board/Board.tsx +++ /dev/null @@ -1,51 +0,0 @@ -"use client"; - -import { type PropsWithChildren } from "react"; -import useModalState from "../../../src/hooks/useModalState"; -import BoardModal from "./BoardModal"; -import BoardTable from "./BoardTable"; -import { type ApplicantPassState } from "../../../src/apis/kanban"; - -export interface BoardData { - id: string; - title: string; - subElements: string[]; - time?: Date; - passState?: ApplicantPassState; -} - -interface BoardProps extends PropsWithChildren { - onClick?: (id: string) => void; - wrapperClassName?: string; - boardData: BoardData[]; -} - -const Board = ({ - children, - onClick, - wrapperClassName, - boardData, -}: BoardProps) => { - const { isOpen, openModal, closeModal } = useModalState(); - - const handleModalOpen = (id: string) => () => { - openModal(); - onClick && onClick(id); - }; - - return ( - <> - - - {children} - - - ); -}; - -export default Board; diff --git a/frontend/components/common/board/BoardTable.tsx b/frontend/components/common/board/BoardTable.tsx index acb64d06..57660833 100644 --- a/frontend/components/common/board/BoardTable.tsx +++ b/frontend/components/common/board/BoardTable.tsx @@ -1,6 +1,6 @@ import Txt from "../Txt.component"; -import { BoardData } from "./Board"; import BoardCell from "./BoardCell.component"; +import { BoardData } from "./types"; interface BoardTableProps { boardRows: BoardData[]; diff --git a/frontend/components/common/board/types.ts b/frontend/components/common/board/types.ts new file mode 100644 index 00000000..ecf50e2f --- /dev/null +++ b/frontend/components/common/board/types.ts @@ -0,0 +1,9 @@ +import { ApplicantPassState } from "../../../src/apis/kanban"; + +export interface BoardData { + id: string; + title: string; + subElements: string[]; + time?: Date; + passState?: ApplicantPassState; +} diff --git a/frontend/components/interview/Board.tsx b/frontend/components/interview/Board.tsx index 0ddfcd78..d1da31ef 100644 --- a/frontend/components/interview/Board.tsx +++ b/frontend/components/interview/Board.tsx @@ -8,7 +8,7 @@ import { interViewApplicantIdState } from "@/src/stores/interview/Interview.atom import BoardTable from "../common/board/BoardTable"; import useModalState from "../../src/hooks/useModalState"; import BoardModal from "../common/board/BoardModal"; -import { BoardData } from "../common/board/Board"; +import { BoardData } from "../common/board/types"; interface InterviewBoardProps { interviewRecords: BoardData[]; From 8bbc3914d26866c6464d61f77ab934c5dbba5e2c Mon Sep 17 00:00:00 2001 From: 2yunseong Date: Mon, 24 Feb 2025 18:49:38 +0900 Subject: [PATCH 16/20] =?UTF-8?q?fix:=20reconcliation=EC=9D=B4=20=EC=95=88?= =?UTF-8?q?=EB=90=98=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/components/interview/modal/score/AvgScore.tsx | 2 +- frontend/components/interview/modal/score/MyScoreForm.tsx | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/components/interview/modal/score/AvgScore.tsx b/frontend/components/interview/modal/score/AvgScore.tsx index 495a819c..f983bf3c 100644 --- a/frontend/components/interview/modal/score/AvgScore.tsx +++ b/frontend/components/interview/modal/score/AvgScore.tsx @@ -24,7 +24,7 @@ const AvgScore = ({ totalAverage, fieldAverages }: AvgScoreProps) => {
{fieldAverages.map(({ fieldName, score }) => ( - + ))}
diff --git a/frontend/components/interview/modal/score/MyScoreForm.tsx b/frontend/components/interview/modal/score/MyScoreForm.tsx index 83193f9f..f6d8ffe3 100644 --- a/frontend/components/interview/modal/score/MyScoreForm.tsx +++ b/frontend/components/interview/modal/score/MyScoreForm.tsx @@ -79,6 +79,7 @@ const MyScoreForm = ({
{myScores.map(({ fieldName, score }) => ( Date: Fri, 28 Feb 2025 21:34:16 +0900 Subject: [PATCH 17/20] =?UTF-8?q?refactor:=20import=20alias=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/app/(WithNavbar)/applicant/[generation]/page.tsx | 2 +- frontend/app/(WithNavbar)/interview/[generation]/page.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/app/(WithNavbar)/applicant/[generation]/page.tsx b/frontend/app/(WithNavbar)/applicant/[generation]/page.tsx index dce8f435..3096e2b4 100644 --- a/frontend/app/(WithNavbar)/applicant/[generation]/page.tsx +++ b/frontend/app/(WithNavbar)/applicant/[generation]/page.tsx @@ -1,7 +1,7 @@ import SortList from "@/components/common/SortList"; import Search from "@/components/common/Search"; import { ORDER_MENU } from "@/src/constants"; -import ApplicantList from "../../../../components/applicant/ApplicantList"; +import ApplicantList from "@/components/applicant/ApplicantList"; interface ApplicantPageProps { params: { diff --git a/frontend/app/(WithNavbar)/interview/[generation]/page.tsx b/frontend/app/(WithNavbar)/interview/[generation]/page.tsx index 72e4baf6..3a356596 100644 --- a/frontend/app/(WithNavbar)/interview/[generation]/page.tsx +++ b/frontend/app/(WithNavbar)/interview/[generation]/page.tsx @@ -1,7 +1,7 @@ import SortList from "@/components/common/SortList"; import Search from "@/components/common/Search"; import { ORDER_MENU } from "@/src/constants"; -import InterviewerList from "../../../../components/interview/InterviewerList"; +import InterviewerList from "@/components/interview/InterviewerList"; interface InterviewPageProps { params: { From 8d5cd5e19a8a73392f15f75a07fc1457d5a6520b Mon Sep 17 00:00:00 2001 From: 2yunseong Date: Fri, 28 Feb 2025 21:40:51 +0900 Subject: [PATCH 18/20] =?UTF-8?q?fix:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=ED=83=9C=EA=B7=B8=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/components/applicant/ApplicantList.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/frontend/components/applicant/ApplicantList.tsx b/frontend/components/applicant/ApplicantList.tsx index e473aeec..262fba3d 100644 --- a/frontend/components/applicant/ApplicantList.tsx +++ b/frontend/components/applicant/ApplicantList.tsx @@ -28,11 +28,7 @@ const ApplicantList = ({ generation }: ApplicantListProps) => { ); if (status === "loading") { - return ( -
- -
- ); + return ; } if (status === "error") { return
에러 발생
; From 97c9e85344a5c3d580e0de719d8fc5e4d6e2a184 Mon Sep 17 00:00:00 2001 From: 2yunseong Date: Fri, 28 Feb 2025 22:02:02 +0900 Subject: [PATCH 19/20] =?UTF-8?q?refactor:=20=EB=A1=9C=EB=94=A9=EC=8A=A4?= =?UTF-8?q?=ED=94=BC=EB=84=88=20=EC=BD=94=EB=93=9C=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/applicant/ApplicantList.tsx | 2 +- frontend/components/common/LoadingSpinner.tsx | 60 +++++++------------ 2 files changed, 23 insertions(+), 39 deletions(-) diff --git a/frontend/components/applicant/ApplicantList.tsx b/frontend/components/applicant/ApplicantList.tsx index 262fba3d..8537612e 100644 --- a/frontend/components/applicant/ApplicantList.tsx +++ b/frontend/components/applicant/ApplicantList.tsx @@ -28,7 +28,7 @@ const ApplicantList = ({ generation }: ApplicantListProps) => { ); if (status === "loading") { - return ; + return ; } if (status === "error") { return
에러 발생
; diff --git a/frontend/components/common/LoadingSpinner.tsx b/frontend/components/common/LoadingSpinner.tsx index c9912697..7235f965 100644 --- a/frontend/components/common/LoadingSpinner.tsx +++ b/frontend/components/common/LoadingSpinner.tsx @@ -1,45 +1,29 @@ -type TailwindSize = - | 0 - | 0.5 - | 1 - | 1.5 - | 2 - | 2.5 - | 3 - | 3.5 - | 4 - | 5 - | 6 - | 7 - | 8 - | 9 - | 10 - | 11 - | 12 - | 14 - | 16 - | 20 - | 24 - | 28 - | 32 - | 36 - | 40 - | 44 - | 48 - | 52 - | 56 - | 60 - | 64 - | 72 - | 80 - | 96; +import { cn } from "../../src/utils/cn"; interface LoadingSpinnerProps { - size?: TailwindSize; + size?: "s" | "m" | "l" | "xl"; } -const LoadingSpinner = ({ size = 6 }: LoadingSpinnerProps) => { + +const getSize = (size: "s" | "m" | "l" | "xl") => { + switch (size) { + case "s": + return cn("w-6", "h-6"); + case "m": + return cn("w-12", "h-12"); + case "l": + return cn("w-18", "h-18"); + case "xl": + return cn("w-24 h-24"); + default: + throw new Error( + "Error: Loading Spinner의 `size` Props는 s, m, l, xl 중 하나 입니다." + ); + } +}; + +const LoadingSpinner = ({ size = "s" }: LoadingSpinnerProps) => { return ( -
+
Date: Fri, 28 Feb 2025 22:05:39 +0900 Subject: [PATCH 20/20] =?UTF-8?q?fix:=20=EC=9E=98=EB=AA=BB=EB=90=9C=20prop?= =?UTF-8?q?s=20=EC=A0=84=EB=8B=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/components/interview/InterviewerList.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/components/interview/InterviewerList.tsx b/frontend/components/interview/InterviewerList.tsx index bd1ba215..8114a0b2 100644 --- a/frontend/components/interview/InterviewerList.tsx +++ b/frontend/components/interview/InterviewerList.tsx @@ -33,7 +33,7 @@ const InterviewerList = ({ generation }: InterviewerListProps) => { if (status === "loading") { return (
- +
); }