Skip to content

Commit

Permalink
feat: 칸반보드 상세 페이지에서 지원 상태 확인 및 지원 상태 변경 가능하게 구현 (#208)
Browse files Browse the repository at this point in the history
  • Loading branch information
smb0123 authored Sep 19, 2024
2 parents 75500bf + b3e062f commit 0909c09
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 14 deletions.
2 changes: 1 addition & 1 deletion frontend/components/applicant/DetailLeft.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const ApplicantDetailLeft = ({

return (
<>
<ApplicantResource data={data} postId={postId} />
<ApplicantResource data={data} postId={postId} generation={generation} />
<ApplicantLabel postId={postId} generation={generation} />
<ApplicantComment
cardId={cardId}
Expand Down
128 changes: 118 additions & 10 deletions frontend/components/applicant/applicantNode/CustomResource.component.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,131 @@
import Txt from "@/components/common/Txt.component";
import { ApplicantReq } from "@/src/apis/applicant";
import { ApplicantReq, patchApplicantState } from "@/src/apis/applicant";
import { applicantDataFinder } from "@/src/functions/finder";
import Portfolio from "./Portfolio";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useSearchParams } from "next/navigation";
import KanbanCardApplicantStatusLabel from "@/components/kanban/card/CardApplicantStatusLabel";
import { useAtomValue } from "jotai";
import { KanbanSelectedButtonNumberState } from "@/src/stores/kanban/Navbar.atoms";
import { getMyInfo } from "@/src/apis/interview";
import { findApplicantState } from "@/src/utils/applicant";
import { ApplicantPassState, getKanbanCards } from "@/src/apis/kanban";

interface ApplicantResourceProps {
data: ApplicantReq[];
postId: string;
generation: string;
}

const ApplicantResource = ({ data, postId }: ApplicantResourceProps) => {
const ApplicantResource = ({
data,
postId,
generation,
}: ApplicantResourceProps) => {
const navbarId = useAtomValue(KanbanSelectedButtonNumberState);
const searchParams = useSearchParams();
const applicantId = searchParams.get("applicantId");
const queryClient = useQueryClient();

const {
data: initialState,
isLoading,
isError,
} = useQuery({
queryKey: ["applicantState", applicantId, navbarId],
queryFn: async () =>
findApplicantState(
await getKanbanCards(navbarId, generation),
`${applicantId}`
),
staleTime: 3000,
});

const {
data: myInfo,
isLoading: myInfoLoading,
isError: myInfoError,
} = useQuery({
queryKey: ["user"],
queryFn: getMyInfo,
});
const { mutate } = useMutation({
mutationFn: (afterState: "non-pass" | "pass") =>
patchApplicantState(`${applicantId}`, afterState),
onMutate: async () => {
await queryClient.cancelQueries([
"applicantState",
applicantId,
navbarId,
]);

const snapshotState = queryClient.getQueryData<ApplicantPassState>([
"applicantState",
applicantId,
navbarId,
]);

return { snapshotState };
},
onSuccess: () => {
queryClient.invalidateQueries(["kanbanDataArray", generation]);
},
onError: (error, variables, context) => {
window.alert("상태 변경에 실패했습니다.");
},
onSettled: () => {
queryClient.invalidateQueries(["applicantState", applicantId, navbarId]);
},
});

const onFailedButtonClick = () => {
mutate("non-pass");
};

const onPassedButtonClick = () => {
mutate("pass");
};

if (!initialState || isLoading || !myInfo || myInfoLoading) {
return <div>로딩중...</div>;
}

if (isError || myInfoError) {
return <div>에러 발생</div>;
}

return (
<>
<div className="flex flex-col gap-1 mb-2">
<Txt className="text-xl text-secondary-200 font-medium">
{applicantDataFinder(data, "major")}
</Txt>
<Txt typography="h2">{`[${applicantDataFinder(
data,
"field"
)}] ${applicantDataFinder(data, "name")}`}</Txt>
<div className="flex justify-between items-center">
<div className="flex flex-col gap-1 mb-2">
<div className="flex justify-between items-center">
<Txt className="text-xl text-secondary-200 font-medium">
{applicantDataFinder(data, "major")}
</Txt>
<KanbanCardApplicantStatusLabel passState={initialState} />
</div>
<Txt typography="h2">{`[${applicantDataFinder(
data,
"field"
)}] ${applicantDataFinder(data, "name")}`}</Txt>
</div>
{(myInfo.role === "ROLE_OPERATION" ||
myInfo.role === "ROLE_PRESIDENT") && (
<div className="flex gap-5">
<button
onClick={onFailedButtonClick}
className="bg-zinc-200 w-20 h-20 hover:bg-sky-400 rounded-xl"
>
불합격
</button>
<button
onClick={onPassedButtonClick}
className="bg-zinc-200 w-20 h-20 hover:bg-sky-400 rounded-xl"
>
합격
</button>
</div>
)}
</div>
<div className="flex gap-4 mb-8">
<div className="flex gap-1">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ const KanbanColumnDetailCard = ({
data: kanbanDataArray,
isError,
isLoading,
} = useQuery<KanbanColumnData[]>(["kanbanDataArray", generation], () =>
getAllKanbanData(navbarId, generation)
);
} = useQuery<KanbanColumnData[]>({
queryKey: ["kanbanDataArray", generation],
queryFn: () => getAllKanbanData(navbarId, generation),
staleTime: 3000,
});

if (!kanbanDataArray || isLoading) {
return <div>로딩중...</div>;
Expand Down
16 changes: 16 additions & 0 deletions frontend/src/apis/applicant/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { getAllInterviewerWithOrder } from "@/src/apis/interview";
import { APPLICANT_KEYS } from "@/src/constants";
import { https } from "@/src/functions/axios";
import { ApplicantPassState, getKanbanCards, KanbanCardReq } from "../kanban";

export interface ApplicantReq {
name: string;
Expand Down Expand Up @@ -131,3 +132,18 @@ export const getApplicantTimeTables = async (id: string) => {

return data;
};

interface PatchApplicantStateRes {
passState: ApplicantPassState;
}

export const patchApplicantState = async (
id: string,
afterState: "non-pass" | "pass"
) => {
const { data } = await https.patch<PatchApplicantStateRes>(
`/applicants/${id}/state?afterState=${afterState}`
);

return data;
};
9 changes: 9 additions & 0 deletions frontend/src/utils/applicant/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { KanbanCardReq } from "@/src/apis/kanban";

export const findApplicantState = (
cardsData: KanbanCardReq[],
applicantId: string
) => {
return cardsData.find((card) => card.applicantId === applicantId)?.state
.passState;
};

0 comments on commit 0909c09

Please sign in to comment.