mirror of
https://bitbucket.org/tagfer_team/tagfer-app.git
synced 2025-12-25 03:37:41 +00:00
Forgot Password
This commit is contained in:
parent
82b8e0699e
commit
ef9210fab0
12
App.js
12
App.js
@ -1,9 +1,17 @@
|
||||
import React from 'react';
|
||||
import { View } from 'react-native';
|
||||
import FlashMessage from 'react-native-flash-message';
|
||||
|
||||
import AppNavigator from './src/config/router';
|
||||
|
||||
export default class App extends React.Component {
|
||||
render() {
|
||||
return <AppNavigator />;
|
||||
return (
|
||||
<View style={{ flex: 1 }}>
|
||||
<AppNavigator />
|
||||
<FlashMessage position="top" />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,11 @@ const endpoints = {
|
||||
login: {
|
||||
method: 'POST',
|
||||
url: `${baseurl}/auth/signin`
|
||||
},
|
||||
passwordReset: {
|
||||
method: 'POST',
|
||||
url: `${baseurl}/auth/passwordReset`
|
||||
}
|
||||
};
|
||||
|
||||
export default endpoints;
|
||||
export default endpoints;
|
||||
|
||||
@ -14,4 +14,4 @@ const errors = {
|
||||
MISSING_BODY_ATTRIBUTES: 'request/missing-body-attributes'
|
||||
};
|
||||
|
||||
export default errors;
|
||||
export default errors;
|
||||
|
||||
@ -1,12 +1,14 @@
|
||||
import { createStackNavigator, createAppContainer } from 'react-navigation';
|
||||
import WelcomeScreen from '../screens/boarding/WelcomeScreen';
|
||||
import LoginScreen from '../screens/boarding/LoginScreen';
|
||||
import WelcomeScreen from '../screens/onboaring/WelcomeScreen';
|
||||
import LoginScreen from '../screens/auth/LoginScreen';
|
||||
import ForgotPasswordScreen from '../screens/auth/ForgotPasswordScreen';
|
||||
|
||||
const StackNavigator = createStackNavigator({
|
||||
welcome: WelcomeScreen,
|
||||
login: LoginScreen
|
||||
login: LoginScreen,
|
||||
forgotPassword: ForgotPasswordScreen
|
||||
});
|
||||
|
||||
const AppNavigator = createAppContainer(StackNavigator);
|
||||
|
||||
export default AppNavigator;
|
||||
export default AppNavigator;
|
||||
|
||||
@ -45,7 +45,7 @@
|
||||
"education_educationSummary_placeholder": "Education Summary",
|
||||
"education_fieldOfStudy_placeholder": "Field Of Study",
|
||||
"education_school_placeholder": "College/University",
|
||||
"email_labelText": "Email",
|
||||
"email_labelText": "Email Address",
|
||||
"email_or_tagferid_label": "EMAIL OR TAGFERID",
|
||||
"email_or_tagferid_placeholder": "username@tagfer.com",
|
||||
"email_placeholder": "Email Address",
|
||||
@ -449,7 +449,7 @@
|
||||
"title": "Fingerprint Settings"
|
||||
},
|
||||
"forgotPasswordScreen": {
|
||||
"submitButton": "Request Reset Email",
|
||||
"submitButton": "Request Reset Link",
|
||||
"title": "Forgot Password"
|
||||
},
|
||||
"investment": {
|
||||
|
||||
196
src/screens/auth/ForgotPasswordScreen.js
Normal file
196
src/screens/auth/ForgotPasswordScreen.js
Normal file
@ -0,0 +1,196 @@
|
||||
import React from 'react';
|
||||
import { Dimensions, Image, TouchableWithoutFeedback, Text, View, Keyboard, KeyboardAvoidingView, Platform } from 'react-native';
|
||||
import { Button, FormInput } from 'react-native-elements';
|
||||
import { showMessage } from 'react-native-flash-message';
|
||||
|
||||
import { FormLabel, Spacer } from '../../components/common';
|
||||
import { fetchAuth } from '../../utils/fetch';
|
||||
import { strings } from '../../locales/i18n';
|
||||
import { getErrorDescription } from '../../utils/errorHandler';
|
||||
|
||||
import endpoints from '../../config/apiEndpoints';
|
||||
import colors from '../../config/colors.json';
|
||||
import logo from '../../../assets/logo-round.png';
|
||||
|
||||
export default class ForgotPasswordScreen extends React.Component {
|
||||
static navigationOptions = {
|
||||
header: null
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
email: '',
|
||||
loading: false
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an API request and display error/sucess message
|
||||
*/
|
||||
onRequestResetPress() {
|
||||
Keyboard.dismiss();
|
||||
this.setState({ loading: true });
|
||||
const body = { email: this.state.email };
|
||||
console.log(body);
|
||||
|
||||
fetchAuth(endpoints.passwordReset, body).then(res => {
|
||||
this.setState({ loading: false });
|
||||
console.log(res);
|
||||
if (res.error) {
|
||||
this.showErrorMessage(res.error);
|
||||
} else {
|
||||
this.showSuccessMessage();
|
||||
}
|
||||
}).catch(error => {
|
||||
this.setState({ loading: false });
|
||||
this.showErrorMessage(error);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple regex to check if the input is an email.
|
||||
*/
|
||||
isNotEmail() {
|
||||
const regex = /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/;
|
||||
return !regex.test(this.state.email);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a flash message at the top of the screen.
|
||||
* @param {String} error one of the error codes in {@see config.error.js}
|
||||
*/
|
||||
showErrorMessage(error) {
|
||||
showMessage({
|
||||
message: 'Authentication Error',
|
||||
description: getErrorDescription(error),
|
||||
type: 'danger',
|
||||
icon: 'auto',
|
||||
duration: 4000
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a success message
|
||||
*/
|
||||
showSuccessMessage() {
|
||||
showMessage({
|
||||
message: 'Password reset link sent',
|
||||
description: 'Please check your email.',
|
||||
type: 'success',
|
||||
icon: 'auto',
|
||||
autoHide: false,
|
||||
onPress: () => this.props.navigation.navigate('login')
|
||||
});
|
||||
}
|
||||
|
||||
renderContent() {
|
||||
return (
|
||||
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
|
||||
<View style={{ flex: 1 }}>
|
||||
|
||||
{/* LOGO */}
|
||||
<View style={styles.logoContainerStyle}>
|
||||
<Image source={logo} />
|
||||
</View>
|
||||
|
||||
{/* HEADER */}
|
||||
<View>
|
||||
<Text style={styles.headerStyle} >Forgot your password?</Text>
|
||||
<Text style={styles.instructions}>Enter your email address below and we'll get you back on track</Text>
|
||||
</View>
|
||||
|
||||
{/* TEXT INPUTS */}
|
||||
<View style={{ flex: 3 }}>
|
||||
<Spacer />
|
||||
<FormLabel
|
||||
required
|
||||
labelText={strings('common.contactFields.email_labelText').toUpperCase()}
|
||||
textStyle={styles.labelStyle}
|
||||
/>
|
||||
<FormInput
|
||||
onChangeText={email => this.setState({ email })}
|
||||
placeholder={strings('common.contactFields.email_or_tagferid_placeholder')}
|
||||
autoCorrect={false}
|
||||
autoCapitalize='none'
|
||||
inputStyle={styles.inputTextStyle}
|
||||
/>
|
||||
</View>
|
||||
|
||||
{/* BUTTONS */}
|
||||
<View>
|
||||
<Text onPress={() => this.props.navigation.navigate('login')} style={styles.backButtonStyle} >
|
||||
Back to Login
|
||||
</Text>
|
||||
|
||||
<Button
|
||||
onPress={this.onRequestResetPress.bind(this)}
|
||||
title={strings('settings.forgotPasswordScreen.submitButton')}
|
||||
buttonStyle={styles.buttonStyle}
|
||||
disabled={this.isNotEmail()}
|
||||
loading={this.state.loading}
|
||||
fontSize={20}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
if (Platform.OS === 'android') {
|
||||
return this.renderContent();
|
||||
}
|
||||
|
||||
return (
|
||||
<KeyboardAvoidingView style={{ flex: 1 }} behavior="padding" >
|
||||
{this.renderContent()}
|
||||
</KeyboardAvoidingView>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const SCREEN_WIDTH = Dimensions.get('window').width;
|
||||
const styles = {
|
||||
logoContainerStyle: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
marginTop: 50,
|
||||
marginBottom: 40
|
||||
},
|
||||
logoStyle: {
|
||||
width: '100%',
|
||||
height: '100%'
|
||||
},
|
||||
headerStyle: {
|
||||
color: colors.headerBlue,
|
||||
fontWeight: 'bold',
|
||||
marginLeft: 20,
|
||||
fontSize: 24
|
||||
},
|
||||
instructions: {
|
||||
color: colors.grey,
|
||||
fontSize: 18,
|
||||
marginLeft: 20,
|
||||
marginRight: 20
|
||||
},
|
||||
buttonStyle: {
|
||||
width: SCREEN_WIDTH * 0.9,
|
||||
marginTop: 15,
|
||||
marginBottom: 30,
|
||||
borderRadius: 5,
|
||||
backgroundColor: colors.buttonBlue
|
||||
},
|
||||
backButtonStyle: {
|
||||
marginLeft: 20,
|
||||
fontSize: 18,
|
||||
color: colors.grey
|
||||
},
|
||||
labelStyle: {
|
||||
color: colors.labelBlue
|
||||
},
|
||||
inputTextStyle: {
|
||||
color: colors.black
|
||||
}
|
||||
};
|
||||
@ -1,12 +1,12 @@
|
||||
import React from 'react';
|
||||
import { Image, KeyboardAvoidingView, Platform, Dimensions, View, Text, Keyboard, TouchableWithoutFeedback } from 'react-native';
|
||||
import { Button, FormInput } from 'react-native-elements';
|
||||
import FlashMessage, { showMessage } from 'react-native-flash-message';
|
||||
import { showMessage } from 'react-native-flash-message';
|
||||
|
||||
import { FormLabel, Spacer, TextButton } from '../../components/common';
|
||||
import { strings } from '../../locales/i18n';
|
||||
import { fetchAuth } from '../../utils/fetch';
|
||||
import { getErrorMessage } from '../../utils/errorHandler';
|
||||
import { getErrorDescription } from '../../utils/errorHandler';
|
||||
|
||||
import endpoints from '../../config/apiEndpoints';
|
||||
import colors from '../../config/colors.json';
|
||||
@ -31,19 +31,20 @@ export default class LoginScreen extends React.Component {
|
||||
* and displays the error if needed.
|
||||
*/
|
||||
onLoginPress() {
|
||||
Keyboard.dismiss();
|
||||
this.setState({ loading: true });
|
||||
const body = this.getLoginRequestBody();
|
||||
|
||||
fetchAuth(endpoints.login, body).then(res => {
|
||||
if (res.error) {
|
||||
this.setState({ loading: false });
|
||||
this.setState({ loading: false, password: '' });
|
||||
this.showErrorMessage(res.error);
|
||||
} else {
|
||||
this.setState({ loading: false });
|
||||
console.log(res.sessionId);
|
||||
}
|
||||
}).catch(error => {
|
||||
this.setState({ loading: false });
|
||||
this.setState({ loading: false, password: '' });
|
||||
this.showErrorMessage(error);
|
||||
});
|
||||
}
|
||||
@ -75,9 +76,10 @@ export default class LoginScreen extends React.Component {
|
||||
showErrorMessage(error) {
|
||||
showMessage({
|
||||
message: 'Authentication Error',
|
||||
description: getErrorMessage(error),
|
||||
description: getErrorDescription(error),
|
||||
type: 'danger',
|
||||
icon: 'auto'
|
||||
icon: 'auto',
|
||||
duration: 3000
|
||||
});
|
||||
}
|
||||
|
||||
@ -118,6 +120,7 @@ export default class LoginScreen extends React.Component {
|
||||
/>
|
||||
<FormInput
|
||||
secureTextEntry
|
||||
value={this.state.password}
|
||||
onChangeText={password => this.setState({ password })}
|
||||
placeholder={strings('userLoginScreen.password_placeholder')}
|
||||
autoCorrect={false}
|
||||
@ -152,8 +155,6 @@ export default class LoginScreen extends React.Component {
|
||||
disabled={this.isButtonDiabled()}
|
||||
fontSize={20}
|
||||
/>
|
||||
|
||||
<FlashMessage position="top" />
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
);
|
||||
@ -165,10 +166,7 @@ export default class LoginScreen extends React.Component {
|
||||
}
|
||||
|
||||
return (
|
||||
<KeyboardAvoidingView
|
||||
style={{ flex: 1 }}
|
||||
behavior="padding"
|
||||
>
|
||||
<KeyboardAvoidingView style={{ flex: 1 }} behavior="padding" >
|
||||
{this.renderContent()}
|
||||
</KeyboardAvoidingView>
|
||||
);
|
||||
@ -1,10 +1,10 @@
|
||||
import errors from '../config/errors';
|
||||
|
||||
export function getErrorMessage(error) {
|
||||
export function getErrorDescription(error) {
|
||||
switch (error) {
|
||||
case errors.AUTH_INVALID_EMAIL: return 'Invalid email format used.';
|
||||
case errors.AUTH_INVALID_PHONE_NUMBER: return 'Invalid phone number format is used.';
|
||||
case errors.AUTH_USER_NOT_FOUND: return 'Identifier used does not exist.';
|
||||
case errors.AUTH_USER_NOT_FOUND: return 'User is not recognized.';
|
||||
case errors.AUTH_WRONG_PASSWORD: return 'Wrong password.';
|
||||
case errors.AUTH_UID_ALREADY_EXISTS: return 'TagferID already exists.';
|
||||
case errors.AUTH_EMAIL_ALREADY_EXISTS: return 'Email already exists.';
|
||||
@ -17,4 +17,4 @@ export function getErrorMessage(error) {
|
||||
case errors.MISSING_BODY_ATTRIBUTES: return 'Invalid request. Please try again.';
|
||||
default: return 'Oops, an error occured! Please try again.';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user