Skip to content

Commit 2b5cf35

Browse files
committed
revert all changes in base onboarding email
1 parent e2ca6eb commit 2b5cf35

1 file changed

Lines changed: 179 additions & 87 deletions

File tree

Lines changed: 179 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,75 @@
11
import {useIsFocused} from '@react-navigation/native';
2-
import React, {useCallback, useEffect} from 'react';
2+
import {PUBLIC_DOMAINS_SET, Str} from 'expensify-common';
3+
import React, {useCallback, useEffect, useState} from 'react';
34
import {View} from 'react-native';
4-
import BlockingView from '@components/BlockingViews/BlockingView';
5+
import AutoEmailLink from '@components/AutoEmailLink';
56
import Button from '@components/Button';
7+
import FormProvider from '@components/Form/FormProvider';
8+
import InputWrapper from '@components/Form/InputWrapper';
9+
import type {FormOnyxValues} from '@components/Form/types';
610
import HeaderWithBackButton from '@components/HeaderWithBackButton';
11+
import Icon from '@components/Icon';
712
import * as Illustrations from '@components/Icon/Illustrations';
13+
import OfflineWithFeedback from '@components/OfflineWithFeedback';
814
import ScreenWrapper from '@components/ScreenWrapper';
915
import Text from '@components/Text';
10-
import ValidateCodeForm from '@components/ValidateCodeActionModal/ValidateCodeForm';
16+
import TextInput from '@components/TextInput';
17+
import useAutoFocusInput from '@hooks/useAutoFocusInput';
1118
import useLocalize from '@hooks/useLocalize';
19+
import useNetwork from '@hooks/useNetwork';
1220
import useOnyx from '@hooks/useOnyx';
1321
import useResponsiveLayout from '@hooks/useResponsiveLayout';
1422
import useThemeStyles from '@hooks/useThemeStyles';
15-
import AccountUtils from '@libs/AccountUtils';
16-
import {openOldDotLink} from '@libs/actions/Link';
17-
import {setOnboardingErrorMessage, setOnboardingMergeAccountStepValue, updateOnboardingValuesAndNavigation} from '@libs/actions/Welcome';
23+
import {isMobileSafari} from '@libs/Browser';
24+
import {addErrorMessage} from '@libs/ErrorUtils';
25+
import getOperatingSystem from '@libs/getOperatingSystem';
1826
import Navigation from '@libs/Navigation/Navigation';
19-
import variables from '@styles/variables';
20-
import {MergeIntoAccountAndLogin} from '@userActions/Session';
21-
import {resendValidateCode} from '@userActions/User';
27+
import {AddWorkEmail} from '@userActions/Session';
28+
import {setOnboardingErrorMessage, setOnboardingMergeAccountStepValue} from '@userActions/Welcome';
2229
import CONST from '@src/CONST';
30+
import type {TranslationPaths} from '@src/languages/types';
31+
import Log from '@src/libs/Log';
2332
import ONYXKEYS from '@src/ONYXKEYS';
2433
import ROUTES from '@src/ROUTES';
25-
import type {BaseOnboardingWorkEmailValidationProps} from './types';
34+
import INPUT_IDS from '@src/types/form/OnboardingWorkEmailForm';
35+
import type IconAsset from '@src/types/utils/IconAsset';
36+
import type {BaseOnboardingWorkEmailProps} from './types';
2637

