From 156a96610615de459cdb2b7495ddacac796987c2 Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Tue, 17 Oct 2023 16:36:09 +0200 Subject: [PATCH 01/11] Update UI to show fraud states --- .../simple-illustration__smartscan.svg | 21 +++ src/components/DotIndicatorMessage.js | 7 +- src/components/Icon/Illustrations.js | 2 + src/languages/en.ts | 4 + src/languages/es.ts | 4 + .../settings/Wallet/DangerCardSection.js | 32 +++++ .../settings/Wallet/ExpensifyCardPage.js | 122 ++++++++++++------ src/styles/styles.ts | 30 +++++ src/styles/themes/default.ts | 1 + src/styles/themes/light.ts | 1 + src/styles/utilities/sizing.ts | 4 + src/styles/utilities/spacing.ts | 8 ++ 12 files changed, 193 insertions(+), 43 deletions(-) create mode 100644 assets/images/product-illustrations/simple-illustration__smartscan.svg create mode 100644 src/pages/settings/Wallet/DangerCardSection.js diff --git a/assets/images/product-illustrations/simple-illustration__smartscan.svg b/assets/images/product-illustrations/simple-illustration__smartscan.svg new file mode 100644 index 000000000000..34d1fadfaa3b --- /dev/null +++ b/assets/images/product-illustrations/simple-illustration__smartscan.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/DotIndicatorMessage.js b/src/components/DotIndicatorMessage.js index b3528b43dc75..89cfe2dc315a 100644 --- a/src/components/DotIndicatorMessage.js +++ b/src/components/DotIndicatorMessage.js @@ -25,11 +25,16 @@ const propTypes = { // Additional styles to apply to the container */ // eslint-disable-next-line react/forbid-prop-types style: PropTypes.arrayOf(PropTypes.object), + + // Additional styles to apply to the text + // eslint-disable-next-line react/forbid-prop-types + textStyle: PropTypes.arrayOf(PropTypes.object), }; const defaultProps = { messages: {}, style: [], + textStyle: [], }; function DotIndicatorMessage(props) { @@ -64,7 +69,7 @@ function DotIndicatorMessage(props) { {_.map(sortedMessages, (message, i) => ( {message} diff --git a/src/components/Icon/Illustrations.js b/src/components/Icon/Illustrations.js index 0e39872a3da6..c9a86cf8f10c 100644 --- a/src/components/Icon/Illustrations.js +++ b/src/components/Icon/Illustrations.js @@ -46,6 +46,7 @@ import TreasureChest from '../../../assets/images/simple-illustrations/simple-il import ThumbsUpStars from '../../../assets/images/simple-illustrations/simple-illustration__thumbsupstars.svg'; import Hands from '../../../assets/images/product-illustrations/home-illustration-hands.svg'; import HandEarth from '../../../assets/images/simple-illustrations/simple-illustration__handearth.svg'; +import SmartScan from '../../../assets/images/product-illustrations/simple-illustration__smartscan.svg'; export { Abracadabra, @@ -96,4 +97,5 @@ export { ThumbsUpStars, Hands, HandEarth, + SmartScan, }; diff --git a/src/languages/en.ts b/src/languages/en.ts index e7f71e755dd8..017579a6b40d 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -870,6 +870,10 @@ export default { virtualCardNumber: 'Virtual card number', physicalCardNumber: 'Physical card number', reportFraud: 'Report virtual card fraud', + reviewTransaction: 'Review transaction', + suspiciousBannerTitle: 'Suspicious transaction', + suspiciousBannerDescription: 'We noticed suspicious transaction on your card. Tap below to review.', + cardLocked: "Your card is temporarily locked while our team reviews your company's account.", cardDetails: { cardNumber: 'Virtual card number', expiration: 'Expiration', diff --git a/src/languages/es.ts b/src/languages/es.ts index 6020ded30b92..1dc1126164fb 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -866,6 +866,10 @@ export default { virtualCardNumber: 'Número de la tarjeta virtual', physicalCardNumber: 'Número de la tarjeta física', reportFraud: 'Reportar fraude con la tarjeta virtual', + reviewTransaction: 'Revisar transacción', + suspiciousBannerTitle: 'Transacción sospechosa', + suspiciousBannerDescription: 'Hemos detectado una transacción sospechosa en la tarjeta. Haga click abajo para revisarla.', + cardLocked: "Your card is temporarily locked while our team reviews your company's account.", cardDetails: { cardNumber: 'Número de tarjeta virtual', expiration: 'Expiración', diff --git a/src/pages/settings/Wallet/DangerCardSection.js b/src/pages/settings/Wallet/DangerCardSection.js new file mode 100644 index 000000000000..95dc1fc7c0f1 --- /dev/null +++ b/src/pages/settings/Wallet/DangerCardSection.js @@ -0,0 +1,32 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { View} from 'react-native'; +import styles from '../../../styles/styles'; +import * as Illustrations from '../../../components/Icon/Illustrations'; +import Text from '../../../components/Text'; + +const propTypes = { + title: PropTypes.string.isRequired, + description: PropTypes.string.isRequired, +}; + +function DangerCardSection({title, description}) { + return ( + + + + {title} + {description} + + + + + + + ); +} + +DangerCardSection.propTypes = propTypes; +DangerCardSection.displayName = 'DangerCardSection'; + +export default DangerCardSection; diff --git a/src/pages/settings/Wallet/ExpensifyCardPage.js b/src/pages/settings/Wallet/ExpensifyCardPage.js index c9ee7ece8fa9..fba6613695b3 100644 --- a/src/pages/settings/Wallet/ExpensifyCardPage.js +++ b/src/pages/settings/Wallet/ExpensifyCardPage.js @@ -20,6 +20,10 @@ import Button from '../../../components/Button'; import CardDetails from './WalletPage/CardDetails'; import CONST from '../../../CONST'; import assignedCardPropTypes from './assignedCardPropTypes'; +import theme from '../../../styles/themes/default'; +import DotIndicatorMessage from '../../../components/DotIndicatorMessage'; +import * as Link from '../../../libs/actions/Link'; +import DangerCardSection from './DangerCardSection'; const propTypes = { /* Onyx Props */ @@ -62,6 +66,9 @@ function ExpensifyCardPage({ setShouldShowCardDetails(true); }; + const detectedDomainFraud = _.some(domainCards, (card) => card.fraud === CONST.EXPENSIFY_CARD.FRAUD_TYPES.DOMAIN); + const detectedIndividualFraud = _.some(domainCards, (card) => card.fraud === CONST.EXPENSIFY_CARD.FRAUD_TYPES.INDIVIDUAL); + return ( Navigation.goBack(ROUTES.SETTINGS_WALLET)} /> - + - - {!_.isEmpty(virtualCard) && ( + {detectedDomainFraud && ( + + )} + + {detectedIndividualFraud && ( <> - {shouldShowCardDetails ? ( - - ) : ( - - } - /> - )} + Navigation.navigate(ROUTES.SETTINGS_REPORT_FRAUD.getRoute(domain))} + brickRoadIndicator='error' + onPress={() => Link.openOldDotLink('inbox')} /> )} - {!_.isEmpty(physicalCard) && ( - + + {!detectedDomainFraud && ( + <> + + {!_.isEmpty(virtualCard) && ( + <> + {shouldShowCardDetails ? ( + + ) : ( + + } + /> + )} + Navigation.navigate(ROUTES.SETTINGS_REPORT_FRAUD.getRoute(domain))} + /> + + )} + {!_.isEmpty(physicalCard) && ( + + )} + )} {physicalCard.state === CONST.EXPENSIFY_CARD.STATE.NOT_ACTIVATED && ( diff --git a/src/styles/styles.ts b/src/styles/styles.ts index 67c1e1cb9589..b99afbe75463 100644 --- a/src/styles/styles.ts +++ b/src/styles/styles.ts @@ -3925,8 +3925,11 @@ const styles = (theme: ThemeDefault) => }, walletCardMenuItem: { + fontFamily: fontFamily.EXP_NEUE_BOLD, + fontWeight: fontWeightBold, color: theme.text, fontSize: variables.fontSizeNormal, + lineHeight: variables.lineHeightXLarge, }, walletCardHolder: { @@ -3946,6 +3949,33 @@ const styles = (theme: ThemeDefault) => paddingBottom: 0, }, + walletDangerSection: { + backgroundColor: theme.dangerSection, + color: theme.dangerSection, + borderRadius: variables.componentBorderRadiusCard, + width: 'auto', + marginHorizontal: 20, + marginBottom: 6, + }, + + walletDangerSectionTitle: { + fontSize: variables.fontSizeNormal, + fontFamily: fontFamily.EXP_NEUE_BOLD, + fontWeight: fontWeightBold, + lineHeight: variables.lineHeightXLarge, + }, + + walletDangerSectionText: { + fontSize: variables.fontSizeLabel, + lineHeight: variables.lineHeightNormal, + }, + + walletLockedMessage: { + color: theme.text, + fontSize: variables.fontSizeNormal, + lineHeight: variables.lineHeightXLarge, + }, + aspectRatioLottie: (source) => { if (!source.uri && typeof source === 'object' && source.w && source.h) { return {aspectRatio: source.w / source.h}; diff --git a/src/styles/themes/default.ts b/src/styles/themes/default.ts index aabe9140bf9d..c8a44bb3bbaf 100644 --- a/src/styles/themes/default.ts +++ b/src/styles/themes/default.ts @@ -33,6 +33,7 @@ const darkTheme = { successPressed: colors.greenPressed, transparent: colors.transparent, signInPage: colors.green800, + dangerSection: colors.tangerine800, // Additional keys overlay: colors.darkBorders, diff --git a/src/styles/themes/light.ts b/src/styles/themes/light.ts index cd3079c3313f..214975cd0902 100644 --- a/src/styles/themes/light.ts +++ b/src/styles/themes/light.ts @@ -33,6 +33,7 @@ const lightTheme = { successPressed: colors.greenPressed, transparent: colors.transparent, signInPage: colors.green800, + dangerSection: colors.tangerine800, // Additional keys overlay: colors.lightBorders, diff --git a/src/styles/utilities/sizing.ts b/src/styles/utilities/sizing.ts index 94d7c5c56f22..e68500beaf99 100644 --- a/src/styles/utilities/sizing.ts +++ b/src/styles/utilities/sizing.ts @@ -46,6 +46,10 @@ export default { width: '70%', }, + w80: { + width: '80%', + }, + w100: { width: '100%', }, diff --git a/src/styles/utilities/spacing.ts b/src/styles/utilities/spacing.ts index e2b161ca0d62..c66b7cbd5250 100644 --- a/src/styles/utilities/spacing.ts +++ b/src/styles/utilities/spacing.ts @@ -207,6 +207,10 @@ export default { marginTop: 32, }, + mt9: { + marginTop: 36, + }, + mt11: { marginTop: 44, }, @@ -255,6 +259,10 @@ export default { marginBottom: 32, }, + mb9: { + marginBottom: 36, + }, + mb10: { marginBottom: 40, }, From 06a9d0d44e8cb532ea21ec5f72314f73f3486e98 Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Tue, 17 Oct 2023 17:10:29 +0200 Subject: [PATCH 02/11] fix typo for fraud types --- src/CONST.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CONST.ts b/src/CONST.ts index e2f3fea08215..f4aeb9ccb5ea 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -1236,7 +1236,7 @@ const CONST = { BANK: 'Expensify Card', FRAUD_TYPES: { DOMAIN: 'domain', - INDIVIDUAL: 'individal', + INDIVIDUAL: 'individual', NONE: 'none', }, STATE: { From 5fec0821e4825cfe9b15a1daf42546bf74512308 Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Tue, 17 Oct 2023 17:13:02 +0200 Subject: [PATCH 03/11] add error indicator for assigned cards --- src/pages/settings/Wallet/PaymentMethodList.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pages/settings/Wallet/PaymentMethodList.js b/src/pages/settings/Wallet/PaymentMethodList.js index 2a533a784a62..eadc7dadeff5 100644 --- a/src/pages/settings/Wallet/PaymentMethodList.js +++ b/src/pages/settings/Wallet/PaymentMethodList.js @@ -217,6 +217,7 @@ function PaymentMethodList({ interactive: isExpensifyCard, canDismissError: isExpensifyCard, errors: card.errors, + brickRoadIndicator: (card.fraud === CONST.EXPENSIFY_CARD.FRAUD_TYPES.DOMAIN || card.fraud === CONST.EXPENSIFY_CARD.FRAUD_TYPES.INDIVIDUAL) ? 'error' : null, ...icon, }; }); @@ -301,6 +302,7 @@ function PaymentMethodList({ shouldShowSelectedState={shouldShowSelectedState} isSelected={selectedMethodID === item.methodID} interactive={item.interactive} + brickRoadIndicator={item.brickRoadIndicator} /> ), From ce7204a1ecc5d3b6f524fa6146dfe4138bd275e9 Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Wed, 18 Oct 2023 14:05:39 +0200 Subject: [PATCH 04/11] fix domain card navigation to the card page --- src/pages/settings/Wallet/PaymentMethodList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/settings/Wallet/PaymentMethodList.js b/src/pages/settings/Wallet/PaymentMethodList.js index eadc7dadeff5..a22da731100e 100644 --- a/src/pages/settings/Wallet/PaymentMethodList.js +++ b/src/pages/settings/Wallet/PaymentMethodList.js @@ -212,7 +212,7 @@ function PaymentMethodList({ key: card.cardID, title: isExpensifyCard ? translate('walletPage.expensifyCard') : card.cardName, description: card.domainName, - onPress: isExpensifyCard ? () => Navigation.navigate(ROUTES.SETTINGS_WALLET_DOMAINCARDS.getRoute(card.domainName)) : () => {}, + onPress: isExpensifyCard ? () => Navigation.navigate(ROUTES.SETTINGS_WALLET_DOMAINCARD.getRoute(card.domainName)) : () => {}, shouldShowRightIcon: isExpensifyCard, interactive: isExpensifyCard, canDismissError: isExpensifyCard, From 6045346bc1463b2116d4fff0a56591eb8c28a722 Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Wed, 18 Oct 2023 15:01:22 +0200 Subject: [PATCH 05/11] fix detectedDomainFraud statement --- src/pages/settings/Wallet/ExpensifyCardPage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/settings/Wallet/ExpensifyCardPage.js b/src/pages/settings/Wallet/ExpensifyCardPage.js index fba6613695b3..7e6dc1ac688d 100644 --- a/src/pages/settings/Wallet/ExpensifyCardPage.js +++ b/src/pages/settings/Wallet/ExpensifyCardPage.js @@ -94,7 +94,7 @@ function ExpensifyCardPage({ /> )} - {detectedIndividualFraud && ( + {detectedIndividualFraud && !detectedDomainFraud && ( <> Date: Wed, 18 Oct 2023 15:04:05 +0200 Subject: [PATCH 06/11] apply prettier --- src/pages/settings/Wallet/DangerCardSection.js | 2 +- src/pages/settings/Wallet/ExpensifyCardPage.js | 2 +- src/pages/settings/Wallet/PaymentMethodList.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/settings/Wallet/DangerCardSection.js b/src/pages/settings/Wallet/DangerCardSection.js index 95dc1fc7c0f1..bd67ba03c43b 100644 --- a/src/pages/settings/Wallet/DangerCardSection.js +++ b/src/pages/settings/Wallet/DangerCardSection.js @@ -1,6 +1,6 @@ import PropTypes from 'prop-types'; import React from 'react'; -import { View} from 'react-native'; +import {View} from 'react-native'; import styles from '../../../styles/styles'; import * as Illustrations from '../../../components/Icon/Illustrations'; import Text from '../../../components/Text'; diff --git a/src/pages/settings/Wallet/ExpensifyCardPage.js b/src/pages/settings/Wallet/ExpensifyCardPage.js index 7e6dc1ac688d..bf99b2fde2c7 100644 --- a/src/pages/settings/Wallet/ExpensifyCardPage.js +++ b/src/pages/settings/Wallet/ExpensifyCardPage.js @@ -106,7 +106,7 @@ function ExpensifyCardPage({ icon={Expensicons.MagnifyingGlass} iconFill={theme.icon} shouldShowRightIcon - brickRoadIndicator='error' + brickRoadIndicator="error" onPress={() => Link.openOldDotLink('inbox')} /> diff --git a/src/pages/settings/Wallet/PaymentMethodList.js b/src/pages/settings/Wallet/PaymentMethodList.js index a22da731100e..cc2c87e80caf 100644 --- a/src/pages/settings/Wallet/PaymentMethodList.js +++ b/src/pages/settings/Wallet/PaymentMethodList.js @@ -217,7 +217,7 @@ function PaymentMethodList({ interactive: isExpensifyCard, canDismissError: isExpensifyCard, errors: card.errors, - brickRoadIndicator: (card.fraud === CONST.EXPENSIFY_CARD.FRAUD_TYPES.DOMAIN || card.fraud === CONST.EXPENSIFY_CARD.FRAUD_TYPES.INDIVIDUAL) ? 'error' : null, + brickRoadIndicator: card.fraud === CONST.EXPENSIFY_CARD.FRAUD_TYPES.DOMAIN || card.fraud === CONST.EXPENSIFY_CARD.FRAUD_TYPES.INDIVIDUAL ? 'error' : null, ...icon, }; }); From 77c0194b8d853adb27bc36a5ccee88d25c85c29a Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Wed, 18 Oct 2023 15:50:00 +0200 Subject: [PATCH 07/11] fix translation --- src/languages/es.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/es.ts b/src/languages/es.ts index 1dc1126164fb..6f8f35236b0b 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -869,7 +869,7 @@ export default { reviewTransaction: 'Revisar transacción', suspiciousBannerTitle: 'Transacción sospechosa', suspiciousBannerDescription: 'Hemos detectado una transacción sospechosa en la tarjeta. Haga click abajo para revisarla.', - cardLocked: "Your card is temporarily locked while our team reviews your company's account.", + cardLocked: 'La tarjeta está temporalmente bloqueada mientras nuestro equipo revisa la cuenta de tu empresa.', cardDetails: { cardNumber: 'Número de tarjeta virtual', expiration: 'Expiración', From 2fcb4f6b88013062b581a75b8b8e40a7442570db Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Wed, 18 Oct 2023 15:53:06 +0200 Subject: [PATCH 08/11] fix boolean namings --- src/pages/settings/Wallet/ExpensifyCardPage.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pages/settings/Wallet/ExpensifyCardPage.js b/src/pages/settings/Wallet/ExpensifyCardPage.js index bf99b2fde2c7..62b31df8490a 100644 --- a/src/pages/settings/Wallet/ExpensifyCardPage.js +++ b/src/pages/settings/Wallet/ExpensifyCardPage.js @@ -66,8 +66,8 @@ function ExpensifyCardPage({ setShouldShowCardDetails(true); }; - const detectedDomainFraud = _.some(domainCards, (card) => card.fraud === CONST.EXPENSIFY_CARD.FRAUD_TYPES.DOMAIN); - const detectedIndividualFraud = _.some(domainCards, (card) => card.fraud === CONST.EXPENSIFY_CARD.FRAUD_TYPES.INDIVIDUAL); + const isDetectedDomainFraud = _.some(domainCards, (card) => card.fraud === CONST.EXPENSIFY_CARD.FRAUD_TYPES.DOMAIN); + const isDetectedIndividualFraud = _.some(domainCards, (card) => card.fraud === CONST.EXPENSIFY_CARD.FRAUD_TYPES.INDIVIDUAL); return ( - {detectedDomainFraud && ( + {isDetectedDomainFraud && ( )} - {detectedIndividualFraud && !detectedDomainFraud && ( + {isDetectedIndividualFraud && !isDetectedDomainFraud && ( <> )} - {!detectedDomainFraud && ( + {!isDetectedDomainFraud && ( <> Date: Thu, 19 Oct 2023 19:48:19 +0200 Subject: [PATCH 09/11] apply comments --- src/components/DotIndicatorMessage.js | 7 ++++--- src/pages/settings/Wallet/ExpensifyCardPage.js | 16 ++++++++-------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/components/DotIndicatorMessage.js b/src/components/DotIndicatorMessage.js index 89cfe2dc315a..00b97f4ee295 100644 --- a/src/components/DotIndicatorMessage.js +++ b/src/components/DotIndicatorMessage.js @@ -3,6 +3,7 @@ import _ from 'underscore'; import PropTypes from 'prop-types'; import {View} from 'react-native'; import styles from '../styles/styles'; +import stylePropTypes from '../styles/stylePropTypes'; import Icon from './Icon'; import * as Expensicons from './Icon/Expensicons'; import themeColors from '../styles/themes/default'; @@ -28,13 +29,13 @@ const propTypes = { // Additional styles to apply to the text // eslint-disable-next-line react/forbid-prop-types - textStyle: PropTypes.arrayOf(PropTypes.object), + textStyles: stylePropTypes, }; const defaultProps = { messages: {}, style: [], - textStyle: [], + textStyles: [], }; function DotIndicatorMessage(props) { @@ -69,7 +70,7 @@ function DotIndicatorMessage(props) { {_.map(sortedMessages, (message, i) => ( {message} diff --git a/src/pages/settings/Wallet/ExpensifyCardPage.js b/src/pages/settings/Wallet/ExpensifyCardPage.js index eb54aa872107..8f15339289eb 100644 --- a/src/pages/settings/Wallet/ExpensifyCardPage.js +++ b/src/pages/settings/Wallet/ExpensifyCardPage.js @@ -67,8 +67,8 @@ function ExpensifyCardPage({ setShouldShowCardDetails(true); }; - const isDetectedDomainFraud = _.some(domainCards, (card) => card.fraud === CONST.EXPENSIFY_CARD.FRAUD_TYPES.DOMAIN); - const isDetectedIndividualFraud = _.some(domainCards, (card) => card.fraud === CONST.EXPENSIFY_CARD.FRAUD_TYPES.INDIVIDUAL); + const hasDetectedDomainFraud = _.some(domainCards, (card) => card.fraud === CONST.EXPENSIFY_CARD.FRAUD_TYPES.DOMAIN); + const hasDetectedIndividualFraud = _.some(domainCards, (card) => card.fraud === CONST.EXPENSIFY_CARD.FRAUD_TYPES.INDIVIDUAL); return ( - {isDetectedDomainFraud && ( + {hasDetectedDomainFraud ? ( - )} + ) : null} - {isDetectedIndividualFraud && !isDetectedDomainFraud && ( + {hasDetectedIndividualFraud && !hasDetectedDomainFraud ? ( <> Link.openOldDotLink('inbox')} /> - )} + ) : null} - {!isDetectedDomainFraud && ( + {!hasDetectedDomainFraud ? ( <> )} - )} + ) : null} {physicalCard.state === CONST.EXPENSIFY_CARD.STATE.NOT_ACTIVATED && (