From 6ddc666827a6477e8d6213b1d9f6dff18f394f33 Mon Sep 17 00:00:00 2001 From: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Date: Mon, 27 Oct 2025 15:01:09 +0000 Subject: [PATCH] feat: onboarding v3 - app install flow personal (#24710) ## What does this PR do? Refactors the personal onboarding flow by creating reusable components for better code organization and maintainability. The changes include: - Creates shared components for the onboarding experience: `OnboardingLayout`, `OnboardingCard`, `InstallableAppCard`, and `SkipButton` - Implements a custom hook `useAppInstallation` to manage app installation state and callbacks - Enhances the video app connection step to automatically set the first connected video app as default - Improves the calendar connection flow with proper installation handling - Adds visual indicators for connected apps ## Visual Demo (For contributors especially) The refactored components maintain the same visual appearance while improving code structure and reusability. ## Mandatory Tasks - [x] I have self-reviewed the code - [x] I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. N/A - [x] I confirm automated tests are in place that prove my fix is effective or that my feature works. ## How should this be tested? - Go through the personal onboarding flow - Test connecting calendar apps in step 3 - Test connecting video apps in step 4 - Verify that the first connected video app is automatically set as default - Check that connected apps show the "connected" indicator - Verify that skipping steps works correctly ## Checklist - I have read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md) - My code follows the style guidelines of this project - I have commented my code, particularly in hard-to-understand areas - I have checked if my changes generate no new warnings --- .../_components/InstallableAppCard.tsx | 69 +++++++ .../personal/_components/OnboardingCard.tsx | 42 +++++ .../personal/_components/OnboardingLayout.tsx | 41 +++++ .../personal/_components/SkipButton.tsx | 21 +++ .../_components/useAppInstallation.ts | 38 ++++ .../calendar/personal-calendar-view.tsx | 118 +++--------- .../personal/video/personal-video-view.tsx | 171 +++++++----------- 7 files changed, 306 insertions(+), 194 deletions(-) create mode 100644 apps/web/modules/onboarding/personal/_components/InstallableAppCard.tsx create mode 100644 apps/web/modules/onboarding/personal/_components/OnboardingCard.tsx create mode 100644 apps/web/modules/onboarding/personal/_components/OnboardingLayout.tsx create mode 100644 apps/web/modules/onboarding/personal/_components/SkipButton.tsx create mode 100644 apps/web/modules/onboarding/personal/_components/useAppInstallation.ts diff --git a/apps/web/modules/onboarding/personal/_components/InstallableAppCard.tsx b/apps/web/modules/onboarding/personal/_components/InstallableAppCard.tsx new file mode 100644 index 0000000000..3c06e6d7d6 --- /dev/null +++ b/apps/web/modules/onboarding/personal/_components/InstallableAppCard.tsx @@ -0,0 +1,69 @@ +import { InstallAppButtonWithoutPlanCheck } from "@calcom/app-store/InstallAppButtonWithoutPlanCheck"; +import type { UseAddAppMutationOptions } from "@calcom/app-store/_utils/useAddAppMutation"; +import { useLocale } from "@calcom/lib/hooks/useLocale"; +import type { App } from "@calcom/types/App"; +import { Button } from "@calcom/ui/components/button"; + +type AppData = { + slug: string; + name: string; + description: string; + logo: string; + type: App["type"]; + userCredentialIds: number[]; +}; + +type InstallableAppCardProps = { + app: AppData; + isInstalling: boolean; + onInstallClick: (appSlug: string) => void; + installOptions: UseAddAppMutationOptions; +}; + +export const InstallableAppCard = ({ + app, + isInstalling, + onInstallClick, + installOptions, +}: InstallableAppCardProps) => { + const { t } = useLocale(); + const isInstalled = app.userCredentialIds && app.userCredentialIds.length > 0; + + return ( +
+ {app.name} +
+{app.description}
+{subtitle}
+{userEmail}
+{userEmail}
-- {t("connect_calendar_to_prevent_conflicts")} -
-- {app.name} -
-- {app.description} -
- -{userEmail}
-- {t("video_app_connection_subtitle")} -
-- {app.name} -
-- {app.description} -
- -