Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions assets/images/product-illustrations/earth-with-coins.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2636,6 +2636,10 @@ const ROUTES = {
route: 'settings/wallet/:bankAccountID/share-bank-account',
getRoute: (bankAccountID: number | undefined) => `settings/wallet/${bankAccountID}/share-bank-account` as const,
},
SETTINGS_WALLET_WISE_GLOBAL_REIMBURSEMENTS_INTRO: {
route: 'settings/wallet/:bankAccountID/global-reimbursements',
getRoute: (bankAccountID: number | undefined) => `settings/wallet/${bankAccountID}/global-reimbursements` as const,
},
SETTINGS_WALLET_EDIT_BANK_ACCOUNT_NICKNAME: {
route: 'settings/wallet/:bankAccountID/edit-nickname',
getRoute: (bankAccountID: number | undefined) => `settings/wallet/${bankAccountID}/edit-nickname` as const,
Expand Down
1 change: 1 addition & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ const SCREENS = {
DYNAMIC_ENABLE_GLOBAL_REIMBURSEMENTS_SIGN: 'Dynamic_Settings_Wallet_Enable_Global_Reimbursements_Sign',
SHARE_BANK_ACCOUNT: 'Settings_Wallet_Share_Bank_Account',
EDIT_BANK_ACCOUNT_NICKNAME: 'Settings_Wallet_Edit_Bank_Account_Nickname',
WISE_GLOBAL_REIMBURSEMENTS_INTRO: 'Settings_Wallet_Wise_Global_Reimbursements_Intro',
TRAVEL_CVV: 'Settings_Wallet_Travel_CVV',
TRAVEL_CVV_VERIFY_ACCOUNT: 'Settings_Wallet_Travel_CVV_VerifyAccount',
PERSONAL_CARD_DETAILS: 'Settings_Wallet_Personal_Card_Details',
Expand Down
9 changes: 8 additions & 1 deletion src/components/ConfirmationPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ function ConfirmationPage({
<ImageSVG
src={illustrations.Fireworks}
contentFit="contain"
aria-hidden
/>
</View>
);
Expand All @@ -150,11 +151,17 @@ function ConfirmationPage({
<ImageSVG
src={illustration}
contentFit="contain"
aria-hidden
/>
</View>
);
})()}
<Text style={[styles.textHeadline, styles.textAlignCenter, styles.mv2, headingStyle]}>{heading}</Text>
<Text
style={[styles.textHeadline, styles.textAlignCenter, styles.mv2, headingStyle]}
accessibilityRole={CONST.ROLE.HEADER}
>
{heading}
</Text>
{!!descriptionComponent && descriptionComponent}
{!!description && <Text style={[styles.textAlignCenter, descriptionStyle, styles.w100]}>{description}</Text>}
{cta ? <Text style={[styles.textAlignCenter, ctaStyle]}>{cta}</Text> : null}
Expand Down
2 changes: 2 additions & 0 deletions src/components/Icon/chunks/illustrations.chunk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import BigVault from '@assets/images/product-illustrations/big-vault.svg';
import BrokenCompanyCardBankConnection from '@assets/images/product-illustrations/broken-humpty-dumpty.svg';
import BrokenMagnifyingGlass from '@assets/images/product-illustrations/broken-magnifying-glass.svg';
import DjBoothReferenceHands from '@assets/images/product-illustrations/dj-booth-reference-hands.svg';
import EarthWithCoins from '@assets/images/product-illustrations/earth-with-coins.svg';
import EarthWithControls from '@assets/images/product-illustrations/earth-with-controls.svg';
import EmptyStateDomainExists from '@assets/images/product-illustrations/empty-state-domain-exists.svg';
import EmptyStateExpenses from '@assets/images/product-illustrations/emptystate__expenses.svg';
Expand Down Expand Up @@ -300,6 +301,7 @@ const Illustrations = {
HoldExpense,
ReceiptFairy,
EmptyStateTravel,
EarthWithCoins,
EarthWithControls,
EmptyStateDomainExists,
Fireworks,
Expand Down
1 change: 1 addition & 0 deletions src/languages/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2828,6 +2828,7 @@ const translations: TranslationDeepObject<typeof en> = {
accountRequiresAttention: 'Dieses Konto erfordert Ihre Aufmerksamkeit',
unlock: 'Entsperren',
},
wiseGlobalReimbursementsIntro: {title: 'Globale Rückerstattungen einrichten?', subtitle: 'Zahlen Sie Mitglieder weltweit in ihrer lokalen Währung.', getStarted: "Los geht's"},
},
addCardToDigitalWallet: {
title: ({walletName}: {walletName: string}) => `Karte zu ${walletName} hinzufügen`,
Expand Down
1 change: 1 addition & 0 deletions src/languages/el.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2884,6 +2884,7 @@ const translations: TranslationDeepObject<typeof en> = {
accountRequiresAttention: 'Αυτός ο λογαριασμός χρειάζεται προσοχή',
unlock: 'Ξεκλείδωμα',
},
wiseGlobalReimbursementsIntro: {title: 'Να ρυθμιστούν οι παγκόσμιες αποζημιώσεις;', subtitle: 'Πληρώστε μέλη παγκοσμίως στο τοπικό τους νόμισμα.', getStarted: 'Ξεκινήστε'},
},
addCardToDigitalWallet: {
title: ({walletName}: {walletName: string}) => `Προσθήκη κάρτας στο ${walletName}`,
Expand Down
5 changes: 5 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2900,6 +2900,11 @@ const translations = {
editNickname: 'Edit nickname',
nickname: 'Nickname',
editNicknameInstruction: 'Give the bank account a nickname that sets it apart from others.',
wiseGlobalReimbursementsIntro: {
title: 'Set up global reimbursements?',
subtitle: 'Pay members worldwide in their local currency.',
getStarted: 'Get started',
},
deleteCard: 'Delete card',
deleteCardConfirmation:
'All unsubmitted card transactions, including those on open reports, will be removed. Are you sure you want to delete this card? You cannot undo this action.',
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2738,6 +2738,7 @@ const translations: TranslationDeepObject<typeof en> = {
accountRequiresAttention: 'Esta cuenta requiere atención',
unlock: 'Desbloquear',
},
wiseGlobalReimbursementsIntro: {title: '¿Configurar reembolsos globales?', subtitle: 'Paga a miembros de todo el mundo en su moneda local.', getStarted: 'Empieza'},
},
addCardToDigitalWallet: {
title: ({walletName}: {walletName: string}) => `Añadir tarjeta a ${walletName}`,
Expand Down
5 changes: 5 additions & 0 deletions src/languages/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2833,6 +2833,11 @@ const translations: TranslationDeepObject<typeof en> = {
accountRequiresAttention: 'Ce compte nécessite une attention particulière',
unlock: 'Déverrouiller',
},
wiseGlobalReimbursementsIntro: {
title: 'Configurer les remboursements globaux ?',
subtitle: 'Payez des membres partout dans le monde dans leur devise locale.',
getStarted: 'Commencer',
},
},
addCardToDigitalWallet: {
title: ({walletName}: {walletName: string}) => `Ajouter la carte à ${walletName}`,
Expand Down
1 change: 1 addition & 0 deletions src/languages/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2817,6 +2817,7 @@ const translations: TranslationDeepObject<typeof en> = {
accountRequiresAttention: 'Questo conto richiede attenzione',
unlock: 'Sblocca',
},
wiseGlobalReimbursementsIntro: {title: 'Configurare i rimborsi globali?', subtitle: 'Paga i membri in tutto il mondo nella loro valuta locale.', getStarted: 'Inizia'},
},
addCardToDigitalWallet: {
title: ({walletName}: {walletName: string}) => `Aggiungi carta a ${walletName}`,
Expand Down
1 change: 1 addition & 0 deletions src/languages/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2796,6 +2796,7 @@ const translations: TranslationDeepObject<typeof en> = {
accountRequiresAttention: 'このアカウントには対応が必要です',
unlock: 'ロック解除',
},
wiseGlobalReimbursementsIntro: {title: 'グローバル払い戻しを設定しますか?', subtitle: '世界中のメンバーに現地通貨で支払えます。', getStarted: '使い始める'},
},
addCardToDigitalWallet: {
title: ({walletName}: {walletName: string}) => `${walletName} にカードを追加`,
Expand Down
1 change: 1 addition & 0 deletions src/languages/nl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2821,6 +2821,7 @@ const translations: TranslationDeepObject<typeof en> = {
accountRequiresAttention: 'Deze account vereist aandacht',
unlock: 'Ontgrendelen',
},
wiseGlobalReimbursementsIntro: {title: 'Wereldwijde terugbetalingen instellen?', subtitle: 'Betaal leden wereldwijd in hun eigen lokale valuta.', getStarted: 'Aan de slag'},
},
addCardToDigitalWallet: {
title: ({walletName}: {walletName: string}) => `Kaart toevoegen aan ${walletName}`,
Expand Down
1 change: 1 addition & 0 deletions src/languages/pl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2855,6 +2855,7 @@ const translations: TranslationDeepObject<typeof en> = {
accountRequiresAttention: 'To konto wymaga uwagi',
unlock: 'Odblokuj',
},
wiseGlobalReimbursementsIntro: {title: 'Skonfigurować globalne zwroty kosztów?', subtitle: 'Płać członkom na całym świecie w ich lokalnej walucie.', getStarted: 'Zacznij'},
},
addCardToDigitalWallet: {
title: ({walletName}: {walletName: string}) => `Dodaj kartę do ${walletName}`,
Expand Down
1 change: 1 addition & 0 deletions src/languages/pt-BR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2812,6 +2812,7 @@ const translations: TranslationDeepObject<typeof en> = {
accountRequiresAttention: 'Esta conta precisa de atenção',
unlock: 'Desbloquear',
},
wiseGlobalReimbursementsIntro: {title: 'Configurar reembolsos globais?', subtitle: 'Pague membros no mundo todo na moeda local deles.', getStarted: 'Começar'},
},
addCardToDigitalWallet: {
title: ({walletName}: {walletName: string}) => `Adicionar cartão à ${walletName}`,
Expand Down
1 change: 1 addition & 0 deletions src/languages/zh-hans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2722,6 +2722,7 @@ const translations: TranslationDeepObject<typeof en> = {
accountRequiresAttention: '此账户需要处理',
unlock: '解锁',
},
wiseGlobalReimbursementsIntro: {title: '设置全球报销?', subtitle: '按当地货币向全球成员付款。', getStarted: '开始使用'},
},
addCardToDigitalWallet: {
title: ({walletName}: {walletName: string}) => `将卡添加到 ${walletName}`,
Expand Down
13 changes: 13 additions & 0 deletions src/libs/BankAccountUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,18 @@ function isFilterableBankAccount(bankAccount: OnyxEntry<OnyxTypes.BankAccount>):
return bankAccount?.accountData?.type === CONST.BANK_ACCOUNT.TYPE.BUSINESS && !isBankAccountPartiallySetup(bankAccount?.accountData?.state);
}

/**
* A verified (OPEN) USD business bank account that is not already set up for global reimbursements can start the Wise flow.
*/
function isEligibleForWiseGlobalReimbursements(accountData: AccountData | undefined): boolean {
return (
accountData?.additionalData?.currency === CONST.CURRENCY.USD &&
accountData.type === CONST.BANK_ACCOUNT.TYPE.BUSINESS &&
!accountData.additionalData.verifications?.corpay &&
accountData.state === CONST.BANK_ACCOUNT.STATE.OPEN
);
}
Comment on lines +142 to +149

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

!paymentMethod.selectedPaymentMethod?.additionalData?.verifications?.corpay &&

@WojtekBoman do we need to apply this here too? there is also a check for !verifications.corpay (ie the bank account has existing verification) so we may need to add for both


function doesPolicyHavePartiallySetupBankAccount(bankAccountList: OnyxEntry<OnyxTypes.BankAccountList>, policyID: string) {
if (!bankAccountList) {
return false;
Expand Down Expand Up @@ -300,6 +312,7 @@ function showUnlockAlreadyRequestedModal(showConfirmModal: ReturnType<typeof use
export {
getBankAccountSearchLabel,
isFilterableBankAccount,
isEligibleForWiseGlobalReimbursements,
getDefaultCompanyWebsite,
getBankAccountState,
hasBankAccountAllowDebit,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,7 @@ const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorP
require<ReactComponentModule>('../../../../pages/settings/Wallet/EnableGlobalReimbursements/EnableGlobalReimbursementsSignPage').default,
[SCREENS.SETTINGS.WALLET.SHARE_BANK_ACCOUNT]: () => require<ReactComponentModule>('../../../../pages/settings/Wallet/ShareBankAccount/ShareBankAccount').default,
[SCREENS.SETTINGS.WALLET.EDIT_BANK_ACCOUNT_NICKNAME]: () => require<ReactComponentModule>('../../../../pages/settings/Wallet/EditBankAccountNicknamePage').default,
[SCREENS.SETTINGS.WALLET.WISE_GLOBAL_REIMBURSEMENTS_INTRO]: () => require<ReactComponentModule>('../../../../pages/settings/Wallet/WiseGlobalReimbursementsIntroPage').default,
[SCREENS.SETTINGS.WALLET.TRAVEL_CVV]: () => require<ReactComponentModule>('../../../../pages/settings/Wallet/TravelCVVPage/TravelCVVPage').default,
[SCREENS.SETTINGS.WALLET.TRAVEL_CVV_VERIFY_ACCOUNT]: () => require<ReactComponentModule>('../../../../pages/settings/Wallet/TravelCVVPage/TravelCVVVerifyAccountPage').default,
[SCREENS.SETTINGS.WALLET.PERSONAL_CARD_FIX_CONNECTION]: () => require<ReactComponentModule>('@pages/settings/Wallet/PersonalCards/FixPersonalCardConnectionPage').default,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const SETTINGS_TO_RHP: Partial<Record<keyof SettingsSplitNavigatorParamList, str
SCREENS.SETTINGS.WALLET.ENABLE_GLOBAL_REIMBURSEMENTS_SIGN,
SCREENS.SETTINGS.WALLET.SHARE_BANK_ACCOUNT,
SCREENS.SETTINGS.WALLET.EDIT_BANK_ACCOUNT_NICKNAME,
SCREENS.SETTINGS.WALLET.WISE_GLOBAL_REIMBURSEMENTS_INTRO,
SCREENS.SETTINGS.WALLET.CARD_ACTIVATE,
SCREENS.SETTINGS.WALLET.REPORT_VIRTUAL_CARD_FRAUD,
SCREENS.SETTINGS.WALLET.REPORT_VIRTUAL_CARD_FRAUD_CONFIRM_VALIDATE_CODE,
Expand Down
4 changes: 4 additions & 0 deletions src/libs/Navigation/linkingConfig/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,10 @@ const config: LinkingOptions<RootNavigatorParamList>['config'] = {
path: ROUTES.SETTINGS_WALLET_SHARE_BANK_ACCOUNT.route,
exact: true,
},
[SCREENS.SETTINGS.WALLET.WISE_GLOBAL_REIMBURSEMENTS_INTRO]: {
path: ROUTES.SETTINGS_WALLET_WISE_GLOBAL_REIMBURSEMENTS_INTRO.route,
exact: true,
},
[SCREENS.SETTINGS.WALLET.EDIT_BANK_ACCOUNT_NICKNAME]: {
path: ROUTES.SETTINGS_WALLET_EDIT_BANK_ACCOUNT_NICKNAME.route,
exact: true,
Expand Down
3 changes: 3 additions & 0 deletions src/libs/Navigation/paramLists/AccountSettingsParamList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ type AccountSettingsParamList = {
[SCREENS.SETTINGS.WALLET.SHARE_BANK_ACCOUNT]: {
bankAccountID: string;
};
[SCREENS.SETTINGS.WALLET.WISE_GLOBAL_REIMBURSEMENTS_INTRO]: {
bankAccountID: string;
};
[SCREENS.SETTINGS.WALLET.EDIT_BANK_ACCOUNT_NICKNAME]: {
bankAccountID: string;
};
Expand Down
90 changes: 90 additions & 0 deletions src/pages/settings/Wallet/WiseGlobalReimbursementsIntroPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView';
import ConfirmationPage from '@components/ConfirmationPage';
import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator';
import Header from '@components/Header';
import ScreenWrapper from '@components/ScreenWrapper';

import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
import useOnyx from '@hooks/useOnyx';
import usePermissions from '@hooks/usePermissions';
import useStyleUtils from '@hooks/useStyleUtils';
import useThemeStyles from '@hooks/useThemeStyles';

import {isEligibleForWiseGlobalReimbursements} from '@libs/BankAccountUtils';
import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';

import Navigation from '@navigation/Navigation';
import type {SettingsNavigatorParamList} from '@navigation/types';

import variables from '@styles/variables';

import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type SCREENS from '@src/SCREENS';
import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue';

import React, {useEffect} from 'react';

type WiseGlobalReimbursementsIntroPageProps = PlatformStackScreenProps<SettingsNavigatorParamList, typeof SCREENS.SETTINGS.WALLET.WISE_GLOBAL_REIMBURSEMENTS_INTRO>;

function WiseGlobalReimbursementsIntroPage({route}: WiseGlobalReimbursementsIntroPageProps) {
const bankAccountID = Number(route.params.bankAccountID);
const [bankAccountList, bankAccountListMetadata] = useOnyx(ONYXKEYS.BANK_ACCOUNT_LIST);
const [isLoadingPaymentMethods = true] = useOnyx(ONYXKEYS.IS_LOADING_PAYMENT_METHODS);
const bankAccount = bankAccountList?.[bankAccountID];

const {translate} = useLocalize();
const {isBetaEnabledOrUnknown} = usePermissions();
const isWiseReimbursementsBetaEnabled = isBetaEnabledOrUnknown(CONST.BETAS.WISE_REIMBURSEMENTS);
const styles = useThemeStyles();
const StyleUtils = useStyleUtils();
const illustrations = useMemoizedLazyIllustrations(['EarthWithCoins']);

const goBackToWallet = () => Navigation.goBack(ROUTES.SETTINGS_WALLET);

// Close the page instead of showing "not found" when the user lacks the beta. Wait for betas to load first
useEffect(() => {
if (isWiseReimbursementsBetaEnabled !== false) {
Comment thread
grgia marked this conversation as resolved.
return;
}
goBackToWallet();
}, [isWiseReimbursementsBetaEnabled, goBackToWallet]);

// On a cold direct link the account list can be empty until the payment-method fetch finishes, so wait for it before judging eligibility
const isWaitingForBankAccount = !bankAccount && !!isLoadingPaymentMethods;

if (isLoadingOnyxValue(bankAccountListMetadata) || isWaitingForBankAccount || !isWiseReimbursementsBetaEnabled) {
return <FullScreenLoadingIndicator shouldUseGoBackButton />;
}

return (
<ScreenWrapper testID="WiseGlobalReimbursementsIntroPage">
<FullPageNotFoundView
shouldShow={!isEligibleForWiseGlobalReimbursements(bankAccount?.accountData)}
onBackButtonPress={goBackToWallet}
>
<Header>
<Header.BackButton onPress={goBackToWallet} />
<Header.Title title={translate('common.enableGlobalReimbursements')} />
</Header>
<ConfirmationPage
illustration={illustrations.EarthWithCoins}
illustrationStyle={StyleUtils.getWidthAndHeightStyle(variables.wiseGlobalReimbursementsIntroIllustrationSize)}
heading={translate('walletPage.wiseGlobalReimbursementsIntro.title')}
description={translate('walletPage.wiseGlobalReimbursementsIntro.subtitle')}
descriptionStyle={styles.textSupporting}
shouldShowSecondaryButton
secondaryButtonText={translate('common.notNow')}
onSecondaryButtonPress={goBackToWallet}
shouldShowButton
buttonText={translate('walletPage.wiseGlobalReimbursementsIntro.getStarted')}
onButtonPress={() => {}}
/>
</FullPageNotFoundView>
</ScreenWrapper>
);
}

export default WiseGlobalReimbursementsIntroPage;
1 change: 1 addition & 0 deletions src/styles/variables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ export default {
productMarketingWindowOffset: 20,
productMarketingWindowOffsetNarrow: 12,
productMarketingWindowHorizontalOffsetNarrow: 16,
wiseGlobalReimbursementsIntroIllustrationSize: 250,
holdEducationModalWidth: 400,
changePolicyEducationModalWidth: 400,
wideConfirmModalWidth: 400,
Expand Down
Loading
Loading