diff --git a/apps/web/src/apis/applications/api.ts b/apps/web/src/apis/applications/api.ts index 9f10a94f..61f3d952 100644 --- a/apps/web/src/apis/applications/api.ts +++ b/apps/web/src/apis/applications/api.ts @@ -25,23 +25,25 @@ export interface UseSubmitApplicationRequest { }; } -export interface CompetitorsResponse { - competitors: Array<{ - id: number; - name: string; - score: number; - }>; -} - // ====== API Functions ====== export const applicationsApi = { /** - * 지원 목록 조회 + * 전체 지원자 현황 조회 */ getApplicationsList: async (): Promise> => { return axiosInstance.get("/applications"); }, + /** + * 내가 지원한 대학의 경쟁자 현황 조회 + * + * 서버에서 현재 사용자의 지원 대학만 반환하므로, 클라이언트에서 소속 대학 기준으로 + * 다시 필터링하지 않는다. + */ + getCompetitors: async (): Promise> => { + return axiosInstance.get("/applications/competitors"); + }, + /** * 지원자가 있는 대학의 제한 공개 정보 조회 */ @@ -57,12 +59,4 @@ export const applicationsApi = { ): Promise> => { return axiosInstance.post("/applications", request); }, - - /** - * 경쟁자 목록 조회 - */ - getCompetitors: async (config?: { params?: Record }): Promise => { - const res = await axiosInstance.get("/applications/competitors", config); - return res.data; - }, }; diff --git a/apps/web/src/apis/applications/getApplicants.ts b/apps/web/src/apis/applications/getApplicants.ts index 9f5572c6..be825ee7 100644 --- a/apps/web/src/apis/applications/getApplicants.ts +++ b/apps/web/src/apis/applications/getApplicants.ts @@ -15,11 +15,20 @@ type UseGetApplicationsListOptions = Omit< >; /** - * @description 지원 목록 조회 훅 - * - * `GET /applications` 는 전체 지원자 현황을 내려주고 소속 대학을 구분해주지 않는다. - * 그래서 access token 에서 파싱된 소속 대학(useAuthStore.homeUniversityId)으로 - * 파견학교 목록을 따로 받아, 그 범위에 속한 항목만 남기도록 클라이언트에서 걸러낸다. + * 지원 기간에는 지원한 대학만, 기간 종료 후에는 소속 대학의 전체 현황을 공개한다. + * 전체 현황을 다시 공개할 때 반환값을 "applications"로 변경한다. + */ +type ApplicationStatusEndpoint = "applications" | "competitors"; + +const getApplicationStatusEndpoint = (): ApplicationStatusEndpoint => "competitors"; + +const applicationStatusEndpoint = getApplicationStatusEndpoint(); +const shouldFilterByHomeUniversity = applicationStatusEndpoint === "applications"; +const applicationStatusQueryFn = + applicationStatusEndpoint === "competitors" ? applicationsApi.getCompetitors : applicationsApi.getApplicationsList; + +/** + * @description 내가 지원한 대학의 지원자 현황 조회 훅 */ const useGetApplicationsList = ( props?: UseGetApplicationsListOptions, @@ -28,28 +37,23 @@ const useGetApplicationsList = ( const applicationsQuery = useQuery({ queryKey: [ApplicationsQueryKeys.competitorsApplicationList], - queryFn: applicationsApi.getApplicationsList, + queryFn: applicationStatusQueryFn, staleTime: 1000 * 60 * 5, // 5분간 캐시 select: (response) => response.data, ...props, }); - // 필터 기준이 되는 소속 대학의 파견학교 목록 + // GET /applications를 사용할 때만 소속 대학의 파견학교 목록으로 범위를 제한한다. const { data: scopedUniversities } = useQuery({ queryKey: [QueryKeys.universities.searchText, { homeUniversityId }], queryFn: () => universitiesApi.getSearchText({ value: "", homeUniversityId: homeUniversityId ?? undefined }), - enabled: homeUniversityId !== null, + enabled: shouldFilterByHomeUniversity && homeUniversityId !== null, staleTime: 1000 * 60 * 5, select: (response) => response.univApplyInfoPreviews, }); const scopedData = useMemo(() => { - if (!applicationsQuery.data) { - return applicationsQuery.data; - } - - // 소속 대학을 모르면(비인증·학교 미인증) 기존과 동일하게 전체를 보여준다. - if (homeUniversityId === null) { + if (!applicationsQuery.data || !shouldFilterByHomeUniversity || homeUniversityId === null) { return applicationsQuery.data; } diff --git a/apps/web/src/apis/applications/getCompetitors.ts b/apps/web/src/apis/applications/getCompetitors.ts index 6b3bda67..48df6135 100644 --- a/apps/web/src/apis/applications/getCompetitors.ts +++ b/apps/web/src/apis/applications/getCompetitors.ts @@ -1,12 +1,21 @@ -import { useQuery } from "@tanstack/react-query"; -import type { AxiosError } from "axios"; +import { type UseQueryOptions, useQuery } from "@tanstack/react-query"; +import type { AxiosError, AxiosResponse } from "axios"; + +import type { ApplicationListResponse } from "@/types/application"; import { QueryKeys } from "../queryKeys"; -import { applicationsApi, type CompetitorsResponse } from "./api"; +import { applicationsApi } from "./api"; + +type UseGetCompetitorsOptions = Omit< + UseQueryOptions, AxiosError<{ message: string }>, ApplicationListResponse>, + "queryKey" | "queryFn" +>; -const useGetCompetitors = (params?: Record) => { - return useQuery({ - queryKey: [QueryKeys.applications.competitors, params], - queryFn: () => applicationsApi.getCompetitors(params ? { params } : {}), +const useGetCompetitors = (props?: UseGetCompetitorsOptions) => { + return useQuery({ + queryKey: [QueryKeys.applications.competitors], + queryFn: applicationsApi.getCompetitors, + select: (response) => response.data, + ...props, }); }; diff --git a/apps/web/src/apis/applications/homeUniversityScope.ts b/apps/web/src/apis/applications/homeUniversityScope.ts index c45f6acb..56362be3 100644 --- a/apps/web/src/apis/applications/homeUniversityScope.ts +++ b/apps/web/src/apis/applications/homeUniversityScope.ts @@ -3,7 +3,7 @@ import type { ApplicationListResponse, ScoreSheet } from "@/types/application"; /** * 지원자 현황 응답을 소속 대학 기준으로 걸러내기 위한 키. * - * `GET /applications` 응답(ScoreSheet)에는 홈 대학 식별자도, 지원 정보 id 도 없다. + * GET /applications 응답(ScoreSheet)에는 홈 대학 식별자도, 지원 정보 id도 없다. * 그래서 파견학교 목록과 겹치는 필드(파견학교명 + 국가 + 모집인원)를 합쳐 식별한다. * * 파견학교명만으로는 부족하다. 서로 다른 홈 대학이 같은 이름의 파견학교를 가질 수 있고