From 91b5b21f792d637159ef683174afd1d3f55eb642 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Musia=C5=82?= Date: Fri, 28 Nov 2025 15:37:44 +0100 Subject: [PATCH 1/8] Remove modal & add new page --- src/ROUTES.ts | 5 + src/SCREENS.ts | 1 + .../ModalStackNavigators/index.tsx | 1 + .../RELATIONS/SETTINGS_TO_RHP.ts | 1 + src/libs/Navigation/linkingConfig/config.ts | 4 + src/libs/Navigation/types.ts | 8 ++ .../ReportCardLostConfirmMagicCodePage.tsx | 96 +++++++++++++++++++ .../settings/Wallet/ReportCardLostPage.tsx | 62 ++---------- 8 files changed, 126 insertions(+), 52 deletions(-) create mode 100644 src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 3893661d76459..14281a9ca9670 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -5,6 +5,7 @@ */ import type {TupleToUnion, ValueOf} from 'type-fest'; import type {UpperCaseCharacters} from 'type-fest/source/internal'; +import type {ReplacementReason} from './libs/actions/Card'; import type {SearchFilterKey, SearchQueryString, UserFriendlyKey} from './components/Search/types'; import type CONST from './CONST'; import type {IOUAction, IOUType} from './CONST'; @@ -336,6 +337,10 @@ const ROUTES = { route: 'settings/wallet/card/:cardID/report-card-lost-or-damaged', getRoute: (cardID: string) => `settings/wallet/card/${cardID}/report-card-lost-or-damaged` as const, }, + SETTINGS_WALLET_REPORT_CARD_LOST_OR_DAMAGED_CONFIRM_MAGIC_CODE: { + route: 'settings/wallet/card/:cardID/report-card-lost-or-damaged/:reason/confirm-magic-code', + getRoute: (cardID: string, reason: ReplacementReason) => `settings/wallet/card/${cardID}/report-card-lost-or-damaged/${reason}/confirm-magic-code` as const, + }, SETTINGS_WALLET_CARD_ACTIVATE: { route: 'settings/wallet/card/:cardID/activate', getRoute: (cardID: string) => `settings/wallet/card/${cardID}/activate` as const, diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 3b0945b501208..b983e82912e11 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -110,6 +110,7 @@ const SCREENS = { ADD_BANK_ACCOUNT_SELECT_COUNTRY_VERIFY_ACCOUNT: 'Settings_Add_Bank_Account_Select_Country_Verify_Account', CLOSE: 'Settings_Close', REPORT_CARD_LOST_OR_DAMAGED: 'Settings_ReportCardLostOrDamaged', + REPORT_CARD_LOST_OR_DAMAGED_CONFIRM_MAGIC_CODE: 'Settings_ReportCardLostOrDamaged_ConfirmMagicCode', TROUBLESHOOT: 'Settings_Troubleshoot', CONSOLE: 'Settings_Console', SHARE_LOG: 'Share_Log', diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 687527baa737b..8ef528036f271 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -548,6 +548,7 @@ const SettingsModalStackNavigator = createModalStackNavigator require('../../../../pages/ReimbursementAccount/ReimbursementAccountVerifyAccountPage').default, [SCREENS.REIMBURSEMENT_ACCOUNT_ENTER_SIGNER_INFO]: () => require('../../../../pages/ReimbursementAccount/EnterSignerInfo').default, [SCREENS.SETTINGS.REPORT_CARD_LOST_OR_DAMAGED]: () => require('../../../../pages/settings/Wallet/ReportCardLostPage').default, + [SCREENS.SETTINGS.REPORT_CARD_LOST_OR_DAMAGED_CONFIRM_MAGIC_CODE]: () => require('../../../../pages/settings/Wallet/ReportCardLostConfirmMagicCodePage').default, [SCREENS.KEYBOARD_SHORTCUTS]: () => require('../../../../pages/KeyboardShortcutsPage').default, [SCREENS.SETTINGS.EXIT_SURVEY.REASON]: () => require('../../../../pages/settings/ExitSurvey/ExitSurveyReasonPage').default, [SCREENS.SETTINGS.EXIT_SURVEY.CONFIRM]: () => require('../../../../pages/settings/ExitSurvey/ExitSurveyConfirmPage').default, diff --git a/src/libs/Navigation/linkingConfig/RELATIONS/SETTINGS_TO_RHP.ts b/src/libs/Navigation/linkingConfig/RELATIONS/SETTINGS_TO_RHP.ts index 9ee3dd508f81b..6b12ee61e369d 100755 --- a/src/libs/Navigation/linkingConfig/RELATIONS/SETTINGS_TO_RHP.ts +++ b/src/libs/Navigation/linkingConfig/RELATIONS/SETTINGS_TO_RHP.ts @@ -45,6 +45,7 @@ const SETTINGS_TO_RHP: Partial['config'] = { path: ROUTES.SETTINGS_WALLET_REPORT_CARD_LOST_OR_DAMAGED.route, exact: true, }, + [SCREENS.SETTINGS.REPORT_CARD_LOST_OR_DAMAGED_CONFIRM_MAGIC_CODE]: { + path: ROUTES.SETTINGS_WALLET_REPORT_CARD_LOST_OR_DAMAGED_CONFIRM_MAGIC_CODE.route, + exact: true, + }, [SCREENS.SETTINGS.WALLET.CARD_ACTIVATE]: { path: ROUTES.SETTINGS_WALLET_CARD_ACTIVATE.route, exact: true, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 2b895fac57149..72be5730e5d77 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -13,6 +13,7 @@ import type { import type {TupleToUnion, ValueOf} from 'type-fest'; import type {UpperCaseCharacters} from 'type-fest/source/internal'; import type {SearchQueryString} from '@components/Search/types'; +import type {ReplacementReason} from '@libs/actions/Card'; import type {IOURequestType} from '@libs/actions/IOU'; import type {SaveSearchParams} from '@libs/API/parameters'; import type {ReimbursementAccountStepToOpen} from '@libs/ReimbursementAccountUtils'; @@ -1080,6 +1081,13 @@ type SettingsNavigatorParamList = { /** cardID of selected card */ cardID: string; }; + [SCREENS.SETTINGS.REPORT_CARD_LOST_OR_DAMAGED_CONFIRM_MAGIC_CODE]: { + /** cardID of selected card */ + cardID: string; + + /** Reason for replacing the card */ + reason: ReplacementReason; + }; [SCREENS.KEYBOARD_SHORTCUTS]: { // eslint-disable-next-line no-restricted-syntax -- `backTo` usages in this file are legacy. Do not add new `backTo` params to screens. See contributingGuides/NAVIGATION.md backTo: Routes; diff --git a/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx b/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx new file mode 100644 index 0000000000000..3bb39eb171144 --- /dev/null +++ b/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx @@ -0,0 +1,96 @@ +import React, {useCallback, useEffect, useState} from 'react'; +import ValidateCodeActionContent from '@components/ValidateCodeActionModal/ValidateCodeActionContent'; +import useLocalize from '@hooks/useLocalize'; +import useOnyx from '@hooks/useOnyx'; +import usePrevious from '@hooks/usePrevious'; +import {clearCardListErrors, requestReplacementExpensifyCard} from '@libs/actions/Card'; +import {setErrors} from '@libs/actions/FormActions'; +import {requestValidateCodeAction, resetValidateActionCodeSent} from '@libs/actions/User'; +import {getLatestErrorMessageField} 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 ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; +import type SCREENS from '@src/SCREENS'; +import {isEmptyObject} from '@src/types/utils/EmptyObject'; +import SuccessReportCardLost from './SuccessReportCardLost'; + +type ReportCardLostConfirmMagicCodePageProps = PlatformStackScreenProps; + +function ReportCardLostConfirmMagicCodePage({ + route: { + params: {cardID = '', reason = 'damaged'}, + }, +}: ReportCardLostConfirmMagicCodePageProps) { + const {translate} = useLocalize(); + const [account] = useOnyx(ONYXKEYS.ACCOUNT, {canBeMissing: false}); + const [formData] = useOnyx(ONYXKEYS.FORMS.REPORT_PHYSICAL_CARD_FORM, {canBeMissing: true}); + + const primaryLogin = account?.primaryLogin ?? ''; + const [cardList] = useOnyx(ONYXKEYS.CARD_LIST, {canBeMissing: true}); + const physicalCard = cardList?.[cardID]; + const [newCardID, setNewCardID] = useState(''); + const previousCardList = usePrevious(cardList); + const validateError = getLatestErrorMessageField(physicalCard); + + useEffect(() => { + const newID = Object.keys(cardList ?? {}).find((cardKey) => cardList?.[cardKey]?.cardID && !(cardKey in (previousCardList ?? {}))); + if (!newID || physicalCard?.cardID) { + return; + } + setNewCardID(newID); + }, [cardList, physicalCard, previousCardList]); + + useEffect(() => { + resetValidateActionCodeSent(); + }, []); + + useEffect(() => { + if (formData?.isLoading && isEmptyObject(physicalCard?.errors)) { + return; + } + + setErrors(ONYXKEYS.FORMS.REPORT_PHYSICAL_CARD_FORM, physicalCard?.errors ?? {}); + }, [formData?.isLoading, physicalCard?.errors]); + + const handleValidateCodeEntered = useCallback( + (validateCode: string) => { + if (!physicalCard) { + return; + } + requestReplacementExpensifyCard(physicalCard.cardID, reason, validateCode); + }, + [physicalCard, reason], + ); + + if (newCardID) { + ; + } + + return ( + requestValidateCodeAction()} + validateError={validateError} + clearError={() => { + if (!physicalCard?.cardID) { + return; + } + clearCardListErrors(physicalCard?.cardID); + }} + onClose={() => { + resetValidateActionCodeSent(); + Navigation.navigate(ROUTES.SETTINGS_WALLET_REPORT_CARD_LOST_OR_DAMAGED.getRoute(cardID)); + }} + /> + ); +} + +ReportCardLostConfirmMagicCodePage.displayName = 'ReportCardLostConfirmMagicCodePage'; + +export default ReportCardLostConfirmMagicCodePage; diff --git a/src/pages/settings/Wallet/ReportCardLostPage.tsx b/src/pages/settings/Wallet/ReportCardLostPage.tsx index dccc0f2dc6081..3eaf388d2a698 100644 --- a/src/pages/settings/Wallet/ReportCardLostPage.tsx +++ b/src/pages/settings/Wallet/ReportCardLostPage.tsx @@ -1,4 +1,4 @@ -import React, {useCallback, useEffect, useState} from 'react'; +import React, {useEffect, useState} from 'react'; import {View} from 'react-native'; import FormAlertWithSubmitButton from '@components/FormAlertWithSubmitButton'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; @@ -6,23 +6,18 @@ import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import ScreenWrapper from '@components/ScreenWrapper'; import SingleOptionSelector from '@components/SingleOptionSelector'; import Text from '@components/Text'; -import ValidateCodeActionModal from '@components/ValidateCodeActionModal'; -import useBeforeRemove from '@hooks/useBeforeRemove'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import usePrevious from '@hooks/usePrevious'; import useSafeAreaPaddings from '@hooks/useSafeAreaPaddings'; import useThemeStyles from '@hooks/useThemeStyles'; +import type {ReplacementReason} from '@libs/actions/Card'; import {setErrors} from '@libs/actions/FormActions'; -import {requestValidateCodeAction, resetValidateActionCodeSent} from '@libs/actions/User'; -import {getLatestErrorMessageField} 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 {getFormattedAddress} from '@libs/PersonalDetailsUtils'; import NotFoundPage from '@pages/ErrorPage/NotFoundPage'; -import {clearCardListErrors, requestReplacementExpensifyCard} from '@userActions/Card'; -import type {ReplacementReason} from '@userActions/Card'; import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; @@ -33,10 +28,10 @@ import SuccessReportCardLost from './SuccessReportCardLost'; const OPTIONS_KEYS = { DAMAGED: 'damaged', STOLEN: 'stolen', -}; +} satisfies Record; type Option = { - key: string; + key: ReplacementReason; label: TranslationPaths; }; @@ -63,7 +58,6 @@ function ReportCardLostPage({ const {translate} = useLocalize(); - const [account] = useOnyx(ONYXKEYS.ACCOUNT, {canBeMissing: true}); const [formData] = useOnyx(ONYXKEYS.FORMS.REPORT_PHYSICAL_CARD_FORM, {canBeMissing: true}); const [cardList] = useOnyx(ONYXKEYS.CARD_LIST, {canBeMissing: true}); const [privatePersonalDetails] = useOnyx(ONYXKEYS.PRIVATE_PERSONAL_DETAILS, {canBeMissing: true}); @@ -75,17 +69,12 @@ function ReportCardLostPage({ const [newCardID, setNewCardID] = useState(''); const physicalCard = cardList?.[cardID]; - const validateError = getLatestErrorMessageField(physicalCard); - const [isValidateCodeActionModalVisible, setIsValidateCodeActionModalVisible] = useState(false); const {paddingBottom} = useSafeAreaPaddings(); const formattedAddress = getFormattedAddress(privatePersonalDetails ?? {}); - const primaryLogin = account?.primaryLogin ?? ''; const previousCardList = usePrevious(cardList); - useBeforeRemove(() => setIsValidateCodeActionModalVisible(false)); - useEffect(() => { const newID = Object.keys(cardList ?? {}).find((cardKey) => cardList?.[cardKey]?.cardID && !(cardKey in (previousCardList ?? {}))); if (!newID || physicalCard?.cardID) { @@ -94,10 +83,6 @@ function ReportCardLostPage({ setNewCardID(newID); }, [cardList, physicalCard?.cardID, previousCardList]); - useEffect(() => { - resetValidateActionCodeSent(); - }, []); - useEffect(() => { if (formData?.isLoading && isEmptyObject(physicalCard?.errors)) { return; @@ -106,17 +91,7 @@ function ReportCardLostPage({ setErrors(ONYXKEYS.FORMS.REPORT_PHYSICAL_CARD_FORM, physicalCard?.errors ?? {}); }, [formData?.isLoading, physicalCard?.errors]); - const handleValidateCodeEntered = useCallback( - (validateCode: string) => { - if (!physicalCard) { - return; - } - requestReplacementExpensifyCard(physicalCard.cardID, reason?.key as ReplacementReason, validateCode); - }, - [physicalCard, reason?.key], - ); - - if (isEmptyObject(physicalCard) && !newCardID && !formData?.isLoading) { + if (isEmptyObject(physicalCard) && !formData?.isLoading) { return ; } @@ -136,7 +111,7 @@ function ReportCardLostPage({ setShouldShowAddressError(true); return; } - setIsValidateCodeActionModalVisible(true); + Navigation.navigate(ROUTES.SETTINGS_WALLET_REPORT_CARD_LOST_OR_DAMAGED_CONFIRM_MAGIC_CODE.getRoute(cardID, reason?.key ?? OPTIONS_KEYS.DAMAGED)); }; const handleOptionSelect = (option: Option) => { @@ -159,10 +134,9 @@ function ReportCardLostPage({ @@ -185,7 +159,7 @@ function ReportCardLostPage({ {translate('reportCardLostOrDamaged.cardLostOrStolenInfo')} )} - + - { - if (!physicalCard?.cardID) { - return; - } - clearCardListErrors(physicalCard?.cardID); - }} - onClose={() => setIsValidateCodeActionModalVisible(false)} - isVisible={isValidateCodeActionModalVisible} - title={translate('cardPage.validateCardTitle')} - descriptionPrimary={translate('cardPage.enterMagicCode', {contactMethod: primaryLogin})} - /> ) : ( <> - + {translate('reportCardLostOrDamaged.reasonTitle')} - + Date: Mon, 1 Dec 2025 10:41:06 +0100 Subject: [PATCH 2/8] navigation for success --- .../ReportCardLostConfirmMagicCodePage.tsx | 10 +- .../settings/Wallet/ReportCardLostPage.tsx | 115 ++++++++---------- .../settings/Wallet/SuccessReportCardLost.tsx | 2 +- 3 files changed, 60 insertions(+), 67 deletions(-) diff --git a/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx b/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx index 3bb39eb171144..5b2dbe92fadc6 100644 --- a/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx +++ b/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx @@ -1,4 +1,5 @@ import React, {useCallback, useEffect, useState} from 'react'; +import ScreenWrapper from '@components/ScreenWrapper'; import ValidateCodeActionContent from '@components/ValidateCodeActionModal/ValidateCodeActionContent'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; @@ -65,7 +66,14 @@ function ReportCardLostConfirmMagicCodePage({ ); if (newCardID) { - ; + return ( + + + + ); } return ( diff --git a/src/pages/settings/Wallet/ReportCardLostPage.tsx b/src/pages/settings/Wallet/ReportCardLostPage.tsx index 3eaf388d2a698..68c407b8ccd87 100644 --- a/src/pages/settings/Wallet/ReportCardLostPage.tsx +++ b/src/pages/settings/Wallet/ReportCardLostPage.tsx @@ -8,7 +8,6 @@ import SingleOptionSelector from '@components/SingleOptionSelector'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; -import usePrevious from '@hooks/usePrevious'; import useSafeAreaPaddings from '@hooks/useSafeAreaPaddings'; import useThemeStyles from '@hooks/useThemeStyles'; import type {ReplacementReason} from '@libs/actions/Card'; @@ -23,7 +22,6 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; -import SuccessReportCardLost from './SuccessReportCardLost'; const OPTIONS_KEYS = { DAMAGED: 'damaged', @@ -66,22 +64,12 @@ function ReportCardLostPage({ const [isReasonConfirmed, setIsReasonConfirmed] = useState(false); const [shouldShowAddressError, setShouldShowAddressError] = useState(false); const [shouldShowReasonError, setShouldShowReasonError] = useState(false); - const [newCardID, setNewCardID] = useState(''); const physicalCard = cardList?.[cardID]; const {paddingBottom} = useSafeAreaPaddings(); const formattedAddress = getFormattedAddress(privatePersonalDetails ?? {}); - const previousCardList = usePrevious(cardList); - - useEffect(() => { - const newID = Object.keys(cardList ?? {}).find((cardKey) => cardList?.[cardKey]?.cardID && !(cardKey in (previousCardList ?? {}))); - if (!newID || physicalCard?.cardID) { - return; - } - setNewCardID(newID); - }, [cardList, physicalCard?.cardID, previousCardList]); useEffect(() => { if (formData?.isLoading && isEmptyObject(physicalCard?.errors)) { @@ -138,60 +126,57 @@ function ReportCardLostPage({ - {!newCardID && ( - - {isReasonConfirmed ? ( - <> - - {translate('reportCardLostOrDamaged.confirmAddressTitle')} - Navigation.navigate(ROUTES.SETTINGS_ADDRESS)} - numberOfLinesTitle={2} - /> - {isDamaged ? ( - {translate('reportCardLostOrDamaged.cardDamagedInfo')} - ) : ( - {translate('reportCardLostOrDamaged.cardLostOrStolenInfo')} - )} - - - - - - ) : ( - <> - - {translate('reportCardLostOrDamaged.reasonTitle')} - - - - - - - )} - - )} - {!!newCardID && } + + {isReasonConfirmed ? ( + <> + + {translate('reportCardLostOrDamaged.confirmAddressTitle')} + Navigation.navigate(ROUTES.SETTINGS_ADDRESS)} + numberOfLinesTitle={2} + /> + {isDamaged ? ( + {translate('reportCardLostOrDamaged.cardDamagedInfo')} + ) : ( + {translate('reportCardLostOrDamaged.cardLostOrStolenInfo')} + )} + + + + + + ) : ( + <> + + {translate('reportCardLostOrDamaged.reasonTitle')} + + + + + + + )} + ); } diff --git a/src/pages/settings/Wallet/SuccessReportCardLost.tsx b/src/pages/settings/Wallet/SuccessReportCardLost.tsx index 0438394691691..24fd608435bc8 100644 --- a/src/pages/settings/Wallet/SuccessReportCardLost.tsx +++ b/src/pages/settings/Wallet/SuccessReportCardLost.tsx @@ -20,7 +20,7 @@ function SuccessReportCardLost({cardID}: {cardID: string}) { illustration={illustrations.CardReplacementSuccess} shouldShowButton onButtonPress={() => { - Navigation.navigate(ROUTES.SETTINGS_WALLET_DOMAIN_CARD.getRoute(cardID)); + Navigation.navigate(ROUTES.SETTINGS_WALLET_DOMAIN_CARD.getRoute(cardID), {forceReplace: true}); }} buttonText={translate('common.buttonConfirm')} containerStyle={styles.h100} From 6f151a7e5f936c40c1451ce0cda22db760167f5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Musia=C5=82?= Date: Mon, 1 Dec 2025 11:02:30 +0100 Subject: [PATCH 3/8] fix lint & prettier --- src/ROUTES.ts | 2 +- .../settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 14281a9ca9670..6e9ce59676397 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -5,10 +5,10 @@ */ import type {TupleToUnion, ValueOf} from 'type-fest'; import type {UpperCaseCharacters} from 'type-fest/source/internal'; -import type {ReplacementReason} from './libs/actions/Card'; import type {SearchFilterKey, SearchQueryString, UserFriendlyKey} from './components/Search/types'; import type CONST from './CONST'; import type {IOUAction, IOUType} from './CONST'; +import type {ReplacementReason} from './libs/actions/Card'; import type {IOURequestType} from './libs/actions/IOU'; import Log from './libs/Log'; import type {RootNavigatorParamList} from './libs/Navigation/types'; diff --git a/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx b/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx index 5b2dbe92fadc6..9173b223eb05e 100644 --- a/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx +++ b/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx @@ -41,7 +41,7 @@ function ReportCardLostConfirmMagicCodePage({ return; } setNewCardID(newID); - }, [cardList, physicalCard, previousCardList]); + }, [cardList, physicalCard?.cardID, previousCardList]); useEffect(() => { resetValidateActionCodeSent(); From cbe9fff411b36da8aaf7d6a8b2f476640e52b19d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Musia=C5=82?= Date: Mon, 1 Dec 2025 13:00:11 +0100 Subject: [PATCH 4/8] goBack on back button --- .../settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx b/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx index 9173b223eb05e..0520e1d9a9a72 100644 --- a/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx +++ b/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx @@ -93,7 +93,7 @@ function ReportCardLostConfirmMagicCodePage({ }} onClose={() => { resetValidateActionCodeSent(); - Navigation.navigate(ROUTES.SETTINGS_WALLET_REPORT_CARD_LOST_OR_DAMAGED.getRoute(cardID)); + Navigation.goBack(ROUTES.SETTINGS_WALLET_REPORT_CARD_LOST_OR_DAMAGED.getRoute(cardID)); }} /> ); From 0d6980b9f2516dabbca3d247f415b7b2eee8174e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Musia=C5=82?= Date: Mon, 1 Dec 2025 14:50:15 +0100 Subject: [PATCH 5/8] fix lint --- src/components/WorkspaceMembersSelectionList.tsx | 2 +- .../expensifyCard/issueNew/AssigneeStep.tsx | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/components/WorkspaceMembersSelectionList.tsx b/src/components/WorkspaceMembersSelectionList.tsx index d9908c586fe9b..65a0442a94591 100644 --- a/src/components/WorkspaceMembersSelectionList.tsx +++ b/src/components/WorkspaceMembersSelectionList.tsx @@ -95,7 +95,7 @@ function WorkspaceMembersSelectionList({policyID, selectedApprover, setApprover} headerMessage: searchTerm && !orderedApprovers.length ? translate('common.noResultsFound') : '', onChangeText: setSearchTerm, }), - [searchTerm, orderedApprovers, setSearchTerm, translate], + [searchTerm, orderedApprovers?.length, setSearchTerm, translate], ); return ( diff --git a/src/pages/workspace/expensifyCard/issueNew/AssigneeStep.tsx b/src/pages/workspace/expensifyCard/issueNew/AssigneeStep.tsx index df044ea60c502..c1c548458f714 100644 --- a/src/pages/workspace/expensifyCard/issueNew/AssigneeStep.tsx +++ b/src/pages/workspace/expensifyCard/issueNew/AssigneeStep.tsx @@ -175,7 +175,16 @@ function AssigneeStep({policy, stepNames, startStepIndex, route}: AssigneeStepPr ...option, keyForList: option.keyForList ?? option.login ?? '', })); - }, [debouncedSearchTerm, areOptionsInitialized, countryCode, membersDetails, selectedOptionsForDisplay, availableOptions]); + }, [ + debouncedSearchTerm, + areOptionsInitialized, + countryCode, + membersDetails, + selectedOptionsForDisplay, + availableOptions?.recentReports, + availableOptions?.personalDetails, + availableOptions?.userToInvite, + ]); useEffect(() => { searchInServer(searchTerm); @@ -187,7 +196,7 @@ function AssigneeStep({policy, stepNames, startStepIndex, route}: AssigneeStepPr return translate('messages.errorMessageInvalidEmail'); } return getHeaderMessage(assignees.length > 0, !!availableOptions.userToInvite, searchValue, countryCode, false); - }, [searchTerm, availableOptions.userToInvite, assignees, countryCode, translate]); + }, [searchTerm, availableOptions.userToInvite, assignees?.length, countryCode, translate]); const textInputOptions = useMemo( () => ({ From 675b97fd0461d63c63f181f41ee2695332013d3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Musia=C5=82?= Date: Fri, 5 Dec 2025 12:50:06 +0100 Subject: [PATCH 6/8] fix redundant magic code reset --- src/pages/settings/Wallet/ExpensifyCardPage/index.tsx | 8 ++------ .../Wallet/ReportCardLostConfirmMagicCodePage.tsx | 6 +----- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/pages/settings/Wallet/ExpensifyCardPage/index.tsx b/src/pages/settings/Wallet/ExpensifyCardPage/index.tsx index f4dfeebb22489..aac45b58ec55e 100644 --- a/src/pages/settings/Wallet/ExpensifyCardPage/index.tsx +++ b/src/pages/settings/Wallet/ExpensifyCardPage/index.tsx @@ -119,10 +119,6 @@ function ExpensifyCardPage({route}: ExpensifyCardPageProps) { setIsNotFound(!currentCard); }, [cardList, cardsToShow, currentCard]); - useEffect(() => { - resetValidateActionCodeSent(); - }, []); - const virtualCards = useMemo(() => cardsToShow?.filter((card) => card?.nameValuePairs?.isVirtual && !card?.nameValuePairs?.isTravelCard), [cardsToShow]); const travelCards = useMemo(() => cardsToShow?.filter((card) => card?.nameValuePairs?.isVirtual && card?.nameValuePairs?.isTravelCard), [cardsToShow]); const physicalCards = useMemo(() => cardsToShow?.filter((card) => !card?.nameValuePairs?.isVirtual), [cardsToShow]); @@ -144,7 +140,7 @@ function ExpensifyCardPage({route}: ExpensifyCardPageProps) { const currentPhysicalCard = physicalCards?.find((card) => String(card?.cardID) === cardID); // Cards that are already activated and working (OPEN) and cards shipped but not activated yet can be reported as missing or damaged - const shouldShowReportLostCardButton = currentPhysicalCard?.state === CONST.EXPENSIFY_CARD.STATE.NOT_ACTIVATED || currentPhysicalCard?.state === CONST.EXPENSIFY_CARD.STATE.OPEN; + const shouldShowReportLostCardButton = currentPhysicalCard?.state === CONST.EXPENSIFY_CARD.STATE.NOT_ACTIVATED || currentPhysicalCard?.state === CONST.EXPENSIFY_CARD.STATE.OPEN || true; const currency = getCurrencyKeyByCountryCode(currencyList, currentCard?.nameValuePairs?.country ?? currentCard?.nameValuePairs?.feedCountry); const shouldShowPIN = currency !== CONST.CURRENCY.USD; @@ -247,7 +243,7 @@ function ExpensifyCardPage({route}: ExpensifyCardPageProps) { Navigation.navigate(ROUTES.SETTINGS_WALLET_CARD_MISSING_DETAILS.getRoute(String(card.cardID))); return; } - + resetValidateActionCodeSent(); if (route.name === SCREENS.DOMAIN_CARD.DOMAIN_CARD_DETAIL) { Navigation.navigate(ROUTES.SETTINGS_DOMAIN_CARD_CONFIRM_MAGIC_CODE.getRoute(String(card.cardID))); return; diff --git a/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx b/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx index 0520e1d9a9a72..a6964ea1fe711 100644 --- a/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx +++ b/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx @@ -31,7 +31,7 @@ function ReportCardLostConfirmMagicCodePage({ const primaryLogin = account?.primaryLogin ?? ''; const [cardList] = useOnyx(ONYXKEYS.CARD_LIST, {canBeMissing: true}); const physicalCard = cardList?.[cardID]; - const [newCardID, setNewCardID] = useState(''); + const [newCardID, setNewCardID] = useState('23580564'); const previousCardList = usePrevious(cardList); const validateError = getLatestErrorMessageField(physicalCard); @@ -43,10 +43,6 @@ function ReportCardLostConfirmMagicCodePage({ setNewCardID(newID); }, [cardList, physicalCard?.cardID, previousCardList]); - useEffect(() => { - resetValidateActionCodeSent(); - }, []); - useEffect(() => { if (formData?.isLoading && isEmptyObject(physicalCard?.errors)) { return; From e91250731e412cf60e1ef9eb02a8df44eab984a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Musia=C5=82?= Date: Fri, 5 Dec 2025 12:52:59 +0100 Subject: [PATCH 7/8] remove test code --- src/pages/settings/Wallet/ExpensifyCardPage/index.tsx | 2 +- .../settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/settings/Wallet/ExpensifyCardPage/index.tsx b/src/pages/settings/Wallet/ExpensifyCardPage/index.tsx index aac45b58ec55e..42e86fba0ef64 100644 --- a/src/pages/settings/Wallet/ExpensifyCardPage/index.tsx +++ b/src/pages/settings/Wallet/ExpensifyCardPage/index.tsx @@ -140,7 +140,7 @@ function ExpensifyCardPage({route}: ExpensifyCardPageProps) { const currentPhysicalCard = physicalCards?.find((card) => String(card?.cardID) === cardID); // Cards that are already activated and working (OPEN) and cards shipped but not activated yet can be reported as missing or damaged - const shouldShowReportLostCardButton = currentPhysicalCard?.state === CONST.EXPENSIFY_CARD.STATE.NOT_ACTIVATED || currentPhysicalCard?.state === CONST.EXPENSIFY_CARD.STATE.OPEN || true; + const shouldShowReportLostCardButton = currentPhysicalCard?.state === CONST.EXPENSIFY_CARD.STATE.NOT_ACTIVATED || currentPhysicalCard?.state === CONST.EXPENSIFY_CARD.STATE.OPEN; const currency = getCurrencyKeyByCountryCode(currencyList, currentCard?.nameValuePairs?.country ?? currentCard?.nameValuePairs?.feedCountry); const shouldShowPIN = currency !== CONST.CURRENCY.USD; diff --git a/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx b/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx index a6964ea1fe711..2af37c3114de7 100644 --- a/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx +++ b/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx @@ -31,7 +31,7 @@ function ReportCardLostConfirmMagicCodePage({ const primaryLogin = account?.primaryLogin ?? ''; const [cardList] = useOnyx(ONYXKEYS.CARD_LIST, {canBeMissing: true}); const physicalCard = cardList?.[cardID]; - const [newCardID, setNewCardID] = useState('23580564'); + const [newCardID, setNewCardID] = useState(''); const previousCardList = usePrevious(cardList); const validateError = getLatestErrorMessageField(physicalCard); From 75a19d7fd7577daa3c00594ffb18ef96924b760a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Musia=C5=82?= Date: Tue, 9 Dec 2025 12:20:05 +0100 Subject: [PATCH 8/8] fix for reload --- .../Wallet/ReportCardLostConfirmMagicCodePage.tsx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx b/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx index 2af37c3114de7..be1889ba8dbdb 100644 --- a/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx +++ b/src/pages/settings/Wallet/ReportCardLostConfirmMagicCodePage.tsx @@ -1,3 +1,4 @@ +import {deepEqual} from 'fast-equals'; import React, {useCallback, useEffect, useState} from 'react'; import ScreenWrapper from '@components/ScreenWrapper'; import ValidateCodeActionContent from '@components/ValidateCodeActionModal/ValidateCodeActionContent'; @@ -14,7 +15,6 @@ import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; -import {isEmptyObject} from '@src/types/utils/EmptyObject'; import SuccessReportCardLost from './SuccessReportCardLost'; type ReportCardLostConfirmMagicCodePageProps = PlatformStackScreenProps; @@ -44,12 +44,17 @@ function ReportCardLostConfirmMagicCodePage({ }, [cardList, physicalCard?.cardID, previousCardList]); useEffect(() => { - if (formData?.isLoading && isEmptyObject(physicalCard?.errors)) { + if (formData?.isLoading) { return; } - setErrors(ONYXKEYS.FORMS.REPORT_PHYSICAL_CARD_FORM, physicalCard?.errors ?? {}); - }, [formData?.isLoading, physicalCard?.errors]); + const newErrors = physicalCard?.errors ?? {}; + // Only update if errors have actually changed to prevent additional rerender + if (deepEqual(newErrors, formData?.errors ?? {})) { + return; + } + setErrors(ONYXKEYS.FORMS.REPORT_PHYSICAL_CARD_FORM, newErrors); + }, [formData?.isLoading, formData?.errors, physicalCard?.errors]); const handleValidateCodeEntered = useCallback( (validateCode: string) => {