From f21cc766024c815cc07d248eecb7b4134460718a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Miko=C5=82ajczak?= Date: Thu, 14 Sep 2023 17:26:33 +0200 Subject: [PATCH 01/20] initial rewrite of RequestorStep --- .../ReimbursementAccount/RequestorStep.js | 288 +++++++++--------- 1 file changed, 138 insertions(+), 150 deletions(-) diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js index 9831f4b8190c..f1bf292e6340 100644 --- a/src/pages/ReimbursementAccount/RequestorStep.js +++ b/src/pages/ReimbursementAccount/RequestorStep.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, {useCallback} from 'react'; import {View} from 'react-native'; import PropTypes from 'prop-types'; import lodashGet from 'lodash/get'; @@ -25,168 +25,156 @@ const propTypes = { shouldShowOnfido: PropTypes.bool.isRequired, }; -class RequestorStep extends React.Component { - constructor(props) { - super(props); +const validate = (values) => { + const requiredFields = ['firstName', 'lastName', 'dob', 'ssnLast4', 'requestorAddressStreet', 'requestorAddressCity', 'requestorAddressState', 'requestorAddressZipCode']; + const errors = ValidationUtils.getFieldRequiredErrors(values, requiredFields); - this.validate = this.validate.bind(this); - this.submit = this.submit.bind(this); - } - - /** - * @param {Object} values - * @returns {Object} - */ - validate(values) { - const requiredFields = ['firstName', 'lastName', 'dob', 'ssnLast4', 'requestorAddressStreet', 'requestorAddressCity', 'requestorAddressState', 'requestorAddressZipCode']; - const errors = ValidationUtils.getFieldRequiredErrors(values, requiredFields); - - if (values.dob) { - if (!ValidationUtils.isValidPastDate(values.dob) || !ValidationUtils.meetsMaximumAgeRequirement(values.dob)) { - errors.dob = 'bankAccount.error.dob'; - } else if (!ValidationUtils.meetsMinimumAgeRequirement(values.dob)) { - errors.dob = 'bankAccount.error.age'; - } - } - - if (values.ssnLast4 && !ValidationUtils.isValidSSNLastFour(values.ssnLast4)) { - errors.ssnLast4 = 'bankAccount.error.ssnLast4'; + if (values.dob) { + if (!ValidationUtils.isValidPastDate(values.dob) || !ValidationUtils.meetsMaximumAgeRequirement(values.dob)) { + errors.dob = 'bankAccount.error.dob'; + } else if (!ValidationUtils.meetsMinimumAgeRequirement(values.dob)) { + errors.dob = 'bankAccount.error.age'; } + } - if (values.requestorAddressStreet && !ValidationUtils.isValidAddress(values.requestorAddressStreet)) { - errors.requestorAddressStreet = 'bankAccount.error.addressStreet'; - } + if (values.ssnLast4 && !ValidationUtils.isValidSSNLastFour(values.ssnLast4)) { + errors.ssnLast4 = 'bankAccount.error.ssnLast4'; + } - if (values.requestorAddressZipCode && !ValidationUtils.isValidZipCode(values.requestorAddressZipCode)) { - errors.requestorAddressZipCode = 'bankAccount.error.zipCode'; - } + if (values.requestorAddressStreet && !ValidationUtils.isValidAddress(values.requestorAddressStreet)) { + errors.requestorAddressStreet = 'bankAccount.error.addressStreet'; + } - if (!ValidationUtils.isRequiredFulfilled(values.isControllingOfficer)) { - errors.isControllingOfficer = 'requestorStep.isControllingOfficerError'; - } + if (values.requestorAddressZipCode && !ValidationUtils.isValidZipCode(values.requestorAddressZipCode)) { + errors.requestorAddressZipCode = 'bankAccount.error.zipCode'; + } - return errors; + if (!ValidationUtils.isRequiredFulfilled(values.isControllingOfficer)) { + errors.isControllingOfficer = 'requestorStep.isControllingOfficerError'; } - submit(values) { - const payload = { - bankAccountID: lodashGet(this.props.reimbursementAccount, 'achData.bankAccountID') || 0, - ...values, - }; + return errors; +}; - BankAccounts.updatePersonalInformationForBankAccount(payload); - } +function RequestorStep({reimbursementAccount, shouldShowOnfido, reimbursementAccountDraft, onBackButtonPress, getDefaultStateForField, translate}) { + const submit = useCallback( + (values) => { + const payload = { + bankAccountID: lodashGet(reimbursementAccount, 'achData.bankAccountID') || 0, + ...values, + }; - render() { - if (this.props.shouldShowOnfido) { - return ( - - ); - } + BankAccounts.updatePersonalInformationForBankAccount(payload); + }, + [reimbursementAccount], + ); + if (shouldShowOnfido) return ( - - -
- {this.props.translate('requestorStep.subtitle')} - - - {`${this.props.translate('requestorStep.learnMore')}`} - - {' | '} - - {`${this.props.translate('requestorStep.isMyDataSafe')}`} - - - - ( - - {this.props.translate('requestorStep.isControllingOfficer')} - - )} - style={[styles.mt4]} - shouldSaveDraft - /> - - {this.props.translate('requestorStep.onFidoConditions')} - - {this.props.translate('onfidoStep.facialScan')} - - {', '} - - {this.props.translate('common.privacy')} - - {` ${this.props.translate('common.and')} `} - - {this.props.translate('common.termsOfService')} - - - -
+ ); - } + + return ( + + +
+ {translate('requestorStep.subtitle')} + + + {`${translate('requestorStep.learnMore')}`} + + {' | '} + + {`${translate('requestorStep.isMyDataSafe')}`} + + + + ( + + {translate('requestorStep.isControllingOfficer')} + + )} + style={[styles.mt4]} + shouldSaveDraft + /> + + {translate('requestorStep.onFidoConditions')} + + {translate('onfidoStep.facialScan')} + + {', '} + + {translate('common.privacy')} + + {` ${translate('common.and')} `} + + {translate('common.termsOfService')} + + + +
+ ); } RequestorStep.propTypes = propTypes; From 062cfac4c2904b6b32f9c1c99c540eb3882d530f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Miko=C5=82ajczak?= Date: Thu, 14 Sep 2023 17:31:05 +0200 Subject: [PATCH 02/20] add forwardRef compatibility --- src/pages/ReimbursementAccount/RequestorStep.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js index f1bf292e6340..bef5c43cbbcd 100644 --- a/src/pages/ReimbursementAccount/RequestorStep.js +++ b/src/pages/ReimbursementAccount/RequestorStep.js @@ -56,7 +56,7 @@ const validate = (values) => { return errors; }; -function RequestorStep({reimbursementAccount, shouldShowOnfido, reimbursementAccountDraft, onBackButtonPress, getDefaultStateForField, translate}) { +function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimbursementAccountDraft, onBackButtonPress, getDefaultStateForField, translate}, ref) { const submit = useCallback( (values) => { const payload = { @@ -177,6 +177,8 @@ function RequestorStep({reimbursementAccount, shouldShowOnfido, reimbursementAcc ); } +const RequestorStep = React.forwardRef(InnerRequestorStep); + RequestorStep.propTypes = propTypes; export default withLocalize(RequestorStep); From f4e9c7df81684fb96e62fdf946325c2fa5294e84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Miko=C5=82ajczak?= Date: Thu, 14 Sep 2023 17:52:35 +0200 Subject: [PATCH 03/20] extraction of constants and memoization --- .../ReimbursementAccount/RequestorStep.js | 71 +++++++++++-------- 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js index bef5c43cbbcd..3952ede70fe4 100644 --- a/src/pages/ReimbursementAccount/RequestorStep.js +++ b/src/pages/ReimbursementAccount/RequestorStep.js @@ -1,4 +1,4 @@ -import React, {useCallback} from 'react'; +import React, {useCallback, useMemo} from 'react'; import {View} from 'react-native'; import PropTypes from 'prop-types'; import lodashGet from 'lodash/get'; @@ -25,9 +25,21 @@ const propTypes = { shouldShowOnfido: PropTypes.bool.isRequired, }; +const REQUIRED_FIELDS = ['firstName', 'lastName', 'dob', 'ssnLast4', 'requestorAddressStreet', 'requestorAddressCity', 'requestorAddressState', 'requestorAddressZipCode']; +const INPUT_KEYS = { + firstName: 'firstName', + lastName: 'lastName', + dob: 'dob', + ssnLast4: 'ssnLast4', + street: 'requestorAddressStreet', + city: 'requestorAddressCity', + state: 'requestorAddressState', + zipCode: 'requestorAddressZipCode', +}; +const STEP_COUNTER = {step: 3, total: 5}; + const validate = (values) => { - const requiredFields = ['firstName', 'lastName', 'dob', 'ssnLast4', 'requestorAddressStreet', 'requestorAddressCity', 'requestorAddressState', 'requestorAddressZipCode']; - const errors = ValidationUtils.getFieldRequiredErrors(values, requiredFields); + const errors = ValidationUtils.getFieldRequiredErrors(values, REQUIRED_FIELDS); if (values.dob) { if (!ValidationUtils.isValidPastDate(values.dob) || !ValidationUtils.meetsMaximumAgeRequirement(values.dob)) { @@ -57,6 +69,20 @@ const validate = (values) => { }; function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimbursementAccountDraft, onBackButtonPress, getDefaultStateForField, translate}, ref) { + const defaultValues = useMemo( + () => ({ + firstName: getDefaultStateForField('firstName'), + lastName: getDefaultStateForField('lastName'), + street: getDefaultStateForField('requestorAddressStreet'), + city: getDefaultStateForField('requestorAddressCity'), + state: getDefaultStateForField('requestorAddressState'), + zipCode: getDefaultStateForField('requestorAddressZipCode'), + dob: getDefaultStateForField('dob'), + ssnLast4: getDefaultStateForField('ssnLast4'), + }), + [getDefaultStateForField], + ); + const submit = useCallback( (values) => { const payload = { @@ -69,6 +95,15 @@ function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimburseme [reimbursementAccount], ); + const LabelComponent = useCallback( + () => ( + + {translate('requestorStep.isControllingOfficer')} + + ), + [translate], + ); + if (shouldShowOnfido) return ( ( - - {translate('requestorStep.isControllingOfficer')} - - )} + LabelComponent={LabelComponent} style={[styles.mt4]} shouldSaveDraft /> From c2c3f3522985ffc3c4b9aed32734f0442b4b7d1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Miko=C5=82ajczak?= Date: Thu, 14 Sep 2023 18:35:24 +0200 Subject: [PATCH 04/20] extract styles --- .../ReimbursementAccount/RequestorStep.js | 34 +++++++++++++------ 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js index 3952ede70fe4..44f9b9ee80a8 100644 --- a/src/pages/ReimbursementAccount/RequestorStep.js +++ b/src/pages/ReimbursementAccount/RequestorStep.js @@ -38,6 +38,18 @@ const INPUT_KEYS = { }; const STEP_COUNTER = {step: 3, total: 5}; +const STYLES = { + Label: [styles.flex1, styles.pr1], + Form: [styles.mh5, styles.flexGrow1], + LearnMoreContainer: [styles.mb5, styles.mt1, styles.dFlex, styles.flexRow], + LearnMoreLink: [styles.textMicro], + LearnMoreSeparator: [styles.textMicroSupporting], + DataSafeLink: [styles.textMicro, styles.textLink], + ControllingOfficerCheckbox: [styles.mt4], + ConditionsContainer: [styles.mt3, styles.textMicroSupporting], + ConditionsLink: [styles.textMicro], +}; + const validate = (values) => { const errors = ValidationUtils.getFieldRequiredErrors(values, REQUIRED_FIELDS); @@ -97,7 +109,7 @@ function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimburseme const LabelComponent = useCallback( () => ( - + {translate('requestorStep.isControllingOfficer')} ), @@ -128,21 +140,21 @@ function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimburseme submitButtonText={translate('common.saveAndContinue')} validate={validate} onSubmit={submit} - style={[styles.mh5, styles.flexGrow1]} + style={STYLES.Form} scrollContextEnabled > {translate('requestorStep.subtitle')} - + {`${translate('requestorStep.learnMore')}`} - {' | '} + {' | '} {`${translate('requestorStep.isMyDataSafe')}`} @@ -159,28 +171,28 @@ function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimburseme inputID="isControllingOfficer" defaultValue={getDefaultStateForField('isControllingOfficer', false)} LabelComponent={LabelComponent} - style={[styles.mt4]} + style={STYLES.ControllingOfficerCheckbox} shouldSaveDraft /> - + {translate('requestorStep.onFidoConditions')} {translate('onfidoStep.facialScan')} {', '} {translate('common.privacy')} {` ${translate('common.and')} `} {translate('common.termsOfService')} From 6dfd5249cd0f35e28c55832b24069617b3f6fbfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Miko=C5=82ajczak?= Date: Fri, 15 Sep 2023 09:32:31 +0200 Subject: [PATCH 05/20] use INPUT_KEYS for form default values object --- src/pages/ReimbursementAccount/RequestorStep.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js index 44f9b9ee80a8..4df8e8467743 100644 --- a/src/pages/ReimbursementAccount/RequestorStep.js +++ b/src/pages/ReimbursementAccount/RequestorStep.js @@ -83,14 +83,14 @@ const validate = (values) => { function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimbursementAccountDraft, onBackButtonPress, getDefaultStateForField, translate}, ref) { const defaultValues = useMemo( () => ({ - firstName: getDefaultStateForField('firstName'), - lastName: getDefaultStateForField('lastName'), - street: getDefaultStateForField('requestorAddressStreet'), - city: getDefaultStateForField('requestorAddressCity'), - state: getDefaultStateForField('requestorAddressState'), - zipCode: getDefaultStateForField('requestorAddressZipCode'), - dob: getDefaultStateForField('dob'), - ssnLast4: getDefaultStateForField('ssnLast4'), + firstName: getDefaultStateForField(INPUT_KEYS.firstName), + lastName: getDefaultStateForField(INPUT_KEYS.lastName), + street: getDefaultStateForField(INPUT_KEYS.street), + city: getDefaultStateForField(INPUT_KEYS.city), + state: getDefaultStateForField(INPUT_KEYS.state), + zipCode: getDefaultStateForField(INPUT_KEYS.zipCode), + dob: getDefaultStateForField(INPUT_KEYS.dob), + ssnLast4: getDefaultStateForField(INPUT_KEYS.ssnLast4), }), [getDefaultStateForField], ); From 8e1d2122077aee62825657d8a9947ea8006e09b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Miko=C5=82ajczak?= Date: Fri, 15 Sep 2023 09:33:31 +0200 Subject: [PATCH 06/20] use lodashGet defaultValue arg --- src/pages/ReimbursementAccount/RequestorStep.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js index 4df8e8467743..e54de4041bb9 100644 --- a/src/pages/ReimbursementAccount/RequestorStep.js +++ b/src/pages/ReimbursementAccount/RequestorStep.js @@ -98,7 +98,7 @@ function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimburseme const submit = useCallback( (values) => { const payload = { - bankAccountID: lodashGet(reimbursementAccount, 'achData.bankAccountID') || 0, + bankAccountID: lodashGet(reimbursementAccount, 'achData.bankAccountID', 0), ...values, }; From 16169e8d56d27c4a6fc47d2285cd5632b5acf48f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Miko=C5=82ajczak?= Date: Fri, 15 Sep 2023 09:35:24 +0200 Subject: [PATCH 07/20] remove redundant template literals --- src/pages/ReimbursementAccount/RequestorStep.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js index e54de4041bb9..05e46e488e66 100644 --- a/src/pages/ReimbursementAccount/RequestorStep.js +++ b/src/pages/ReimbursementAccount/RequestorStep.js @@ -150,14 +150,14 @@ function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimburseme // eslint-disable-next-line max-len href="https://community.expensify.com/discussion/6983/faq-why-do-i-need-to-provide-personal-documentation-when-setting-up-updating-my-bank-account" > - {`${translate('requestorStep.learnMore')}`} + {translate('requestorStep.learnMore')} {' | '} - {`${translate('requestorStep.isMyDataSafe')}`} + {translate('requestorStep.isMyDataSafe')} Date: Fri, 15 Sep 2023 09:36:44 +0200 Subject: [PATCH 08/20] add displayName --- src/pages/ReimbursementAccount/RequestorStep.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js index 05e46e488e66..5565c34addc2 100644 --- a/src/pages/ReimbursementAccount/RequestorStep.js +++ b/src/pages/ReimbursementAccount/RequestorStep.js @@ -205,5 +205,6 @@ function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimburseme const RequestorStep = React.forwardRef(InnerRequestorStep); RequestorStep.propTypes = propTypes; +RequestorStep.displayName = 'RequestorStep'; export default withLocalize(RequestorStep); From a20cb719bb77063596ea1edd0c55202a62707a7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Miko=C5=82ajczak?= Date: Fri, 15 Sep 2023 09:49:15 +0200 Subject: [PATCH 09/20] swap withLocalize for useLocalize --- src/pages/ReimbursementAccount/RequestorStep.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js index 5565c34addc2..043615aacdce 100644 --- a/src/pages/ReimbursementAccount/RequestorStep.js +++ b/src/pages/ReimbursementAccount/RequestorStep.js @@ -3,7 +3,6 @@ import {View} from 'react-native'; import PropTypes from 'prop-types'; import lodashGet from 'lodash/get'; import styles from '../../styles/styles'; -import withLocalize from '../../components/withLocalize'; import HeaderWithBackButton from '../../components/HeaderWithBackButton'; import CONST from '../../CONST'; import TextLink from '../../components/TextLink'; @@ -17,9 +16,12 @@ import RequestorOnfidoStep from './RequestorOnfidoStep'; import Form from '../../components/Form'; import ScreenWrapper from '../../components/ScreenWrapper'; import StepPropTypes from './StepPropTypes'; +import useLocalize from '../../hooks/useLocalize'; + +const {reimbursementAccount, reimbursementAccountDraft, onBackButtonPress, getDefaultStateForField} = StepPropTypes; const propTypes = { - ...StepPropTypes, + ...{reimbursementAccount, reimbursementAccountDraft, onBackButtonPress, getDefaultStateForField}, /** If we should show Onfido flow */ shouldShowOnfido: PropTypes.bool.isRequired, @@ -80,7 +82,9 @@ const validate = (values) => { return errors; }; -function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimbursementAccountDraft, onBackButtonPress, getDefaultStateForField, translate}, ref) { +function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimbursementAccountDraft, onBackButtonPress, getDefaultStateForField}, ref) { + const {translate} = useLocalize(); + const defaultValues = useMemo( () => ({ firstName: getDefaultStateForField(INPUT_KEYS.firstName), @@ -207,4 +211,4 @@ const RequestorStep = React.forwardRef(InnerRequestorStep); RequestorStep.propTypes = propTypes; RequestorStep.displayName = 'RequestorStep'; -export default withLocalize(RequestorStep); +export default RequestorStep; From 43e915e48f40955eb3d5aaadd5473a17e440efac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Miko=C5=82ajczak?= Date: Fri, 15 Sep 2023 09:52:26 +0200 Subject: [PATCH 10/20] add braces to early return --- src/pages/ReimbursementAccount/RequestorStep.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js index 043615aacdce..df7ac691cedb 100644 --- a/src/pages/ReimbursementAccount/RequestorStep.js +++ b/src/pages/ReimbursementAccount/RequestorStep.js @@ -120,7 +120,7 @@ function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimburseme [translate], ); - if (shouldShowOnfido) + if (shouldShowOnfido) { return ( ); + } return ( From 7f5655f4712d03f2113e4e58974ac38bc806ef51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Miko=C5=82ajczak?= Date: Fri, 15 Sep 2023 10:02:29 +0200 Subject: [PATCH 11/20] Revert "extract styles" This reverts commit c2c3f3522985ffc3c4b9aed32734f0442b4b7d1e. --- .../ReimbursementAccount/RequestorStep.js | 34 ++++++------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js index df7ac691cedb..34785dc88eb4 100644 --- a/src/pages/ReimbursementAccount/RequestorStep.js +++ b/src/pages/ReimbursementAccount/RequestorStep.js @@ -40,18 +40,6 @@ const INPUT_KEYS = { }; const STEP_COUNTER = {step: 3, total: 5}; -const STYLES = { - Label: [styles.flex1, styles.pr1], - Form: [styles.mh5, styles.flexGrow1], - LearnMoreContainer: [styles.mb5, styles.mt1, styles.dFlex, styles.flexRow], - LearnMoreLink: [styles.textMicro], - LearnMoreSeparator: [styles.textMicroSupporting], - DataSafeLink: [styles.textMicro, styles.textLink], - ControllingOfficerCheckbox: [styles.mt4], - ConditionsContainer: [styles.mt3, styles.textMicroSupporting], - ConditionsLink: [styles.textMicro], -}; - const validate = (values) => { const errors = ValidationUtils.getFieldRequiredErrors(values, REQUIRED_FIELDS); @@ -113,7 +101,7 @@ function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimburseme const LabelComponent = useCallback( () => ( - + {translate('requestorStep.isControllingOfficer')} ), @@ -145,21 +133,21 @@ function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimburseme submitButtonText={translate('common.saveAndContinue')} validate={validate} onSubmit={submit} - style={STYLES.Form} + style={[styles.mh5, styles.flexGrow1]} scrollContextEnabled > {translate('requestorStep.subtitle')} - + {translate('requestorStep.learnMore')} - {' | '} + {' | '} {translate('requestorStep.isMyDataSafe')} @@ -176,28 +164,28 @@ function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimburseme inputID="isControllingOfficer" defaultValue={getDefaultStateForField('isControllingOfficer', false)} LabelComponent={LabelComponent} - style={STYLES.ControllingOfficerCheckbox} + style={[styles.mt4]} shouldSaveDraft /> - + {translate('requestorStep.onFidoConditions')} {translate('onfidoStep.facialScan')} {', '} {translate('common.privacy')} {` ${translate('common.and')} `} {translate('common.termsOfService')} From 22ae3d3df87a2c6471a5379d7ea391b687c26e10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Miko=C5=82ajczak?= Date: Fri, 15 Sep 2023 11:51:55 +0200 Subject: [PATCH 12/20] rename LabelComponent to renderLabelComponent --- src/pages/ReimbursementAccount/RequestorStep.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js index 34785dc88eb4..2b6bc9bf1deb 100644 --- a/src/pages/ReimbursementAccount/RequestorStep.js +++ b/src/pages/ReimbursementAccount/RequestorStep.js @@ -99,7 +99,7 @@ function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimburseme [reimbursementAccount], ); - const LabelComponent = useCallback( + const renderLabelComponent = useCallback( () => ( {translate('requestorStep.isControllingOfficer')} @@ -163,7 +163,7 @@ function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimburseme accessibilityLabel={translate('requestorStep.isControllingOfficer')} inputID="isControllingOfficer" defaultValue={getDefaultStateForField('isControllingOfficer', false)} - LabelComponent={LabelComponent} + LabelComponent={renderLabelComponent} style={[styles.mt4]} shouldSaveDraft /> From e32147bae7a904511e94b198637602d1f9997a7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Miko=C5=82ajczak?= Date: Fri, 15 Sep 2023 11:54:28 +0200 Subject: [PATCH 13/20] propTypes omit improvement --- src/pages/ReimbursementAccount/RequestorStep.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js index 2b6bc9bf1deb..b14c6891f03e 100644 --- a/src/pages/ReimbursementAccount/RequestorStep.js +++ b/src/pages/ReimbursementAccount/RequestorStep.js @@ -17,11 +17,10 @@ import Form from '../../components/Form'; import ScreenWrapper from '../../components/ScreenWrapper'; import StepPropTypes from './StepPropTypes'; import useLocalize from '../../hooks/useLocalize'; - -const {reimbursementAccount, reimbursementAccountDraft, onBackButtonPress, getDefaultStateForField} = StepPropTypes; +import {withLocalizePropTypes} from '../../components/withLocalize'; const propTypes = { - ...{reimbursementAccount, reimbursementAccountDraft, onBackButtonPress, getDefaultStateForField}, + ..._.omit(StepPropTypes, _.keys(withLocalizePropTypes)), /** If we should show Onfido flow */ shouldShowOnfido: PropTypes.bool.isRequired, From 0e0c07c4317a7bc88671510767b4463d8803e5c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Miko=C5=82ajczak?= Date: Fri, 15 Sep 2023 19:26:08 +0200 Subject: [PATCH 14/20] extract urls --- src/CONST.ts | 6 ++++++ src/pages/ReimbursementAccount/RequestorStep.js | 11 +++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index 1ef2f3e83246..f75f3785934c 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -442,6 +442,12 @@ const CONST = { INTERNAL_DEV_EXPENSIFY_URL: 'https://www.expensify.com.dev', STAGING_EXPENSIFY_URL: 'https://staging.expensify.com', EXPENSIFY_URL: 'https://www.expensify.com', + BANK_ACCOUNT_PERSONAL_DOCUMENTATION_INFO_URL: + 'https://community.expensify.com/discussion/6983/faq-why-do-i-need-to-provide-personal-documentation-when-setting-up-updating-my-bank-account', + PERSONAL_DATA_PROTECTION_INFO_URL: 'https://community.expensify.com/discussion/5677/deep-dive-security-how-expensify-protects-your-information', + ONFIDO_FACIAL_SCAN_POLICY_URL: 'https://onfido.com/facial-scan-policy-and-release/', + ONFIDO_PRIVACY_POLICY_URL: 'https://onfido.com/privacy/', + ONFIDO_TERMS_OF_SERVICE_URL: 'https://onfido.com/terms-of-service/', // Use Environment.getEnvironmentURL to get the complete URL with port number DEV_NEW_EXPENSIFY_URL: 'http://localhost:', diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js index b14c6891f03e..9ddfcb3d3f72 100644 --- a/src/pages/ReimbursementAccount/RequestorStep.js +++ b/src/pages/ReimbursementAccount/RequestorStep.js @@ -139,15 +139,14 @@ function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimburseme {translate('requestorStep.learnMore')} {' | '} {translate('requestorStep.isMyDataSafe')} @@ -169,21 +168,21 @@ function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimburseme {translate('requestorStep.onFidoConditions')} {translate('onfidoStep.facialScan')} {', '} {translate('common.privacy')} {` ${translate('common.and')} `} {translate('common.termsOfService')} From c75ad401fbee9c117d6296792d9efebdb66829aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Miko=C5=82ajczak?= Date: Fri, 15 Sep 2023 19:33:53 +0200 Subject: [PATCH 15/20] remove renderLabelComponent memoization --- src/pages/ReimbursementAccount/RequestorStep.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js index 9ddfcb3d3f72..01d30fb9b95f 100644 --- a/src/pages/ReimbursementAccount/RequestorStep.js +++ b/src/pages/ReimbursementAccount/RequestorStep.js @@ -98,13 +98,10 @@ function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimburseme [reimbursementAccount], ); - const renderLabelComponent = useCallback( - () => ( - - {translate('requestorStep.isControllingOfficer')} - - ), - [translate], + const renderLabelComponent = () => ( + + {translate('requestorStep.isControllingOfficer')} + ); if (shouldShowOnfido) { From 6e5fa8accdb89d657e3a7e01552e3ba8d05d02af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Miko=C5=82ajczak?= Date: Tue, 19 Sep 2023 21:12:40 +0200 Subject: [PATCH 16/20] fix lodash issues --- src/pages/ReimbursementAccount/RequestorStep.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js index 01d30fb9b95f..21f8f0c74912 100644 --- a/src/pages/ReimbursementAccount/RequestorStep.js +++ b/src/pages/ReimbursementAccount/RequestorStep.js @@ -1,7 +1,7 @@ import React, {useCallback, useMemo} from 'react'; import {View} from 'react-native'; import PropTypes from 'prop-types'; -import lodashGet from 'lodash/get'; +import _ from 'lodash'; import styles from '../../styles/styles'; import HeaderWithBackButton from '../../components/HeaderWithBackButton'; import CONST from '../../CONST'; @@ -89,7 +89,7 @@ function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimburseme const submit = useCallback( (values) => { const payload = { - bankAccountID: lodashGet(reimbursementAccount, 'achData.bankAccountID', 0), + bankAccountID: _.get(reimbursementAccount, 'achData.bankAccountID', 0), ...values, }; From 375c85ff38e852606bc3be66fc31bd3fe091ce37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Miko=C5=82ajczak?= Date: Tue, 19 Sep 2023 21:13:01 +0200 Subject: [PATCH 17/20] remove unused ref --- src/pages/ReimbursementAccount/RequestorStep.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js index 21f8f0c74912..33d36b5f9819 100644 --- a/src/pages/ReimbursementAccount/RequestorStep.js +++ b/src/pages/ReimbursementAccount/RequestorStep.js @@ -69,7 +69,7 @@ const validate = (values) => { return errors; }; -function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimbursementAccountDraft, onBackButtonPress, getDefaultStateForField}, ref) { +function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimbursementAccountDraft, onBackButtonPress, getDefaultStateForField}) { const {translate} = useLocalize(); const defaultValues = useMemo( From 9de749dc1ea0a8c2c88b9419b377be08d3d87b05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Miko=C5=82ajczak?= Date: Fri, 22 Sep 2023 12:24:22 +0200 Subject: [PATCH 18/20] fix PropTypes --- src/pages/ReimbursementAccount/RequestorStep.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js index 33d36b5f9819..3e27c41d8b6b 100644 --- a/src/pages/ReimbursementAccount/RequestorStep.js +++ b/src/pages/ReimbursementAccount/RequestorStep.js @@ -15,12 +15,15 @@ import ONYXKEYS from '../../ONYXKEYS'; import RequestorOnfidoStep from './RequestorOnfidoStep'; import Form from '../../components/Form'; import ScreenWrapper from '../../components/ScreenWrapper'; -import StepPropTypes from './StepPropTypes'; import useLocalize from '../../hooks/useLocalize'; -import {withLocalizePropTypes} from '../../components/withLocalize'; +import {reimbursementAccountPropTypes} from './reimbursementAccountPropTypes'; +import ReimbursementAccountDraftPropTypes from './ReimbursementAccountDraftPropTypes'; const propTypes = { - ..._.omit(StepPropTypes, _.keys(withLocalizePropTypes)), + onBackButtonPress: PropTypes.func.isRequired, + getDefaultStateForField: PropTypes.func.isRequired, + reimbursementAccount: reimbursementAccountPropTypes.isRequired, + reimbursementAccountDraft: ReimbursementAccountDraftPropTypes.isRequired, /** If we should show Onfido flow */ shouldShowOnfido: PropTypes.bool.isRequired, From f1274513e5e6ed0a301c25a905572cd1ef4c0743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Miko=C5=82ajczak?= Date: Fri, 22 Sep 2023 16:57:58 +0200 Subject: [PATCH 19/20] add PropTypes to inner forward ref component --- src/pages/ReimbursementAccount/RequestorStep.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js index ca7995064d12..d2ffb68fb6d9 100644 --- a/src/pages/ReimbursementAccount/RequestorStep.js +++ b/src/pages/ReimbursementAccount/RequestorStep.js @@ -196,6 +196,8 @@ function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimburseme ); } +InnerRequestorStep.propTypes = propTypes; + const RequestorStep = React.forwardRef(InnerRequestorStep); RequestorStep.propTypes = propTypes; From 08ba6ac826f50b32612022450af79e34cb1c7d35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Miko=C5=82ajczak?= Date: Fri, 22 Sep 2023 17:04:56 +0200 Subject: [PATCH 20/20] fix displayName issues and remove inner component --- src/pages/ReimbursementAccount/RequestorStep.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js index d2ffb68fb6d9..53ca279c2cb2 100644 --- a/src/pages/ReimbursementAccount/RequestorStep.js +++ b/src/pages/ReimbursementAccount/RequestorStep.js @@ -72,7 +72,7 @@ const validate = (values) => { return errors; }; -function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimbursementAccountDraft, onBackButtonPress, getDefaultStateForField}) { +function RequestorStep({reimbursementAccount, shouldShowOnfido, reimbursementAccountDraft, onBackButtonPress, getDefaultStateForField}) { const {translate} = useLocalize(); const defaultValues = useMemo( @@ -196,11 +196,7 @@ function InnerRequestorStep({reimbursementAccount, shouldShowOnfido, reimburseme ); } -InnerRequestorStep.propTypes = propTypes; - -const RequestorStep = React.forwardRef(InnerRequestorStep); - RequestorStep.propTypes = propTypes; RequestorStep.displayName = 'RequestorStep'; -export default RequestorStep; +export default React.forwardRef(RequestorStep);