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);
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: '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([]);
const checkOnboardingStatus = useCallback(async (currentSteps: OnboardingStep[]) => {
try {
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()),
]);
const hasPurchases = purchaseData.total_shares > 0;
const hasMilestones = milestonesData.length > 0;
const hasAsset = !!assetData.asset;
const hasPrice = !!priceData.current_price;
const freshSteps = currentSteps.map(step => ({
...step,
completed:
(step.id === 'asset' && hasAsset) ||
(step.id === 'purchases' && hasPurchases) ||
(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 (trackerType === null) {
return;
}
const initialSteps = trackerType === 'simple' ? SIMPLE_STEPS : ASSET_STEPS;
setSteps(initialSteps);
setCurrentStep(0);
checkOnboardingStatus(initialSteps);
}, [trackerType, checkOnboardingStatus]);
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 'asset':
return ;
case 'purchases':
return ;
case 'milestones':
return ;
case 'price':
return {})} />;
default:
return null;
}
};
return (
[SYSTEM] ONBOARDING SEQUENCE
{trackerType === null ? 'Choose how you want to track' : 'Set up your tracker'}
{trackerType === null ? (
) : (
<>
{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
>
)}
);
}