Skip to content
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

22875 Add API Calls when clicking “Reveal details” buttons #29017

Merged
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
f73d601
first commit
lukemorawski Oct 6, 2023
5985ec1
move to reducer and error handling
lukemorawski Oct 6, 2023
df10ff7
removed unnecessary helper function
lukemorawski Oct 9, 2023
36fb11a
formatting
lukemorawski Oct 9, 2023
bfdb546
var name change to isLoading
lukemorawski Oct 9, 2023
9a8962c
better linting
lukemorawski Oct 9, 2023
c7dd8fa
moved action types to const
lukemorawski Oct 9, 2023
ccf8f4e
action types fix and cardID added to api call
lukemorawski Oct 9, 2023
ef623a4
address refactoring
lukemorawski Oct 10, 2023
f7ba68a
refactoring
lukemorawski Oct 11, 2023
9f173af
Merge branch 'main' into 22875-api_call_on_reveal_card_details
lukemorawski Oct 11, 2023
8361350
removed comment
lukemorawski Oct 12, 2023
36a6d4e
revealCardDetails move
lukemorawski Oct 13, 2023
28ca868
Merge branch 'main' into 22875-api_call_on_reveal_card_details
lukemorawski Oct 17, 2023
a7bcbb6
added offline disabling
lukemorawski Oct 17, 2023
f1aad79
Merge branch 'main' into 22875-api_call_on_reveal_card_details
lukemorawski Oct 17, 2023
42cb473
reject with generic error message
lukemorawski Oct 18, 2023
6dac4ca
Merge branch 'main' into 22875-api_call_on_reveal_card_details
lukemorawski Oct 19, 2023
dcb188b
Update src/libs/actions/Card.js
lukemorawski Oct 20, 2023
8254860
linting
lukemorawski Oct 20, 2023
586f20e
Merge branch 'main' into 22875-api_call_on_reveal_card_details
lukemorawski Oct 23, 2023
aaa7042
merging with latest changes
lukemorawski Oct 23, 2023
95d4a43
Update src/languages/en.ts
lukemorawski Oct 24, 2023
934344a
removed error handling
lukemorawski Oct 25, 2023
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
35 changes: 27 additions & 8 deletions src/pages/settings/Wallet/ExpensifyCardPage.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import PropTypes from 'prop-types';
import React, {useState} from 'react';
import React, {useReducer} from 'react';
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we should start with useReducer. We have avoided it until now and it looks like the incorrect pattern for what we are trying to achieve here.

import {ScrollView, View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import _ from 'underscore';
Expand All @@ -18,6 +18,10 @@ import styles from '../../../styles/styles';
import * as CardUtils from '../../../libs/CardUtils';
import Button from '../../../components/Button';
import CardDetails from './WalletPage/CardDetails';
// eslint-disable-next-line rulesdir/no-api-in-views
import * as API from '../../../libs/API';
Copy link
Contributor

Choose a reason for hiding this comment

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

This is here for a reason. If you want to call an API you need to create an "action" in the Card.js file

import CONST from '../../../CONST';
import * as revealCardDetailsUtils from './revealCardDetailsUtils';

const propTypes = {
/* Onyx Props */
Expand Down Expand Up @@ -47,7 +51,7 @@ function ExpensifyCardPage({
const virtualCard = _.find(domainCards, (card) => card.isVirtual) || {};
const physicalCard = _.find(domainCards, (card) => !card.isVirtual) || {};

const [shouldShowCardDetails, setShouldShowCardDetails] = useState(false);
const [{isLoading, details, error}, dispatch] = useReducer(revealCardDetailsUtils.reducer, revealCardDetailsUtils.initialState);

if (_.isEmpty(virtualCard) && _.isEmpty(physicalCard)) {
return <NotFoundPage />;
Expand All @@ -56,7 +60,19 @@ function ExpensifyCardPage({
const formattedAvailableSpendAmount = CurrencyUtils.convertToDisplayString(physicalCard.availableSpend || virtualCard.availableSpend || 0);

const handleRevealDetails = () => {
setShouldShowCardDetails(true);
dispatch({type: revealCardDetailsUtils.ACTION_TYPES.start});
// eslint-disable-next-line rulesdir/no-api-in-views,rulesdir/no-api-side-effects-method
API.makeRequestWithSideEffects('RevealVirtualCardDetails', {cardID: virtualCard.cardID})
.then((response) => {
if (response.jsonCode !== CONST.JSON_CODE.SUCCESS) {
dispatch({type: revealCardDetailsUtils.ACTION_TYPES.FAIL, payload: response.message});
return;
}
dispatch({type: revealCardDetailsUtils.ACTION_TYPES.SUCCESS, payload: response});
})
.catch((err) => {
dispatch({type: revealCardDetailsUtils.ACTION_TYPES.FAIL, payload: err.message});
});
};

return (
Expand All @@ -83,12 +99,12 @@ function ExpensifyCardPage({
/>
{!_.isEmpty(virtualCard) && (
<>
{shouldShowCardDetails ? (
{details.pan ? (
<CardDetails
// This is just a temporary mock, it will be replaced in this issue https://github.com/orgs/Expensify/projects/58?pane=issue&itemId=33286617
pan="1234123412341234"
expiration="11/02/2024"
cvv="321"
pan={details.pan}
expiration={details.expiration}
cvv={details.cvv}
privatePersonalDetails={{address: details.address}}
/>
) : (
<MenuItemWithTopDescription
Expand All @@ -97,11 +113,14 @@ function ExpensifyCardPage({
interactive={false}
titleStyle={styles.walletCardNumber}
shouldShowRightComponent
error={error}
rightComponent={
<Button
medium
text={translate('cardPage.cardDetails.revealDetails')}
onPress={handleRevealDetails}
isDisabled={isLoading}
isLoading={isLoading}
/>
}
/>
Expand Down
59 changes: 59 additions & 0 deletions src/pages/settings/Wallet/revealCardDetailsUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
const ACTION_TYPES = {
START: 'START',
SUCCESS: 'SUCCESS',
FAIL: 'FAIL',
} as const;

type State = {
details: {
pan: string;
expiration: string;
cvv: string;
address: {
street: string;
street2: string;
city: string;
state: string;
zip: string;
country: string;
};
};
isLoading: boolean;
error: string;
};

type Action = {type: typeof ACTION_TYPES.START} | {type: typeof ACTION_TYPES.SUCCESS; payload: State['details']} | {type: typeof ACTION_TYPES.FAIL; payload: string};

const initialState: State = {
details: {
pan: '',
expiration: '',
cvv: '',
address: {
street: '',
street2: '',
city: '',
state: '',
zip: '',
country: '',
},
},
isLoading: false,
error: '',
};

const reducer = (state: State, action: Action): State => {
switch (action.type) {
case ACTION_TYPES.START:
return {...state, isLoading: true};
case ACTION_TYPES.SUCCESS:
return {details: action.payload, isLoading: false, error: ''};
case ACTION_TYPES.FAIL: {
return {...state, error: action.payload, isLoading: false};
}
default:
return state;
}
};

export {initialState, reducer, ACTION_TYPES};
Loading