Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
9b19b47
refactor resendValidationLink and ResendValidationForm to use new API
jasperhuangg Aug 23, 2022
0ef21bf
revert comment change
jasperhuangg Aug 23, 2022
7c8c66f
style
jasperhuangg Aug 23, 2022
392360b
fix error handling
jasperhuangg Aug 23, 2022
47db859
fix error handling
jasperhuangg Aug 23, 2022
09bb3a2
remove unused imports
jasperhuangg Aug 23, 2022
3238229
make Session action calls inline
jasperhuangg Aug 23, 2022
edb8d9c
update look of error message to match login screen
jasperhuangg Aug 24, 2022
9eb610f
fix function doc type
jasperhuangg Aug 24, 2022
5df3a91
use API.write instead of read
jasperhuangg Aug 24, 2022
bd28e3a
remove unused imports
jasperhuangg Aug 24, 2022
c8d1d25
Revert "update look of error message to match login screen"
jasperhuangg Aug 24, 2022
362a015
revert UI changes
jasperhuangg Aug 24, 2022
d20eeb8
fix onPress
jasperhuangg Aug 24, 2022
9f468d9
update success and error message styles
jasperhuangg Aug 25, 2022
26e524e
revert UI changes
jasperhuangg Aug 24, 2022
7ea1fc9
fix onPress
jasperhuangg Aug 24, 2022
263e4f7
update success and error message styles
jasperhuangg Aug 25, 2022
c168a4d
Revert "update look of error message to match login screen"
jasperhuangg Aug 24, 2022
de87f3e
Merge branch 'jasper-resendValidateCodeRefactor' of github.com:Expens…
jasperhuangg Aug 25, 2022
ed1f71c
revert UI changes
jasperhuangg Aug 24, 2022
14782c1
fix onPress
jasperhuangg Aug 24, 2022
435f2ba
update success and error message styles
jasperhuangg Aug 25, 2022
46e3c1e
Merge branch 'jasper-resendValidateCodeRefactor' of github.com:Expens…
jasperhuangg Aug 25, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/libs/ErrorUtils.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import _ from 'underscore';
import CONST from '../CONST';

/**
Expand Down Expand Up @@ -35,7 +36,23 @@ function getAuthenticateErrorMessage(response) {
}
}

/**
* @param {Object} onyxData
* @param {Object} onyxData.errors
* @returns {String}
*/
function getLatestErrorMessage(onyxData) {
return _.chain(onyxData.errors || [])
.keys()
.sortBy()
.reverse()
.map(key => onyxData.errors[key])
.first()
.value();
}

