From 5ca3c6b20f774aec6d3b503e27f38c8e83f7b4d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Thu, 19 Sep 2024 15:03:21 +0900 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20=EC=A7=80=EC=9B=90=EC=84=9C=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=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #202 --- .../_applicant/ApplicantDetailLeft.tsx | 74 +++++++++++++++++ .../_applicantNode/CustomResource.tsx | 80 +++++++++++++++++++ frontend/src/apis/passState/index.tsx | 8 +- 3 files changed, 157 insertions(+), 5 deletions(-) create mode 100644 frontend/components/applicant/_applicant/ApplicantDetailLeft.tsx create mode 100644 frontend/components/applicant/_applicant/_applicantNode/CustomResource.tsx diff --git a/frontend/components/applicant/_applicant/ApplicantDetailLeft.tsx b/frontend/components/applicant/_applicant/ApplicantDetailLeft.tsx new file mode 100644 index 0000000..c54ce66 --- /dev/null +++ b/frontend/components/applicant/_applicant/ApplicantDetailLeft.tsx @@ -0,0 +1,74 @@ +"use client"; + +import { ApplicantReq } from "@/src/apis/applicant"; +import CustomResource from "./_applicantNode/CustomResource"; +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { + postApplicantPassState, + PostApplicantPassStateParams, +} from "@/src/apis/passState"; +import { applicantDataFinder } from "@/src/functions/finder"; +import { getMyInfo } from "@/src/apis/interview"; +import ApplicantLabel from "../applicantNode/Label.component"; +import ApplicantComment from "../applicantNode/comment/Comment.component"; + +interface DetailLeftProps { + data: ApplicantReq[]; + generation: string; + cardId: number; +} +const ApplicantDetailLeft = ({ data, cardId, generation }: DetailLeftProps) => { + const queryClient = useQueryClient(); + const { mutate: updateApplicantPassState } = useMutation({ + mutationFn: (params: PostApplicantPassStateParams) => + postApplicantPassState(params), + onSuccess: () => { + queryClient.invalidateQueries({ + queryKey: [ + "allApplicantsWithPassState", + applicantDataFinder(data, "generation"), + ], + }); + }, + }); + const { data: userData } = useQuery(["user"], getMyInfo); + + const postId = applicantDataFinder(data, "id"); + + const onClickPass = () => { + const ok = confirm("합격 처리하시겠습니까?"); + if (!ok) return; + updateApplicantPassState({ + applicantId: postId, + afterState: "pass", + }); + }; + + const onClickNonPass = () => { + const ok = confirm("불합격 처리하시겠습니까?"); + if (!ok) return; + updateApplicantPassState({ + applicantId: postId, + afterState: "non-pass", + }); + }; + + return ( + <> + + + + + ); +}; + +export default ApplicantDetailLeft; diff --git a/frontend/components/applicant/_applicant/_applicantNode/CustomResource.tsx b/frontend/components/applicant/_applicant/_applicantNode/CustomResource.tsx new file mode 100644 index 0000000..cad15de --- /dev/null +++ b/frontend/components/applicant/_applicant/_applicantNode/CustomResource.tsx @@ -0,0 +1,80 @@ +import { applicantDataFinder } from "@/src/functions/finder"; +import Portfolio from "../../applicantNode/Portfolio"; +import { ApplicantReq } from "@/src/apis/applicant"; +import Txt from "@/components/common/Txt.component"; +import { getApplicantPassState } from "@/src/functions/formatter"; + +interface CustomResourceProps { + data: ApplicantReq[]; + ableToEdit?: boolean; + onClickPass?: () => void; + onClickNonPass?: () => void; +} + +const CustomResource = ({ + data, + ableToEdit = false, + onClickPass, + onClickNonPass, +}: CustomResourceProps) => { + return ( + <> +
+ + {applicantDataFinder(data, "major")} + +
+ {`[${applicantDataFinder( + data, + "field" + )}] ${applicantDataFinder(data, "name")}`} +
+ + {getApplicantPassState(applicantDataFinder(data, "passState")) || + "에러 발생"} + + {ableToEdit && ( +
+ + +
+ )} +
+
+
+
+
+ + 1지망: + + + {applicantDataFinder(data, "field1")} + +
+
+ + 2지망: + + + {applicantDataFinder(data, "field2")} + +
+
+
+ +
+ + ); +}; + +export default CustomResource; diff --git a/frontend/src/apis/passState/index.tsx b/frontend/src/apis/passState/index.tsx index dd7e2f1..a103ce1 100644 --- a/frontend/src/apis/passState/index.tsx +++ b/frontend/src/apis/passState/index.tsx @@ -23,14 +23,12 @@ export const getAllApplicantsWithPassState = async (generation: string) => { }; export interface PostApplicantPassStateParams { - applicantsId: string; + applicantId: string; afterState: "non-pass" | "pass"; } export const postApplicantPassState = async ({ afterState, - applicantsId, + applicantId, }: PostApplicantPassStateParams) => { - await https.post( - `/applicants/${applicantsId}/state?afterState=${afterState}` - ); + await https.post(`/applicants/${applicantId}/state?afterState=${afterState}`); }; From 37ab3bd30c35d17a8f058e4b7a9bdac7120d99e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Thu, 19 Sep 2024 16:14:17 +0900 Subject: [PATCH 2/5] =?UTF-8?q?fix:=20=EC=9D=91=EB=8B=B5=EA=B0=92=EC=9D=84?= =?UTF-8?q?=20=ED=8C=8C=EC=8B=B1=ED=95=98=EB=8A=94=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #202 --- frontend/components/applicant/Board.tsx | 10 ++-- frontend/src/apis/applicant/index.ts | 69 ++++++++++++++++++++++--- 2 files changed, 68 insertions(+), 11 deletions(-) diff --git a/frontend/components/applicant/Board.tsx b/frontend/components/applicant/Board.tsx index f24daec..56fdf87 100644 --- a/frontend/components/applicant/Board.tsx +++ b/frontend/components/applicant/Board.tsx @@ -3,7 +3,6 @@ import Board from "@/components/common/board/Board"; import { getApplicantByPageWithGeneration } from "@/src/apis/applicant"; import ApplicantDetailRight from "./DetailRight.component"; -import ApplicantDetailLeft from "./DetailLeft.component"; import { useState } from "react"; import { ApplicantReq } from "@/src/apis/application"; import { applicantDataFinder } from "@/src/functions/finder"; @@ -12,6 +11,8 @@ 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"; interface ApplicantBoardProps { generation: string; @@ -74,9 +75,10 @@ const ApplicantBoard = ({ generation }: ApplicantBoardProps) => { Number(applicantDataFinder(value, "uploadDate")) ).toLocaleString("ko-KR", { dateStyle: "short" }), ], - passState: `${ - applicantDataFinder(value, "passState").passState - }` as ApplicantPassState, + passState: `${applicantDataFinder( + value, + "passState" + )}` as ApplicantPassState, })); return ( diff --git a/frontend/src/apis/applicant/index.ts b/frontend/src/apis/applicant/index.ts index 355e65d..85f31ac 100644 --- a/frontend/src/apis/applicant/index.ts +++ b/frontend/src/apis/applicant/index.ts @@ -12,6 +12,46 @@ interface AllApplicantReq { [string: string]: string; } +interface ApplicantByPageReqAnswer { + field: string; + field1: string; + field2: string; + name: string; + contacted: string; + classOf: string; + registered: string; + grade: string; + semester: string; + major: string; + doubleMajor: string; + minor: string; + activity: string; + reason: string; + future: string; + experience: string; + experienceTextarea: string; + restoration: string; + deep: string; + collaboration: string; + studyPlan: string; + portfolio: string; + fileUrl: string; + email: string; + check: string; + personalInformationAgree: string; + personalInformationAgreeForPortfolio: string; + generation: string; + uploadDate: string; + channel: string; + timeline: number[]; + id: string; + year: number; + created_at: string; + passState: { + passState: ApplicantPassState; + }; +} + export const getApplicantByIdWithField = async ( id: string, fields?: string[] @@ -36,9 +76,29 @@ export interface PageInfo { boardLimit: number; } +function formatApplicantsDataToApplicantReq( + applicants: ApplicantByPageReqAnswer[] +) { + return applicants.map( + (applicant) => + Object.keys(applicant).map((key) => { + if (key === "passState") { + return { + name: "passState", + answer: applicant.passState.passState, + }; + } + return { + name: key, + answer: applicant[key as keyof ApplicantByPageReqAnswer], + }; + }) as ApplicantReq[] + ); +} + interface ApplicantByPageReq { pageInfo: PageInfo; - answers: AllApplicantReq[]; + answers: ApplicantByPageReqAnswer[]; } export const getApplicantByPageWithGeneration = async ( @@ -54,12 +114,7 @@ export const getApplicantByPageWithGeneration = async ( return { maxPage: pageInfo.endPage, - applicants: answers.map((applicant) => - Object.keys(applicant).map((key) => ({ - name: key, - answer: applicant[key], - })) - ), + applicants: formatApplicantsDataToApplicantReq(answers), }; }; From a74f3feb2fabbd7d899af06b60f605ac357afe47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Thu, 19 Sep 2024 16:48:34 +0900 Subject: [PATCH 3/5] =?UTF-8?q?fix:=20=EB=B9=8C=EB=93=9C=20=EB=B2=84?= =?UTF-8?q?=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 오탈자 수정 #202 --- frontend/components/passState/ApplicantsList.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/components/passState/ApplicantsList.tsx b/frontend/components/passState/ApplicantsList.tsx index 183af24..da33be6 100644 --- a/frontend/components/passState/ApplicantsList.tsx +++ b/frontend/components/passState/ApplicantsList.tsx @@ -132,7 +132,7 @@ const ApplicantsList = ({ sortedBy }: ApplicantsListProps) => { className="border px-4 py-2 rounded-lg truncate hover:bg-primary-100" onClick={() => onChangeApplicantsPassState(name, { - applicantsId: id, + applicantId: id, afterState: "pass", }) } @@ -143,7 +143,7 @@ const ApplicantsList = ({ sortedBy }: ApplicantsListProps) => { className="border px-4 rounded-lg truncate hover:bg-primary-100" onClick={() => onChangeApplicantsPassState(name, { - applicantsId: id, + applicantId: id, afterState: "non-pass", }) } From 5829277902f8855165464e0dc8d87ead20db901b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Thu, 19 Sep 2024 17:53:19 +0900 Subject: [PATCH 4/5] =?UTF-8?q?fix:=20post=EC=9A=94=EC=B2=AD=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #202 --- .../applicant/_applicant/ApplicantDetailLeft.tsx | 8 ++++---- frontend/components/passState/ApplicantsList.tsx | 10 +++++----- frontend/src/apis/passState/index.tsx | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/frontend/components/applicant/_applicant/ApplicantDetailLeft.tsx b/frontend/components/applicant/_applicant/ApplicantDetailLeft.tsx index c54ce66..d9a2705 100644 --- a/frontend/components/applicant/_applicant/ApplicantDetailLeft.tsx +++ b/frontend/components/applicant/_applicant/ApplicantDetailLeft.tsx @@ -4,8 +4,8 @@ import { ApplicantReq } from "@/src/apis/applicant"; import CustomResource from "./_applicantNode/CustomResource"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { - postApplicantPassState, - PostApplicantPassStateParams, + patchApplicantPassState, + PatchApplicantPassStateParams, } from "@/src/apis/passState"; import { applicantDataFinder } from "@/src/functions/finder"; import { getMyInfo } from "@/src/apis/interview"; @@ -20,8 +20,8 @@ interface DetailLeftProps { const ApplicantDetailLeft = ({ data, cardId, generation }: DetailLeftProps) => { const queryClient = useQueryClient(); const { mutate: updateApplicantPassState } = useMutation({ - mutationFn: (params: PostApplicantPassStateParams) => - postApplicantPassState(params), + mutationFn: (params: PatchApplicantPassStateParams) => + patchApplicantPassState(params), onSuccess: () => { queryClient.invalidateQueries({ queryKey: [ diff --git a/frontend/components/passState/ApplicantsList.tsx b/frontend/components/passState/ApplicantsList.tsx index da33be6..af5d01e 100644 --- a/frontend/components/passState/ApplicantsList.tsx +++ b/frontend/components/passState/ApplicantsList.tsx @@ -2,7 +2,7 @@ import { getAllApplicantsWithPassState, - postApplicantPassState, + patchApplicantPassState, } from "@/src/apis/passState"; import { CURRENT_GENERATION } from "@/src/constants"; import { usePathname } from "next/navigation"; @@ -10,7 +10,7 @@ import Txt from "../common/Txt.component"; import { getApplicantPassState } from "@/src/functions/formatter"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import type { - PostApplicantPassStateParams, + PatchApplicantPassStateParams, Answer, } from "@/src/apis/passState"; @@ -57,8 +57,8 @@ const ApplicantsList = ({ sortedBy }: ApplicantsListProps) => { ); const { mutate: updateApplicantPassState } = useMutation({ - mutationFn: (params: PostApplicantPassStateParams) => - postApplicantPassState(params), + mutationFn: (params: PatchApplicantPassStateParams) => + patchApplicantPassState(params), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["allApplicantsWithPassState", selectedGeneration], @@ -86,7 +86,7 @@ const ApplicantsList = ({ sortedBy }: ApplicantsListProps) => { const onChangeApplicantsPassState = ( applicantName: string, - params: PostApplicantPassStateParams + params: PatchApplicantPassStateParams ) => { const ok = confirm( `${applicantName}님을 ${params.afterState} 처리하시겠습니까?` diff --git a/frontend/src/apis/passState/index.tsx b/frontend/src/apis/passState/index.tsx index a103ce1..9868a11 100644 --- a/frontend/src/apis/passState/index.tsx +++ b/frontend/src/apis/passState/index.tsx @@ -22,13 +22,13 @@ export const getAllApplicantsWithPassState = async (generation: string) => { return data; }; -export interface PostApplicantPassStateParams { +export interface PatchApplicantPassStateParams { applicantId: string; afterState: "non-pass" | "pass"; } -export const postApplicantPassState = async ({ +export const patchApplicantPassState = async ({ afterState, applicantId, -}: PostApplicantPassStateParams) => { +}: PatchApplicantPassStateParams) => { await https.post(`/applicants/${applicantId}/state?afterState=${afterState}`); }; From 8d10216de5bac0eccb657c86ba789c73082f5896 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=80=E1=85=A5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=B2?= Date: Thu, 19 Sep 2024 17:56:50 +0900 Subject: [PATCH 5/5] =?UTF-8?q?fix:=20=EC=88=98=EC=A0=95=20=EA=B0=80?= =?UTF-8?q?=EB=8A=A5=20=EA=B6=8C=ED=95=9C=EC=97=90=20=ED=9A=8C=EC=9E=A5?= =?UTF-8?q?=EB=8B=A8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #202 --- .../components/applicant/_applicant/ApplicantDetailLeft.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontend/components/applicant/_applicant/ApplicantDetailLeft.tsx b/frontend/components/applicant/_applicant/ApplicantDetailLeft.tsx index d9a2705..57389b0 100644 --- a/frontend/components/applicant/_applicant/ApplicantDetailLeft.tsx +++ b/frontend/components/applicant/_applicant/ApplicantDetailLeft.tsx @@ -57,7 +57,10 @@ const ApplicantDetailLeft = ({ data, cardId, generation }: DetailLeftProps) => { <>