diff --git a/src/ONYXKEYS.js b/src/ONYXKEYS.js
index 84add6c9f423..77c3f0396cbc 100755
--- a/src/ONYXKEYS.js
+++ b/src/ONYXKEYS.js
@@ -112,9 +112,6 @@ export default {
// Stores information about additional details form entry
WALLET_ADDITIONAL_DETAILS: 'walletAdditionalDetails',
- // Stores values put into the additional details step of the wallet KYC flow
- WALLET_ADDITIONAL_DETAILS_DRAFT: 'walletAdditionalDetailsDraft',
-
// Object containing Wallet terms step state
WALLET_TERMS: 'walletTerms',
diff --git a/src/libs/actions/Wallet.js b/src/libs/actions/Wallet.js
index 89f4753726c7..e9627d8bf329 100644
--- a/src/libs/actions/Wallet.js
+++ b/src/libs/actions/Wallet.js
@@ -262,13 +262,6 @@ function openEnablePaymentsPage() {
API.read('OpenEnablePaymentsPage');
}
-/**
- * @param {Object} keyValuePair
- */
-function updateAdditionalDetailsDraft(keyValuePair) {
- Onyx.merge(ONYXKEYS.WALLET_ADDITIONAL_DETAILS_DRAFT, keyValuePair);
-}
-
/**
* @param {String} currentStep
*/
@@ -317,7 +310,6 @@ export {
openInitialSettingsPage,
openEnablePaymentsPage,
setAdditionalDetailsErrors,
- updateAdditionalDetailsDraft,
setAdditionalDetailsErrorMessage,
setAdditionalDetailsQuestions,
updateCurrentStep,
diff --git a/src/pages/EnablePayments/AdditionalDetailsStep.js b/src/pages/EnablePayments/AdditionalDetailsStep.js
index 4051a1becdc5..c303c6fac53c 100644
--- a/src/pages/EnablePayments/AdditionalDetailsStep.js
+++ b/src/pages/EnablePayments/AdditionalDetailsStep.js
@@ -1,4 +1,3 @@
-import lodashGet from 'lodash/get';
import _ from 'underscore';
import React from 'react';
import PropTypes from 'prop-types';
@@ -17,20 +16,15 @@ import compose from '../../libs/compose';
import ONYXKEYS from '../../ONYXKEYS';
import TextLink from '../../components/TextLink';
import TextInput from '../../components/TextInput';
-import FormScrollView from '../../components/FormScrollView';
-import FormAlertWithSubmitButton from '../../components/FormAlertWithSubmitButton';
import * as Wallet from '../../libs/actions/Wallet';
import * as ValidationUtils from '../../libs/ValidationUtils';
import * as LoginUtils from '../../libs/LoginUtils';
import AddressForm from '../ReimbursementAccount/AddressForm';
import DatePicker from '../../components/DatePicker';
-import FormHelper from '../../libs/FormHelper';
-import walletAdditionalDetailsDraftPropTypes from './walletAdditionalDetailsDraftPropTypes';
+import Form from '../../components/Form';
import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from '../../components/withCurrentUserPersonalDetails';
import * as PersonalDetails from '../../libs/actions/PersonalDetails';
import OfflineIndicator from '../../components/OfflineIndicator';
-import * as ErrorUtils from '../../libs/ErrorUtils';
-import SafeAreaConsumer from '../../components/SafeAreaConsumer';
const propTypes = {
...withLocalizePropTypes,
@@ -60,9 +54,6 @@ const propTypes = {
/** Error code to determine additional behavior */
errorCode: PropTypes.string,
}),
-
- /** Stores the personal details typed by the user */
- walletAdditionalDetailsDraft: walletAdditionalDetailsDraftPropTypes,
};
const defaultProps = {
@@ -74,25 +65,29 @@ const defaultProps = {
idNumber: '',
errorCode: '',
},
- walletAdditionalDetailsDraft: {
- legalFirstName: '',
- legalLastName: '',
- addressStreet: '',
- addressCity: '',
- addressState: '',
- addressZip: '',
- phoneNumber: '',
- dob: '',
- ssn: '',
- },
...withCurrentUserPersonalDetailsDefaultProps,
};
+const INPUT_IDS = {
+ LEGAL_FIRST_NAME: 'legalFirstName',
+ LEGAL_LAST_NAME: 'legalLastName',
+ PHONE_NUMBER: 'phoneNumber',
+ DOB: 'dob',
+ SSN: 'ssn',
+ ADDRESS: {
+ street: 'addressStreet',
+ city: 'addressCity',
+ state: 'addressState',
+ zipCode: 'addressZip',
+ },
+};
+
class AdditionalDetailsStep extends React.Component {
constructor(props) {
super(props);
this.activateWallet = this.activateWallet.bind(this);
+ this.validate = this.validate.bind(this);
this.errorTranslationKeys = {
legalFirstName: 'bankAccount.error.firstName',
@@ -113,146 +108,82 @@ class AdditionalDetailsStep extends React.Component {
ssn: 'common.ssnLast4',
ssnFull9: 'common.ssnFull9',
};
-
- this.formHelper = new FormHelper({
- errorPath: 'walletAdditionalDetails.errorFields',
- setErrors: Wallet.setAdditionalDetailsErrors,
- });
- }
-
- getFirstName() {
- const {firstName} = PersonalDetails.extractFirstAndLastNameFromAvailableDetails(this.props.currentUserPersonalDetails);
- return this.props.walletAdditionalDetailsDraft.legalFirstName || firstName;
- }
-
- getLastName() {
- const {lastName} = PersonalDetails.extractFirstAndLastNameFromAvailableDetails(this.props.currentUserPersonalDetails);
- return this.props.walletAdditionalDetailsDraft.legalLastName || lastName;
}
/**
+ * @param {Object} values The values object is passed from Form.js and contains info for each form element that has an inputID
* @returns {Object}
*/
- getErrors() {
- return this.formHelper.getErrors(this.props);
- }
-
- /**
- * @param {String} fieldName
- * @returns {String}
- */
- getErrorText(fieldName) {
- if (!this.getErrors()[fieldName]) {
- return '';
- }
-
- return this.props.translate(this.errorTranslationKeys[fieldName]);
- }
-
- /**
- * @param {String} path
- */
- clearError(path) {
- this.formHelper.clearError(this.props, path);
- }
-
- /**
- * @returns {Boolean}
- */
- validate() {
- // Reset server error messages when resubmitting form
- Wallet.setAdditionalDetailsErrorMessage('');
-
+ validate(values) {
const errors = {};
- if (!this.getFirstName()) {
- errors.legalFirstName = true;
+ if (_.isEmpty(values[INPUT_IDS.LEGAL_FIRST_NAME])) {
+ errors[INPUT_IDS.LEGAL_FIRST_NAME] = this.props.translate(this.errorTranslationKeys.legalFirstName);
}
- if (!this.getLastName()) {
- errors.legalLastName = true;
+ if (_.isEmpty(values[INPUT_IDS.LEGAL_LAST_NAME])) {
+ errors[INPUT_IDS.LEGAL_LAST_NAME] = this.props.translate(this.errorTranslationKeys.legalLastName);
}
- if (!ValidationUtils.isValidPastDate(this.props.walletAdditionalDetailsDraft.dob)) {
- errors.dob = true;
+ if (!ValidationUtils.isValidPastDate(values[INPUT_IDS.DOB])) {
+ errors[INPUT_IDS.DOB] = this.props.translate(this.errorTranslationKeys.dob);
}
- if (!ValidationUtils.meetsAgeRequirements(this.props.walletAdditionalDetailsDraft.dob)) {
- errors.age = true;
+ if (!ValidationUtils.meetsAgeRequirements(values[INPUT_IDS.DOB])) {
+ errors[INPUT_IDS.DOB] = this.props.translate(this.errorTranslationKeys.age);
}
- if (!ValidationUtils.isValidAddress(this.props.walletAdditionalDetailsDraft.addressStreet)) {
- errors.addressStreet = true;
+ if (!ValidationUtils.isValidAddress(values[INPUT_IDS.ADDRESS.street]) || _.isEmpty(values[INPUT_IDS.ADDRESS.street])) {
+ errors[INPUT_IDS.ADDRESS.street] = this.props.translate('bankAccount.error.addressStreet');
}
- if (_.isEmpty(this.props.walletAdditionalDetailsDraft.addressCity)) {
- errors.addressCity = true;
+ if (_.isEmpty(values[INPUT_IDS.ADDRESS.city])) {
+ errors[INPUT_IDS.ADDRESS.city] = this.props.translate('bankAccount.error.addressCity');
}
- if (_.isEmpty(this.props.walletAdditionalDetailsDraft.addressState)) {
- errors.addressState = true;
+ if (_.isEmpty(values[INPUT_IDS.ADDRESS.state])) {
+ errors[INPUT_IDS.ADDRESS.state] = this.props.translate('bankAccount.error.addressState');
}
- if (!ValidationUtils.isValidZipCode(this.props.walletAdditionalDetailsDraft.addressZip)) {
- errors.addressZip = true;
+ if (!ValidationUtils.isValidZipCode(values[INPUT_IDS.ADDRESS.zipCode])) {
+ errors[INPUT_IDS.ADDRESS.zipCode] = this.props.translate('bankAccount.error.zipCode');
}
- if (!ValidationUtils.isValidUSPhone(this.props.walletAdditionalDetailsDraft.phoneNumber, true)) {
- errors.phoneNumber = true;
+ if (!ValidationUtils.isValidUSPhone(values[INPUT_IDS.PHONE_NUMBER], true)) {
+ errors[INPUT_IDS.PHONE_NUMBER] = this.props.translate(this.errorTranslationKeys.phoneNumber);
}
+ // this.props.walletAdditionalDetails stores errors returned by the server. If the server returns an SSN error
+ // then the user needs to provide the full 9 digit SSN.
if (this.props.walletAdditionalDetails.errorCode === CONST.WALLET.ERROR.SSN) {
- if (!ValidationUtils.isValidSSNFullNine(this.props.walletAdditionalDetailsDraft.ssn)) {
- errors.ssnFull9 = true;
+ if (!ValidationUtils.isValidSSNFullNine(values[INPUT_IDS.SSN])) {
+ errors[INPUT_IDS.SSN] = this.props.translate(this.errorTranslationKeys.ssnFull9);
}
- } else if (!ValidationUtils.isValidSSNLastFour(this.props.walletAdditionalDetailsDraft.ssn)) {
- errors.ssn = true;
+ } else if (!ValidationUtils.isValidSSNLastFour(values[INPUT_IDS.SSN])) {
+ errors[INPUT_IDS.SSN] = this.props.translate(this.errorTranslationKeys.ssn);
}
- Wallet.setAdditionalDetailsErrors(errors);
- return _.size(errors) === 0;
- }
-
- activateWallet() {
- if (!this.validate()) {
- return;
- }
- const personalDetails = {
- ...this.props.walletAdditionalDetailsDraft,
- phoneNumber: LoginUtils.getPhoneNumberWithoutUSCountryCodeAndSpecialChars(this.props.walletAdditionalDetailsDraft.phoneNumber),
- legalFirstName: this.getFirstName(),
- legalLastName: this.getLastName(),
- };
- Wallet.updatePersonalDetails(personalDetails);
+ return errors;
}
/**
- * Clear both errors associated with dob, and set the new value.
- *
- * @param {String} value
+ * @param {Object} values The values object is passed from Form.js and contains info for each form element that has an inputID
*/
- clearDateErrorsAndSetValue(value) {
- this.formHelper.clearErrors(this.props, ['dob', 'age']);
- Wallet.updateAdditionalDetailsDraft({dob: moment(value).format(CONST.DATE.MOMENT_FORMAT_STRING)});
- }
-
- /**
- * Clear ssn and ssnFull9 error and set the new value
- *
- * @param {String} value
- */
- clearSSNErrorAndSetValue(value) {
- this.formHelper.clearErrors(this.props, ['ssn', 'ssnFull9']);
- Wallet.updateAdditionalDetailsDraft({ssn: value});
- }
+ activateWallet(values) {
+ const personalDetails = {
+ phoneNumber: LoginUtils.getPhoneNumberWithoutUSCountryCodeAndSpecialChars(values[INPUT_IDS.PHONE_NUMBER]),
+ legalFirstName: values[INPUT_IDS.LEGAL_FIRST_NAME],
+ legalLastName: values[INPUT_IDS.LEGAL_LAST_NAME],
+ addressStreet: values[INPUT_IDS.ADDRESS.street],
+ addressCity: values[INPUT_IDS.ADDRESS.city],
+ addressState: values[INPUT_IDS.ADDRESS.state],
+ addressZip: values[INPUT_IDS.ADDRESS.zipCode],
+ dob: moment(values[INPUT_IDS.DOB]).format(CONST.DATE.MOMENT_FORMAT_STRING),
+ ssn: values[INPUT_IDS.SSN],
+ };
- /**
- * @param {String} fieldName
- * @param {String} value
- */
- clearErrorAndSetValue(fieldName, value) {
- Wallet.updateAdditionalDetailsDraft({[fieldName]: value});
- this.clearError(fieldName);
+ // Attempt to set the personal details
+ Wallet.updatePersonalDetails(personalDetails);
}
render() {
@@ -272,9 +203,6 @@ class AdditionalDetailsStep extends React.Component {
);
}
-
- const errorMessage = ErrorUtils.getLatestErrorMessage(this.props.walletAdditionalDetails) || '';
- const isErrorVisible = _.size(this.getErrors()) > 0 || Boolean(errorMessage);
const shouldAskForFullSSN = this.props.walletAdditionalDetails.errorCode === CONST.WALLET.ERROR.SSN;
return (
@@ -293,97 +221,58 @@ class AdditionalDetailsStep extends React.Component {
{this.props.translate('additionalDetailsStep.helpLink')}
- this.form = el}>
-
-
- this.clearErrorAndSetValue('legalFirstName', val)}
- value={this.getFirstName()}
- errorText={this.getErrorText('legalFirstName')}
- />
- this.clearErrorAndSetValue('legalLastName', val)}
- value={this.getLastName()}
- errorText={this.getErrorText('legalLastName')}
- />
- {
- const renamedFields = {
- street: 'addressStreet',
- state: 'addressState',
- city: 'addressCity',
- zipCode: 'addressZip',
- };
- _.each(values, (value, inputKey) => {
- const renamedInputKey = lodashGet(renamedFields, inputKey, inputKey);
- this.clearErrorAndSetValue(renamedInputKey, value);
- });
- }}
- />
-
- this.clearErrorAndSetValue('phoneNumber', val)}
- value={this.props.walletAdditionalDetailsDraft.phoneNumber || ''}
- placeholder={this.props.translate('common.phoneNumberPlaceholder')}
- errorText={this.getErrorText('phoneNumber')}
- />
- this.clearDateErrorsAndSetValue(val)}
- defaultValue={this.props.walletAdditionalDetailsDraft.dob || ''}
- placeholder={this.props.translate('common.dob')}
- errorText={this.getErrorText('dob') || this.getErrorText('age')}
- />
- this.clearSSNErrorAndSetValue(val)}
- value={this.props.walletAdditionalDetailsDraft.ssn || ''}
- errorText={this.getErrorText('ssnFull9') || this.getErrorText('ssn')}
- maxLength={shouldAskForFullSSN ? 9 : 4}
- keyboardType={CONST.KEYBOARD_TYPE.NUMBER_PAD}
- />
-
-
- {({safeAreaPaddingBottomStyle}) => (
-
- {
- this.form.scrollTo({y: 0, animated: true});
- }}
- message={errorMessage}
- isLoading={this.props.walletAdditionalDetails.isLoading}
- buttonText={this.props.translate('common.saveAndContinue')}
- />
-
- )}
-
+
+
>
);
@@ -398,7 +287,6 @@ export default compose(
withOnyx({
walletAdditionalDetails: {
key: ONYXKEYS.WALLET_ADDITIONAL_DETAILS,
- initWithStoredValues: false,
},
}),
)(AdditionalDetailsStep);
diff --git a/src/pages/EnablePayments/EnablePaymentsPage.js b/src/pages/EnablePayments/EnablePaymentsPage.js
index 91c4799a808b..a374adaab40b 100644
--- a/src/pages/EnablePayments/EnablePaymentsPage.js
+++ b/src/pages/EnablePayments/EnablePaymentsPage.js
@@ -78,7 +78,7 @@ class EnablePaymentsPage extends React.Component {
return (
<>
{(currentStep === CONST.WALLET.STEP.ADDITIONAL_DETAILS || currentStep === CONST.WALLET.STEP.ADDITIONAL_DETAILS_KBA)
- && }
+ && }
{currentStep === CONST.WALLET.STEP.ONFIDO && this.props.walletAdditionalDetailsDraft
&& }
{currentStep === CONST.WALLET.STEP.TERMS && }
@@ -104,9 +104,6 @@ export default compose(
// stored values here.
initWithStoredValues: false,
},
- walletAdditionalDetailsDraft: {
- key: ONYXKEYS.WALLET_ADDITIONAL_DETAILS_DRAFT,
- },
}),
withNetwork(),
)(EnablePaymentsPage);
diff --git a/src/pages/ReimbursementAccount/AddressForm.js b/src/pages/ReimbursementAccount/AddressForm.js
index bccf706a16d9..a731952c9eed 100644
--- a/src/pages/ReimbursementAccount/AddressForm.js
+++ b/src/pages/ReimbursementAccount/AddressForm.js
@@ -46,7 +46,12 @@ const propTypes = {
}),
/** Any errors that can arise from form validation */
- errors: PropTypes.objectOf(PropTypes.bool),
+ errors: PropTypes.shape({
+ street: PropTypes.bool,
+ city: PropTypes.bool,
+ state: PropTypes.bool,
+ zipCode: PropTypes.bool,
+ }),
/** The map for inputID of the inputs */
inputKeys: PropTypes.shape({