Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
465db11
new: Transfer balance page added
parasharrajat Jul 17, 2021
a094ac4
WIP transfer amount page
parasharrajat Jul 19, 2021
6b5e413
resolve conflict and Merged latest code
parasharrajat Jul 22, 2021
4caaeeb
added Choose account page
parasharrajat Jul 22, 2021
6312af1
navigation setup
parasharrajat Jul 22, 2021
981faee
transfer page Finalized
parasharrajat Jul 22, 2021
46739f1
Pulled latest changes
parasharrajat Aug 7, 2021
360808e
Merge branch 'main' of github.com:Expensify/Expensify.cash into trans…
parasharrajat Aug 9, 2021
1022e5e
Pull latest changes
parasharrajat Aug 13, 2021
ebef54c
completed thee transfer balance flow
parasharrajat Aug 13, 2021
596835c
added localization
parasharrajat Aug 13, 2021
389ddaf
selection feature to PaymentMethodList
parasharrajat Aug 13, 2021
62f8bbf
missing translations
parasharrajat Aug 13, 2021
38052af
typos
parasharrajat Aug 14, 2021
10b4d1b
Pull new changes
parasharrajat Aug 14, 2021
f3f9973
Merge branch 'main' of github.com:Expensify/Expensify.cash into trans…
parasharrajat Sep 10, 2021
8f7f20a
updates
parasharrajat Sep 10, 2021
c593bae
updates
parasharrajat Sep 10, 2021
c0bfe28
pull new changes
parasharrajat Sep 13, 2021
e9e303d
fix prop
parasharrajat Sep 14, 2021
88d1b66
link API call
parasharrajat Sep 14, 2021
a96ef09
refactor
parasharrajat Sep 14, 2021
8551692
Pull latest changes
parasharrajat Nov 4, 2021
7c66493
patch logic to run the app
parasharrajat Nov 4, 2021
324960b
missing keys
parasharrajat Nov 4, 2021
62813f3
Pull latest changes
parasharrajat Nov 25, 2021
e41a044
Refactor to fix lint issues
parasharrajat Nov 25, 2021
5317be3
remove extra paypal method
parasharrajat Nov 25, 2021
3216524
Merge branch 'main' of github.com:Expensify/Expensify.cash into trans…
parasharrajat Dec 8, 2021
710be34
Refactor and Corrections to Transfer Balance
parasharrajat Dec 8, 2021
6bf8335
Use constants instead of hardcoded strings
parasharrajat Dec 8, 2021
7787b7c
Fix: add Method button logic
parasharrajat Dec 8, 2021
25bda90
Fix: add payment button and add logic to it
parasharrajat Dec 8, 2021
b708e61
api refactor
parasharrajat Dec 8, 2021
e1407c0
Merge branch 'main' of github.com:Expensify/Expensify.cash into trans…
parasharrajat Dec 8, 2021
427990d
Added add bacnk account link
parasharrajat Dec 8, 2021
419d2c3
Margin adjust
parasharrajat Dec 8, 2021
52ca3fe
Small button disabling fix
parasharrajat Dec 9, 2021
aa9075b
Use bank Icon in select account
parasharrajat Dec 9, 2021
6f26ee9
Refactor code for Intial review
parasharrajat Dec 10, 2021
f12c40f
More review cleanup
parasharrajat Dec 10, 2021
48c4c0d
Props clean up
parasharrajat Dec 12, 2021
747197e
Rename and revert extra changes
parasharrajat Dec 12, 2021
eaa00c6
Separate Click handlers on paymentMethodList and Cleanup
parasharrajat Dec 12, 2021
e016f45
Clean up props and Methods
parasharrajat Dec 12, 2021
57b22d8
Preselect the default account for walltet transfer
parasharrajat Dec 12, 2021
83f9bf0
parameter checking
parasharrajat Dec 12, 2021
48d330d
Rename functions
parasharrajat Dec 14, 2021
419ab92
refactor Addpaymentmethod Button
parasharrajat Dec 15, 2021
5a893ae
Create Selectable versions of PaymentMethodList
parasharrajat Dec 15, 2021
05520cb
refactor and cleanup
parasharrajat Dec 15, 2021
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
7 changes: 7 additions & 0 deletions assets/images/bolt.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions assets/images/transfer.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/CONST.js
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,11 @@ const CONST = {
},

