Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature]: Add phone number to the private personal details section #50773

Merged
merged 25 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0306beb
add phoneNumber RHP to private details page
allgandalf Oct 15, 2024
f90cc5d
fix lint and import UpdateLegalNameParams as type
allgandalf Oct 15, 2024
d017a85
Delete src/pages/settings/Profile/PersonalDetails/test.md
allgandalf Oct 15, 2024
a33bf2d
update to correct api command
allgandalf Oct 15, 2024
47b3dc9
fix typecheck, add update phone number to write command
allgandalf Oct 15, 2024
9446f6a
change the input header for phone number
allgandalf Oct 16, 2024
53d430a
add BE error RBR and error field to phone number
allgandalf Oct 21, 2024
5f274bb
fix eslint
allgandalf Oct 21, 2024
a82ee09
add top padding to error message
allgandalf Oct 22, 2024
a7e017c
add RBR for profile settings
allgandalf Oct 22, 2024
aed96f9
Merge branch 'main' into newPhoneNumberRHPForProfile
allgandalf Oct 22, 2024
23b9bc9
add RBR to Avatar Indicator
allgandalf Oct 22, 2024
4ea40be
pull up validation for phone number
allgandalf Oct 22, 2024
2ff3e62
Apply suggestions from code review
allgandalf Oct 22, 2024
c30c194
fix prettier
allgandalf Oct 22, 2024
96355c1
implement suggestions
allgandalf Oct 22, 2024
4414c13
clear BE error on blur
allgandalf Oct 23, 2024
89b1f44
fix lint
allgandalf Oct 24, 2024
3c927e2
return early if no error is present
allgandalf Oct 24, 2024
6a32dea
Merge branch 'Expensify:main' into newPhoneNumberRHPForProfile
allgandalf Oct 25, 2024
d0fb1b5
delete md file
allgandalf Oct 25, 2024
f539c52
clear BE error on validation
allgandalf Oct 25, 2024
7e4239e
Merge branch 'Expensify:main' into newPhoneNumberRHPForProfile
allgandalf Oct 27, 2024
e532ef1
fix lint
allgandalf Oct 27, 2024
c07af88
Apply suggestions from code review
allgandalf Oct 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5960,6 +5960,7 @@ const CONST = {
HAS_WALLET_TERMS_ERRORS: 'hasWalletTermsErrors',
HAS_LOGIN_LIST_INFO: 'hasLoginListInfo',
HAS_SUBSCRIPTION_INFO: 'hasSubscriptionInfo',
HAS_PHONE_NUMBER_ERROR: 'hasPhoneNumberError',
},

