import React from "react"; import { LogOut } from "lucide-react"; import { Button } from "./button"; import { Stepper, Step, StepItem, StepIndicator, StepLabel } from "./stepper"; import { cn } from "../../lib/utils"; // ─── Types ──────────────────────────────────────────────────────────────────── export type OnboardingStep = { id: string; title: string; description?: string; isOptional?: boolean; isLocked?: boolean; }; export type OnboardingLayoutProps = { steps: OnboardingStep[]; currentStepIndex: number; /** Label for the primary action button. Defaults to "Next" / "Finish". */ nextLabel?: string; /** Disable the Next button (e.g. required fields not filled). */ canProceed?: boolean; onBack: () => void; onNext: () => void; /** Skip is only shown when provided and the step is not locked. */ onSkip?: () => void; /** Called when the user clicks "Upgrade Plan" on a locked step. */ onUpgrade?: () => void; className?: string; children: React.ReactNode; }; // ─── OnboardingLayout ───────────────────────────────────────────────────────── // ─── OnboardingPanelLayoutProps ─────────────────────────────────────────────── export type OnboardingPanelLayoutProps = { title: string; subtitle?: string; steps: OnboardingStep[]; currentStepIndex: number; canProceed?: boolean; onBack?: () => void; onNext?: () => void; onSkip?: () => void; /** Override the label on the last-step primary button. Defaults to "Finish Setup". */ finishLabel?: string; /** Show a logout button pinned to the bottom of the step list. */ showLogout?: boolean; /** Called when the logout button is clicked. */ onLogout?: () => void; /** Override the logout button label. Defaults to "Log out". */ logoutLabel?: string; className?: string; children: React.ReactNode; }; // ─── OnboardingPanelLayout ──────────────────────────────────────────────────── export function OnboardingPanelLayout({ title, subtitle, steps, currentStepIndex, canProceed = true, onBack, onNext, onSkip, finishLabel = "Finish Setup", showLogout = false, onLogout, logoutLabel = "Log out", className, children, }: OnboardingPanelLayoutProps) { const isFirstStep = currentStepIndex === 0; const isLastStep = currentStepIndex === steps.length - 1; const showFooter = onNext !== undefined || onBack !== undefined || onSkip !== undefined; return (
{/* ── Left panel — vertical stepper ── */}
{title} {subtitle && ( {subtitle} )}
{steps.length > 1 && (
{steps.map((step) => (
{step.title}
))}
)} {showLogout && (
)}
{/* ── Right panel — content + footer ── */}
{children}
{showFooter && (
{onNext && ( )} {!isFirstStep && onBack && ( )} {onSkip && ( )}
)}
); } // ─── OnboardingLayout ───────────────────────────────────────────────────────── export function OnboardingLayout({ steps, currentStepIndex, nextLabel, canProceed = true, onBack, onNext, onSkip, onUpgrade, className, children, }: OnboardingLayoutProps) { const isFirstStep = currentStepIndex === 0; const isLastStep = currentStepIndex === steps.length - 1; const currentStep = steps[currentStepIndex]; const isLocked = currentStep?.isLocked ?? false; const primaryLabel = isLocked ? "Upgrade Plan" : isLastStep ? "Finish Setup" : (nextLabel ?? "Next"); return (
{steps.map((step) => ( ))}
{children}
{onSkip && ( )}
{!isFirstStep && ( )}
); }