From 29dcc711e4553d083ecbd85256ba6809b413b710 Mon Sep 17 00:00:00 2001
From: nkdengineer <nkdengineer@outlook.com>
Date: Thu, 11 Dec 2025 16:32:18 +0700
Subject: [PATCH 1/4] Refactor ConfirmModal usage to useConfirmModal in IOU

---
 .../step/IOURequestStepConfirmation.tsx       | 34 ++++++++-------
 .../IOURequestStepScan/ReceiptView/index.tsx  | 42 +++++++++----------
 .../request/step/IOURequestStepSubrate.tsx    | 42 +++++++++----------
 .../request/step/IOURequestStepWaypoint.tsx   | 42 +++++++++----------
 4 files changed, 77 insertions(+), 83 deletions(-)

diff --git a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx
index 21fead678f19..82702a5e993b 100644
--- a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx
+++ b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx
@@ -2,18 +2,19 @@ import reportsSelector from '@selectors/Attributes';
 import {transactionDraftValuesSelector} from '@selectors/TransactionDraft';
 import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
 import {View} from 'react-native';
-import ConfirmModal from '@components/ConfirmModal';
 import DragAndDropConsumer from '@components/DragAndDrop/Consumer';
 import DragAndDropProvider from '@components/DragAndDrop/Provider';
 import DropZoneUI from '@components/DropZone/DropZoneUI';
 import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator';
 import HeaderWithBackButton from '@components/HeaderWithBackButton';
 import LocationPermissionModal from '@components/LocationPermissionModal';
+import {ModalActions} from '@components/Modal/Global/ModalContext';
 import MoneyRequestConfirmationList from '@components/MoneyRequestConfirmationList';
 import {usePersonalDetails, usePolicyCategories} from '@components/OnyxListItemProvider';
 import PrevNextButtons from '@components/PrevNextButtons';
 import ScreenWrapper from '@components/ScreenWrapper';
 import useArchivedReportsIdSet from '@hooks/useArchivedReportsIdSet';
+import useConfirmModal from '@hooks/useConfirmModal';
 import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
 import useDeepCompareRef from '@hooks/useDeepCompareRef';
 import useFetchRoute from '@hooks/useFetchRoute';
