diff --git a/src/CONST.ts b/src/CONST.ts index 2af183d9d751..9a6bf21db303 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -84,6 +84,12 @@ const onboardingChoices = { ...backendOnboardingChoices, } as const; +const signupQualifiers = { + INDIVIDUAL: 'individual', + VSB: 'vsb', + SMB: 'smb', +} as const; + const onboardingEmployerOrSubmitMessage: OnboardingMessageType = { message: 'Getting paid back is as easy as sending a message. Let’s go over the basics.', video: { @@ -4462,9 +4468,11 @@ const CONST = { WELCOME_VIDEO_URL: `${CLOUDFRONT_URL}/videos/intro-1280.mp4`, + QUALIFIER_PARAM: 'signupQualifier', ONBOARDING_INTRODUCTION: 'Let’s get you set up 🔧', ONBOARDING_CHOICES: {...onboardingChoices}, SELECTABLE_ONBOARDING_CHOICES: {...selectableOnboardingChoices}, + ONBOARDING_SIGNUP_QUALIFIERS: {...signupQualifiers}, ONBOARDING_INVITE_TYPES: {...onboardingInviteTypes}, ACTIONABLE_TRACK_EXPENSE_WHISPER_MESSAGE: 'What would you like to do with this expense?', ONBOARDING_CONCIERGE: { diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index f16b41538531..df1413620c20 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -330,6 +330,9 @@ const ONYXKEYS = { /** Onboarding Purpose selected by the user during Onboarding flow */ ONBOARDING_PURPOSE_SELECTED: 'onboardingPurposeSelected', + /** Onboarding customized choices to display to the user based on their profile when signing up */ + ONBOARDING_CUSTOM_CHOICES: 'onboardingCustomChoices', + /** Onboarding error message to be displayed to the user */ ONBOARDING_ERROR_MESSAGE: 'onboardingErrorMessage', @@ -953,6 +956,7 @@ type OnyxValuesMapping = { [ONYXKEYS.MAX_CANVAS_HEIGHT]: number; [ONYXKEYS.MAX_CANVAS_WIDTH]: number; [ONYXKEYS.ONBOARDING_PURPOSE_SELECTED]: OnboardingPurposeType; + [ONYXKEYS.ONBOARDING_CUSTOM_CHOICES]: OnboardingPurposeType[] | []; [ONYXKEYS.ONBOARDING_ERROR_MESSAGE]: string; [ONYXKEYS.ONBOARDING_POLICY_ID]: string; [ONYXKEYS.ONBOARDING_ADMINS_CHAT_REPORT_ID]: string; diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.tsx b/src/libs/Navigation/AppNavigator/AuthScreens.tsx index 0453e496cecf..f5f35fd21025 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.tsx +++ b/src/libs/Navigation/AppNavigator/AuthScreens.tsx @@ -14,6 +14,7 @@ import usePermissions from '@hooks/usePermissions'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; +import * as Welcome from '@libs/actions/Welcome'; import {READ_COMMANDS} from '@libs/API/types'; import HttpUtils from '@libs/HttpUtils'; import KeyboardShortcut from '@libs/KeyboardShortcut'; @@ -273,6 +274,18 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie return; } + let signupQualifier; + if (currentUrl.includes(CONST.QUALIFIER_PARAM)) { + signupQualifier = new URL(currentUrl).searchParams.get(CONST.QUALIFIER_PARAM); + + if (signupQualifier === CONST.ONBOARDING_SIGNUP_QUALIFIERS.INDIVIDUAL) { + Welcome.setOnboardingCustomChoices([CONST.ONBOARDING_CHOICES.PERSONAL_SPEND, CONST.ONBOARDING_CHOICES.EMPLOYER, CONST.ONBOARDING_CHOICES.CHAT_SPLIT]); + } + if (signupQualifier === CONST.ONBOARDING_SIGNUP_QUALIFIERS.VSB) { + Welcome.setOnboardingPurposeSelected(CONST.ONBOARDING_CHOICES.MANAGE_TEAM); + } + } + NetworkConnection.listenForReconnect(); NetworkConnection.onReconnect(handleNetworkReconnect); PusherConnectionManager.init(); diff --git a/src/libs/actions/Welcome/OnboardingFlow.ts b/src/libs/actions/Welcome/OnboardingFlow.ts index bc89effc9b50..4ab3cda27c64 100644 --- a/src/libs/actions/Welcome/OnboardingFlow.ts +++ b/src/libs/actions/Welcome/OnboardingFlow.ts @@ -10,6 +10,7 @@ import NAVIGATORS from '@src/NAVIGATORS'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import SCREENS from '@src/SCREENS'; +import type Onboarding from '@src/types/onyx/Onboarding'; let selectedPurpose: string | undefined = ''; Onyx.connect({ @@ -31,6 +32,17 @@ const onboardingLastVisitedPathConnection = Onyx.connect({ }, }); +let onboardingValues: Onboarding; +Onyx.connect({ + key: ONYXKEYS.NVP_ONBOARDING, + callback: (value) => { + if (value === undefined) { + return; + } + onboardingValues = value as Onboarding; + }, +}); + /** * Build the correct stack order for `onboardingModalNavigator`, * based on onboarding data (currently from the selected purpose). @@ -103,6 +115,11 @@ function startOnboardingFlow() { function getOnboardingInitialPath(): string { const state = getStateFromPath(onboardingInitialPath, linkingConfig.config); + const showBusinessModal = onboardingValues && CONST.QUALIFIER_PARAM in onboardingValues && onboardingValues.signupQualifier === CONST.ONBOARDING_SIGNUP_QUALIFIERS.VSB; + + if (showBusinessModal) { + return `/${ROUTES.ONBOARDING_WORK.route}`; + } if (state?.routes?.at(-1)?.name !== NAVIGATORS.ONBOARDING_MODAL_NAVIGATOR) { return `/${ROUTES.ONBOARDING_ROOT.route}`; } diff --git a/src/libs/actions/Welcome/index.ts b/src/libs/actions/Welcome/index.ts index b15c5a6cc39c..d27a5e195a0e 100644 --- a/src/libs/actions/Welcome/index.ts +++ b/src/libs/actions/Welcome/index.ts @@ -89,6 +89,10 @@ function checkOnboardingDataReady() { resolveOnboardingFlowStatus(); } +function setOnboardingCustomChoices(value: OnboardingPurposeType[]) { + Onyx.set(ONYXKEYS.ONBOARDING_CUSTOM_CHOICES, value ?? []); +} + function setOnboardingPurposeSelected(value: OnboardingPurposeType) { Onyx.set(ONYXKEYS.ONBOARDING_PURPOSE_SELECTED, value ?? null); } @@ -178,6 +182,7 @@ function resetAllChecks() { export { onServerDataReady, isOnboardingFlowCompleted, + setOnboardingCustomChoices, setOnboardingPurposeSelected, updateOnboardingLastVisitedPath, resetAllChecks, diff --git a/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx b/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx index 81f3e6be36ad..ca6b768136de 100644 --- a/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx +++ b/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx @@ -49,7 +49,12 @@ function BaseOnboardingPurpose({shouldUseNativeStyles, shouldEnableMaxHeight, ro const maxHeight = shouldEnableMaxHeight ? windowHeight : undefined; const paddingHorizontal = onboardingIsMediumOrLargerScreenWidth ? styles.ph8 : styles.ph5; - const menuItems: MenuItemProps[] = Object.values(CONST.SELECTABLE_ONBOARDING_CHOICES).map((choice) => { + const [customChoices = []] = useOnyx(ONYXKEYS.ONBOARDING_CUSTOM_CHOICES); + + const onboardingChoices = + customChoices.length > 0 ? Object.values(CONST.SELECTABLE_ONBOARDING_CHOICES).filter((choice) => customChoices.includes(choice)) : Object.values(CONST.SELECTABLE_ONBOARDING_CHOICES); + + const menuItems: MenuItemProps[] = onboardingChoices.map((choice) => { const translationKey = `onboarding.purpose.${choice}` as const; return { key: translationKey, diff --git a/src/pages/OnboardingWork/BaseOnboardingWork.tsx b/src/pages/OnboardingWork/BaseOnboardingWork.tsx index 7026bfcf28ae..9e8e2e3bbfa8 100644 --- a/src/pages/OnboardingWork/BaseOnboardingWork.tsx +++ b/src/pages/OnboardingWork/BaseOnboardingWork.tsx @@ -31,10 +31,13 @@ function BaseOnboardingWork({shouldUseNativeStyles, route}: BaseOnboardingWorkPr const {translate} = useLocalize(); const [onboardingPurposeSelected] = useOnyx(ONYXKEYS.ONBOARDING_PURPOSE_SELECTED); const [onboardingPolicyID] = useOnyx(ONYXKEYS.ONBOARDING_POLICY_ID); + const [onboardingValues] = useOnyx(ONYXKEYS.NVP_ONBOARDING); const {isSmallScreenWidth, onboardingIsMediumOrLargerScreenWidth} = useResponsiveLayout(); const {inputCallbackRef} = useAutoFocusInput(); const {isOffline} = useNetwork(); + const isVsbOnboarding = onboardingValues && CONST.QUALIFIER_PARAM in onboardingValues && onboardingValues.signupQualifier === CONST.ONBOARDING_SIGNUP_QUALIFIERS.VSB; + const completeEngagement = useCallback( (values: FormOnyxValues<'onboardingWorkForm'>) => { if (!onboardingPurposeSelected) { @@ -79,7 +82,7 @@ function BaseOnboardingWork({shouldUseNativeStyles, route}: BaseOnboardingWorkPr style={[styles.defaultModalContainer, shouldUseNativeStyles && styles.pt8]} > diff --git a/src/types/onyx/Onboarding.ts b/src/types/onyx/Onboarding.ts index bb250d895c87..4b6a52f25cb4 100644 --- a/src/types/onyx/Onboarding.ts +++ b/src/types/onyx/Onboarding.ts @@ -1,3 +1,6 @@ +import type {ValueOf} from 'type-fest'; +import type CONST from '@src/CONST'; + /** Model of onboarding */ type Onboarding = { /** ID of the report used to display the onboarding checklist message */ @@ -5,6 +8,9 @@ type Onboarding = { /** A Boolean that informs whether the user has completed the guided setup onboarding flow */ hasCompletedGuidedSetupFlow: boolean; + + /** A string that informs which qualifier the user selected during sign up */ + signupQualifier: ValueOf; }; export default Onboarding;