Skip to content

Commit 77aa31b

Browse files
authored
Merge pull request Expensify#79076 from nkdengineer/fix/76694-1-1
fix: Refactor ConfirmModal usage to useConfirmModal in IOU
2 parents 6a7d0a3 + c5fe531 commit 77aa31b

File tree

4 files changed

+88
-84
lines changed

4 files changed

+88
-84
lines changed

src/pages/iou/request/step/IOURequestStepConfirmation.tsx

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,19 @@ import reportsSelector from '@selectors/Attributes';
22
import {transactionDraftValuesSelector} from '@selectors/TransactionDraft';
33
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
44
import {View} from 'react-native';
5-
import ConfirmModal from '@components/ConfirmModal';
65
import DragAndDropConsumer from '@components/DragAndDrop/Consumer';
76
import DragAndDropProvider from '@components/DragAndDrop/Provider';
87
import DropZoneUI from '@components/DropZone/DropZoneUI';
98
import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator';
109
import HeaderWithBackButton from '@components/HeaderWithBackButton';
1110
import LocationPermissionModal from '@components/LocationPermissionModal';
11+
import {ModalActions} from '@components/Modal/Global/ModalContext';
1212
import MoneyRequestConfirmationList from '@components/MoneyRequestConfirmationList';
1313
import {usePersonalDetails, usePolicyCategories} from '@components/OnyxListItemProvider';
1414
import PrevNextButtons from '@components/PrevNextButtons';
1515
import ScreenWrapper from '@components/ScreenWrapper';
1616
import useArchivedReportsIdSet from '@hooks/useArchivedReportsIdSet';
17+
import useConfirmModal from '@hooks/useConfirmModal';
1718
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
1819
import useDeepCompareRef from '@hooks/useDeepCompareRef';
1920
import useFetchRoute from '@hooks/useFetchRoute';
@@ -127,7 +128,6 @@ function IOURequestStepConfirmation({
127128
const personalDetails = usePersonalDetails();
128129
const allPolicyCategories = usePolicyCategories();
129130

130-
const [isRemoveConfirmModalVisible, setRemoveConfirmModalVisible] = useState(false);
131131
const [optimisticTransactions] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_DRAFT, {
132132
selector: transactionDraftValuesSelector,
133133
canBeMissing: true,
@@ -234,6 +234,7 @@ function IOURequestStepConfirmation({
234234
const {translate} = useLocalize();
235235
const {isBetaEnabled} = usePermissions();
236236
const {isOffline} = useNetwork();
237+
const {showConfirmModal} = useConfirmModal();
237238
const [startLocationPermissionFlow, setStartLocationPermissionFlow] = useState(false);
238239
const [selectedParticipantList, setSelectedParticipantList] = useState<Participant[]>([]);
239240

@@ -1293,15 +1294,27 @@ function IOURequestStepConfirmation({
12931294
if (currentTransactionID === CONST.IOU.OPTIMISTIC_TRANSACTION_ID) {
12941295
const nextTransaction = transactions.at(currentTransactionIndex + 1);
12951296
replaceDefaultDraftTransaction(nextTransaction);
1296-
setRemoveConfirmModalVisible(false);
12971297
return;
12981298
}
12991299

13001300
removeDraftTransaction(currentTransactionID);
1301-
setRemoveConfirmModalVisible(false);
13021301
showPreviousTransaction();
13031302
};
13041303

1304+
const confirmRemoveCurrentTransaction = async () => {
1305+
const result = await showConfirmModal({
1306+
title: translate('iou.removeExpense'),
1307+
prompt: translate('iou.removeExpenseConfirmation'),
1308+
confirmText: translate('common.remove'),
1309+
cancelText: translate('common.cancel'),
1310+
danger: true,
1311+
});
1312+
if (result.action !== ModalActions.CONFIRM) {
1313+
return;
1314+
}
1315+
removeCurrentTransaction();
1316+
};
1317+
13051318
const showReceiptEmptyState = shouldShowReceiptEmptyState(iouType, action, policy, isPerDiemRequest);
13061319

13071320
const shouldShowSmartScanFields =
@@ -1372,7 +1385,9 @@ function IOURequestStepConfirmation({
13721385
iouCategory={transaction?.category}
13731386
onConfirm={onConfirm}
13741387
onSendMoney={sendMoney}
1375-
showRemoveExpenseConfirmModal={() => setRemoveConfirmModalVisible(true)}
1388+
showRemoveExpenseConfirmModal={() => {
1389+
confirmRemoveCurrentTransaction();
1390+
}}
13761391
receiptPath={receiptPath}
13771392
receiptFilename={receiptFilename}
13781393
iouType={iouType}
@@ -1396,16 +1411,6 @@ function IOURequestStepConfirmation({
13961411
isReceiptEditable
13971412
/>
13981413
</View>
1399-
<ConfirmModal
1400-
title={translate('iou.removeExpense')}
1401-
isVisible={isRemoveConfirmModalVisible}
1402-
onConfirm={removeCurrentTransaction}
1403-
onCancel={() => setRemoveConfirmModalVisible(false)}
1404-
prompt={translate('iou.removeExpenseConfirmation')}
1405-
confirmText={translate('common.remove')}
1406-
cancelText={translate('common.cancel')}
1407-
danger
1408-
/>
14091414
</DragAndDropProvider>
14101415
</ScreenWrapper>
14111416
);

src/pages/iou/request/step/IOURequestStepScan/ReceiptView/index.tsx

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ import AttachmentCarouselView from '@components/Attachments/AttachmentCarousel/A
55
import useCarouselArrows from '@components/Attachments/AttachmentCarousel/useCarouselArrows';
66
import useAttachmentErrors from '@components/Attachments/AttachmentView/useAttachmentErrors';
77
import Button from '@components/Button';
8-
import ConfirmModal from '@components/ConfirmModal';
98
import HeaderWithBackButton from '@components/HeaderWithBackButton';
10-
import * as Expensicons from '@components/Icon/Expensicons';
9+
import {ModalActions} from '@components/Modal/Global/ModalContext';
1110
import ScreenWrapper from '@components/ScreenWrapper';
11+
import useConfirmModal from '@hooks/useConfirmModal';
12+
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
1213
import useLocalize from '@hooks/useLocalize';
1314
import useOnyx from '@hooks/useOnyx';
1415
import useThemeStyles from '@hooks/useThemeStyles';
@@ -37,9 +38,10 @@ function ReceiptView({route}: ReceiptViewProps) {
3738
const {setAttachmentError} = useAttachmentErrors();
3839
const {shouldShowArrows, setShouldShowArrows, autoHideArrows, cancelAutoHideArrows} = useCarouselArrows();
3940
const styles = useThemeStyles();
41+
const expensifyIcons = useMemoizedLazyExpensifyIcons(['Trashcan'] as const);
4042
const [currentReceipt, setCurrentReceipt] = useState<ReceiptWithTransactionIDAndSource | null>();
4143
const [page, setPage] = useState<number>(-1);
42-
const [isDeleteReceiptConfirmModalVisible, setIsDeleteReceiptConfirmModalVisible] = useState(false);
44+
const {showConfirmModal} = useConfirmModal();
4345

4446
const [receipts = getEmptyArray<ReceiptWithTransactionIDAndSource>()] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_DRAFT, {
4547
selector: transactionDraftReceiptsViewSelector,
@@ -81,19 +83,28 @@ function ReceiptView({route}: ReceiptViewProps) {
8183
Navigation.goBack();
8284
}, [currentReceipt, receipts.length, secondTransaction, secondTransactionID]);
8385

84-
const handleCloseConfirmModal = () => {
85-
setIsDeleteReceiptConfirmModalVisible(false);
86-
};
87-
8886
const deleteReceipt = useCallback(() => {
89-
handleCloseConfirmModal();
9087
handleDeleteReceipt();
9188
}, [handleDeleteReceipt]);
9289

9390
const handleGoBack = useCallback(() => {
9491
Navigation.goBack(route.params.backTo);
9592
}, [route.params.backTo]);
9693

94+
const handleDeleteReceiptPress = useCallback(async () => {
95+
const result = await showConfirmModal({
96+
title: translate('receipt.deleteReceipt'),
97+
prompt: translate('receipt.deleteConfirmation'),
98+
confirmText: translate('common.delete'),
99+
cancelText: translate('common.cancel'),
100+
danger: true,
101+
});
102+
if (result.action !== ModalActions.CONFIRM) {
103+
return;
104+
}
105+
deleteReceipt();
106+
}, [showConfirmModal, translate, deleteReceipt]);
107+
97108
return (
98109
<ScreenWrapper
99110
testID="ReceiptView"
@@ -103,12 +114,11 @@ function ReceiptView({route}: ReceiptViewProps) {
103114
title={translate('common.receipt')}
104115
shouldDisplayHelpButton={false}
105116
onBackButtonPress={handleGoBack}
106-
onCloseButtonPress={handleCloseConfirmModal}
107117
>
108118
<Button
109119
shouldShowRightIcon
110-
iconRight={Expensicons.Trashcan}
111-
onPress={() => setIsDeleteReceiptConfirmModalVisible(true)}
120+
iconRight={expensifyIcons.Trashcan}
121+
onPress={handleDeleteReceiptPress}
112122
innerStyles={styles.bgTransparent}
113123
large
114124
/>
@@ -126,17 +136,6 @@ function ReceiptView({route}: ReceiptViewProps) {
126136
onAttachmentError={setAttachmentError}
127137
shouldShowArrows={shouldShowArrows}
128138
/>
129-
<ConfirmModal
130-
title={translate('receipt.deleteReceipt')}
131-
isVisible={isDeleteReceiptConfirmModalVisible}
132-
onConfirm={deleteReceipt}
133-
onCancel={handleCloseConfirmModal}
134-
prompt={translate('receipt.deleteConfirmation')}
135-
confirmText={translate('common.delete')}
136-
cancelText={translate('common.cancel')}
137-
onBackdropPress={handleCloseConfirmModal}
138-
danger
139-
/>
140139
</ScreenWrapper>
141140
);
142141
}

src/pages/iou/request/step/IOURequestStepSubrate.tsx

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@ import React, {useCallback, useEffect, useRef, useState} from 'react';
33
import {InteractionManager, View} from 'react-native';
44
import type {OnyxEntry} from 'react-native-onyx';
55
import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView';
6-
import ConfirmModal from '@components/ConfirmModal';
76
import FormProvider from '@components/Form/FormProvider';
87
import InputWrapperWithRef from '@components/Form/InputWrapper';
98
import type {FormOnyxValues} from '@components/Form/types';
109
import HeaderWithBackButton from '@components/HeaderWithBackButton';
11-
import * as Expensicons from '@components/Icon/Expensicons';
12-
import type BaseModalProps from '@components/Modal/types';
10+
import {ModalActions} from '@components/Modal/Global/ModalContext';
1311
import type {AnimatedTextInputRef} from '@components/RNTextInput';
1412
import ScreenWrapper from '@components/ScreenWrapper';
1513
import Text from '@components/Text';
1614
import TextInput from '@components/TextInput';
1715
import ValuePicker from '@components/ValuePicker';
16+
import useConfirmModal from '@hooks/useConfirmModal';
17+
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
1818
import useLocalize from '@hooks/useLocalize';
1919
import usePolicy from '@hooks/usePolicy';
2020
import useThemeStyles from '@hooks/useThemeStyles';
@@ -70,11 +70,11 @@ function IOURequestStepSubrate({
7070
const styles = useThemeStyles();
7171
const policy = usePolicy(report?.policyID);
7272
const customUnit = getPerDiemCustomUnit(policy);
73-
const [isDeleteStopModalOpen, setIsDeleteStopModalOpen] = useState(false);
74-
const [restoreFocusType, setRestoreFocusType] = useState<BaseModalProps['restoreFocusType']>();
7573
const navigation = useNavigation();
7674
const isFocused = navigation.isFocused();
7775
const {translate} = useLocalize();
76+
const expensifyIcons = useMemoizedLazyExpensifyIcons(['Trashcan'] as const);
77+
const {showConfirmModal} = useConfirmModal();
7878
const textInputRef = useRef<AnimatedTextInputRef>(null);
7979
const parsedIndex = parseInt(pageIndex, 10);
8080
const selectedDestination = transaction?.comment?.customUnit?.customUnitRateID;
@@ -155,11 +155,24 @@ function IOURequestStepSubrate({
155155

156156
const deleteSubrateAndHideModal = () => {
157157
removeSubrate(transaction, pageIndex);
158-
setRestoreFocusType(CONST.MODAL.RESTORE_FOCUS_TYPE.DELETE);
159-
setIsDeleteStopModalOpen(false);
160158
goBack();
161159
};
162160

161+
const handleDeleteSubrate = async () => {
162+
const result = await showConfirmModal({
163+
title: translate('iou.deleteSubrate'),
164+
prompt: translate('iou.deleteSubrateConfirmation'),
165+
confirmText: translate('common.delete'),
166+
cancelText: translate('common.cancel'),
167+
shouldEnableNewFocusManagement: true,
168+
danger: true,
169+
});
170+
if (result.action !== ModalActions.CONFIRM) {
171+
return;
172+
}
173+
deleteSubrateAndHideModal();
174+
};
175+
163176
const tabTitles = {
164177
[CONST.IOU.TYPE.REQUEST]: translate('iou.createExpense'),
165178
[CONST.IOU.TYPE.SUBMIT]: translate('iou.createExpense'),
@@ -176,7 +189,7 @@ function IOURequestStepSubrate({
176189
<ScreenWrapper
177190
includeSafeAreaPaddingBottom
178191
shouldEnableMaxHeight
179-
testID="IOURequestStepSubrate"
192+
testID={IOURequestStepSubrate.displayName}
180193
>
181194
<FullPageNotFoundView shouldShow={shouldDisableEditor}>
182195
<HeaderWithBackButton
@@ -187,29 +200,15 @@ function IOURequestStepSubrate({
187200
shouldSetModalVisibility={false}
188201
threeDotsMenuItems={[
189202
{
190-
icon: Expensicons.Trashcan,
203+
icon: expensifyIcons.Trashcan,
191204
text: translate('iou.deleteSubrate'),
192205
onSelected: () => {
193-
setRestoreFocusType(undefined);
194-
setIsDeleteStopModalOpen(true);
206+
handleDeleteSubrate();
195207
},
196208
shouldCallAfterModalHide: true,
197209
},
198210
]}
199211
/>
200-
<ConfirmModal
201-
title={translate('iou.deleteSubrate')}
202-
isVisible={isDeleteStopModalOpen}
203-
onConfirm={deleteSubrateAndHideModal}
204-
onCancel={() => setIsDeleteStopModalOpen(false)}
205-
shouldSetModalVisibility={false}
206-
prompt={translate('iou.deleteSubrateConfirmation')}
207-
confirmText={translate('common.delete')}
208-
cancelText={translate('common.cancel')}
209-
shouldEnableNewFocusManagement
210-
danger
211-
restoreFocusType={restoreFocusType}
212-
/>
213212
<FormProvider
214213
style={[styles.flexGrow1, styles.mh5]}
215214
formID={ONYXKEYS.FORMS.MONEY_REQUEST_SUBRATE_FORM}
@@ -255,4 +254,6 @@ function IOURequestStepSubrate({
255254
);
256255
}
257256

257+
IOURequestStepSubrate.displayName = 'IOURequestStepSubrate';
258+
258259
export default withWritableReportOrNotFound(withFullTransactionOrNotFound(IOURequestStepSubrate));

src/pages/iou/request/step/IOURequestStepWaypoint.tsx

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ import {View} from 'react-native';
55
import type {OnyxEntry} from 'react-native-onyx';
66
import AddressSearch from '@components/AddressSearch';
77
import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView';
8-
import ConfirmModal from '@components/ConfirmModal';
98
import FormProvider from '@components/Form/FormProvider';
109
import InputWrapperWithRef from '@components/Form/InputWrapper';
1110
import type {FormOnyxValues} from '@components/Form/types';
1211
import HeaderWithBackButton from '@components/HeaderWithBackButton';
13-
import * as Expensicons from '@components/Icon/Expensicons';
14-
import type BaseModalProps from '@components/Modal/types';
12+
import {ModalActions} from '@components/Modal/Global/ModalContext';
1513
import ScreenWrapper from '@components/ScreenWrapper';
14+
import useConfirmModal from '@hooks/useConfirmModal';
15+
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
1616
import useLocalize from '@hooks/useLocalize';
1717
import useLocationBias from '@hooks/useLocationBias';
1818
import useNetwork from '@hooks/useNetwork';
@@ -66,8 +66,6 @@ function IOURequestStepWaypoint({
6666
transaction,
6767
}: IOURequestStepWaypointProps) {
6868
const styles = useThemeStyles();
69-
const [isDeleteStopModalOpen, setIsDeleteStopModalOpen] = useState(false);
70-
const [restoreFocusType, setRestoreFocusType] = useState<BaseModalProps['restoreFocusType']>();
7169
const navigation = useNavigation();
7270
const isFocused = navigation.isFocused();
7371
const {translate} = useLocalize();
@@ -79,6 +77,8 @@ function IOURequestStepWaypoint({
7977
const waypointCount = Object.keys(allWaypoints).length;
8078
const filledWaypointCount = Object.values(allWaypoints).filter((waypoint) => !isEmptyObject(waypoint)).length;
8179
const [caretHidden, setCaretHidden] = useState(false);
80+
const {showConfirmModal} = useConfirmModal();
81+
const expensifyIcons = useMemoizedLazyExpensifyIcons(['Trashcan'] as const);
8282

8383
const [userLocation] = useOnyx(ONYXKEYS.USER_LOCATION, {canBeMissing: true});
8484
const [recentWaypoints] = useOnyx(ONYXKEYS.NVP_RECENT_WAYPOINTS, {selector: recentWaypointsSelector, canBeMissing: true});
@@ -155,11 +155,24 @@ function IOURequestStepWaypoint({
155155

156156
const deleteStopAndHideModal = () => {
157157
removeWaypoint(transaction, pageIndex, shouldUseTransactionDraft(action));
158-
setRestoreFocusType(CONST.MODAL.RESTORE_FOCUS_TYPE.DELETE);
159-
setIsDeleteStopModalOpen(false);
160158
goBack();
161159
};
162160

161+
const handleDeleteWaypoint = async () => {
162+
const result = await showConfirmModal({
163+
title: translate('distance.deleteWaypoint'),
164+
prompt: translate('distance.deleteWaypointConfirmation'),
165+
confirmText: translate('common.delete'),
166+
cancelText: translate('common.cancel'),
167+
shouldEnableNewFocusManagement: true,
168+
danger: true,
169+
});
170+
if (result.action !== ModalActions.CONFIRM) {
171+
return;
172+
}
173+
deleteStopAndHideModal();
174+
};
175+
163176
const selectWaypoint = (values: Waypoint) => {
164177
const waypoint = {
165178
lat: values.lat ?? 0,
@@ -207,29 +220,15 @@ function IOURequestStepWaypoint({
207220
shouldSetModalVisibility={false}
208221
threeDotsMenuItems={[
209222
{
210-
icon: Expensicons.Trashcan,
223+
icon: expensifyIcons.Trashcan,
211224
text: translate('distance.deleteWaypoint'),
212225
onSelected: () => {
213-
setRestoreFocusType(undefined);
214-
setIsDeleteStopModalOpen(true);
226+
handleDeleteWaypoint();
215227
},
216228
shouldCallAfterModalHide: true,
217229
},
218230
]}
219231
/>
220-
<ConfirmModal
221-
title={translate('distance.deleteWaypoint')}
222-
isVisible={isDeleteStopModalOpen}
223-
onConfirm={deleteStopAndHideModal}
224-
onCancel={() => setIsDeleteStopModalOpen(false)}
225-
shouldSetModalVisibility={false}
226-
prompt={translate('distance.deleteWaypointConfirmation')}
227-
confirmText={translate('common.delete')}
228-
cancelText={translate('common.cancel')}
229-
shouldEnableNewFocusManagement
230-
danger
231-
restoreFocusType={restoreFocusType}
232-
/>
233232
<FormProvider
234233
style={[styles.flexGrow1, styles.mh5]}
235234
formID={ONYXKEYS.FORMS.WAYPOINT_FORM}

0 commit comments

Comments
 (0)