File size: 6,863 Bytes
bb52ddf 591fafa bb52ddf 591fafa bb52ddf 591fafa bb52ddf 591fafa bb52ddf 591fafa bb52ddf 591fafa bb52ddf 591fafa bb52ddf 591fafa bb52ddf |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
import { useState, useEffect } from 'react'
import { X, ChevronRight, ChevronLeft, HelpCircle, Zap, Layers, Share2, Palette, Code } from 'lucide-react'
import { useTutorial } from './TutorialContext'
const tutorialSteps = [
{
id: 'toolbar',
title: 'The Toolbar',
description: 'Access all neural layer types and tools from here. Drag nodes onto the canvas to start building.',
position: { top: '120px', left: '20px' },
target: 'toolbar'
},
{
id: 'canvas',
title: 'Design Canvas',
description: 'This is your main workspace. Drop nodes here and connect them to create your neural architecture.',
position: { top: '50%', left: '50%', transform: 'translate(-50%, -50%)' },
target: 'canvas'
},
{
id: 'properties',
title: 'Properties Panel',
description: 'Select any node to view and edit its parameters here. All layer configurations are centralized.',
position: { top: '120px', right: '20px' },
target: 'properties-panel'
},
{
id: 'connections',
title: 'Making Connections',
description: 'Click and drag from one node\'s output to another\'s input to create data flow connections.',
position: { top: '50%', left: '50%', transform: 'translate(-50%, -50%)' },
target: 'canvas'
},
{
id: 'export',
title: 'Export & Share',
description: 'Export your architecture to code or share with your team. Supports PyTorch, TensorFlow, and more.',
position: { bottom: '120px', right: '20px' },
target: 'export-button'
},
{
id: 'theme',
title: 'Dark Mode',
description: 'Toggle between light and dark themes for comfortable viewing in any environment.',
position: { top: '20px', right: '20px' },
target: 'theme-toggle'
},
{
id: 'complete',
title: 'Tutorial Complete!',
description: 'You\'re ready to start building. Remember, you can always access this tutorial from the help menu.',
position: { top: '50%', left: '50%', transform: 'translate(-50%, -50%)' },
target: null
}
]
export default function TutorialOverlay() {
const { currentStep, nextStep, previousStep, endTutorial } = useTutorial()
const [isVisible, setIsVisible] = useState(false)
const [highlightedElement, setHighlightedElement] = useState(null)
useEffect(() => {
setIsVisible(true)
const timer = setTimeout(() => {
const step = tutorialSteps[currentStep]
if (step.target) {
const element = document.querySelector(`[data-tutorial-target="${step.target}"]`)
setHighlightedElement(element)
} else {
setHighlightedElement(null)
}
}, 100)
return () => clearTimeout(timer)
}, [currentStep])
const handleNext = () => {
if (currentStep < tutorialSteps.length - 1) {
nextStep()
} else {
endTutorial()
}
}
const handlePrevious = () => {
if (currentStep > 0) {
previousStep()
}
}
const currentTutorialStep = tutorialSteps[currentStep]
return (
<>
{/* Overlay */}
<div className="fixed inset-0 bg-black bg-opacity-60 z-40" onClick={endTutorial} />
{/* Highlight Overlay */}
{highlightedElement && (
<div className="fixed inset-0 z-40 pointer-events-none">
<div
className="absolute border-4 border-primary-500 rounded-lg shadow-2xl transition-all duration-300"
style={{
...highlightedElement.getBoundingClientRect(),
boxShadow: '0 0 0 9999px rgba(0, 0, 0, 0.6)'
/>
</div>
)}
{/* Tutorial Tooltip */}
<div
className={`fixed z-50 bg-white rounded-2xl shadow-2xl p-6 max-w-sm transition-all duration-300 ${
isVisible ? 'opacity-100 scale-100' : 'opacity-0 scale-95'
}`}
style={currentTutorialStep.position}
>
{/* Progress Dots */}
<div className="flex items-center justify-center space-x-2 mb-4">
{tutorialSteps.map((_, index) => (
<div
key={index}
className={`w-2 h-2 rounded-full transition-all duration-300 ${
index === currentStep ? 'bg-primary-600 w-8' : 'bg-gray-300'
}`}
/>
))}
</div>
{/* Icon */}
<div className="w-12 h-12 bg-primary-100 rounded-full flex items-center justify-center mx-auto mb-4">
{currentStep === 0 && <Zap className="w-6 h-6 text-primary-600" />}
{currentStep === 1 && <Layers className="w-6 h-6 text-primary-600" />}
{currentStep === 2 && <Settings className="w-6 h-6 text-primary-600" />}
{currentStep === 3 && <Share2 className="w-6 h-6 text-primary-600" />}
{currentStep === 4 && <Code className="w-6 h-6 text-primary-600" />}
{currentStep === 5 && <Palette className="w-6 h-6 text-primary-600" />}
{currentStep === 6 && <Check className="w-6 h-6 text-primary-600" />}
</div>
{/* Content */}
<h3 className="text-xl font-bold text-gray-900 mb-3 text-center">
{currentTutorialStep.title}
</h3>
<p className="text-gray-600 mb-6 text-center">
{currentTutorialStep.description}
</p>
{/* Actions */}
<div className="flex items-center justify-between">
<button
onClick={handlePrevious}
disabled={currentStep === 0}
className={`flex items-center space-x-2 px-4 py-2 rounded-lg transition-colors ${
currentStep === 0
? 'text-gray-300 cursor-not-allowed'
: 'text-gray-700 hover:bg-gray-100'
}`}
>
<ChevronLeft className="w-4 h-4" />
<span className="text-sm">Previous</span>
</button>
<span className="text-sm text-gray-500">
{currentStep + 1} / {tutorialSteps.length}
</span>
<button
onClick={handleNext}
className="flex items-center space-x-2 px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors"
>
<span className="text-sm">
{currentStep === tutorialSteps.length - 1 ? 'Finish' : 'Next'}
</span>
<ChevronRight className="w-4 h-4" />
</button>
</div>
{/* Skip Tutorial */}
<button
onClick={endTutorial}
className="w-full mt-4 text-sm text-gray-500 hover:text-gray-700 transition-colors"
>
Skip tutorial
</button>
</div>
{/* Close Button */}
<button
onClick={endTutorial}
className="fixed top-4 right-4 z-50 w-10 h-10 bg-white rounded-full shadow-lg flex items-center justify-center hover:bg-gray-50 transition-colors"
>
<X className="w-5 h-5 text-gray-600" />
</button>
</>
)
} |