@@ -16,7 +16,8 @@ interface LoginScreenProps {
1616}
1717
1818export default function LoginScreen ( { onNext } : LoginScreenProps ) {
19- const [ isLoading , setIsLoading ] = useState ( false ) ;
19+ const [ isGoogleLoading , setIsGoogleLoading ] = useState ( false ) ;
20+ const [ isKakaoLoading , setIsKakaoLoading ] = useState ( false ) ;
2021 const {
2122 oauthState,
2223 setOauthState,
@@ -62,7 +63,8 @@ export default function LoginScreen({ onNext }: LoginScreenProps) {
6263 if ( error ) {
6364 console . error ( "OAuth 인증 오류:" , error ) ;
6465 console . error ( "OAuth 로그인 실패" ) ;
65- setIsLoading ( false ) ;
66+ setIsGoogleLoading ( false ) ;
67+ setIsKakaoLoading ( false ) ;
6668 return ;
6769 }
6870
@@ -74,7 +76,8 @@ export default function LoginScreen({ onNext }: LoginScreenProps) {
7476 if ( state && oauthState && state !== oauthState ) {
7577 console . error ( "State 파라미터가 일치하지 않습니다." ) ;
7678 console . error ( "OAuth state 파라미터 불일치" ) ;
77- setIsLoading ( false ) ;
79+ setIsGoogleLoading ( false ) ;
80+ setIsKakaoLoading ( false ) ;
7881 return ;
7982 }
8083
@@ -135,7 +138,7 @@ export default function LoginScreen({ onNext }: LoginScreenProps) {
135138 ] ) ;
136139
137140 const handleGoogleLogin = ( ) => {
138- setIsLoading ( true ) ;
141+ setIsGoogleLoading ( true ) ;
139142
140143 // 현재 페이지 상태 저장 (인증 후 돌아올 때 사용)
141144 const currentStep = "login" ;
@@ -151,9 +154,19 @@ export default function LoginScreen({ onNext }: LoginScreenProps) {
151154 } ;
152155
153156 const handleKakaoLogin = ( ) => {
154- // TODO: Implement Kakao login
155- login ( ) ;
156- onNext ( ) ;
157+ setIsKakaoLoading ( true ) ;
158+
159+ // 현재 페이지 상태 저장 (인증 후 돌아올 때 사용)
160+ const currentStep = "login" ;
161+ setOauthReturnStep ( currentStep ) ;
162+
163+ // CSRF 보호를 위한 state 파라미터 생성
164+ const state = Math . random ( ) . toString ( 36 ) . substring ( 2 , 15 ) ;
165+ setOauthState ( state ) ;
166+
167+ // Kakao OAuth 인증 페이지로 리다이렉트
168+ const redirect_uri = `${ process . env . NEXT_PUBLIC_FRONTEND_BASE_URL } /onboarding` ;
169+ window . location . href = `${ OAUTH_ENDPOINTS . KAKAO_AUTHORIZE } ?redirect_uri=${ redirect_uri } &state=${ state } ` ;
157170 } ;
158171
159172 const handleBrowse = ( ) => {
@@ -212,27 +225,32 @@ export default function LoginScreen({ onNext }: LoginScreenProps) {
212225 { /* Google Login */ }
213226 < button
214227 onClick = { handleGoogleLogin }
215- disabled = { isLoading }
228+ disabled = { isGoogleLoading }
216229 className = "w-full flex items-center justify-center gap-2 py-[15px] px-4 bg-background-alternative border border-line-normal rounded-lg disabled:opacity-50 disabled:cursor-not-allowed"
217230 >
218- { isLoading ? (
231+ { isGoogleLoading ? (
219232 < div className = "w-6 h-6 border-2 border-label-normal border-t-transparent rounded-full animate-spin" > </ div >
220233 ) : (
221234 < GoogleIcon size = { 24 } />
222235 ) }
223236 < span className = "text-sm font-semibold text-label-normal" >
224- { isLoading ? "로그인 중..." : "Google로 시작하기" }
237+ { isGoogleLoading ? "로그인 중..." : "Google로 시작하기" }
225238 </ span >
226239 </ button >
227240
228241 { /* Kakao Login */ }
229242 < button
230243 onClick = { handleKakaoLogin }
231- className = "w-full flex items-center justify-center gap-2 py-[15px] px-4 bg-[#FEE500] rounded-lg"
244+ disabled = { isKakaoLoading }
245+ className = "w-full flex items-center justify-center gap-2 py-[15px] px-4 bg-[#FEE500] rounded-lg disabled:opacity-50 disabled:cursor-not-allowed"
232246 >
233- < KakaoIcon size = { 24 } />
247+ { isKakaoLoading ? (
248+ < div className = "w-6 h-6 border-2 border-label-normal border-t-transparent rounded-full animate-spin" > </ div >
249+ ) : (
250+ < KakaoIcon size = { 24 } />
251+ ) }
234252 < span className = "text-sm font-semibold text-label-normal" >
235- 카카오로 시작하기
253+ { isKakaoLoading ? "로그인 중..." : " 카카오로 시작하기" }
236254 </ span >
237255 </ button >
238256
0 commit comments