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
10 changes: 10 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,
threeDotsMenuItems = [],
onThreeDotsButtonPress = () => {},
}: 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,11 @@ function ValidateCodeActionModal({
<HeaderWithBackButton
title={title}
onBackButtonPress={hide}
threeDotsMenuItems={threeDotsMenuItems}
shouldShowThreeDotsButton={threeDotsMenuItems.length > 0}
shouldOverlayDots
threeDotsAnchorPosition={styles.threeDotsPopoverOffset(windowWidth)}
onThreeDotsButtonPress={onThreeDotsButtonPress}
/>

<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[];

/** Method to trigger when pressing more options button of the header */
onThreeDotsButtonPress?: () => void;
};

// eslint-disable-next-line import/prefer-default-export
Expand Down
58 changes: 42 additions & 16 deletions src/pages/settings/Profile/Contacts/ContactMethodDetailsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,22 @@ 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';
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<SettingsNavigatorParamList, typeof SCREENS.SETTINGS.PROFILE.CONTACT_METHOD_DETAILS>;
Expand Down Expand Up @@ -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 <FullscreenLoadingIndicator />;
}
Expand All @@ -177,6 +192,24 @@ function ContactMethodDetailsPage({route}: ContactMethodDetailsPageProps) {
const isFailedAddContactMethod = !!loginData.errorFields?.addedLogin;
const isFailedRemovedContactMethod = !!loginData.errorFields?.deletedLogin;

const getDeleteConfirmationModal = () => (
<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
/>
);

const getMenuItems = () => (
<>
{canChangeDefaultContactMethod ? (
Expand Down Expand Up @@ -216,22 +249,7 @@ 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
/>
{getDeleteConfirmationModal()}
</>
);

Expand Down Expand Up @@ -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()}
Expand Down
Loading