diff --git a/src/components/DelegateNoAccessModal.tsx b/src/components/DelegateNoAccessModal.tsx deleted file mode 100644 index ae5a982934075..0000000000000 --- a/src/components/DelegateNoAccessModal.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React from 'react'; -import useDelegateUserDetails from '@hooks/useDelegateUserDetails'; -import useLocalize from '@hooks/useLocalize'; -import CONST from '@src/CONST'; -import ConfirmModal from './ConfirmModal'; -import Text from './Text'; -import TextLink from './TextLink'; - -type DelegateNoAccessModalProps = { - isNoDelegateAccessMenuVisible: boolean; - onClose: () => void; -}; - -export default function DelegateNoAccessModal({isNoDelegateAccessMenuVisible = false, onClose}: DelegateNoAccessModalProps) { - const {translate} = useLocalize(); - const {delegatorEmail} = useDelegateUserDetails(); - const noDelegateAccessPromptStart = translate('delegate.notAllowedMessageStart'); - const noDelegateAccessHyperLinked = translate('delegate.notAllowedMessageHyperLinked'); - const noDelegateAccessPromptEnd = translate('delegate.notAllowedMessageEnd', {accountOwnerEmail: delegatorEmail ?? ''}); - const delegateNoAccessPrompt = ( - - {noDelegateAccessPromptStart} - {noDelegateAccessHyperLinked} - {noDelegateAccessPromptEnd} - - ); - - return ( - - ); -} diff --git a/src/components/DelegateNoAccessModalProvider.tsx b/src/components/DelegateNoAccessModalProvider.tsx new file mode 100644 index 0000000000000..202edbe7da914 --- /dev/null +++ b/src/components/DelegateNoAccessModalProvider.tsx @@ -0,0 +1,74 @@ +import React, {createContext, useMemo, useState} from 'react'; +import type {PropsWithChildren} from 'react'; +import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; +import useLocalize from '@hooks/useLocalize'; +import useOnyx from '@hooks/useOnyx'; +import AccountUtils from '@libs/AccountUtils'; +import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; +import ConfirmModal from './ConfirmModal'; +import Text from './Text'; +import TextLink from './TextLink'; + +type DelegateNoAccessContextType = { + /** Whether the current user is acting as delegate */ + isActingAsDelegate: boolean; + + /** Whether the current user has restricted access as a submitter only delegate */ + isDelegateAccessRestricted: boolean; + + /** Function to show the delegate no access modal */ + showDelegateNoAccessModal: () => void; +}; + +const DelegateNoAccessContext = createContext({ + isActingAsDelegate: false, + isDelegateAccessRestricted: false, + showDelegateNoAccessModal: () => {}, +}); + +function DelegateNoAccessModalProvider({children}: PropsWithChildren) { + const {translate} = useLocalize(); + const [isModalOpen, setIsModalOpen] = useState(false); + const currentUserDetails = useCurrentUserPersonalDetails(); + const delegatorEmail = currentUserDetails?.login ?? ''; + const [account] = useOnyx(ONYXKEYS.ACCOUNT, {canBeMissing: true}); + const isActingAsDelegate = !!account?.delegatedAccess?.delegate; + const isDelegateAccessRestricted = isActingAsDelegate && AccountUtils.isDelegateOnlySubmitter(account); + + const delegateNoAccessPrompt = ( + + {translate('delegate.notAllowedMessageStart')} + {translate('delegate.notAllowedMessageHyperLinked')} + {translate('delegate.notAllowedMessageEnd', {accountOwnerEmail: delegatorEmail})} + + ); + const contextValue = useMemo( + () => ({ + isActingAsDelegate, + isDelegateAccessRestricted, + showDelegateNoAccessModal: () => setIsModalOpen(true), + }), + [isActingAsDelegate, isDelegateAccessRestricted], + ); + + return ( + + {children} + setIsModalOpen(false)} + onCancel={() => setIsModalOpen(false)} + title={translate('delegate.notAllowed')} + prompt={delegateNoAccessPrompt} + confirmText={translate('common.buttonConfirm')} + shouldShowCancelButton={false} + /> + + ); +} + +DelegateNoAccessModalProvider.displayName = 'DelegateNoAccessModalProvider'; + +export default DelegateNoAccessModalProvider; +export {DelegateNoAccessContext}; diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index 555abf38e5ad6..31f91af74bed6 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -1,5 +1,5 @@ import {useRoute} from '@react-navigation/native'; -import React, {useCallback, useEffect, useMemo, useState} from 'react'; +import React, {useCallback, useContext, useEffect, useMemo, useState} from 'react'; import {ActivityIndicator, InteractionManager, View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {useOnyx} from 'react-native-onyx'; @@ -79,7 +79,6 @@ import { } from '@userActions/IOU'; import {markAsCash as markAsCashAction} from '@userActions/Transaction'; import CONST from '@src/CONST'; -import useDelegateUserDetails from '@src/hooks/useDelegateUserDetails'; import ONYXKEYS from '@src/ONYXKEYS'; import type {Route} from '@src/ROUTES'; import ROUTES from '@src/ROUTES'; @@ -94,7 +93,7 @@ import ButtonWithDropdownMenu from './ButtonWithDropdownMenu'; import type {DropdownOption} from './ButtonWithDropdownMenu/types'; import ConfirmModal from './ConfirmModal'; import DecisionModal from './DecisionModal'; -import DelegateNoAccessModal from './DelegateNoAccessModal'; +import {DelegateNoAccessContext} from './DelegateNoAccessModalProvider'; import Header from './Header'; import HeaderWithBackButton from './HeaderWithBackButton'; import Icon from './Icon'; @@ -295,8 +294,7 @@ function MoneyReportHeader({ const bankAccountRoute = getBankAccountRoute(chatReport); const {nonHeldAmount, fullAmount, hasValidNonHeldAmount} = getNonHeldAndFullAmount(moneyRequestReport, shouldShowPayButton); const isAnyTransactionOnHold = hasHeldExpensesReportUtils(moneyRequestReport?.reportID); - const {isDelegateAccessRestricted} = useDelegateUserDetails(); - const [isNoDelegateAccessMenuVisible, setIsNoDelegateAccessMenuVisible] = useState(false); + const {isDelegateAccessRestricted, showDelegateNoAccessModal} = useContext(DelegateNoAccessContext); const [isLoadingReportData] = useOnyx(ONYXKEYS.IS_LOADING_REPORT_DATA, {canBeMissing: true}); const isReportInRHP = route.name === SCREENS.SEARCH.REPORT_RHP; @@ -310,7 +308,7 @@ function MoneyReportHeader({ setPaymentType(type); setRequestType(CONST.IOU.REPORT_ACTION_TYPE.PAY); if (isDelegateAccessRestricted) { - setIsNoDelegateAccessMenuVisible(true); + showDelegateNoAccessModal(); } else if (isAnyTransactionOnHold) { InteractionManager.runAfterInteractions(() => setIsHoldMenuVisible(true)); } else if (isInvoiceReport) { @@ -321,13 +319,13 @@ function MoneyReportHeader({ payMoneyRequest(type, chatReport, moneyRequestReport, true); } }, - [chatReport, isAnyTransactionOnHold, isDelegateAccessRestricted, isInvoiceReport, moneyRequestReport, startAnimation], + [chatReport, isAnyTransactionOnHold, isDelegateAccessRestricted, showDelegateNoAccessModal, isInvoiceReport, moneyRequestReport, startAnimation], ); const confirmApproval = () => { setRequestType(CONST.IOU.REPORT_ACTION_TYPE.APPROVE); if (isDelegateAccessRestricted) { - setIsNoDelegateAccessMenuVisible(true); + showDelegateNoAccessModal(); } else if (isAnyTransactionOnHold) { setIsHoldMenuVisible(true); } else { @@ -705,7 +703,7 @@ function MoneyReportHeader({ value: CONST.REPORT.SECONDARY_ACTIONS.UNAPPROVE, onSelected: () => { if (isDelegateAccessRestricted) { - setIsNoDelegateAccessMenuVisible(true); + showDelegateNoAccessModal(); return; } @@ -1020,10 +1018,6 @@ function MoneyReportHeader({ transactionCount={transactionIDs?.length ?? 0} /> )} - setIsNoDelegateAccessMenuVisible(false)} - /> isWaitingForSubmissionFromCurrentUserReportUtils(chatReport, policy), [chatReport, policy]); - const [isNoDelegateAccessMenuVisible, setIsNoDelegateAccessMenuVisible] = useState(false); + const {isDelegateAccessRestricted, showDelegateNoAccessModal} = useContext(DelegateNoAccessContext); const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`, {canBeMissing: true}); const confirmPayment = useCallback( (type: PaymentMethodType | undefined, payAsBusiness?: boolean) => { @@ -200,7 +199,7 @@ function MoneyRequestReportPreviewContent({ setPaymentType(type); setRequestType(CONST.IOU.REPORT_ACTION_TYPE.PAY); if (isDelegateAccessRestricted) { - setIsNoDelegateAccessMenuVisible(true); + showDelegateNoAccessModal(); } else if (hasHeldExpensesReportUtils(iouReport?.reportID)) { setIsHoldMenuVisible(true); } else if (chatReport && iouReport) { @@ -212,13 +211,13 @@ function MoneyRequestReportPreviewContent({ } } }, - [chatReport, iouReport, isDelegateAccessRestricted, startAnimation], + [chatReport, iouReport, isDelegateAccessRestricted, showDelegateNoAccessModal, startAnimation], ); const confirmApproval = () => { setRequestType(CONST.IOU.REPORT_ACTION_TYPE.APPROVE); if (isDelegateAccessRestricted) { - setIsNoDelegateAccessMenuVisible(true); + showDelegateNoAccessModal(); } else if (hasHeldExpensesReportUtils(iouReport?.reportID)) { setIsHoldMenuVisible(true); } else { @@ -767,10 +766,6 @@ function MoneyRequestReportPreviewContent({ - setIsNoDelegateAccessMenuVisible(false)} - /> {isHoldMenuVisible && !!iouReport && !!requestType && ( (0); @@ -125,7 +123,6 @@ function MoneyRequestReportPreview({ invoiceReceiverPersonalDetail={invoiceReceiverPersonalDetail} invoiceReceiverPolicy={invoiceReceiverPolicy} lastTransactionViolations={lastTransactionViolations} - isDelegateAccessRestricted={isDelegateAccessRestricted} renderTransactionItem={renderItem} onCarouselLayout={(e: LayoutChangeEvent) => { setCurrentWidth(e.nativeEvent.layout.width); diff --git a/src/components/ReportActionItem/MoneyRequestReportPreview/types.ts b/src/components/ReportActionItem/MoneyRequestReportPreview/types.ts index 922b910ddb1b6..cf9c6bf59178f 100644 --- a/src/components/ReportActionItem/MoneyRequestReportPreview/types.ts +++ b/src/components/ReportActionItem/MoneyRequestReportPreview/types.ts @@ -67,7 +67,6 @@ type MoneyRequestReportPreviewContentOnyxProps = { policy: OnyxEntry; invoiceReceiverPersonalDetail: OnyxEntry; lastTransactionViolations: TransactionViolations; - isDelegateAccessRestricted: boolean; }; type MoneyRequestReportPreviewContentProps = MoneyRequestReportPreviewContentOnyxProps & diff --git a/src/hooks/useDelegateUserDetails.ts b/src/hooks/useDelegateUserDetails.ts deleted file mode 100644 index 6e90f2906277d..0000000000000 --- a/src/hooks/useDelegateUserDetails.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {useOnyx} from 'react-native-onyx'; -import AccountUtils from '@libs/AccountUtils'; -import ONYXKEYS from '@src/ONYXKEYS'; -import useCurrentUserPersonalDetails from './useCurrentUserPersonalDetails'; - -function useDelegateUserDetails() { - const currentUserDetails = useCurrentUserPersonalDetails(); - const [currentUserAccountDetails] = useOnyx(ONYXKEYS.ACCOUNT); - const isDelegateAccessRestricted = AccountUtils.isDelegateOnlySubmitter(currentUserAccountDetails); - const delegatorEmail = currentUserDetails?.login; - - return { - isDelegateAccessRestricted, - delegatorEmail, - }; -} - -export default useDelegateUserDetails; diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.tsx b/src/libs/Navigation/AppNavigator/AuthScreens.tsx index 8b7896f1f3f4c..59aaeb3acf7ee 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.tsx +++ b/src/libs/Navigation/AppNavigator/AuthScreens.tsx @@ -4,6 +4,7 @@ import React, {memo, useEffect, useMemo, useRef, useState} from 'react'; import type {OnyxEntry} from 'react-native-onyx'; import Onyx, {useOnyx, withOnyx} from 'react-native-onyx'; import ComposeProviders from '@components/ComposeProviders'; +import DelegateNoAccessModalProvider from '@components/DelegateNoAccessModalProvider'; import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import LockedAccountModalProvider from '@components/LockedAccountModalProvider'; import OptionsListContextProvider from '@components/OptionListContextProvider'; @@ -539,7 +540,7 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie } return ( - + {/* This has to be the first navigator in auth screens. */} { if (isDelegateAccessRestricted) { close(() => { - setIsNoDelegateAccessMenuVisible(true); + showDelegateNoAccessModal(); }); return; } @@ -199,7 +197,7 @@ function AttachmentPickerWithMenuItems({ })); return moneyRequestOptionsList.filter((item, index, self) => index === self.findIndex((t) => t.text === item.text)); - }, [translate, shouldUseNarrowLayout, report, policy, reportParticipantIDs, selectOption, isDelegateAccessRestricted]); + }, [translate, shouldUseNarrowLayout, report, policy, reportParticipantIDs, selectOption, isDelegateAccessRestricted, showDelegateNoAccessModal]); const createReportOption: PopoverMenuItem[] = useMemo(() => { if (!isPolicyExpenseChat(report) || !isPaidGroupPolicy(report) || !isReportOwner(report)) { @@ -414,10 +412,6 @@ function AttachmentPickerWithMenuItems({ withoutOverlay anchorRef={actionButtonRef} /> - setIsNoDelegateAccessMenuVisible(false)} - /> ); }} diff --git a/src/pages/settings/Profile/Contacts/ContactMethodDetailsPage.tsx b/src/pages/settings/Profile/Contacts/ContactMethodDetailsPage.tsx index 93042bce02b95..6de3aa90fe6df 100644 --- a/src/pages/settings/Profile/Contacts/ContactMethodDetailsPage.tsx +++ b/src/pages/settings/Profile/Contacts/ContactMethodDetailsPage.tsx @@ -4,7 +4,7 @@ import {InteractionManager, Keyboard} from 'react-native'; import {useOnyx} from 'react-native-onyx'; import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; import ConfirmModal from '@components/ConfirmModal'; -import DelegateNoAccessModal from '@components/DelegateNoAccessModal'; +import {DelegateNoAccessContext} from '@components/DelegateNoAccessModalProvider'; import ErrorMessageRow from '@components/ErrorMessageRow'; import FullscreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; @@ -58,8 +58,7 @@ function ContactMethodDetailsPage({route}: ContactMethodDetailsPageProps) { const [securityGroups, securityGroupsResult] = useOnyx(ONYXKEYS.COLLECTION.SECURITY_GROUP, {canBeMissing: true}); const [isLoadingReportData, isLoadingReportDataResult] = useOnyx(ONYXKEYS.IS_LOADING_REPORT_DATA, {initialValue: true, canBeMissing: true}); const [isValidateCodeFormVisible, setIsValidateCodeFormVisible] = useState(true); - const [isActingAsDelegate] = useOnyx(ONYXKEYS.ACCOUNT, {selector: (account) => !!account?.delegatedAccess?.delegate, canBeMissing: true}); - const [isNoDelegateAccessMenuVisible, setIsNoDelegateAccessMenuVisible] = useState(false); + const {isActingAsDelegate, showDelegateNoAccessModal} = useContext(DelegateNoAccessContext); const isLoadingOnyxValues = isLoadingOnyxValue(loginListResult, sessionResult, myDomainSecurityGroupsResult, securityGroupsResult, isLoadingReportDataResult); const {isAccountLocked, showLockedAccountModal} = useContext(LockedAccountContext); @@ -271,7 +270,7 @@ function ContactMethodDetailsPage({route}: ContactMethodDetailsPageProps) { iconFill={theme.danger} onPress={() => { if (isActingAsDelegate) { - setIsNoDelegateAccessMenuVisible(true); + showDelegateNoAccessModal(); return; } if (isAccountLocked) { @@ -361,10 +360,6 @@ function ContactMethodDetailsPage({route}: ContactMethodDetailsPageProps) { {!isValidateCodeFormVisible && !!loginData.validatedDate && getMenuItems()} {getDeleteConfirmationModal()} - setIsNoDelegateAccessMenuVisible(false)} - /> ); } diff --git a/src/pages/settings/Profile/Contacts/ContactMethodsPage.tsx b/src/pages/settings/Profile/Contacts/ContactMethodsPage.tsx index 433656a1fdfb3..0bdd2b31544c1 100644 --- a/src/pages/settings/Profile/Contacts/ContactMethodsPage.tsx +++ b/src/pages/settings/Profile/Contacts/ContactMethodsPage.tsx @@ -1,10 +1,10 @@ import {Str} from 'expensify-common'; -import React, {useCallback, useContext, useState} from 'react'; +import React, {useCallback, useContext} from 'react'; import {View} from 'react-native'; import {useOnyx} from 'react-native-onyx'; import Button from '@components/Button'; import CopyTextToClipboard from '@components/CopyTextToClipboard'; -import DelegateNoAccessModal from '@components/DelegateNoAccessModal'; +import {DelegateNoAccessContext} from '@components/DelegateNoAccessModalProvider'; import FixedFooter from '@components/FixedFooter'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import {LockedAccountContext} from '@components/LockedAccountModalProvider'; @@ -34,9 +34,7 @@ function ContactMethodsPage({route}: ContactMethodsPageProps) { const loginNames = Object.keys(loginList ?? {}); const navigateBackTo = route?.params?.backTo; - const [isActingAsDelegate] = useOnyx(ONYXKEYS.ACCOUNT, {selector: (account) => !!account?.delegatedAccess?.delegate, canBeMissing: false}); - const [isNoDelegateAccessMenuVisible, setIsNoDelegateAccessMenuVisible] = useState(false); - + const {isActingAsDelegate, showDelegateNoAccessModal} = useContext(DelegateNoAccessContext); const [isUserValidated] = useOnyx(ONYXKEYS.ACCOUNT, {selector: (account) => account?.validated, canBeMissing: false}); const {isAccountLocked, showLockedAccountModal} = useContext(LockedAccountContext); @@ -94,7 +92,7 @@ function ContactMethodsPage({route}: ContactMethodsPageProps) { const onNewContactMethodButtonPress = useCallback(() => { if (isActingAsDelegate) { - setIsNoDelegateAccessMenuVisible(true); + showDelegateNoAccessModal(); return; } if (isAccountLocked) { @@ -108,7 +106,7 @@ function ContactMethodsPage({route}: ContactMethodsPageProps) { } Navigation.navigate(ROUTES.SETTINGS_NEW_CONTACT_METHOD.getRoute(navigateBackTo)); - }, [navigateBackTo, isActingAsDelegate, isAccountLocked, isUserValidated, showLockedAccountModal]); + }, [navigateBackTo, isActingAsDelegate, showDelegateNoAccessModal, isAccountLocked, isUserValidated, showLockedAccountModal]); return ( - setIsNoDelegateAccessMenuVisible(false)} - /> ); } diff --git a/src/pages/settings/Profile/ProfilePage.tsx b/src/pages/settings/Profile/ProfilePage.tsx index d33bd317ac15b..681514cf10ca8 100755 --- a/src/pages/settings/Profile/ProfilePage.tsx +++ b/src/pages/settings/Profile/ProfilePage.tsx @@ -1,11 +1,11 @@ import {useRoute} from '@react-navigation/native'; -import React, {useState} from 'react'; +import React, {useContext} from 'react'; import {View} from 'react-native'; import {useOnyx} from 'react-native-onyx'; import AvatarSkeleton from '@components/AvatarSkeleton'; import AvatarWithImagePicker from '@components/AvatarWithImagePicker'; import Button from '@components/Button'; -import DelegateNoAccessModal from '@components/DelegateNoAccessModal'; +import {DelegateNoAccessContext} from '@components/DelegateNoAccessModalProvider'; import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import * as Expensicons from '@components/Icon/Expensicons'; @@ -64,9 +64,7 @@ function ProfilePage() { const privateDetails = privatePersonalDetails ?? {}; const legalName = `${privateDetails.legalFirstName ?? ''} ${privateDetails.legalLastName ?? ''}`.trim(); - const [isActingAsDelegate] = useOnyx(ONYXKEYS.ACCOUNT, {selector: (account) => !!account?.delegatedAccess?.delegate, canBeMissing: false}); - const [isNoDelegateAccessMenuVisible, setIsNoDelegateAccessMenuVisible] = useState(false); - + const {isActingAsDelegate, showDelegateNoAccessModal} = useContext(DelegateNoAccessContext); const publicOptions = [ { description: translate('displayNamePage.headerTitle'), @@ -102,7 +100,7 @@ function ProfilePage() { title: legalName, action: () => { if (isActingAsDelegate) { - setIsNoDelegateAccessMenuVisible(true); + showDelegateNoAccessModal(); return; } Navigation.navigate(ROUTES.SETTINGS_LEGAL_NAME); @@ -113,7 +111,7 @@ function ProfilePage() { title: privateDetails.dob ?? '', action: () => { if (isActingAsDelegate) { - setIsNoDelegateAccessMenuVisible(true); + showDelegateNoAccessModal(); return; } Navigation.navigate(ROUTES.SETTINGS_DATE_OF_BIRTH); @@ -124,7 +122,7 @@ function ProfilePage() { title: privateDetails.phoneNumber ?? '', action: () => { if (isActingAsDelegate) { - setIsNoDelegateAccessMenuVisible(true); + showDelegateNoAccessModal(); return; } Navigation.navigate(ROUTES.SETTINGS_PHONE_NUMBER); @@ -136,7 +134,7 @@ function ProfilePage() { title: getFormattedAddress(privateDetails), action: () => { if (isActingAsDelegate) { - setIsNoDelegateAccessMenuVisible(true); + showDelegateNoAccessModal(); return; } Navigation.navigate(ROUTES.SETTINGS_ADDRESS); @@ -256,10 +254,6 @@ function ProfilePage() { - setIsNoDelegateAccessMenuVisible(false)} - /> ); } diff --git a/src/pages/settings/Security/SecuritySettingsPage.tsx b/src/pages/settings/Security/SecuritySettingsPage.tsx index 4d7b85d8a6b10..eb743588b4da4 100644 --- a/src/pages/settings/Security/SecuritySettingsPage.tsx +++ b/src/pages/settings/Security/SecuritySettingsPage.tsx @@ -5,7 +5,7 @@ import {Dimensions, View} from 'react-native'; import type {GestureResponderEvent, StyleProp, ViewStyle} from 'react-native'; import {useOnyx} from 'react-native-onyx'; import ConfirmModal from '@components/ConfirmModal'; -import DelegateNoAccessModal from '@components/DelegateNoAccessModal'; +import {DelegateNoAccessContext} from '@components/DelegateNoAccessModalProvider'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import * as Expensicons from '@components/Icon/Expensicons'; import {FallbackAvatar} from '@components/Icon/Expensicons'; @@ -80,9 +80,7 @@ function SecuritySettingsPage() { }); const {isAccountLocked, showLockedAccountModal} = useContext(LockedAccountContext); - const isActingAsDelegate = !!account?.delegatedAccess?.delegate || false; - const [isNoDelegateAccessMenuVisible, setIsNoDelegateAccessMenuVisible] = useState(false); - + const {isActingAsDelegate, showDelegateNoAccessModal} = useContext(DelegateNoAccessContext); const delegates = account?.delegatedAccess?.delegates ?? []; const delegators = account?.delegatedAccess?.delegators ?? []; @@ -109,9 +107,6 @@ function SecuritySettingsPage() { setSelectedEmail(delegate.email); }; - const showDelegateNoAccessMenu = () => { - setIsNoDelegateAccessMenuVisible(true); - }; useLayoutEffect(() => { const popoverPositionListener = Dimensions.addEventListener('change', () => { debounce(setMenuPosition, CONST.TIMING.RESIZE_DEBOUNCE_TIME)(); @@ -132,7 +127,7 @@ function SecuritySettingsPage() { icon: Expensicons.Shield, action: () => { if (isActingAsDelegate) { - showDelegateNoAccessMenu(); + showDelegateNoAccessModal(); return; } if (isAccountLocked) { @@ -150,7 +145,7 @@ function SecuritySettingsPage() { icon: Expensicons.ArrowCollapse, action: () => { if (isActingAsDelegate) { - showDelegateNoAccessMenu(); + showDelegateNoAccessModal(); return; } if (isAccountLocked) { @@ -181,7 +176,7 @@ function SecuritySettingsPage() { icon: Expensicons.ClosedSign, action: () => { if (isActingAsDelegate) { - showDelegateNoAccessMenu(); + showDelegateNoAccessModal(); return; } @@ -201,7 +196,7 @@ function SecuritySettingsPage() { link: '', wrapperStyle: [styles.sectionMenuItemTopDescription], })); - }, [translate, waitForNavigate, styles, isActingAsDelegate, isBetaEnabled, isAccountLocked, showLockedAccountModal]); + }, [translate, waitForNavigate, styles, isActingAsDelegate, showDelegateNoAccessModal, isBetaEnabled, isAccountLocked, showLockedAccountModal]); const delegateMenuItems: MenuItemProps[] = useMemo( () => @@ -281,7 +276,7 @@ function SecuritySettingsPage() { icon: Expensicons.Pencil, onPress: () => { if (isActingAsDelegate) { - modalClose(() => setIsNoDelegateAccessMenuVisible(true)); + modalClose(() => showDelegateNoAccessModal()); return; } if (isAccountLocked) { @@ -299,7 +294,7 @@ function SecuritySettingsPage() { icon: Expensicons.Trashcan, onPress: () => { if (isActingAsDelegate) { - modalClose(() => setIsNoDelegateAccessMenuVisible(true)); + modalClose(() => showDelegateNoAccessModal()); return; } if (isAccountLocked) { @@ -441,10 +436,6 @@ function SecuritySettingsPage() { /> - setIsNoDelegateAccessMenuVisible(false)} - /> )} diff --git a/src/pages/settings/Subscription/CardSection/CardSectionDataEmpty/index.tsx b/src/pages/settings/Subscription/CardSection/CardSectionDataEmpty/index.tsx index 79a200c4772ca..71c6c8da64923 100644 --- a/src/pages/settings/Subscription/CardSection/CardSectionDataEmpty/index.tsx +++ b/src/pages/settings/Subscription/CardSection/CardSectionDataEmpty/index.tsx @@ -1,43 +1,34 @@ -import React, {useCallback, useState} from 'react'; -import {useOnyx} from 'react-native-onyx'; +import React, {useCallback, useContext} from 'react'; import Button from '@components/Button'; -import DelegateNoAccessModal from '@components/DelegateNoAccessModal'; +import {DelegateNoAccessContext} from '@components/DelegateNoAccessModalProvider'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@navigation/Navigation'; -import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; function CardSectionDataEmpty() { const {translate} = useLocalize(); const styles = useThemeStyles(); - const [isActingAsDelegate] = useOnyx(ONYXKEYS.ACCOUNT, {selector: (account) => account?.delegatedAccess?.delegate}); - const [isNoDelegateAccessMenuVisible, setIsNoDelegateAccessMenuVisible] = useState(false); + const {isActingAsDelegate, showDelegateNoAccessModal} = useContext(DelegateNoAccessContext); const openAddPaymentCardScreen = useCallback(() => { Navigation.navigate(ROUTES.SETTINGS_SUBSCRIPTION_ADD_PAYMENT_CARD); }, []); const handleAddPaymentCardPress = () => { if (isActingAsDelegate) { - setIsNoDelegateAccessMenuVisible(true); + showDelegateNoAccessModal(); return; } openAddPaymentCardScreen(); }; return ( - <> -