diff --git a/apps/web/src/apis/Scores/api.ts b/apps/web/src/apis/Scores/api.ts
index e19619394..b9b1d07bf 100644
--- a/apps/web/src/apis/Scores/api.ts
+++ b/apps/web/src/apis/Scores/api.ts
@@ -10,6 +10,7 @@ export const ScoresQueryKeys = {
// ====== Types ======
export interface UseMyGpaScoreResponse {
+ homeUniversityName: string;
gpaScoreStatusResponseList: GpaScore[];
}
diff --git a/apps/web/src/apis/Scores/getGpaList.ts b/apps/web/src/apis/Scores/getGpaList.ts
index 00437ae8c..e2e43eb5c 100644
--- a/apps/web/src/apis/Scores/getGpaList.ts
+++ b/apps/web/src/apis/Scores/getGpaList.ts
@@ -5,12 +5,13 @@ import { ScoresQueryKeys, scoresApi } from "./api";
/**
* @description 내 학점 점수 조회 훅
*/
-const useGetMyGpaScore = () => {
+const useGetMyGpaScore = ({ enabled = true }: { enabled?: boolean } = {}) => {
return useQuery({
queryKey: [ScoresQueryKeys.myGpaScore],
queryFn: scoresApi.getMyGpaScore,
+ enabled,
staleTime: Infinity,
- select: (data) => data.data.gpaScoreStatusResponseList,
+ select: (data) => data.data,
});
};
diff --git a/apps/web/src/app/my/school-email/_lib/returnTo.ts b/apps/web/src/app/my/school-email/_lib/returnTo.ts
new file mode 100644
index 000000000..989c76a35
--- /dev/null
+++ b/apps/web/src/app/my/school-email/_lib/returnTo.ts
@@ -0,0 +1,19 @@
+export const SCHOOL_EMAIL_RETURN_PATHS = {
+ applicationApply: "/university/application/apply",
+ score: "/university/score",
+ gpaSubmit: "/university/score/submit/gpa",
+} as const;
+
+export type SchoolEmailReturnTo = keyof typeof SCHOOL_EMAIL_RETURN_PATHS;
+
+export const getSchoolEmailReturnPath = (returnTo: string | null | undefined) => {
+ if (!returnTo || !(returnTo in SCHOOL_EMAIL_RETURN_PATHS)) {
+ return "/";
+ }
+
+ return SCHOOL_EMAIL_RETURN_PATHS[returnTo as SchoolEmailReturnTo];
+};
+
+export const getSchoolEmailVerificationPath = (returnTo: SchoolEmailReturnTo) => {
+ return `/my/school-email?returnTo=${returnTo}`;
+};
diff --git a/apps/web/src/app/my/school-email/_ui/SchoolEmailVerificationContent/index.tsx b/apps/web/src/app/my/school-email/_ui/SchoolEmailVerificationContent/index.tsx
index d10a070be..7edcea215 100644
--- a/apps/web/src/app/my/school-email/_ui/SchoolEmailVerificationContent/index.tsx
+++ b/apps/web/src/app/my/school-email/_ui/SchoolEmailVerificationContent/index.tsx
@@ -8,6 +8,7 @@ import { Input } from "@/components/ui/Inputa";
import { Label } from "@/components/ui/Label";
import { Progress } from "@/components/ui/Progress";
import { IconExpRed } from "@/public/svgs/ui";
+import { getSchoolEmailReturnPath } from "../../_lib/returnTo";
const VERIFICATION_LIMIT_SECONDS = 300;
const CODE_LENGTH = 6;
@@ -43,7 +44,7 @@ const SchoolEmailVerificationContent = () => {
const isCodeInputValid = code.length === CODE_LENGTH;
const isTimerExpired = remainingSeconds <= 0;
const progressValue = step === "email" ? 0 : step === "code" ? 50 : 100;
- const shouldReturnToApply = searchParams?.get("returnTo") === "applicationApply";
+ const returnPath = getSchoolEmailReturnPath(searchParams?.get("returnTo"));
useEffect(() => {
if (step !== "code" || remainingSeconds <= 0) return;
@@ -134,8 +135,8 @@ const SchoolEmailVerificationContent = () => {
- router.replace(shouldReturnToApply ? "/university/application/apply" : "/")}>
- {shouldReturnToApply ? "지원하기로 돌아가기" : "홈으로"}
+ router.replace(returnPath)}>
+ {returnPath === "/" ? "홈으로" : "이전 화면으로 돌아가기"}
diff --git a/apps/web/src/app/university/application/apply/ApplyPageContent.tsx b/apps/web/src/app/university/application/apply/ApplyPageContent.tsx
index 7421498cd..266cbe8ad 100644
--- a/apps/web/src/app/university/application/apply/ApplyPageContent.tsx
+++ b/apps/web/src/app/university/application/apply/ApplyPageContent.tsx
@@ -5,6 +5,7 @@ import { useEffect, useMemo, useState } from "react";
import { usePostSubmitApplication } from "@/apis/applications";
import { useGetMyGpaScore, useGetMyLanguageTestScore } from "@/apis/Scores";
import { useUniversitySearch } from "@/apis/universities";
+import { getSchoolEmailVerificationPath } from "@/app/my/school-email/_lib/returnTo";
import TopDetailNavigation from "@/components/layout/TopDetailNavigation";
import ProgressBar from "@/components/ui/ProgressBar";
import { DEFAULT_MAX_CHOICE_COUNT, getHomeUniversityById } from "@/constants/university";
@@ -36,7 +37,9 @@ const ApplyPageContent = () => {
);
const { data: universityList = [] } = useUniversitySearch("", undefined, universitySearchOptions);
- const { data: gpaScoreList = [] } = useGetMyGpaScore();
+ const shouldFetchGpaScore = isAuthInitialized && isAuthenticated && homeUniversityId !== null;
+ // TODO: 서버의 모학교 미인증 에러 코드가 확정되면 GPA 조회 실패 시 학교 인증으로 보내는 fallback을 추가한다.
+ const { data: gpaScoreData } = useGetMyGpaScore({ enabled: shouldFetchGpaScore });
const { data: languageTestScoreList = [] } = useGetMyLanguageTestScore();
const { mutate: postSubmitApplication } = usePostSubmitApplication({
onSuccess: () => {
@@ -53,7 +56,7 @@ const ApplyPageContent = () => {
return;
}
- router.replace("/my/school-email?returnTo=applicationApply");
+ router.replace(getSchoolEmailVerificationPath("applicationApply"));
}, [homeUniversityId, isAuthInitialized, isAuthenticated, router]);
// 다음 스텝으로 넘어가기
@@ -95,6 +98,8 @@ const ApplyPageContent = () => {
});
};
+ const gpaScoreList = gpaScoreData?.gpaScoreStatusResponseList ?? [];
+ const homeUniversityName = gpaScoreData?.homeUniversityName;
const isDataExist = gpaScoreList.length === 0 || languageTestScoreList.length === 0;
const hasSelectedUniversity = curUniversityList.some((universityId) => universityId > 0);
const progressStep = step === 3 && hasSelectedUniversity ? APPLY_PROGRESS_TOTAL_STEPS : step + 1;
@@ -123,9 +128,10 @@ const ApplyPageContent = () => {
onNext={goNextStep}
/>
)}
- {step === 2 && (
+ {step === 2 && homeUniversityName && (
void;
onNext: () => void;
};
-const GpaStep = ({ gpaScoreList, curGpaScore, setCurGpaScore, onNext }: GpaStepProps) => {
+const GpaStep = ({ gpaScoreList, homeUniversityName, curGpaScore, setCurGpaScore, onNext }: GpaStepProps) => {
const [isModalOpen, setIsModalOpen] = useState(false);
const handleNext = () => {
@@ -50,7 +51,7 @@ const GpaStep = ({ gpaScoreList, curGpaScore, setCurGpaScore, onNext }: GpaStepP
className="transition-transform hover:scale-[1.01] active:scale-[0.97]"
>
{
const router = useRouter();
+ const homeUniversityId = useAuthStore((state) => state.homeUniversityId);
+ const isAuthInitialized = useAuthStore((state) => state.isInitialized);
+ const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
const [curTab, setCurTab] = useState("공인어학");
- const { data: gpaScoreList = [] } = useGetMyGpaScore();
+ const shouldFetchGpaScore = isAuthInitialized && isAuthenticated && homeUniversityId !== null;
+ // TODO: 서버의 모학교 미인증 에러 코드가 확정되면 GPA 조회 실패 시 학교 인증으로 보내는 fallback을 추가한다.
+ const { data: gpaScoreData } = useGetMyGpaScore({ enabled: shouldFetchGpaScore });
const { data: languageTestScoreList = [] } = useGetMyLanguageTestScore();
+ const gpaScoreList = gpaScoreData?.gpaScoreStatusResponseList ?? [];
const isEmptyCurrentTab = curTab === "공인어학" ? languageTestScoreList.length === 0 : gpaScoreList.length === 0;
+ useEffect(() => {
+ if (!isAuthInitialized || !isAuthenticated || homeUniversityId !== null) {
+ return;
+ }
+
+ router.replace(getSchoolEmailVerificationPath("score"));
+ }, [homeUniversityId, isAuthInitialized, isAuthenticated, router]);
+
const handleScoreClick = (status: ScoreSubmitStatus, rejectedReason?: string | null) => {
if (status === ScoreSubmitStatus.REJECTED) {
showIconToast("logo", rejectedReason ?? "승인이 거절되었습니다.");
@@ -30,6 +46,14 @@ const ScoreScreen = () => {
}
};
+ if (!isAuthInitialized) {
+ return null;
+ }
+
+ if (isAuthenticated && homeUniversityId === null) {
+ return null;
+ }
+
return (
@@ -68,6 +92,7 @@ const ScoreScreen = () => {
))}
{curTab === "학점" &&
+ gpaScoreData &&
gpaScoreList.map((score) => (