diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts
index 6649a33fe15e..c3fbcd457555 100755
--- a/src/ONYXKEYS.ts
+++ b/src/ONYXKEYS.ts
@@ -291,6 +291,7 @@ const ONYXKEYS = {
PRIVATE_NOTES_FORM: 'privateNotesForm',
I_KNOW_A_TEACHER_FORM: 'iKnowTeacherForm',
INTRO_SCHOOL_PRINCIPAL_FORM: 'introSchoolPrincipalForm',
+ REPORT_FRAUD_FORM: 'reportFraudForm',
},
} as const;
diff --git a/src/ROUTES.ts b/src/ROUTES.ts
index 1b2e9330869f..9d8792802954 100644
--- a/src/ROUTES.ts
+++ b/src/ROUTES.ts
@@ -76,6 +76,10 @@ export default {
route: '/settings/wallet/card/:domain',
getRoute: (domain: string) => `/settings/wallet/card/${domain}`,
},
+ SETTINGS_REPORT_FRAUD: {
+ route: '/settings/wallet/cards/:domain/report-digital-fraud',
+ getRoute: (domain: string) => `/settings/wallet/cards/${domain}/report-digital-fraud`,
+ },
SETTINGS_ADD_DEBIT_CARD: 'settings/wallet/add-debit-card',
SETTINGS_ADD_BANK_ACCOUNT: 'settings/wallet/add-bank-account',
SETTINGS_ENABLE_PAYMENTS: 'settings/wallet/enable-payments',
diff --git a/src/languages/en.ts b/src/languages/en.ts
index 403931d542f3..0736f6ec6f07 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -814,6 +814,13 @@ export default {
availableSpend: 'Remaining spending power',
virtualCardNumber: 'Virtual card number',
physicalCardNumber: 'Physical card number',
+ reportFraud: 'Report virtual card fraud',
+ },
+ reportFraudPage: {
+ title: 'Report virtual card fraud',
+ description: 'If your virtual card details have been stolen or compromised, we’ll permanently deactivate your existing card and provide you with a new virtual card and number.',
+ deactivateCard: 'Deactivate card',
+ reportVirtualCardFraud: 'Report virtual card fraud',
},
transferAmountPage: {
transfer: ({amount}: TransferParams) => `Transfer${amount ? ` ${amount}` : ''}`,
diff --git a/src/languages/es.ts b/src/languages/es.ts
index ffe334f4a807..60bd0dcc5653 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -809,6 +809,14 @@ export default {
availableSpend: 'Capacidad de gasto restante',
virtualCardNumber: 'Número de la tarjeta virtual',
physicalCardNumber: 'Número de la tarjeta física',
+ reportFraud: 'Reportar fraude con la tarjeta virtual',
+ },
+ reportFraudPage: {
+ title: 'Reportar fraude con la tarjeta virtual',
+ description:
+ 'Si los datos de tu tarjeta virtual han sido robados o se han visto comprometidos, desactivaremos permanentemente la tarjeta actual y le proporcionaremos una tarjeta virtual y un número nuevo.',
+ deactivateCard: 'Desactivar tarjeta',
+ reportVirtualCardFraud: 'Reportar fraude con la tarjeta virtual',
},
transferAmountPage: {
transfer: ({amount}: TransferParams) => `Transferir${amount ? ` ${amount}` : ''}`,
diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js
index fc284f566c80..98ec7d4a14b3 100644
--- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js
+++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js
@@ -141,6 +141,7 @@ const SettingsModalStackNavigator = createModalStackNavigator({
Settings_Lounge_Access: () => require('../../../pages/settings/Profile/LoungeAccessPage').default,
Settings_Wallet: () => require('../../../pages/settings/Wallet/WalletPage').default,
Settings_Wallet_DomainCards: () => require('../../../pages/settings/Wallet/ExpensifyCardPage').default,
+ Settings_Report_Fraud: () => require('../../../pages/settings/Wallet/ReportFraudPage').default,
Settings_Wallet_Transfer_Balance: () => require('../../../pages/settings/Wallet/TransferBalancePage').default,
Settings_Wallet_Choose_Transfer_Account: () => require('../../../pages/settings/Wallet/ChooseTransferAccountPage').default,
Settings_Wallet_EnablePayments: () => require('../../../pages/EnablePayments/EnablePaymentsPage').default,
diff --git a/src/libs/Navigation/linkingConfig.js b/src/libs/Navigation/linkingConfig.js
index d13f30822bb9..430bbb1fc362 100644
--- a/src/libs/Navigation/linkingConfig.js
+++ b/src/libs/Navigation/linkingConfig.js
@@ -73,6 +73,10 @@ export default {
path: ROUTES.SETTINGS_WALLET_DOMAINCARDS.route,
exact: true,
},
+ Settings_Report_Fraud: {
+ path: ROUTES.SETTINGS_REPORT_FRAUD.route,
+ exact: true,
+ },
Settings_Wallet_EnablePayments: {
path: ROUTES.SETTINGS_ENABLE_PAYMENTS,
exact: true,
diff --git a/src/libs/actions/Card.js b/src/libs/actions/Card.js
new file mode 100644
index 000000000000..cc3021d4260d
--- /dev/null
+++ b/src/libs/actions/Card.js
@@ -0,0 +1,49 @@
+import Onyx from 'react-native-onyx';
+import ONYXKEYS from '../../ONYXKEYS';
+import * as API from '../API';
+
+/**
+ * @param {Number} cardID
+ */
+function reportDigitalExpensifyCardFraud(cardID) {
+ API.write(
+ 'ReportDigitalExpensifyCardFraud',
+ {
+ cardID,
+ },
+ {
+ optimisticData: [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: ONYXKEYS.FORMS.REPORT_FRAUD_FORM,
+ value: {
+ isLoading: true,
+ },
+ },
+ ],
+ successData: [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: ONYXKEYS.FORMS.REPORT_FRAUD_FORM,
+ value: {
+ isLoading: false,
+ },
+ },
+ ],
+ failureData: [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: ONYXKEYS.FORMS.REPORT_FRAUD_FORM,
+ value: {
+ isLoading: false,
+ },
+ },
+ ],
+ },
+ );
+}
+
+export {
+ // eslint-disable-next-line import/prefer-default-export
+ reportDigitalExpensifyCardFraud,
+};
diff --git a/src/pages/settings/Wallet/ExpensifyCardPage.js b/src/pages/settings/Wallet/ExpensifyCardPage.js
index bc49301e8d80..b57d73cce673 100644
--- a/src/pages/settings/Wallet/ExpensifyCardPage.js
+++ b/src/pages/settings/Wallet/ExpensifyCardPage.js
@@ -15,6 +15,7 @@ import useLocalize from '../../../hooks/useLocalize';
import * as CurrencyUtils from '../../../libs/CurrencyUtils';
import Navigation from '../../../libs/Navigation/Navigation';
import styles from '../../../styles/styles';
+import * as Expensicons from '../../../components/Icon/Expensicons';
import * as CardUtils from '../../../libs/CardUtils';
const propTypes = {
@@ -73,20 +74,29 @@ function ExpensifyCardPage({
interactive={false}
titleStyle={styles.newKansasLarge}
/>
- {!_.isEmpty(physicalCard) && (
-
+ {!_.isEmpty(virtualCard) && (
+ <>
+
+ Navigation.navigate(ROUTES.SETTINGS_REPORT_FRAUD.getRoute(domain))}
+ />
+ >
)}
{!_.isEmpty(physicalCard) && (
)}
diff --git a/src/pages/settings/Wallet/ReportFraudPage.js b/src/pages/settings/Wallet/ReportFraudPage.js
new file mode 100644
index 000000000000..c05b0a6472b4
--- /dev/null
+++ b/src/pages/settings/Wallet/ReportFraudPage.js
@@ -0,0 +1,110 @@
+import React, {useEffect} from 'react';
+import _ from 'underscore';
+import PropTypes from 'prop-types';
+import {withOnyx} from 'react-native-onyx';
+import ROUTES from '../../../ROUTES';
+import HeaderWithBackButton from '../../../components/HeaderWithBackButton';
+import ScreenWrapper from '../../../components/ScreenWrapper';
+import Navigation from '../../../libs/Navigation/Navigation';
+import styles from '../../../styles/styles';
+import Text from '../../../components/Text';
+import useLocalize from '../../../hooks/useLocalize';
+import * as Card from '../../../libs/actions/Card';
+import assignedCardPropTypes from './assignedCardPropTypes';
+import * as CardUtils from '../../../libs/CardUtils';
+import ONYXKEYS from '../../../ONYXKEYS';
+import NotFoundPage from '../../ErrorPage/NotFoundPage';
+import Form from '../../../components/Form';
+import usePrevious from '../../../hooks/usePrevious';
+import * as FormActions from '../../../libs/actions/FormActions';
+
+const propTypes = {
+ /* Onyx Props */
+ formData: PropTypes.shape({
+ isLoading: PropTypes.bool,
+ }),
+ cardList: PropTypes.objectOf(assignedCardPropTypes),
+ /** The parameters needed to authenticate with a short-lived token are in the URL */
+ route: PropTypes.shape({
+ /** Each parameter passed via the URL */
+ params: PropTypes.shape({
+ /** Domain string */
+ domain: PropTypes.string,
+ }),
+ }).isRequired,
+};
+
+const defaultProps = {
+ cardList: {},
+ formData: {},
+};
+
+function ReportFraudPage({
+ route: {
+ params: {domain},
+ },
+ cardList,
+ formData,
+}) {
+ const {translate} = useLocalize();
+
+ const domainCards = CardUtils.getDomainCards(cardList)[domain];
+ const virtualCard = _.find(domainCards, (card) => card.isVirtual) || {};
+
+ const prevIsLoading = usePrevious(formData.isLoading);
+
+ useEffect(() => {
+ if (prevIsLoading && formData.isLoading === false && _.isEmpty(virtualCard.errors)) {
+ Navigation.navigate(ROUTES.SETTINGS_WALLET_DOMAINCARDS.getRoute(domain));
+ }
+
+ if (formData.isLoading !== false && _.isEmpty(virtualCard.errors)) {
+ return;
+ }
+
+ FormActions.setErrors(ONYXKEYS.FORMS.REPORT_FRAUD_FORM, virtualCard.errors);
+ }, [domain, formData.isLoading, prevIsLoading, virtualCard.errors]);
+
+ const submitReportFraud = () => {
+ Card.reportDigitalExpensifyCardFraud(virtualCard.cardID);
+ };
+
+ const onBackButtonPress = () => Navigation.goBack(ROUTES.SETTINGS_WALLET_DOMAINCARDS.getRoute(domain));
+
+ if (_.isEmpty(virtualCard)) {
+ return ;
+ }
+
+ return (
+
+
+
+
+ );
+}
+
+ReportFraudPage.propTypes = propTypes;
+ReportFraudPage.defaultProps = defaultProps;
+ReportFraudPage.displayName = 'ReportFraudPage';
+
+export default withOnyx({
+ cardList: {
+ key: ONYXKEYS.CARD_LIST,
+ },
+ formData: {
+ key: ONYXKEYS.FORMS.REPORT_FRAUD_FORM,
+ },
+})(ReportFraudPage);
diff --git a/src/styles/styles.js b/src/styles/styles.js
index 7bba63c8f09f..5360b97233e3 100644
--- a/src/styles/styles.js
+++ b/src/styles/styles.js
@@ -3680,7 +3680,7 @@ const styles = (theme) => ({
overflow: 'hidden',
},
- walletCardNumber: {
+ walletCardMenuItem: {
color: theme.text,
fontSize: variables.fontSizeNormal,
},