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/components/applicant/_applicant/ApplicantDetailLeft.tsx b/frontend/components/applicant/_applicant/ApplicantDetailLeft.tsx
new file mode 100644
index 0000000..57389b0
--- /dev/null
+++ b/frontend/components/applicant/_applicant/ApplicantDetailLeft.tsx
@@ -0,0 +1,77 @@
+"use client";
+
+import { ApplicantReq } from "@/src/apis/applicant";
+import CustomResource from "./_applicantNode/CustomResource";
+import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
+import {
+ patchApplicantPassState,
+ PatchApplicantPassStateParams,
+} 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: PatchApplicantPassStateParams) =>
+ patchApplicantPassState(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/components/passState/ApplicantsList.tsx b/frontend/components/passState/ApplicantsList.tsx
index 183af24..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} 처리하시겠습니까?`
@@ -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",
})
}
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),
};
};
diff --git a/frontend/src/apis/passState/index.tsx b/frontend/src/apis/passState/index.tsx
index dd7e2f1..9868a11 100644
--- a/frontend/src/apis/passState/index.tsx
+++ b/frontend/src/apis/passState/index.tsx
@@ -22,15 +22,13 @@ export const getAllApplicantsWithPassState = async (generation: string) => {
return data;
};
-export interface PostApplicantPassStateParams {
- applicantsId: string;
+export interface PatchApplicantPassStateParams {
+ applicantId: string;
afterState: "non-pass" | "pass";
}
-export const postApplicantPassState = async ({
+export const patchApplicantPassState = async ({
afterState,
- applicantsId,
-}: PostApplicantPassStateParams) => {
- await https.post(
- `/applicants/${applicantsId}/state?afterState=${afterState}`
- );
+ applicantId,
+}: PatchApplicantPassStateParams) => {
+ await https.post(`/applicants/${applicantId}/state?afterState=${afterState}`);
};