import { useEffect, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import { ArrowLeft, ArrowRight } from "lucide-react"; import { Button } from "@/components/button"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from "@/components/dialog"; import { useUiPreferencesContext } from "@/contexts/UiPreferencesContext"; import { useActionSlot } from "@/hooks/use-action-slot"; import { relevantSteps, type OnboardingContext, type OnboardingStep, } from "./onboarding-steps"; /** Plugin steps go in before this one. */ const PLUGIN_STEPS_BEFORE = "security"; export function OnboardingDialog({ open, context, onClose, }: { open: boolean; context: OnboardingContext; onClose: (skipped: boolean) => void; }) { const { t } = useTranslation(); const ctx = useUiPreferencesContext(); const pluginSteps = useActionSlot("onboarding.steps"); const steps = useMemo(() => { const core = relevantSteps(context); const extra: OnboardingStep[] = pluginSteps .filter((contribution) => contribution.component) .map((contribution) => ({ id: contribution.actionId, titleKey: contribution.titleKey, Component: contribution.component as unknown as OnboardingStep["Component"], })); const at = core.findIndex((step) => step.id === PLUGIN_STEPS_BEFORE); return at < 0 ? [...core, ...extra] : [...core.slice(0, at), ...extra, ...core.slice(at)]; }, [context, pluginSteps]); const [index, setIndex] = useState(0); // A reopened run always starts from the top. useEffect(() => { if (open) setIndex(0); }, [open]); if (steps.length === 0) return null; const clamped = Math.min(index, steps.length - 1); const step = steps[clamped]; const isLast = clamped === steps.length - 1; const StepComponent = step.Component; function finish(skipped: boolean) { ctx?.completeOnboarding(skipped); onClose(skipped); } return ( { if (!next) finish(true); }} > e.preventDefault()} > {t(step.titleKey)} {t("onboarding.stepCounter", { current: clamped + 1, total: steps.length, })}
{steps.map((s, i) => (
{!isLast && ( )} {clamped > 0 && ( )}
); }