@@ -3,14 +3,38 @@ import { View, Text, TextInput, TouchableOpacity, StyleSheet, Alert, KeyboardAvo
33import { SafeAreaView } from 'react-native-safe-area-context' ;
44import { Ionicons } from '@expo/vector-icons' ;
55import AsyncStorage from '@react-native-async-storage/async-storage' ;
6+ import { GoogleSignin , statusCodes } from '@react-native-google-signin/google-signin' ;
67import { colors } from '../theme/colors' ;
78import { useApp } from '../context/AppContext' ;
89
10+ GoogleSignin . configure ( {
11+ webClientId : '1076957044730-mht8sbihb0d4661hprrvbjf9v4gb0njr.apps.googleusercontent.com' ,
12+ offlineAccess : true ,
13+ } ) ;
14+
915export default function LoginScreen ( { navigation } ) {
1016 const [ isSignUp , setIsSignUp ] = useState ( false ) ;
1117 const [ form , setForm ] = useState ( { name : '' , email : '' , password : '' , confirm : '' } ) ;
1218 const { login } = useApp ( ) ;
1319
20+ const handleGoogleSignIn = async ( ) => {
21+ try {
22+ await GoogleSignin . hasPlayServices ( ) ;
23+ const userInfo = await GoogleSignin . signIn ( ) ;
24+ const user = {
25+ name : userInfo . data . user . name ,
26+ email : userInfo . data . user . email ,
27+ picture : userInfo . data . user . photo ,
28+ } ;
29+ await login ( user ) ;
30+ navigation . goBack ( ) ;
31+ } catch ( error ) {
32+ if ( error . code === statusCodes . SIGN_IN_CANCELLED ) return ;
33+ if ( error . code === statusCodes . IN_PROGRESS ) return ;
34+ Alert . alert ( 'Google Sign In Failed' , error . message ) ;
35+ }
36+ } ;
37+
1438 const handleAuth = async ( ) => {
1539 if ( ! form . email || ! form . password ) { Alert . alert ( 'Error' , 'Please fill all fields' ) ; return ; }
1640 if ( isSignUp ) {
@@ -59,6 +83,17 @@ export default function LoginScreen({ navigation }) {
5983 < Text style = { styles . authBtnTxt } > { isSignUp ? 'CREATE ACCOUNT' : 'SIGN IN' } </ Text >
6084 </ TouchableOpacity >
6185
86+ < View style = { styles . separator } >
87+ < View style = { styles . sepLine } />
88+ < Text style = { styles . sepTxt } > OR CONTINUE WITH</ Text >
89+ < View style = { styles . sepLine } />
90+ </ View >
91+
92+ < TouchableOpacity style = { styles . googleBtn } onPress = { handleGoogleSignIn } >
93+ < Text style = { styles . googleG } > G</ Text >
94+ < Text style = { styles . googleBtnTxt } > { isSignUp ? 'Sign up with Google' : 'Sign in with Google' } </ Text >
95+ </ TouchableOpacity >
96+
6297 < TouchableOpacity style = { styles . switchBtn } onPress = { ( ) => setIsSignUp ( ! isSignUp ) } >
6398 < Text style = { styles . switchTxt } >
6499 { isSignUp ? 'Already have an account? ' : "Don't have an account? " }
@@ -80,6 +115,12 @@ const styles = StyleSheet.create({
80115 input : { width : '100%' , borderWidth : 1.5 , borderColor : colors . border , borderRadius : 12 , paddingHorizontal : 16 , paddingVertical : 14 , fontSize : 15 , color : colors . dark , marginBottom : 14 } ,
81116 authBtn : { width : '100%' , backgroundColor : colors . brand , borderRadius : 12 , paddingVertical : 16 , alignItems : 'center' , marginTop : 4 } ,
82117 authBtnTxt : { color : colors . white , fontWeight : '800' , fontSize : 15 , letterSpacing : 1 } ,
118+ separator : { flexDirection : 'row' , alignItems : 'center' , width : '100%' , marginVertical : 16 , gap : 10 } ,
119+ sepLine : { flex : 1 , height : 1 , backgroundColor : colors . border } ,
120+ sepTxt : { fontSize : 11 , color : colors . gray , fontWeight : '600' , letterSpacing : 0.5 } ,
121+ googleBtn : { width : '100%' , flexDirection : 'row' , alignItems : 'center' , justifyContent : 'center' , gap : 10 , borderWidth : 1.5 , borderColor : colors . border , borderRadius : 12 , paddingVertical : 14 } ,
122+ googleG : { fontSize : 18 , fontWeight : '800' , color : '#4285F4' } ,
123+ googleBtnTxt : { fontSize : 14 , fontWeight : '600' , color : colors . dark } ,
83124 switchBtn : { marginTop : 20 } ,
84125 switchTxt : { fontSize : 14 , color : colors . gray } ,
85126 switchLink : { color : colors . brand , fontWeight : '700' } ,
0 commit comments