import { useState, useEffect, useCallback } from 'react'; import AssetSetupForm from '@/components/Assets/AssetSetupForm'; import AddEntryForm from '@/components/Transactions/AddEntryForm'; import AddMilestoneForm from '@/components/Milestones/AddMilestoneForm'; import UpdatePriceForm from '@/components/Pricing/UpdatePriceForm'; import CreateTrackerStep from '@/components/Onboarding/CreateTrackerStep'; function PriceTrackingStep({ onEnable, onSkip }: { onEnable: () => void; onSkip?: () => void }) { const [enabled, setEnabled] = useState(false); return (

Track the current market price of your asset to see portfolio value and P&L. You can enable this later in settings.

{enabled && (
)} {!enabled && ( )}
); } interface OnboardingStep { id: string; title: string; description: string; completed: boolean; required: boolean; } const ASSET_STEPS: OnboardingStep[] = [ { id: 'entries', title: 'ADD ENTRIES', description: 'Enter your current holdings', completed: false, required: true }, { id: 'milestones', title: 'SET MILESTONES', description: 'Define your goals', completed: false, required: true }, { id: 'price', title: 'CURRENT PRICE', description: 'Set current asset price (optional)', completed: false, required: false }, ]; const SIMPLE_STEPS: OnboardingStep[] = [ { id: 'entries', title: 'STARTING AMOUNT', description: 'Enter your starting amount', completed: false, required: true }, { id: 'milestones', title: 'SET MILESTONES', description: 'Define your goals', completed: false, required: true }, ]; interface OnboardingFlowProps { onComplete?: () => void; } export default function OnboardingFlow({ onComplete }: OnboardingFlowProps) { const [trackerCreated, setTrackerCreated] = useState(false); const [priceTracking, setPriceTracking] = useState(false); const [currentStep, setCurrentStep] = useState(0); const [steps, setSteps] = useState([]); // On mount: check if a tracker already exists and skip step 1 if so useEffect(() => { fetch('/tracker') .then(r => r.ok ? r.json() : null) .then(data => { if (data?.tracker) { setPriceTracking(data.tracker.price_tracking_enabled ?? false); setTrackerCreated(true); } }) .catch(() => {}); }, []); const checkOnboardingStatus = useCallback(async (currentSteps: OnboardingStep[]) => { try { const [entriesData, milestonesData, priceData] = await Promise.all([ fetch('/entries/summary').then(r => r.json()), fetch('/milestones').then(r => r.json()), fetch('/pricing/current').then(r => r.json()), ]); const hasEntries = entriesData.total_quantity > 0; const hasMilestones = milestonesData.length > 0; const hasPrice = !!priceData.current_price; const freshSteps = currentSteps.map(step => ({ ...step, completed: (step.id === 'entries' && hasEntries) || (step.id === 'milestones' && hasMilestones) || (step.id === 'price' && hasPrice), })); setSteps(freshSteps); const firstIncompleteRequired = freshSteps.findIndex(s => s.required && !s.completed); if (firstIncompleteRequired !== -1) { setCurrentStep(firstIncompleteRequired); } else if (onComplete) { onComplete(); } } catch (error) { console.error('Failed to check onboarding status:', error); } }, [onComplete]); useEffect(() => { if (!trackerCreated) return; const initialSteps = priceTracking ? ASSET_STEPS : SIMPLE_STEPS; setSteps(initialSteps); setCurrentStep(0); checkOnboardingStatus(initialSteps); }, [trackerCreated, priceTracking, checkOnboardingStatus]); const handleTrackerCreated = (withPriceTracking: boolean) => { setPriceTracking(withPriceTracking); setTrackerCreated(true); }; const handleStepComplete = async () => { const updatedSteps = steps.map((step, index) => index === currentStep ? { ...step, completed: true } : step ); setSteps(updatedSteps); await checkOnboardingStatus(updatedSteps); }; const handleStepSelect = (stepIndex: number) => { setCurrentStep(stepIndex); }; const renderStepContent = () => { const step = steps[currentStep]; if (!step) return null; switch (step.id) { case 'entries': return ; case 'milestones': return ; case 'price': return {})} />; default: return null; } }; return (

[SYSTEM] ONBOARDING SEQUENCE

{!trackerCreated ? 'Set up your tracker' : 'Configure your tracker'}

{!trackerCreated ? (
) : ( <>
{steps.map((step, index) => ( ))}

{steps[currentStep]?.description}

STEP {currentStep + 1}/{steps.length}

{renderStepContent()}

[STATUS] {steps.filter(s => s.completed).length}/{steps.length} STEPS COMPLETE

{steps.filter(s => s.required && !s.completed).length} REQUIRED REMAINING

)}
); }