Skip to content

Commit

Permalink
Merge branch 'main' into fix/221-ApplicantPassState-fix
Browse files Browse the repository at this point in the history
  • Loading branch information
geongyu09 authored Sep 19, 2024
2 parents 6f503e4 + f33fa1d commit dc06a5f
Show file tree
Hide file tree
Showing 4 changed files with 225 additions and 11 deletions.
10 changes: 6 additions & 4 deletions frontend/components/applicant/Board.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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;
Expand Down Expand Up @@ -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 (
Expand Down
77 changes: 77 additions & 0 deletions frontend/components/applicant/_applicant/ApplicantDetailLeft.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<>
<CustomResource
data={data}
ableToEdit={
userData?.role === "ROLE_OPERATION" ||
userData?.role === "ROLE_PRESIDENT"
}
onClickPass={onClickPass}
onClickNonPass={onClickNonPass}
/>
<ApplicantLabel postId={postId} generation={generation} />
<ApplicantComment
cardId={cardId}
postId={postId}
generation={generation}
/>
</>
);
};

export default ApplicantDetailLeft;
Original file line number Diff line number Diff line change
@@ -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 (
<>
<div className="flex flex-col gap-1 mb-2">
<Txt className="text-xl text-secondary-200 font-medium">
{applicantDataFinder(data, "major")}
</Txt>
<div className="flex gap-8 items-center">
<Txt typography="h2">{`[${applicantDataFinder(
data,
"field"
)}] ${applicantDataFinder(data, "name")}`}</Txt>
<div className="flex justify-between grow items-center">
<Txt typography="h5" color="light_gray" className="truncate">
{getApplicantPassState(applicantDataFinder(data, "passState")) ||
"에러 발생"}
</Txt>
{ableToEdit && (
<div className="flex gap-4">
<button
className="border rounded-lg px-4 py-2 truncate hover:bg-primary-100"
onClick={onClickPass}
>
합격
</button>
<button
className="border rounded-lg px-4 py-2 truncate hover:bg-primary-100"
onClick={onClickNonPass}
>
불합격
</button>
</div>
)}
</div>
</div>
</div>
<div className="flex gap-4 mb-8">
<div className="flex gap-1">
<Txt typography="h3" color="gray" className="font-normal">
1지망:
</Txt>
<Txt typography="h3" color="blue">
{applicantDataFinder(data, "field1")}
</Txt>
</div>
<div className="flex gap-1">
<Txt typography="h3" color="gray" className="font-normal">
2지망:
</Txt>
<Txt typography="h3" color="blue">
{applicantDataFinder(data, "field2")}
</Txt>
</div>
</div>
<div className="flex flex-col gap-4">
<Portfolio data={data} />
</div>
</>
);
};

export default CustomResource;
69 changes: 62 additions & 7 deletions frontend/src/apis/applicant/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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[]
Expand All @@ -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 (
Expand All @@ -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),
};
};

Expand Down

0 comments on commit dc06a5f

Please sign in to comment.