diff --git a/src/pages/settings/InitialSettingsPage.js b/src/pages/settings/InitialSettingsPage.js index edcc92982c8b..a92ee760ce21 100755 --- a/src/pages/settings/InitialSettingsPage.js +++ b/src/pages/settings/InitialSettingsPage.js @@ -1,6 +1,6 @@ import lodashGet from 'lodash/get'; -import React from 'react'; -import {ScrollView, View} from 'react-native'; +import React, {useState, useEffect, useRef, useMemo, useCallback} from 'react'; +import {View, ScrollView} from 'react-native'; import PropTypes from 'prop-types'; import _ from 'underscore'; import {withOnyx} from 'react-native-onyx'; @@ -40,6 +40,7 @@ import * as ReportActionContextMenu from '../home/report/ContextMenu/ReportActio import {CONTEXT_MENU_TYPES} from '../home/report/ContextMenu/ContextMenuActions'; import * as CurrencyUtils from '../../libs/CurrencyUtils'; import PressableWithoutFeedback from '../../components/Pressable/PressableWithoutFeedback'; +import useLocalize from '../../hooks/useLocalize'; const propTypes = { /* Onyx Props */ @@ -123,42 +124,44 @@ const defaultProps = { ...withCurrentUserPersonalDetailsDefaultProps, }; -class InitialSettingsPage extends React.Component { - constructor(props) { - super(props); +function InitialSettingsPage(props) { + const popoverAnchor = useRef(null); + const {translate} = useLocalize(); - this.popoverAnchor = React.createRef(); + const [shouldShowSignoutConfirmModal, setShouldShowSignoutConfirmModal] = useState(false); - this.getWalletBalance = this.getWalletBalance.bind(this); - this.getDefaultMenuItems = this.getDefaultMenuItems.bind(this); - this.getMenuItem = this.getMenuItem.bind(this); - this.toggleSignoutConfirmModal = this.toggleSignoutConfirmModal.bind(this); - this.signout = this.signOut.bind(this); + useEffect(() => { + Wallet.openInitialSettingsPage(); + }, []); - this.state = { - shouldShowSignoutConfirmModal: false, - }; - } + const toggleSignoutConfirmModal = (value) => { + setShouldShowSignoutConfirmModal(value); + }; - componentDidMount() { - Wallet.openInitialSettingsPage(); - } + const openProfileSettings = () => { + Navigation.navigate(ROUTES.SETTINGS_PROFILE); + }; - /** - * @param {Boolean} isPaymentItem whether the item being rendered is the payments menu item - * @returns {Number} the user wallet balance - */ - getWalletBalance(isPaymentItem) { - return isPaymentItem && Permissions.canUseWallet(this.props.betas) ? CurrencyUtils.convertToDisplayString(this.props.userWallet.currentBalance) : undefined; - } + const signOut = useCallback( + (shouldForceSignout = false) => { + if (props.network.isOffline || shouldForceSignout) { + Session.signOutAndRedirectToSignIn(); + return; + } + + // When offline, warn the user that any actions they took while offline will be lost if they sign out + toggleSignoutConfirmModal(true); + }, + [props.network.isOffline], + ); /** * Retuns a list of default menu items * @returns {Array} the default menu items */ - getDefaultMenuItems() { - const policiesAvatars = _.chain(this.props.policies) - .filter((policy) => PolicyUtils.shouldShowPolicy(policy, this.props.network.isOffline)) + const getDefaultMenuItems = useMemo(() => { + const policiesAvatars = _.chain(props.policies) + .filter((policy) => PolicyUtils.shouldShowPolicy(policy, props.network.isOffline)) .sortBy((policy) => policy.name.toLowerCase()) .map((policy) => ({ source: policy.avatar || ReportUtils.getDefaultWorkspaceAvatar(policy.name), @@ -168,14 +171,14 @@ class InitialSettingsPage extends React.Component { .value(); const policyBrickRoadIndicator = - !_.isEmpty(this.props.reimbursementAccount.errors) || - _.chain(this.props.policies) + !_.isEmpty(props.reimbursementAccount.errors) || + _.chain(props.policies) .filter((policy) => policy && policy.type === CONST.POLICY.TYPE.FREE && policy.role === CONST.POLICY.ROLE.ADMIN) - .some((policy) => PolicyUtils.hasPolicyError(policy) || PolicyUtils.getPolicyBrickRoadIndicatorStatus(policy, this.props.allPolicyMembers)) + .some((policy) => PolicyUtils.hasPolicyError(policy) || PolicyUtils.getPolicyBrickRoadIndicatorStatus(policy, props.allPolicyMembers)) .value() ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : null; - const profileBrickRoadIndicator = UserUtils.getLoginListBrickRoadIndicator(this.props.loginList); + const profileBrickRoadIndicator = UserUtils.getLoginListBrickRoadIndicator(props.loginList); return [ { @@ -225,9 +228,7 @@ class InitialSettingsPage extends React.Component { Navigation.navigate(ROUTES.SETTINGS_PAYMENTS); }, brickRoadIndicator: - PaymentMethods.hasPaymentMethodError(this.props.bankAccountList, this.props.cardList) || - !_.isEmpty(this.props.userWallet.errors) || - !_.isEmpty(this.props.walletTerms.errors) + PaymentMethods.hasPaymentMethodError(props.bankAccountList, props.cardList) || !_.isEmpty(props.userWallet.errors) || !_.isEmpty(props.walletTerms.errors) ? 'error' : null, }, @@ -252,134 +253,145 @@ class InitialSettingsPage extends React.Component { translationKey: 'initialSettingsPage.signOut', icon: Expensicons.Exit, action: () => { - this.signout(false); + signOut(false); }, }, ]; - } - - getMenuItem(item, index) { - const keyTitle = item.translationKey ? this.props.translate(item.translationKey) : item.title; - const isPaymentItem = item.translationKey === 'common.payments'; + }, [ + props.allPolicyMembers, + props.bankAccountList, + props.cardList, + props.loginList, + props.network.isOffline, + props.policies, + props.reimbursementAccount.errors, + props.userWallet.errors, + props.walletTerms.errors, + signOut, + ]); + + const getMenuItems = useMemo(() => { + /** + * @param {Boolean} isPaymentItem whether the item being rendered is the payments menu item + * @returns {Number} the user wallet balance + */ + const getWalletBalance = (isPaymentItem) => + isPaymentItem && Permissions.canUseWallet(props.betas) ? CurrencyUtils.convertToDisplayString(props.userWallet.currentBalance) : undefined; return ( - ReportActionContextMenu.showContextMenu(CONTEXT_MENU_TYPES.LINK, e, item.link, this.popoverAnchor.current) : undefined} - /> + <> + {_.map(getDefaultMenuItems, (item, index) => { + const keyTitle = item.translationKey ? translate(item.translationKey) : item.title; + const isPaymentItem = item.translationKey === 'common.payments'; + + return ( + ReportActionContextMenu.showContextMenu(CONTEXT_MENU_TYPES.LINK, e, item.link, popoverAnchor.current) : undefined + } + /> + ); + })} + ); - } + }, [getDefaultMenuItems, props.betas, props.userWallet.currentBalance, translate]); - toggleSignoutConfirmModal(value) { - this.setState({shouldShowSignoutConfirmModal: value}); + // On the very first sign in or after clearing storage these + // details will not be present on the first render so we'll just + // return nothing for now. + if (_.isEmpty(props.currentUserPersonalDetails)) { + return null; } - signOut(shouldForceSignout = false) { - if (!this.props.network.isOffline || shouldForceSignout) { - Session.signOutAndRedirectToSignIn(); - return; - } - - // When offline, warn the user that any actions they took while offline will be lost if they sign out - this.toggleSignoutConfirmModal(true); - } - - openProfileSettings() { - Navigation.navigate(ROUTES.SETTINGS_PROFILE); - } - - render() { - return ( - - {({safeAreaPaddingBottomStyle}) => ( - <> - - - - {_.isEmpty(this.props.currentUserPersonalDetails) || _.isUndefined(this.props.currentUserPersonalDetails.displayName) ? ( - - ) : ( - - - - - - - - + return ( + + {({safeAreaPaddingBottomStyle}) => ( + <> + + + + {_.isEmpty(props.currentUserPersonalDetails) || _.isUndefined(props.currentUserPersonalDetails.displayName) ? ( + + ) : ( + + - - - {this.props.currentUserPersonalDetails.displayName - ? this.props.currentUserPersonalDetails.displayName - : this.props.formatPhoneNumber(this.props.session.email)} - - + + + - {Boolean(this.props.currentUserPersonalDetails.displayName) && ( + + + - {this.props.formatPhoneNumber(this.props.session.email)} + {props.currentUserPersonalDetails.displayName ? props.currentUserPersonalDetails.displayName : props.formatPhoneNumber(props.session.email)} - )} - - )} - {_.map(this.getDefaultMenuItems(), (item, index) => this.getMenuItem(item, index))} - - this.signOut(true)} - onCancel={() => this.toggleSignoutConfirmModal(false)} - /> - - - - )} - - ); - } + + + {Boolean(props.currentUserPersonalDetails.displayName) && ( + + {props.formatPhoneNumber(props.session.email)} + + )} + + )} + {getMenuItems} + + signOut(true)} + onCancel={() => toggleSignoutConfirmModal(false)} + /> + + + + )} + + ); } InitialSettingsPage.propTypes = propTypes;