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>
    </>
  )
}