diff --git a/src/components/common/Modal/ErrorModal.tsx b/src/components/common/Modal/ErrorModal.tsx
index d145ede8..9ebc5f31 100644
--- a/src/components/common/Modal/ErrorModal.tsx
+++ b/src/components/common/Modal/ErrorModal.tsx
@@ -12,6 +12,7 @@ interface ErrorModalProps {
showCloseButton?: boolean;
children?: React.ReactNode;
className?: string;
+ confirmText?: string;
}
/* 기존에 errorMessage를 props로 받았는데,
@@ -24,6 +25,7 @@ const ErrorModal = ({
showCloseButton = false,
children,
className,
+ confirmText,
}: ErrorModalProps) => {
return (
- 확인
+ {confirmText ?? '확인'}
diff --git a/src/hooks/useInitUser.tsx b/src/hooks/useInitUser.tsx
index fe9b8b73..b5abf129 100644
--- a/src/hooks/useInitUser.tsx
+++ b/src/hooks/useInitUser.tsx
@@ -7,18 +7,23 @@ import { useUserStore } from '@/stores/userStore';
* 앱 진입 시 유저 정보를 패치하고 Zustand에 저장하는 훅 */
export const useInitUser = () => {
const setUser = useUserStore((state) => state.setUser);
+ const clearUser = useUserStore((state) => state.clearUser);
+ const setIsUserLoading = useUserStore((state) => state.setIsUserLoading);
- /* 처음에만 실행 */
useEffect(() => {
const fetchUser = async () => {
+ setIsUserLoading(true); // 유저 정보 불러오기 시작
+
try {
- const user = await getUser();
- setUser(user);
+ const user = await getUser(); // API 호출
+ setUser(user); // 로그인 상태로 전역 상태 설정
} catch (error) {
- // 로그인 안 돼있는 경우 무시
+ clearUser(); // 실패 시 로그아웃 상태로 초기화
+ } finally {
+ setIsUserLoading(false); // 로딩 끝
}
};
fetchUser();
- }, [setUser]);
+ }, [setUser, clearUser, setIsUserLoading]);
};
diff --git a/src/hooks/useUser.tsx b/src/hooks/useUser.tsx
index 118a3682..83c8940c 100644
--- a/src/hooks/useUser.tsx
+++ b/src/hooks/useUser.tsx
@@ -5,8 +5,9 @@ import { useUserStore } from '@/stores/userStore';
export const useUser = () => {
const user = useUserStore((state) => state.user);
const isLoggedIn = useUserStore((state) => state.isLoggedIn);
+ const isUserLoading = useUserStore((state) => state.isUserLoading);
const setUser = useUserStore((state) => state.setUser);
const clearUser = useUserStore((state) => state.clearUser);
- return { user, isLoggedIn, setUser, clearUser };
+ return { user, isLoggedIn, isUserLoading, setUser, clearUser };
};
diff --git a/src/pages/my-profile/index.tsx b/src/pages/my-profile/index.tsx
index 940cb7aa..51d4fda3 100644
--- a/src/pages/my-profile/index.tsx
+++ b/src/pages/my-profile/index.tsx
@@ -1,9 +1,14 @@
-import React, { useState } from 'react';
+import React, { useEffect, useState } from 'react';
+import { useRouter } from 'next/router';
+
+import { LoadingOverlay } from '@/components/common/LoadingOverlay';
+import ErrorModal from '@/components/common/Modal/ErrorModal';
import Profile from '@/components/my-profile/Profile';
import { ReviewList } from '@/components/my-profile/ReviewList';
import { TabNav } from '@/components/my-profile/Tab';
import { WineList } from '@/components/my-profile/WineList';
+import { useUser } from '@/hooks/useUser';
/**
* MyProfile
@@ -15,43 +20,61 @@ import { WineList } from '@/components/my-profile/WineList';
* - 각 리스트의 총 개수를 상위에서 관리
*/
export default function MyProfile() {
- /**
- * 현재 선택된 탭 상태
- * - 'reviews': 내가 쓴 리뷰
- * - 'wines': 내가 등록한 와인
- */
- const [tab, setTab] = useState<'reviews' | 'wines'>('reviews');
+ const router = useRouter();
+ const { isLoggedIn, isUserLoading } = useUser();
+ const [showModal, setShowModal] = useState(false);
- /** 리뷰 총 개수 (리뷰 탭에서 ReviewList가 설정함) */
+ const [tab, setTab] = useState<'reviews' | 'wines'>('reviews');
const [reviewsCount, setReviewsCount] = useState(0);
-
- /** 와인 총 개수 (와인 탭에서 WineList가 설정함) */
const [winesCount, setWinesCount] = useState(0);
+ useEffect(() => {
+ if (!isUserLoading && !isLoggedIn) {
+ setShowModal(true);
+ }
+ }, [isLoggedIn, isUserLoading]);
+
+ const handleRedirect = () => {
+ router.push('/signin'); // 로그인 페이지로 이동
+ };
+
return (
-
- {/* 프로필 섹션 */}
-
-
- {/* 탭 + 리스트 */}
-
- {/* 탭 네비게이션: 현재 탭, 탭 전환 함수, 각각의 개수 전달 */}
-
-
- {/* 탭 상태에 따라 리스트 컴포넌트 조건부 렌더링 */}
- {tab === 'reviews' ? (
-
- ) : (
-
- )}
-
-
+ {/* 로딩 중일 때 전체 오버레이 */}
+ {isUserLoading &&
}
+
+
{}}
+ onConfirm={handleRedirect}
+ confirmText='로그인 하러 가기'
+ >
+ 마이페이지는 로그인 후 이용할 수 있어요
+
+ {isLoggedIn && (
+
+ {/* 프로필 섹션 */}
+
+
+ {/* 탭 + 리스트 */}
+
+ {/* 탭 네비게이션: 현재 탭, 탭 전환 함수, 각각의 개수 전달 */}
+
+
+ {/* 탭 상태에 따라 리스트 컴포넌트 조건부 렌더링 */}
+ {tab === 'reviews' ? (
+
+ ) : (
+
+ )}
+
+
+ )}
);
}
diff --git a/src/stores/userStore.ts b/src/stores/userStore.ts
index 3644a57f..5666fa0f 100644
--- a/src/stores/userStore.ts
+++ b/src/stores/userStore.ts
@@ -1,32 +1,42 @@
import { create } from 'zustand';
-/* 유저 정보 타입 */
-interface User {
- id: number;
- nickname: string;
- image: string | null;
- teamId: string;
- createdAt: string;
- updatedAt: string;
-}
+import { GetUserResponse } from '@/types/UserTypes';
/* Zustand 유저 상태 저장소 타입 */
interface UserStore {
- user: User | null;
+ user: GetUserResponse | null;
isLoggedIn: boolean;
+ isUserLoading: boolean;
/* 유저 정보 설정 (로그인 등) */
- setUser: (user: User) => void;
+ setUser: (user: GetUserResponse) => void;
/* 유저 정보 초기화 (로그아웃 등) */
clearUser: () => void;
+
+ /* 유저 정보 로딩 상태 변경 */
+ setIsUserLoading: (loading: boolean) => void;
}
/**
- * 유저 상태 전역 스토어 */
+ * 유저 상태 전역 스토어
+ */
export const useUserStore = create((set) => ({
user: null,
isLoggedIn: false,
- setUser: (user) => set({ user, isLoggedIn: true }),
- clearUser: () => set({ user: null, isLoggedIn: false }),
+ isUserLoading: true,
+
+ setUser: (user) =>
+ set({
+ user,
+ isLoggedIn: true,
+ }),
+
+ clearUser: () =>
+ set({
+ user: null,
+ isLoggedIn: false,
+ }),
+
+ setIsUserLoading: (loading) => set({ isUserLoading: loading }),
}));