27-
function BaseOnboardingWorkEmailValidation({shouldUseNativeStyles}: BaseOnboardingWorkEmailValidationProps) {
38+
type Item = {
39+
icon: IconAsset;
40+
titleTranslationKey: TranslationPaths;
41+
shouldRenderEmail?: boolean;
42+
};
43+
44+
function BaseOnboardingWorkEmail({shouldUseNativeStyles}: BaseOnboardingWorkEmailProps) {
2845
const styles = useThemeStyles();
2946
const {translate} = useLocalize();
30-
const [account] = useOnyx(ONYXKEYS.ACCOUNT, {canBeMissing: true});
31-
const [session] = useOnyx(ONYXKEYS.SESSION, {canBeMissing: true});
32-
const [credentials] = useOnyx(ONYXKEYS.CREDENTIALS, {canBeMissing: true});
33-
const [onboardingEmail] = useOnyx(ONYXKEYS.FORMS.ONBOARDING_WORK_EMAIL_FORM, {canBeMissing: true});
34-
const workEmail = onboardingEmail?.onboardingWorkEmail;
35-
36-
const {onboardingIsMediumOrLargerScreenWidth} = useResponsiveLayout();
3747
const [onboardingValues] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {canBeMissing: true});
48+
const [formValue] = useOnyx(ONYXKEYS.FORMS.ONBOARDING_WORK_EMAIL_FORM, {canBeMissing: true});
49+
const workEmail = formValue?.[INPUT_IDS.ONBOARDING_WORK_EMAIL];
50+
const [onboardingErrorMessage] = useOnyx(ONYXKEYS.ONBOARDING_ERROR_MESSAGE, {canBeMissing: true});
3851
const isVsb = onboardingValues && 'signupQualifier' in onboardingValues && onboardingValues.signupQualifier === CONST.ONBOARDING_SIGNUP_QUALIFIERS.VSB;
3952
const isSmb = onboardingValues?.signupQualifier === CONST.ONBOARDING_SIGNUP_QUALIFIERS.SMB;
40-
const [onboardingErrorMessage] = useOnyx(ONYXKEYS.ONBOARDING_ERROR_MESSAGE, {canBeMissing: true});
41-
const isValidateCodeFormSubmitting = AccountUtils.isValidateCodeFormSubmitting(account);
53+
const {onboardingIsMediumOrLargerScreenWidth} = useResponsiveLayout();
54+
const {inputCallbackRef} = useAutoFocusInput();
55+
const [shouldValidateOnChange, setShouldValidateOnChange] = useState(false);
56+
const {isOffline} = useNetwork();
57+
const ICON_SIZE = 48;
58+
const operatingSystem = getOperatingSystem();
4259
const isFocused = useIsFocused();
4360

4461
useEffect(() => {
45-
if (onboardingValues?.isMergeAccountStepCompleted === undefined) {
62+
setOnboardingErrorMessage('');
63+
}, []);
64+
65+
useEffect(() => {
66+
if (onboardingValues?.shouldValidate === undefined && onboardingValues?.isMergeAccountStepCompleted === undefined) {
4667
return;
4768
}
4869
setOnboardingErrorMessage('');
49-
if (onboardingValues?.shouldRedirectToClassicAfterMerge) {
50-
openOldDotLink(CONST.OLDDOT_URLS.INBOX, true);
70+
71+
if (onboardingValues?.shouldValidate) {
72+
Navigation.navigate(ROUTES.ONBOARDING_WORK_EMAIL_VALIDATION.getRoute());
5173
return;
5274
}
5375
// Once we verify that shouldValidate is false, we need to force replace the screen
@@ -63,90 +85,160 @@ function BaseOnboardingWorkEmailValidation({shouldUseNativeStyles}: BaseOnboardi
6385
}
6486

6587
if (!onboardingValues?.isMergeAccountStepSkipped) {
66-
Navigation.navigate(ROUTES.ONBOARDING_WORKSPACES.getRoute(), {forceReplace: true});
88+
Navigation.navigate(ROUTES.ONBOARDING_PRIVATE_DOMAIN.getRoute(), {forceReplace: true});
6789
return;
6890
}
6991

7092
Navigation.navigate(ROUTES.ONBOARDING_PURPOSE.getRoute(), {forceReplace: true});
71-
}, [onboardingValues, isVsb, isSmb, isFocused]);
93+
}, [onboardingValues?.shouldValidate, isVsb, isSmb, isFocused, onboardingValues?.isMergeAccountStepCompleted, onboardingValues?.isMergeAccountStepSkipped]);
7294

73-
const sendValidateCode = useCallback(() => {
74-
if (!credentials?.login) {
75-
return;
95+
const submitWorkEmail = useCallback((values: FormOnyxValues<typeof ONYXKEYS.FORMS.ONBOARDING_WORK_EMAIL_FORM>) => {
96+
AddWorkEmail(values[INPUT_IDS.ONBOARDING_WORK_EMAIL]);
97+
}, []);
98+
99+
const validate = (values: FormOnyxValues<typeof ONYXKEYS.FORMS.ONBOARDING_WORK_EMAIL_FORM>) => {
100+
if (!shouldValidateOnChange) {
101+
setShouldValidateOnChange(true);
76102
}
77-
resendValidateCode(credentials.login);
78-
}, [credentials?.login]);
103+
const userEmail = values[INPUT_IDS.ONBOARDING_WORK_EMAIL];
104+
105+
const errors = {};
106+
const emailParts = userEmail.split('@');
107+
const domain = emailParts.at(1) ?? '';
79108

80-
const validateAccountAndMerge = useCallback(
81-
(validateCode: string) => {
82-
setOnboardingErrorMessage('');
83-
MergeIntoAccountAndLogin(workEmail, validateCode, session?.accountID);
109+
if ((PUBLIC_DOMAINS_SET.has(domain.toLowerCase()) || !Str.isValidEmail(userEmail)) && !isOffline) {
110+
Log.hmmm('User is trying to add an invalid work email', {userEmail, domain});
111+
addErrorMessage(errors, INPUT_IDS.ONBOARDING_WORK_EMAIL, translate('onboarding.workEmailValidationError.publicEmail'));
112+
}
113+
114+
if (isOffline ?? false) {
115+
addErrorMessage(errors, INPUT_IDS.ONBOARDING_WORK_EMAIL, translate('onboarding.workEmailValidationError.offline'));
116+
}
117+
118+
return errors;
119+
};
120+
121+
const section: Item[] = [
122+
{
123+
icon: Illustrations.EnvelopeReceipt,
124+
titleTranslationKey: 'onboarding.workEmail.explanationModal.descriptionOne',
125+
shouldRenderEmail: true,
84126
},
85-
[workEmail, session?.accountID],
86-
);
127+
{
128+
icon: Illustrations.Profile,
129+
titleTranslationKey: 'onboarding.workEmail.explanationModal.descriptionTwo',
130+
},
131+
{
132+
icon: Illustrations.Gears,
133+
titleTranslationKey: 'onboarding.workEmail.explanationModal.descriptionThree',
134+
},
135+
];
87136

88137
return (
89138
<ScreenWrapper
90-
includeSafeAreaPaddingBottom={false}
91-
testID="BaseOnboardingWorkEmailValidation"
139+
shouldEnableMaxHeight={!isMobileSafari()}
140+
shouldAvoidScrollOnVirtualViewport={!isMobileSafari()}
141+
includeSafeAreaPaddingBottom={isOffline}
142+
testID="BaseOnboardingWorkEmail"
92143
style={[styles.defaultModalContainer, shouldUseNativeStyles && styles.pt8]}
93144
>
94145
<HeaderWithBackButton
95-
shouldShowBackButton={!onboardingValues?.isMergingAccountBlocked}
96-
progressBarPercentage={15}
97-
onBackButtonPress={() => {
98-
updateOnboardingValuesAndNavigation(onboardingValues);
99-
}}
146+
progressBarPercentage={10}
147+
shouldShowBackButton={false}
100148
/>
101-
{onboardingValues?.isMergingAccountBlocked ? (
102-
<View style={[styles.flex1, onboardingIsMediumOrLargerScreenWidth && styles.mt5, onboardingIsMediumOrLargerScreenWidth ? styles.mh8 : styles.mh5]}>
103-
<BlockingView
104-
icon={Illustrations.ToddBehindCloud}
105-
iconWidth={variables.modalTopIconWidth}
106-
iconHeight={variables.modalTopIconHeight}
107-
title={translate('onboarding.mergeBlockScreen.title')}
108-
subtitle={translate('onboarding.mergeBlockScreen.subtitle', {workEmail})}
109-
subtitleStyle={[styles.colorMuted]}
110-
/>
111-
<Button
112-
success={onboardingValues?.isMergingAccountBlocked}
113-
large
114-
style={[styles.mb5]}
115-
text={translate('common.buttonConfirm')}
116-
onPress={() => {
117-
setOnboardingErrorMessage('');
118-
if (isVsb) {
119-
Navigation.navigate(ROUTES.ONBOARDING_ACCOUNTING.getRoute());
120-
return;
121-
}
122-
Navigation.navigate(ROUTES.ONBOARDING_PURPOSE.getRoute());
123-
}}
124-
/>
149+
<FormProvider
150+
style={[styles.flexGrow1, onboardingIsMediumOrLargerScreenWidth && styles.mt5, onboardingIsMediumOrLargerScreenWidth ? styles.mh8 : styles.mh5]}
151+
formID={ONYXKEYS.FORMS.ONBOARDING_WORK_EMAIL_FORM}
152+
validate={validate}
153+
onSubmit={submitWorkEmail}
154+
submitButtonText={translate('onboarding.workEmail.addWorkEmail')}
155+
enabledWhenOffline
156+
submitFlexEnabled
157+
shouldValidateOnBlur={false}
158+
shouldValidateOnChange={shouldValidateOnChange}
159+
shouldTrimValues={false}
160+
footerContent={
161+
<OfflineWithFeedback
162+
shouldDisplayErrorAbove
163+
style={styles.mb3}
164+
errors={onboardingErrorMessage ? {addWorkEmailError: onboardingErrorMessage} : undefined}
165+
errorRowStyles={[styles.mt2, styles.textWrap]}
166+
onClose={() => setOnboardingErrorMessage('')}
167+
>
168+
<Button
169+
large
170+
text={translate('common.skip')}
171+
testID="onboardingPrivateEmailSkipButton"
172+
onPress={() => {
173+
setOnboardingErrorMessage('');
174+
175+
setOnboardingMergeAccountStepValue(true, true);
176+
}}
177+
/>
178+
</OfflineWithFeedback>
179+
}
180+
shouldRenderFooterAboveSubmit
181+
shouldHideFixErrorsAlert
182+
>
183+
<View>
184+
<View style={[onboardingIsMediumOrLargerScreenWidth ? styles.flexRow : styles.flexColumn, styles.mb3]}>
185+
<Text style={styles.textHeadlineH1}>{translate('onboarding.workEmail.title')}</Text>
186+
</View>
187+
<View style={styles.mb2}>
188+
<Text style={[styles.textNormal, styles.colorMuted]}>{translate('onboarding.workEmail.subtitle')}</Text>
189+
</View>
190+
<View>
191+
{section.map((item) => {
192+
return (
193+
<View
194+
key={item.titleTranslationKey}
195+
style={[styles.mt2, styles.mb3]}
196+
>
197+
<View style={[styles.flexRow, styles.alignItemsCenter, styles.flex1]}>
198+
<Icon
199+
src={item.icon}
200+
height={ICON_SIZE}
201+
width={ICON_SIZE}
202+
additionalStyles={[styles.mr3]}
203+
/>
204+
<View style={[styles.flexColumn, styles.flex1]}>
205+
{item.shouldRenderEmail ? (
206+
<AutoEmailLink
207+
style={[styles.textStrong, styles.lh20]}
208+
text={translate(item.titleTranslationKey)}
209+
/>
210+
) : (
211+
<Text style={[styles.textStrong, styles.lh20]}>{translate(item.titleTranslationKey)}</Text>
212+
)}
213+
</View>
214+
</View>
215+
</View>
216+
);
217+
})}
218+
</View>
125219
</View>
126-
) : (
127-
<View style={[styles.flex1, onboardingIsMediumOrLargerScreenWidth && styles.mt5, onboardingIsMediumOrLargerScreenWidth ? styles.mh8 : styles.mh5]}>
128-
<Text style={styles.textHeadlineH1}>{translate('onboarding.workEmailValidation.title')}</Text>
129-
<Text style={[styles.textNormal, styles.colorMuted, styles.textAlignLeft, styles.mt5]}>{translate('onboarding.workEmailValidation.magicCodeSent', {workEmail})}</Text>
130-
<ValidateCodeForm
131-
handleSubmitForm={validateAccountAndMerge}
132-
sendValidateCode={sendValidateCode}
133-
validateCodeActionErrorField="mergeIntoAccountAndLogIn"
134-
clearError={() => setOnboardingErrorMessage('')}
135-
buttonStyles={[styles.flex2, styles.justifyContentEnd, styles.mb5]}
136-
shouldShowSkipButton
137-
handleSkipButtonPress={() => {
138-
setOnboardingErrorMessage('');
139-
setOnboardingMergeAccountStepValue(true, true);
140-
}}
141-
isLoading={isValidateCodeFormSubmitting}
142-
validateError={onboardingErrorMessage ? {invalidCodeError: onboardingErrorMessage} : undefined}
220+
221+
<View style={[styles.mb4, styles.pt3]}>
222+
<InputWrapper
223+
InputComponent={TextInput}
224+
// We do not want to auto-focus for mobile platforms
225+
ref={operatingSystem !== CONST.OS.ANDROID && operatingSystem !== CONST.OS.IOS ? inputCallbackRef : undefined}
226+
name="fname"
227+
inputID={INPUT_IDS.ONBOARDING_WORK_EMAIL}
228+
label={translate('common.workEmail')}
229+
aria-label={translate('common.workEmail')}
230+
role={CONST.ROLE.PRESENTATION}
231+
defaultValue={workEmail ?? ''}
232+
shouldSaveDraft
233+
maxLength={CONST.LOGIN_CHARACTER_LIMIT}
234+
spellCheck={false}
143235
/>
144236
</View>
145-
)}
237+
</FormProvider>
146238
</ScreenWrapper>
147239
);
148240
}
149241

150-
BaseOnboardingWorkEmailValidation.displayName = 'BaseOnboardingWorkEmailValidation';
242+
BaseOnboardingWorkEmail.displayName = 'BaseOnboardingWorkEmail';
151243

152-
export default BaseOnboardingWorkEmailValidation;
244+
export default BaseOnboardingWorkEmail;

0 commit comments

Comments
 (0)