WALLET: {
TRANSFER_BALANCE_FEE: 0.30,
TRANSFER_METHOD_TYPE: {
INSTANT: 'instant',
ACH: 'ach',
},
Comment thread
marcaaron marked this conversation as resolved.
ERROR: {
IDENTITY_NOT_FOUND: 'Identity not found',
INVALID_SSN: 'Invalid SSN',
Expand Down
3 changes: 3 additions & 0 deletions src/ONYXKEYS.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ export default {
// Stores information about the active reimbursement account being set up
REIMBURSEMENT_ACCOUNT: 'reimbursementAccount',

// Stores information about active wallet transfer amount, selectedAccountID, status, etc
WALLET_TRANSFER: 'walletTransfer',

// Stores draft information about the active reimbursement account being set up
REIMBURSEMENT_ACCOUNT_DRAFT: 'reimbursementAccountDraft',

Expand Down
2 changes: 2 additions & 0 deletions src/ROUTES.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export default {
SETTINGS_APP_DOWNLOAD_LINKS: 'settings/about/app-download-links',
SETTINGS_PAYMENTS: 'settings/payments',
SETTINGS_ADD_PAYPAL_ME: 'settings/payments/add-paypal-me',
SETTINGS_TRANSFER_BALANCE: 'settings/payments/transfer-balance',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

SETTINGS_PAYMENTS_TRANSFER_BALANCE

SETTINGS_PAYMENTS_CHOOSE_TRANSFER_ACCOUNT: 'settings/payments/choose-transfer-account',
SETTINGS_ADD_DEBIT_CARD: 'settings/payments/add-debit-card',
SETTINGS_ADD_BANK_ACCOUNT: 'settings/payments/add-bank-account',
SETTINGS_ADD_LOGIN: 'settings/addlogin/:type',
Expand Down
186 changes: 149 additions & 37 deletions src/components/AddPaymentMethodMenu.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import {withOnyx} from 'react-native-onyx';
import Popover from './Popover';
Expand All @@ -9,54 +9,166 @@ import styles from '../styles/styles';
import compose from '../libs/compose';
import ONYXKEYS from '../ONYXKEYS';
import CONST from '../CONST';
import * as StyleUtils from '../styles/StyleUtils';
import getClickedElementLocation from '../libs/getClickedElementLocation';
import ROUTES from '../ROUTES';
import Navigation from '../libs/Navigation/Navigation';

const propTypes = {
isVisible: PropTypes.bool.isRequired,
onClose: PropTypes.func.isRequired,
anchorPosition: PropTypes.shape({
top: PropTypes.number,
left: PropTypes.number,
}),

const propTypes = {
/** Username for PayPal.Me */
payPalMeUsername: PropTypes.string,

/** Type to filter the payment Method list */
filterType: PropTypes.oneOf([CONST.PAYMENT_METHODS.DEBIT_CARD, CONST.PAYMENT_METHODS.BANK_ACCOUNT, '']),

/** Are we loading payments from the server? */
isLoadingPayments: PropTypes.bool,

...withLocalizePropTypes,
};

const defaultProps = {
anchorPosition: {},
payPalMeUsername: '',
filterType: '',
isLoadingPayments: false,
};

const AddPaymentMethodMenu = props => (
<Popover
isVisible={props.isVisible}
onClose={props.onClose}
anchorPosition={props.anchorPosition}
>
<MenuItem
title={props.translate('common.bankAccount')}
icon={Expensicons.Bank}
onPress={() => props.onItemSelected(CONST.PAYMENT_METHODS.BANK_ACCOUNT)}
wrapperStyle={styles.pr15}
/>
<MenuItem
title={props.translate('common.debitCard')}
icon={Expensicons.CreditCard}
onPress={() => props.onItemSelected(CONST.PAYMENT_METHODS.DEBIT_CARD)}
wrapperStyle={styles.pr15}
/>
{!props.payPalMeUsername && (
<MenuItem
title={props.translate('common.payPalMe')}
icon={Expensicons.PayPal}
onPress={() => props.onItemSelected(CONST.PAYMENT_METHODS.PAYPAL)}
wrapperStyle={styles.pr15}
/>
)}
</Popover>
);
class AddPaymentMethodMenu extends Component {
constructor(props) {
super(props);

this.state = {
isAddPaymentMenuActive: false,
anchorPosition: {
top: 0,
left: 0,
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We need to use this component in this PR and having it internally track the anchorPosition isn't going to work.

};
this.addPaymentMethodPressed = this.addPaymentMethodPressed.bind(this);
this.addPaymentMethodTypePressed = this.addPaymentMethodTypePressed.bind(this);
this.hideAddPaymentMenu = this.hideAddPaymentMenu.bind(this);
}

/**
* Get the AddPaymentMethod Button title
* @returns {String}
*/
getAddPaymentMethodButtonTitle() {
switch (this.props.filterType) {
case CONST.PAYMENT_METHODS.BANK_ACCOUNT:
return this.props.translate('paymentMethodList.addBankAccount');
case CONST.PAYMENT_METHODS.DEBIT_CARD:
return this.props.translate('paymentMethodList.addDebitCard');
default: break;
}
return this.props.translate('paymentMethodList.addPaymentMethod');
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We need to make a new component that:

  • Has AddPaymentMethodMenu inside it
  • Shows the different button options and only opens the popover when we don't want one or the other.

AddPaymentMethodMenu itself shouldn't be modified because we need the popover to open when the "Transfer Balance" button is eventually pressed. Does that make sense? There's an issue here describing what the ultimate goal is: https://github.com/Expensify/Expensify/issues/187802

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd suggest calling it AddPaymentMethodButton

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

AddPaymentMethodMenu itself shouldn't be modified because we need the popover to open when the "Transfer Balance" button is eventually pressed.

I didn't get it and I don't have access to that issue. But I got the idea.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah I'm sorry, I forgot that you cannot see those issues.


/**
* Display the add payment method menu
* @param {Object} nativeEvent
*/
addPaymentMethodPressed(nativeEvent) {
const position = getClickedElementLocation(nativeEvent);
this.setState({
isAddPaymentMenuActive: true,
anchorPosition: {
top: position.bottom,

// We want the position to be 20px to the right of the left border
left: position.left + 20,
},
});
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This would need to go into that other component.


/**
* Navigate to the appropriate payment type addition screen
* @param {String} paymentType
*/
addPaymentMethodTypePressed(paymentType) {
if (!this.props.filterType) {
this.hideAddPaymentMenu();
}

if (paymentType === CONST.PAYMENT_METHODS.PAYPAL) {
Navigation.navigate(ROUTES.SETTINGS_ADD_PAYPAL_ME);
return;
}

if (paymentType === CONST.PAYMENT_METHODS.DEBIT_CARD) {
Navigation.navigate(ROUTES.SETTINGS_ADD_DEBIT_CARD);
return;
}

if (paymentType === CONST.PAYMENT_METHODS.BANK_ACCOUNT) {
Navigation.navigate(ROUTES.SETTINGS_ADD_BANK_ACCOUNT);
return;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

None of these routes should be in this component because we will eventually need to navigate to different routes depending on the context in which this component will be used. I would suggest passing in the route as a prop to keep this component reusable.


throw new Error('Invalid payment method type selected');
}

/**
* Hide the add payment modal
*/
hideAddPaymentMenu() {
this.setState({isAddPaymentMenuActive: false});
}

render() {
const addPaymentMethodButtonTitle = this.getAddPaymentMethodButtonTitle();

return (
<>
<MenuItem
onPress={e => (this.props.filterType
? this.addPaymentMethodTypePressed(this.props.filterType)
: this.addPaymentMethodPressed(e)
)}
title={addPaymentMethodButtonTitle}
icon={Expensicons.Plus}
disabled={this.props.isLoadingPayments}
iconFill={this.state.isAddPaymentMenuActive
? StyleUtils.getIconFillColor(CONST.BUTTON_STATES.PRESSED)
: undefined}
wrapperStyle={this.state.isAddPaymentMenuActive
? [StyleUtils.getButtonBackgroundColorStyle(CONST.BUTTON_STATES.PRESSED)]
: []}

/>
{!this.props.filterType && (
<Popover
isVisible={this.state.isAddPaymentMenuActive}
onClose={this.hideAddPaymentMenu}
anchorPosition={this.state.anchorPosition}
>
<MenuItem
title={this.props.translate('common.bankAccount')}
icon={Expensicons.Bank}
onPress={() => this.addPaymentMethodTypePressed(CONST.PAYMENT_METHODS.BANK_ACCOUNT)}
wrapperStyle={styles.pr15}
/>
<MenuItem
title={this.props.translate('common.debitCard')}
icon={Expensicons.CreditCard}
onPress={() => this.addPaymentMethodTypePressed(CONST.PAYMENT_METHODS.DEBIT_CARD)}
wrapperStyle={styles.pr15}
/>
{!this.props.payPalMeUsername && (
<MenuItem
title={this.props.translate('common.payPalMe')}
icon={Expensicons.PayPal}
onPress={() => this.addPaymentMethodTypePressed(CONST.PAYMENT_METHODS.PAYPAL)}
wrapperStyle={styles.pr15}
/>
)}
</Popover>
)}
</>
);
}
}

AddPaymentMethodMenu.propTypes = propTypes;
AddPaymentMethodMenu.defaultProps = defaultProps;
Expand Down
6 changes: 5 additions & 1 deletion src/components/CurrentWalletBalance.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,15 @@ const propTypes = {
currentBalance: PropTypes.number,
}),

/** Styles of the amount */
balanceStyles: PropTypes.arrayOf(PropTypes.object),

...withLocalizePropTypes,
};

const defaultProps = {
userWallet: {},
balanceStyles: [],
};

const CurrentWalletBalance = (props) => {
Expand All @@ -41,7 +45,7 @@ const CurrentWalletBalance = (props) => {
);
return (
<Text
style={[styles.textXXXLarge, styles.pv5, styles.alignSelfCenter]}
style={[styles.textXXXLarge, styles.pv5, styles.alignSelfCenter, ...props.balanceStyles]}
>
{`${formattedBalance}`}
</Text>
Expand Down
4 changes: 4 additions & 0 deletions src/components/Icon/Expensicons.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import ArrowRight from '../../../assets/images/arrow-right.svg';
import BackArrow from '../../../assets/images/back-left.svg';
import Bank from '../../../assets/images/bank.svg';
import Bill from '../../../assets/images/bill.svg';
import Bolt from '../../../assets/images/bolt.svg';
import Briefcase from '../../../assets/images/briefcase.svg';
import Bug from '../../../assets/images/bug.svg';
import Building from '../../../assets/images/building.svg';
Expand Down Expand Up @@ -55,6 +56,7 @@ import RotateLeft from '../../../assets/images/rotate-left.svg';
import Send from '../../../assets/images/send.svg';
import SignOut from '../../../assets/images/sign-out.svg';
import Sync from '../../../assets/images/sync.svg';
import Transfer from '../../../assets/images/transfer.svg';
import Trashcan from '../../../assets/images/trashcan.svg';
import UpArrow from '../../../assets/images/arrow-up.svg';
import Upload from '../../../assets/images/upload.svg';
Expand All @@ -71,6 +73,7 @@ export {
BackArrow,
Bank,
Bill,
Bolt,
Briefcase,
Building,
Bug,
Expand Down Expand Up @@ -122,6 +125,7 @@ export {
Send,
SignOut,
Sync,
Transfer,
Trashcan,
UpArrow,
Upload,
Expand Down
10 changes: 5 additions & 5 deletions src/components/MenuItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,12 @@ import Avatar from './Avatar';
import Badge from './Badge';
import CONST from '../CONST';
import menuItemPropTypes from './menuItemPropTypes';

const propTypes = {
...menuItemPropTypes,
};
import SelectCircle from './SelectCircle';

const defaultProps = {
badgeText: undefined,
shouldShowRightIcon: false,
shouldShowSelectedState: false,
wrapperStyle: [],
success: false,
icon: undefined,
Expand All @@ -32,6 +30,7 @@ const defaultProps = {
iconFill: undefined,
focused: false,
disabled: false,
isSelected: false,
subtitle: undefined,
iconType: 'icon',
onPress: () => {},
Expand Down Expand Up @@ -124,13 +123,14 @@ const MenuItem = props => (
/>
</View>
)}
{props.shouldShowSelectedState && <SelectCircle isChecked={props.isSelected} />}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just FYI I tried to help out a bit and moved this change to a new PR to lighten things up here.

</View>
</>
)}
</Pressable>
);

MenuItem.propTypes = propTypes;
MenuItem.propTypes = menuItemPropTypes;
MenuItem.defaultProps = defaultProps;
MenuItem.displayName = 'MenuItem';

Expand Down
30 changes: 30 additions & 0 deletions src/components/SelectCircle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import {View} from 'react-native';
import PropTypes from 'prop-types';
import styles from '../styles/styles';
import Icon from './Icon';
import * as Expensicons from './Icon/Expensicons';
import themeColors from '../styles/themes/default';

const propTypes = {
/** Whether SelectCircle is checked */
isChecked: PropTypes.bool,
};

const defaultProps = {
isChecked: false,
};

const SelectCircle = props => (
<View style={[styles.selectCircle, styles.alignSelfCenter]}>
{props.isChecked && (
<Icon src={Expensicons.Checkmark} fill={themeColors.iconSuccessFill} />
)}
</View>
);

SelectCircle.propTypes = propTypes;
SelectCircle.defaultProps = defaultProps;
SelectCircle.displayName = 'SelectCircle';

export default SelectCircle;
Loading