'use client'; import React, { useState, useCallback, useEffect } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { X, BookOpen, BarChart3, Pencil, Flower2, FileText, PartyPopper, Users, ClipboardCheck, GraduationCap, Palette, Leaf, TreePine, CalendarDays, MessageSquare, Target, Zap, Award, Shield, Notebook, Grid3X3, Calculator, CalendarCheck, BookCheck, Briefcase, Clock, Library, Settings as SettingsIcon, Ruler, MessageSquareText, Heart, } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Checkbox } from '@/components/ui/checkbox'; 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'; const DONT_SHOW_KEY = 'ct_onboarding_dont_show'; interface OnboardingStep { iconComponent: React.ElementType; titleKey: string; descKey: string; accent: string; } const steps: OnboardingStep[] = [ { iconComponent: BookOpen, titleKey: 'onboarding.step_1_title', descKey: 'onboarding.step_1_desc', accent: 'from-emerald-400 to-teal-500', }, { iconComponent: BarChart3, titleKey: 'onboarding.step_2_title', descKey: 'onboarding.step_2_desc', accent: 'from-teal-400 to-emerald-500', }, { iconComponent: Users, titleKey: 'onboarding.step_3_title', descKey: 'onboarding.step_3_desc', accent: 'from-emerald-400 to-cyan-500', }, { iconComponent: Grid3X3, titleKey: 'onboarding.step_4_title', descKey: 'onboarding.step_4_desc', accent: 'from-cyan-400 to-emerald-500', }, { iconComponent: Pencil, titleKey: 'onboarding.step_5_title', descKey: 'onboarding.step_5_desc', accent: 'from-amber-400 to-emerald-500', }, { iconComponent: Flower2, titleKey: 'onboarding.step_6_title', descKey: 'onboarding.step_6_desc', accent: 'from-rose-400 to-emerald-500', }, { iconComponent: Grid3X3, titleKey: 'onboarding.step_7_title', descKey: 'onboarding.step_7_desc', accent: 'from-teal-400 to-cyan-500', }, { iconComponent: ClipboardCheck, titleKey: 'onboarding.step_8_title', descKey: 'onboarding.step_8_desc', accent: 'from-amber-400 to-rose-500', }, { iconComponent: Calculator, titleKey: 'onboarding.step_9_title', descKey: 'onboarding.step_9_desc', accent: 'from-violet-400 to-emerald-500', }, { iconComponent: CalendarCheck, titleKey: 'onboarding.step_10_title', descKey: 'onboarding.step_10_desc', accent: 'from-emerald-400 to-teal-500', }, { iconComponent: CalendarDays, titleKey: 'onboarding.step_11_title', descKey: 'onboarding.step_11_desc', accent: 'from-amber-400 to-teal-500', }, { iconComponent: CalendarDays, titleKey: 'onboarding.step_12_title', descKey: 'onboarding.step_12_desc', accent: 'from-teal-400 to-amber-500', }, { iconComponent: Shield, titleKey: 'onboarding.step_13_title', descKey: 'onboarding.step_13_desc', accent: 'from-rose-400 to-amber-500', }, { iconComponent: MessageSquare, titleKey: 'onboarding.step_14_title', descKey: 'onboarding.step_14_desc', accent: 'from-cyan-400 to-emerald-500', }, { iconComponent: Ruler, titleKey: 'onboarding.step_15_title', descKey: 'onboarding.step_15_desc', accent: 'from-amber-400 to-teal-500', }, { iconComponent: MessageSquareText, titleKey: 'onboarding.step_16_title', descKey: 'onboarding.step_16_desc', accent: 'from-teal-400 to-emerald-500', }, { iconComponent: Notebook, titleKey: 'onboarding.step_17_title', descKey: 'onboarding.step_17_desc', accent: 'from-emerald-400 to-teal-500', }, { iconComponent: Palette, titleKey: 'onboarding.step_18_title', descKey: 'onboarding.step_18_desc', accent: 'from-rose-400 to-violet-500', }, { iconComponent: Briefcase, titleKey: 'onboarding.step_19_title', descKey: 'onboarding.step_19_desc', accent: 'from-violet-400 to-emerald-500', }, { iconComponent: BookCheck, titleKey: 'onboarding.step_20_title', descKey: 'onboarding.step_20_desc', accent: 'from-amber-400 to-emerald-500', }, { iconComponent: Clock, titleKey: 'onboarding.step_21_title', descKey: 'onboarding.step_21_desc', accent: 'from-teal-400 to-cyan-500', }, { iconComponent: Library, titleKey: 'onboarding.step_22_title', descKey: 'onboarding.step_22_desc', accent: 'from-emerald-400 to-amber-500', }, { iconComponent: BarChart3, titleKey: 'onboarding.step_23_title', descKey: 'onboarding.step_23_desc', accent: 'from-teal-400 to-violet-500', }, { iconComponent: SettingsIcon, titleKey: 'onboarding.step_24_title', descKey: 'onboarding.step_24_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 [dontShowAgain, setDontShowAgain] = useState(false); const [showCelebration, setShowCelebration] = useState(false); useEffect(() => { if (open) { setCurrentStep(0); setShowCelebration(false); } }, [open]); const handleNext = useCallback(() => { if (currentStep < steps.length - 1) { setCurrentStep((s) => s + 1); } else { // Complete onboarding try { localStorage.setItem(ONBOARDING_KEY, 'true'); if (dontShowAgain) { localStorage.setItem(DONT_SHOW_KEY, 'true'); } } catch { // ignore } setShowCelebration(true); setTimeout(() => { onClose(); }, 2000); } }, [currentStep, onClose, dontShowAgain]); const handleBack = useCallback(() => { if (currentStep > 0) { setCurrentStep((s) => s - 1); } }, [currentStep]); const handleSkip = useCallback(() => { try { localStorage.setItem(ONBOARDING_KEY, 'true'); if (dontShowAgain) { localStorage.setItem(DONT_SHOW_KEY, 'true'); } } catch { // ignore } onClose(); }, [onClose, dontShowAgain]); const step = steps[currentStep]; const isLastStep = currentStep === steps.length - 1; const isFirstStep = currentStep === 0; const progress = ((currentStep + 1) / steps.length) * 100; return ( { if (!isOpen) handleSkip(); }}> {/* Hidden title for accessibility */} SchulOS Onboarding Tour {/* Close button */} {/* Progress bar */}
{/* Step content with animation */}
{/* Icon illustration with animated highlight ring */}
{/* Step number badge */} {t('onboarding.step', { current: String(currentStep + 1), total: String(steps.length) })} {/* Title */} {t(step.titleKey)} {/* Description */} {t(step.descKey)}
{/* Celebration overlay */} {showCelebration && ( {t('onboarding.celebration')} {t('onboarding.complete')} {/* Confetti-like particles */} {[...Array(8)].map((_, i) => ( ))} )}
{/* Step indicator dots (scrollable for 24 steps) */}
{steps.map((_, i) => (
{/* Action buttons */}
{!isFirstStep && ( )} {/* Don't show again checkbox */}
{!isLastStep && ( )}
); } export function isOnboardingCompleted(): boolean { try { return localStorage.getItem(ONBOARDING_KEY) === 'true'; } catch { return false; } } export function isDontShowAgain(): boolean { try { return localStorage.getItem(DONT_SHOW_KEY) === 'true'; } catch { return false; } }