forked from Expensify/App
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPhoneNumberPage.tsx
More file actions
136 lines (123 loc) · 6.23 KB
/
PhoneNumberPage.tsx
File metadata and controls
136 lines (123 loc) · 6.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import React, {useCallback} from 'react';
import DelegateNoAccessWrapper from '@components/DelegateNoAccessWrapper';
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 useAutoFocusInput from '@hooks/useAutoFocusInput';
import useLocalize from '@hooks/useLocalize';
import useOnyx from '@hooks/useOnyx';
import useThemeStyles from '@hooks/useThemeStyles';
import {getEarliestErrorField} from '@libs/ErrorUtils';
import {appendCountryCode, formatE164PhoneNumber} from '@libs/LoginUtils';
import Navigation from '@libs/Navigation/Navigation';
import type {SkeletonSpanReasonAttributes} from '@libs/telemetry/useSkeletonSpan';
import {isRequiredFulfilled, isValidPhoneNumber} from '@libs/ValidationUtils';
import {clearPhoneNumberError, updatePhoneNumber as updatePhone} 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 = true] = useOnyx(ONYXKEYS.IS_LOADING_APP);
const [countryCode = CONST.DEFAULT_COUNTRY_CODE] = useOnyx(ONYXKEYS.COUNTRY_CODE);
const styles = useThemeStyles();
const {translate} = useLocalize();
const {inputCallbackRef} = useAutoFocusInput();
const phoneNumber = privatePersonalDetails?.phoneNumber ?? '';
const validateLoginError = getEarliestErrorField(privatePersonalDetails, 'phoneNumber');
const currenPhoneNumber = privatePersonalDetails?.phoneNumber ?? '';
const updatePhoneNumber = (values: PrivatePersonalDetails) => {
// Clear the error when the user tries to submit the form
if (validateLoginError) {
clearPhoneNumberError();
}
// Only call the API if the user has changed their phone number
if (values?.phoneNumber && phoneNumber !== values.phoneNumber) {
updatePhone(formatE164PhoneNumber(values.phoneNumber, countryCode) ?? '', currenPhoneNumber);
}
Navigation.goBack();
};
const validate = useCallback(
(values: FormOnyxValues<typeof ONYXKEYS.FORMS.PERSONAL_DETAILS_FORM>): FormInputErrors<typeof ONYXKEYS.FORMS.PERSONAL_DETAILS_FORM> => {
const errors: FormInputErrors<typeof ONYXKEYS.FORMS.PERSONAL_DETAILS_FORM> = {};
const phoneNumberValue = values[INPUT_IDS.PHONE_NUMBER];
if (!isRequiredFulfilled(phoneNumberValue)) {
errors[INPUT_IDS.PHONE_NUMBER] = translate('common.error.fieldRequired');
return errors;
}
const phoneNumberWithCountryCode = appendCountryCode(phoneNumberValue, countryCode);
if (!isValidPhoneNumber(phoneNumberWithCountryCode)) {
errors[INPUT_IDS.PHONE_NUMBER] = translate('common.error.phoneNumber');
return errors;
}
if (validateLoginError && Object.keys(errors).length > 0) {
clearPhoneNumberError();
}
return errors;
},
[translate, validateLoginError, countryCode],
);
return (
<ScreenWrapper
includeSafeAreaPaddingBottom
shouldEnableMaxHeight
testID="PhoneNumberPage"
>
<DelegateNoAccessWrapper accessDeniedVariants={[CONST.DELEGATE.DENIED_ACCESS_VARIANTS.DELEGATE]}>
<HeaderWithBackButton
title={translate('common.phoneNumber')}
onBackButtonPress={() => Navigation.goBack()}
/>
{isLoadingApp ? (
<FullscreenLoadingIndicator
style={[styles.flex1, styles.pRelative]}
reasonAttributes={{context: 'PhoneNumberPage', isLoadingApp} satisfies SkeletonSpanReasonAttributes}
/>
) : (
<FormProvider
style={[styles.flexGrow1, styles.ph5]}
formID={ONYXKEYS.FORMS.PERSONAL_DETAILS_FORM}
validate={validate}
onSubmit={updatePhoneNumber}
submitButtonText={translate('common.save')}
enabledWhenOffline
shouldHideFixErrorsAlert
>
<OfflineWithFeedback
errors={validateLoginError}
errorRowStyles={styles.mt2}
onClose={() => clearPhoneNumberError()}
>
<InputWrapper
InputComponent={TextInput}
ref={inputCallbackRef}
inputID={INPUT_IDS.PHONE_NUMBER}
name="phoneNumber"
label={translate('common.phoneNumber')}
aria-label={translate('common.phoneNumber')}
role={CONST.ROLE.PRESENTATION}
defaultValue={phoneNumber}
spellCheck={false}
inputMode={CONST.INPUT_MODE.TEL}
onBlur={() => {
if (!validateLoginError) {
return;
}
clearPhoneNumberError();
}}
autoComplete="tel"
/>
</OfflineWithFeedback>
</FormProvider>
)}
</DelegateNoAccessWrapper>
</ScreenWrapper>
);
}
export default PhoneNumberPage;