diff --git a/src/pages/login/login-page.tsx b/src/pages/login/login-page.tsx index 89063ac..b0eb274 100644 --- a/src/pages/login/login-page.tsx +++ b/src/pages/login/login-page.tsx @@ -15,6 +15,21 @@ type SocialProvider = | 'kakao' | 'naver'; +const waitForMinimumLoadingTime = async ( + startTime: number, + minimumTime = 3000, +) => { + const elapsedTime = Date.now() - startTime; + const remainingTime = Math.max( + minimumTime - elapsedTime, + 0, + ); + + await new Promise((resolve) => + setTimeout(resolve, remainingTime), + ); +}; + interface SocialLoginResult { userId?: number; isNewUser: boolean; @@ -44,6 +59,9 @@ const LoginPage = () => { setError(''); setIsLoading(true); + const startTime = Date.now(); + + try { const response = await api.post( `/api/auth/login/${provider}`, @@ -63,6 +81,7 @@ const LoginPage = () => { setError( '소셜 회원가입 정보를 불러오지 못했습니다.', ); + setIsLoading(false); return; } @@ -82,19 +101,21 @@ const LoginPage = () => { setError( '로그인 토큰을 발급받지 못했습니다.', ); + setIsLoading(false); return; } setAccessToken(result.accessToken); + await waitForMinimumLoadingTime(startTime); + navigate('/'); } catch { - setError( - '소셜 로그인에 실패했습니다.', - ); - } finally { - setIsLoading(false); - } + setError( + '소셜 로그인에 실패했습니다.', + ); + setIsLoading(false); +} }, [navigate], ); @@ -320,6 +341,8 @@ const handleNaverLogin = () => { setError(''); setIsLoading(true); + const startTime = Date.now(); + try { const response = await api.post('/api/auth/login', { loginId: id.trim(), @@ -330,12 +353,15 @@ const handleNaverLogin = () => { setAccessToken(accessToken); + await waitForMinimumLoadingTime(startTime); + navigate('/'); } catch { - setError('아이디 혹은 비밀번호가 일치하지 않습니다'); - } finally { - setIsLoading(false); - } + setError( + '아이디 혹은 비밀번호가 일치하지 않습니다', + ); + setIsLoading(false); +} }; if (isLoading) { diff --git a/src/pages/signup/complete-page.tsx b/src/pages/signup/complete-page.tsx index c95c3f7..61b5665 100644 --- a/src/pages/signup/complete-page.tsx +++ b/src/pages/signup/complete-page.tsx @@ -1,11 +1,12 @@ -import { useEffect } from 'react'; +import { useEffect,useState, } from 'react'; import { useNavigate } from 'react-router-dom'; import { getAccessToken } from '../../apis/token'; - +import LoadingSpinner from '../../components/common/LoadingSpinner'; import CompleteCheckIcon from '../../assets/icons/signup-complete.svg?react'; const SignupCompletePage = () => { const navigate = useNavigate(); + const [isLoading, setIsLoading] =useState(false); useEffect(() => { const accessToken = getAccessToken(); @@ -24,12 +25,26 @@ const SignupCompletePage = () => { }, [navigate]); const handleStart = () => { - sessionStorage.removeItem('signupProfileCompleted'); - sessionStorage.removeItem('signupAgreedTermsIds'); + setIsLoading(true); + + sessionStorage.removeItem('signupProfileCompleted',); + sessionStorage.removeItem('signupAgreedTermsIds',); - navigate('/', { replace: true }); + setTimeout(() => { + navigate('/', { + replace: true, + }); + }, 3000); }; + if (isLoading) { + return ( +
+ +
+ ); +} + return (
diff --git a/src/pages/signup/signup-page.tsx b/src/pages/signup/signup-page.tsx index fa487ac..2ca7d5d 100644 --- a/src/pages/signup/signup-page.tsx +++ b/src/pages/signup/signup-page.tsx @@ -117,7 +117,27 @@ const SignupPage = () => { setVerificationCode(''); alert('인증번호를 발송했습니다.'); - } catch { + } catch (error) { + if (!axios.isAxiosError(error) || !error.response) { + alert('인증번호 발송에 실패했습니다.'); + return; + } + + const {code,message,} = error.response.data; + + // 이메일 형식이 올바르지 않은 경우 + if (code === 'COMMON_400_002') { + alert('올바른 형식의 이메일 주소가 아닙니다.'); + return; + } + + // 이미 가입된 이메일인 경우 + if (code === 'AUTH_409_001') { + alert(message); + return; + } + + // 그 외 오류 alert('인증번호 발송에 실패했습니다.'); } };