/** * OnboardingWizard Component * Multi-step wizard for new user onboarding * Provides a guided flow: Welcome → Add Site → Connect Integration → Add Keywords → Complete */ import React, { useState, useCallback, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { Card } from '../ui/card'; import Button from '../ui/button/Button'; import { ArrowRightIcon, ArrowLeftIcon, CloseIcon, BoltIcon, CheckCircleIcon, } from '../../icons'; import { useOnboardingStore } from '../../store/onboardingStore'; import { useToast } from '../ui/toast/ToastContainer'; // Step components import Step1Welcome from './steps/Step1Welcome'; import Step2AddSite from './steps/Step2AddSite'; import Step3ConnectIntegration from './steps/Step3ConnectIntegration'; import Step4AddKeywords from './steps/Step4AddKeywords'; import Step5Complete from './steps/Step5Complete'; export interface WizardStep { id: number; title: string; description: string; isOptional?: boolean; } export interface WizardData { // Site data siteName: string; domain: string; hostingType: string; industryId: number | null; industrySlug: string; selectedSectors: string[]; // Created site reference createdSiteId: number | null; // Integration data integrationTested: boolean; // Keywords data keywordsAdded: boolean; keywordsCount: number; } const STEPS: WizardStep[] = [ { id: 1, title: 'Welcome', description: 'Get started with IGNY8' }, { id: 2, title: 'Add Site', description: 'Create your first site' }, { id: 3, title: 'Connect', description: 'Install WordPress plugin', isOptional: true }, { id: 4, title: 'Keywords', description: 'Add target keywords', isOptional: true }, { id: 5, title: 'Complete', description: 'You\'re all set!' }, ]; interface OnboardingWizardProps { onComplete?: () => void; onSkip?: () => void; } export default function OnboardingWizard({ onComplete, onSkip }: OnboardingWizardProps) { const navigate = useNavigate(); const toast = useToast(); const { dismissGuide } = useOnboardingStore(); const [currentStep, setCurrentStep] = useState(1); const [isLoading, setIsLoading] = useState(false); const [wizardData, setWizardData] = useState({ siteName: '', domain: '', hostingType: 'wordpress', industryId: null, industrySlug: '', selectedSectors: [], createdSiteId: null, integrationTested: false, keywordsAdded: false, keywordsCount: 0, }); const updateWizardData = useCallback((updates: Partial) => { setWizardData(prev => ({ ...prev, ...updates })); }, []); const handleNext = useCallback(() => { if (currentStep < STEPS.length) { setCurrentStep(prev => prev + 1); } }, [currentStep]); const handleBack = useCallback(() => { if (currentStep > 1) { setCurrentStep(prev => prev - 1); } }, [currentStep]); const handleSkipStep = useCallback(() => { // Skip to next step (for optional steps) handleNext(); }, [handleNext]); const handleComplete = useCallback(async () => { setIsLoading(true); try { await dismissGuide(); if (onComplete) { onComplete(); } // Navigate to the site dashboard if (wizardData.createdSiteId) { navigate(`/sites/${wizardData.createdSiteId}`); } else { navigate('/dashboard'); } toast.success('Welcome to IGNY8! Your content pipeline is ready.'); } catch (error) { console.error('Failed to complete onboarding:', error); } finally { setIsLoading(false); } }, [dismissGuide, navigate, onComplete, toast, wizardData.createdSiteId]); const handleSkipAll = useCallback(async () => { await dismissGuide(); if (onSkip) { onSkip(); } navigate('/dashboard'); }, [dismissGuide, navigate, onSkip]); // Calculate progress percentage const progressPercent = ((currentStep - 1) / (STEPS.length - 1)) * 100; const renderStepContent = () => { switch (currentStep) { case 1: return ( ); case 2: return ( ); case 3: return ( ); case 4: return ( ); case 5: return ( ); default: return null; } }; return (
{/* Header */}

Getting Started

Step {currentStep} of {STEPS.length}

{/* Progress Bar */}
{STEPS.map((step) => (
{step.id < currentStep ? ( ) : ( step.id )}
{step.id < STEPS.length && (
)}
))}
{STEPS.map((step) => ( {step.title} ))}
{/* Step Content */}
{renderStepContent()}
); }