## 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
42 lines
1.4 KiB
TypeScript
42 lines
1.4 KiB
TypeScript
import type { ReactNode } from "react";
|
|
|
|
import { Logo } from "@calcom/ui/components/logo";
|
|
|
|
type OnboardingLayoutProps = {
|
|
userEmail: string;
|
|
currentStep: 1 | 2 | 3 | 4;
|
|
children: ReactNode;
|
|
};
|
|
|
|
export const OnboardingLayout = ({ userEmail, currentStep, children }: OnboardingLayoutProps) => {
|
|
return (
|
|
<div className="bg-default flex min-h-screen w-full flex-col items-start overflow-clip rounded-xl">
|
|
{/* Header */}
|
|
<div className="flex w-full items-center justify-between px-6 py-4">
|
|
<Logo className="h-5 w-auto" />
|
|
|
|
{/* Progress dots - centered */}
|
|
<div className="absolute left-1/2 flex -translate-x-1/2 items-center justify-center gap-1">
|
|
{[1, 2, 3, 4].map((step) => (
|
|
<div
|
|
key={step}
|
|
className={`bg-${step <= currentStep ? "emphasis" : "subtle"} ${
|
|
step === currentStep ? "h-1.5 w-1.5" : "h-1 w-1"
|
|
} rounded-full`}
|
|
/>
|
|
))}
|
|
</div>
|
|
|
|
<div className="bg-muted flex items-center gap-2 rounded-full px-3 py-2">
|
|
<p className="text-emphasis text-sm font-medium leading-none">{userEmail}</p>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Main content */}
|
|
<div className="flex h-full w-full items-start justify-center px-6 py-8">
|
|
<div className="flex w-full max-w-[600px] flex-col gap-4">{children}</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|