Created
February 11, 2019 20:42
-
-
Save jrdn91/f6656f7eb90d161b39f9fe7701d22dd1 to your computer and use it in GitHub Desktop.
Login Page
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import { connect } from 'react-redux'; | |
import { Container, Button, Form, Item, Input, Label } from 'native-base'; | |
import { | |
NativeModules, | |
LayoutAnimation, | |
Animated, | |
View, | |
Keyboard, | |
ScrollView, | |
TouchableWithoutFeedback, | |
Image, | |
ImageBackground, | |
Text, | |
Dimensions, | |
Easing, | |
StatusBar, | |
Platform, | |
AsyncStorage | |
} from 'react-native'; | |
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view' | |
import { withTheme } from 'react-native-material-ui'; | |
import styles from './styles'; | |
import { login, register, sendPin, socialLogin } from '../../actions/authentication'; | |
import { openSnackBar } from '../../actions/snack-bar'; | |
import { formatNumber } from 'libphonenumber-js' | |
import Dialog from '../../components/Dialog'; | |
import PinInput from '../../components/PinInput'; | |
import PhoneInput from '../../components/PhoneInput'; | |
import { getGroups } from '../../actions/groups'; | |
import theme from '../../native-base-theme/variables/material'; | |
import LoadingButton from 'react-native-material-loading-button'; | |
import { LoginButton, LoginManager, AccessToken, GraphRequest, GraphRequestManager } from 'react-native-fbsdk'; | |
import { GoogleSignin, statusCodes } from 'react-native-google-signin'; | |
import packageJson from '../../package.json' | |
import { updateUser } from '../../actions/users'; | |
import { pubnub } from '../../components/App'; | |
const { version } = packageJson; | |
const { UIManager } = NativeModules; | |
const graphRequestManager = new GraphRequestManager(); | |
GoogleSignin.configure(); | |
UIManager.setLayoutAnimationEnabledExperimental && | |
UIManager.setLayoutAnimationEnabledExperimental(true); | |
export class Login extends React.Component { | |
initialHeight = Dimensions.get('window').height; | |
initialWidth = Dimensions.get('window').width; | |
state = { | |
phone: '', | |
password: '', | |
email: '', | |
logoWrapperHeight: '100%', | |
inputViewTop: this.initialHeight, | |
slideInAnim: new Animated.Value(this.initialHeight), | |
slideRegisterAnim: new Animated.Value(this.initialWidth), | |
trackWidth: 0, | |
isRegister: false, | |
inputs: {}, | |
forgotLoginDialogOpen: false, | |
pinSent: false, | |
forgotLoginDialogErrorMessage: '', | |
forgotLoginDialogErrorOpen: false, | |
forgotLoginModalVisible: false, | |
snackBarMessage: "", | |
snackBarOpen: false, | |
enterPhoneModalVisible: false | |
}; | |
componentDidMount = () => { | |
console.log('mounted') | |
setTimeout(() => { | |
Animated.timing( | |
this.state.slideInAnim, | |
{ | |
toValue: 0, | |
duration: 650, | |
} | |
).start(); | |
// LayoutAnimation.configureNext({ | |
// duration: 650, | |
// create: { | |
// type: LayoutAnimation.Types.easeOut, | |
// property: LayoutAnimation.Properties.height | |
// }, | |
// update: { | |
// type: LayoutAnimation.Types.easeOut | |
// }, | |
// }); | |
LayoutAnimation.easeInEaseOut(); | |
this.setState({ logoWrapperHeight: '35%' }) | |
}, 500); | |
} | |
_focusNextField(id) { | |
this.state.inputs[id]._root.focus(); | |
} | |
_handleLogin = () => { | |
Keyboard.dismiss() | |
setTimeout(() => { | |
this.setState({ | |
loggingIn: true | |
}) | |
const { phone, password } = this.state | |
this.props.dispatch(login({ phone: `+1${phone.replace(/[()\s-]/g, '')}`, password })).then((res) => { | |
this.setState({ | |
loggingIn: false | |
}) | |
AsyncStorage.getItem('onBoarded').then((res)=> { | |
if (res === 'true') { | |
this.props.navigation.navigate("Map") | |
} else { | |
this.props.navigation.navigate("OnBoarding") | |
} | |
}) | |
this.props.dispatch(getGroups()).then(res => { | |
}).catch(err => console.log(err.response.body)) | |
}).catch((err) => { | |
this.setState({ | |
loggingIn: false | |
}) | |
this.props.dispatch(openSnackBar({ | |
message: 'There was an error logging in' | |
})) | |
console.log(err); | |
}) | |
}, 40); | |
} | |
_handleRegister = () => { | |
Keyboard.dismiss() | |
this.setState({ | |
registering: true | |
}) | |
const { phone, email, firstName, lastName, password } = this.state | |
this.props.dispatch(register({ phone: `+1${phone.replace(/[()\s-]/g, '')}`, email, first_name: firstName, last_name: lastName, password, login_type: 'password' })).then((res) => { | |
this.setState({ | |
registering: false | |
}) | |
this.props.dispatch(getGroups()).then(res => { | |
AsyncStorage.getItem('onBoarded').then((res)=> { | |
if (res === 'true') { | |
this.props.navigation.navigate("Map") | |
} else { | |
this.props.navigation.navigate("OnBoarding") | |
} | |
}) | |
}).catch(err => console.log(err.response.body)) | |
}).catch((err) => { | |
this.setState({ | |
registering: false | |
}) | |
console.log(err); | |
let message = "There was an error with your registration"; | |
if (err.message === "users create error") { | |
if (err.error.code === "ER_DUP_ENTRY") { | |
if (err.error.sqlMessage.indexOf("for key 'phone'") > -1) { | |
message = "That phone number is already in our system"; | |
} | |
} | |
} | |
this.props.dispatch( | |
openSnackBar({ | |
message | |
}) | |
); | |
}) | |
} | |
_handleSwitch = () => { | |
if (this.state.isRegister) { | |
// is register, switch to login | |
Animated.timing( | |
this.state.slideRegisterAnim, | |
{ | |
toValue: this.initialWidth, | |
duration: 250, | |
easing: Easing.easeInOut | |
} | |
).start(); | |
setTimeout(() => { | |
this.setState({ isRegister: false }); | |
}, 250); | |
} else { | |
// is not login, switch to register | |
Animated.timing( | |
this.state.slideRegisterAnim, | |
{ | |
toValue: 0, | |
duration: 250, | |
easing: Easing.easeInOut | |
} | |
).start(); | |
setTimeout(() => { | |
this.setState({ isRegister: true }); | |
}, 250); | |
} | |
} | |
_sendPin = () => { | |
if (!this.state.phone) { | |
this.setState({ | |
snackBarMessage: "Please enter your mobile number", | |
snackBarOpen: true | |
}); | |
return; | |
} | |
this.props.dispatch(sendPin(`+1${this.state.phone.replace(/[()\s-]/g, '')}`)).then((res) => { | |
this.setState({ pinSent: true }); | |
}).catch((err) => { | |
console.log(err); | |
this.setState({ | |
snackBarMessage: "There was an error texting pin number", | |
snackBarOpen: true | |
}); | |
}) | |
} | |
_checkPin = () => { | |
const { phone, auth_code } = this.state | |
this.props.dispatch(login({ phone: `+1${phone.replace(/[()\s-]/g, '')}`, auth_code })).then((res) => { | |
this.props.dispatch(getGroups()).then(res => { | |
AsyncStorage.getItem('onBoarded').then((res)=> { | |
if (res === 'true') { | |
this.props.navigation.navigate("Map") | |
} else { | |
this.props.navigation.navigate("OnBoarding") | |
} | |
}) | |
}).catch(err => console.log(err.response.body)) | |
}).catch((err) => { | |
console.log(err); | |
}) | |
} | |
_handleOk = () => { | |
if (this.state.pinSent) { | |
this._checkPin(); | |
} else { | |
this._sendPin(); | |
} | |
} | |
_handleSendPin = () => { | |
this.setState({ | |
forgotLoginModalVisible: true | |
}) | |
} | |
_handlePhoneSubmit = () => { | |
if (this.state.pinSent) { | |
const { phone, auth_code } = this.state | |
this.setState({ | |
checkingPin: true | |
}) | |
this.props.dispatch(login({ phone: `+1${phone.replace(/[()\s-]/g, '')}`, auth_code })).then((res) => { | |
const { email, first_name, last_name, ...rest } = this.state.socialData | |
this.props.dispatch(updateUser(res.id, rest)).then(res => { | |
this.props.dispatch(getGroups()).then(res => { | |
this.setState({ | |
checkingPin: false | |
}) | |
AsyncStorage.getItem('onBoarded').then((res)=> { | |
if (res === 'true') { | |
this.props.navigation.navigate("Map") | |
} else { | |
this.props.navigation.navigate("OnBoarding") | |
} | |
}) | |
}).catch(err => console.log(err.response.body)) | |
}) | |
}).catch((err) => { | |
console.log(err) | |
if (err.type === 'not found') { | |
const { phone } = this.state | |
this.props.dispatch(register({ phone: `+1${phone.replace(/[()\s-]/g, '')}`, ...this.state.socialData })).then((res) => { | |
this.props.dispatch(getGroups()).then(res => { | |
AsyncStorage.getItem('onBoarded').then((res)=> { | |
if (res === 'true') { | |
this.props.navigation.navigate("Map") | |
} else { | |
this.props.navigation.navigate("OnBoarding") | |
} | |
}) | |
}).catch(err => { | |
console.log(err) | |
this.props.dispatch( | |
openSnackBar({ | |
message: "There was an error registering this number" | |
}) | |
); | |
this.setState({ | |
loggingInWithFacebook: false, | |
loggingInWithGoogle: false | |
}) | |
}) | |
}).catch((err) => { | |
console.log(err); | |
this.props.dispatch( | |
openSnackBar({ | |
message: "There was an error with your registration" | |
}) | |
); | |
this.setState({ | |
loggingInWithFacebook: false, | |
loggingInWithGoogle: false | |
}) | |
}) | |
} else { | |
this.setState({ | |
checkingPin: false | |
}) | |
this.props.dispatch( | |
openSnackBar({ | |
message: "There was an error with this registration" | |
}) | |
); | |
} | |
}) | |
} else { | |
this._sendPin(); | |
} | |
} | |
_handleSocialLogin = (data) => { | |
this.props.dispatch(socialLogin(data)).then(res => { | |
this.props.dispatch(getGroups()).then(res => { | |
this.setState({ | |
loggingInWithFacebook: false, | |
loggingInWithGoogle: false | |
}) | |
AsyncStorage.getItem('onBoarded').then((res)=> { | |
if (res === 'true') { | |
this.props.navigation.navigate("Map") | |
} else { | |
this.props.navigation.navigate("OnBoarding") | |
} | |
}) | |
}).catch(err => console.log(err.response.body)) | |
}).catch(err => { | |
console.log(err) | |
pubnub.publish({ | |
message: { | |
method: '_handleSocialLogin', | |
file: 'components/app/index.js', | |
varName: 'social login .catch', | |
err | |
}, | |
channel: `debug_channel`, | |
sendByPost: false, // true to send via post | |
storeInHistory: false, //override default storage options | |
}); | |
if (err.err === 'not found') { | |
console.log('is not found') | |
this.setState({ | |
enterPhoneModalVisible: true, | |
socialData: data | |
}) | |
} else { | |
this.props.dispatch( | |
openSnackBar({ | |
message: "There was an error logging in, please try again" | |
}) | |
); | |
this.setState({ | |
loggingInWithFacebook: false, | |
loggingInWithGoogle: false | |
}) | |
} | |
}) | |
} | |
_facebookGraphCallback = (err, data) => { | |
if (err) { | |
pubnub.publish({ | |
message: { | |
method: '_facebookGraphCallback', | |
file: 'components/app/index.js', | |
varName: 'graph err', | |
err | |
}, | |
channel: `debug_channel`, | |
sendByPost: false, // true to send via post | |
storeInHistory: false, //override default storage options | |
}); | |
this.setState({ | |
loggingInWithFacebook: false | |
}) | |
console.log('graph error',err) | |
} else { | |
const {id, ...rest} = data | |
this._handleSocialLogin({...rest, facebook: id}) | |
} | |
} | |
facebookLogin = async () => { | |
// native_only config will fail in the case that the user has | |
// not installed in his device the Facebook app. In this case we | |
// need to go for webview. | |
let result; | |
try { | |
this.setState({ | |
loggingInWithFacebook: true | |
}) | |
console.log(LoginManager) | |
LoginManager.logOut(); | |
LoginManager.setLoginBehavior('native'); | |
result = await LoginManager.logInWithReadPermissions(['public_profile', 'email']); | |
pubnub.publish({ | |
message: { | |
method: 'facebookLogin', | |
file: 'components/app/index.js', | |
varName: 'try LoginManager.logInWithReadPermissions native result', | |
result: result | |
}, | |
channel: `debug_channel`, | |
sendByPost: false, // true to send via post | |
storeInHistory: false, //override default storage options | |
}); | |
} catch (nativeError) { | |
console.log(nativeError) | |
pubnub.publish({ | |
message: { | |
method: 'facebookLogin', | |
file: 'components/app/index.js', | |
varName: 'try LoginManager.logInWithReadPermissions native catch', | |
err: nativeError | |
}, | |
channel: `debug_channel`, | |
sendByPost: false, // true to send via post | |
storeInHistory: false, //override default storage options | |
}); | |
this.setState({ | |
loggingInWithFacebook: false | |
}) | |
this.props.dispatch(openSnackBar({ | |
message: "There was an error logging in, please try again" | |
})) | |
} | |
// handle the case that users clicks cancel button in Login view | |
console.log(result) | |
if (result.isCancelled) { | |
this.setState({ | |
loggingInWithFacebook: false | |
}) | |
} else { | |
// Create a graph request asking for user information | |
this.FBGraphRequest('first_name, last_name, id, email', this.FBLoginCallback); | |
} | |
} | |
FBGraphRequest = async (fields, callback) => { | |
const accessData = await AccessToken.getCurrentAccessToken(); | |
// Create a graph request asking for user information | |
const infoRequest = new GraphRequest('/me', { | |
accessToken: accessData.accessToken, | |
parameters: { | |
fields: { | |
string: fields | |
} | |
} | |
}, callback); | |
// Execute the graph request created above | |
new GraphRequestManager().addRequest(infoRequest).start(); | |
} | |
FBLoginCallback = async (error, result) => { | |
if (error) { | |
pubnub.publish({ | |
message: { | |
method: 'FBLoginCallback', | |
file: 'components/app/index.js', | |
varName: 'callback error', | |
err: error | |
}, | |
channel: `debug_channel`, | |
sendByPost: false, // true to send via post | |
storeInHistory: false, //override default storage options | |
}); | |
this.setState({ | |
loggingInWithFacebook: false | |
}); | |
} else { | |
// Retrieve and save user details in state. In our case with | |
// Redux and custom action saveUser | |
const {id, picture, ...rest} = result | |
this._handleSocialLogin({...rest, facebook: id}) | |
} | |
} | |
// _loginWithFacebook = () => { | |
// // LoginManager.logOut(); | |
// try { | |
// this.setState({ | |
// loggingInWithFacebook: true | |
// }) | |
// AccessToken.getCurrentAccessToken().then( | |
// (data) => { | |
// if (data) { | |
// try { | |
// if (graphRequestManager.requestBatch.length === 0) { | |
// let infoRequest = new GraphRequest('/me', {parameters: {fields: {string: 'first_name,last_name,email'}}}, this._facebookGraphCallback); | |
// graphRequestManager.addRequest(infoRequest) | |
// } | |
// graphRequestManager.start() | |
// } catch (e) { | |
// pubnub.publish({ | |
// message: { | |
// method: '_loginWithFacebook', | |
// file: 'components/app/index.js', | |
// varName: 'try infoRequest catch - had no data', | |
// err: e | |
// }, | |
// channel: `debug_channel`, | |
// sendByPost: false, // true to send via post | |
// storeInHistory: false, //override default storage options | |
// }); | |
// } | |
// } else { | |
// LoginManager.logOut() | |
// LoginManager.logInWithReadPermissions(['public_profile','email']).then((result) => { | |
// if (!result.isCancelled) { | |
// try { | |
// let infoRequest = new GraphRequest('/me', {parameters: {fields: {string: 'first_name,last_name,email'}}}, this._facebookGraphCallback); | |
// graphRequestManager.addRequest(infoRequest).start() | |
// } catch (e) { | |
// pubnub.publish({ | |
// message: { | |
// method: '_loginWithFacebook', | |
// file: 'components/app/index.js', | |
// varName: 'try infoRequest catch - had data', | |
// err: e | |
// }, | |
// channel: `debug_channel`, | |
// sendByPost: false, // true to send via post | |
// storeInHistory: false, //override default storage options | |
// }); | |
// console.log(e) | |
// } | |
// } | |
// }, (error) => { | |
// pubnub.publish({ | |
// message: { | |
// method: '_loginWithFacebook', | |
// file: 'components/app/index.js', | |
// varName: 'LoginManager.logInWithReadPermissions error', | |
// err: error | |
// }, | |
// channel: `debug_channel`, | |
// sendByPost: false, // true to send via post | |
// storeInHistory: false, //override default storage options | |
// }); | |
// this.setState({ | |
// loggingInWithFacebook: false | |
// }) | |
// }); | |
// } | |
// } | |
// ).catch(err => { | |
// this.setState({ | |
// loggingInWithFacebook: false | |
// }) | |
// pubnub.publish({ | |
// message: { | |
// method: '_loginWithFacebook', | |
// file: 'components/app/index.js', | |
// varName: 'AccessToken.getCurrentAccessToken.catch', | |
// err | |
// }, | |
// channel: `debug_channel`, | |
// sendByPost: false, // true to send via post | |
// storeInHistory: false, //override default storage options | |
// }); | |
// console.log(err) | |
// }) | |
// } catch(e) { | |
// pubnub.publish({ | |
// message: { | |
// method: '_loginWithFacebook', | |
// file: 'components/app/index.js', | |
// varName: 'catch', | |
// err: e | |
// }, | |
// channel: `debug_channel`, | |
// sendByPost: false, // true to send via post | |
// storeInHistory: false, //override default storage options | |
// }); | |
// console.log(e) | |
// } | |
// } | |
_loginWithGoogle = async () => { | |
try { | |
this.setState({ | |
loggingInWithGoogle: true | |
}) | |
await GoogleSignin.hasPlayServices(); | |
const userInfo = await GoogleSignin.signIn(); | |
this._handleSocialLogin({google: userInfo.user.id, email: userInfo.user.email, first_name: userInfo.user.givenName, last_name: userInfo.user.familyName}) | |
} catch (error) { | |
if (error.code === statusCodes.SIGN_IN_CANCELLED) { | |
// user cancelled the login flow | |
} else if (error.code === statusCodes.IN_PROGRESS) { | |
// operation (f.e. sign in) is in progress already | |
} else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) { | |
// play services not available or outdated | |
} else { | |
// some other error happened | |
} | |
} | |
} | |
render() { | |
let { firstName, lastName, phone, password, email, trackWidth, slideInAnim, slideRegisterAnim, logoWrapperHeight } = this.state; | |
const backgroundImage = Platform.OS === 'ios' ? 'background_image' : 'asset:/background_image.png'; | |
const logoImage = Platform.OS === 'ios' ? 'Logo' : 'asset:/Logo.png'; | |
console.log(this.state.enterPhoneModalVisible) | |
return ( | |
<KeyboardAwareScrollView> | |
<StatusBar | |
backgroundColor="transparent" | |
barStyle="light-content" | |
/> | |
<View style={styles.container}> | |
<Dialog | |
colorAccent={theme.brandPrimary} | |
visible={this.state.enterPhoneModalVisible} | |
onOk={this._handlePhoneSubmit} | |
onCancel={() => this.setState({ enterPhoneModalVisible: false })} | |
snackBarMessage={this.state.snackBarMessage} | |
snackBarOpen={this.state.snackBarOpen} | |
onSnackBarClose={() => this.setState({ snackBarOpen: false })} | |
isLoading={this.state.checkingPin}> | |
<View> | |
{this.state.pinSent && | |
<View> | |
<Text style={styles.dialogText}> | |
Enter the pin number we just texted to complete registration | |
</Text> | |
<Text style={styles.phoneNumberText}> | |
{formatNumber(`+1${this.state.phone}`, 'National')} | |
</Text> | |
<PinInput onPinComplete={auth_code => this.setState({ auth_code })} /> | |
</View> | |
} | |
{!this.state.pinSent && | |
<View> | |
<Text style={styles.dialogText}> | |
Enter your mobile number to complete registration | |
</Text> | |
<Form> | |
<PhoneInput | |
value={phone} | |
onChangeText={(phone) => this.setState({ phone })} /> | |
</Form> | |
</View> | |
} | |
</View> | |
</Dialog> | |
<Dialog | |
colorAccent={theme.brandPrimary} | |
visible={this.state.forgotLoginModalVisible} | |
onOk={this._handleOk} | |
onCancel={() => this.setState({ forgotLoginModalVisible: false, pinSent: false })} | |
snackBarMessage={this.state.snackBarMessage} | |
snackBarOpen={this.state.snackBarOpen} | |
onSnackBarClose={() => this.setState({ snackBarOpen: false })}> | |
<View> | |
{this.state.pinSent && | |
<View> | |
<Text style={styles.dialogText}> | |
We just texted a login pin to | |
</Text> | |
<Text style={styles.phoneNumberText}> | |
{formatNumber(`+1${this.state.phone}`, 'National')} | |
</Text> | |
<PinInput onPinComplete={auth_code => this.setState({ auth_code })} /> | |
</View> | |
} | |
{!this.state.pinSent && | |
<View> | |
<Text style={styles.dialogText}> | |
Enter your mobile number and we will text you a pin number | |
</Text> | |
<Form> | |
<PhoneInput | |
value={phone} | |
onChangeText={(phone) => this.setState({ phone })} /> | |
</Form> | |
</View> | |
} | |
</View> | |
</Dialog> | |
<ImageBackground style={styles.backgroundImage} imageStyle={styles.backgroundImageStyle} source={{uri: backgroundImage}}> | |
<View style={{flex: 1}}> | |
<View style={[styles.logoView, { | |
height: logoWrapperHeight | |
}]}> | |
<Image style={styles.logoImage} source={{ uri: logoImage }} /> | |
</View> | |
<Animated.View style={[styles.inputView, {transform: [{ | |
translateY: slideInAnim | |
}]} | |
]}> | |
<View style={styles.switchView}> | |
<View style={styles.switchInner} onLayout={(event) => { | |
this.setState({ trackWidth: event.nativeEvent.layout.width }) | |
}}> | |
<Animated.View style={{ | |
width: '50%', | |
position: 'absolute', | |
zIndex: 1300, | |
transform: [{ | |
translateX: slideRegisterAnim.interpolate({ | |
inputRange: [0, this.initialWidth], | |
outputRange: [trackWidth / 2, 0] | |
}) | |
}] | |
}}> | |
<Button rounded block onPress={this._handleSwitch} style={styles.switchButton}><Text style={styles.switchButtonText}>{this.state.isRegister ? "REGISTER" : "LOGIN"}</Text></Button> | |
</Animated.View> | |
<TouchableWithoutFeedback onPress={this._handleSwitch}> | |
<View style={styles.switchSlideTextView}> | |
<Text style={styles.switchSlideText}>LOGIN</Text> | |
</View> | |
</TouchableWithoutFeedback> | |
<TouchableWithoutFeedback onPress={this._handleSwitch}> | |
<View style={styles.switchSlideTextView}> | |
<Text style={styles.switchSlideText}>REGISTER</Text> | |
</View> | |
</TouchableWithoutFeedback> | |
</View> | |
</View> | |
<View style={styles.inputWrapper}> | |
<Animated.ScrollView style={[styles.formView, styles.loginForm, { | |
transform: [{ | |
translateX: slideRegisterAnim.interpolate({ | |
inputRange: [0, this.initialWidth], | |
outputRange: [-this.initialWidth, 0] | |
}) | |
}] | |
}]} keyboardShouldPersistTaps='handled'> | |
<Form> | |
<PhoneInput | |
value={phone} | |
onChangeText={(phone) => this.setState({ phone })} /> | |
<Item style={{ marginLeft: 0 }} floatingLabel> | |
<Label>Password</Label> | |
<Input | |
secureTextEntry | |
value={password} | |
onChangeText={ (password) => this.setState({ password }) } | |
/> | |
</Item> | |
</Form> | |
<View style={styles.loginButton}> | |
<LoadingButton | |
text={'LOGIN'} | |
disabled={!phone || !password} | |
isLoading={this.state.loggingIn} | |
onPress={this._handleLogin} | |
color={theme.brandPrimary} | |
/> | |
<Button transparent block onPress={this._handleSendPin}><Text>FORGOT LOGIN?</Text></Button> | |
</View> | |
<View style={styles.loginWithView}> | |
<View style={styles.loginWithBar}><View style={styles.bar}/></View> | |
<View style={styles.loginWithTextView}> | |
<Text style={styles.loginWithText}>log in with</Text> | |
</View> | |
<View style={styles.loginWithBar}><View style={styles.bar}/></View> | |
</View> | |
<View style={styles.socialButtons}> | |
<View style={styles.buttonWrapper}> | |
<LoadingButton | |
text={'FACEBOOK'} | |
isLoading={this.state.loggingInWithFacebook} | |
onPress={this.facebookLogin} | |
color={'#4367b3'} | |
/> | |
</View> | |
<View style={styles.buttonWrapper}> | |
<LoadingButton | |
text={'GOOGLE'} | |
isLoading={this.state.loggingInWithGoogle} | |
onPress={this._loginWithGoogle} | |
color={'#db4437'} | |
/> | |
</View> | |
</View> | |
</Animated.ScrollView> | |
<Animated.ScrollView style={[styles.formView, styles.registerForm, { | |
transform: [{ | |
translateX: slideRegisterAnim | |
}] | |
}]} keyboardShouldPersistTaps='handled'> | |
<Form> | |
<Item style={{ marginLeft: 0 }} floatingLabel> | |
<Label>First Name</Label> | |
<Input | |
value={firstName} | |
blurOnSubmit={ false } | |
onSubmitEditing={() => { | |
this._focusNextField('lastName'); | |
}} | |
returnKeyType={ "next" } | |
onChangeText={ (firstName) => this.setState({ firstName }) } | |
getRef={ input => { | |
this.state.inputs['firstName'] = input; | |
}} | |
/> | |
</Item> | |
<Item style={{ marginLeft: 0 }} floatingLabel> | |
<Label>Last Name</Label> | |
<Input | |
value={lastName} | |
blurOnSubmit={ false } | |
onSubmitEditing={() => { | |
this._focusNextField('registerPhone'); | |
}} | |
returnKeyType={ "next" } | |
onChangeText={ (lastName) => this.setState({ lastName }) } | |
getRef={ input => { | |
this.state.inputs['lastName'] = input; | |
}} | |
/> | |
</Item> | |
<PhoneInput | |
value={phone} | |
onChangeText={(phone) => this.setState({ phone })} | |
getRef={ input => { | |
this.state.inputs['registerPhone'] = input; | |
}} | |
/> | |
<Item style={{ marginLeft: 0 }} floatingLabel> | |
<Label>Email</Label> | |
<Input | |
keyboardType="email-address" | |
autoCapitalize="none" | |
value={email} | |
blurOnSubmit={ false } | |
onSubmitEditing={() => { | |
this._focusNextField('registerPassword'); | |
}} | |
returnKeyType={ "next" } | |
onChangeText={ (email) => this.setState({ email }) } | |
getRef={ input => { | |
this.state.inputs['email'] = input; | |
}} | |
/> | |
</Item> | |
<Item style={{ marginLeft: 0 }} floatingLabel> | |
<Label>Password</Label> | |
<Input | |
secureTextEntry | |
value={password} | |
blurOnSubmit={ true } | |
returnKeyType={ "done" } | |
onChangeText={ (password) => this.setState({ password }) } | |
getRef={ input => { | |
this.state.inputs['registerPassword'] = input; | |
}} | |
/> | |
</Item> | |
</Form> | |
<View style={styles.loginButton}> | |
<LoadingButton | |
text={'REGISTER'} | |
isLoading={this.state.registering} | |
onPress={this._handleRegister} | |
color={theme.brandPrimary} | |
/> | |
</View> | |
</Animated.ScrollView> | |
</View> | |
<View style={styles.copyRightWrapper}> | |
<Text style={styles.copyRightText}>copyright © {new Date().getFullYear()} MobileKeep | Version {version} - ({process.env.NODE_ENV})</Text> | |
</View> | |
</Animated.View> | |
</View> | |
</ImageBackground> | |
</View> | |
</KeyboardAwareScrollView> | |
); | |
} | |
} | |
const mapStateToProps = state => ({ | |
authentication: state.authentication | |
}); | |
export default connect(mapStateToProps)(withTheme(Login)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment