Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 칸반보드 상세 페이지에서 지원 상태 확인 및 지원 상태 변경 가능하게 구현 #208

Merged
merged 16 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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;
};