'use client'; import React, { useState, useCallback } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { X, BookOpen, BarChart3, Pencil, Flower2, FileText, PartyPopper } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { VisuallyHidden } from '@radix-ui/react-visually-hidden'; import { t } from '@/lib/i18n'; const ONBOARDING_KEY = 'ct_onboarding_completed'; interface OnboardingStep { iconComponent: React.ElementType; titleKey: string; descKey: string; accent: string; } const steps: OnboardingStep[] = [ { iconComponent: BookOpen, titleKey: 'onboarding.welcome_title', descKey: 'onboarding.welcome_desc', accent: 'from-emerald-400 to-teal-500', }, { iconComponent: BarChart3, titleKey: 'onboarding.dashboard_title', descKey: 'onboarding.dashboard_desc', accent: 'from-teal-400 to-emerald-500', }, { iconComponent: Pencil, titleKey: 'onboarding.progress_title', descKey: 'onboarding.progress_desc', accent: 'from-amber-400 to-emerald-500', }, { iconComponent: Flower2, titleKey: 'onboarding.flower_title', descKey: 'onboarding.flower_desc', accent: 'from-rose-400 to-emerald-500', }, { iconComponent: FileText, titleKey: 'onboarding.reports_title', descKey: 'onboarding.reports_desc', accent: 'from-violet-400 to-emerald-500', }, { iconComponent: PartyPopper, titleKey: 'onboarding.done_title', descKey: 'onboarding.done_desc', accent: 'from-emerald-400 to-teal-500', }, ]; interface OnboardingTourProps { open: boolean; onClose: () => void; } export default function OnboardingTour({ open, onClose }: OnboardingTourProps) { const [currentStep, setCurrentStep] = useState(0); const handleNext = useCallback(() => { if (currentStep < steps.length - 1) { setCurrentStep((s) => s + 1); } else { // Complete onboarding try { localStorage.setItem(ONBOARDING_KEY, 'true'); } catch { // ignore } onClose(); } }, [currentStep, onClose]); const handleBack = useCallback(() => { if (currentStep > 0) { setCurrentStep((s) => s - 1); } }, [currentStep]); const handleSkip = useCallback(() => { try { localStorage.setItem(ONBOARDING_KEY, 'true'); } catch { // ignore } onClose(); }, [onClose]); const step = steps[currentStep]; const isLastStep = currentStep === steps.length - 1; const isFirstStep = currentStep === 0; return ( { if (!isOpen) handleSkip(); }}> {/* Hidden title for accessibility */} CompetenceTrack Onboarding Tour {/* Close button */} {/* Step content with animation */}
{/* Emoji illustration */} {/* Title */} {t(step.titleKey)} {/* Description */} {t(step.descKey)}
{/* Step indicator dots */}
{steps.map((_, i) => (
{/* Step counter */}
{t('onboarding.step', { current: String(currentStep + 1), total: String(steps.length) })}
{/* Action buttons */}
{!isFirstStep && ( )}
{!isLastStep && ( )}
); } export function isOnboardingCompleted(): boolean { try { return localStorage.getItem(ONBOARDING_KEY) === 'true'; } catch { return false; } }