Files
calendar/apps/web/modules/onboarding/components/OnboardingLayout.tsx
T
sean-brydonandGitHub 52e27bab53 chore: Add shared onboarding components (OnboardingCard, OnboardingLayout, browser views) (#24946)
## What does this PR do?

Creates new onboarding UI components for the user onboarding flow, including:

- `OnboardingCard` - A reusable card component with title, subtitle, content, and footer sections
- `OnboardingLayout` - A layout component with progress indicators and sign-out functionality
- `OnboardingBrowserView` - A browser preview showing how the user's booking page will look
- `OnboardingCalendarBrowserView` - A calendar preview showing sample events
- `OnboardingInviteBrowserView` - A preview of the team invitation email
- Enhanced `PlanIcon` component with new variants and animations for organization and team plans

## Visual Demo (For contributors especially)

#### Image Demo:
The PR adds several visual components for the onboarding flow, including browser previews, calendar views, and animated plan icons with concentric rings and user avatars.

## Mandatory Tasks (DO NOT REMOVE)

- [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. If N/A, write N/A here and check the checkbox.
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

- Navigate to the onboarding flow to see the new components in action
- Test the layout with different screen sizes to ensure responsive behavior
- Verify that the browser previews render correctly with sample data
- Check that the plan icon animations work properly for different variants (single, team, organization)
- Ensure the calendar view displays sample events 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
2025-11-07 07:58:34 +00:00

65 lines
2.4 KiB
TypeScript

"use client";
import { signOut } from "next-auth/react";
import { Children, type ReactNode } from "react";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Button } from "@calcom/ui/components/button";
import { Logo } from "@calcom/ui/components/logo";
type OnboardingLayoutProps = {
userEmail: string;
currentStep: 1 | 2 | 3;
children: ReactNode;
};
export const OnboardingLayout = ({ userEmail, currentStep, children }: OnboardingLayoutProps) => {
const { t } = useLocale();
const handleSignOut = () => {
signOut({ callbackUrl: "/auth/logout" });
};
// Extract children as array
const childrenArray = Children.toArray(children);
const column1 = childrenArray[0];
const column2 = childrenArray[1];
return (
<div className="bg-muted flex min-h-screen w-full flex-col items-center justify-between overflow-clip rounded-[12px] px-6 py-10">
{/* Logo and container - centered */}
<div className="flex w-full flex-1 flex-col items-center justify-center gap-8">
<Logo className="h-5 w-auto shrink-0" />
<div className="border-subtle bg-default grid w-full max-w-[1130px] grid-cols-1 gap-6 overflow-hidden rounded-2xl border px-12 py-10 xl:h-[690px] xl:grid-cols-[40%_1fr] xl:pl-10 xl:pr-0">
{/* Column 1 - Always visible, 40% on xl+ */}
<div className="flex min-h-0 flex-col">{column1}</div>
{/* Column 2 - Hidden on mobile, visible on xl+, 60% on xl+ */}
{column2 && (
<div className="hidden h-full max-h-full min-h-0 flex-col overflow-hidden xl:flex">{column2}</div>
)}
</div>
</div>
{/* Footer with progress dots and sign out */}
<div className="flex w-full flex-col items-center justify-center gap-4 px-10 py-8">
<div className="flex items-center gap-2">
{[1, 2, 3].map((step) => (
<div key={step} className="relative flex h-2 w-2 shrink-0 items-center justify-center">
<div
className={`absolute inset-0 rounded-full ${
step <= currentStep ? "bg-emphasis" : "bg-muted"
}`}
/>
{step <= currentStep && <div className="bg-emphasis absolute h-1 w-1 rounded-full" />}
</div>
))}
</div>
<Button onClick={handleSignOut} color="minimal" className="text-subtle h-7">
{t("sign_out")}
</Button>
</div>
</div>
);
};