// @flow import * as React from 'react'; import { Alert, Keyboard, KeyboardAvoidingView, ScrollView, StyleSheet, TouchableWithoutFeedback, View } from "react-native"; import {Avatar, Button, Card, HelperText, Text, TextInput, withTheme} from 'react-native-paper'; import ConnectionManager, {ERROR_TYPE} from "../../managers/ConnectionManager"; import {openBrowser} from "../../utils/WebBrowser"; import i18n from 'i18n-js'; type Props = { navigation: Object, } type State = { email: string, password: string, isEmailValidated: boolean, isPasswordValidated: boolean, loading: boolean, } const ICON_AMICALE = require('../../assets/amicale.png'); const RESET_PASSWORD_LINK = "https://www.amicale-insat.fr/password/reset"; const emailRegex = /^.+@.+\..+$/; class LoginScreen extends React.Component { state = { email: '', password: '', isEmailValidated: false, isPasswordValidated: false, loading: false, }; colors: Object; onEmailChange: Function; onPasswordChange: Function; validateEmail: Function; validatePassword: Function; onSubmit: Function; onEmailSubmit: Function; onResetPasswordClick: Function; passwordInputRef: Object; constructor(props) { super(props); this.onEmailChange = this.onInputChange.bind(this, true); this.onPasswordChange = this.onInputChange.bind(this, false); this.validateEmail = this.validateEmail.bind(this); this.validatePassword = this.validatePassword.bind(this); this.onSubmit = this.onSubmit.bind(this); this.onEmailSubmit = this.onEmailSubmit.bind(this); this.onResetPasswordClick = this.onResetPasswordClick.bind(this); this.colors = props.theme.colors; } onResetPasswordClick() { openBrowser(RESET_PASSWORD_LINK, this.colors.primary); } validateEmail() { this.setState({isEmailValidated: true}); } isEmailValid() { return emailRegex.test(this.state.email); } shouldShowEmailError() { return this.state.isEmailValidated && !this.isEmailValid(); } validatePassword() { this.setState({isPasswordValidated: true}); } isPasswordValid() { return this.state.password !== ''; } shouldShowPasswordError() { return this.state.isPasswordValidated && !this.isPasswordValid(); } shouldEnableLogin() { return this.isEmailValid() && this.isPasswordValid(); } onInputChange(isEmail: boolean, value: string) { if (isEmail) { this.setState({ email: value, isEmailValidated: false, }); } else { this.setState({ password: value, isPasswordValidated: false, }); } } onEmailSubmit() { this.passwordInputRef.focus(); } onSubmit() { if (this.shouldEnableLogin()) { this.setState({loading: true}); ConnectionManager.getInstance().connect(this.state.email, this.state.password) .then((data) => { this.handleSuccess(); }) .catch((error) => { this.handleErrors(error); }) .finally(() => { this.setState({loading: false}); }); } } handleSuccess() { this.props.navigation.navigate('ProfileScreen'); } handleErrors(error: number) { const title = i18n.t("loginScreen.errors.title"); let message; switch (error) { case ERROR_TYPE.CONNECTION_ERROR: message = i18n.t("loginScreen.errors.connection"); break; case ERROR_TYPE.BAD_CREDENTIALS: message = i18n.t("loginScreen.errors.credentials"); break; case ERROR_TYPE.SAVE_TOKEN: message = i18n.t("loginScreen.errors.saveToken"); break; case ERROR_TYPE.NO_CONSENT: message = i18n.t("loginScreen.errors.consent"); break; default: message = i18n.t("loginScreen.errors.unknown"); break; } Alert.alert(title, message); } getFormInput() { return ( {i18n.t("loginScreen.emailError")} { this.passwordInputRef = ref; }} label={i18n.t("loginScreen.password")} mode='outlined' value={this.state.password} onChangeText={this.onPasswordChange} onBlur={this.validatePassword} onSubmitEditing={this.onSubmit} error={this.shouldShowPasswordError()} textContentType={'password'} autoCapitalize={'none'} autoCompleteType={'password'} autoCorrect={false} keyboardType={'default'} returnKeyType={'done'} secureTextEntry={true} /> {i18n.t("loginScreen.passwordError")} ); } getMainCard() { return ( } /> {this.getFormInput()} ); } getSecondaryCard() { return ( {i18n.t("loginScreen.forgotPassword")} {i18n.t("loginScreen.noAccount")} ); } render() { return ( {this.getMainCard()} {this.getSecondaryCard()} ); } } const styles = StyleSheet.create({ container: { flex: 1, flexDirection: 'column', justifyContent: 'center', }, card: { margin: 10, }, header: { fontSize: 36, marginBottom: 48 }, textInput: {}, btnContainer: { marginTop: 5, marginBottom: 10, } }); export default withTheme(LoginScreen);