diff --git a/components/wiki.page/Contents.tsx b/components/wiki.page/Contents.tsx index 327cab2..2c3ae9f 100644 --- a/components/wiki.page/Contents.tsx +++ b/components/wiki.page/Contents.tsx @@ -11,8 +11,9 @@ import instance from '@/lib/axios-client'; import Blank from './Blank'; import ContentHeader from './ContentHeader'; -import { useProfileContext } from '@/hooks/useProfileContext'; import { useSnackbar } from 'context/SnackBarContext'; +import { useAuth } from '@/hooks/useAuth'; +import { ProfileAPI } from '@/services/api/profileAPI'; interface ProfileProps { profile: ProfileAnswer; @@ -31,11 +32,11 @@ export default function Contents({ profile }: ProfileProps) { const previousContent = useRef(newContent); const isEmpty = newContent === ''; - const { isAuthenticated } = useProfileContext(); + const { isAuthenticated } = useAuth(); const handleQuizOpen = async () => { if (!isAuthenticated) { - showSnackbar('로그인 후 이용해주세요.', 'fail'); + showSnackbar('로그인이 필요한 서비스 입니다.', 'fail'); return; } try { @@ -51,7 +52,7 @@ export default function Contents({ profile }: ProfileProps) { setIsInfoSnackBarOpen(true); } } catch (error) { - showSnackbar('다시 시도해주세요.', 'fail'); + showSnackbar('다시 시도해주세요. -1', 'fail'); } }; @@ -59,24 +60,17 @@ export default function Contents({ profile }: ProfileProps) { const handleQuizSuccess = async () => { showSnackbar('정답입니다!', 'success'); setIsQuizOpen(false); - + // 내 위키인지 확인 try { - const accessToken = localStorage.getItem('accessToken'); - const res = await instance.get('/users/me', { - headers: { - Authorization: `Bearer ${accessToken}`, - }, - }); - const userCode = (res.data as { profile: ProfileAnswer }).profile.code; + const { code } = await ProfileAPI.getProfile(); + const userCode = code; if (profile.code === userCode) { setIsProfileEdit(true); - } else { - setIsProfileEdit(false); } - setIsEditing(true); } catch (error) { - showSnackbar('다시 시도해주세요.', 'fail'); + setIsProfileEdit(false); } + setIsEditing(true); }; //위키 제목과 내용 편집 diff --git a/context/ProfileContext.tsx b/context/ProfileContext.tsx index 5a73328..7b5e920 100644 --- a/context/ProfileContext.tsx +++ b/context/ProfileContext.tsx @@ -1,16 +1,7 @@ -import { - createContext, - ReactNode, - useCallback, - useEffect, - useState, -} from 'react'; +import { createContext, ReactNode } from 'react'; import { Profile } from 'types/profile'; -import instance from '@/lib/axios-client'; - -interface UserProfileResponse { - profile: Profile | null; -} +import { useAuth } from '@/hooks/useAuth'; +import { useProfile } from '@/hooks/useProfile'; interface ProfileContextType { isAuthenticated: boolean; @@ -23,65 +14,8 @@ export const ProfileContext = createContext(null); export const ProfileProvider: React.FC<{ children: ReactNode }> = ({ children, }) => { - const [isAuthenticated, setIsAuthenticated] = useState(false); - const [profile, setProfile] = useState(null); - const [accessToken, setAccessTokenState] = useState(null); - - // accessToken 상태를 업데이트하면서 localStorage와 동기화 - const setAccessToken = (token: string | null) => { - if (token) { - localStorage.setItem('accessToken', token); - } else { - localStorage.removeItem('accessToken'); - } - setAccessTokenState(token); - }; - - const getProfile = useCallback(async () => { - if (!accessToken) { - console.log('[디버그] 토큰 없음. 프로필을 불러올 수 없습니다.'); - return; - } - - try { - const res = await instance.get('/users/me', { - headers: { Authorization: `Bearer ${accessToken}` }, - }); - - const profileData = res.data.profile; - - if (!profileData) { - setProfile(null); - setIsAuthenticated(false); - return; - } - - // 추가 정보 가져오기 - if (profileData.code) { - const profileRes = await instance.get( - `/profiles/${profileData.code}` - ); - setProfile(profileRes.data); - } else { - setProfile(profileData); - } - setIsAuthenticated(true); - } catch { - setProfile(null); - setIsAuthenticated(false); - } - }, [accessToken]); - - // accessToken 상태 변화 감지 - useEffect(() => { - if (accessToken) { - setIsAuthenticated(true); - getProfile(); - } else { - setIsAuthenticated(false); - setProfile(null); - } - }, [accessToken, getProfile]); // accessToken이 변경될 때마다 실행 + const { isAuthenticated, accessToken, setAccessToken } = useAuth(); + const { profile } = useProfile(accessToken); return ( { + const [accessToken, setAccessTokenState] = useState(null); + const [isAuthenticated, setIsAuthenticated] = useState(false); + + // accessToken 상태를 업데이트하면서 localStorage와 동기화 + const setAccessToken = (token: string | null) => { + if (token) { + localStorage.setItem('accessToken', token); + } else { + localStorage.removeItem('accessToken'); + } + setAccessTokenState(token); + }; + + // 클라이언트 렌더링 후 accessToken 초기화 + useEffect(() => { + const token = localStorage.getItem('accessToken'); // 브라우저 환경에서만 localStorage 사용 + setAccessTokenState(token); + setIsAuthenticated(!!token); // accessToken이 있으면 true로 설정 + }, []); + + useEffect(() => { + setIsAuthenticated(!!accessToken); + }, [accessToken]); + + return { + isAuthenticated, + accessToken, + setAccessToken, + }; +}; diff --git a/hooks/useProfile.ts b/hooks/useProfile.ts new file mode 100644 index 0000000..9fec4ab --- /dev/null +++ b/hooks/useProfile.ts @@ -0,0 +1,58 @@ +import { useState, useCallback, useEffect } from 'react'; +import { Profile } from 'types/profile'; +import instance from '@/lib/axios-client'; + +interface UserProfileResponse { + profile: Profile | null; +} + +export const useProfile = (accessToken: string | null) => { + const [profile, setProfile] = useState(null); + + const getProfile = useCallback(async () => { + if (!accessToken) { + console.log('[디버그] 토큰 없음. 프로필을 불러올 수 없습니다.'); + return; + } + + try { + const res = await instance.get('/users/me', { + headers: { Authorization: `Bearer ${accessToken}` }, + }); + + const profileData = res.data.profile; + + if (!profileData) { + setProfile(null); + return; + } + + // 추가 정보 가져오기 + if (profileData.code) { + const profileRes = await instance.get( + `/profiles/${profileData.code}` + ); + setProfile(profileRes.data); + } else { + setProfile(profileData); + } + } catch { + setProfile(null); + } + }, [accessToken]); + + useEffect(() => { + if (accessToken) { + getProfile().catch((error) => { + console.error('[디버그] 프로필 로드 실패:', error); + }); + } else { + setProfile(null); + } + }, [accessToken, getProfile]); + + return { + profile, + getProfile, + }; +};