-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add “Report virtual card fraud” page and route #28312
Changes from 10 commits
0274f11
46ecfe1
c6f6791
716775c
a40ddf6
48528c9
963509f
4b1e552
1ccd7de
852628c
f6a4166
fd13bba
04ede94
00666f5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import Onyx from 'react-native-onyx'; | ||
import ONYXKEYS from '../../ONYXKEYS'; | ||
import * as API from '../API'; | ||
|
||
/** | ||
* @param {Number} cardID | ||
*/ | ||
function reportVirtualExpensifyCardFraud(cardID) { | ||
API.write( | ||
'ReportVirtualExpensifyCardFraud', | ||
{ | ||
cardID, | ||
}, | ||
{ | ||
optimisticData: [ | ||
{ | ||
onyxMethod: Onyx.METHOD.MERGE, | ||
key: ONYXKEYS.FORMS.REPORT_VIRTUAL_CARD_FRAUD, | ||
value: { | ||
isLoading: true, | ||
}, | ||
}, | ||
], | ||
successData: [ | ||
{ | ||
onyxMethod: Onyx.METHOD.MERGE, | ||
key: ONYXKEYS.FORMS.REPORT_VIRTUAL_CARD_FRAUD, | ||
value: { | ||
isLoading: false, | ||
}, | ||
}, | ||
], | ||
failureData: [ | ||
{ | ||
onyxMethod: Onyx.METHOD.MERGE, | ||
key: ONYXKEYS.FORMS.REPORT_VIRTUAL_CARD_FRAUD, | ||
value: { | ||
isLoading: false, | ||
}, | ||
}, | ||
], | ||
}, | ||
); | ||
} | ||
|
||
export { | ||
// eslint-disable-next-line import/prefer-default-export | ||
reportVirtualExpensifyCardFraud, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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'; | ||
import Button from '../../../components/Button'; | ||
import CardDetails from './WalletPage/CardDetails'; | ||
|
@@ -96,6 +97,7 @@ function ExpensifyCardPage({ | |
title={CardUtils.maskCard(virtualCard.lastFourPAN)} | ||
interactive={false} | ||
titleStyle={styles.walletCardNumber} | ||
// titleStyle={styles.walletCardMenuItem} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ^ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My bad, removed |
||
shouldShowRightComponent | ||
rightComponent={ | ||
<Button | ||
|
@@ -106,14 +108,21 @@ function ExpensifyCardPage({ | |
} | ||
/> | ||
)} | ||
<MenuItemWithTopDescription | ||
title={translate('cardPage.reportFraud')} | ||
titleStyle={styles.walletCardMenuItem} | ||
icon={Expensicons.Flag} | ||
shouldShowRightIcon | ||
onPress={() => Navigation.navigate(ROUTES.SETTINGS_REPORT_FRAUD.getRoute(domain))} | ||
/> | ||
</> | ||
)} | ||
{!_.isEmpty(physicalCard) && ( | ||
<MenuItemWithTopDescription | ||
description={translate('cardPage.physicalCardNumber')} | ||
title={CardUtils.maskCard(physicalCard.lastFourPAN)} | ||
interactive={false} | ||
titleStyle={styles.walletCardNumber} | ||
titleStyle={styles.walletCardMenuItem} | ||
/> | ||
)} | ||
</ScrollView> | ||
|
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -0,0 +1,103 @@ | ||||
import React, {useEffect} from 'react'; | ||||
import _ from 'underscore'; | ||||
import {View} from 'react-native'; | ||||
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 usePrevious from '../../../hooks/usePrevious'; | ||||
import FormAlertWithSubmitButton from '../../../components/FormAlertWithSubmitButton'; | ||||
import * as ErrorUtils from '../../../libs/ErrorUtils'; | ||||
|
||||
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({ | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we rename this and the filename to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done! |
||||
route: { | ||||
params: {domain}, | ||||
}, | ||||
cardList, | ||||
formData, | ||||
}) { | ||||
const {translate} = useLocalize(); | ||||
|
||||
const domainCards = CardUtils.getDomainCards(cardList)[domain]; | ||||
const virtualCard = _.find(domainCards, (card) => card.isVirtual) || {}; | ||||
const virtualCardError = ErrorUtils.getLatestErrorMessage(virtualCard) || ''; | ||||
|
||||
const prevIsLoading = usePrevious(formData.isLoading); | ||||
|
||||
// eslint-disable-next-line rulesdir/prefer-early-return | ||||
useEffect(() => { | ||||
if (prevIsLoading && formData.isLoading === false && _.isEmpty(virtualCard.errors)) { | ||||
Navigation.navigate(ROUTES.SETTINGS_WALLET_DOMAINCARDS.getRoute(domain)); | ||||
} | ||||
}, [domain, formData, prevIsLoading, virtualCard.errors]); | ||||
|
||||
if (_.isEmpty(virtualCard)) { | ||||
return <NotFoundPage />; | ||||
} | ||||
|
||||
return ( | ||||
<ScreenWrapper | ||||
includeSafeAreaPaddingBottom | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
NAB. includeSafeAreaPaddingBottom defaults to true There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||||
testID={ReportFraudPage.displayName} | ||||
> | ||||
<HeaderWithBackButton | ||||
title={translate('reportFraudPage.title')} | ||||
onBackButtonPress={() => Navigation.goBack(ROUTES.SETTINGS_WALLET_DOMAINCARDS.getRoute(domain))} | ||||
/> | ||||
<View style={[styles.flex1, styles.justifyContentBetween]}> | ||||
<Text style={[styles.baseFontStyle, styles.mh5]}>{translate('reportFraudPage.description')}</Text> | ||||
<FormAlertWithSubmitButton | ||||
isAlertVisible={Boolean(virtualCardError)} | ||||
onSubmit={() => Card.reportVirtualExpensifyCardFraud(virtualCard.cardID)} | ||||
message={virtualCardError} | ||||
isLoading={formData.isLoading} | ||||
buttonText={translate('reportFraudPage.deactivateCard')} | ||||
/> | ||||
</View> | ||||
</ScreenWrapper> | ||||
); | ||||
} | ||||
|
||||
ReportFraudPage.propTypes = propTypes; | ||||
ReportFraudPage.defaultProps = defaultProps; | ||||
ReportFraudPage.displayName = 'ReportFraudPage'; | ||||
|
||||
export default withOnyx({ | ||||
cardList: { | ||||
key: ONYXKEYS.CARD_LIST, | ||||
}, | ||||
formData: { | ||||
key: ONYXKEYS.FORMS.REPORT_VIRTUAL_CARD_FRAUD, | ||||
}, | ||||
})(ReportFraudPage); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for consistency
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated!