Skip to content

Commit 5ff1cde

Browse files
authored
fix: 대학 상세 데이터 미준비 상태 폴백 UI 추가 (#449)
1 parent 850b2bd commit 5ff1cde

4 files changed

Lines changed: 87 additions & 8 deletions

File tree

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,42 @@
11
import type { University } from "@/types/university";
22
import serverFetch from "@/utils/serverFetchUtil";
33

4-
export const getUniversityDetail = async (universityInfoForApplyId: number): Promise<University | undefined> => {
4+
type UniversityDetailFetchSuccess = {
5+
ok: true;
6+
status: number;
7+
data: University;
8+
};
9+
10+
type UniversityDetailFetchFailure = {
11+
ok: false;
12+
status: number;
13+
error: string;
14+
};
15+
16+
export type UniversityDetailFetchResult = UniversityDetailFetchSuccess | UniversityDetailFetchFailure;
17+
18+
export const getUniversityDetailWithStatus = async (
19+
universityInfoForApplyId: number,
20+
): Promise<UniversityDetailFetchResult> => {
521
const result = await serverFetch<University>(`/univ-apply-infos/${universityInfoForApplyId}`);
622

723
if (!result.ok) {
824
console.error(`Failed to fetch university detail (ID: ${universityInfoForApplyId}):`, result.error);
9-
return undefined;
25+
return {
26+
ok: false,
27+
status: result.status,
28+
error: result.error,
29+
};
1030
}
1131

12-
return result.data;
32+
return {
33+
ok: true,
34+
status: result.status,
35+
data: result.data,
36+
};
37+
};
38+
39+
export const getUniversityDetail = async (universityInfoForApplyId: number): Promise<University | undefined> => {
40+
const result = await getUniversityDetailWithStatus(universityInfoForApplyId);
41+
return result.ok ? result.data : undefined;
1342
};

apps/web/src/apis/universities/server/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,8 @@ export {
66
type UniversitySearchFilterParams,
77
} from "./getSearchUniversitiesByFilter";
88
export { getAllUniversities, getCategorizedUniversities, getUniversitiesByText } from "./getSearchUniversitiesByText";
9-
export { getUniversityDetail } from "./getUniversityDetail";
9+
export {
10+
getUniversityDetail,
11+
getUniversityDetailWithStatus,
12+
type UniversityDetailFetchResult,
13+
} from "./getUniversityDetail";
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import Link from "next/link";
2+
3+
import { IconSolidConnectionSmallLogo } from "@/public/svgs/my";
4+
5+
interface UniversityDetailPreparingFallbackProps {
6+
backHref: string;
7+
}
8+
9+
const UniversityDetailPreparingFallback = ({ backHref }: UniversityDetailPreparingFallbackProps) => {
10+
return (
11+
<div
12+
className="flex min-h-[calc(100vh-56px)] flex-col items-center justify-center px-5 pb-24 pt-20 text-center"
13+
role="status"
14+
aria-live="polite"
15+
aria-atomic="true"
16+
>
17+
<IconSolidConnectionSmallLogo />
18+
<p className="mt-3 text-k-700 typo-sb-9">대학 정보를 준비중입니다.</p>
19+
<p className="mt-1 text-k-400 typo-regular-3">아직 데이터가 준비되지 않았어요. 잠시 후 다시 확인해주세요.</p>
20+
<Link
21+
href={backHref}
22+
className="mt-5 rounded-full border border-k-200 bg-k-0 px-5 py-2 text-k-700 typo-sb-11 transition-colors hover:bg-k-50"
23+
>
24+
파견학교 목록으로 돌아가기
25+
</Link>
26+
</div>
27+
);
28+
};
29+
30+
export default UniversityDetailPreparingFallback;

apps/web/src/app/university/[homeUniversity]/[id]/page.tsx

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import type { Metadata } from "next";
22
import { notFound } from "next/navigation";
33

4-
import { getAllUniversities, getUniversityDetail } from "@/apis/universities/server";
4+
import { getAllUniversities, getUniversityDetail, getUniversityDetailWithStatus } from "@/apis/universities/server";
55
import TopDetailNavigation from "@/components/layout/TopDetailNavigation";
66
import { getHomeUniversityBySlug, HOME_UNIVERSITY_SLUGS } from "@/constants/university";
77
import type { HomeUniversitySlug } from "@/types/university";
88

99
// UniversityDetail 컴포넌트
1010
import UniversityDetail from "./_ui/UniversityDetail";
11+
import UniversityDetailPreparingFallback from "./_ui/UniversityDetailPreparingFallback";
1112

1213
export const revalidate = false; // 완전 정적 생성
1314

@@ -117,12 +118,27 @@ const CollegeDetailPage = async ({ params }: PageProps) => {
117118
}
118119

119120
const collegeId = Number(id);
120-
const universityData = await getUniversityDetail(collegeId);
121-
122-
if (!universityData) {
121+
if (Number.isNaN(collegeId)) {
123122
notFound();
124123
}
125124

125+
const universityDetailResult = await getUniversityDetailWithStatus(collegeId);
126+
127+
if (!universityDetailResult.ok) {
128+
if (universityDetailResult.status === 404) {
129+
notFound();
130+
}
131+
132+
return (
133+
<>
134+
<TopDetailNavigation title="파견 학교 상세" backHref={`/university/${homeUniversity}`} />
135+
<UniversityDetailPreparingFallback backHref={`/university/${homeUniversity}`} />
136+
</>
137+
);
138+
}
139+
140+
const universityData = universityDetailResult.data;
141+
126142
const convertedKoreanName =
127143
universityData.term !== process.env.NEXT_PUBLIC_CURRENT_TERM
128144
? `${universityData.koreanName}(${universityData.term})`

0 commit comments

Comments
 (0)