diff --git a/src/components/ValidateCodeActionModal/index.tsx b/src/components/ValidateCodeActionModal/index.tsx index c25401d33494..53d781997d44 100644 --- a/src/components/ValidateCodeActionModal/index.tsx +++ b/src/components/ValidateCodeActionModal/index.tsx @@ -6,6 +6,7 @@ import Modal from '@components/Modal'; import ScreenWrapper from '@components/ScreenWrapper'; import Text from '@components/Text'; import useThemeStyles from '@hooks/useThemeStyles'; +import useWindowDimensions from '@hooks/useWindowDimensions'; import Navigation from '@libs/Navigation/Navigation'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -29,10 +30,14 @@ function ValidateCodeActionModal({ hasMagicCodeBeenSent, isLoading, shouldHandleNavigationBack, + threeDotsMenuItems = [], + onThreeDotsButtonPress = () => {}, }: ValidateCodeActionModalProps) { const themeStyles = useThemeStyles(); const firstRenderRef = useRef(true); const validateCodeFormRef = useRef(null); + const styles = useThemeStyles(); + const {windowWidth} = useWindowDimensions(); const [validateCodeAction] = useOnyx(ONYXKEYS.VALIDATE_ACTION_CODE); @@ -76,6 +81,11 @@ function ValidateCodeActionModal({ 0} + shouldOverlayDots + threeDotsAnchorPosition={styles.threeDotsPopoverOffset(windowWidth)} + onThreeDotsButtonPress={onThreeDotsButtonPress} /> diff --git a/src/components/ValidateCodeActionModal/type.ts b/src/components/ValidateCodeActionModal/type.ts index aed82f0fa525..4f70870ead3c 100644 --- a/src/components/ValidateCodeActionModal/type.ts +++ b/src/components/ValidateCodeActionModal/type.ts @@ -1,4 +1,5 @@ import type React from 'react'; +import type {PopoverMenuItem} from '@components/PopoverMenu'; import type {Errors, PendingAction} from '@src/types/onyx/OnyxCommon'; type ValidateCodeActionModalProps = { @@ -46,6 +47,12 @@ type ValidateCodeActionModalProps = { /** Whether handle navigation back when modal show. */ shouldHandleNavigationBack?: boolean; + + /** List of menu items for more(three dots) menu */ + threeDotsMenuItems?: PopoverMenuItem[]; + + /** Method to trigger when pressing more options button of the header */ + onThreeDotsButtonPress?: () => void; }; // eslint-disable-next-line import/prefer-default-export diff --git a/src/pages/settings/Profile/Contacts/ContactMethodDetailsPage.tsx b/src/pages/settings/Profile/Contacts/ContactMethodDetailsPage.tsx index e94042b25e68..37fc4d26c7f4 100644 --- a/src/pages/settings/Profile/Contacts/ContactMethodDetailsPage.tsx +++ b/src/pages/settings/Profile/Contacts/ContactMethodDetailsPage.tsx @@ -19,12 +19,14 @@ import useLocalize from '@hooks/useLocalize'; import usePrevious from '@hooks/usePrevious'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; +import blurActiveElement from '@libs/Accessibility/blurActiveElement'; import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import * as ErrorUtils from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types'; import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; import {addSMSDomainIfPhoneNumber} from '@libs/PhoneNumber'; +import * as Modal from '@userActions/Modal'; import * as User from '@userActions/User'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -32,6 +34,7 @@ import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue'; +import KeyboardUtils from '@src/utils/keyboard'; import type {ValidateCodeFormHandle} from './ValidateCodeForm/BaseValidateCodeForm'; type ContactMethodDetailsPageProps = PlatformStackScreenProps; @@ -154,6 +157,18 @@ function ContactMethodDetailsPage({route}: ContactMethodDetailsPageProps) { setIsValidateCodeActionModalVisible(!loginData?.validatedDate); }, [loginData?.validatedDate, loginData?.errorFields?.addedLogin]); + const getThreeDotsMenuItems = useCallback(() => { + const menuItems = []; + if (isValidateCodeActionModalVisible && !isDefaultContactMethod) { + menuItems.push({ + icon: Expensicons.Trashcan, + text: translate('common.remove'), + onSelected: () => Modal.close(() => toggleDeleteModal(true)), + }); + } + return menuItems; + }, [isValidateCodeActionModalVisible, translate, toggleDeleteModal, isDefaultContactMethod]); + if (isLoadingOnyxValues || (isLoadingReportData && isEmptyObject(loginList))) { return ; } @@ -177,6 +192,24 @@ function ContactMethodDetailsPage({route}: ContactMethodDetailsPageProps) { const isFailedAddContactMethod = !!loginData.errorFields?.addedLogin; const isFailedRemovedContactMethod = !!loginData.errorFields?.deletedLogin; + const getDeleteConfirmationModal = () => ( + toggleDeleteModal(false)} + onModalHide={() => { + InteractionManager.runAfterInteractions(() => { + validateCodeFormRef.current?.focusLastSelected?.(); + }); + }} + prompt={translate('contacts.removeAreYouSure')} + confirmText={translate('common.yesContinue')} + cancelText={translate('common.cancel')} + isVisible={isDeleteModalOpen && !isDefaultContactMethod} + danger + /> + ); + const getMenuItems = () => ( <> {canChangeDefaultContactMethod ? ( @@ -216,22 +249,7 @@ function ContactMethodDetailsPage({route}: ContactMethodDetailsPageProps) { /> )} - - toggleDeleteModal(false)} - onModalHide={() => { - InteractionManager.runAfterInteractions(() => { - validateCodeFormRef.current?.focusLastSelected?.(); - }); - }} - prompt={translate('contacts.removeAreYouSure')} - confirmText={translate('common.yesContinue')} - cancelText={translate('common.cancel')} - isVisible={isDeleteModalOpen && !isDefaultContactMethod} - danger - /> + {getDeleteConfirmationModal()} ); @@ -273,6 +291,14 @@ function ContactMethodDetailsPage({route}: ContactMethodDetailsPageProps) { }} sendValidateCode={() => User.requestContactMethodValidateCode(contactMethod)} descriptionPrimary={translate('contacts.enterMagicCode', {contactMethod: formattedContactMethod})} + onThreeDotsButtonPress={() => { + // Hide the keyboard when the user clicks the three-dot menu. + // Use blurActiveElement() for mWeb and KeyboardUtils.dismiss() for native apps. + blurActiveElement(); + KeyboardUtils.dismiss(); + }} + threeDotsMenuItems={getThreeDotsMenuItems()} + footer={getDeleteConfirmationModal} /> {!isValidateCodeActionModalVisible && getMenuItems()}