11'use client' ;
22
3- import { useState } from 'react' ;
3+ import { useSearchParams } from 'next/navigation' ;
4+ import { useEffect , useState } from 'react' ;
5+ import { env } from '@/lib/env' ;
46import { zodResolver } from '@hookform/resolvers/zod' ;
57import { SubmitHandler , useForm } from 'react-hook-form' ;
68import { loginSchema } from '@/schema/authSchema' ;
79import { LoginRequest } from '@/type/auth/authRequest' ;
10+ import { saveTokens } from '@/utils/saveTokens' ;
811import Button from '@/components/common/Button/Button' ;
912import Icon from '@/components/common/Icon' ;
1013import { Input } from '@/components/common/Input' ;
@@ -16,6 +19,7 @@ import {
1619 Subtitle2Black ,
1720} from '@/components/common/Typography' ;
1821import { BASE_ROUTES } from '@/constants/_navbar' ;
22+ import { usePostGoogleLogin } from '@/hooks/auth/usePostGoogleLogin' ;
1923import { usePostLogin } from '@/hooks/auth/usePostLogin' ;
2024import { useAuth } from '@/hooks/useAuth' ;
2125import useNavigate from '@/hooks/useNavigate' ;
@@ -24,12 +28,17 @@ import { useUserStore } from '@/stores/useUserStore';
2428
2529const LoginBody = ( ) => {
2630 const { navigate } = useNavigate ( ) ;
27- const [ isShowPassword , setIsShowPassword ] = useState ( false ) ;
28- const { mutate : loginMutate } = usePostLogin ( ) ;
2931 const { login } = useAuth ( ) ;
32+ const searchParams = useSearchParams ( ) ;
33+
34+ const [ isShowPassword , setIsShowPassword ] = useState ( false ) ;
35+
3036 const showToast = useToastStore ( ( set ) => set . showToast ) ;
3137 const setUserInfo = useUserStore ( ( set ) => set . setUserInfo ) ;
3238
39+ const { mutate : loginMutate } = usePostLogin ( ) ;
40+ const { mutate : googleLoginMutate } = usePostGoogleLogin ( ) ;
41+
3342 const {
3443 register,
3544 handleSubmit,
@@ -52,12 +61,40 @@ const LoginBody = () => {
5261 login ( ) ;
5362 } ,
5463 onError : ( error ) => {
55- error . message ;
5664 showToast ( `${ error . message } 로그인 실패` , 'warning' , 1000 ) ;
5765 } ,
5866 } ) ;
5967 } ;
6068
69+ const googleLoginHandler = ( ) => {
70+ navigate (
71+ `https://accounts.google.com/o/oauth2/v2/auth?client_id=${ env . GOOGLE_CLIENT_ID } &redirect_uri=${ env . GOOGLE_REDIRECT_URL } &response_type=code&scope=email%20profile%20openid&access_type=offline` ,
72+ ) ;
73+ } ;
74+
75+ useEffect ( ( ) => {
76+ const authCode = searchParams . get ( 'code' ) ;
77+ if ( authCode ) {
78+ googleLoginMutate (
79+ { authCode : authCode || '' } ,
80+ {
81+ onSuccess : ( data ) => {
82+ const { username, userId, email } = data . data ;
83+ setUserInfo ( username , userId , email ) ;
84+ login ( ) ;
85+ saveTokens ( {
86+ accessToken : data . data . accessToken ,
87+ refreshToken : data . data . refreshToken ,
88+ } ) ;
89+ } ,
90+ onError : ( ) => {
91+ showToast ( '구글 로그인 실패' , 'warning' , 1000 ) ;
92+ } ,
93+ } ,
94+ ) ;
95+ }
96+ } , [ searchParams ] ) ;
97+
6198 return (
6299 < div className = 'flex w-[480px] flex-col items-center gap-10' >
63100 < form onSubmit = { handleSubmit ( onSubmit ) } className = 'w-full' >
@@ -131,6 +168,7 @@ const LoginBody = () => {
131168 width = 'full'
132169 size = 'md'
133170 variant = 'outline'
171+ onClick = { ( ) => googleLoginHandler ( ) }
134172 >
135173 < Icon name = 'google' width = { 24 } height = { 24 } />
136174 < Subtitle2Black > 구글로 시작하기</ Subtitle2Black >
0 commit comments