diff --git a/src/libs/actions/PersonalDetails.ts b/src/libs/actions/PersonalDetails.ts index 94a9dc95e846..05fc87cf2802 100644 --- a/src/libs/actions/PersonalDetails.ts +++ b/src/libs/actions/PersonalDetails.ts @@ -465,6 +465,15 @@ function clearAvatarErrors() { }); } +/** + * Clear errors for the current user's personal details + */ +function clearPersonalDetailsErrors() { + Onyx.merge(ONYXKEYS.PRIVATE_PERSONAL_DETAILS, { + errors: null, + }); +} + function updatePersonalDetailsAndShipExpensifyCards(values: FormOnyxValues, validateCode: string) { const parameters: SetPersonalDetailsAndShipExpensifyCardsParams = { legalFirstName: values.legalFirstName?.trim() ?? '', @@ -486,21 +495,16 @@ function updatePersonalDetailsAndShipExpensifyCards(values: FormOnyxValues = useRef(null); @@ -73,7 +68,7 @@ function MissingPersonalDetailsContent({privatePersonalDetails, draftValues}: Mi // Clicking back on the first screen should dismiss the modal if (screenIndex === CONST.MISSING_PERSONAL_DETAILS_INDEXES.MAPPING.LEGAL_NAME) { - FormActions.clearDraftValues(ONYXKEYS.FORMS.PERSONAL_DETAILS_FORM); + clearDraftValues(ONYXKEYS.FORMS.PERSONAL_DETAILS_FORM); Navigation.goBack(); return; } @@ -81,23 +76,13 @@ function MissingPersonalDetailsContent({privatePersonalDetails, draftValues}: Mi prevScreen(); }; - const handleValidateCodeEntered = useCallback( + const handleSubmitForm = useCallback( (validateCode: string) => { - PersonalDetails.updatePersonalDetailsAndShipExpensifyCards(values, validateCode); - FormActions.clearDraftValues(ONYXKEYS.FORMS.PERSONAL_DETAILS_FORM); - Navigation.goBack(); + updatePersonalDetailsAndShipExpensifyCards(values, validateCode); }, [values], ); - const sendValidateCode = () => { - if (validateCodeAction?.validateCodeSent) { - return; - } - - requestValidateCodeAction(); - }; - const handleNextScreen = useCallback(() => { if (isEditing) { goToTheLastStep(); @@ -132,15 +117,10 @@ function MissingPersonalDetailsContent({privatePersonalDetails, draftValues}: Mi personalDetailsValues={values} /> - {}} + setIsValidateCodeActionModalVisible(false)} - isVisible={isValidateCodeActionModalVisible} - title={translate('cardPage.validateCardTitle')} - descriptionPrimary={translate('cardPage.enterMagicCode', {contactMethod: primaryLogin})} - hasMagicCodeBeenSent={!!validateCodeAction?.validateCodeSent} + isValidateCodeActionModalVisible={isValidateCodeActionModalVisible} + handleSubmitForm={handleSubmitForm} /> ); diff --git a/src/pages/MissingPersonalDetails/MissingPersonalDetailsMagicCodeModal.tsx b/src/pages/MissingPersonalDetails/MissingPersonalDetailsMagicCodeModal.tsx new file mode 100644 index 000000000000..9b3210fbf2d9 --- /dev/null +++ b/src/pages/MissingPersonalDetails/MissingPersonalDetailsMagicCodeModal.tsx @@ -0,0 +1,74 @@ +import React, {useEffect} from 'react'; +import {useOnyx} from 'react-native-onyx'; +import ValidateCodeActionModal from '@components/ValidateCodeActionModal'; +import useLocalize from '@hooks/useLocalize'; +import {clearDraftValues} from '@libs/actions/FormActions'; +import {clearPersonalDetailsErrors} from '@libs/actions/PersonalDetails'; +import {requestValidateCodeAction} from '@libs/actions/User'; +import {getLatestError} from '@libs/ErrorUtils'; +import Navigation from '@libs/Navigation/Navigation'; +import ONYXKEYS from '@src/ONYXKEYS'; +import {isEmptyObject} from '@src/types/utils/EmptyObject'; + +type MissingPersonalDetailsMagicCodeModalProps = { + handleSubmitForm: (validateCode: string) => void; + isValidateCodeActionModalVisible: boolean; + onClose?: () => void; +}; + +function MissingPersonalDetailsMagicCodeModal({onClose, isValidateCodeActionModalVisible, handleSubmitForm}: MissingPersonalDetailsMagicCodeModalProps) { + const {translate} = useLocalize(); + const [privatePersonalDetails] = useOnyx(ONYXKEYS.PRIVATE_PERSONAL_DETAILS); + const [account] = useOnyx(ONYXKEYS.ACCOUNT); + const [validateCodeAction] = useOnyx(ONYXKEYS.VALIDATE_ACTION_CODE); + const privateDetailsErrors = privatePersonalDetails?.errors ?? undefined; + const validateLoginError = getLatestError(privateDetailsErrors); + const primaryLogin = account?.primaryLogin ?? ''; + + const missingDetails = + !privatePersonalDetails?.legalFirstName || + !privatePersonalDetails?.legalLastName || + !privatePersonalDetails?.dob || + !privatePersonalDetails?.phoneNumber || + isEmptyObject(privatePersonalDetails?.addresses) || + privatePersonalDetails.addresses.length === 0; + + useEffect(() => { + if (missingDetails || !!privateDetailsErrors) { + return; + } + + clearDraftValues(ONYXKEYS.FORMS.PERSONAL_DETAILS_FORM); + Navigation.goBack(); + }, [missingDetails, privateDetailsErrors]); + + const onBackButtonPress = () => { + onClose?.(); + }; + + const clearError = () => { + if (!validateLoginError) { + return; + } + clearPersonalDetailsErrors(); + }; + + return ( + requestValidateCodeAction()} + hasMagicCodeBeenSent={validateCodeAction?.validateCodeSent} + handleSubmitForm={handleSubmitForm} + isLoading={privatePersonalDetails?.isLoading} + /> + ); +} + +MissingPersonalDetailsMagicCodeModal.displayName = 'MissingPersonalDetailsMagicCodeModal'; + +export default MissingPersonalDetailsMagicCodeModal; diff --git a/src/types/onyx/PrivatePersonalDetails.ts b/src/types/onyx/PrivatePersonalDetails.ts index 1d88cd3af1ff..519cd7d26386 100644 --- a/src/types/onyx/PrivatePersonalDetails.ts +++ b/src/types/onyx/PrivatePersonalDetails.ts @@ -68,6 +68,12 @@ type PrivatePersonalDetails = { /** Error objects keyed by field name containing errors keyed by microtime */ errorFields?: OnyxCommon.ErrorFields; + + /** Authentication failure errors */ + errors?: OnyxCommon.Errors | null; + + /** Whether the request is being processed */ + isLoading?: boolean; }; export default PrivatePersonalDetails;