@@ -127,7 +128,6 @@ function IOURequestStepConfirmation({
     const personalDetails = usePersonalDetails();
     const allPolicyCategories = usePolicyCategories();
 
-    const [isRemoveConfirmModalVisible, setRemoveConfirmModalVisible] = useState(false);
     const [optimisticTransactions] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_DRAFT, {
         selector: transactionDraftValuesSelector,
         canBeMissing: true,
@@ -230,6 +230,7 @@ function IOURequestStepConfirmation({
     const {translate} = useLocalize();
     const {isBetaEnabled} = usePermissions();
     const {isOffline} = useNetwork();
+    const {showConfirmModal} = useConfirmModal();
     const [startLocationPermissionFlow, setStartLocationPermissionFlow] = useState(false);
     const [selectedParticipantList, setSelectedParticipantList] = useState<Participant[]>([]);
     const [isDraggingOver, setIsDraggingOver] = useState(false);
@@ -1238,15 +1239,28 @@ function IOURequestStepConfirmation({
         if (currentTransactionID === CONST.IOU.OPTIMISTIC_TRANSACTION_ID) {
             const nextTransaction = transactions.at(currentTransactionIndex + 1);
             replaceDefaultDraftTransaction(nextTransaction);
-            setRemoveConfirmModalVisible(false);
             return;
         }
 
         removeDraftTransaction(currentTransactionID);
-        setRemoveConfirmModalVisible(false);
         showPreviousTransaction();
     };
 
+    const confirmRemoveCurrentTransaction = () => {
+        showConfirmModal({
+            title: translate('iou.removeExpense'),
+            prompt: translate('iou.removeExpenseConfirmation'),
+            confirmText: translate('common.remove'),
+            cancelText: translate('common.cancel'),
+            danger: true,
+        }).then((result) => {
+            if (result.action !== ModalActions.CONFIRM) {
+                return;
+            }
+            removeCurrentTransaction();
+        });
+    };
+
     const showReceiptEmptyState = shouldShowReceiptEmptyState(iouType, action, policy, isPerDiemRequest);
 
     const shouldShowSmartScanFields =
@@ -1321,7 +1335,7 @@ function IOURequestStepConfirmation({
                         iouCategory={transaction?.category}
                         onConfirm={onConfirm}
                         onSendMoney={sendMoney}
-                        showRemoveExpenseConfirmModal={() => setRemoveConfirmModalVisible(true)}
+                        showRemoveExpenseConfirmModal={confirmRemoveCurrentTransaction}
                         receiptPath={receiptPath}
                         receiptFilename={receiptFilename}
                         iouType={iouType}
@@ -1344,16 +1358,6 @@ function IOURequestStepConfirmation({
                         isReceiptEditable
                     />
                 </View>
-                <ConfirmModal
-                    title={translate('iou.removeExpense')}
-                    isVisible={isRemoveConfirmModalVisible}
-                    onConfirm={removeCurrentTransaction}
-                    onCancel={() => setRemoveConfirmModalVisible(false)}
-                    prompt={translate('iou.removeExpenseConfirmation')}
-                    confirmText={translate('common.remove')}
-                    cancelText={translate('common.cancel')}
-                    danger
-                />
             </DragAndDropProvider>
         </ScreenWrapper>
     );
diff --git a/src/pages/iou/request/step/IOURequestStepScan/ReceiptView/index.tsx b/src/pages/iou/request/step/IOURequestStepScan/ReceiptView/index.tsx
index 0d5911ae63f5..e0626aa72eec 100644
--- a/src/pages/iou/request/step/IOURequestStepScan/ReceiptView/index.tsx
+++ b/src/pages/iou/request/step/IOURequestStepScan/ReceiptView/index.tsx
@@ -5,10 +5,11 @@ import AttachmentCarouselView from '@components/Attachments/AttachmentCarousel/A
 import useCarouselArrows from '@components/Attachments/AttachmentCarousel/useCarouselArrows';
 import useAttachmentErrors from '@components/Attachments/AttachmentView/useAttachmentErrors';
 import Button from '@components/Button';
-import ConfirmModal from '@components/ConfirmModal';
 import HeaderWithBackButton from '@components/HeaderWithBackButton';
-import * as Expensicons from '@components/Icon/Expensicons';
+import {ModalActions} from '@components/Modal/Global/ModalContext';
 import ScreenWrapper from '@components/ScreenWrapper';
+import useConfirmModal from '@hooks/useConfirmModal';
+import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useThemeStyles from '@hooks/useThemeStyles';
@@ -37,9 +38,10 @@ function ReceiptView({route}: ReceiptViewProps) {
     const {setAttachmentError} = useAttachmentErrors();
     const {shouldShowArrows, setShouldShowArrows, autoHideArrows, cancelAutoHideArrows} = useCarouselArrows();
     const styles = useThemeStyles();
+    const expensifyIcons = useMemoizedLazyExpensifyIcons(['Trashcan'] as const);
     const [currentReceipt, setCurrentReceipt] = useState<ReceiptWithTransactionIDAndSource | null>();
     const [page, setPage] = useState<number>(-1);
-    const [isDeleteReceiptConfirmModalVisible, setIsDeleteReceiptConfirmModalVisible] = useState(false);
+    const {showConfirmModal} = useConfirmModal();
 
     const [receipts = getEmptyArray<ReceiptWithTransactionIDAndSource>()] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_DRAFT, {
         selector: transactionDraftReceiptsViewSelector,
@@ -81,12 +83,7 @@ function ReceiptView({route}: ReceiptViewProps) {
         Navigation.goBack();
     }, [currentReceipt, receipts.length, secondTransaction, secondTransactionID]);
 
-    const handleCloseConfirmModal = () => {
-        setIsDeleteReceiptConfirmModalVisible(false);
-    };
-
     const deleteReceipt = useCallback(() => {
-        handleCloseConfirmModal();
         handleDeleteReceipt();
     }, [handleDeleteReceipt]);
 
@@ -103,12 +100,24 @@ function ReceiptView({route}: ReceiptViewProps) {
                 title={translate('common.receipt')}
                 shouldDisplayHelpButton={false}
                 onBackButtonPress={handleGoBack}
-                onCloseButtonPress={handleCloseConfirmModal}
             >
                 <Button
                     shouldShowRightIcon
-                    iconRight={Expensicons.Trashcan}
-                    onPress={() => setIsDeleteReceiptConfirmModalVisible(true)}
+                    iconRight={expensifyIcons.Trashcan}
+                    onPress={() => {
+                        showConfirmModal({
+                            title: translate('receipt.deleteReceipt'),
+                            prompt: translate('receipt.deleteConfirmation'),
+                            confirmText: translate('common.delete'),
+                            cancelText: translate('common.cancel'),
+                            danger: true,
+                        }).then((result) => {
+                            if (result.action !== ModalActions.CONFIRM) {
+                                return;
+                            }
+                            deleteReceipt();
+                        });
+                    }}
                     innerStyles={styles.bgTransparent}
                     large
                 />
@@ -126,17 +135,6 @@ function ReceiptView({route}: ReceiptViewProps) {
                 onAttachmentError={setAttachmentError}
                 shouldShowArrows={shouldShowArrows}
             />
-            <ConfirmModal
-                title={translate('receipt.deleteReceipt')}
-                isVisible={isDeleteReceiptConfirmModalVisible}
-                onConfirm={deleteReceipt}
-                onCancel={handleCloseConfirmModal}
-                prompt={translate('receipt.deleteConfirmation')}
-                confirmText={translate('common.delete')}
-                cancelText={translate('common.cancel')}
-                onBackdropPress={handleCloseConfirmModal}
-                danger
-            />
         </ScreenWrapper>
     );
 }
diff --git a/src/pages/iou/request/step/IOURequestStepSubrate.tsx b/src/pages/iou/request/step/IOURequestStepSubrate.tsx
index 9aa1da1dc9f7..adb9d8a79372 100644
--- a/src/pages/iou/request/step/IOURequestStepSubrate.tsx
+++ b/src/pages/iou/request/step/IOURequestStepSubrate.tsx
@@ -3,18 +3,18 @@ import React, {useCallback, useEffect, useRef, useState} from 'react';
 import {InteractionManager, View} from 'react-native';
 import type {OnyxEntry} from 'react-native-onyx';
 import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView';
-import ConfirmModal from '@components/ConfirmModal';
 import FormProvider from '@components/Form/FormProvider';
 import InputWrapperWithRef from '@components/Form/InputWrapper';
 import type {FormOnyxValues} from '@components/Form/types';
 import HeaderWithBackButton from '@components/HeaderWithBackButton';
-import * as Expensicons from '@components/Icon/Expensicons';
-import type BaseModalProps from '@components/Modal/types';
+import {ModalActions} from '@components/Modal/Global/ModalContext';
 import type {AnimatedTextInputRef} from '@components/RNTextInput';
 import ScreenWrapper from '@components/ScreenWrapper';
 import Text from '@components/Text';
 import TextInput from '@components/TextInput';
 import ValuePicker from '@components/ValuePicker';
+import useConfirmModal from '@hooks/useConfirmModal';
+import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
 import useLocalize from '@hooks/useLocalize';
 import usePolicy from '@hooks/usePolicy';
 import useThemeStyles from '@hooks/useThemeStyles';
@@ -70,11 +70,11 @@ function IOURequestStepSubrate({
     const styles = useThemeStyles();
     const policy = usePolicy(report?.policyID);
     const customUnit = getPerDiemCustomUnit(policy);
-    const [isDeleteStopModalOpen, setIsDeleteStopModalOpen] = useState(false);
-    const [restoreFocusType, setRestoreFocusType] = useState<BaseModalProps['restoreFocusType']>();
     const navigation = useNavigation();
     const isFocused = navigation.isFocused();
     const {translate} = useLocalize();
+    const expensifyIcons = useMemoizedLazyExpensifyIcons(['Trashcan'] as const);
+    const {showConfirmModal} = useConfirmModal();
     const textInputRef = useRef<AnimatedTextInputRef>(null);
     const parsedIndex = parseInt(pageIndex, 10);
     const selectedDestination = transaction?.comment?.customUnit?.customUnitRateID;
@@ -155,8 +155,6 @@ function IOURequestStepSubrate({
 
     const deleteSubrateAndHideModal = () => {
         removeSubrate(transaction, pageIndex);
-        setRestoreFocusType(CONST.MODAL.RESTORE_FOCUS_TYPE.DELETE);
-        setIsDeleteStopModalOpen(false);
         goBack();
     };
 
@@ -187,29 +185,27 @@ function IOURequestStepSubrate({
                     shouldSetModalVisibility={false}
                     threeDotsMenuItems={[
                         {
-                            icon: Expensicons.Trashcan,
+                            icon: expensifyIcons.Trashcan,
                             text: translate('iou.deleteSubrate'),
                             onSelected: () => {
-                                setRestoreFocusType(undefined);
-                                setIsDeleteStopModalOpen(true);
+                                showConfirmModal({
+                                    title: translate('iou.deleteSubrate'),
+                                    prompt: translate('iou.deleteSubrateConfirmation'),
+                                    confirmText: translate('common.delete'),
+                                    cancelText: translate('common.cancel'),
+                                    shouldEnableNewFocusManagement: true,
+                                    danger: true,
+                                }).then((result) => {
+                                    if (result.action !== ModalActions.CONFIRM) {
+                                        return;
+                                    }
+                                    deleteSubrateAndHideModal();
+                                });
                             },
                             shouldCallAfterModalHide: true,
                         },
                     ]}
                 />
-                <ConfirmModal
-                    title={translate('iou.deleteSubrate')}
-                    isVisible={isDeleteStopModalOpen}
-                    onConfirm={deleteSubrateAndHideModal}
-                    onCancel={() => setIsDeleteStopModalOpen(false)}
-                    shouldSetModalVisibility={false}
-                    prompt={translate('iou.deleteSubrateConfirmation')}
-                    confirmText={translate('common.delete')}
-                    cancelText={translate('common.cancel')}
-                    shouldEnableNewFocusManagement
-                    danger
-                    restoreFocusType={restoreFocusType}
-                />
                 <FormProvider
                     style={[styles.flexGrow1, styles.mh5]}
                     formID={ONYXKEYS.FORMS.MONEY_REQUEST_SUBRATE_FORM}
diff --git a/src/pages/iou/request/step/IOURequestStepWaypoint.tsx b/src/pages/iou/request/step/IOURequestStepWaypoint.tsx
index da0912559dfe..2a1bae5be124 100644
--- a/src/pages/iou/request/step/IOURequestStepWaypoint.tsx
+++ b/src/pages/iou/request/step/IOURequestStepWaypoint.tsx
@@ -5,14 +5,14 @@ import {View} from 'react-native';
 import type {OnyxEntry} from 'react-native-onyx';
 import AddressSearch from '@components/AddressSearch';
 import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView';
-import ConfirmModal from '@components/ConfirmModal';
 import FormProvider from '@components/Form/FormProvider';
 import InputWrapperWithRef from '@components/Form/InputWrapper';
 import type {FormOnyxValues} from '@components/Form/types';
 import HeaderWithBackButton from '@components/HeaderWithBackButton';
-import * as Expensicons from '@components/Icon/Expensicons';
-import type BaseModalProps from '@components/Modal/types';
+import {ModalActions} from '@components/Modal/Global/ModalContext';
 import ScreenWrapper from '@components/ScreenWrapper';
+import useConfirmModal from '@hooks/useConfirmModal';
+import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
 import useLocalize from '@hooks/useLocalize';
 import useLocationBias from '@hooks/useLocationBias';
 import useNetwork from '@hooks/useNetwork';
@@ -66,11 +66,11 @@ function IOURequestStepWaypoint({
     transaction,
 }: IOURequestStepWaypointProps) {
     const styles = useThemeStyles();
-    const [isDeleteStopModalOpen, setIsDeleteStopModalOpen] = useState(false);
-    const [restoreFocusType, setRestoreFocusType] = useState<BaseModalProps['restoreFocusType']>();
     const navigation = useNavigation();
     const isFocused = navigation.isFocused();
     const {translate} = useLocalize();
+    const {showConfirmModal} = useConfirmModal();
+    const expensifyIcons = useMemoizedLazyExpensifyIcons(['Trashcan'] as const);
     const {isOffline} = useNetwork();
     const textInput = useRef<TextInput | null>(null);
     const parsedWaypointIndex = parseInt(pageIndex, 10);
@@ -155,8 +155,6 @@ function IOURequestStepWaypoint({
 
     const deleteStopAndHideModal = () => {
         removeWaypoint(transaction, pageIndex, shouldUseTransactionDraft(action));
-        setRestoreFocusType(CONST.MODAL.RESTORE_FOCUS_TYPE.DELETE);
-        setIsDeleteStopModalOpen(false);
         goBack();
     };
 
@@ -207,29 +205,27 @@ function IOURequestStepWaypoint({
                     shouldSetModalVisibility={false}
                     threeDotsMenuItems={[
                         {
-                            icon: Expensicons.Trashcan,
+                            icon: expensifyIcons.Trashcan,
                             text: translate('distance.deleteWaypoint'),
                             onSelected: () => {
-                                setRestoreFocusType(undefined);
-                                setIsDeleteStopModalOpen(true);
+                                showConfirmModal({
+                                    title: translate('distance.deleteWaypoint'),
+                                    prompt: translate('distance.deleteWaypointConfirmation'),
+                                    confirmText: translate('common.delete'),
+                                    cancelText: translate('common.cancel'),
+                                    shouldEnableNewFocusManagement: true,
+                                    danger: true,
+                                }).then((result) => {
+                                    if (result.action !== ModalActions.CONFIRM) {
+                                        return;
+                                    }
+                                    deleteStopAndHideModal();
+                                });
                             },
                             shouldCallAfterModalHide: true,
                         },
                     ]}
                 />
-                <ConfirmModal
-                    title={translate('distance.deleteWaypoint')}
-                    isVisible={isDeleteStopModalOpen}
-                    onConfirm={deleteStopAndHideModal}
-                    onCancel={() => setIsDeleteStopModalOpen(false)}
-                    shouldSetModalVisibility={false}
-                    prompt={translate('distance.deleteWaypointConfirmation')}
-                    confirmText={translate('common.delete')}
-                    cancelText={translate('common.cancel')}
-                    shouldEnableNewFocusManagement
-                    danger
-                    restoreFocusType={restoreFocusType}
-                />
                 <FormProvider
                     style={[styles.flexGrow1, styles.mh5]}
                     formID={ONYXKEYS.FORMS.WAYPOINT_FORM}

From 89399134068049cae04bcd5e328738884ba41773 Mon Sep 17 00:00:00 2001
From: Clara Jones <clara@expensify.com>
Date: Thu, 11 Dec 2025 09:15:53 -0800
Subject: [PATCH 2/4] Update Set-Up-SAML-Single-Sign-On.md

updating the link name after this PR gets released: https://github.com/Expensify/App/pull/77168/files
---
 .../new-expensify/workspaces/Set-Up-SAML-Single-Sign-On.md      | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/articles/new-expensify/workspaces/Set-Up-SAML-Single-Sign-On.md b/docs/articles/new-expensify/workspaces/Set-Up-SAML-Single-Sign-On.md
index ad32f85273c5..f56aaf9b06f8 100644
--- a/docs/articles/new-expensify/workspaces/Set-Up-SAML-Single-Sign-On.md
+++ b/docs/articles/new-expensify/workspaces/Set-Up-SAML-Single-Sign-On.md
@@ -11,7 +11,7 @@ Expensify supports Single Sign-On (SSO) through the SAML protocol, allowing you
 
 # Set Up SAML Single Sign-On
 
-⚠️ **Note:** Your domain must be verified before you can enable SAML. [Learn how to verify a domain](https://help.expensify.com/articles/new-expensify/workspaces/Verify-a-Domain)
+⚠️ **Note:** Your domain must be verified before you can enable SAML. [Learn how to claim and verify a domain](https://help.expensify.com/articles/new-expensify/workspaces/Claim-and-Verify-a-Domain)
 
 Once your domain is verified, you can configure SAML-based login for enhanced authentication.
 

From d530785f2640e6015a2e24b985f7182ff1e2b6a5 Mon Sep 17 00:00:00 2001
From: Clara Jones <clara@expensify.com>
Date: Thu, 11 Dec 2025 09:17:40 -0800
Subject: [PATCH 3/4] Update Set-Up-SAML-Single-Sign-On.md

updating the link name after this PR gets released: https://github.com/Expensify/App/pull/77168/files

From d77d8530edc1978ca718e7d400c5c67db4edaaee Mon Sep 17 00:00:00 2001
From: Vit Horacek <vit@expensify.com>
Date: Fri, 12 Dec 2025 12:32:19 -0500
Subject: [PATCH 4/4] Revert "Refactor ConfirmModal usage to useConfirmModal in
 IOU"

This reverts commit 29dcc711e4553d083ecbd85256ba6809b413b710.
---
 .../step/IOURequestStepConfirmation.tsx       | 34 +++++++--------
 .../IOURequestStepScan/ReceiptView/index.tsx  | 42 ++++++++++---------
 .../request/step/IOURequestStepSubrate.tsx    | 42 ++++++++++---------
 .../request/step/IOURequestStepWaypoint.tsx   | 42 ++++++++++---------
 4 files changed, 83 insertions(+), 77 deletions(-)

diff --git a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx
index 82702a5e993b..21fead678f19 100644
--- a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx
+++ b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx
@@ -2,19 +2,18 @@ import reportsSelector from '@selectors/Attributes';
 import {transactionDraftValuesSelector} from '@selectors/TransactionDraft';
 import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
 import {View} from 'react-native';
+import ConfirmModal from '@components/ConfirmModal';
 import DragAndDropConsumer from '@components/DragAndDrop/Consumer';
 import DragAndDropProvider from '@components/DragAndDrop/Provider';
 import DropZoneUI from '@components/DropZone/DropZoneUI';
 import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator';
 import HeaderWithBackButton from '@components/HeaderWithBackButton';
 import LocationPermissionModal from '@components/LocationPermissionModal';
-import {ModalActions} from '@components/Modal/Global/ModalContext';
 import MoneyRequestConfirmationList from '@components/MoneyRequestConfirmationList';
 import {usePersonalDetails, usePolicyCategories} from '@components/OnyxListItemProvider';
 import PrevNextButtons from '@components/PrevNextButtons';
 import ScreenWrapper from '@components/ScreenWrapper';
 import useArchivedReportsIdSet from '@hooks/useArchivedReportsIdSet';
-import useConfirmModal from '@hooks/useConfirmModal';
 import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
 import useDeepCompareRef from '@hooks/useDeepCompareRef';
 import useFetchRoute from '@hooks/useFetchRoute';
@@ -128,6 +127,7 @@ function IOURequestStepConfirmation({
     const personalDetails = usePersonalDetails();
     const allPolicyCategories = usePolicyCategories();
 
+    const [isRemoveConfirmModalVisible, setRemoveConfirmModalVisible] = useState(false);
     const [optimisticTransactions] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_DRAFT, {
         selector: transactionDraftValuesSelector,
         canBeMissing: true,
@@ -230,7 +230,6 @@ function IOURequestStepConfirmation({
     const {translate} = useLocalize();
     const {isBetaEnabled} = usePermissions();
     const {isOffline} = useNetwork();
-    const {showConfirmModal} = useConfirmModal();
     const [startLocationPermissionFlow, setStartLocationPermissionFlow] = useState(false);
     const [selectedParticipantList, setSelectedParticipantList] = useState<Participant[]>([]);
     const [isDraggingOver, setIsDraggingOver] = useState(false);
@@ -1239,28 +1238,15 @@ function IOURequestStepConfirmation({
         if (currentTransactionID === CONST.IOU.OPTIMISTIC_TRANSACTION_ID) {
             const nextTransaction = transactions.at(currentTransactionIndex + 1);
             replaceDefaultDraftTransaction(nextTransaction);
+            setRemoveConfirmModalVisible(false);
             return;
         }
 
         removeDraftTransaction(currentTransactionID);
+        setRemoveConfirmModalVisible(false);
         showPreviousTransaction();
     };
 
-    const confirmRemoveCurrentTransaction = () => {
-        showConfirmModal({
-            title: translate('iou.removeExpense'),
-            prompt: translate('iou.removeExpenseConfirmation'),
-            confirmText: translate('common.remove'),
-            cancelText: translate('common.cancel'),
-            danger: true,
-        }).then((result) => {
-            if (result.action !== ModalActions.CONFIRM) {
-                return;
-            }
-            removeCurrentTransaction();
-        });
-    };
-
     const showReceiptEmptyState = shouldShowReceiptEmptyState(iouType, action, policy, isPerDiemRequest);
 
     const shouldShowSmartScanFields =
@@ -1335,7 +1321,7 @@ function IOURequestStepConfirmation({
                         iouCategory={transaction?.category}
                         onConfirm={onConfirm}
                         onSendMoney={sendMoney}
-                        showRemoveExpenseConfirmModal={confirmRemoveCurrentTransaction}
+                        showRemoveExpenseConfirmModal={() => setRemoveConfirmModalVisible(true)}
                         receiptPath={receiptPath}
                         receiptFilename={receiptFilename}
                         iouType={iouType}
@@ -1358,6 +1344,16 @@ function IOURequestStepConfirmation({
                         isReceiptEditable
                     />
                 </View>
+                <ConfirmModal
+                    title={translate('iou.removeExpense')}
+                    isVisible={isRemoveConfirmModalVisible}
+                    onConfirm={removeCurrentTransaction}
+                    onCancel={() => setRemoveConfirmModalVisible(false)}
+                    prompt={translate('iou.removeExpenseConfirmation')}
+                    confirmText={translate('common.remove')}
+                    cancelText={translate('common.cancel')}
+                    danger
+                />
             </DragAndDropProvider>
         </ScreenWrapper>
     );
diff --git a/src/pages/iou/request/step/IOURequestStepScan/ReceiptView/index.tsx b/src/pages/iou/request/step/IOURequestStepScan/ReceiptView/index.tsx
index e0626aa72eec..0d5911ae63f5 100644
--- a/src/pages/iou/request/step/IOURequestStepScan/ReceiptView/index.tsx
+++ b/src/pages/iou/request/step/IOURequestStepScan/ReceiptView/index.tsx
@@ -5,11 +5,10 @@ import AttachmentCarouselView from '@components/Attachments/AttachmentCarousel/A
 import useCarouselArrows from '@components/Attachments/AttachmentCarousel/useCarouselArrows';
 import useAttachmentErrors from '@components/Attachments/AttachmentView/useAttachmentErrors';
 import Button from '@components/Button';
+import ConfirmModal from '@components/ConfirmModal';
 import HeaderWithBackButton from '@components/HeaderWithBackButton';
-import {ModalActions} from '@components/Modal/Global/ModalContext';
+import * as Expensicons from '@components/Icon/Expensicons';
 import ScreenWrapper from '@components/ScreenWrapper';
-import useConfirmModal from '@hooks/useConfirmModal';
-import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useThemeStyles from '@hooks/useThemeStyles';
@@ -38,10 +37,9 @@ function ReceiptView({route}: ReceiptViewProps) {
     const {setAttachmentError} = useAttachmentErrors();
     const {shouldShowArrows, setShouldShowArrows, autoHideArrows, cancelAutoHideArrows} = useCarouselArrows();
     const styles = useThemeStyles();
-    const expensifyIcons = useMemoizedLazyExpensifyIcons(['Trashcan'] as const);
     const [currentReceipt, setCurrentReceipt] = useState<ReceiptWithTransactionIDAndSource | null>();
     const [page, setPage] = useState<number>(-1);
-    const {showConfirmModal} = useConfirmModal();
+    const [isDeleteReceiptConfirmModalVisible, setIsDeleteReceiptConfirmModalVisible] = useState(false);
 
     const [receipts = getEmptyArray<ReceiptWithTransactionIDAndSource>()] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_DRAFT, {
         selector: transactionDraftReceiptsViewSelector,
@@ -83,7 +81,12 @@ function ReceiptView({route}: ReceiptViewProps) {
         Navigation.goBack();
     }, [currentReceipt, receipts.length, secondTransaction, secondTransactionID]);
 
+    const handleCloseConfirmModal = () => {
+        setIsDeleteReceiptConfirmModalVisible(false);
+    };
+
     const deleteReceipt = useCallback(() => {
+        handleCloseConfirmModal();
         handleDeleteReceipt();
     }, [handleDeleteReceipt]);
 
@@ -100,24 +103,12 @@ function ReceiptView({route}: ReceiptViewProps) {
                 title={translate('common.receipt')}
                 shouldDisplayHelpButton={false}
                 onBackButtonPress={handleGoBack}
+                onCloseButtonPress={handleCloseConfirmModal}
             >
                 <Button
                     shouldShowRightIcon
-                    iconRight={expensifyIcons.Trashcan}
-                    onPress={() => {
-                        showConfirmModal({
-                            title: translate('receipt.deleteReceipt'),
-                            prompt: translate('receipt.deleteConfirmation'),
-                            confirmText: translate('common.delete'),
-                            cancelText: translate('common.cancel'),
-                            danger: true,
-                        }).then((result) => {
-                            if (result.action !== ModalActions.CONFIRM) {
-                                return;
-                            }
-                            deleteReceipt();
-                        });
-                    }}
+                    iconRight={Expensicons.Trashcan}
+                    onPress={() => setIsDeleteReceiptConfirmModalVisible(true)}
                     innerStyles={styles.bgTransparent}
                     large
                 />
@@ -135,6 +126,17 @@ function ReceiptView({route}: ReceiptViewProps) {
                 onAttachmentError={setAttachmentError}
                 shouldShowArrows={shouldShowArrows}
             />
+            <ConfirmModal
+                title={translate('receipt.deleteReceipt')}
+                isVisible={isDeleteReceiptConfirmModalVisible}
+                onConfirm={deleteReceipt}
+                onCancel={handleCloseConfirmModal}
+                prompt={translate('receipt.deleteConfirmation')}
+                confirmText={translate('common.delete')}
+                cancelText={translate('common.cancel')}
+                onBackdropPress={handleCloseConfirmModal}
+                danger
+            />
         </ScreenWrapper>
     );
 }
diff --git a/src/pages/iou/request/step/IOURequestStepSubrate.tsx b/src/pages/iou/request/step/IOURequestStepSubrate.tsx
index adb9d8a79372..9aa1da1dc9f7 100644
--- a/src/pages/iou/request/step/IOURequestStepSubrate.tsx
+++ b/src/pages/iou/request/step/IOURequestStepSubrate.tsx
@@ -3,18 +3,18 @@ import React, {useCallback, useEffect, useRef, useState} from 'react';
 import {InteractionManager, View} from 'react-native';
 import type {OnyxEntry} from 'react-native-onyx';
 import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView';
+import ConfirmModal from '@components/ConfirmModal';
 import FormProvider from '@components/Form/FormProvider';
 import InputWrapperWithRef from '@components/Form/InputWrapper';
 import type {FormOnyxValues} from '@components/Form/types';
 import HeaderWithBackButton from '@components/HeaderWithBackButton';
-import {ModalActions} from '@components/Modal/Global/ModalContext';
+import * as Expensicons from '@components/Icon/Expensicons';
+import type BaseModalProps from '@components/Modal/types';
 import type {AnimatedTextInputRef} from '@components/RNTextInput';
 import ScreenWrapper from '@components/ScreenWrapper';
 import Text from '@components/Text';
 import TextInput from '@components/TextInput';
 import ValuePicker from '@components/ValuePicker';
-import useConfirmModal from '@hooks/useConfirmModal';
-import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
 import useLocalize from '@hooks/useLocalize';
 import usePolicy from '@hooks/usePolicy';
 import useThemeStyles from '@hooks/useThemeStyles';
@@ -70,11 +70,11 @@ function IOURequestStepSubrate({
     const styles = useThemeStyles();
     const policy = usePolicy(report?.policyID);
     const customUnit = getPerDiemCustomUnit(policy);
+    const [isDeleteStopModalOpen, setIsDeleteStopModalOpen] = useState(false);
+    const [restoreFocusType, setRestoreFocusType] = useState<BaseModalProps['restoreFocusType']>();
     const navigation = useNavigation();
     const isFocused = navigation.isFocused();
     const {translate} = useLocalize();
-    const expensifyIcons = useMemoizedLazyExpensifyIcons(['Trashcan'] as const);
-    const {showConfirmModal} = useConfirmModal();
     const textInputRef = useRef<AnimatedTextInputRef>(null);
     const parsedIndex = parseInt(pageIndex, 10);
     const selectedDestination = transaction?.comment?.customUnit?.customUnitRateID;
@@ -155,6 +155,8 @@ function IOURequestStepSubrate({
 
     const deleteSubrateAndHideModal = () => {
         removeSubrate(transaction, pageIndex);
+        setRestoreFocusType(CONST.MODAL.RESTORE_FOCUS_TYPE.DELETE);
+        setIsDeleteStopModalOpen(false);
         goBack();
     };
 
@@ -185,27 +187,29 @@ function IOURequestStepSubrate({
                     shouldSetModalVisibility={false}
                     threeDotsMenuItems={[
                         {
-                            icon: expensifyIcons.Trashcan,
+                            icon: Expensicons.Trashcan,
                             text: translate('iou.deleteSubrate'),
                             onSelected: () => {
-                                showConfirmModal({
-                                    title: translate('iou.deleteSubrate'),
-                                    prompt: translate('iou.deleteSubrateConfirmation'),
-                                    confirmText: translate('common.delete'),
-                                    cancelText: translate('common.cancel'),
-                                    shouldEnableNewFocusManagement: true,
-                                    danger: true,
-                                }).then((result) => {
-                                    if (result.action !== ModalActions.CONFIRM) {
-                                        return;
-                                    }
-                                    deleteSubrateAndHideModal();
-                                });
+                                setRestoreFocusType(undefined);
+                                setIsDeleteStopModalOpen(true);
                             },
                             shouldCallAfterModalHide: true,
                         },
                     ]}
                 />
+                <ConfirmModal
+                    title={translate('iou.deleteSubrate')}
+                    isVisible={isDeleteStopModalOpen}
+                    onConfirm={deleteSubrateAndHideModal}
+                    onCancel={() => setIsDeleteStopModalOpen(false)}
+                    shouldSetModalVisibility={false}
+                    prompt={translate('iou.deleteSubrateConfirmation')}
+                    confirmText={translate('common.delete')}
+                    cancelText={translate('common.cancel')}
+                    shouldEnableNewFocusManagement
+                    danger
+                    restoreFocusType={restoreFocusType}
+                />
                 <FormProvider
                     style={[styles.flexGrow1, styles.mh5]}
                     formID={ONYXKEYS.FORMS.MONEY_REQUEST_SUBRATE_FORM}
diff --git a/src/pages/iou/request/step/IOURequestStepWaypoint.tsx b/src/pages/iou/request/step/IOURequestStepWaypoint.tsx
index 2a1bae5be124..da0912559dfe 100644
--- a/src/pages/iou/request/step/IOURequestStepWaypoint.tsx
+++ b/src/pages/iou/request/step/IOURequestStepWaypoint.tsx
@@ -5,14 +5,14 @@ import {View} from 'react-native';
 import type {OnyxEntry} from 'react-native-onyx';
 import AddressSearch from '@components/AddressSearch';
 import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView';
+import ConfirmModal from '@components/ConfirmModal';
 import FormProvider from '@components/Form/FormProvider';
 import InputWrapperWithRef from '@components/Form/InputWrapper';
 import type {FormOnyxValues} from '@components/Form/types';
 import HeaderWithBackButton from '@components/HeaderWithBackButton';
-import {ModalActions} from '@components/Modal/Global/ModalContext';
+import * as Expensicons from '@components/Icon/Expensicons';
+import type BaseModalProps from '@components/Modal/types';
 import ScreenWrapper from '@components/ScreenWrapper';
-import useConfirmModal from '@hooks/useConfirmModal';
-import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
 import useLocalize from '@hooks/useLocalize';
 import useLocationBias from '@hooks/useLocationBias';
 import useNetwork from '@hooks/useNetwork';
@@ -66,11 +66,11 @@ function IOURequestStepWaypoint({
     transaction,
 }: IOURequestStepWaypointProps) {
     const styles = useThemeStyles();
+    const [isDeleteStopModalOpen, setIsDeleteStopModalOpen] = useState(false);
+    const [restoreFocusType, setRestoreFocusType] = useState<BaseModalProps['restoreFocusType']>();
     const navigation = useNavigation();
     const isFocused = navigation.isFocused();
     const {translate} = useLocalize();
-    const {showConfirmModal} = useConfirmModal();
-    const expensifyIcons = useMemoizedLazyExpensifyIcons(['Trashcan'] as const);
     const {isOffline} = useNetwork();
     const textInput = useRef<TextInput | null>(null);
     const parsedWaypointIndex = parseInt(pageIndex, 10);
@@ -155,6 +155,8 @@ function IOURequestStepWaypoint({
 
     const deleteStopAndHideModal = () => {
         removeWaypoint(transaction, pageIndex, shouldUseTransactionDraft(action));
+        setRestoreFocusType(CONST.MODAL.RESTORE_FOCUS_TYPE.DELETE);
+        setIsDeleteStopModalOpen(false);
         goBack();
     };
 
@@ -205,27 +207,29 @@ function IOURequestStepWaypoint({
                     shouldSetModalVisibility={false}
                     threeDotsMenuItems={[
                         {
-                            icon: expensifyIcons.Trashcan,
+                            icon: Expensicons.Trashcan,
                             text: translate('distance.deleteWaypoint'),
                             onSelected: () => {
-                                showConfirmModal({
-                                    title: translate('distance.deleteWaypoint'),
-                                    prompt: translate('distance.deleteWaypointConfirmation'),
-                                    confirmText: translate('common.delete'),
-                                    cancelText: translate('common.cancel'),
-                                    shouldEnableNewFocusManagement: true,
-                                    danger: true,
-                                }).then((result) => {
-                                    if (result.action !== ModalActions.CONFIRM) {
-                                        return;
-                                    }
-                                    deleteStopAndHideModal();
-                                });
+                                setRestoreFocusType(undefined);
+                                setIsDeleteStopModalOpen(true);
                             },
                             shouldCallAfterModalHide: true,
                         },
                     ]}
                 />
+                <ConfirmModal
+                    title={translate('distance.deleteWaypoint')}
+                    isVisible={isDeleteStopModalOpen}
+                    onConfirm={deleteStopAndHideModal}
+                    onCancel={() => setIsDeleteStopModalOpen(false)}
+                    shouldSetModalVisibility={false}
+                    prompt={translate('distance.deleteWaypointConfirmation')}
+                    confirmText={translate('common.delete')}
+                    cancelText={translate('common.cancel')}
+                    shouldEnableNewFocusManagement
+                    danger
+                    restoreFocusType={restoreFocusType}
+                />
                 <FormProvider
                     style={[styles.flexGrow1, styles.mh5]}
                     formID={ONYXKEYS.FORMS.WAYPOINT_FORM}
