\## What does this PR do? Refactors the onboarding UI components to use shared layout components across personal and organization onboarding flows. This change: - Creates reusable `OnboardingCard` and `OnboardingLayout` components - Implements these components across all onboarding views - Maintains consistent UI and reduces code duplication - Improves maintainability by centralizing layout logic ## Visual Demo (For contributors especially) #### Image Demo: Before this change, each onboarding view had its own layout implementation with duplicated header, footer, and card structure. After this change, the shared components provide consistent styling and structure. ## 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 through the onboarding flow for both personal and organization accounts - Verify that all screens maintain consistent layout and styling - Check that progress indicators correctly show the current step - Ensure all functionality (form submissions, navigation between steps) works as expected ## 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
43 lines
1.3 KiB
TypeScript
43 lines
1.3 KiB
TypeScript
import type { ReactNode } from "react";
|
|
|
|
import { SkeletonText } from "@calcom/ui/components/skeleton";
|
|
|
|
type OnboardingCardProps = {
|
|
title: string;
|
|
subtitle: string;
|
|
children: ReactNode;
|
|
footer: ReactNode;
|
|
isLoading?: boolean;
|
|
};
|
|
|
|
export const OnboardingCard = ({ title, subtitle, children, footer, isLoading }: OnboardingCardProps) => {
|
|
return (
|
|
<div className="bg-muted border-muted relative rounded-xl border p-1">
|
|
<div className="rounded-inherit flex w-full flex-col items-start overflow-clip">
|
|
{/* Card Header */}
|
|
<div className="flex w-full gap-1.5 px-5 py-4">
|
|
<div className="flex w-full flex-col gap-1">
|
|
<h1 className="font-cal text-xl font-semibold leading-6">{title}</h1>
|
|
<p className="text-subtle text-sm font-medium leading-tight">{subtitle}</p>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Content */}
|
|
<div className="flex w-full flex-col gap-4">
|
|
{isLoading ? (
|
|
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
|
|
<SkeletonText className="h-40 w-full" />
|
|
<SkeletonText className="h-40 w-full" />
|
|
</div>
|
|
) : (
|
|
children
|
|
)}
|
|
</div>
|
|
|
|
{/* Footer */}
|
|
<div className="flex w-full items-center justify-end gap-1 px-5 py-4">{footer}</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|