|
|
import React from 'react'; |
|
|
import { X, ArrowRight, ArrowLeft, MousePointer2, Link2, Play, Cpu } from 'lucide-react'; |
|
|
|
|
|
const steps = [ |
|
|
{ |
|
|
title: "Welcome to NeuroArch", |
|
|
content: "A visual environment to design AI architectures using a node-based system. Build pipelines by connecting data sources, processing units, and outputs.", |
|
|
icon: <Cpu className="text-primary" size={32} />, |
|
|
}, |
|
|
{ |
|
|
title: "Add Components", |
|
|
content: "Drag components from the left sidebar onto the canvas. Start with a 'Data Source' and add an 'LLM Core' to process it.", |
|
|
icon: <MousePointer2 className="text-accent" size={32} />, |
|
|
}, |
|
|
{ |
|
|
title: "Connect Nodes", |
|
|
content: "Select a node, then hold Shift and click another node to select multiple. Click 'Connect Selected' in the sidebar to link them.", |
|
|
icon: <Link2 className="text-success" size={32} />, |
|
|
}, |
|
|
{ |
|
|
title: "Run Simulation", |
|
|
content: "Once your architecture is built, click 'Run Simulation' to test data flow and visualize latency across your pipeline.", |
|
|
icon: <Play className="text-warning" size={32} />, |
|
|
} |
|
|
]; |
|
|
|
|
|
export default function Wizard({ isOpen, onClose, onFinish }) { |
|
|
const [currentStep, setCurrentStep] = React.useState(0); |
|
|
|
|
|
|
|
|
React.useEffect(() => { |
|
|
if (isOpen) setCurrentStep(0); |
|
|
}, [isOpen]); |
|
|
|
|
|
if (!isOpen) return null; |
|
|
|
|
|
const next = () => { |
|
|
if (currentStep < steps.length - 1) { |
|
|
setCurrentStep(currentStep + 1); |
|
|
} else { |
|
|
onFinish(); |
|
|
} |
|
|
}; |
|
|
|
|
|
const prev = () => { |
|
|
if (currentStep > 0) setCurrentStep(currentStep - 1); |
|
|
}; |
|
|
|
|
|
return ( |
|
|
<div className="fixed inset-0 z-[100] bg-deep/90 backdrop-blur-md flex items-center justify-center p-4"> |
|
|
<div className="bg-panel border border-border rounded-xl w-full max-w-lg shadow-2xl overflow-hidden animate-in fade-in zoom-in duration-300 relative"> |
|
|
{/* Decorative gradient blur behind icon */} |
|
|
<div className="absolute top-0 left-1/2 -translate-x-1/2 w-32 h-32 bg-primary/20 blur-[60px] rounded-full pointer-events-none" /> |
|
|
|
|
|
{/* Header */} |
|
|
<div className="flex justify-between items-center p-6 border-b border-border relative z-10"> |
|
|
<h2 className="text-xl font-bold text-main">Setup Wizard</h2> |
|
|
<button onClick={onClose} className="text-muted hover:text-white transition-colors" aria-label="Close wizard"> |
|
|
<X size={20} /> |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
{/* Content */} |
|
|
<div className="p-8 text-center space-y-6 relative z-10"> |
|
|
<div className="w-20 h-20 bg-surface rounded-2xl flex items-center justify-center mx-auto border border-border shadow-xl ring-1 ring-white/5"> |
|
|
{steps[currentStep].icon} |
|
|
</div> |
|
|
|
|
|
<div className="space-y-2"> |
|
|
<h3 className="text-xl font-semibold text-main">{steps[currentStep].title}</h3> |
|
|
<p className="text-muted leading-relaxed">{steps[currentStep].content}</p> |
|
|
</div> |
|
|
|
|
|
{/* Progress Dots */} |
|
|
<div className="flex justify-center gap-2.5 pt-4"> |
|
|
{steps.map((_, i) => ( |
|
|
<div |
|
|
key={i} |
|
|
className={`h-1.5 rounded-full transition-all duration-300 ${ |
|
|
i === currentStep ? 'w-8 bg-primary shadow-[0_0_10px_rgba(59,130,246,0.5)]' : |
|
|
i < currentStep ? 'w-1.5 bg-success' : 'w-1.5 bg-border' |
|
|
}`} |
|
|
/> |
|
|
))} |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
{/* Footer */} |
|
|
<div className="p-6 bg-surface/30 border-t border-border flex justify-between items-center relative z-10"> |
|
|
<button |
|
|
onClick={prev} |
|
|
disabled={currentStep === 0} |
|
|
className="px-4 py-2 rounded-lg text-sm text-muted hover:text-white hover:bg-white/5 disabled:opacity-30 disabled:cursor-not-allowed disabled:hover:bg-transparent transition-all flex items-center gap-2 font-medium" |
|
|
> |
|
|
<ArrowLeft size={16} /> Back |
|
|
</button> |
|
|
|
|
|
<span className="text-xs text-muted font-mono"> |
|
|
Step {currentStep + 1} of {steps.length} |
|
|
</span> |
|
|
|
|
|
<button |
|
|
onClick={next} |
|
|
className="px-6 py-2 rounded-lg bg-gradient-to-r from-primary to-blue-600 hover:from-blue-500 hover:to-blue-700 text-white font-medium text-sm transition-all shadow-lg shadow-primary/25 flex items-center gap-2 transform active:scale-95" |
|
|
> |
|
|
{currentStep === steps.length - 1 ? 'Get Started' : 'Next'} <ArrowRight size={16} /> |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
); |
|
|
} |