Skip to content

Commit 052d86a

Browse files
committed
fix(web): use my profile API for mentor page auth gating
1 parent 8533088 commit 052d86a

1 file changed

Lines changed: 34 additions & 42 deletions

File tree

  • apps/web/src/app/mentor/_ui/MentorClient
Lines changed: 34 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,59 @@
11
"use client";
22

3+
import type { AxiosError } from "axios";
34
import { useRouter } from "next/navigation";
4-
import { useEffect, useState } from "react";
5-
import { postReissueToken } from "@/apis/Auth";
5+
import { useEffect } from "react";
6+
import { useGetMyInfo } from "@/apis/MyPage";
67
import CloudSpinnerPage from "@/components/ui/CloudSpinnerPage";
78
import useAuthStore from "@/lib/zustand/useAuthStore";
89
import { UserRole } from "@/types/mentor";
9-
import { isTokenExpired } from "@/utils/jwtUtils";
1010
import MenteePage from "./_ui/MenteePage";
1111
import MentorPage from "./_ui/MentorPage";
1212

1313
const MentorClient = () => {
1414
const router = useRouter();
15-
const { isLoading, accessToken, clientRole, isInitialized, refreshStatus, setRefreshStatus } = useAuthStore();
16-
const [isRefreshing, setIsRefreshing] = useState(false);
17-
const hasValidAccessToken = Boolean(accessToken && !isTokenExpired(accessToken));
15+
const clientRole = useAuthStore((state) => state.clientRole);
16+
const { data: myInfo, isLoading, isFetching, isError, error, refetch } = useGetMyInfo();
17+
const role = myInfo?.role;
18+
const status = (error as AxiosError | null)?.response?.status;
19+
const isUnauthorized = status === 401 || status === 403;
20+
const isAuthResolving = isLoading || (isFetching && !role);
1821

19-
// 토큰 재발급 로직
2022
useEffect(() => {
21-
const attemptTokenRefresh = async () => {
22-
// 이미 실패한 경우 재시도하지 않음 (무한 루프 방지)
23-
if (refreshStatus === "failed") {
24-
return;
25-
}
23+
if (isAuthResolving) return;
24+
if (isUnauthorized || (!isError && !role)) {
25+
router.replace("/login");
26+
}
27+
}, [isAuthResolving, isUnauthorized, isError, role, router]);
2628

27-
// 초기화 이후 유효한 access token이 없을 때만 재발급 시도
28-
if (!isInitialized || hasValidAccessToken || isRefreshing || refreshStatus === "refreshing") {
29-
return;
30-
}
31-
32-
setIsRefreshing(true);
33-
setRefreshStatus("refreshing");
34-
35-
try {
36-
await postReissueToken();
37-
setRefreshStatus("success");
38-
} catch {
39-
// 재발급 실패 시 로그인 페이지로 리다이렉트
40-
setRefreshStatus("failed");
41-
router.push("/login");
42-
} finally {
43-
setIsRefreshing(false);
44-
}
45-
};
46-
47-
attemptTokenRefresh();
48-
}, [isInitialized, hasValidAccessToken, isRefreshing, refreshStatus, setRefreshStatus, router]);
49-
50-
// 초기화 전이거나 로딩 중이거나 재발급 중일 때 스피너 표시
51-
if (!isInitialized || isLoading || refreshStatus === "refreshing" || isRefreshing) {
29+
if (isAuthResolving) {
5230
return <CloudSpinnerPage />;
5331
}
5432

55-
// 초기화 완료 후에도 토큰이 없으면 리다이렉트 (useEffect에서 처리되지만 fallback)
56-
if (!hasValidAccessToken) {
33+
if (isUnauthorized || (!isError && !role)) {
5734
return <CloudSpinnerPage />;
5835
}
5936

60-
if (!clientRole) {
61-
return <CloudSpinnerPage />;
37+
if (isError) {
38+
return (
39+
<div className="flex min-h-[40vh] flex-col items-center justify-center gap-3 px-4 text-center">
40+
<p className="text-k-700 typo-medium-2">멘토 페이지 정보를 불러오지 못했어요.</p>
41+
<button
42+
type="button"
43+
onClick={() => refetch()}
44+
className="rounded-full bg-primary px-4 py-2 text-white typo-medium-2"
45+
>
46+
다시 시도
47+
</button>
48+
</div>
49+
);
50+
}
51+
52+
if (role === UserRole.ADMIN) {
53+
return clientRole === UserRole.MENTEE ? <MenteePage /> : <MentorPage />;
6254
}
6355

64-
return clientRole === UserRole.MENTOR ? <MentorPage /> : <MenteePage />;
56+
return role === UserRole.MENTOR ? <MentorPage /> : <MenteePage />;
6557
};
6658

6759
export default MentorClient;

0 commit comments

Comments
 (0)