Skip to content

Commit

Permalink
Merge pull request #40567 from koko57/refactor/36648-wallet-enablemen…
Browse files Browse the repository at this point in the history
…t-flow-terms

Refactor/36648 wallet enablement flow terms
  • Loading branch information
mountiny authored May 13, 2024
2 parents 15088d5 + 267ef3c commit 1e5c18c
Show file tree
Hide file tree
Showing 11 changed files with 245 additions and 10 deletions.
3 changes: 3 additions & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,10 @@ const ROUTES = {
SETTINGS_ADD_BANK_ACCOUNT: 'settings/wallet/add-bank-account',
SETTINGS_ADD_BANK_ACCOUNT_REFACTOR: 'settings/wallet/add-bank-account-refactor',
SETTINGS_ENABLE_PAYMENTS: 'settings/wallet/enable-payments',
// TODO: Added temporarily for testing purposes, remove after refactor - https://github.com/Expensify/App/issues/36648
SETTINGS_ENABLE_PAYMENTS_REFACTOR: 'settings/wallet/enable-payments-refactor',
// TODO: Added temporarily for testing purposes, remove after refactor - https://github.com/Expensify/App/issues/36648
SETTINGS_ENABLE_PAYMENTS_TEMPORARY_TERMS: 'settings/wallet/enable-payments-temporary-terms',
SETTINGS_WALLET_CARD_DIGITAL_DETAILS_UPDATE_ADDRESS: {
route: 'settings/wallet/card/:domain/digital-details/update-address',
getRoute: (domain: string) => `settings/wallet/card/${domain}/digital-details/update-address` as const,
Expand Down
3 changes: 3 additions & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,10 @@ const SCREENS = {
TRANSFER_BALANCE: 'Settings_Wallet_Transfer_Balance',
CHOOSE_TRANSFER_ACCOUNT: 'Settings_Wallet_Choose_Transfer_Account',
ENABLE_PAYMENTS: 'Settings_Wallet_EnablePayments',
// TODO: Added temporarily for testing purposes, remove after refactor - https://github.com/Expensify/App/issues/36648
ENABLE_PAYMENTS_REFACTOR: 'Settings_Wallet_EnablePayments_Refactor',
// TODO: Added temporarily for testing purposes, remove after refactor - https://github.com/Expensify/App/issues/36648
ENABLE_PAYMENTS_TEMPORARY_TERMS: 'Settings_Wallet_EnablePayments_Temporary_Terms',
CARD_ACTIVATE: 'Settings_Wallet_Card_Activate',
REPORT_VIRTUAL_CARD_FRAUD: 'Settings_Wallet_ReportVirtualCardFraud',
CARDS_DIGITAL_DETAILS_UPDATE_ADDRESS: 'Settings_Wallet_Cards_Digital_Details_Update_Address',
Expand Down
4 changes: 4 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1600,6 +1600,7 @@ export default {
},
termsStep: {
headerTitle: 'Terms and fees',
headerTitleRefactor: 'Fees and terms',
haveReadAndAgree: 'I have read and agree to receive ',
electronicDisclosures: 'electronic disclosures',
agreeToThe: 'I agree to the',
Expand All @@ -1610,6 +1611,9 @@ export default {
noOverdraftOrCredit: 'No overdraft/credit feature.',
electronicFundsWithdrawal: 'Electronic funds withdrawal',
standard: 'Standard',
takeALookAtSomeFees: 'Take a look at some fees.',
checkPlease: 'Check please.',
agreeToTerms: 'Agree to the terms and you’ll be good to go!',
shortTermsForm: {
expensifyPaymentsAccount: ({walletProgram}: WalletProgramParams) => `The Expensify Wallet is issued by ${walletProgram}.`,
perPurchase: 'Per purchase',
Expand Down
4 changes: 4 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1621,6 +1621,7 @@ export default {
},
termsStep: {
headerTitle: 'Condiciones y tarifas',
headerTitleRefactor: 'Tarifas y condiciones',
haveReadAndAgree: 'He leído y acepto recibir ',
electronicDisclosures: 'divulgaciones electrónicas',
agreeToThe: 'Estoy de acuerdo con el ',
Expand All @@ -1631,6 +1632,9 @@ export default {
noOverdraftOrCredit: 'Sin función de sobregiro/crédito',
electronicFundsWithdrawal: 'Retiro electrónico de fondos',
standard: 'Estándar',
takeALookAtSomeFees: 'Echa un vistazo a algunas tarifas.',
checkPlease: 'Por favor, revisa.',
agreeToTerms: 'Debes aceptar los términos y condiciones para continuar.',
shortTermsForm: {
expensifyPaymentsAccount: ({walletProgram}: WalletProgramParams) => `La billetera Expensify es emitida por ${walletProgram}.`,
perPurchase: 'Por compra',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,10 @@ const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorP
[SCREENS.SETTINGS.WALLET.TRANSFER_BALANCE]: () => require('../../../../pages/settings/Wallet/TransferBalancePage').default as React.ComponentType,
[SCREENS.SETTINGS.WALLET.CHOOSE_TRANSFER_ACCOUNT]: () => require('../../../../pages/settings/Wallet/ChooseTransferAccountPage').default as React.ComponentType,
[SCREENS.SETTINGS.WALLET.ENABLE_PAYMENTS]: () => require('../../../../pages/EnablePayments/EnablePaymentsPage').default as React.ComponentType,
// TODO: Added temporarily for testing purposes, remove after refactor - https://github.com/Expensify/App/issues/36648
[SCREENS.SETTINGS.WALLET.ENABLE_PAYMENTS_REFACTOR]: () => require('../../../../pages/EnablePayments/PersonalInfo/PersonalInfo').default as React.ComponentType,
// TODO: Added temporarily for testing purposes, remove after refactor - https://github.com/Expensify/App/issues/36648
[SCREENS.SETTINGS.WALLET.ENABLE_PAYMENTS_TEMPORARY_TERMS]: () => require('../../../../pages/EnablePayments/FeesAndTerms/FeesAndTerms').default as React.ComponentType,
[SCREENS.SETTINGS.ADD_DEBIT_CARD]: () => require('../../../../pages/settings/Wallet/AddDebitCardPage').default as React.ComponentType,
[SCREENS.SETTINGS.ADD_BANK_ACCOUNT]: () => require('../../../../pages/AddPersonalBankAccountPage').default as React.ComponentType,
[SCREENS.SETTINGS.ADD_BANK_ACCOUNT_REFACTOR]: () => require('../../../../pages/EnablePayments/AddBankAccount/AddBankAccount').default as React.ComponentType,
Expand Down
6 changes: 6 additions & 0 deletions src/libs/Navigation/linkingConfig/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,16 @@ const config: LinkingOptions<RootStackParamList>['config'] = {
path: ROUTES.SETTINGS_ENABLE_PAYMENTS,
exact: true,
},
// TODO: Added temporarily for testing purposes, remove after refactor - https://github.com/Expensify/App/issues/36648
[SCREENS.SETTINGS.WALLET.ENABLE_PAYMENTS_REFACTOR]: {
path: ROUTES.SETTINGS_ENABLE_PAYMENTS_REFACTOR,
exact: true,
},
// TODO: Added temporarily for testing purposes, remove after refactor - https://github.com/Expensify/App/issues/36648
[SCREENS.SETTINGS.WALLET.ENABLE_PAYMENTS_TEMPORARY_TERMS]: {
path: ROUTES.SETTINGS_ENABLE_PAYMENTS_TEMPORARY_TERMS,
exact: true,
},
[SCREENS.SETTINGS.WALLET.TRANSFER_BALANCE]: {
path: ROUTES.SETTINGS_WALLET_TRANSFER_BALANCE,
exact: true,
Expand Down
62 changes: 62 additions & 0 deletions src/pages/EnablePayments/FeesAndTerms/FeesAndTerms.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React from 'react';
import {View} from 'react-native';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import InteractiveStepSubHeader from '@components/InteractiveStepSubHeader';
import ScreenWrapper from '@components/ScreenWrapper';
import useLocalize from '@hooks/useLocalize';
import useSubStep from '@hooks/useSubStep';
import type {SubStepProps} from '@hooks/useSubStep/types';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@navigation/Navigation';
import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';
import FeesStep from './substeps/FeesStep';
import TermsStep from './substeps/TermsStep';

const termsAndFeesSubsteps: Array<React.ComponentType<SubStepProps>> = [FeesStep, TermsStep];

function FeesAndTerms() {
const {translate} = useLocalize();
const styles = useThemeStyles();

const submit = () => {};
const {componentToRender: SubStep, isEditing, screenIndex, nextScreen, prevScreen, moveTo} = useSubStep({bodyContent: termsAndFeesSubsteps, startFrom: 0, onFinished: submit});

const handleBackButtonPress = () => {
if (screenIndex === 0) {
// TODO: temporary for refactor https://github.com/Expensify/App/issues/36648
Navigation.navigate(ROUTES.SETTINGS_WALLET);
return;
}
prevScreen();
};

return (
<ScreenWrapper
testID={FeesAndTerms.displayName}
includeSafeAreaPaddingBottom={false}
shouldEnablePickerAvoiding={false}
shouldEnableMaxHeight
>
<HeaderWithBackButton
title={translate('termsStep.headerTitleRefactor')}
onBackButtonPress={handleBackButtonPress}
/>
<View style={[styles.ph5, styles.mb5, styles.mt3, {height: CONST.BANK_ACCOUNT.STEPS_HEADER_HEIGHT}]}>
<InteractiveStepSubHeader
startStepIndex={3}
stepNames={CONST.WALLET.STEP_NAMES}
/>
</View>
<SubStep
isEditing={isEditing}
onNext={nextScreen}
onMove={moveTo}
/>
</ScreenWrapper>
);
}

FeesAndTerms.displayName = 'TermsAndFees';

export default FeesAndTerms;
37 changes: 37 additions & 0 deletions src/pages/EnablePayments/FeesAndTerms/substeps/FeesStep.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react';
import {View} from 'react-native';
import {useOnyx} from 'react-native-onyx';
import Button from '@components/Button';
import ScrollView from '@components/ScrollView';
import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
import type {SubStepProps} from '@hooks/useSubStep/types';
import useThemeStyles from '@hooks/useThemeStyles';
import LongTermsForm from '@pages/EnablePayments/TermsPage/LongTermsForm';
import ShortTermsForm from '@pages/EnablePayments/TermsPage/ShortTermsForm';
import ONYXKEYS from '@src/ONYXKEYS';

function FeesStep({onNext}: SubStepProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const [userWallet] = useOnyx(ONYXKEYS.USER_WALLET);

return (
<ScrollView style={styles.flex1}>
<Text style={[styles.textHeadlineLineHeightXXL, styles.ph5, styles.mb3]}>{translate('termsStep.takeALookAtSomeFees')}</Text>
<View style={[styles.ph5]}>
<ShortTermsForm userWallet={userWallet} />
<LongTermsForm />
<Button
success
large
style={[styles.w100, styles.mv5]}
onPress={onNext}
text={translate('common.next')}
/>
</View>
</ScrollView>
);
}

export default FeesStep;
112 changes: 112 additions & 0 deletions src/pages/EnablePayments/FeesAndTerms/substeps/TermsStep.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import React, {useEffect, useState} from 'react';
import {View} from 'react-native';
import {useOnyx} from 'react-native-onyx';
import CheckboxWithLabel from '@components/CheckboxWithLabel';
import FormAlertWithSubmitButton from '@components/FormAlertWithSubmitButton';
import Text from '@components/Text';
import TextLink from '@components/TextLink';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as ErrorUtils from '@libs/ErrorUtils';
import Navigation from '@navigation/Navigation';
// TODO: uncomment at the end of the refactor https://github.com/Expensify/App/issues/36648
// import * as BankAccounts from '@userActions/BankAccounts';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';

function HaveReadAndAgreeLabel() {
const {translate} = useLocalize();

return (
<Text>
{`${translate('termsStep.haveReadAndAgree')}`}
<TextLink href={CONST.ELECTRONIC_DISCLOSURES_URL}>{`${translate('termsStep.electronicDisclosures')}.`}</TextLink>
</Text>
);
}

function AgreeToTheLabel() {
const {translate} = useLocalize();

return (
<Text>
{`${translate('termsStep.agreeToThe')} `}
<TextLink href={CONST.PRIVACY_URL}>{`${translate('common.privacy')} `}</TextLink>
{`${translate('common.and')} `}
<TextLink href={CONST.WALLET_AGREEMENT_URL}>{`${translate('termsStep.walletAgreement')}.`}</TextLink>
</Text>
);
}

function TermsStep() {
const styles = useThemeStyles();
const [hasAcceptedDisclosure, setHasAcceptedDisclosure] = useState(false);
const [hasAcceptedPrivacyPolicyAndWalletAgreement, setHasAcceptedPrivacyPolicyAndWalletAgreement] = useState(false);
const [error, setError] = useState(false);
const {translate} = useLocalize();

const [walletTerms] = useOnyx(ONYXKEYS.WALLET_TERMS);

const errorMessage = error ? 'common.error.acceptTerms' : ErrorUtils.getLatestErrorMessage(walletTerms ?? {}) ?? '';

const toggleDisclosure = () => {
setHasAcceptedDisclosure(!hasAcceptedDisclosure);
};

const togglePrivacyPolicy = () => {
setHasAcceptedPrivacyPolicyAndWalletAgreement(!hasAcceptedPrivacyPolicyAndWalletAgreement);
};

/** clear error */
useEffect(() => {
if (!hasAcceptedDisclosure || !hasAcceptedPrivacyPolicyAndWalletAgreement) {
return;
}

setError(false);
}, [hasAcceptedDisclosure, hasAcceptedPrivacyPolicyAndWalletAgreement]);

return (
<View style={[styles.flexGrow1, styles.ph5]}>
<Text style={[styles.textHeadlineLineHeightXXL]}>{translate('termsStep.checkPlease')}</Text>
<Text style={[styles.mt3, styles.mb3, styles.textSupporting]}>{translate('termsStep.agreeToTerms')}</Text>
<View style={styles.flex1}>
<CheckboxWithLabel
accessibilityLabel={translate('termsStep.haveReadAndAgree')}
style={[styles.mb4, styles.mt4]}
onInputChange={toggleDisclosure}
LabelComponent={HaveReadAndAgreeLabel}
/>
<CheckboxWithLabel
accessibilityLabel={translate('termsStep.agreeToThe')}
onInputChange={togglePrivacyPolicy}
LabelComponent={AgreeToTheLabel}
/>
</View>
<FormAlertWithSubmitButton
buttonText={translate('termsStep.enablePayments')}
onSubmit={() => {
if (!hasAcceptedDisclosure || !hasAcceptedPrivacyPolicyAndWalletAgreement) {
setError(true);
return;
}

setError(false);
// TODO: uncomment at the end of the refactor https://github.com/Expensify/App/issues/36648
// BankAccounts.acceptWalletTerms({
// hasAcceptedTerms: hasAcceptedDisclosure && hasAcceptedPrivacyPolicyAndWalletAgreement,
// reportID: walletTerms?.chatReportID ?? '',
// });
Navigation.navigate(ROUTES.SETTINGS_WALLET);
}}
message={errorMessage}
isAlertVisible={error || Boolean(errorMessage)}
isLoading={!!walletTerms?.isLoading}
containerStyles={[styles.mh0, styles.mv5]}
/>
</View>
);
}

export default TermsStep;
16 changes: 8 additions & 8 deletions src/pages/EnablePayments/TermsPage/ShortTermsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ function ShortTermsForm(props: ShortTermsFormProps) {
const {translate, numberFormat} = useLocalize();
return (
<>
<Text style={styles.mb5}>
<Text style={[styles.mb5, styles.textSupporting]}>
{translate('termsStep.shortTermsForm.expensifyPaymentsAccount', {
walletProgram:
props.userWallet?.walletProgramID === CONST.WALLET.MTL_WALLET_PROGRAM_ID
Expand All @@ -32,7 +32,7 @@ function ShortTermsForm(props: ShortTermsFormProps) {
<View style={[styles.shortTermsRow, styles.mb4]}>
<View style={[styles.flex2]}>
<View style={[styles.flexRow, styles.mb1]}>
<Text style={styles.textLarge}>{translate('termsStep.monthlyFee')}</Text>
<Text style={styles.mutedNormalTextLabel}>{translate('termsStep.monthlyFee')}</Text>
</View>
<View style={styles.flexRow}>
<Text style={styles.shortTermsHeadline}>{CurrencyUtils.convertToDisplayString(0, 'USD')}</Text>
Expand All @@ -41,7 +41,7 @@ function ShortTermsForm(props: ShortTermsFormProps) {
<View style={[styles.flex2]}>
<View style={[styles.flex2]}>
<View style={[styles.flexRow, styles.mb1]}>
<Text style={styles.textLarge}>{translate('termsStep.shortTermsForm.perPurchase')}</Text>
<Text style={styles.mutedNormalTextLabel}>{translate('termsStep.shortTermsForm.perPurchase')}</Text>
</View>
<View style={styles.flexRow}>
<Text style={styles.shortTermsHeadline}>{CurrencyUtils.convertToDisplayString(0, 'USD')}</Text>
Expand All @@ -51,27 +51,27 @@ function ShortTermsForm(props: ShortTermsFormProps) {
</View>

<View style={[styles.shortTermsRow, styles.mb6]}>
<View style={[styles.flex2]}>
<View style={styles.flex2}>
<View style={[styles.flexRow, styles.mb1]}>
<Text style={styles.textLarge}>{translate('termsStep.shortTermsForm.atmWithdrawal')}</Text>
<Text style={styles.mutedNormalTextLabel}>{translate('termsStep.shortTermsForm.atmWithdrawal')}</Text>
</View>
<View style={styles.flexRow}>
<Text style={styles.shortTermsHeadline}>{translate('common.na')}</Text>
</View>
<View style={styles.flexRow}>
<Text style={styles.textLabelSupporting}>{translate('termsStep.shortTermsForm.inNetwork')}</Text>
<Text style={styles.textMicroSupporting}>{translate('termsStep.shortTermsForm.inNetwork')}</Text>
</View>
<View style={[styles.flexRow, styles.mt4]}>
<Text style={styles.shortTermsHeadline}>{translate('common.na')}</Text>
</View>
<View style={styles.flexRow}>
<Text style={styles.textLabelSupporting}>{translate('termsStep.shortTermsForm.outOfNetwork')}</Text>
<Text style={styles.textMicroSupporting}>{translate('termsStep.shortTermsForm.outOfNetwork')}</Text>
</View>
</View>
<View style={[styles.flex2]}>
<View style={[styles.flex2]}>
<View style={[styles.flexRow, styles.mb1]}>
<Text style={styles.textLarge}>{translate('termsStep.shortTermsForm.cashReload')}</Text>
<Text style={styles.mutedNormalTextLabel}>{translate('termsStep.shortTermsForm.cashReload')}</Text>
</View>
<View style={styles.flexRow}>
<Text style={styles.shortTermsHeadline}>{translate('common.na')}</Text>
Expand Down
5 changes: 3 additions & 2 deletions src/styles/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3378,6 +3378,7 @@ const styles = (theme: ThemeColors) =>
shortTermsBorder: {
borderWidth: 1,
borderColor: theme.border,
borderRadius: variables.componentBorderRadius,
},

shortTermsHorizontalRule: {
Expand Down Expand Up @@ -3412,8 +3413,8 @@ const styles = (theme: ThemeColors) =>
...headlineFont,
...whiteSpace.preWrap,
color: theme.heading,
fontSize: variables.fontSizeXXXLarge,
lineHeight: variables.lineHeightXXXLarge,
fontSize: variables.fontSizeXLarge,
lineHeight: variables.lineHeightXXLarge,
},

longTermsRow: {
Expand Down

0 comments on commit 1e5c18c

Please sign in to comment.