Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add feature to delete unverified contact methods #54784

Merged
merged 9 commits into from
Jan 13, 2025
Merged
9 changes: 9 additions & 0 deletions src/components/ValidateCodeActionModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -29,10 +30,14 @@ function ValidateCodeActionModal({
hasMagicCodeBeenSent,
isLoading,
shouldHandleNavigationBack,
shouldShowThreeDotsButton = false,
Copy link
Contributor

Choose a reason for hiding this comment

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

Can the value of this prop be determined by the length of threeDotsMenuItems? ie. it should be TRUE when there are items in the array and FALSE when there are no items in the array? It seems unnecessary to have the shouldShowThreeDotsButton prop.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Got it, I’ll update it based on threeDotsMenuItems.length as
shouldShowThreeDotsButton={threeDotsMenuItems.length>0}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@tgolen , after looking at it again, I realized that the three-dot menu only shows when the contact is not primary and not verified. If I use the threeDotsMenuItems.length>0, it would always show the button, so I guess we need this prop.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK. If I follow that logic though, if the menu is not shown, why would it need to have any menu items at all? I would say, remove the menu items based on the contact is not primary and not verified and it should still work the same. Right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, we can do that as well.
I added the shouldShowThreeDotsButton prop because it was already available in the props for the ThreeDotsMenu and HeaderWithBackButton
It seems we could use the same logic there as well, but that would need to update the threeDotsMenuItems in different pages

threeDotsMenuItems = [],
}: ValidateCodeActionModalProps) {
const themeStyles = useThemeStyles();
const firstRenderRef = useRef(true);
const validateCodeFormRef = useRef<ValidateCodeFormHandle>(null);
const styles = useThemeStyles();
const {windowWidth} = useWindowDimensions();

const [validateCodeAction] = useOnyx(ONYXKEYS.VALIDATE_ACTION_CODE);

Expand Down Expand Up @@ -76,6 +81,10 @@ function ValidateCodeActionModal({
<HeaderWithBackButton
title={title}
onBackButtonPress={hide}
threeDotsMenuItems={threeDotsMenuItems}
shouldShowThreeDotsButton={shouldShowThreeDotsButton}
shouldOverlayDots
threeDotsAnchorPosition={styles.threeDotsPopoverOffset(windowWidth)}
/>

<View style={[themeStyles.ph5, themeStyles.mt3, themeStyles.mb5, themeStyles.flex1]}>
Expand Down
7 changes: 7 additions & 0 deletions src/components/ValidateCodeActionModal/type.ts
Original file line number Diff line number Diff line change
@@ -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 = {
Expand Down Expand Up @@ -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[];

/** Whether we should show a more options (threedots) button */
shouldShowThreeDotsButton?: boolean;
};

// eslint-disable-next-line import/prefer-default-export
Expand Down
59 changes: 41 additions & 18 deletions src/pages/settings/Profile/Contacts/ContactMethodDetailsPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Str} from 'expensify-common';
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
import {InteractionManager, Keyboard} from 'react-native';
import {InteractionManager, Keyboard, Platform} from 'react-native';
import {useOnyx} from 'react-native-onyx';
import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView';
import ConfirmModal from '@components/ConfirmModal';
Expand Down Expand Up @@ -216,22 +216,6 @@ function ContactMethodDetailsPage({route}: ContactMethodDetailsPageProps) {
/>
</OfflineWithFeedback>
)}

<ConfirmModal
title={translate('contacts.removeContactMethod')}
onConfirm={confirmDeleteAndHideModal}
onCancel={() => toggleDeleteModal(false)}
onModalHide={() => {
InteractionManager.runAfterInteractions(() => {
validateCodeFormRef.current?.focusLastSelected?.();
});
}}
prompt={translate('contacts.removeAreYouSure')}
confirmText={translate('common.yesContinue')}
cancelText={translate('common.cancel')}
isVisible={isDeleteModalOpen && !isDefaultContactMethod}
danger
/>
</>
);

Expand Down Expand Up @@ -273,9 +257,48 @@ function ContactMethodDetailsPage({route}: ContactMethodDetailsPageProps) {
}}
sendValidateCode={() => User.requestContactMethodValidateCode(contactMethod)}
descriptionPrimary={translate('contacts.enterMagicCode', {contactMethod: formattedContactMethod})}
threeDotsMenuItems={[
{
icon: Expensicons.Trashcan,
text: translate('common.remove'),
onSelected: () => {
if (Platform.OS === 'ios') {
setIsValidateCodeActionModalVisible(false);
}
toggleDeleteModal(true);
},
},
]}
shouldShowThreeDotsButton={isValidateCodeActionModalVisible}
/>

{!isValidateCodeActionModalVisible && getMenuItems()}
{!isValidateCodeActionModalVisible && !!loginData && !!loginData.validatedDate && getMenuItems()}
<ConfirmModal
title={translate('contacts.removeContactMethod')}
onConfirm={confirmDeleteAndHideModal}
onCancel={() => {
toggleDeleteModal(false);
// On iOS, if the secondary login is not validated, reopen the ValidateCodeActionModal
if (Platform.OS === 'ios' && !!loginData && !loginData.validatedDate) {
// Ensure the ConfirmModal is fully closed before showing the ValidateCodeActionModal
InteractionManager.runAfterInteractions(() => {
setTimeout(() => {
setIsValidateCodeActionModalVisible(true);
}, 0);
});
}
}}
onModalHide={() => {
InteractionManager.runAfterInteractions(() => {
validateCodeFormRef.current?.focusLastSelected?.();
});
}}
prompt={translate('contacts.removeAreYouSure')}
confirmText={translate('common.yesContinue')}
cancelText={translate('common.cancel')}
isVisible={isDeleteModalOpen && !isDefaultContactMethod}
danger
/>
</ScrollView>
</ScreenWrapper>
);
Expand Down
Loading