export {
// eslint-disable-next-line import/prefer-default-export
getAuthenticateErrorMessage,
getLatestErrorMessage,
};
28 changes: 23 additions & 5 deletions src/libs/actions/Session/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,29 @@ function signOutAndRedirectToSignIn() {
* @param {String} [login]
*/
function resendValidationLink(login = credentials.login) {
Onyx.merge(ONYXKEYS.ACCOUNT, {isLoading: true});
DeprecatedAPI.ResendValidateCode({email: login})
.finally(() => {
Onyx.merge(ONYXKEYS.ACCOUNT, {isLoading: false});
});
const optimisticData = [{
onyxMethod: CONST.ONYX.METHOD.MERGE,
key: ONYXKEYS.ACCOUNT,
value: {isLoading: true},
}];
const successData = [{
onyxMethod: CONST.ONYX.METHOD.MERGE,
key: ONYXKEYS.ACCOUNT,
value: {
isLoading: false,
message: Localize.translateLocal('resendValidationForm.linkHasBeenResent'),
},
}];
const failureData = [{
onyxMethod: CONST.ONYX.METHOD.MERGE,
key: ONYXKEYS.ACCOUNT,
value: {
isLoading: false,
message: '',
},
}];

API.write('RequestAccountValidationLink', {email: login}, {optimisticData, successData, failureData});
}

/**
Expand Down
9 changes: 2 additions & 7 deletions src/pages/signin/LoginForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import FormAlertWithSubmitButton from '../../components/FormAlertWithSubmitButto
import OfflineIndicator from '../../components/OfflineIndicator';
import {withNetwork} from '../../components/OnyxProvider';
import networkPropTypes from '../../components/networkPropTypes';
import * as ErrorUtils from '../../libs/ErrorUtils';

const propTypes = {
/** Should we dismiss the keyboard when transitioning away from the page? */
Expand Down Expand Up @@ -151,13 +152,7 @@ class LoginForm extends React.Component {

render() {
const formErrorTranslated = this.state.formError && this.props.translate(this.state.formError);
const error = formErrorTranslated || _.chain(this.props.account.errors || [])
.keys()
.sortBy()
.reverse()
.map(key => this.props.account.errors[key])
.first()
.value();
const error = formErrorTranslated || ErrorUtils.getLatestErrorMessage(this.props.account);
return (
<>
<View style={[styles.mt3]}>
Expand Down
62 changes: 27 additions & 35 deletions src/pages/signin/ResendValidationForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React from 'react';
import {TouchableOpacity, View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import PropTypes from 'prop-types';
import _ from 'underscore';
import Str from 'expensify-common/lib/str';
import styles from '../../styles/styles';
import Button from '../../components/Button';
Expand All @@ -17,6 +16,11 @@ import * as ReportUtils from '../../libs/ReportUtils';
import OfflineIndicator from '../../components/OfflineIndicator';
import networkPropTypes from '../../components/networkPropTypes';
import {withNetwork} from '../../components/OnyxProvider';
import * as ErrorUtils from '../../libs/ErrorUtils';
import Icon from '../../components/Icon';
import * as Expensicons from '../../components/Icon/Expensicons';
import colors from '../../styles/colors';
import variables from '../../styles/variables';

const propTypes = {
/* Onyx Props */
Expand Down Expand Up @@ -47,16 +51,6 @@ const defaultProps = {
};

class ResendValidationForm extends React.Component {
constructor(props) {
super(props);

this.validateAndSubmitForm = this.validateAndSubmitForm.bind(this);

this.state = {
formSuccess: '',
};
}

componentWillUnmount() {
if (!this.successMessageTimer) {
return;
Expand All @@ -65,29 +59,12 @@ class ResendValidationForm extends React.Component {
clearTimeout(this.successMessageTimer);
}

/**
* Check that all the form fields are valid, then trigger the submit callback
*/
validateAndSubmitForm() {
this.setState({
formSuccess: this.props.translate('resendValidationForm.linkHasBeenResent'),
});

if (!this.props.account.validated) {
Session.resendValidationLink();
} else {
Session.resetPassword();
}

this.successMessageTimer = setTimeout(() => {
this.setState({formSuccess: ''});
}, 5000);
}

render() {
const isSMSLogin = Str.isSMSLogin(this.props.credentials.login);
const login = isSMSLogin ? this.props.toLocalPhone(Str.removeSMSDomain(this.props.credentials.login)) : this.props.credentials.login;
const loginType = (isSMSLogin ? this.props.translate('common.phone') : this.props.translate('common.email')).toLowerCase();
const error = ErrorUtils.getLatestErrorMessage(this.props.account);
const successMessage = this.props.account.message;

return (
<>
Expand All @@ -107,10 +84,25 @@ class ResendValidationForm extends React.Component {
{this.props.translate('resendValidationForm.weSentYouMagicSignInLink', {login, loginType})}
</Text>
</View>
{!_.isEmpty(this.state.formSuccess) && (
<Text style={[styles.formSuccess]}>
{this.state.formSuccess}
</Text>
{successMessage && (
Comment thread
jasperhuangg marked this conversation as resolved.
<View style={[styles.flexRow, styles.mb5]}>
<View style={styles.offlineFeedback.errorDot}>
<Icon src={Expensicons.DotIndicator} fill={colors.green} height={variables.iconSizeSmall} width={variables.iconSizeSmall} />
</View>
<Text style={[styles.textLabel, styles.colorMuted]}>
{successMessage}
</Text>
</View>
)}
{!successMessage && error && (
<View style={[styles.flexRow, styles.mb5]}>
<View style={styles.offlineFeedback.errorDot}>
<Icon src={Expensicons.DotIndicator} fill={colors.red} height={variables.iconSizeSmall} width={variables.iconSizeSmall} />
</View>
<Text style={[styles.textLabel, styles.colorMuted]}>
{error}
</Text>
</View>
)}
<View style={[styles.mb4, styles.flexRow, styles.justifyContentBetween, styles.alignItemsCenter]}>
<TouchableOpacity onPress={() => redirectToSignIn()}>
Expand All @@ -123,7 +115,7 @@ class ResendValidationForm extends React.Component {
success
text={this.props.translate('resendValidationForm.resendLink')}
isLoading={this.props.account.loading}
onPress={this.validateAndSubmitForm}
onPress={() => (this.props.account.validated ? Session.resetPassword() : Session.resendValidationLink())}
isDisabled={this.props.network.isOffline}
/>
</View>
Expand Down