diff --git a/resources/js/components/Onboarding/OnboardingFlow.tsx b/resources/js/components/Onboarding/OnboardingFlow.tsx index 579fdfb..f7baba2 100644 --- a/resources/js/components/Onboarding/OnboardingFlow.tsx +++ b/resources/js/components/Onboarding/OnboardingFlow.tsx @@ -1,9 +1,47 @@ -import { useState, useEffect } from 'react'; +import { useState, useEffect, useCallback } from 'react'; import AssetSetupForm from '@/components/Assets/AssetSetupForm'; import AddPurchaseForm from '@/components/Transactions/AddPurchaseForm'; import AddMilestoneForm from '@/components/Milestones/AddMilestoneForm'; import UpdatePriceForm from '@/components/Pricing/UpdatePriceForm'; +type TrackerType = 'simple' | 'asset'; + +function TrackerTypeSelector({ onSelect }: { onSelect: (type: TrackerType) => void }) { + return ( +
+

+ [SELECT] What do you want to track? +

+ +
+ + + +
+
+ ); +} + function PriceTrackingStep({ onEnable, onSkip }: { onEnable: () => void; onSkip?: () => void }) { const [enabled, setEnabled] = useState(false); @@ -50,77 +88,48 @@ interface OnboardingStep { required: boolean; } +const ASSET_STEPS: OnboardingStep[] = [ + { id: 'asset', title: 'SET ASSET', description: 'Choose the asset you want to track', completed: false, required: true }, + { id: 'purchases', title: 'ADD PURCHASES', 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: 'purchases', 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 [trackerType, setTrackerType] = useState(null); const [currentStep, setCurrentStep] = useState(0); - const [steps, setSteps] = useState([ - { - id: 'asset', - title: 'SET ASSET', - description: 'Choose the asset you want to track', - completed: false, - required: true, - }, - { - id: 'purchases', - title: 'ADD PURCHASES', - 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 [steps, setSteps] = useState([]); - // Check onboarding status on mount - useEffect(() => { - checkOnboardingStatus(); - }, []); - - const checkOnboardingStatus = async () => { + const checkOnboardingStatus = useCallback(async (currentSteps: OnboardingStep[]) => { try { - // Check asset - const assetResponse = await fetch('/assets/current'); - const assetData = await assetResponse.json(); - const hasAsset = !!assetData.asset; + const [purchaseData, milestonesData, assetData, priceData] = await Promise.all([ + fetch('/purchases/summary').then(r => r.json()), + fetch('/milestones').then(r => r.json()), + fetch('/assets/current').then(r => r.json()), + fetch('/pricing/current').then(r => r.json()), + ]); - // Check purchases - const purchaseResponse = await fetch('/purchases/summary'); - const purchaseData = await purchaseResponse.json(); const hasPurchases = purchaseData.total_shares > 0; - - // Check milestones - const milestonesResponse = await fetch('/milestones'); - const milestonesData = await milestonesResponse.json(); const hasMilestones = milestonesData.length > 0; - - // Check current price - const priceResponse = await fetch('/pricing/current'); - const priceData = await priceResponse.json(); + const hasAsset = !!assetData.asset; const hasPrice = !!priceData.current_price; - const freshSteps = steps.map(step => ({ + const freshSteps = currentSteps.map(step => ({ ...step, completed: (step.id === 'asset' && hasAsset) || (step.id === 'purchases' && hasPurchases) || (step.id === 'milestones' && hasMilestones) || - (step.id === 'price' && hasPrice) + (step.id === 'price' && hasPrice), })); setSteps(freshSteps); @@ -129,24 +138,31 @@ export default function OnboardingFlow({ onComplete }: OnboardingFlowProps) { if (firstIncompleteRequired !== -1) { setCurrentStep(firstIncompleteRequired); - } else { - if (onComplete) { - onComplete(); - } + } else if (onComplete) { + onComplete(); } } catch (error) { console.error('Failed to check onboarding status:', error); } - }; + }, [onComplete]); + + useEffect(() => { + if (trackerType === null) { + return; + } + + const initialSteps = trackerType === 'simple' ? SIMPLE_STEPS : ASSET_STEPS; + setSteps(initialSteps); + setCurrentStep(0); + checkOnboardingStatus(initialSteps); + }, [trackerType, checkOnboardingStatus]); const handleStepComplete = async () => { - // Mark current step as completed - setSteps(prev => prev.map((step, index) => + const updatedSteps = steps.map((step, index) => index === currentStep ? { ...step, completed: true } : step - )); - - // Refresh onboarding status — handles setCurrentStep and onComplete - await checkOnboardingStatus(); + ); + setSteps(updatedSteps); + await checkOnboardingStatus(updatedSteps); }; const handleStepSelect = (stepIndex: number) => { @@ -155,33 +171,19 @@ export default function OnboardingFlow({ onComplete }: OnboardingFlowProps) { const renderStepContent = () => { const step = steps[currentStep]; - + if (!step) { + return null; + } + switch (step.id) { case 'asset': - return ( - - ); + return ; case 'purchases': - return ( - - ); + return ; case 'milestones': - return ( - - ); + return ; case 'price': - return ( - - ); + return ; default: return null; } @@ -190,66 +192,69 @@ export default function OnboardingFlow({ onComplete }: OnboardingFlowProps) { return (
- {/* Terminal-style border with red glow */}
- {/* Header */}

[SYSTEM] ONBOARDING SEQUENCE

- Set up your tracker + {trackerType === null ? 'Choose how you want to track' : 'Set up your tracker'}

- {/* Progress indicator */} -
-
- {steps.map((step, index) => ( - - ))} + {trackerType === null ? ( +
+
- -
-

- {steps[currentStep].description} -

-

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

-
-
+ ) : ( + <> +
+
+ {steps.map((step, index) => ( + + ))} +
- {/* Step content */} -
- {renderStepContent()} -
+
+

+ {steps[currentStep]?.description} +

+

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

+
+
- {/* Status footer */} -
-
-

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

-

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

-
-
+
+ {renderStepContent()} +
+ +
+
+

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

+

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

+
+
+ + )}
); -} \ No newline at end of file +}