import React, { useState, useEffect } from 'react'; import { X, ChevronRight } from 'lucide-react'; type TourStep = { selector: string; title: string; body: string; }; const TOUR_STEPS: TourStep[] = [ { selector: '[data-tour="welcome"]', title: 'Willkommen bei EmberClone', body: 'Hier hast du den vollen Überblick über deine Projekte und deine investierte Zeit.', }, { selector: '[data-tour="nav-customers"]', title: 'Kunden verwalten', body: 'Lege hier deine Kunden an, um Projekte sauber zuordnen und später abzurechnen.', }, { selector: '[data-tour="nav-time"]', title: 'Zeit erfassen', body: 'Hier kannst du deine täglichen Einträge erstellen, bearbeiten und exportieren.', }, { selector: '[data-tour="search-hint"]', title: 'Schnellsuche', body: 'Nutze ⌘K (oder Strg+K), um blitzschnell durch deine Projekte zu navigieren.', }, ]; export default function OnboardingTour() { const [currentStep, setCurrentStep] = useState(null); const [coords, setCoords] = useState({ top: 0, left: 0, width: 0, height: 0 }); const [isVisible, setIsVisible] = useState(false); useEffect(() => { const isDone = localStorage.getItem('onboarding-done'); if (!isDone) { setCurrentStep(0); } }, []); useEffect(() => { if (currentStep === null) return; const updatePosition = () => { const element = document.querySelector(TOUR_STEPS[currentStep].selector); if (element) { const rect = element.getBoundingClientRect(); setCoords({ top: rect.top, left: rect.left, width: rect.width, height: rect.height, }); setIsVisible(true); } else { setIsVisible(false); } }; updatePosition(); window.addEventListener('resize', updatePosition); return () => window.removeEventListener('resize', updatePosition); }, [currentStep]); const handleNext = () => { if (currentStep === null) return; if (currentStep < TOUR_STEPS.length - 1) { setCurrentStep(currentStep + 1); } else { completeTour(); } }; const completeTour = () => { localStorage.setItem('onboarding-done', 'true'); setCurrentStep(null); }; if (currentStep === null || !isVisible) return null; const step = TOUR_STEPS[currentStep]; const isLastStep = currentStep === TOUR_STEPS.length - 1; return (
{/* Backdrop with Hole */}
{/* Popover Card */}
window.innerHeight - 250 ? coords.top - 220 : coords.top + coords.height + 16, left: Math.max(16, Math.min(window.innerWidth - 336, coords.left + (coords.width / 2) - 160)) }} >

{step.title}

{step.body}

{TOUR_STEPS.map((_, idx) => (
))}
); }