From 024ffcc175211432736456c3a6d6024f8d0cc577 Mon Sep 17 00:00:00 2001 From: David Bondy Date: Fri, 20 Oct 2023 16:28:58 -0600 Subject: [PATCH] Revert "feat: migrate KYCWall class component to functional" --- src/components/KYCWall/BaseKYCWall.js | 238 ++++++++++++-------------- src/libs/actions/PaymentMethods.ts | 6 +- 2 files changed, 108 insertions(+), 136 deletions(-) diff --git a/src/components/KYCWall/BaseKYCWall.js b/src/components/KYCWall/BaseKYCWall.js index f8e8573311e9..ccee8bc4e6a0 100644 --- a/src/components/KYCWall/BaseKYCWall.js +++ b/src/components/KYCWall/BaseKYCWall.js @@ -1,5 +1,5 @@ -import React, {useEffect, useState, useRef, useCallback} from 'react'; import _ from 'underscore'; +import React from 'react'; import {withOnyx} from 'react-native-onyx'; import {Dimensions} from 'react-native'; import lodashGet from 'lodash/get'; @@ -15,114 +15,90 @@ import {propTypes, defaultProps} from './kycWallPropTypes'; import * as Wallet from '../../libs/actions/Wallet'; import * as ReportUtils from '../../libs/ReportUtils'; -const POPOVER_MENU_ANCHOR_POSITION_HORIZONTAL_OFFSET = 20; - // This component allows us to block various actions by forcing the user to first add a default payment method and successfully make it through our Know Your Customer flow // before continuing to take whatever action they originally intended to take. It requires a button as a child and a native event so we can get the coordinates and use it // to render the AddPaymentMethodMenu in the correct location. -function KYCWall({ - addBankAccountRoute, - addDebitCardRoute, - anchorAlignment, - bankAccountList, - chatReportID, - children, - enablePaymentsRoute, - fundList, - iouReport, - onSelectPaymentMethod, - onSuccessfulKYC, - reimbursementAccount, - shouldIncludeDebitCard, - shouldListenForResize, - source, - userWallet, - walletTerms, -}) { - const anchorRef = useRef(null); - const transferBalanceButtonRef = useRef(null); - - const [shouldShowAddPaymentMenu, setShouldShowAddPaymentMenu] = useState(false); - const [anchorPosition, setAnchorPosition] = useState({ - anchorPositionVertical: 0, - anchorPositionHorizontal: 0, - }); +class KYCWall extends React.Component { + constructor(props) { + super(props); + + this.continue = this.continue.bind(this); + this.setMenuPosition = this.setMenuPosition.bind(this); + this.selectPaymentMethod = this.selectPaymentMethod.bind(this); + this.anchorRef = React.createRef(null); + + this.state = { + shouldShowAddPaymentMenu: false, + anchorPositionVertical: 0, + anchorPositionHorizontal: 0, + transferBalanceButton: null, + }; + } + + componentDidMount() { + PaymentMethods.kycWallRef.current = this; + if (this.props.shouldListenForResize) { + this.dimensionsSubscription = Dimensions.addEventListener('change', this.setMenuPosition); + } + } + + componentWillUnmount() { + if (this.props.shouldListenForResize && this.dimensionsSubscription) { + this.dimensionsSubscription.remove(); + } + PaymentMethods.kycWallRef.current = null; + } + + setMenuPosition() { + if (!this.state.transferBalanceButton) { + return; + } + const buttonPosition = getClickedTargetLocation(this.state.transferBalanceButton); + const position = this.getAnchorPosition(buttonPosition); + this.setPositionAddPaymentMenu(position); + } /** * @param {DOMRect} domRect * @returns {Object} */ - const getAnchorPosition = useCallback( - (domRect) => { - if (anchorAlignment.vertical === CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.TOP) { - return { - anchorPositionVertical: domRect.top + domRect.height + CONST.MODAL.POPOVER_MENU_PADDING, - anchorPositionHorizontal: domRect.left + POPOVER_MENU_ANCHOR_POSITION_HORIZONTAL_OFFSET, - }; - } - + getAnchorPosition(domRect) { + if (this.props.anchorAlignment.vertical === CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.TOP) { return { - anchorPositionVertical: domRect.top - CONST.MODAL.POPOVER_MENU_PADDING, - anchorPositionHorizontal: domRect.left, + anchorPositionVertical: domRect.top + domRect.height + CONST.MODAL.POPOVER_MENU_PADDING, + anchorPositionHorizontal: domRect.left + 20, }; - }, - [anchorAlignment.vertical], - ); + } + + return { + anchorPositionVertical: domRect.top - CONST.MODAL.POPOVER_MENU_PADDING, + anchorPositionHorizontal: domRect.left, + }; + } /** * Set position of the transfer payment menu * * @param {Object} position */ - const setPositionAddPaymentMenu = ({anchorPositionVertical, anchorPositionHorizontal}) => { - setAnchorPosition({ - anchorPositionVertical, - anchorPositionHorizontal, + setPositionAddPaymentMenu(position) { + this.setState({ + anchorPositionVertical: position.anchorPositionVertical, + anchorPositionHorizontal: position.anchorPositionHorizontal, }); - }; - - const setMenuPosition = useCallback(() => { - if (!transferBalanceButtonRef.current) { - return; - } - const buttonPosition = getClickedTargetLocation(transferBalanceButtonRef.current); - const position = getAnchorPosition(buttonPosition); - - setPositionAddPaymentMenu(position); - }, [getAnchorPosition]); - - useEffect(() => { - let dimensionsSubscription = null; - - PaymentMethods.kycWallRef.current = this; - - if (shouldListenForResize) { - dimensionsSubscription = Dimensions.addEventListener('change', setMenuPosition); - } - - Wallet.setKYCWallSourceChatReportID(chatReportID); - - return () => { - if (shouldListenForResize && dimensionsSubscription) { - dimensionsSubscription.remove(); - } - - PaymentMethods.kycWallRef.current = null; - }; - }, [chatReportID, setMenuPosition, shouldListenForResize]); + } /** * @param {String} paymentMethod */ - const selectPaymentMethod = (paymentMethod) => { - onSelectPaymentMethod(paymentMethod); - + selectPaymentMethod(paymentMethod) { + this.props.onSelectPaymentMethod(paymentMethod); if (paymentMethod === CONST.PAYMENT_METHODS.BANK_ACCOUNT) { - Navigation.navigate(addBankAccountRoute); + Navigation.navigate(this.props.addBankAccountRoute); } else if (paymentMethod === CONST.PAYMENT_METHODS.DEBIT_CARD) { - Navigation.navigate(addDebitCardRoute); + Navigation.navigate(this.props.addDebitCardRoute); } - }; + } /** * Take the position of the button that calls this method and show the Add Payment method menu when the user has no valid payment method. @@ -132,86 +108,82 @@ function KYCWall({ * @param {Event} event * @param {String} iouPaymentType */ - const continueAction = (event, iouPaymentType) => { - const currentSource = lodashGet(walletTerms, 'source', source); + continue(event, iouPaymentType) { + const currentSource = lodashGet(this.props.walletTerms, 'source', this.props.source); /** * Set the source, so we can tailor the process according to how we got here. * We do not want to set this on mount, as the source can change upon completing the flow, e.g. when upgrading the wallet to Gold. */ - Wallet.setKYCWallSource(source, chatReportID); - - if (shouldShowAddPaymentMenu) { - setShouldShowAddPaymentMenu(false); + Wallet.setKYCWallSource(this.props.source, this.props.chatReportID); + if (this.state.shouldShowAddPaymentMenu) { + this.setState({shouldShowAddPaymentMenu: false}); return; } // Use event target as fallback if anchorRef is null for safety - const targetElement = anchorRef.current || event.nativeEvent.target; - - transferBalanceButtonRef.current = targetElement; - const isExpenseReport = ReportUtils.isExpenseReport(iouReport); - const paymentCardList = fundList || {}; + const targetElement = this.anchorRef.current || event.nativeEvent.target; + this.setState({transferBalanceButton: targetElement}); + const isExpenseReport = ReportUtils.isExpenseReport(this.props.iouReport); + const paymentCardList = this.props.fundList || {}; // Check to see if user has a valid payment method on file and display the add payment popover if they don't if ( - (isExpenseReport && lodashGet(reimbursementAccount, 'achData.state', '') !== CONST.BANK_ACCOUNT.STATE.OPEN) || - (!isExpenseReport && !PaymentUtils.hasExpensifyPaymentMethod(paymentCardList, bankAccountList, shouldIncludeDebitCard)) + (isExpenseReport && lodashGet(this.props.reimbursementAccount, 'achData.state', '') !== CONST.BANK_ACCOUNT.STATE.OPEN) || + (!isExpenseReport && !PaymentUtils.hasExpensifyPaymentMethod(paymentCardList, this.props.bankAccountList, this.props.shouldIncludeDebitCard)) ) { Log.info('[KYC Wallet] User does not have valid payment method'); - if (!shouldIncludeDebitCard) { - selectPaymentMethod(CONST.PAYMENT_METHODS.BANK_ACCOUNT); + if (!this.props.shouldIncludeDebitCard) { + this.selectPaymentMethod(CONST.PAYMENT_METHODS.BANK_ACCOUNT); return; } - const clickedElementLocation = getClickedTargetLocation(targetElement); - const position = getAnchorPosition(clickedElementLocation); - - setPositionAddPaymentMenu(position); - setShouldShowAddPaymentMenu(true); - + const position = this.getAnchorPosition(clickedElementLocation); + this.setPositionAddPaymentMenu(position); + this.setState({ + shouldShowAddPaymentMenu: true, + }); return; } - if (!isExpenseReport) { // Ask the user to upgrade to a gold wallet as this means they have not yet gone through our Know Your Customer (KYC) checks - const hasActivatedWallet = userWallet.tierName && _.contains([CONST.WALLET.TIER_NAME.GOLD, CONST.WALLET.TIER_NAME.PLATINUM], userWallet.tierName); + const hasActivatedWallet = this.props.userWallet.tierName && _.contains([CONST.WALLET.TIER_NAME.GOLD, CONST.WALLET.TIER_NAME.PLATINUM], this.props.userWallet.tierName); if (!hasActivatedWallet) { Log.info('[KYC Wallet] User does not have active wallet'); - Navigation.navigate(enablePaymentsRoute); + Navigation.navigate(this.props.enablePaymentsRoute); return; } } - Log.info('[KYC Wallet] User has valid payment method and passed KYC checks or did not need them'); - onSuccessfulKYC(iouPaymentType, currentSource); - }; - - return ( - <> - setShouldShowAddPaymentMenu(false)} - anchorRef={anchorRef} - anchorAlignment={anchorAlignment} - anchorPosition={{ - vertical: anchorPosition.anchorPositionVertical, - horizontal: anchorPosition.anchorPositionHorizontal, - }} - onItemSelected={(item) => { - setShouldShowAddPaymentMenu(false); - selectPaymentMethod(item); - }} - /> - {children(continueAction, anchorRef)} - - ); + this.props.onSuccessfulKYC(iouPaymentType, currentSource); + } + + render() { + return ( + <> + this.setState({shouldShowAddPaymentMenu: false})} + anchorRef={this.anchorRef} + anchorPosition={{ + vertical: this.state.anchorPositionVertical, + horizontal: this.state.anchorPositionHorizontal, + }} + anchorAlignment={this.props.anchorAlignment} + onItemSelected={(item) => { + this.setState({shouldShowAddPaymentMenu: false}); + this.selectPaymentMethod(item); + }} + /> + {this.props.children(this.continue, this.anchorRef)} + + ); + } } KYCWall.propTypes = propTypes; KYCWall.defaultProps = defaultProps; -KYCWall.displayName = 'BaseKYCWall'; export default withOnyx({ userWallet: { diff --git a/src/libs/actions/PaymentMethods.ts b/src/libs/actions/PaymentMethods.ts index 5030f15387b8..fe1b5ebe10e9 100644 --- a/src/libs/actions/PaymentMethods.ts +++ b/src/libs/actions/PaymentMethods.ts @@ -11,7 +11,7 @@ import {FilterMethodPaymentType} from '../../types/onyx/WalletTransfer'; import PaymentMethod from '../../types/onyx/PaymentMethod'; type KYCWallRef = { - continueAction?: () => void; + continue?: () => void; }; /** @@ -23,14 +23,14 @@ const kycWallRef = createRef(); * When we successfully add a payment method or pass the KYC checks we will continue with our setup action if we have one set. */ function continueSetup(fallbackRoute = ROUTES.HOME) { - if (!kycWallRef.current?.continueAction) { + if (!kycWallRef.current?.continue) { Navigation.goBack(fallbackRoute); return; } // Close the screen (Add Debit Card, Add Bank Account, or Enable Payments) on success and continue with setup Navigation.goBack(fallbackRoute); - kycWallRef.current.continueAction(); + kycWallRef.current.continue(); } function openWalletPage() {