Skip to content

Commit

Permalink
Merge pull request Expensify#31067 from lukemorawski/30329-reveal_car…
Browse files Browse the repository at this point in the history
…d_details_error_handling

Reveal card details error handling
  • Loading branch information
grgia authored Nov 13, 2023
2 parents bf2d545 + 7bd2411 commit b867619
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 47 deletions.
1 change: 1 addition & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -886,6 +886,7 @@ export default {
copyCardNumber: 'Copy card number',
updateAddress: 'Update address',
},
cardDetailsLoadingFailure: 'An error occurred while loading the card details. Please check your internet connection and try again.',
},
reportFraudPage: {
title: 'Report virtual card fraud',
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,7 @@ export default {
copyCardNumber: 'Copiar número de la tarjeta',
updateAddress: 'Actualizar dirección',
},
cardDetailsLoadingFailure: 'Se ha producido un error al cargar los datos de la tarjeta. Comprueba tu conexión a Internet e inténtalo de nuevo.',
},
reportFraudPage: {
title: 'Reportar fraude con la tarjeta virtual',
Expand Down
5 changes: 3 additions & 2 deletions src/libs/actions/Card.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Onyx from 'react-native-onyx';
import * as API from '@libs/API';
import * as Localize from '@libs/Localize';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';

Expand Down Expand Up @@ -163,12 +164,12 @@ function revealVirtualCardDetails(cardID) {
API.makeRequestWithSideEffects('RevealExpensifyCardDetails', {cardID})
.then((response) => {
if (response.jsonCode !== CONST.JSON_CODE.SUCCESS) {
reject();
reject(Localize.translateLocal('cardPage.cardDetailsLoadingFailure'));
return;
}
resolve(response);
})
.catch(reject);
.catch(() => reject(Localize.translateLocal('cardPage.cardDetailsLoadingFailure')));
});
}

Expand Down
77 changes: 32 additions & 45 deletions src/pages/settings/Wallet/ExpensifyCardPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ function ExpensifyCardPage({

const [isLoading, setIsLoading] = useState(false);
const [details, setDetails] = useState({});
const [cardDetailsError, setCardDetailsError] = useState('');

if (_.isEmpty(virtualCard) && _.isEmpty(physicalCard)) {
return <NotFoundPage />;
Expand All @@ -70,16 +71,21 @@ function ExpensifyCardPage({
const handleRevealDetails = () => {
setIsLoading(true);
// We can't store the response in Onyx for security reasons.
// That is this action is handled manually and the response is stored in a local state
// Hence the eslint disable here.
// That is why this action is handled manually and the response is stored in a local state
// Hence eslint disable here.
// eslint-disable-next-line rulesdir/no-thenable-actions-in-views
Card.revealVirtualCardDetails(virtualCard.cardID)
.then(setDetails)
.then((value) => {
setDetails(value);
setCardDetailsError('');
})
.catch(setCardDetailsError)
.finally(() => setIsLoading(false));
};

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);
const cardDetailsErrorObject = cardDetailsError ? {error: cardDetailsError} : {};

return (
<ScreenWrapper
Expand Down Expand Up @@ -108,32 +114,6 @@ function ExpensifyCardPage({

{hasDetectedIndividualFraud && !hasDetectedDomainFraud ? (
<>
{details.pan ? (
<CardDetails
pan={details.pan}
expiration={details.expiration}
cvv={details.cvv}
privatePersonalDetails={{address: details.address}}
domain={domain}
/>
) : (
<MenuItemWithTopDescription
description={translate('cardPage.virtualCardNumber')}
title={CardUtils.maskCard(virtualCard.lastFourPAN)}
interactive={false}
titleStyle={styles.walletCardNumber}
shouldShowRightComponent
rightComponent={
<Button
medium
text={translate('cardPage.cardDetails.revealDetails')}
onPress={handleRevealDetails}
isDisabled={isLoading || isOffline}
isLoading={isLoading}
/>
}
/>
)}
<DangerCardSection
title={translate('cardPage.suspiciousBannerTitle')}
description={translate('cardPage.suspiciousBannerDescription')}
Expand Down Expand Up @@ -169,22 +149,29 @@ function ExpensifyCardPage({
domain={domain}
/>
) : (
<MenuItemWithTopDescription
description={translate('cardPage.virtualCardNumber')}
title={CardUtils.maskCard(virtualCard.lastFourPAN)}
interactive={false}
titleStyle={styles.walletCardNumber}
shouldShowRightComponent
rightComponent={
<Button
medium
text={translate('cardPage.cardDetails.revealDetails')}
onPress={handleRevealDetails}
isDisabled={isLoading || isOffline}
isLoading={isLoading}
/>
}
/>
<>
<MenuItemWithTopDescription
description={translate('cardPage.virtualCardNumber')}
title={CardUtils.maskCard(virtualCard.lastFourPAN)}
interactive={false}
titleStyle={styles.walletCardNumber}
shouldShowRightComponent
rightComponent={
<Button
medium
text={translate('cardPage.cardDetails.revealDetails')}
onPress={handleRevealDetails}
isDisabled={isLoading || isOffline}
isLoading={isLoading}
/>
}
/>
<DotIndicatorMessage
messages={cardDetailsErrorObject}
type="error"
style={[styles.ph5]}
/>
</>
)}
<MenuItemWithTopDescription
title={translate('cardPage.reportFraud')}
Expand Down

0 comments on commit b867619

Please sign in to comment.