1 import type { ReactNode } from 'react';
2 import { type FC, useEffect, useMemo, useState } from 'react';
4 import { useUserSettings, useWelcomeFlags } from '@proton/account';
5 import type { ModalStateProps } from '@proton/components';
6 import { Loader, ModalTwo, ModalTwoContent, ModalTwoFooter, useApi, useDrivePlan } from '@proton/components';
7 import { updateFlags, updateWelcomeFlags } from '@proton/shared/lib/api/settings';
8 import { isMobile } from '@proton/shared/lib/helpers/browser';
9 import isTruthy from '@proton/utils/isTruthy';
10 import noop from '@proton/utils/noop';
12 import { useDesktopDownloads } from '../../../hooks/drive/useDesktopDownloads';
13 import { Actions, countActionWithTelemetry } from '../../../utils/telemetry';
14 import { useOnboarding } from '../../onboarding/useOnboarding';
15 import { Header } from './Header';
16 import { B2BInviteStep, B2BInviteStepButtons } from './steps/B2BInviteStep';
17 import { DesktopAppStep, DesktopAppStepButtons } from './steps/DesktopAppStep';
18 import { MobileAppStep, MobileAppStepButtons } from './steps/MobileAppStep';
19 import { PendingInvitationStep, PendingInvitationStepButtons } from './steps/PendingInvitationStep';
20 import { ThemeStep, ThemeStepButtons } from './steps/ThemeStep';
21 import { UploadStep, UploadStepButtons } from './steps/UploadStep';
22 import { WelcomeStep, WelcomeStepButtons } from './steps/WelcomeStep';
24 export const DriveOnboardingV2Modal: FC<ModalStateProps> = (props) => {
26 const { welcomeFlags, setDone: setWelcomeFlagsDone } = useWelcomeFlags();
27 const [userSettings] = useUserSettings();
29 const { isLoading: isOnboardingLoading, hasPendingExternalInvitations } = useOnboarding();
30 const { isB2B, isAdmin } = useDrivePlan();
32 const { downloads: desktopDownloads, isLoading: isDesktopDownloadsLoading } = useDesktopDownloads();
33 const isLoading = isOnboardingLoading || isDesktopDownloadsLoading;
34 const preferredPlatform = useMemo(
35 () => desktopDownloads.find((platform) => platform.isPreferred()),
39 const [step, setStep] = useState(0);
41 // Only show the B2B invite step to admins
42 const showB2BInviteStep = isB2B && isAdmin;
43 // Only show the desktop app step if there is a platform, and on desktop
44 const showDesktopAppStep = !!preferredPlatform && !isMobile();
45 // Only show if we have pending invitations
46 const showPendingInvitationsStep = !showB2BInviteStep && hasPendingExternalInvitations;
47 // Only show upload step on desktop
48 const showUploadStep = !isMobile();
52 countActionWithTelemetry(Actions.OnboardingV2Shown);
58 <ModalTwo open fullscreenOnMobile blurBackdrop size="xlarge">
59 <ModalTwoContent className="my-8">
60 <div className="flex flex-column items-center">
61 <Loader size="medium" className="my-4" />
69 [WelcomeStep, WelcomeStepButtons],
70 [ThemeStep, ThemeStepButtons],
71 showDesktopAppStep && [
73 DesktopAppStepButtons,
75 download: preferredPlatform.startDownload,
76 platform: preferredPlatform.platform,
79 [MobileAppStep, MobileAppStepButtons],
80 showB2BInviteStep && [B2BInviteStep, B2BInviteStepButtons],
81 showPendingInvitationsStep && [PendingInvitationStep, PendingInvitationStepButtons],
82 showUploadStep && [UploadStep, UploadStepButtons],
83 ].filter(isTruthy) as [() => ReactNode, () => ReactNode, any][];
85 const [Container, Buttons, extraProps] = steps[step] || [];
87 const onNext = () => {
88 if (step < steps.length - 1) {
89 setStep((step) => step + 1);
91 if (welcomeFlags.isWelcomeFlow) {
92 api(updateFlags({ Welcomed: 1 })).catch(noop);
94 if (!userSettings.WelcomeFlag) {
95 api(updateWelcomeFlags()).catch(noop);
97 setWelcomeFlagsDone();
104 <ModalTwo {...props} fullscreenOnMobile blurBackdrop size="xlarge" data-testid="drive-onboarding-v2">
105 <ModalTwoContent className="my-8">
108 maxSteps={steps.length}
109 onBack={step > 0 ? () => setStep((step) => step - 1) : undefined}
111 <Container {...extraProps} onNext={onNext} />
115 <Buttons {...extraProps} onNext={onNext} />