From bcf1eb55c03b3b1506738c975433d4a03d31af45 Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 20 Jan 2026 22:16:37 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=EC=9D=B4=EB=A0=A5=EC=84=9C=20?= =?UTF-8?q?=EA=B8=B0=EB=B0=98=20=EB=A9=B4=EC=A0=91=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EA=B4=80=EB=A0=A8=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 이력서 기반 면접 질문 생성 API 및 상태 관리 로직 추가 - 면접 질문 생성 폼 및 히스토리 컴포넌트 구현 - 이력서 기반 면접 결과 페이지 및 모드 선택 모달 추가 - 관련 타입 및 이벤트 정의 추가 - .gitignore에 sitemap-*.xml 추가 --- .gitignore | 3 +- apps/client/public/og/resume-interview.png | Bin 0 -> 150499 bytes apps/client/src/domains/resume/api/index.ts | 35 ++- .../resume/api/resumeBasedInterview.ts | 229 ++++++++++++++++++ .../components/resumeBasedInterviewForm.tsx | 225 +++++++++++++++++ .../resumeBasedInterviewHistory.tsx | 216 +++++++++++++++++ .../components/resumeSelectMenuNormal.tsx | 16 +- .../context/resumeBasedInterviewStore.tsx | 119 +++++++++ .../members/interviews/[interviewId].tsx | 4 +- apps/client/src/pages/resume/index.tsx | 1 + .../pages/resume/interview/[interviewId].tsx | 216 +++++++++++++++++ apps/client/src/utils/querykeys.ts | 24 +- packages/types/src/events/index.ts | 1 + .../types/src/events/resumeBasedInterview.ts | 14 ++ packages/types/src/interviews/index.ts | 1 + .../src/interviews/resumeBasedInterview.ts | 52 ++++ 16 files changed, 1144 insertions(+), 12 deletions(-) create mode 100644 apps/client/public/og/resume-interview.png create mode 100644 apps/client/src/domains/resume/api/resumeBasedInterview.ts create mode 100644 apps/client/src/domains/resume/components/resumeBasedInterviewForm.tsx create mode 100644 apps/client/src/domains/resume/components/resumeBasedInterviewHistory.tsx create mode 100644 apps/client/src/domains/resume/context/resumeBasedInterviewStore.tsx create mode 100644 apps/client/src/pages/resume/interview/[interviewId].tsx create mode 100644 packages/types/src/events/resumeBasedInterview.ts create mode 100644 packages/types/src/interviews/resumeBasedInterview.ts diff --git a/.gitignore b/.gitignore index 5d0d55fc..0ea1f643 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,5 @@ node_modules/ *.key *.crt robots.txt -sitemap.xml \ No newline at end of file +sitemap.xml +sitemap-*.xml diff --git a/apps/client/public/og/resume-interview.png b/apps/client/public/og/resume-interview.png new file mode 100644 index 0000000000000000000000000000000000000000..0c2c74938e3702223f5e48247751369500ac6688 GIT binary patch literal 150499 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%0Do`_xar$U!y=aS(u_(ms&y65!3n@g_Jq@ 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

  • T45GrG!kxJRef?{{<0mzd*79} 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%0AvHnjxzs8ge* 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 literal 0 HcmV?d00001 diff --git a/apps/client/src/domains/resume/api/index.ts b/apps/client/src/domains/resume/api/index.ts index 3ef35182..f4f37f93 100644 --- a/apps/client/src/domains/resume/api/index.ts +++ b/apps/client/src/domains/resume/api/index.ts @@ -3,7 +3,9 @@ import { ResumeEvaluationResult, ResumeFailed, ResumeOutput, - ResumePending + ResumePending, + ResumeEvaluationsResponse, + CamelCasedProperties } from "@kokomen/types"; import axios, { AxiosError, AxiosRequestConfig, AxiosResponse } from "axios"; import { delay, exponentialDelay } from "@kokomen/utils"; @@ -147,9 +149,38 @@ function getResumeEvaluationResult( .then((res) => res.data) .then(mapToCamelCase); } + +function getResumeEvaluations( + page: number = 0, + size: number = 20, + context?: GetServerSidePropsContext +): Promise> { + const instance = axios.create({ + baseURL: process.env.NEXT_PUBLIC_API_BASE_URL + "/resumes/evaluations", + withCredentials: true + }); + + return instance + .get>("", { + params: { + page, + size + }, + headers: context + ? { + Cookie: context.req.headers.cookie + } + : undefined + }) + .then((res) => res.data) + .then(mapToCamelCase); +} + export { submitResumeEvaluation, getResumeEvaluationState, - getResumeEvaluationResult + getResumeEvaluationResult, + getResumeEvaluations }; export * from "./archive"; +export * from "./resumeBasedInterview"; diff --git a/apps/client/src/domains/resume/api/resumeBasedInterview.ts b/apps/client/src/domains/resume/api/resumeBasedInterview.ts new file mode 100644 index 00000000..70cfd94f --- /dev/null +++ b/apps/client/src/domains/resume/api/resumeBasedInterview.ts @@ -0,0 +1,229 @@ +import { mapToCamelCase } from "@/utils/convertConvention"; +import { + ResumeInterviewPending, + ResumeInterviewFailed, + ResumeBasedInterviewQuestion, + ResumeInterviewSuccess, + Interview, + InterviewMode, + ResumeBasedInterviewGenerationsResponse, + CamelCasedProperties +} from "@kokomen/types"; +import axios, { AxiosError, AxiosRequestConfig, AxiosResponse } from "axios"; +import { delay, exponentialDelay } from "@kokomen/utils"; +import { GetServerSidePropsContext } from "next"; + +// 요청별 재시도 상태를 관리하는 Map +const retryStateMap = new Map(); + +// 요청 식별자 생성 함수 +const createRequestId = (config: AxiosRequestConfig): string => { + const { method, url, data } = config; + return `${method}:${url}:${JSON.stringify(data || {})}`; +}; + +// 재시도 상태 관리 함수들 +const getRetryCount = (requestId: string): number => { + return retryStateMap.get(requestId) || 0; +}; + +const incrementRetryCount = (requestId: string): number => { + const currentCount = getRetryCount(requestId); + const newCount = currentCount + 1; + retryStateMap.set(requestId, newCount); + return newCount; +}; + +const resetRetryCount = (requestId: string): void => { + retryStateMap.delete(requestId); +}; + +// 이력서 제출 부분 +const resumeBasedInterviewServerInstance = axios.create({ + baseURL: process.env.NEXT_PUBLIC_API_BASE_URL + "/interviews/resume-based", + withCredentials: true +}); +resumeBasedInterviewServerInstance.interceptors.response.use( + (response: AxiosResponse) => { + // 성공 시 해당 요청의 retry 상태 정리 + const requestId = createRequestId(response.config); + resetRetryCount(requestId); + return response; + }, + + // 에러 응답 처리 + async (error: AxiosError) => { + const requestId = createRequestId(error.config as AxiosRequestConfig); + const retryCount = incrementRetryCount(requestId); + const maxRetries = 3; + + if (retryCount >= maxRetries) { + resetRetryCount(requestId); + return Promise.reject(error); + } + + await exponentialDelay(retryCount); + return resumeBasedInterviewServerInstance.request( + error.config as AxiosRequestConfig + ); + } +); + +function generateResumeBasedInterviewQuestion(data: FormData) { + return resumeBasedInterviewServerInstance + .post<{ resume_based_interview_result_id: number }>( + "/questions/generate", + data + ) + .then((res) => res.data) + .then(mapToCamelCase); +} + +const resumeBasedInterviewQuestionPollingServerInstance = axios.create({ + baseURL: process.env.NEXT_PUBLIC_API_BASE_URL + "/interviews/resume-based", + withCredentials: true +}); + +// 폴링에 대한 요청 완료시 +const onFullFilledPolling = async ( + response: AxiosResponse< + ResumeInterviewSuccess | ResumeInterviewPending | ResumeInterviewFailed + > +) => { + const requestId = createRequestId(response.config); + console.log(response.data); + + if (response.data.state === "COMPLETED") { + resetRetryCount(requestId); + return response; + } + + if (response.data.state === "FAILED") + return Promise.reject("이력서 평가 중 오류가 발생했어요"); + + const retryCount = incrementRetryCount(requestId); + const maxRetries = 50; + + if (retryCount >= maxRetries) { + resetRetryCount(requestId); + return Promise.reject("서버가 응답하지 않습니다."); + } + + await delay(1000); + return resumeBasedInterviewQuestionPollingServerInstance.request( + response.config + ); +}; + +// 폴링 에러 처리 함수 +const onRejectedPolling = async (error: AxiosError) => { + const requestId = createRequestId(error.config as AxiosRequestConfig); + const retryCount = incrementRetryCount(requestId); + const maxRetries = 3; + + if (retryCount >= maxRetries) { + resetRetryCount(requestId); + return Promise.reject(error); + } + + await exponentialDelay(retryCount); + return resumeBasedInterviewQuestionPollingServerInstance.request( + error.config as AxiosRequestConfig + ); +}; + +// 인터뷰 면접 답변 폴링을 위한 서버 인스턴스 +resumeBasedInterviewQuestionPollingServerInstance.interceptors.response.use( + onFullFilledPolling, + onRejectedPolling +); + +function checkResumeBasedInterviewQuestion( + resumeBasedInterviewQuestionId: number +) { + return resumeBasedInterviewQuestionPollingServerInstance + .get(`/${resumeBasedInterviewQuestionId}/check`) + .then((res) => res.data) + .then(mapToCamelCase); +} + +const resumeBasedInterviewResultServerInstance = axios.create({ + baseURL: process.env.NEXT_PUBLIC_API_BASE_URL + "/interviews/resume-based", + withCredentials: true +}); + +function getResumeInterviewResult( + resumeBasedInterviewResultId: number, + context: GetServerSidePropsContext +) { + return resumeBasedInterviewResultServerInstance + .get(`/${resumeBasedInterviewResultId}`, { + headers: { + Cookie: context.req.headers.cookie + } + }) + .then((res) => res.data) + .then(mapToCamelCase); +} + +function getResumeBasedInterviewGenerations( + page: number = 0, + context?: GetServerSidePropsContext +): Promise> { + const instance = axios.create({ + baseURL: process.env.NEXT_PUBLIC_API_BASE_URL + "/interviews/resume-based", + withCredentials: true + }); + + return instance + .get>( + "/questions/generations", + { + params: { + page + }, + headers: context + ? { + Cookie: context.req.headers.cookie + } + : undefined + } + ) + .then((res) => res.data); +} + +const resumeBasedInterviewCreateInstance = axios.create({ + baseURL: process.env.NEXT_PUBLIC_API_BASE_URL, + withCredentials: true +}); + +function createResumeBasedInterview({ + resumeBasedInterviewResultId, + generatedQuestionId, + maxQuestionCount, + mode +}: { + resumeBasedInterviewResultId: number; + generatedQuestionId: number; + maxQuestionCount: number; + mode: InterviewMode; +}): Promise { + return resumeBasedInterviewCreateInstance + .post( + `/interviews/resume-based/${resumeBasedInterviewResultId}`, + { + generated_question_id: generatedQuestionId, + max_question_count: maxQuestionCount, + mode + } + ) + .then((res) => res.data); +} + +export { + generateResumeBasedInterviewQuestion, + checkResumeBasedInterviewQuestion, + getResumeInterviewResult, + createResumeBasedInterview, + getResumeBasedInterviewGenerations +}; diff --git a/apps/client/src/domains/resume/components/resumeBasedInterviewForm.tsx b/apps/client/src/domains/resume/components/resumeBasedInterviewForm.tsx new file mode 100644 index 00000000..51958b96 --- /dev/null +++ b/apps/client/src/domains/resume/components/resumeBasedInterviewForm.tsx @@ -0,0 +1,225 @@ +import { generateResumeBasedInterviewQuestion } from "@/domains/resume/api"; +import { ArchiveButton } from "@/domains/resume/components/resumeArchiveButton"; +import useExtendedRouter from "@/hooks/useExtendedRouter"; +import { withApiErrorCapture } from "@/utils/error"; +import { standardSchemaResolver } from "@hookform/resolvers/standard-schema"; +import { generateFormData } from "@kokomen/utils"; +import { CamelCasedProperties, UserInfo } from "@kokomen/types"; +import { Button, FileField, useToast } from "@kokomen/ui"; +import { useMutation } from "@tanstack/react-query"; +import { isAxiosError } from "axios"; +import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import z from "zod"; +import { publishResumeBasedInterviewEvent } from "@/domains/resume/utils/resumeInterviewEventEmitter"; + +const jobCareers = ["0-1년", "1-3년", "3-5년", "5-10년", "10년 이상"]; + +// SSR 환경에서 FileList가 정의되지 않을 수 있으므로 custom 검증 사용 +const fileListSchema: z.ZodTypeAny = + typeof FileList !== "undefined" + ? z.instanceof(FileList) + : z.custom((val): val is FileList => { + return typeof FileList !== "undefined" && val instanceof FileList; + }); + +const resumeBasedInterviewFormFields = z + .object({ + // FileList를 직접 받거나, 이미 업로드된 경우를 위해 optional 처리 + resume: fileListSchema.optional(), + resume_id: z.string().optional(), + + portfolio: fileListSchema.optional(), + portfolio_id: z.string().optional(), + + job_career: z.enum(jobCareers as [string, ...string[]]).default("0-1년") + }) + // 1. 이력서 검증: ID가 있거나, 파일이 선택되었거나 + .refine((data) => data.resume_id || (data.resume && data.resume.length > 0), { + message: "이력서를 선택해주세요", + path: ["resume"] // 에러 메시지를 표시할 필드 위치 + }); +type ResumeBasedInterviewFormFields = z.infer< + typeof resumeBasedInterviewFormFields +>; + +export default function ResumeBasedInterviewForm({ user }: { user: UserInfo }) { + const { toast } = useToast(); + const form = useForm({ + resolver: standardSchemaResolver(resumeBasedInterviewFormFields), + defaultValues: { + job_career: "0-1년" + } + }); + const [displayName, setDisplayName] = useState<{ + resume: string; + portfolio: string; + }>({ resume: "", portfolio: "" }); + + useEffect(() => { + const resume = form.getValues("resume"); + const portfolio = form.getValues("portfolio"); + if (resume instanceof FileList && resume.length > 0) { + setDisplayName({ ...displayName, resume: "" }); + form.setValue("resume_id", ""); + } + if (portfolio instanceof FileList && portfolio.length > 0) { + setDisplayName({ ...displayName, portfolio: "" }); + form.setValue("portfolio_id", ""); + } + }, [form.watch("resume_id"), form.watch("portfolio_id")]); + + const router = useExtendedRouter(); + const mutation = useMutation< + CamelCasedProperties<{ resume_based_interview_result_id: number }>, + Error, + FormData + >({ + mutationFn: generateResumeBasedInterviewQuestion, + onSuccess: (data) => { + publishResumeBasedInterviewEvent("resumeBasedInterview:submitted", { + resume_based_interview_result_id: data.resumeBasedInterviewResultId + }); + toast({ + title: "이력서 분석 중입니다. 잠시 후 평가 결과를 알려드려요", + variant: "info" + }); + router.replace({ + pathname: "/resume" + }); + }, + onError: withApiErrorCapture((error) => { + if (isAxiosError(error) && error.response?.status === 401) { + router.navigateToLogin(); + return; + } else { + toast({ + title: "이력서 분석 실패", + description: + "이력서 분석 중 오류가 발생했어요. 잠시 후 다시 시도해주세요", + variant: "error" + }); + } + }) + }); + const [isParsing, setIsParsing] = useState(false); + + async function onSubmit(data: ResumeBasedInterviewFormFields) { + try { + setIsParsing(true); + const formData = generateFormData(data); + mutation.mutate(formData); + } catch (error) { + console.log(error); + } finally { + setIsParsing(false); + } + } + const onclickArchiveButton = (data: { + resume_id?: string; + resume_name?: string; + portfolio_id?: string; + portfolio_name?: string; + }) => { + if (data.resume_id) { + form.setValue("resume_id", data.resume_id); + setDisplayName({ + ...displayName, + resume: data.resume_name || "" + }); + } + if (data.portfolio_id) { + form.setValue("portfolio_id", data.portfolio_id); + setDisplayName({ + ...displayName, + portfolio: data.portfolio_name || "" + }); + } + }; + + const isPending = isParsing || mutation.isPending; + + return ( +
    +
    +
    +

    이력서 평가

    +

    + 이력서와 포트폴리오를 업로드하고, 지원하려는 직무 정보를 + 입력해주세요. +

    +
    + +
    +
    +
    + + +
    + +
    + + +
    + +
    + +
    + {jobCareers.map((career) => ( + + ))} +
    +
    +
    + +
    +
    +
    + ); +} diff --git a/apps/client/src/domains/resume/components/resumeBasedInterviewHistory.tsx b/apps/client/src/domains/resume/components/resumeBasedInterviewHistory.tsx new file mode 100644 index 00000000..bf031472 --- /dev/null +++ b/apps/client/src/domains/resume/components/resumeBasedInterviewHistory.tsx @@ -0,0 +1,216 @@ +import { getResumeBasedInterviewGenerations } from "@/domains/resume/api/resumeBasedInterview"; +import { ResumeBasedInterviewGenerationsResponse } from "@kokomen/types"; +import { CamelCasedProperties } from "@/utils/convertConvention"; +import { resumeBasedInterviewKeys } from "@/utils/querykeys"; +import { useQuery } from "@tanstack/react-query"; +import { useRouter } from "next/router"; +import { + Calendar, + FileText, + ExternalLink, + CheckCircle, + XCircle, + Clock +} from "lucide-react"; +import Link from "next/link"; +import PaginationButtons from "@/shared/paginationButtons"; +import { formatDate } from "@/utils/date"; + +export default function ResumeBasedInterviewHistory() { + const router = useRouter(); + const page = Number(router.query.page) || 0; + + const { data, isLoading, isError } = useQuery< + CamelCasedProperties + >({ + queryKey: resumeBasedInterviewKeys.generations(page), + queryFn: () => getResumeBasedInterviewGenerations(page) + }); + + const getStateBadge = (state: string) => { + switch (state) { + case "COMPLETED": + return ( + + + 완료 + + ); + case "PENDING": + return ( + + + 진행중 + + ); + case "FAILED": + return ( + + + 실패 + + ); + default: + return null; + } + }; + + if (isLoading) { + return ( +
    +
    +

    + 이력서 기반 면접 질문 히스토리 +

    +

    + 생성된 이력서 기반 면접 질문들을 확인해보세요 +

    +
    +
    + {Array.from({ length: 5 }).map((_, index) => ( +
    +
    +
    +
    +
    + ))} +
    +
    + ); + } + + if (isError || !data) { + return ( +
    +
    +

    + 이력서 기반 면접 질문 히스토리 +

    +

    + 생성된 이력서 기반 면접 질문들을 확인해보세요 +

    +
    +
    +

    + 데이터를 불러오는 중 오류가 발생했습니다. +

    +
    +
    + ); + } + + const generations = data.data || []; + + return ( +
    + ); +} diff --git a/apps/client/src/domains/resume/components/resumeSelectMenuNormal.tsx b/apps/client/src/domains/resume/components/resumeSelectMenuNormal.tsx index 50be9f80..f397135b 100644 --- a/apps/client/src/domains/resume/components/resumeSelectMenuNormal.tsx +++ b/apps/client/src/domains/resume/components/resumeSelectMenuNormal.tsx @@ -1,6 +1,5 @@ import Link from "next/link"; import Image from "next/image"; -import { Tooltip } from "@kokomen/ui"; interface MenuItemProps { title: string; description: string; @@ -109,18 +108,21 @@ export default function ResumeSelectMenuNormal() { 체험해보기 - +
    - - 곧 출시돼요! 조금만 기다려주세요 :) - - + + 체험해보기 + +
    diff --git a/apps/client/src/domains/resume/context/resumeBasedInterviewStore.tsx b/apps/client/src/domains/resume/context/resumeBasedInterviewStore.tsx new file mode 100644 index 00000000..1b4789bb --- /dev/null +++ b/apps/client/src/domains/resume/context/resumeBasedInterviewStore.tsx @@ -0,0 +1,119 @@ +import { checkResumeBasedInterviewQuestion } from "@/domains/resume/api/resumeBasedInterview"; +import { useResumeBasedInterviewEvent } from "@/domains/resume/utils/resumeInterviewEventEmitter"; +import { RoundSpinner, Tooltip } from "@kokomen/ui"; +import { CheckIcon, X } from "lucide-react"; +import { AnimatePresence, motion } from "motion/react"; +import Link from "next/link"; +import React, { createContext, useState } from "react"; + +type ResumeBasedInterviewState = "IDLE" | "PENDING" | "COMPLETED" | "ERROR"; +interface IResumeBasedInterviewStore { + interviewState: ResumeBasedInterviewState; + interviewResultId: number | null; + // eslint-disable-next-line no-unused-vars + setInterviewResultId: (interviewResultId: number) => void; +} +const ResumeBasedInterviewStore = + createContext(null); + +export default function ResumeBasedInterviewStoreProvider({ + children +}: { + children: React.ReactNode; +}) { + const [interviewState, setInterviewState] = + useState("IDLE"); + const [interviewResultId, setInterviewResultId] = useState( + null + ); + + useResumeBasedInterviewEvent( + "resumeBasedInterview:submitted", + async (payload) => { + try { + setInterviewState("PENDING"); + setInterviewResultId(payload.resume_based_interview_result_id); + const response = await checkResumeBasedInterviewQuestion( + payload.resume_based_interview_result_id + ); + if (response.state === "COMPLETED") { + setInterviewState("COMPLETED"); + } else if (response.state === "FAILED") { + setInterviewState("ERROR"); + } + } catch (error) { + setInterviewState("ERROR"); + } + } + ); + + return ( + + + {interviewState === "PENDING" && ( + + + + 면접 질문 생성 중... + + + + + )} + {interviewState === "COMPLETED" && ( + { + setInterviewState("IDLE"); + setInterviewResultId(null); + }} + > + + + + 면접 질문 생성 완료 + + + + + + )} + {interviewState === "ERROR" && ( + + { + setInterviewState("IDLE"); + setInterviewResultId(null); + }} + > + + 면접 질문 생성 중
    오류가 발생했어요 +
    + +
    +
    + )} +
    + {children} +
    + ); +} diff --git a/apps/client/src/pages/members/interviews/[interviewId].tsx b/apps/client/src/pages/members/interviews/[interviewId].tsx index 24430614..ca198d57 100644 --- a/apps/client/src/pages/members/interviews/[interviewId].tsx +++ b/apps/client/src/pages/members/interviews/[interviewId].tsx @@ -173,7 +173,9 @@ export const getServerSideProps = async ( ]); if (interviewResult.status === "rejected") { - return { redirect: { destination: "/error", permanent: false } }; + // 크롤러가 인덱싱할 수 있도록 redirect 대신 notFound 반환 + // API가 인증 없이 접근 가능하도록 서버 측 수정이 필요할 수 있음 + return { notFound: true }; } const result = interviewResult.value; diff --git a/apps/client/src/pages/resume/index.tsx b/apps/client/src/pages/resume/index.tsx index 2b55a88a..accfa1bc 100644 --- a/apps/client/src/pages/resume/index.tsx +++ b/apps/client/src/pages/resume/index.tsx @@ -22,6 +22,7 @@ export default function ResumePage({ description="내 이력서는 채용 공고에 얼마나 적합할까? 지금 꼬꼬면에서 이력서와 포트폴리오가 채용 공고에 얼마나 적합한지 평가해보세요." image="/resume.png" robots="index, follow" + pathname="/resume" />
    diff --git a/apps/client/src/pages/resume/interview/[interviewId].tsx b/apps/client/src/pages/resume/interview/[interviewId].tsx new file mode 100644 index 00000000..fc6d0540 --- /dev/null +++ b/apps/client/src/pages/resume/interview/[interviewId].tsx @@ -0,0 +1,216 @@ +import Header from "@/shared/header"; +import { getUserInfo } from "@/domains/auth/api"; +import { UserInfo } from "@kokomen/types"; +import { + GetServerSidePropsContext, + GetServerSidePropsResult, + InferGetServerSidePropsType +} from "next"; +import { Footer } from "@/shared/footer"; +import { AxiosError } from "axios"; +import { SEO } from "@/shared/seo"; +import { getResumeInterviewResult } from "@/domains/resume/api/resumeBasedInterview"; +import { ResumeBasedInterviewQuestion } from "@kokomen/types"; +import { Button, useToast } from "@kokomen/ui"; +import { useRouter } from "next/router"; +import { useMutation } from "@tanstack/react-query"; +import { createResumeBasedInterview } from "@/domains/resume/api/resumeBasedInterview"; +import { InterviewMode } from "@kokomen/types"; +import { useState } from "react"; +import ResumeInterviewModeSelectModal from "@/domains/resume/components/resumeInterviewModeSelectModal"; +import { withApiErrorCapture } from "@/utils/error"; +import useExtendedRouter from "@/hooks/useExtendedRouter"; +import { MessageSquare } from "lucide-react"; + +export default function ResumeInterviewResultPage({ + userInfo, + questions, + interviewId +}: InferGetServerSidePropsType) { + const router = useRouter(); + const { toast } = useToast(); + const extendedRouter = useExtendedRouter(); + const [selectedQuestionId, setSelectedQuestionId] = useState( + null + ); + const [isModeModalOpen, setIsModeModalOpen] = useState(false); + + const createInterviewMutation = useMutation({ + mutationFn: ({ + generatedQuestionId, + mode + }: { + generatedQuestionId: number; + mode: InterviewMode; + }) => + createResumeBasedInterview({ + resumeBasedInterviewResultId: Number(interviewId), + generatedQuestionId, + maxQuestionCount: questions.length, + mode + }), + onSuccess: (data) => { + const mode = "cur_question" in data ? "TEXT" : "VOICE"; + router.push(`/interviews/${data.interview_id}?mode=${mode}`); + }, + onError: withApiErrorCapture((error) => { + if (error instanceof AxiosError && error.response?.status === 401) { + extendedRouter.navigateToLogin(); + return; + } + toast({ + title: "면접 생성 실패", + description: + "면접 생성 중 오류가 발생했어요. 잠시 후 다시 시도해주세요.", + variant: "error" + }); + }) + }); + + const handleStartInterview = (questionId: number): void => { + setSelectedQuestionId(questionId); + setIsModeModalOpen(true); + }; + + const handleSelectMode = (mode: InterviewMode): void => { + if (selectedQuestionId === null) return; + + createInterviewMutation.mutate({ + generatedQuestionId: selectedQuestionId, + mode + }); + }; + + return ( + <> + +
    +
    +
    +
    +
    +
    +

    + 생성된 면접 질문 +

    +

    + 이력서를 기반으로 생성된 면접 질문입니다. 질문을 선택하여 + 면접을 시작해보세요. +

    +
    + +
    + {questions.map((question, index) => ( +
    +
    +
    +
    + + {index + 1} + +

    + 질문 {index + 1} +

    +
    +

    + {question.question} +

    +
    + +
    +
    + ))} +
    +
    +
    +
    +
    +
    + + { + setIsModeModalOpen(false); + setSelectedQuestionId(null); + }} + onSelectMode={handleSelectMode} + /> + + ); +} + +export const getServerSideProps = async ( + context: GetServerSidePropsContext +): Promise< + GetServerSidePropsResult<{ + userInfo: UserInfo | null; + questions: ResumeBasedInterviewQuestion[]; + interviewId: string; + }> +> => { + const { interviewId } = context.params as { interviewId: string }; + const interviewIdNumber = parseInt(interviewId, 10); + + if (isNaN(interviewIdNumber)) { + return { + notFound: true + }; + } + + try { + const [userInfoResult, questionsResult] = await Promise.all([ + getUserInfo(context) + .then((res) => res.data) + .catch((error) => { + if (error instanceof AxiosError && error.response?.status === 401) { + return null; + } + throw error; + }), + getResumeInterviewResult(interviewIdNumber, context) + ]); + + return { + props: { + userInfo: userInfoResult, + questions: questionsResult as ResumeBasedInterviewQuestion[], + interviewId + } + }; + } catch (error) { + if (error instanceof AxiosError && error.response?.status === 401) { + return { + redirect: { + destination: "/login", + permanent: false + } + }; + } + if (error instanceof AxiosError) { + if (error.response?.status === 404 || error.response?.status === 403) { + return { + notFound: true + }; + } + } + throw error; + } +}; diff --git a/apps/client/src/utils/querykeys.ts b/apps/client/src/utils/querykeys.ts index dc0151d8..73bd49e8 100644 --- a/apps/client/src/utils/querykeys.ts +++ b/apps/client/src/utils/querykeys.ts @@ -109,6 +109,24 @@ const archiveKeys: QueryKeyFactory = { [...archiveKeys.all, "resumes", type ?? "ALL"] as const }; +type ResumeBasedInterviewMethods = { + generations: (page?: number) => QueryKey; +}; +const resumeBasedInterviewKeys: QueryKeyFactory = { + all: ["resumeBasedInterview"] as const, + generations: (page: number = 0): QueryKey => + [...resumeBasedInterviewKeys.all, "generations", page] as const +}; + +type ResumeEvaluationMethods = { + history: (page?: number, size?: number) => QueryKey; +}; +const resumeEvaluationKeys: QueryKeyFactory = { + all: ["resumeEvaluation"] as const, + history: (page: number = 0, size: number = 20): QueryKey => + [...resumeEvaluationKeys.all, "history", page, size] as const +}; + export { interviewHistoryKeys, interviewKeys, @@ -116,9 +134,13 @@ export { archiveKeys, purchaseKeys, recruitKeys, + resumeBasedInterviewKeys, + resumeEvaluationKeys, type InterviewHistoryParams, type InterviewParams, type MemberRankParams, type RecruitMethods, - type ArchiveMethods + type ArchiveMethods, + type ResumeBasedInterviewMethods, + type ResumeEvaluationMethods }; diff --git a/packages/types/src/events/index.ts b/packages/types/src/events/index.ts index 11786bb4..3bac9aab 100644 --- a/packages/types/src/events/index.ts +++ b/packages/types/src/events/index.ts @@ -1,2 +1,3 @@ export * from "./interview"; export * from "./report"; +export * from "./resumeBasedInterview"; diff --git a/packages/types/src/events/resumeBasedInterview.ts b/packages/types/src/events/resumeBasedInterview.ts new file mode 100644 index 00000000..f406ccfa --- /dev/null +++ b/packages/types/src/events/resumeBasedInterview.ts @@ -0,0 +1,14 @@ +interface ResumeBasedInterviewEventPayloads { + "resumeBasedInterview:submitted": { + resume_based_interview_result_id: number; + }; + "resumeBasedInterview:created": undefined; + "resumeBasedInterview:updated": undefined; + "resumeBasedInterview:error": { error: string }; +} + +type ResumeBasedInterviewEventType = keyof ResumeBasedInterviewEventPayloads; +export type { + ResumeBasedInterviewEventType, + ResumeBasedInterviewEventPayloads +}; diff --git a/packages/types/src/interviews/index.ts b/packages/types/src/interviews/index.ts index dddcc18f..7543f661 100644 --- a/packages/types/src/interviews/index.ts +++ b/packages/types/src/interviews/index.ts @@ -156,3 +156,4 @@ export type { AnswerScore, InterviewQuestion }; +export * from "./resumeBasedInterview"; diff --git a/packages/types/src/interviews/resumeBasedInterview.ts b/packages/types/src/interviews/resumeBasedInterview.ts new file mode 100644 index 00000000..fe90d490 --- /dev/null +++ b/packages/types/src/interviews/resumeBasedInterview.ts @@ -0,0 +1,52 @@ +import { InterviewMode } from "."; +import { Paginated } from "../utils"; + +type CreateResumeBasedInterview = { + generated_question_id: number; + max_question_count: number; + mode: InterviewMode; +}; + +type ResumeBasedInterviewQuestion = { + id: number; + question: string; +}; + +type ResumeInterviewPending = { + state: "PENDING"; +}; +type ResumeInterviewFailed = { + state: "FAILED"; +}; +type ResumeInterviewSuccess = { + state: "COMPLETED"; +}; + +type ResumeBasedInterviewGeneration = { + id: number; + job_career: string; + state: "PENDING" | "COMPLETED" | "FAILED"; + created_at: string; + resume: { + name: string; + url: string; + } | null; + portfolio: { + name: string; + url: string; + } | null; +}; + +type ResumeBasedInterviewGenerationsResponse = Paginated< + ResumeBasedInterviewGeneration[] +>; + +export type { + CreateResumeBasedInterview, + ResumeBasedInterviewQuestion, + ResumeInterviewPending, + ResumeInterviewFailed, + ResumeInterviewSuccess, + ResumeBasedInterviewGeneration, + ResumeBasedInterviewGenerationsResponse +}; From 048f04a829a783823233dcbe83f7269a0a672792 Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 20 Jan 2026 22:16:56 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20=EC=9D=B4=EB=A0=A5=EC=84=9C=20?= =?UTF-8?q?=EA=B8=B0=EB=B0=98=20=EB=A9=B4=EC=A0=91=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=ED=99=95=EC=9E=A5=20=EB=B0=8F=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 - 이력서 기반 면접 히스토리 컴포넌트 및 모드 선택 모달 구현 - 선택 섹션에 이력서 기반 면접 및 평가 결과 추가 - 이력서 평가 폼에서 FileList 검증 로직 개선 - 관련 타입 및 이벤트 정의 추가 --- .../dashboard/components/selectSection.tsx | 21 +- .../components/resumeEvaluationForm.tsx | 13 +- .../components/resumeEvaluationHistory.tsx | 209 ++++++++++++++++++ .../resumeInterviewModeSelectModal.tsx | 69 ++++++ .../utils/resumeInterviewEventEmitter.ts | 27 +++ apps/client/src/pages/_app.tsx | 7 +- .../src/pages/resume/interview/index.tsx | 59 +++++ packages/types/src/resume/index.ts | 22 +- 8 files changed, 421 insertions(+), 6 deletions(-) create mode 100644 apps/client/src/domains/resume/components/resumeEvaluationHistory.tsx create mode 100644 apps/client/src/domains/resume/components/resumeInterviewModeSelectModal.tsx create mode 100644 apps/client/src/domains/resume/utils/resumeInterviewEventEmitter.ts create mode 100644 apps/client/src/pages/resume/interview/index.tsx diff --git a/apps/client/src/domains/dashboard/components/selectSection.tsx b/apps/client/src/domains/dashboard/components/selectSection.tsx index 266f86fa..3cbc81f7 100644 --- a/apps/client/src/domains/dashboard/components/selectSection.tsx +++ b/apps/client/src/domains/dashboard/components/selectSection.tsx @@ -2,11 +2,18 @@ import { useState } from "react"; import InterviewHistory from "./interviewHistory"; import ChangeNickname from "@/domains/dashboard/components/changeNickname"; import Withdrawal from "@/domains/dashboard/components/withDrawl"; +import ResumeBasedInterviewHistory from "@/domains/resume/components/resumeBasedInterviewHistory"; +import ResumeEvaluationHistory from "@/domains/resume/components/resumeEvaluationHistory"; import { UserInfo } from "@kokomen/types"; import { Button } from "@kokomen/ui"; import { useRouter } from "next/router"; -type Section = "interview" | "changeNickname" | "withdrawal"; +type Section = + | "interview" + | "resumeBasedInterview" + | "resumeEvaluation" + | "changeNickname" + | "withdrawal"; interface SelectSectionProps { userInfo: UserInfo; @@ -16,6 +23,14 @@ const interviewSections: { label: string; value: Section }[] = [ { label: "면접 기록", value: "interview" + }, + { + label: "이력서 기반 면접 질문", + value: "resumeBasedInterview" + }, + { + label: "이력서 평가 결과", + value: "resumeEvaluation" } ]; @@ -121,6 +136,10 @@ function SelectedSection({ switch (section) { case "interview": return ; + case "resumeBasedInterview": + return ; + case "resumeEvaluation": + return ; case "changeNickname": return ; case "withdrawal": diff --git a/apps/client/src/domains/resume/components/resumeEvaluationForm.tsx b/apps/client/src/domains/resume/components/resumeEvaluationForm.tsx index 8bbca71c..bde47ad4 100644 --- a/apps/client/src/domains/resume/components/resumeEvaluationForm.tsx +++ b/apps/client/src/domains/resume/components/resumeEvaluationForm.tsx @@ -15,13 +15,22 @@ import { archiveKeys } from "@/utils/querykeys"; import { publishReportEvent } from "@/domains/resume/utils/reportEventEmitter"; const jobCareers = ["0-1년", "1-3년", "3-5년", "5-10년", "10년 이상"]; + +// SSR 환경에서 FileList가 정의되지 않을 수 있으므로 custom 검증 사용 +const fileListSchema: z.ZodTypeAny = + typeof FileList !== "undefined" + ? z.instanceof(FileList) + : z.custom((val): val is FileList => { + return typeof FileList !== "undefined" && val instanceof FileList; + }); + const resumeEvalFormFields = z .object({ // FileList를 직접 받거나, 이미 업로드된 경우를 위해 optional 처리 - resume: z.instanceof(FileList).optional(), + resume: fileListSchema.optional(), resume_id: z.string().optional(), - portfolio: z.instanceof(FileList).optional(), + portfolio: fileListSchema.optional(), portfolio_id: z.string().optional(), job_position: z.string().min(1, { message: "지원 직무를 입력해주세요" }), diff --git a/apps/client/src/domains/resume/components/resumeEvaluationHistory.tsx b/apps/client/src/domains/resume/components/resumeEvaluationHistory.tsx new file mode 100644 index 00000000..02d242ad --- /dev/null +++ b/apps/client/src/domains/resume/components/resumeEvaluationHistory.tsx @@ -0,0 +1,209 @@ +import { getResumeEvaluations } from "@/domains/resume/api"; +import { ResumeEvaluationsResponse } from "@kokomen/types"; +import { CamelCasedProperties } from "@/utils/convertConvention"; +import { resumeEvaluationKeys } from "@/utils/querykeys"; +import { useQuery } from "@tanstack/react-query"; +import { useRouter } from "next/router"; +import { + Calendar, + Briefcase, + TrendingUp, + CheckCircle, + XCircle, + Clock +} from "lucide-react"; +import Link from "next/link"; +import PaginationButtons from "@/shared/paginationButtons"; +import { formatDate } from "@/utils/date"; + +export default function ResumeEvaluationHistory() { + const router = useRouter(); + const page = Number(router.query.page) || 0; + const size = 20; + + const { data, isLoading, isError } = useQuery< + CamelCasedProperties + >({ + queryKey: resumeEvaluationKeys.history(page, size), + queryFn: () => getResumeEvaluations(page, size) + }); + + const getStateBadge = (state: string) => { + switch (state) { + case "COMPLETED": + return ( + + + 완료 + + ); + case "PENDING": + return ( + + + 진행중 + + ); + case "FAILED": + return ( + + + 실패 + + ); + default: + return null; + } + }; + + const getScoreColor = (score: number) => { + if (score >= 80) return "text-green-600"; + if (score >= 60) return "text-yellow-600"; + return "text-red-600"; + }; + + if (isLoading) { + return ( +
    +
    +

    + 이력서 평가 히스토리 +

    +

    + 이력서 평가 결과를 확인해보세요 +

    +
    +
    + {Array.from({ length: 5 }).map((_, index) => ( +
    +
    +
    +
    +
    + ))} +
    +
    + ); + } + + if (isError || !data) { + return ( +
    +
    +

    + 이력서 평가 히스토리 +

    +

    + 이력서 평가 결과를 확인해보세요 +

    +
    +
    +

    + 데이터를 불러오는 중 오류가 발생했습니다. +

    +
    +
    + ); + } + + const evaluations = data.evaluations || []; + + return ( +
    +
    +

    + 이력서 평가 히스토리 +

    +

    + 이력서 평가 결과를 확인해보세요 +

    +
    + + {evaluations.length === 0 ? ( +
    + +

    + 평가한 이력서가 없습니다 +

    +

    + 이력서를 업로드하여 평가를 받아보세요 +

    +
    + ) : ( +
    + {evaluations.map((evaluation) => ( +
    +
    +
    +
    +

    + 이력서 평가 +

    + {getStateBadge(evaluation.state)} +
    + +
    +
    + + {formatDate(evaluation.createdAt)} +
    +
    + + 직무: + {evaluation.jobPosition} +
    +
    + 연차: + {evaluation.jobCareer} +
    +
    + + {evaluation.state === "COMPLETED" && ( +
    + + + 총점: {evaluation.totalScore}점 + +
    + )} +
    + + {evaluation.state === "COMPLETED" && ( +
    + + 결과 보기 + +
    + )} +
    +
    + ))} + + {data.totalPages > 1 && ( + + )} +
    + )} +
    + ); +} + diff --git a/apps/client/src/domains/resume/components/resumeInterviewModeSelectModal.tsx b/apps/client/src/domains/resume/components/resumeInterviewModeSelectModal.tsx new file mode 100644 index 00000000..b03066f1 --- /dev/null +++ b/apps/client/src/domains/resume/components/resumeInterviewModeSelectModal.tsx @@ -0,0 +1,69 @@ +import { Modal } from "@kokomen/ui"; +import { InterviewMode } from "@kokomen/types"; +import { Mic, FileText } from "lucide-react"; + +interface ResumeInterviewModeSelectModalProps { + isOpen: boolean; + onClose: () => void; + // eslint-disable-next-line no-unused-vars + onSelectMode: (mode: InterviewMode) => void; +} + +export default function ResumeInterviewModeSelectModal({ + isOpen, + onClose, + onSelectMode +}: ResumeInterviewModeSelectModalProps) { + const handleSelectMode = (mode: InterviewMode) => { + onSelectMode(mode); + onClose(); + }; + + return ( + +
    +

    + 면접을 진행할 모드를 선택해주세요. +

    + +
    + + + +
    +
    +
    + ); +} diff --git a/apps/client/src/domains/resume/utils/resumeInterviewEventEmitter.ts b/apps/client/src/domains/resume/utils/resumeInterviewEventEmitter.ts new file mode 100644 index 00000000..4969979a --- /dev/null +++ b/apps/client/src/domains/resume/utils/resumeInterviewEventEmitter.ts @@ -0,0 +1,27 @@ +/* eslint-disable no-unused-vars */ +import { publishEvent, useSubscribeEvents } from "@/utils/eventEmitter"; +import { + ResumeBasedInterviewEventPayloads, + ResumeBasedInterviewEventType +} from "@kokomen/types"; +import { DependencyList } from "react"; +// 이벤트에 대서 콜백 함수 구독하는 훅 +export function useResumeBasedInterviewEvent< + K extends ResumeBasedInterviewEventType +>( + event: K, + handler: ResumeBasedInterviewEventPayloads[K] extends undefined + ? () => void + : (payload: ResumeBasedInterviewEventPayloads[K]) => void, + deps: DependencyList = [] +): void { + const eventEmitter = useSubscribeEvents( + [{ event, handler }], + [] + ); +} + +export const publishResumeBasedInterviewEvent = publishEvent< + ResumeBasedInterviewEventType, + ResumeBasedInterviewEventPayloads +>(); diff --git a/apps/client/src/pages/_app.tsx b/apps/client/src/pages/_app.tsx index 196c1434..1f359b82 100644 --- a/apps/client/src/pages/_app.tsx +++ b/apps/client/src/pages/_app.tsx @@ -7,6 +7,7 @@ import { ErrorBoundary } from "@sentry/nextjs"; import ErrorFallback from "@/shared/errorFallback"; import FeedbackButton from "@/shared/feedbackButton"; import ResumeStoreProvider from "@/domains/resume/context/resumeStore"; +import ResumeBasedInterviewStoreProvider from "@/domains/resume/context/resumeBasedInterviewStore"; const queryClient: QueryClient = new QueryClient(); @@ -17,8 +18,10 @@ export default function App({ Component, pageProps }: AppProps): JSX.Element { }> - - + + + + diff --git a/apps/client/src/pages/resume/interview/index.tsx b/apps/client/src/pages/resume/interview/index.tsx new file mode 100644 index 00000000..49f66ae9 --- /dev/null +++ b/apps/client/src/pages/resume/interview/index.tsx @@ -0,0 +1,59 @@ +import Header from "@/shared/header"; +import { getUserInfo } from "@/domains/auth/api"; +import { UserInfo } from "@kokomen/types"; +import { ErrorBoundary } from "@sentry/nextjs"; +import { + GetServerSidePropsContext, + GetServerSidePropsResult, + InferGetServerSidePropsType +} from "next"; +import { Footer } from "@/shared/footer"; +import { AxiosError } from "axios"; +import { SEO } from "@/shared/seo"; +import ResumeBasedInterviewForm from "@/domains/resume/components/resumeBasedInterviewForm"; + +export default function ResumeInterviewCreatePage({ + userInfo +}: InferGetServerSidePropsType) { + return ( + <> + +
    +
    +
    +
    + + + +
    +
    +
    +
    + + ); +} + +export const getServerSideProps = async ( + context: GetServerSidePropsContext +): Promise> => { + const userInfo = await getUserInfo(context) + .then((res) => res.data) + .catch((error) => { + if (error instanceof AxiosError && error.response?.status === 401) { + return null; + } + throw error; + }); + + return { + props: { + userInfo + } + }; +}; diff --git a/packages/types/src/resume/index.ts b/packages/types/src/resume/index.ts index 8d565c1c..1e8d0af8 100644 --- a/packages/types/src/resume/index.ts +++ b/packages/types/src/resume/index.ts @@ -77,6 +77,24 @@ type ResumeEvaluationResult = { job_career: string; result: ResumeOutput["result"]; }; + +type ResumeEvaluationHistoryItem = { + id: number; + state: "PENDING" | "COMPLETED" | "FAILED"; + job_position: string; + job_career: string; + total_score: number; + created_at: string; +}; + +type ResumeEvaluationsResponse = { + evaluations: ResumeEvaluationHistoryItem[]; + current_page: number; + total_resume_evaluation_count: number; + total_pages: number; + has_next: boolean; +}; + export type { ResumeInput, ResumeOutput, @@ -85,5 +103,7 @@ export type { ResumeInputWithArchivedFile, ResumeInputWithNewFile, ResumeFailed, - ResumeEvaluationResult + ResumeEvaluationResult, + ResumeEvaluationHistoryItem, + ResumeEvaluationsResponse }; From ac233db93de593d189644fa9ea83702fa4906408 Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Sat, 31 Jan 2026 12:32:23 +0900 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20=EC=95=84=EC=B9=B4=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=20=EB=AF=B8=EB=A6=AC=EB=B3=B4=EA=B8=B0=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EA=B4=80=EB=A0=A8?= =?UTF-8?q?=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 아카이브 미리보기 컴포넌트 및 PDF 뷰어 추가 - 선택 섹션에 아카이브 옵션 추가 - react-pdf 라이브러리 통합 및 PDF 파일 로드 기능 구현 - canvas 모듈에 대한 webpack 설정 추가 --- .pnp.cjs | 326 ++++++++++++++++++ apps/client/next.config.ts | 11 + apps/client/package.json | 1 + .../dashboard/components/selectSection.tsx | 28 ++ .../resume/components/archivePreview.tsx | 242 +++++++++++++ .../domains/resume/components/pdfViewer.tsx | 55 +++ yarn.lock | 298 +++++++++++++++- 7 files changed, 954 insertions(+), 7 deletions(-) create mode 100644 apps/client/src/domains/resume/components/archivePreview.tsx create mode 100644 apps/client/src/domains/resume/components/pdfViewer.tsx diff --git a/.pnp.cjs b/.pnp.cjs index 12c3aac7..19c2c56c 100755 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -8690,6 +8690,7 @@ const RAW_RUNTIME_STATE = ["react-chartjs-2", "virtual:a21e24cf4a793f04e2e07474217597c8b8491086897b7ceb58f7c959b6c65ef5decbff14fa97445a76a680e4e81febb25c198102b2ba038b85eb731f05365753#npm:5.3.0"],\ ["react-dom", "virtual:a21e24cf4a793f04e2e07474217597c8b8491086897b7ceb58f7c959b6c65ef5decbff14fa97445a76a680e4e81febb25c198102b2ba038b85eb731f05365753#npm:19.1.0"],\ ["react-hook-form", "virtual:a21e24cf4a793f04e2e07474217597c8b8491086897b7ceb58f7c959b6c65ef5decbff14fa97445a76a680e4e81febb25c198102b2ba038b85eb731f05365753#npm:7.59.0"],\ + ["react-pdf", "virtual:a21e24cf4a793f04e2e07474217597c8b8491086897b7ceb58f7c959b6c65ef5decbff14fa97445a76a680e4e81febb25c198102b2ba038b85eb731f05365753#npm:9.2.1"],\ ["tailwindcss", "npm:4.1.11"],\ ["three", "npm:0.177.0"],\ ["ts-node", "virtual:a21e24cf4a793f04e2e07474217597c8b8491086897b7ceb58f7c959b6c65ef5decbff14fa97445a76a680e4e81febb25c198102b2ba038b85eb731f05365753#npm:10.9.2"],\ @@ -18090,6 +18091,18 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["canvas", [\ + ["npm:3.2.1", {\ + "packageLocation": "./.yarn/unplugged/canvas-npm-3.2.1-b6952492b7/node_modules/canvas/",\ + "packageDependencies": [\ + ["canvas", "npm:3.2.1"],\ + ["node-addon-api", "npm:7.1.1"],\ + ["node-gyp", "npm:11.2.0"],\ + ["prebuild-install", "npm:7.1.3"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["chai", [\ ["npm:5.2.0", {\ "packageLocation": "./.yarn/cache/chai-npm-5.2.0-373e52d821-dfd1cb719c.zip/node_modules/chai/",\ @@ -18216,6 +18229,13 @@ const RAW_RUNTIME_STATE = }]\ ]],\ ["chownr", [\ + ["npm:1.1.4", {\ + "packageLocation": "./.yarn/cache/chownr-npm-1.1.4-5bd400ab08-ed57952a84.zip/node_modules/chownr/",\ + "packageDependencies": [\ + ["chownr", "npm:1.1.4"]\ + ],\ + "linkType": "HARD"\ + }],\ ["npm:3.0.0", {\ "packageLocation": "./.yarn/cache/chownr-npm-3.0.0-5275e85d25-43925b8770.zip/node_modules/chownr/",\ "packageDependencies": [\ @@ -19145,6 +19165,16 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["decompress-response", [\ + ["npm:6.0.0", {\ + "packageLocation": "./.yarn/cache/decompress-response-npm-6.0.0-359de2878c-bd89d23141.zip/node_modules/decompress-response/",\ + "packageDependencies": [\ + ["decompress-response", "npm:6.0.0"],\ + ["mimic-response", "npm:3.1.0"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["dedent", [\ ["npm:1.6.0", {\ "packageLocation": "./.yarn/cache/dedent-npm-1.6.0-2a2b4ba2b1-671b8f5e39.zip/node_modules/dedent/",\ @@ -19176,6 +19206,15 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["deep-extend", [\ + ["npm:0.6.0", {\ + "packageLocation": "./.yarn/cache/deep-extend-npm-0.6.0-e182924219-1c6b0abcdb.zip/node_modules/deep-extend/",\ + "packageDependencies": [\ + ["deep-extend", "npm:0.6.0"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["deep-is", [\ ["npm:0.1.4", {\ "packageLocation": "./.yarn/cache/deep-is-npm-0.1.4-88938b5a67-7f0ee496e0.zip/node_modules/deep-is/",\ @@ -19311,6 +19350,13 @@ const RAW_RUNTIME_STATE = ["detect-libc", "npm:2.0.4"]\ ],\ "linkType": "HARD"\ + }],\ + ["npm:2.1.2", {\ + "packageLocation": "./.yarn/cache/detect-libc-npm-2.1.2-d0c382b1e2-acc675c29a.zip/node_modules/detect-libc/",\ + "packageDependencies": [\ + ["detect-libc", "npm:2.1.2"]\ + ],\ + "linkType": "HARD"\ }]\ ]],\ ["detect-newline", [\ @@ -20614,6 +20660,15 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["expand-template", [\ + ["npm:2.0.3", {\ + "packageLocation": "./.yarn/cache/expand-template-npm-2.0.3-80de959306-1c9e7afe9a.zip/node_modules/expand-template/",\ + "packageDependencies": [\ + ["expand-template", "npm:2.0.3"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["expect", [\ ["npm:30.0.3", {\ "packageLocation": "./.yarn/cache/expect-npm-30.0.3-b2a8f9af08-6bb88a42d6.zip/node_modules/expect/",\ @@ -21292,6 +21347,15 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["fs-constants", [\ + ["npm:1.0.0", {\ + "packageLocation": "./.yarn/cache/fs-constants-npm-1.0.0-59576b2177-a0cde99085.zip/node_modules/fs-constants/",\ + "packageDependencies": [\ + ["fs-constants", "npm:1.0.0"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["fs-extra", [\ ["npm:10.1.0", {\ "packageLocation": "./.yarn/cache/fs-extra-npm-10.1.0-86573680ed-5f579466e7.zip/node_modules/fs-extra/",\ @@ -21493,6 +21557,15 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["github-from-package", [\ + ["npm:0.0.0", {\ + "packageLocation": "./.yarn/cache/github-from-package-npm-0.0.0-519f80c9a1-737ee3f52d.zip/node_modules/github-from-package/",\ + "packageDependencies": [\ + ["github-from-package", "npm:0.0.0"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["glob", [\ ["npm:10.4.5", {\ "packageLocation": "./.yarn/cache/glob-npm-10.4.5-8c63175f05-19a9759ea7.zip/node_modules/glob/",\ @@ -22131,6 +22204,15 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["ini", [\ + ["npm:1.3.8", {\ + "packageLocation": "./.yarn/cache/ini-npm-1.3.8-fb5040b4c0-ec93838d23.zip/node_modules/ini/",\ + "packageDependencies": [\ + ["ini", "npm:1.3.8"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["inquirer", [\ ["npm:6.5.2", {\ "packageLocation": "./.yarn/cache/inquirer-npm-6.5.2-4f6408c247-a5aa53a8f8.zip/node_modules/inquirer/",\ @@ -25391,6 +25473,15 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["make-cancellable-promise", [\ + ["npm:1.3.2", {\ + "packageLocation": "./.yarn/cache/make-cancellable-promise-npm-1.3.2-6612d27c4e-10aa0450c7.zip/node_modules/make-cancellable-promise/",\ + "packageDependencies": [\ + ["make-cancellable-promise", "npm:1.3.2"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["make-dir", [\ ["npm:3.1.0", {\ "packageLocation": "./.yarn/cache/make-dir-npm-3.1.0-d1d7505142-56aaafefc4.zip/node_modules/make-dir/",\ @@ -25418,6 +25509,15 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["make-event-props", [\ + ["npm:1.6.2", {\ + "packageLocation": "./.yarn/cache/make-event-props-npm-1.6.2-89d60d5202-ecf0b742e4.zip/node_modules/make-event-props/",\ + "packageDependencies": [\ + ["make-event-props", "npm:1.6.2"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["make-fetch-happen", [\ ["npm:14.0.3", {\ "packageLocation": "./.yarn/cache/make-fetch-happen-npm-14.0.3-23b30e8691-c40efb5e52.zip/node_modules/make-fetch-happen/",\ @@ -25536,6 +25636,26 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["merge-refs", [\ + ["npm:1.3.0", {\ + "packageLocation": "./.yarn/cache/merge-refs-npm-1.3.0-3b965c4c45-403d20d283.zip/node_modules/merge-refs/",\ + "packageDependencies": [\ + ["merge-refs", "npm:1.3.0"]\ + ],\ + "linkType": "SOFT"\ + }],\ + ["virtual:a4e997d1238027b6f64c1eb66438b0f71064cabb137a4a0d099c7a75ff9f332487bec2fb27637d58df006dcf5422d5deaee216de4f09141ad8bb94929b4c6a68#npm:1.3.0", {\ + "packageLocation": "./.yarn/__virtual__/merge-refs-virtual-d21ed373bc/0/cache/merge-refs-npm-1.3.0-3b965c4c45-403d20d283.zip/node_modules/merge-refs/",\ + "packageDependencies": [\ + ["@types/react", "npm:19.1.8"],\ + ["merge-refs", "virtual:a4e997d1238027b6f64c1eb66438b0f71064cabb137a4a0d099c7a75ff9f332487bec2fb27637d58df006dcf5422d5deaee216de4f09141ad8bb94929b4c6a68#npm:1.3.0"]\ + ],\ + "packagePeers": [\ + "@types/react"\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["merge-stream", [\ ["npm:2.0.0", {\ "packageLocation": "./.yarn/cache/merge-stream-npm-2.0.0-2ac83efea5-867fdbb30a.zip/node_modules/merge-stream/",\ @@ -25680,6 +25800,15 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["mimic-response", [\ + ["npm:3.1.0", {\ + "packageLocation": "./.yarn/cache/mimic-response-npm-3.1.0-a4a24b4e96-0d6f07ce6e.zip/node_modules/mimic-response/",\ + "packageDependencies": [\ + ["mimic-response", "npm:3.1.0"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["min-indent", [\ ["npm:1.0.1", {\ "packageLocation": "./.yarn/cache/min-indent-npm-1.0.1-77031f50e1-7e207bd5c2.zip/node_modules/min-indent/",\ @@ -25845,6 +25974,15 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["mkdirp-classic", [\ + ["npm:0.5.3", {\ + "packageLocation": "./.yarn/cache/mkdirp-classic-npm-0.5.3-3b5c991910-95371d831d.zip/node_modules/mkdirp-classic/",\ + "packageDependencies": [\ + ["mkdirp-classic", "npm:0.5.3"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["module-details-from-path", [\ ["npm:1.0.4", {\ "packageLocation": "./.yarn/cache/module-details-from-path-npm-1.0.4-c3d0545459-10863413e9.zip/node_modules/module-details-from-path/",\ @@ -26039,6 +26177,15 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["napi-build-utils", [\ + ["npm:2.0.0", {\ + "packageLocation": "./.yarn/cache/napi-build-utils-npm-2.0.0-95da9c2e4e-5833aaeb5c.zip/node_modules/napi-build-utils/",\ + "packageDependencies": [\ + ["napi-build-utils", "npm:2.0.0"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["napi-postinstall", [\ ["npm:0.2.5", {\ "packageLocation": "./.yarn/cache/napi-postinstall-npm-0.2.5-2d85d6ee0e-c4a1a8ca61.zip/node_modules/napi-postinstall/",\ @@ -26194,6 +26341,16 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["node-abi", [\ + ["npm:3.87.0", {\ + "packageLocation": "./.yarn/cache/node-abi-npm-3.87.0-502d02db75-41cfc361ed.zip/node_modules/node-abi/",\ + "packageDependencies": [\ + ["node-abi", "npm:3.87.0"],\ + ["semver", "npm:7.7.2"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["node-abort-controller", [\ ["npm:3.1.1", {\ "packageLocation": "./.yarn/cache/node-abort-controller-npm-3.1.1-e246ed42cd-f7ad0e7a8e.zip/node_modules/node-abort-controller/",\ @@ -26203,6 +26360,16 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["node-addon-api", [\ + ["npm:7.1.1", {\ + "packageLocation": "./.yarn/unplugged/node-addon-api-npm-7.1.1-bfb302df19/node_modules/node-addon-api/",\ + "packageDependencies": [\ + ["node-addon-api", "npm:7.1.1"],\ + ["node-gyp", "npm:11.2.0"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["node-emoji", [\ ["npm:1.11.0", {\ "packageLocation": "./.yarn/cache/node-emoji-npm-1.11.0-dd2f09050c-5dac6502db.zip/node_modules/node-emoji/",\ @@ -26812,6 +26979,15 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["path2d", [\ + ["npm:0.2.2", {\ + "packageLocation": "./.yarn/cache/path2d-npm-0.2.2-61baf92922-1bb76c7f27.zip/node_modules/path2d/",\ + "packageDependencies": [\ + ["path2d", "npm:0.2.2"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["pathe", [\ ["npm:2.0.3", {\ "packageLocation": "./.yarn/cache/pathe-npm-2.0.3-0924246ee0-c118dc5a8b.zip/node_modules/pathe/",\ @@ -26830,6 +27006,17 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["pdfjs-dist", [\ + ["npm:4.8.69", {\ + "packageLocation": "./.yarn/cache/pdfjs-dist-npm-4.8.69-789befba80-dc297f2a36.zip/node_modules/pdfjs-dist/",\ + "packageDependencies": [\ + ["canvas", "npm:3.2.1"],\ + ["path2d", "npm:0.2.2"],\ + ["pdfjs-dist", "npm:4.8.69"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["pend", [\ ["npm:1.2.0", {\ "packageLocation": "./.yarn/cache/pend-npm-1.2.0-7a13d93266-8a87e63f7a.zip/node_modules/pend/",\ @@ -27086,6 +27273,27 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["prebuild-install", [\ + ["npm:7.1.3", {\ + "packageLocation": "./.yarn/cache/prebuild-install-npm-7.1.3-8e79c3a0a2-25919a42b5.zip/node_modules/prebuild-install/",\ + "packageDependencies": [\ + ["detect-libc", "npm:2.1.2"],\ + ["expand-template", "npm:2.0.3"],\ + ["github-from-package", "npm:0.0.0"],\ + ["minimist", "npm:1.2.8"],\ + ["mkdirp-classic", "npm:0.5.3"],\ + ["napi-build-utils", "npm:2.0.0"],\ + ["node-abi", "npm:3.87.0"],\ + ["prebuild-install", "npm:7.1.3"],\ + ["pump", "npm:3.0.3"],\ + ["rc", "npm:1.2.8"],\ + ["simple-get", "npm:4.0.1"],\ + ["tar-fs", "npm:2.1.4"],\ + ["tunnel-agent", "npm:0.6.0"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["prelude-ls", [\ ["npm:1.2.1", {\ "packageLocation": "./.yarn/cache/prelude-ls-npm-1.2.1-3e4d272a55-b00d617431.zip/node_modules/prelude-ls/",\ @@ -27386,6 +27594,19 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["rc", [\ + ["npm:1.2.8", {\ + "packageLocation": "./.yarn/cache/rc-npm-1.2.8-d6768ac936-24a0765315.zip/node_modules/rc/",\ + "packageDependencies": [\ + ["deep-extend", "npm:0.6.0"],\ + ["ini", "npm:1.3.8"],\ + ["minimist", "npm:1.2.8"],\ + ["rc", "npm:1.2.8"],\ + ["strip-json-comments", "npm:2.0.1"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["react", [\ ["npm:19.1.0", {\ "packageLocation": "./.yarn/cache/react-npm-19.1.0-9804a7da5b-530fb9a622.zip/node_modules/react/",\ @@ -27564,6 +27785,40 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["react-pdf", [\ + ["npm:9.2.1", {\ + "packageLocation": "./.yarn/cache/react-pdf-npm-9.2.1-a56cdc884b-69b5456b39.zip/node_modules/react-pdf/",\ + "packageDependencies": [\ + ["react-pdf", "npm:9.2.1"]\ + ],\ + "linkType": "SOFT"\ + }],\ + ["virtual:a21e24cf4a793f04e2e07474217597c8b8491086897b7ceb58f7c959b6c65ef5decbff14fa97445a76a680e4e81febb25c198102b2ba038b85eb731f05365753#npm:9.2.1", {\ + "packageLocation": "./.yarn/__virtual__/react-pdf-virtual-a4e997d123/0/cache/react-pdf-npm-9.2.1-a56cdc884b-69b5456b39.zip/node_modules/react-pdf/",\ + "packageDependencies": [\ + ["@types/react", "npm:19.1.8"],\ + ["@types/react-dom", "virtual:a21e24cf4a793f04e2e07474217597c8b8491086897b7ceb58f7c959b6c65ef5decbff14fa97445a76a680e4e81febb25c198102b2ba038b85eb731f05365753#npm:19.1.6"],\ + ["clsx", "npm:2.1.1"],\ + ["dequal", "npm:2.0.3"],\ + ["make-cancellable-promise", "npm:1.3.2"],\ + ["make-event-props", "npm:1.6.2"],\ + ["merge-refs", "virtual:a4e997d1238027b6f64c1eb66438b0f71064cabb137a4a0d099c7a75ff9f332487bec2fb27637d58df006dcf5422d5deaee216de4f09141ad8bb94929b4c6a68#npm:1.3.0"],\ + ["pdfjs-dist", "npm:4.8.69"],\ + ["react", "npm:19.1.0"],\ + ["react-dom", "virtual:a21e24cf4a793f04e2e07474217597c8b8491086897b7ceb58f7c959b6c65ef5decbff14fa97445a76a680e4e81febb25c198102b2ba038b85eb731f05365753#npm:19.1.0"],\ + ["react-pdf", "virtual:a21e24cf4a793f04e2e07474217597c8b8491086897b7ceb58f7c959b6c65ef5decbff14fa97445a76a680e4e81febb25c198102b2ba038b85eb731f05365753#npm:9.2.1"],\ + ["tiny-invariant", "npm:1.3.3"],\ + ["warning", "npm:4.0.3"]\ + ],\ + "packagePeers": [\ + "@types/react-dom",\ + "@types/react",\ + "react-dom",\ + "react"\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["react-reconciler", [\ ["npm:0.31.0", {\ "packageLocation": "./.yarn/cache/react-reconciler-npm-0.31.0-8f5bda4868-97920e1866.zip/node_modules/react-reconciler/",\ @@ -28614,6 +28869,27 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["simple-concat", [\ + ["npm:1.0.1", {\ + "packageLocation": "./.yarn/cache/simple-concat-npm-1.0.1-48df70de29-62f7508e67.zip/node_modules/simple-concat/",\ + "packageDependencies": [\ + ["simple-concat", "npm:1.0.1"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ + ["simple-get", [\ + ["npm:4.0.1", {\ + "packageLocation": "./.yarn/cache/simple-get-npm-4.0.1-fa2a97645d-b0649a581d.zip/node_modules/simple-get/",\ + "packageDependencies": [\ + ["decompress-response", "npm:6.0.0"],\ + ["once", "npm:1.4.0"],\ + ["simple-concat", "npm:1.0.1"],\ + ["simple-get", "npm:4.0.1"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["simple-swizzle", [\ ["npm:0.2.2", {\ "packageLocation": "./.yarn/cache/simple-swizzle-npm-0.2.2-8dee37fad1-df5e4662a8.zip/node_modules/simple-swizzle/",\ @@ -29173,6 +29449,13 @@ const RAW_RUNTIME_STATE = }]\ ]],\ ["strip-json-comments", [\ + ["npm:2.0.1", {\ + "packageLocation": "./.yarn/cache/strip-json-comments-npm-2.0.1-e7883b2d04-b509231cbd.zip/node_modules/strip-json-comments/",\ + "packageDependencies": [\ + ["strip-json-comments", "npm:2.0.1"]\ + ],\ + "linkType": "HARD"\ + }],\ ["npm:3.1.1", {\ "packageLocation": "./.yarn/cache/strip-json-comments-npm-3.1.1-dcb2324823-9681a6257b.zip/node_modules/strip-json-comments/",\ "packageDependencies": [\ @@ -29449,6 +29732,17 @@ const RAW_RUNTIME_STATE = }]\ ]],\ ["tar-fs", [\ + ["npm:2.1.4", {\ + "packageLocation": "./.yarn/cache/tar-fs-npm-2.1.4-90a454735f-decb25acdc.zip/node_modules/tar-fs/",\ + "packageDependencies": [\ + ["chownr", "npm:1.1.4"],\ + ["mkdirp-classic", "npm:0.5.3"],\ + ["pump", "npm:3.0.3"],\ + ["tar-fs", "npm:2.1.4"],\ + ["tar-stream", "npm:2.2.0"]\ + ],\ + "linkType": "HARD"\ + }],\ ["npm:3.1.0", {\ "packageLocation": "./.yarn/cache/tar-fs-npm-3.1.0-e568911671-7603096775.zip/node_modules/tar-fs/",\ "packageDependencies": [\ @@ -29462,6 +29756,18 @@ const RAW_RUNTIME_STATE = }]\ ]],\ ["tar-stream", [\ + ["npm:2.2.0", {\ + "packageLocation": "./.yarn/cache/tar-stream-npm-2.2.0-884c79b510-2f4c910b3e.zip/node_modules/tar-stream/",\ + "packageDependencies": [\ + ["bl", "npm:4.1.0"],\ + ["end-of-stream", "npm:1.4.5"],\ + ["fs-constants", "npm:1.0.0"],\ + ["inherits", "npm:2.0.4"],\ + ["readable-stream", "npm:3.6.2"],\ + ["tar-stream", "npm:2.2.0"]\ + ],\ + "linkType": "HARD"\ + }],\ ["npm:3.1.7", {\ "packageLocation": "./.yarn/cache/tar-stream-npm-3.1.7-c34f9aa00f-a09199d21f.zip/node_modules/tar-stream/",\ "packageDependencies": [\ @@ -30277,6 +30583,16 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["tunnel-agent", [\ + ["npm:0.6.0", {\ + "packageLocation": "./.yarn/cache/tunnel-agent-npm-0.6.0-64345ab7eb-4c7a1b813e.zip/node_modules/tunnel-agent/",\ + "packageDependencies": [\ + ["safe-buffer", "npm:5.2.1"],\ + ["tunnel-agent", "npm:0.6.0"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["tunnel-rat", [\ ["npm:0.1.2", {\ "packageLocation": "./.yarn/cache/tunnel-rat-npm-0.1.2-69bf8f367e-93cd50c7c9.zip/node_modules/tunnel-rat/",\ @@ -31428,6 +31744,16 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["warning", [\ + ["npm:4.0.3", {\ + "packageLocation": "./.yarn/cache/warning-npm-4.0.3-291e921d6d-aebab44512.zip/node_modules/warning/",\ + "packageDependencies": [\ + ["loose-envify", "npm:1.4.0"],\ + ["warning", "npm:4.0.3"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["watchpack", [\ ["npm:2.4.4", {\ "packageLocation": "./.yarn/cache/watchpack-npm-2.4.4-01f92bffc4-6c0901f75c.zip/node_modules/watchpack/",\ diff --git a/apps/client/next.config.ts b/apps/client/next.config.ts index 12fc019b..421ad2f9 100644 --- a/apps/client/next.config.ts +++ b/apps/client/next.config.ts @@ -34,6 +34,17 @@ const nextConfig: NextConfig = { webpackBuildWorker: true, preloadEntriesOnStart: true, urlImports: ["https://cdn.jsdelivr.net/"] + }, + webpack: (config) => { + config.resolve.alias = { + ...config.resolve.alias, + canvas: false + }; + config.resolve.fallback = { + ...config.resolve.fallback, + canvas: false + }; + return config } }; diff --git a/apps/client/package.json b/apps/client/package.json index ec9b1be4..a64fdb6b 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -35,6 +35,7 @@ "react-chartjs-2": "^5.3.0", "react-dom": "^19.0.0", "react-hook-form": "^7.59.0", + "react-pdf": "^9.2.1", "zod": "^3.25.74" }, "devDependencies": { diff --git a/apps/client/src/domains/dashboard/components/selectSection.tsx b/apps/client/src/domains/dashboard/components/selectSection.tsx index 3cbc81f7..5f16ba44 100644 --- a/apps/client/src/domains/dashboard/components/selectSection.tsx +++ b/apps/client/src/domains/dashboard/components/selectSection.tsx @@ -4,6 +4,7 @@ import ChangeNickname from "@/domains/dashboard/components/changeNickname"; import Withdrawal from "@/domains/dashboard/components/withDrawl"; import ResumeBasedInterviewHistory from "@/domains/resume/components/resumeBasedInterviewHistory"; import ResumeEvaluationHistory from "@/domains/resume/components/resumeEvaluationHistory"; +import ArchivePreview from "@/domains/resume/components/archivePreview"; import { UserInfo } from "@kokomen/types"; import { Button } from "@kokomen/ui"; import { useRouter } from "next/router"; @@ -12,6 +13,7 @@ type Section = | "interview" | "resumeBasedInterview" | "resumeEvaluation" + | "archive" | "changeNickname" | "withdrawal"; @@ -34,6 +36,13 @@ const interviewSections: { label: string; value: Section }[] = [ } ]; +const archiveSections: { label: string; value: Section }[] = [ + { + label: "아카이브", + value: "archive" + } +]; + const userSections: { label: string; value: Section }[] = [ { label: "닉네임 변경", @@ -77,6 +86,23 @@ export default function SelectSection({ userInfo }: SelectSectionProps) { ))}
    +

    아카이브

    + {archiveSections.map((sec) => ( + + ))} +
    +

    유저 정보 관리

    @@ -140,6 +166,8 @@ function SelectedSection({ return ; case "resumeEvaluation": return ; + case "archive": + return ; case "changeNickname": return ; case "withdrawal": diff --git a/apps/client/src/domains/resume/components/archivePreview.tsx b/apps/client/src/domains/resume/components/archivePreview.tsx new file mode 100644 index 00000000..89ab4ac6 --- /dev/null +++ b/apps/client/src/domains/resume/components/archivePreview.tsx @@ -0,0 +1,242 @@ +"use client" + +import { getArchivedResumes } from "@/domains/resume/api"; +import { ArchivedResumeAndPortfolio, CamelCasedProperties } from "@kokomen/types"; +import { archiveKeys } from "@/utils/querykeys"; +import { useQuery } from "@tanstack/react-query"; +import { useState } from "react"; +import { Button, Modal } from "@kokomen/ui"; +import { FileText, Loader2 } from "lucide-react"; +import dynamic from "next/dynamic"; + +// eslint-disable-next-line @rushstack/typedef-var +const PdfViewer = dynamic( + () => import("../components/pdfViewer"), + { + ssr: false, + loading: () =>
    + +
    + } +); + + +type TabType = "RESUME" | "PORTFOLIO"; + + +export default function ArchivePreview() { + const [activeTab, setActiveTab] = useState("RESUME"); + const [selectedFile, setSelectedFile] = + useState | null>(null); + const [numPages, setNumPages] = useState(); + const [pageNumber, setPageNumber] = useState(1); + const [isModalOpen, setIsModalOpen] = useState(false); + + const { data, isLoading, isError } = useQuery({ + queryKey: archiveKeys.resumes("ALL"), + queryFn: () => getArchivedResumes("ALL"), + staleTime: 1000 * 60 * 60, + gcTime: 1000 * 60 * 5 + }); + + const resumes = data?.resumes || []; + const portfolios = data?.portfolios || []; + + const currentList = + activeTab === "RESUME" ? resumes : portfolios; + + const handleFileSelect = ( + file: CamelCasedProperties + ): void => { + setSelectedFile(file); + setPageNumber(1); + setNumPages(undefined); + setIsModalOpen(true); + }; + + const handleCloseModal = (): void => { + setIsModalOpen(false); + setSelectedFile(null); + setPageNumber(1); + setNumPages(undefined); + }; + + const handleDocumentLoadSuccess = ({ numPages }: { numPages: number }): void => { + console.log('numPages', numPages); + setNumPages(numPages); + setPageNumber(1); + }; + + const goToPrevPage = (): void => { + setPageNumber((prev) => Math.max(1, prev - 1)); + }; + + const goToNextPage = (): void => { + setPageNumber((prev) => Math.min(numPages || 0, prev + 1)); + }; + + + if (isLoading) { + return ( +
    +
    +

    + 아카이브 미리보기 +

    +

    + 아카이빙된 이력서와 포트폴리오를 미리보기할 수 있습니다 +

    +
    +
    + +
    +
    + ); + } + + if (isError) { + return ( +
    +
    +

    + 아카이브 미리보기 +

    +

    + 아카이빙된 이력서와 포트폴리오를 미리보기할 수 있습니다 +

    +
    +
    +

    + 데이터를 불러오는 중 오류가 발생했습니다. +

    +
    +
    + ); + } + + return ( +
    +
    +

    + 아카이브 미리보기 +

    +

    + 아카이빙된 이력서와 포트폴리오를 미리보기할 수 있습니다 +

    +
    + +
    + {/* 파일 목록 */} +
    + {/* 탭 */} +
    + + +
    + + {/* 파일 리스트 */} +
    + {currentList.length === 0 ? ( +
    + +

    + {activeTab === "RESUME" + ? "아카이빙된 이력서가 없습니다" + : "아카이빙된 포트폴리오가 없습니다"} +

    +
    + ) : ( + currentList.map((file) => ( + + )) + )} +
    +
    +
    + + {/* PDF 미리보기 모달 */} + {selectedFile && ( + +
    +

    + {new Date(selectedFile.createdAt).toLocaleDateString("ko-KR")} +

    +
    + +
    +
    + +
    + + + {pageNumber} / {numPages || "-"} + + +
    +
    + +
    +
    + )} +
    + ); +} diff --git a/apps/client/src/domains/resume/components/pdfViewer.tsx b/apps/client/src/domains/resume/components/pdfViewer.tsx new file mode 100644 index 00000000..82964bfd --- /dev/null +++ b/apps/client/src/domains/resume/components/pdfViewer.tsx @@ -0,0 +1,55 @@ +"use client" + +import { Document, Page, pdfjs } from "react-pdf"; +import { JSX } from "react"; +import "react-pdf/dist/Page/TextLayer.css"; +import "react-pdf/dist/Page/AnnotationLayer.css"; + + +// workerSrc 정의 하지 않으면 pdf 보여지지 않습니다. +pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`; +const options = { + cMapUrl: `https://unpkg.com/pdfjs-dist@${pdfjs.version}/cmaps/`, + standardFontDataUrl: `https://unpkg.com/pdfjs-dist@${pdfjs.version}/standard_fonts/`, + }; + +type PdfViewerProps = { + fileUrl: string; + pageNumber: number; + // eslint-disable-next-line no-unused-vars + onLoadSuccess: ({ numPages }: { numPages: number }) => void; +}; + +export default function PdfViewer({ + fileUrl, + pageNumber, + onLoadSuccess +}: PdfViewerProps): JSX.Element { + // const [isLoading, setIsLoading] = useState(true); + + return ( + + { + onLoadSuccess({ numPages }); + }} + error={ +
    +

    PDF를 불러올 수 없습니다.

    +

    + 파일이 손상되었거나 지원되지 않는 형식일 수 있습니다. +

    +
    + } + > + +
    + ); +} diff --git a/yarn.lock b/yarn.lock index 464e1cdf..eca99b9a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5035,6 +5035,7 @@ __metadata: react-chartjs-2: "npm:^5.3.0" react-dom: "npm:^19.0.0" react-hook-form: "npm:^7.59.0" + react-pdf: "npm:^9.2.1" tailwindcss: "npm:^4" three: "npm:^0.177.0" ts-node: "npm:^10.9.2" @@ -11341,7 +11342,7 @@ __metadata: languageName: node linkType: hard -"bl@npm:^4.1.0": +"bl@npm:^4.0.3, bl@npm:^4.1.0": version: 4.1.0 resolution: "bl@npm:4.1.0" dependencies: @@ -11619,6 +11620,17 @@ __metadata: languageName: node linkType: hard +"canvas@npm:^3.0.0-rc2": + version: 3.2.1 + resolution: "canvas@npm:3.2.1" + dependencies: + node-addon-api: "npm:^7.0.0" + node-gyp: "npm:latest" + prebuild-install: "npm:^7.1.3" + checksum: 10c0/c0fd572a8b28e075b40a42b523bdf05e985feaeb18b56085432bfb91a3b905af48f89ec73ed4e795de892cb13f7332ceb0c78cf84c64281c41c29995665b89c8 + languageName: node + linkType: hard + "chai@npm:^5.1.1": version: 5.2.0 resolution: "chai@npm:5.2.0" @@ -11741,6 +11753,13 @@ __metadata: languageName: node linkType: hard +"chownr@npm:^1.1.1": + version: 1.1.4 + resolution: "chownr@npm:1.1.4" + checksum: 10c0/ed57952a84cc0c802af900cf7136de643d3aba2eecb59d29344bc2f3f9bf703a301b9d84cdc71f82c3ffc9ccde831b0d92f5b45f91727d6c9da62f23aef9d9db + languageName: node + linkType: hard + "chownr@npm:^3.0.0": version: 3.0.0 resolution: "chownr@npm:3.0.0" @@ -11950,7 +11969,7 @@ __metadata: languageName: node linkType: hard -"clsx@npm:^2.1.1": +"clsx@npm:^2.0.0, clsx@npm:^2.1.1": version: 2.1.1 resolution: "clsx@npm:2.1.1" checksum: 10c0/c4c8eb865f8c82baab07e71bfa8897c73454881c4f99d6bc81585aecd7c441746c1399d08363dc096c550cceaf97bd4ce1e8854e1771e9998d9f94c4fe075839 @@ -12503,6 +12522,15 @@ __metadata: languageName: node linkType: hard +"decompress-response@npm:^6.0.0": + version: 6.0.0 + resolution: "decompress-response@npm:6.0.0" + dependencies: + mimic-response: "npm:^3.1.0" + checksum: 10c0/bd89d23141b96d80577e70c54fb226b2f40e74a6817652b80a116d7befb8758261ad073a8895648a29cc0a5947021ab66705cb542fa9c143c82022b27c5b175e + languageName: node + linkType: hard + "dedent@npm:^1.6.0": version: 1.6.0 resolution: "dedent@npm:1.6.0" @@ -12522,6 +12550,13 @@ __metadata: languageName: node linkType: hard +"deep-extend@npm:^0.6.0": + version: 0.6.0 + resolution: "deep-extend@npm:0.6.0" + checksum: 10c0/1c6b0abcdb901e13a44c7d699116d3d4279fdb261983122a3783e7273844d5f2537dc2e1c454a23fcf645917f93fbf8d07101c1d03c015a87faa662755212566 + languageName: node + linkType: hard + "deep-is@npm:^0.1.3": version: 0.1.4 resolution: "deep-is@npm:0.1.4" @@ -12629,6 +12664,13 @@ __metadata: languageName: node linkType: hard +"detect-libc@npm:^2.0.0": + version: 2.1.2 + resolution: "detect-libc@npm:2.1.2" + checksum: 10c0/acc675c29a5649fa1fb6e255f993b8ee829e510b6b56b0910666949c80c364738833417d0edb5f90e4e46be17228b0f2b66a010513984e18b15deeeac49369c4 + languageName: node + linkType: hard + "detect-libc@npm:^2.0.3, detect-libc@npm:^2.0.4": version: 2.0.4 resolution: "detect-libc@npm:2.0.4" @@ -12851,7 +12893,7 @@ __metadata: languageName: node linkType: hard -"end-of-stream@npm:^1.1.0": +"end-of-stream@npm:^1.1.0, end-of-stream@npm:^1.4.1": version: 1.4.5 resolution: "end-of-stream@npm:1.4.5" dependencies: @@ -13806,6 +13848,13 @@ __metadata: languageName: node linkType: hard +"expand-template@npm:^2.0.3": + version: 2.0.3 + resolution: "expand-template@npm:2.0.3" + checksum: 10c0/1c9e7afe9acadf9d373301d27f6a47b34e89b3391b1ef38b7471d381812537ef2457e620ae7f819d2642ce9c43b189b3583813ec395e2938319abe356a9b2f51 + languageName: node + linkType: hard + "expect-type@npm:^1.2.1": version: 1.2.2 resolution: "expect-type@npm:1.2.2" @@ -14390,6 +14439,13 @@ __metadata: languageName: node linkType: hard +"fs-constants@npm:^1.0.0": + version: 1.0.0 + resolution: "fs-constants@npm:1.0.0" + checksum: 10c0/a0cde99085f0872f4d244e83e03a46aa387b74f5a5af750896c6b05e9077fac00e9932fdf5aef84f2f16634cd473c63037d7a512576da7d5c2b9163d1909f3a8 + languageName: node + linkType: hard + "fs-extra@npm:^10.0.0": version: 10.1.0 resolution: "fs-extra@npm:10.1.0" @@ -14576,6 +14632,13 @@ __metadata: languageName: node linkType: hard +"github-from-package@npm:0.0.0": + version: 0.0.0 + resolution: "github-from-package@npm:0.0.0" + checksum: 10c0/737ee3f52d0a27e26332cde85b533c21fcdc0b09fb716c3f8e522cfaa9c600d4a631dec9fcde179ec9d47cca89017b7848ed4d6ae6b6b78f936c06825b1fcc12 + languageName: node + linkType: hard + "glob-parent@npm:^5.1.2, glob-parent@npm:~5.1.2": version: 5.1.2 resolution: "glob-parent@npm:5.1.2" @@ -15124,6 +15187,13 @@ __metadata: languageName: node linkType: hard +"ini@npm:~1.3.0": + version: 1.3.8 + resolution: "ini@npm:1.3.8" + checksum: 10c0/ec93838d2328b619532e4f1ff05df7909760b6f66d9c9e2ded11e5c1897d6f2f9980c54dd638f88654b00919ce31e827040631eab0a3969e4d1abefa0719516a + languageName: node + linkType: hard + "inquirer@npm:^6.3.1": version: 6.5.2 resolution: "inquirer@npm:6.5.2" @@ -17797,7 +17867,7 @@ __metadata: languageName: node linkType: hard -"loose-envify@npm:^1.4.0": +"loose-envify@npm:^1.0.0, loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" dependencies: @@ -17933,6 +18003,13 @@ __metadata: languageName: node linkType: hard +"make-cancellable-promise@npm:^1.3.1": + version: 1.3.2 + resolution: "make-cancellable-promise@npm:1.3.2" + checksum: 10c0/10aa0450c743dcf20b55414c433ca45926b775b22eb6d25fa386fc499a8f3fc64c70eb575d99bdd16667d300068f51702822c293bc4e72da7ff4f82d0ea48184 + languageName: node + linkType: hard + "make-dir@npm:^3.0.0": version: 3.1.0 resolution: "make-dir@npm:3.1.0" @@ -17958,6 +18035,13 @@ __metadata: languageName: node linkType: hard +"make-event-props@npm:^1.6.0": + version: 1.6.2 + resolution: "make-event-props@npm:1.6.2" + checksum: 10c0/ecf0b742e43a392c07e2267baca2397e750d38cc14ef3cb72ef8bfe4a8c8b0fd99a03a2eeab84a26c2b204f7c231da6af31fa26321fbfd413ded43ba1825e867 + languageName: node + linkType: hard + "make-fetch-happen@npm:^14.0.3": version: 14.0.3 resolution: "make-fetch-happen@npm:14.0.3" @@ -18060,6 +18144,18 @@ __metadata: languageName: node linkType: hard +"merge-refs@npm:^1.3.0": + version: 1.3.0 + resolution: "merge-refs@npm:1.3.0" + peerDependencies: + "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/403d20d283a595565a6bef813415df509dad12a5ad157f0ae04861b3aee4a3691971ccae7079e20497d9f367a478ad60e5b63a2ca9ffb2cc3d511284b49b4bd6 + languageName: node + linkType: hard + "merge-stream@npm:^2.0.0": version: 2.0.0 resolution: "merge-stream@npm:2.0.0" @@ -18178,6 +18274,13 @@ __metadata: languageName: node linkType: hard +"mimic-response@npm:^3.1.0": + version: 3.1.0 + resolution: "mimic-response@npm:3.1.0" + checksum: 10c0/0d6f07ce6e03e9e4445bee655202153bdb8a98d67ee8dc965ac140900d7a2688343e6b4c9a72cfc9ef2f7944dfd76eef4ab2482eb7b293a68b84916bac735362 + languageName: node + linkType: hard + "min-indent@npm:^1.0.0, min-indent@npm:^1.0.1": version: 1.0.1 resolution: "min-indent@npm:1.0.1" @@ -18221,7 +18324,7 @@ __metadata: languageName: node linkType: hard -"minimist@npm:^1.2.0, minimist@npm:^1.2.5, minimist@npm:^1.2.6, minimist@npm:^1.2.8": +"minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.5, minimist@npm:^1.2.6, minimist@npm:^1.2.8": version: 1.2.8 resolution: "minimist@npm:1.2.8" checksum: 10c0/19d3fcdca050087b84c2029841a093691a91259a47def2f18222f41e7645a0b7c44ef4b40e88a1e58a40c84d2ef0ee6047c55594d298146d0eb3f6b737c20ce6 @@ -18318,6 +18421,13 @@ __metadata: languageName: node linkType: hard +"mkdirp-classic@npm:^0.5.2, mkdirp-classic@npm:^0.5.3": + version: 0.5.3 + resolution: "mkdirp-classic@npm:0.5.3" + checksum: 10c0/95371d831d196960ddc3833cc6907e6b8f67ac5501a6582f47dfae5eb0f092e9f8ce88e0d83afcae95d6e2b61a01741ba03714eeafb6f7a6e9dcc158ac85b168 + languageName: node + linkType: hard + "mkdirp@npm:^0.5.3, mkdirp@npm:^0.5.6": version: 0.5.6 resolution: "mkdirp@npm:0.5.6" @@ -18500,6 +18610,13 @@ __metadata: languageName: node linkType: hard +"napi-build-utils@npm:^2.0.0": + version: 2.0.0 + resolution: "napi-build-utils@npm:2.0.0" + checksum: 10c0/5833aaeb5cc5c173da47a102efa4680a95842c13e0d9cc70428bd3ee8d96bb2172f8860d2811799b5daa5cbeda779933601492a2028a6a5351c6d0fcf6de83db + languageName: node + linkType: hard + "napi-postinstall@npm:^0.2.4": version: 0.2.5 resolution: "napi-postinstall@npm:0.2.5" @@ -18629,6 +18746,15 @@ __metadata: languageName: node linkType: hard +"node-abi@npm:^3.3.0": + version: 3.87.0 + resolution: "node-abi@npm:3.87.0" + dependencies: + semver: "npm:^7.3.5" + checksum: 10c0/41cfc361edd1b0711d412ca9e1a475180c5b897868bd5583df7ff73e30e6044cc7de307df36c2257203320f17fadf7e82dfdf5a9f6fd510a8578e3fe3ed67ebb + languageName: node + linkType: hard + "node-abort-controller@npm:^3.0.1, node-abort-controller@npm:^3.1.1": version: 3.1.1 resolution: "node-abort-controller@npm:3.1.1" @@ -18636,6 +18762,15 @@ __metadata: languageName: node linkType: hard +"node-addon-api@npm:^7.0.0": + version: 7.1.1 + resolution: "node-addon-api@npm:7.1.1" + dependencies: + node-gyp: "npm:latest" + checksum: 10c0/fb32a206276d608037fa1bcd7e9921e177fe992fc610d098aa3128baca3c0050fc1e014fa007e9b3874cf865ddb4f5bd9f43ccb7cbbbe4efaff6a83e920b17e9 + languageName: node + linkType: hard + "node-emoji@npm:1.11.0": version: 1.11.0 resolution: "node-emoji@npm:1.11.0" @@ -19167,6 +19302,13 @@ __metadata: languageName: node linkType: hard +"path2d@npm:^0.2.1": + version: 0.2.2 + resolution: "path2d@npm:0.2.2" + checksum: 10c0/1bb76c7f275d07f1bc7ca12171d828e91bf8a12596f0765a52e9d4d47fe1a428455dc1dd4c9002924a9bc554f6ac25e09a6c22eaecf32e5e33fba2985b5168f8 + languageName: node + linkType: hard + "path@npm:^0.12.7": version: 0.12.7 resolution: "path@npm:0.12.7" @@ -19191,6 +19333,21 @@ __metadata: languageName: node linkType: hard +"pdfjs-dist@npm:4.8.69": + version: 4.8.69 + resolution: "pdfjs-dist@npm:4.8.69" + dependencies: + canvas: "npm:^3.0.0-rc2" + path2d: "npm:^0.2.1" + dependenciesMeta: + canvas: + optional: true + path2d: + optional: true + checksum: 10c0/dc297f2a36aa36834a2892cb78c3cafc7ac01753a2e7c4316a1f6e8c1d337a52a3bfbf7fdff7aaba615893b53f2d06a0efc2176525592b4d7b51021279c101be + languageName: node + linkType: hard + "pend@npm:~1.2.0": version: 1.2.0 resolution: "pend@npm:1.2.0" @@ -19399,6 +19556,28 @@ __metadata: languageName: node linkType: hard +"prebuild-install@npm:^7.1.3": + version: 7.1.3 + resolution: "prebuild-install@npm:7.1.3" + dependencies: + detect-libc: "npm:^2.0.0" + expand-template: "npm:^2.0.3" + github-from-package: "npm:0.0.0" + minimist: "npm:^1.2.3" + mkdirp-classic: "npm:^0.5.3" + napi-build-utils: "npm:^2.0.0" + node-abi: "npm:^3.3.0" + pump: "npm:^3.0.0" + rc: "npm:^1.2.7" + simple-get: "npm:^4.0.0" + tar-fs: "npm:^2.0.0" + tunnel-agent: "npm:^0.6.0" + bin: + prebuild-install: bin.js + checksum: 10c0/25919a42b52734606a4036ab492d37cfe8b601273d8dfb1fa3c84e141a0a475e7bad3ab848c741d2f810cef892fcf6059b8c7fe5b29f98d30e0c29ad009bedff + languageName: node + linkType: hard + "prelude-ls@npm:^1.2.1": version: 1.2.1 resolution: "prelude-ls@npm:1.2.1" @@ -19668,6 +19847,20 @@ __metadata: languageName: node linkType: hard +"rc@npm:^1.2.7": + version: 1.2.8 + resolution: "rc@npm:1.2.8" + dependencies: + deep-extend: "npm:^0.6.0" + ini: "npm:~1.3.0" + minimist: "npm:^1.2.0" + strip-json-comments: "npm:~2.0.1" + bin: + rc: ./cli.js + checksum: 10c0/24a07653150f0d9ac7168e52943cc3cb4b7a22c0e43c7dff3219977c2fdca5a2760a304a029c20811a0e79d351f57d46c9bde216193a0f73978496afc2b85b15 + languageName: node + linkType: hard + "react-chartjs-2@npm:^5.3.0": version: 5.3.0 resolution: "react-chartjs-2@npm:5.3.0" @@ -19753,6 +19946,29 @@ __metadata: languageName: node linkType: hard +"react-pdf@npm:^9.2.1": + version: 9.2.1 + resolution: "react-pdf@npm:9.2.1" + dependencies: + clsx: "npm:^2.0.0" + dequal: "npm:^2.0.3" + make-cancellable-promise: "npm:^1.3.1" + make-event-props: "npm:^1.6.0" + merge-refs: "npm:^1.3.0" + pdfjs-dist: "npm:4.8.69" + tiny-invariant: "npm:^1.0.0" + warning: "npm:^4.0.0" + peerDependencies: + "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/69b5456b3941ea08f03319a94b155db782232dee4b3e03513c4a4c10cc3d81d129fc3284136990b51d5dcf766192abc64d71e1d258ca7e0eb4e6592343fea6a4 + languageName: node + linkType: hard + "react-reconciler@npm:^0.31.0": version: 0.31.0 resolution: "react-reconciler@npm:0.31.0" @@ -19803,7 +20019,7 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^3.0.2, readable-stream@npm:^3.4.0": +"readable-stream@npm:^3.0.2, readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0": version: 3.6.2 resolution: "readable-stream@npm:3.6.2" dependencies: @@ -20911,6 +21127,24 @@ __metadata: languageName: node linkType: hard +"simple-concat@npm:^1.0.0": + version: 1.0.1 + resolution: "simple-concat@npm:1.0.1" + checksum: 10c0/62f7508e674414008910b5397c1811941d457dfa0db4fd5aa7fa0409eb02c3609608dfcd7508cace75b3a0bf67a2a77990711e32cd213d2c76f4fd12ee86d776 + languageName: node + linkType: hard + +"simple-get@npm:^4.0.0": + version: 4.0.1 + resolution: "simple-get@npm:4.0.1" + dependencies: + decompress-response: "npm:^6.0.0" + once: "npm:^1.3.1" + simple-concat: "npm:^1.0.0" + checksum: 10c0/b0649a581dbca741babb960423248899203165769747142033479a7dc5e77d7b0fced0253c731cd57cf21e31e4d77c9157c3069f4448d558ebc96cf9e1eebcf0 + languageName: node + linkType: hard + "simple-swizzle@npm:^0.2.2": version: 0.2.2 resolution: "simple-swizzle@npm:0.2.2" @@ -21415,6 +21649,13 @@ __metadata: languageName: node linkType: hard +"strip-json-comments@npm:~2.0.1": + version: 2.0.1 + resolution: "strip-json-comments@npm:2.0.1" + checksum: 10c0/b509231cbdee45064ff4f9fd73609e2bcc4e84a4d508e9dd0f31f70356473fde18abfb5838c17d56fb236f5a06b102ef115438de0600b749e818a35fbbc48c43 + languageName: node + linkType: hard + "strip-literal@npm:^3.0.0": version: 3.0.0 resolution: "strip-literal@npm:3.0.0" @@ -21608,6 +21849,18 @@ __metadata: languageName: node linkType: hard +"tar-fs@npm:^2.0.0": + version: 2.1.4 + resolution: "tar-fs@npm:2.1.4" + dependencies: + chownr: "npm:^1.1.1" + mkdirp-classic: "npm:^0.5.2" + pump: "npm:^3.0.0" + tar-stream: "npm:^2.1.4" + checksum: 10c0/decb25acdc6839182c06ec83cba6136205bda1db984e120c8ffd0d80182bc5baa1d916f9b6c5c663ea3f9975b4dd49e3c6bb7b1707cbcdaba4e76042f43ec84c + languageName: node + linkType: hard + "tar-fs@npm:^3.0.8": version: 3.1.0 resolution: "tar-fs@npm:3.1.0" @@ -21625,6 +21878,19 @@ __metadata: languageName: node linkType: hard +"tar-stream@npm:^2.1.4": + version: 2.2.0 + resolution: "tar-stream@npm:2.2.0" + dependencies: + bl: "npm:^4.0.3" + end-of-stream: "npm:^1.4.1" + fs-constants: "npm:^1.0.0" + inherits: "npm:^2.0.3" + readable-stream: "npm:^3.1.1" + checksum: 10c0/2f4c910b3ee7196502e1ff015a7ba321ec6ea837667220d7bcb8d0852d51cb04b87f7ae471008a6fb8f5b1a1b5078f62f3a82d30c706f20ada1238ac797e7692 + languageName: node + linkType: hard + "tar-stream@npm:^3.1.5": version: 3.1.7 resolution: "tar-stream@npm:3.1.7" @@ -21773,7 +22039,7 @@ __metadata: languageName: node linkType: hard -"tiny-invariant@npm:*, tiny-invariant@npm:^1.3.1, tiny-invariant@npm:^1.3.3": +"tiny-invariant@npm:*, tiny-invariant@npm:^1.0.0, tiny-invariant@npm:^1.3.1, tiny-invariant@npm:^1.3.3": version: 1.3.3 resolution: "tiny-invariant@npm:1.3.3" checksum: 10c0/65af4a07324b591a059b35269cd696aba21bef2107f29b9f5894d83cc143159a204b299553435b03874ebb5b94d019afa8b8eff241c8a4cfee95872c2e1c1c4a @@ -22208,6 +22474,15 @@ __metadata: languageName: node linkType: hard +"tunnel-agent@npm:^0.6.0": + version: 0.6.0 + resolution: "tunnel-agent@npm:0.6.0" + dependencies: + safe-buffer: "npm:^5.0.1" + checksum: 10c0/4c7a1b813e7beae66fdbf567a65ec6d46313643753d0beefb3c7973d66fcec3a1e7f39759f0a0b4465883499c6dc8b0750ab8b287399af2e583823e40410a17a + languageName: node + linkType: hard + "tunnel-rat@npm:^0.1.2": version: 0.1.2 resolution: "tunnel-rat@npm:0.1.2" @@ -23144,6 +23419,15 @@ __metadata: languageName: node linkType: hard +"warning@npm:^4.0.0": + version: 4.0.3 + resolution: "warning@npm:4.0.3" + dependencies: + loose-envify: "npm:^1.0.0" + checksum: 10c0/aebab445129f3e104c271f1637fa38e55eb25f968593e3825bd2f7a12bd58dc3738bb70dc8ec85826621d80b4acfed5a29ebc9da17397c6125864d72301b937e + languageName: node + linkType: hard + "watchpack@npm:^2.4.1": version: 2.4.4 resolution: "watchpack@npm:2.4.4" From 4a702790d2eb97b68541feab57b90670a6808ecc Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Sat, 31 Jan 2026 21:45:13 +0900 Subject: [PATCH 4/4] =?UTF-8?q?feat:=20=EC=9D=B4=EB=A0=A5=EC=84=9C=20?= =?UTF-8?q?=EA=B8=B0=EB=B0=98=20=EB=A9=B4=EC=A0=91=20=ED=9E=88=EC=8A=A4?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20?= =?UTF-8?q?=EB=AC=B4=ED=95=9C=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - useInfiniteQuery를 사용하여 이력서 기반 면접 생성 기록을 무한 스크롤로 로드하도록 개선 - 페이지 매개변수를 관리하는 새로운 쿼리 키 추가 - 로딩 상태를 표시하는 로더 컴포넌트 추가 및 페이지네이션 버튼 제거 --- .../resume/api/resumeBasedInterview.ts | 3 +- .../resumeBasedInterviewHistory.tsx | 63 ++++++++++++------- apps/client/src/utils/querykeys.ts | 5 +- 3 files changed, 48 insertions(+), 23 deletions(-) diff --git a/apps/client/src/domains/resume/api/resumeBasedInterview.ts b/apps/client/src/domains/resume/api/resumeBasedInterview.ts index 70cfd94f..e9fb733c 100644 --- a/apps/client/src/domains/resume/api/resumeBasedInterview.ts +++ b/apps/client/src/domains/resume/api/resumeBasedInterview.ts @@ -189,7 +189,8 @@ function getResumeBasedInterviewGenerations( : undefined } ) - .then((res) => res.data); + .then((res) => res.data) + .then(mapToCamelCase); } const resumeBasedInterviewCreateInstance = axios.create({ diff --git a/apps/client/src/domains/resume/components/resumeBasedInterviewHistory.tsx b/apps/client/src/domains/resume/components/resumeBasedInterviewHistory.tsx index bf031472..f581378b 100644 --- a/apps/client/src/domains/resume/components/resumeBasedInterviewHistory.tsx +++ b/apps/client/src/domains/resume/components/resumeBasedInterviewHistory.tsx @@ -2,32 +2,50 @@ import { getResumeBasedInterviewGenerations } from "@/domains/resume/api/resumeB import { ResumeBasedInterviewGenerationsResponse } from "@kokomen/types"; import { CamelCasedProperties } from "@/utils/convertConvention"; import { resumeBasedInterviewKeys } from "@/utils/querykeys"; -import { useQuery } from "@tanstack/react-query"; -import { useRouter } from "next/router"; +import { useInfiniteQuery } from "@tanstack/react-query"; +import { useInfiniteObserver } from "@kokomen/utils"; +import { useRef, JSX } from "react"; import { Calendar, FileText, ExternalLink, CheckCircle, XCircle, - Clock + Clock, + Loader2 } from "lucide-react"; import Link from "next/link"; -import PaginationButtons from "@/shared/paginationButtons"; import { formatDate } from "@/utils/date"; -export default function ResumeBasedInterviewHistory() { - const router = useRouter(); - const page = Number(router.query.page) || 0; - - const { data, isLoading, isError } = useQuery< +export default function ResumeBasedInterviewHistory(): JSX.Element { + const { + data, + fetchNextPage, + hasNextPage, + isFetchingNextPage, + isLoading, + isError + } = useInfiniteQuery< CamelCasedProperties >({ - queryKey: resumeBasedInterviewKeys.generations(page), - queryFn: () => getResumeBasedInterviewGenerations(page) + queryKey: resumeBasedInterviewKeys.infinite(), + queryFn: ({ pageParam = 0 }) => + getResumeBasedInterviewGenerations(pageParam as number), + getNextPageParam: (lastPage) => { + return lastPage.hasNext ? lastPage.currentPage + 1 : undefined; + }, + initialPageParam: 0 }); - const getStateBadge = (state: string) => { + const loadMoreRef = useRef(null); + + useInfiniteObserver(loadMoreRef, () => { + if (hasNextPage && !isFetchingNextPage) { + fetchNextPage(); + } + }); + + const getStateBadge = (state: string): JSX.Element | null => { switch (state) { case "COMPLETED": return ( @@ -102,7 +120,7 @@ export default function ResumeBasedInterviewHistory() { ); } - const generations = data.data || []; + const generations = data.pages.flatMap((page) => page.data || []); return (
    @@ -200,14 +218,17 @@ export default function ResumeBasedInterviewHistory() {
    ))} - {data.totalPages > 1 && ( - + {hasNextPage && ( +
    + {isFetchingNextPage ? ( +
    + + 더 불러오는 중... +
    + ) : ( +
    + )} +
    )}
    )} diff --git a/apps/client/src/utils/querykeys.ts b/apps/client/src/utils/querykeys.ts index 73bd49e8..2fa3e74d 100644 --- a/apps/client/src/utils/querykeys.ts +++ b/apps/client/src/utils/querykeys.ts @@ -111,11 +111,14 @@ const archiveKeys: QueryKeyFactory = { type ResumeBasedInterviewMethods = { generations: (page?: number) => QueryKey; + infinite: () => QueryKey; }; const resumeBasedInterviewKeys: QueryKeyFactory = { all: ["resumeBasedInterview"] as const, generations: (page: number = 0): QueryKey => - [...resumeBasedInterviewKeys.all, "generations", page] as const + [...resumeBasedInterviewKeys.all, "generations", page] as const, + infinite: (): QueryKey => + [...resumeBasedInterviewKeys.all, "infinite"] as const }; type ResumeEvaluationMethods = {
    +
    +

    + 이력서 기반 면접 질문 히스토리 +

    +

    + 생성된 이력서 기반 면접 질문들을 확인해보세요 +

    +
    + + {generations.length === 0 ? ( +
    + +

    + 생성된 이력서 기반 면접 질문이 없습니다 +

    +

    + 이력서를 업로드하여 면접 질문을 생성해보세요 +

    +
    + ) : ( +
    + )} +