DEBUG: {
Expand Down
1 change: 1 addition & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ const ROUTES = {
},
SETTINGS_LEGAL_NAME: 'settings/profile/legal-name',
SETTINGS_DATE_OF_BIRTH: 'settings/profile/date-of-birth',
SETTINGS_PHONE_NUMBER: 'settings/profile/phone',
SETTINGS_ADDRESS: 'settings/profile/address',
SETTINGS_ADDRESS_COUNTRY: {
route: 'settings/profile/address/country',
Expand Down
1 change: 1 addition & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ const SCREENS = {
TIMEZONE_SELECT: 'Settings_Timezone_Select',
LEGAL_NAME: 'Settings_LegalName',
DATE_OF_BIRTH: 'Settings_DateOfBirth',
PHONE_NUMBER: 'Settings_PhoneNumber',
ADDRESS: 'Settings_Address',
ADDRESS_COUNTRY: 'Settings_Address_Country',
ADDRESS_STATE: 'Settings_Address_State',
Expand Down
2 changes: 2 additions & 0 deletions src/hooks/useIndicatorStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ function useIndicatorStatus(): IndicatorStatusResult {
const [userWallet] = useOnyx(ONYXKEYS.USER_WALLET);
const [walletTerms] = useOnyx(ONYXKEYS.WALLET_TERMS);
const [loginList] = useOnyx(ONYXKEYS.LOGIN_LIST);
const [privatePersoanlDetails] = useOnyx(ONYXKEYS.PRIVATE_PERSONAL_DETAILS);
allgandalf marked this conversation as resolved.
Show resolved Hide resolved

// If a policy was just deleted from Onyx, then Onyx will pass a null value to the props, and
// those should be cleaned out before doing any error checking
Expand Down Expand Up @@ -57,6 +58,7 @@ function useIndicatorStatus(): IndicatorStatusResult {
[CONST.INDICATOR_STATUS.HAS_LOGIN_LIST_ERROR]: !!loginList && UserUtils.hasLoginListError(loginList),
// Wallet term errors that are not caused by an IOU (we show the red brick indicator for those in the LHN instead)
[CONST.INDICATOR_STATUS.HAS_WALLET_TERMS_ERRORS]: Object.keys(walletTerms?.errors ?? {}).length > 0 && !walletTerms?.chatReportID,
[CONST.INDICATOR_STATUS.HAS_PHONE_NUMBER_ERROR]: !!privatePersoanlDetails?.errorFields?.phoneNumber ?? undefined,
allgandalf marked this conversation as resolved.
Show resolved Hide resolved
};

const infoChecking: Partial<Record<IndicatorStatus, boolean>> = {
Expand Down
1 change: 1 addition & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1783,6 +1783,7 @@ const translations = {
dateShouldBeAfter: ({dateString}: DateShouldBeAfterParams) => `Date should be after ${dateString}.`,
hasInvalidCharacter: 'Name can only include Latin characters.',
incorrectZipFormat: ({zipFormat}: IncorrectZipFormatParams = {}) => `Incorrect zip code format.${zipFormat ? ` Acceptable format: ${zipFormat}` : ''}`,
invalidPhoneNumber: `Please ensure the phone number is valid (e.g. ${CONST.EXAMPLE_PHONE_NUMBER}).`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we reuse error.phoneNumber

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current error is more descriptive IMO, it specifies a US number !

},
},
resendValidationForm: {
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1784,6 +1784,7 @@ const translations = {
dateShouldBeAfter: ({dateString}: DateShouldBeAfterParams) => `La fecha debe ser posterior a ${dateString}.`,
incorrectZipFormat: ({zipFormat}: IncorrectZipFormatParams = {}) => `Formato de código postal incorrecto.${zipFormat ? ` Formato aceptable: ${zipFormat}` : ''}`,
hasInvalidCharacter: 'El nombre sólo puede incluir caracteres latinos.',
invalidPhoneNumber: `Asegúrese de que el número de teléfono sean válidos (p. ej. ${CONST.EXAMPLE_PHONE_NUMBER}).`,
},
},
resendValidationForm: {
Expand Down
5 changes: 5 additions & 0 deletions src/libs/API/parameters/UpdatePhoneNumberParams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
type UpdatePhoneNumberParams = {
phoneNumber?: string;
};

export default UpdatePhoneNumberParams;
1 change: 1 addition & 0 deletions src/libs/API/parameters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export type {default as UpdateGroupChatMemberRolesParams} from './UpdateGroupCha
export type {default as UpdateHomeAddressParams} from './UpdateHomeAddressParams';
export type {default as UpdatePolicyAddressParams} from './UpdatePolicyAddressParams';
export type {default as UpdateLegalNameParams} from './UpdateLegalNameParams';
export type {default as UpdatePhoneNumberParams} from './UpdatePhoneNumberParams';
export type {default as UpdateNewsletterSubscriptionParams} from './UpdateNewsletterSubscriptionParams';
export type {default as UpdatePersonalInformationForBankAccountParams} from './UpdatePersonalInformationForBankAccountParams';
export type {default as UpdatePreferredEmojiSkinToneParams} from './UpdatePreferredEmojiSkinToneParams';
Expand Down
2 changes: 2 additions & 0 deletions src/libs/API/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ const WRITE_COMMANDS = {
UPDATE_DISPLAY_NAME: 'UpdateDisplayName',
UPDATE_LEGAL_NAME: 'UpdateLegalName',
UPDATE_DATE_OF_BIRTH: 'UpdateDateOfBirth',
UPDATE_PHONE_NUMBER: 'UpdatePhoneNumber',
UPDATE_HOME_ADDRESS: 'UpdateHomeAddress',
UPDATE_POLICY_ADDRESS: 'SetPolicyAddress',
UPDATE_AUTOMATIC_TIMEZONE: 'UpdateAutomaticTimezone',
Expand Down Expand Up @@ -466,6 +467,7 @@ type WriteCommandParameters = {
[WRITE_COMMANDS.UPDATE_DISPLAY_NAME]: Parameters.UpdateDisplayNameParams;
[WRITE_COMMANDS.UPDATE_LEGAL_NAME]: Parameters.UpdateLegalNameParams;
[WRITE_COMMANDS.UPDATE_DATE_OF_BIRTH]: Parameters.UpdateDateOfBirthParams;
[WRITE_COMMANDS.UPDATE_PHONE_NUMBER]: Parameters.UpdatePhoneNumberParams;
[WRITE_COMMANDS.UPDATE_POLICY_ADDRESS]: Parameters.UpdatePolicyAddressParams;
[WRITE_COMMANDS.UPDATE_HOME_ADDRESS]: Parameters.UpdateHomeAddressParams;
[WRITE_COMMANDS.UPDATE_AUTOMATIC_TIMEZONE]: Parameters.UpdateAutomaticTimezoneParams;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorP
[SCREENS.SETTINGS.PROFILE.TIMEZONE_SELECT]: () => require<ReactComponentModule>('../../../../pages/settings/Profile/TimezoneSelectPage').default,
[SCREENS.SETTINGS.PROFILE.LEGAL_NAME]: () => require<ReactComponentModule>('../../../../pages/settings/Profile/PersonalDetails/LegalNamePage').default,
[SCREENS.SETTINGS.PROFILE.DATE_OF_BIRTH]: () => require<ReactComponentModule>('../../../../pages/settings/Profile/PersonalDetails/DateOfBirthPage').default,
[SCREENS.SETTINGS.PROFILE.PHONE_NUMBER]: () => require<ReactComponentModule>('../../../../pages/settings/Profile/PersonalDetails/PhoneNumberPage').default,
[SCREENS.SETTINGS.PROFILE.ADDRESS]: () => require<ReactComponentModule>('../../../../pages/settings/Profile/PersonalDetails/PersonalAddressPage').default,
[SCREENS.SETTINGS.PROFILE.ADDRESS_COUNTRY]: () => require<ReactComponentModule>('../../../../pages/settings/Profile/PersonalDetails/CountrySelectionPage').default,
[SCREENS.SETTINGS.PROFILE.ADDRESS_STATE]: () => require<ReactComponentModule>('../../../../pages/settings/Profile/PersonalDetails/StateSelectionPage').default,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const CENTRAL_PANE_TO_RHP_MAPPING: Partial<Record<CentralPaneName, string[]>> =
SCREENS.SETTINGS.PROFILE.TIMEZONE_SELECT,
SCREENS.SETTINGS.PROFILE.LEGAL_NAME,
SCREENS.SETTINGS.PROFILE.DATE_OF_BIRTH,
SCREENS.SETTINGS.PROFILE.PHONE_NUMBER,
SCREENS.SETTINGS.PROFILE.ADDRESS,
SCREENS.SETTINGS.PROFILE.ADDRESS_COUNTRY,
SCREENS.SETTINGS.SHARE_CODE,
Expand Down
4 changes: 4 additions & 0 deletions src/libs/Navigation/linkingConfig/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,10 @@ const config: LinkingOptions<RootStackParamList>['config'] = {
path: ROUTES.SETTINGS_LEGAL_NAME,
exact: true,
},
[SCREENS.SETTINGS.PROFILE.PHONE_NUMBER]: {
path: ROUTES.SETTINGS_PHONE_NUMBER,
exact: true,
},
[SCREENS.SETTINGS.PROFILE.DATE_OF_BIRTH]: {
path: ROUTES.SETTINGS_DATE_OF_BIRTH,
exact: true,
Expand Down
20 changes: 19 additions & 1 deletion src/libs/UserUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as defaultAvatars from '@components/Icon/DefaultAvatars';
import {ConciergeAvatar, NotificationsAvatar} from '@components/Icon/Expensicons';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {Account, LoginList, Session} from '@src/types/onyx';
import type {Account, LoginList, PrivatePersonalDetails, Session} from '@src/types/onyx';
import type Login from '@src/types/onyx/Login';
import type IconAsset from '@src/types/utils/IconAsset';
import hashCode from './hashCode';
Expand Down Expand Up @@ -78,6 +78,23 @@ function getLoginListBrickRoadIndicator(loginList: OnyxEntry<LoginList>): LoginL
if (hasLoginListInfo(loginList)) {
return CONST.BRICK_ROAD_INDICATOR_STATUS.INFO;
}

return undefined;
}

allgandalf marked this conversation as resolved.
Show resolved Hide resolved
/**
* Gets the appropriate brick road indicator status for the Profile section.
* Error status is higher priority, so we check for that first.
*/
function getProfilePageBrickRoadIndicator(loginList: OnyxEntry<LoginList>, privatePersoanlDetails: OnyxEntry<PrivatePersonalDetails>): LoginListIndicator {
allgandalf marked this conversation as resolved.
Show resolved Hide resolved
const hasPhoneNumberError = !!privatePersoanlDetails?.errorFields?.phoneNumber;
allgandalf marked this conversation as resolved.
Show resolved Hide resolved
if (hasLoginListError(loginList) || hasPhoneNumberError) {
return CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR;
}
if (hasLoginListInfo(loginList)) {
return CONST.BRICK_ROAD_INDICATOR_STATUS.INFO;
}

return undefined;
}

Expand Down Expand Up @@ -240,6 +257,7 @@ export {
getDefaultAvatarURL,
getFullSizeAvatar,
getLoginListBrickRoadIndicator,
getProfilePageBrickRoadIndicator,
getSecondaryPhoneLogin,
getSmallSizeAvatar,
hasLoginListError,
Expand Down
39 changes: 39 additions & 0 deletions src/libs/actions/PersonalDetails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ import type {
UpdateDisplayNameParams,
UpdateHomeAddressParams,
UpdateLegalNameParams,
UpdatePhoneNumberParams,
UpdatePronounsParams,
UpdateSelectedTimezoneParams,
UpdateUserAvatarParams,
} from '@libs/API/parameters';
import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types';
import type {CustomRNImageManipulatorResult} from '@libs/cropOrRotateImage/types';
import DateUtils from '@libs/DateUtils';
import * as ErrorUtils from '@libs/ErrorUtils';
import * as LoginUtils from '@libs/LoginUtils';
import Navigation from '@libs/Navigation/Navigation';
import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils';
Expand Down Expand Up @@ -157,6 +159,41 @@ function updateDateOfBirth({dob}: DateOfBirthForm) {
Navigation.goBack();
}

function updatePhoneNumber(phoneNumber: string, currenPhoneNumber: string) {
const parameters: UpdatePhoneNumberParams = {phoneNumber};
API.write(WRITE_COMMANDS.UPDATE_PHONE_NUMBER, parameters, {
optimisticData: [
mountiny marked this conversation as resolved.
Show resolved Hide resolved
{
onyxMethod: Onyx.METHOD.MERGE,
key: ONYXKEYS.PRIVATE_PERSONAL_DETAILS,
value: {
phoneNumber,
},
},
],
failureData: [
{
onyxMethod: Onyx.METHOD.MERGE,
key: ONYXKEYS.PRIVATE_PERSONAL_DETAILS,
value: {
phoneNumber: currenPhoneNumber,
errorFields: {
phoneNumber: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('privatePersonalDetails.error.invalidPhoneNumber'),
},
},
},
],
});
}

function clearPhoneNumberError() {
Onyx.merge(ONYXKEYS.PRIVATE_PERSONAL_DETAILS, {
errorFields: {
phoneNumber: null,
},
});
}

function updateAddress(street: string, street2: string, city: string, state: string, zip: string, country: Country | '') {
const parameters: UpdateHomeAddressParams = {
homeAddressStreet: street,
Expand Down Expand Up @@ -480,6 +517,8 @@ export {
setDisplayName,
updateDisplayName,
updateLegalName,
updatePhoneNumber,
clearPhoneNumberError,
updatePronouns,
updateSelectedTimezone,
updatePersonalDetailsAndShipExpensifyCards,
Expand Down
5 changes: 3 additions & 2 deletions src/pages/settings/InitialSettingsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ function InitialSettingsPage({currentUserPersonalDetails}: InitialSettingsPagePr
const [walletTerms] = useOnyx(ONYXKEYS.WALLET_TERMS);
const [loginList] = useOnyx(ONYXKEYS.LOGIN_LIST);
const [policies] = useOnyx(ONYXKEYS.COLLECTION.POLICY);
const [privatePersoanlDetails] = useOnyx(ONYXKEYS.PRIVATE_PERSONAL_DETAILS);
allgandalf marked this conversation as resolved.
Show resolved Hide resolved

const network = useNetwork();
const theme = useTheme();
Expand Down Expand Up @@ -126,7 +127,7 @@ function InitialSettingsPage({currentUserPersonalDetails}: InitialSettingsPagePr
* @returns object with translationKey, style and items for the account section
*/
const accountMenuItemsData: Menu = useMemo(() => {
const profileBrickRoadIndicator = UserUtils.getLoginListBrickRoadIndicator(loginList);
const profileBrickRoadIndicator = UserUtils.getProfilePageBrickRoadIndicator(loginList, privatePersoanlDetails);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we use getLoginListBrickRoadIndicator for the contact section as well, we needed to introduce a new util for the whole profile section.

allgandalf marked this conversation as resolved.
Show resolved Hide resolved
const paymentCardList = fundList;
const defaultMenu: Menu = {
sectionStyle: styles.accountSettingsSectionContainer,
Expand Down Expand Up @@ -161,7 +162,7 @@ function InitialSettingsPage({currentUserPersonalDetails}: InitialSettingsPagePr
};

return defaultMenu;
}, [loginList, fundList, styles.accountSettingsSectionContainer, bankAccountList, userWallet?.errors, walletTerms?.errors]);
}, [loginList, fundList, styles.accountSettingsSectionContainer, bankAccountList, userWallet?.errors, walletTerms?.errors, privatePersoanlDetails]);
allgandalf marked this conversation as resolved.
Show resolved Hide resolved

/**
* Retuns a list of menu items data for workspace section
Expand Down
121 changes: 121 additions & 0 deletions src/pages/settings/Profile/PersonalDetails/PhoneNumberPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import {Str} from 'expensify-common';
import React, {useCallback} from 'react';
import {useOnyx} from 'react-native-onyx';
import FormProvider from '@components/Form/FormProvider';
import InputWrapper from '@components/Form/InputWrapper';
import type {FormInputErrors, FormOnyxValues} from '@components/Form/types';
import FullscreenLoadingIndicator from '@components/FullscreenLoadingIndicator';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import OfflineWithFeedback from '@components/OfflineWithFeedback';
import ScreenWrapper from '@components/ScreenWrapper';
import TextInput from '@components/TextInput';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as ErrorUtils from '@libs/ErrorUtils';
import * as LoginUtils from '@libs/LoginUtils';
import Navigation from '@libs/Navigation/Navigation';
import * as PhoneNumberUtils from '@libs/PhoneNumber';
import * as ValidationUtils from '@libs/ValidationUtils';
import * as PersonalDetails from '@userActions/PersonalDetails';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import INPUT_IDS from '@src/types/form/PersonalDetailsForm';
import type {PrivatePersonalDetails} from '@src/types/onyx';

function PhoneNumberPage() {
const [privatePersonalDetails] = useOnyx(ONYXKEYS.PRIVATE_PERSONAL_DETAILS);
const [isLoadingApp] = useOnyx(ONYXKEYS.IS_LOADING_APP, {initialValue: true});
const styles = useThemeStyles();
const {translate} = useLocalize();
const phoneNumber = privatePersonalDetails?.phoneNumber ?? '';

const validateLoginError = ErrorUtils.getEarliestErrorField(privatePersonalDetails, 'phoneNumber');
const currenPhoneNumber = privatePersonalDetails?.phoneNumber ?? '';

const updatePhoneNumber = (values: PrivatePersonalDetails) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please clear the error when submit phone number

// Clear the error when the user tries to submit the form
if (validateLoginError) {
PersonalDetails.clearPhoneNumberError();
}

// Only call the API if the user has changed their phone number
if (phoneNumber !== values?.phoneNumber) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should move thí check to above validateLoginError

PersonalDetails.updatePhoneNumber(values?.phoneNumber ?? '', currenPhoneNumber);
}

Navigation.goBack();
};

const validate = useCallback(
mountiny marked this conversation as resolved.
Show resolved Hide resolved
(values: FormOnyxValues<typeof ONYXKEYS.FORMS.PERSONAL_DETAILS_FORM>): FormInputErrors<typeof ONYXKEYS.FORMS.PERSONAL_DETAILS_FORM> => {
const errors: FormInputErrors<typeof ONYXKEYS.FORMS.PERSONAL_DETAILS_FORM> = {};
if (!ValidationUtils.isRequiredFulfilled(values[INPUT_IDS.PHONE_NUMBER])) {
errors[INPUT_IDS.PHONE_NUMBER] = translate('common.error.fieldRequired');
}
const phoneNumberWithCountryCode = LoginUtils.appendCountryCode(values[INPUT_IDS.PHONE_NUMBER]);
const parsedPhoneNumber = PhoneNumberUtils.parsePhoneNumber(phoneNumberWithCountryCode);
if (!parsedPhoneNumber.possible || !Str.isValidE164Phone(phoneNumberWithCountryCode.slice(0))) {
errors[INPUT_IDS.PHONE_NUMBER] = translate('bankAccount.error.phoneNumber');
}

// Clear the error when the user tries to validate the form and there are errors
if (validateLoginError && !!errors) {
PersonalDetails.clearPhoneNumberError();
}
return errors;
},
[translate],

Check warning on line 67 in src/pages/settings/Profile/PersonalDetails/PhoneNumberPage.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

React Hook useCallback has a missing dependency: 'validateLoginError'. Either include it or remove the dependency array
);

return (
<ScreenWrapper
includeSafeAreaPaddingBottom={false}
shouldEnableMaxHeight
testID={PhoneNumberPage.displayName}
>
<HeaderWithBackButton
title={translate('common.phoneNumber')}
onBackButtonPress={() => Navigation.goBack()}
/>
{isLoadingApp ? (
<FullscreenLoadingIndicator style={[styles.flex1, styles.pRelative]} />
) : (
<FormProvider
style={[styles.flexGrow1, styles.ph5]}
formID={ONYXKEYS.FORMS.PERSONAL_DETAILS_FORM}
validate={validate}
onSubmit={updatePhoneNumber}
submitButtonText={translate('common.save')}
enabledWhenOffline
>
<OfflineWithFeedback
errors={validateLoginError}
errorRowStyles={styles.mt2}
onClose={() => PersonalDetails.clearPhoneNumberError()}
>
<InputWrapper
InputComponent={TextInput}
inputID={INPUT_IDS.PHONE_NUMBER}
name="lfname"
label={translate('common.phoneNumber')}
aria-label={translate('common.phoneNumber')}
role={CONST.ROLE.PRESENTATION}
defaultValue={phoneNumber}
spellCheck={false}
onBlur={() => {
if (!validateLoginError) {
return;
}
PersonalDetails.clearPhoneNumberError();
}}
/>
</OfflineWithFeedback>
</FormProvider>
)}
</ScreenWrapper>
);
}

PhoneNumberPage.displayName = 'PhoneNumberPage';

export default PhoneNumberPage;
7 changes: 7 additions & 0 deletions src/pages/settings/Profile/ProfilePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ function ProfilePage() {
title: privateDetails.dob ?? '',
pageRoute: ROUTES.SETTINGS_DATE_OF_BIRTH,
},
{
description: translate('common.phoneNumber'),
title: privateDetails.phoneNumber ?? '',
pageRoute: ROUTES.SETTINGS_PHONE_NUMBER,
brickRoadIndicator: privatePersonalDetails?.errorFields?.phoneNumber ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined,
},
{
description: translate('privatePersonalDetails.address'),
title: PersonalDetailsUtils.getFormattedAddress(privateDetails),
Expand Down Expand Up @@ -195,6 +201,7 @@ function ProfilePage() {
description={detail.description}
wrapperStyle={styles.sectionMenuItemTopDescription}
onPress={() => Navigation.navigate(detail.pageRoute)}
brickRoadIndicator={detail.brickRoadIndicator}
/>
))}
</>
Expand Down
Loading
Loading