Skip to content

Commit ad6007b

Browse files
onboarding flow without errors
1 parent bef062b commit ad6007b

34 files changed

+635
-38
lines changed

src/ONYXKEYS.ts

+3
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ const ONYXKEYS = {
104104
/** Store the information of magic code */
105105
VALIDATE_ACTION_CODE: 'validate_action_code',
106106

107+
KEY_JOINABLE_POLICIES: 'keyJoinablePolicies',
108+
107109
/** Information about the current session (authToken, accountID, email, loading, error) */
108110
SESSION: 'session',
109111
STASHED_SESSION: 'stashedSession',
@@ -907,6 +909,7 @@ type OnyxValuesMapping = {
907909
[ONYXKEYS.LOGIN_LIST]: OnyxTypes.LoginList;
908910
[ONYXKEYS.PENDING_CONTACT_ACTION]: OnyxTypes.PendingContactAction;
909911
[ONYXKEYS.VALIDATE_ACTION_CODE]: OnyxTypes.ValidateMagicCodeAction;
912+
[ONYXKEYS.KEY_JOINABLE_POLICIES]: OnyxTypes.JoinablePolicies;
910913
[ONYXKEYS.SESSION]: OnyxTypes.Session;
911914
[ONYXKEYS.USER_METADATA]: OnyxTypes.UserMetadata;
912915
[ONYXKEYS.STASHED_SESSION]: OnyxTypes.Session;

src/ROUTES.ts

+8
Original file line numberDiff line numberDiff line change
@@ -1325,6 +1325,10 @@ const ROUTES = {
13251325
route: 'onboarding/personal-details',
13261326
getRoute: (backTo?: string) => getUrlWithBackToParam(`onboarding/personal-details`, backTo),
13271327
},
1328+
ONBOARDING_PRIVATE_DOMAIN: {
1329+
route: 'onboarding/private-domain',
1330+
getRoute: (backTo?: string) => getUrlWithBackToParam(`onboarding/private-domain`, backTo),
1331+
},
13281332
ONBOARDING_EMPLOYEES: {
13291333
route: 'onboarding/employees',
13301334
getRoute: (backTo?: string) => getUrlWithBackToParam(`onboarding/employees`, backTo),
@@ -1337,6 +1341,10 @@ const ROUTES = {
13371341
route: 'onboarding/purpose',
13381342
getRoute: (backTo?: string) => getUrlWithBackToParam(`onboarding/purpose`, backTo),
13391343
},
1344+
ONBOARDING_WORKSPACES: {
1345+
route: 'onboarding/workspaces',
1346+
getRoute: (backTo?: string) => getUrlWithBackToParam(`onboarding/workspaces`, backTo),
1347+
},
13401348
WELCOME_VIDEO_ROOT: 'onboarding/welcome-video',
13411349
EXPLANATION_MODAL_ROOT: 'onboarding/explanation',
13421350

src/SCREENS.ts

+2
Original file line numberDiff line numberDiff line change
@@ -566,8 +566,10 @@ const SCREENS = {
566566
ONBOARDING: {
567567
PERSONAL_DETAILS: 'Onboarding_Personal_Details',
568568
PURPOSE: 'Onboarding_Purpose',
569+
PRIVATE_DOMAIN: 'Onboarding_Private_Domain',
569570
EMPLOYEES: 'Onboarding_Employees',
570571
ACCOUNTING: 'Onboarding_Accounting',
572+
WORKSPACES: 'Onboarding_Workspaces',
571573
},
572574

573575
WELCOME_VIDEO: {

src/components/ValidateCodeActionModal/ValidateCodeForm/BaseValidateCodeForm.tsx

+15-9
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ type ValidateCodeFormProps = {
6363
/** Function to clear error of the form */
6464
clearError: () => void;
6565

66+
/** Whether to show the verify button (hidden in private domain onboarding) */
67+
hideButton?: boolean;
68+
6669
/** Function is called when validate code modal is mounted and on magic code resend */
6770
sendValidateCode: () => void;
6871
};
@@ -78,6 +81,7 @@ function BaseValidateCodeForm({
7881
clearError,
7982
sendValidateCode,
8083
buttonStyles,
84+
hideButton,
8185
}: ValidateCodeFormProps) {
8286
const {translate} = useLocalize();
8387
const {isOffline} = useNetwork();
@@ -259,15 +263,17 @@ function BaseValidateCodeForm({
259263
onClose={() => clearError()}
260264
style={buttonStyles}
261265
>
262-
<Button
263-
isDisabled={isOffline}
264-
text={translate('common.verify')}
265-
onPress={validateAndSubmitForm}
266-
style={[styles.mt4]}
267-
success
268-
large
269-
isLoading={account?.isLoading}
270-
/>
266+
{!hideButton && (
267+
<Button
268+
isDisabled={isOffline}
269+
text={translate('common.verify')}
270+
onPress={validateAndSubmitForm}
271+
style={[styles.mt4]}
272+
success
273+
large
274+
isLoading={account?.isLoading}
275+
/>
276+
)}
271277
</OfflineWithFeedback>
272278
</>
273279
);

src/hooks/useOnboardingFlow.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {useEffect} from 'react';
22
import {NativeModules} from 'react-native';
33
import {useOnyx} from 'react-native-onyx';
4+
import * as LoginUtils from '@libs/LoginUtils';
45
import Navigation from '@libs/Navigation/Navigation';
56
import {hasCompletedGuidedSetupFlowSelector, hasCompletedHybridAppOnboardingFlowSelector} from '@libs/onboardingSelectors';
67
import * as OnboardingFlow from '@userActions/Welcome/OnboardingFlow';
@@ -21,6 +22,9 @@ function useOnboardingFlowRouter() {
2122
selector: hasCompletedHybridAppOnboardingFlowSelector,
2223
});
2324

25+
const [session] = useOnyx(ONYXKEYS.SESSION);
26+
const isPrivateDomain = !!session?.email && !LoginUtils.isEmailPublicDomain(session?.email);
27+
2428
useEffect(() => {
2529
if (isLoadingOnyxValue(isOnboardingCompletedMetadata, isHybridAppOnboardingCompletedMetadata)) {
2630
return;
@@ -35,15 +39,15 @@ function useOnboardingFlowRouter() {
3539
// But if the hybrid app onboarding is completed, but NewDot onboarding is not completed, we start NewDot onboarding flow
3640
// This is a special case when user created an account from NewDot without finishing the onboarding flow and then logged in from OldDot
3741
if (isHybridAppOnboardingCompleted === true && isOnboardingCompleted === false) {
38-
OnboardingFlow.startOnboardingFlow();
42+
OnboardingFlow.startOnboardingFlow(isPrivateDomain);
3943
}
4044
}
4145

4246
// If the user is not transitioning from OldDot to NewDot, we should start NewDot onboarding flow if it's not completed yet
4347
if (!NativeModules.HybridAppModule && isOnboardingCompleted === false) {
44-
OnboardingFlow.startOnboardingFlow();
48+
OnboardingFlow.startOnboardingFlow(isPrivateDomain);
4549
}
46-
}, [isOnboardingCompleted, isHybridAppOnboardingCompleted, isOnboardingCompletedMetadata, isHybridAppOnboardingCompletedMetadata]);
50+
}, [isOnboardingCompleted, isHybridAppOnboardingCompleted, isOnboardingCompletedMetadata, isHybridAppOnboardingCompletedMetadata, isPrivateDomain]);
4751

4852
return {isOnboardingCompleted, isHybridAppOnboardingCompleted};
4953
}

src/languages/en.ts

+10
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ import type {
187187
WelcomeToRoomParams,
188188
WeSentYouMagicSignInLinkParams,
189189
WorkspaceOwnerWillNeedToAddOrUpdatePaymentCardParams,
190+
WorkspaceYouMayJoin,
190191
YourPlanPriceParams,
191192
ZipCodeExampleFormatParams,
192193
} from './params';
@@ -470,6 +471,7 @@ const translations = {
470471
links: 'Links',
471472
days: 'days',
472473
rename: 'Rename',
474+
skip: 'Skip',
473475
},
474476
location: {
475477
useCurrent: 'Use current location',
@@ -1733,6 +1735,10 @@ const translations = {
17331735
},
17341736
getStarted: 'Get started',
17351737
whatsYourName: "What's your name?",
1738+
peopleYouMayKnow: 'People you may know are already here! Verify your email to join them.',
1739+
workspaceYouMayJoin: ({domain, email}: WorkspaceYouMayJoin) => `Someone from ${domain} has already created a workspace. Please enter the magic code sent to ${email}.`,
1740+
joinAWorkspace: 'Join a workspace',
1741+
listOfWorkspaces: "Here's the list of workspaces you can join. Don't worry, you can always join them later if you prefer.",
17361742
whereYouWork: 'Where do you work?',
17371743
errorSelection: 'Please make a selection to continue.',
17381744
purpose: {
@@ -2598,6 +2604,10 @@ const translations = {
25982604
noAccountsFound: 'No accounts found',
25992605
noAccountsFoundDescription: 'Add the account in Quickbooks Online and sync the connection again.',
26002606
},
2607+
workspaceList: {
2608+
joinNow: 'Join now',
2609+
askToJoin: 'Ask to join',
2610+
},
26012611
xero: {
26022612
organization: 'Xero organization',
26032613
organizationDescription: "Choose the Xero organization that you'd like to import data from.",

src/languages/es.ts

+10
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ import type {
186186
WelcomeToRoomParams,
187187
WeSentYouMagicSignInLinkParams,
188188
WorkspaceOwnerWillNeedToAddOrUpdatePaymentCardParams,
189+
WorkspaceYouMayJoin,
189190
YourPlanPriceParams,
190191
ZipCodeExampleFormatParams,
191192
} from './params';
@@ -341,6 +342,7 @@ const translations = {
341342
semicolon: 'el punto y coma',
342343
please: 'Por favor',
343344
rename: 'Renombrar',
345+
skip: 'Saltarse',
344346
contactUs: 'contáctenos',
345347
pleaseEnterEmailOrPhoneNumber: 'Por favor, escribe un email o número de teléfono',
346348
fixTheErrors: 'corrige los errores',
@@ -1734,6 +1736,10 @@ const translations = {
17341736
},
17351737
getStarted: 'Comenzar',
17361738
whatsYourName: '¿Cómo te llamas?',
1739+
peopleYouMayKnow: 'Las personas que tal vez conozcas ya están aquí. Verifica tu correo electrónico para unirte a ellos.',
1740+
workspaceYouMayJoin: ({domain, email}: WorkspaceYouMayJoin) => `Alguien de ${domain} ya ha creado un espacio de trabajo. Por favor, introduce el código mágico enviado a ${email}.`,
1741+
joinAWorkspace: 'Unirse a un espacio de trabajo',
1742+
listOfWorkspaces: 'Aquí está la lista de espacios de trabajo a los que puedes unirte. No te preocupes, siempre puedes unirte a ellos más tarde si lo prefieres.',
17371743
whereYouWork: '¿Dónde trabajas?',
17381744
errorSelection: 'Por favor selecciona una opción para continuar.',
17391745
purpose: {
@@ -2628,6 +2634,10 @@ const translations = {
26282634
noAccountsFound: 'No se ha encontrado ninguna cuenta',
26292635
noAccountsFoundDescription: 'Añade la cuenta en Quickbooks Online y sincroniza de nuevo la conexión.',
26302636
},
2637+
workspaceList: {
2638+
joinNow: 'Únete ahora',
2639+
askToJoin: 'Pedir unirse',
2640+
},
26312641
xero: {
26322642
organization: 'Organización Xero',
26332643
organizationDescription: 'Seleccione la organización en Xero desde la que está importando los datos.',

src/languages/params.ts

+6
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,11 @@ type ImportedTypesParams = {
539539
importedTypes: string[];
540540
};
541541

542+
type WorkspaceYouMayJoin = {
543+
domain: string;
544+
email: string;
545+
};
546+
542547
type FileLimitParams = {
543548
fileLimit: number;
544549
};
@@ -746,4 +751,5 @@ export type {
746751
OptionalParam,
747752
AssignCardParams,
748753
ImportedTypesParams,
754+
WorkspaceYouMayJoin,
749755
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
type JoinAccessiblePolicyParams = {
2+
policyID: string;
3+
};
4+
5+
export default JoinAccessiblePolicyParams;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
type ValidateUserAndGetAccessiblePoliciesParams = {
2+
validationCode: string;
3+
};
4+
5+
export default ValidateUserAndGetAccessiblePoliciesParams;

src/libs/API/parameters/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -345,5 +345,7 @@ export type {default as ConnectPolicyToQuickBooksDesktopParams} from './ConnectP
345345
export type {default as UpdateInvoiceCompanyNameParams} from './UpdateInvoiceCompanyNameParams';
346346
export type {default as UpdateInvoiceCompanyWebsiteParams} from './UpdateInvoiceCompanyWebsiteParams';
347347
export type {default as UpdateQuickbooksDesktopExpensesExportDestinationTypeParams} from './UpdateQuickbooksDesktopExpensesExportDestinationTypeParams';
348+
export type {default as ValidateUserAndGetAccessiblePoliciesParams} from './ValidateUserAndGetAccessiblePoliciesParams';
348349
export type {default as UpdateQuickbooksDesktopCompanyCardExpenseAccountTypeParams} from './UpdateQuickbooksDesktopCompanyCardExpenseAccountTypeParams';
349350
export type {default as TogglePlatformMuteParams} from './TogglePlatformMuteParams';
351+
export type {default as JoinAccessiblePolicyParams} from './JoinAccessiblePolicyParams';

src/libs/API/types.ts

+5
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ const WRITE_COMMANDS = {
241241
SET_POLICY_TAXES_FOREIGN_CURRENCY_DEFAULT: 'SetPolicyForeignCurrencyDefaultTax',
242242
SET_POLICY_CUSTOM_TAX_NAME: 'SetPolicyCustomTaxName',
243243
JOIN_POLICY_VIA_INVITE_LINK: 'JoinWorkspaceViaInviteLink',
244+
JOIN_ACCESSIBLE_POLICY: 'JoinAccessiblePolicy',
244245
ACCEPT_JOIN_REQUEST: 'AcceptJoinRequest',
245246
DECLINE_JOIN_REQUEST: 'DeclineJoinRequest',
246247
CREATE_POLICY_TAX: 'CreatePolicyTax',
@@ -436,6 +437,7 @@ const WRITE_COMMANDS = {
436437
SET_INVOICING_TRANSFER_BANK_ACCOUNT: 'SetInvoicingTransferBankAccount',
437438
UPDATE_INVOICE_COMPANY_NAME: 'UpdateInvoiceCompanyName',
438439
UPDATE_INVOICE_COMPANY_WEBSITE: 'UpdateInvoiceCompanyWebsite',
440+
VALIDATE_USER_AND_GET_ACCESSIBLE_POLICIES: 'ValidateUserAndGetAccessiblePolicies',
439441
} as const;
440442

441443
type WriteCommand = ValueOf<typeof WRITE_COMMANDS>;
@@ -672,6 +674,7 @@ type WriteCommandParameters = {
672674
[WRITE_COMMANDS.SEARCH]: Parameters.SearchParams;
673675
[WRITE_COMMANDS.SET_POLICY_CATEGORY_TAX]: Parameters.SetPolicyCategoryTaxParams;
674676
[WRITE_COMMANDS.JOIN_POLICY_VIA_INVITE_LINK]: Parameters.JoinPolicyInviteLinkParams;
677+
[WRITE_COMMANDS.VALIDATE_USER_AND_GET_ACCESSIBLE_POLICIES]: Parameters.ValidateUserAndGetAccessiblePoliciesParams;
675678
[WRITE_COMMANDS.ACCEPT_JOIN_REQUEST]: Parameters.AcceptJoinRequestParams;
676679
[WRITE_COMMANDS.DECLINE_JOIN_REQUEST]: Parameters.DeclineJoinRequestParams;
677680
[WRITE_COMMANDS.SET_POLICY_TAXES_CURRENCY_DEFAULT]: Parameters.SetPolicyCurrencyDefaultParams;
@@ -883,6 +886,8 @@ type WriteCommandParameters = {
883886
[WRITE_COMMANDS.SET_INVOICING_TRANSFER_BANK_ACCOUNT]: Parameters.SetInvoicingTransferBankAccountParams;
884887
[WRITE_COMMANDS.UPDATE_INVOICE_COMPANY_NAME]: Parameters.UpdateInvoiceCompanyNameParams;
885888
[WRITE_COMMANDS.UPDATE_INVOICE_COMPANY_WEBSITE]: Parameters.UpdateInvoiceCompanyWebsiteParams;
889+
890+
[WRITE_COMMANDS.JOIN_ACCESSIBLE_POLICY]: Parameters.JoinAccessiblePolicyParams;
886891
};
887892

888893
const READ_COMMANDS = {

src/libs/Navigation/AppNavigator/Navigators/OnboardingModalNavigator.tsx

+10
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ import OnboardingRefManager from '@libs/OnboardingRefManager';
1212
import OnboardingAccounting from '@pages/OnboardingAccounting';
1313
import OnboardingEmployees from '@pages/OnboardingEmployees';
1414
import OnboardingPersonalDetails from '@pages/OnboardingPersonalDetails';
15+
import OnboardingPrivateDomain from '@pages/OnboardingPrivateDomain';
1516
import OnboardingPurpose from '@pages/OnboardingPurpose';
17+
import OnboardingWorkspaces from '@pages/OnboardingWorkspaces';
1618
import CONST from '@src/CONST';
1719
import SCREENS from '@src/SCREENS';
1820
import Overlay from './Overlay';
@@ -52,6 +54,14 @@ function OnboardingModalNavigator() {
5254
name={SCREENS.ONBOARDING.PERSONAL_DETAILS}
5355
component={OnboardingPersonalDetails}
5456
/>
57+
<Stack.Screen
58+
name={SCREENS.ONBOARDING.PRIVATE_DOMAIN}
59+
component={OnboardingPrivateDomain}
60+
/>
61+
<Stack.Screen
62+
name={SCREENS.ONBOARDING.WORKSPACES}
63+
component={OnboardingWorkspaces}
64+
/>
5565
<Stack.Screen
5666
name={SCREENS.ONBOARDING.EMPLOYEES}
5767
component={OnboardingEmployees}

src/libs/Navigation/NavigationRoot.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import useTheme from '@hooks/useTheme';
1111
import Firebase from '@libs/Firebase';
1212
import {FSPage} from '@libs/Fullstory';
1313
import Log from '@libs/Log';
14+
import * as LoginUtils from '@libs/LoginUtils';
1415
import {hasCompletedGuidedSetupFlowSelector} from '@libs/onboardingSelectors';
1516
import {getPathFromURL} from '@libs/Url';
1617
import {updateLastVisitedPath} from '@userActions/App';
@@ -90,6 +91,8 @@ function NavigationRoot({authenticated, lastVisitedPath, initialUrl, onReady, sh
9091
const {shouldUseNarrowLayout} = useResponsiveLayout();
9192
const {setActiveWorkspaceID} = useActiveWorkspace();
9293
const [user] = useOnyx(ONYXKEYS.USER);
94+
const [session] = useOnyx(ONYXKEYS.SESSION);
95+
const isPrivateDomain = !!session?.email && !LoginUtils.isEmailPublicDomain(session?.email);
9396

9497
const [isOnboardingCompleted = true] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {
9598
selector: hasCompletedGuidedSetupFlowSelector,
@@ -103,7 +106,7 @@ function NavigationRoot({authenticated, lastVisitedPath, initialUrl, onReady, sh
103106
// If the user haven't completed the flow, we want to always redirect them to the onboarding flow.
104107
// We also make sure that the user is authenticated.
105108
if (!NativeModules.HybridAppModule && !isOnboardingCompleted && authenticated && !shouldShowRequire2FAModal) {
106-
const {adaptedState} = getAdaptedStateFromPath(getOnboardingInitialPath(), linkingConfig.config);
109+
const {adaptedState} = getAdaptedStateFromPath(getOnboardingInitialPath(isPrivateDomain), linkingConfig.config);
107110
return adaptedState;
108111
}
109112

src/libs/Navigation/linkingConfig/config.ts

+8
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@ const config: LinkingOptions<RootStackParamList>['config'] = {
118118
path: ROUTES.ONBOARDING_PERSONAL_DETAILS.route,
119119
exact: true,
120120
},
121+
[SCREENS.ONBOARDING.PRIVATE_DOMAIN]: {
122+
path: ROUTES.ONBOARDING_PRIVATE_DOMAIN.route,
123+
exact: true,
124+
},
121125
[SCREENS.ONBOARDING.EMPLOYEES]: {
122126
path: ROUTES.ONBOARDING_EMPLOYEES.route,
123127
exact: true,
@@ -126,6 +130,10 @@ const config: LinkingOptions<RootStackParamList>['config'] = {
126130
path: ROUTES.ONBOARDING_ACCOUNTING.route,
127131
exact: true,
128132
},
133+
[SCREENS.ONBOARDING.WORKSPACES]: {
134+
path: ROUTES.ONBOARDING_WORKSPACES.route,
135+
exact: true,
136+
},
129137
},
130138
},
131139
[NAVIGATORS.RIGHT_MODAL_NAVIGATOR]: {

src/libs/Navigation/types.ts

+6
Original file line numberDiff line numberDiff line change
@@ -1482,6 +1482,12 @@ type OnboardingModalNavigatorParamList = {
14821482
[SCREENS.ONBOARDING.PERSONAL_DETAILS]: {
14831483
backTo?: string;
14841484
};
1485+
[SCREENS.ONBOARDING.PRIVATE_DOMAIN]: {
1486+
backTo?: string;
1487+
};
1488+
[SCREENS.ONBOARDING.WORKSPACES]: {
1489+
backTo?: string;
1490+
};
14851491
[SCREENS.ONBOARDING.PURPOSE]: {
14861492
backTo?: string;
14871493
};

src/libs/NavigationUtils.ts

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ const ONBOARDING_SCREEN_NAMES = new Set([
2323
SCREENS.ONBOARDING_MODAL.ONBOARDING,
2424
SCREENS.ONBOARDING.EMPLOYEES,
2525
SCREENS.ONBOARDING.ACCOUNTING,
26+
SCREENS.ONBOARDING.PRIVATE_DOMAIN,
27+
SCREENS.ONBOARDING.WORKSPACES,
2628
]);
2729

2830
const removePolicyIDParamFromState = (state: State<RootStackParamList>) => {

0 commit comments

Comments
 (0)