File size: 4,572 Bytes
cf93910
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import { useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { Hand, Sun, Eye, ArrowRight, X } from 'lucide-react';

interface Props {
  onComplete: () => void;
}

const STEPS = [
  {
    icon: Hand,
    title: 'Position Your Hand',
    body: 'Hold your hand 30–60 cm from the camera with the palm facing forward. Make sure all five fingers are clearly visible.',
    color: '#00f5d4',
  },
  {
    icon: Sun,
    title: 'Check Your Lighting',
    body: 'Ensure your hand is well-lit from the front. Avoid strong back-lighting or dark backgrounds for best accuracy.',
    color: '#fee440',
  },
  {
    icon: Eye,
    title: 'Sign Clearly',
    body: 'Form each Gujarati sign deliberately. The system detects one hand at a time. Signs appear instantly in the HUD.',
    color: '#9b5de5',
  },
] as const;

const variants = {
  enter: (dir: number) => ({ x: dir > 0 ? 80 : -80, opacity: 0 }),
  center: { x: 0, opacity: 1 },
  exit:   (dir: number) => ({ x: dir > 0 ? -80 : 80, opacity: 0 }),
};

/**
 * 3-step animated onboarding wizard shown on first visit.
 */
export function OnboardingGuide({ onComplete }: Props) {
  const [step, setStep] = useState(0);
  const [dir,  setDir]  = useState(1);

  const go = (next: number) => {
    setDir(next > step ? 1 : -1);
    setStep(next);
  };

  const { icon: Icon, title, body, color } = STEPS[step];

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center"
         style={{ background: 'rgba(5,8,22,0.85)', backdropFilter: 'blur(8px)' }}>
      <div className="glass glow-border p-8 max-w-sm w-full mx-4 relative">

        {/* Skip / close */}
        <button
          onClick={onComplete}
          className="absolute top-4 right-4 text-slate-400 hover:text-white transition-colors"
          aria-label="Skip"
        >
          <X size={18} />
        </button>

        {/* Step indicator */}
        <div className="flex gap-2 mb-6">
          {STEPS.map((_, i) => (
            <div
              key={i}
              className="h-1 rounded-full flex-1 transition-all duration-300"
              style={{ background: i <= step ? color : 'rgba(255,255,255,0.1)' }}
            />
          ))}
        </div>

        {/* Animated step content */}
        <AnimatePresence custom={dir} mode="wait">
          <motion.div
            key={step}
            custom={dir}
            variants={variants}
            initial="enter"
            animate="center"
            exit="exit"
            transition={{ type: 'spring', stiffness: 300, damping: 30 }}
            className="flex flex-col items-center text-center gap-4"
          >
            <div
              className="w-20 h-20 rounded-full flex items-center justify-center"
              style={{
                background: `${color}15`,
                border: `2px solid ${color}40`,
                boxShadow: `0 0 20px ${color}30`,
              }}
            >
              <Icon size={36} style={{ color }} />
            </div>
            <h2 className="text-xl font-bold text-white">{title}</h2>
            <p className="text-slate-300 text-sm leading-relaxed">{body}</p>
          </motion.div>
        </AnimatePresence>

        {/* Navigation */}
        <div className="flex items-center justify-between mt-8">
          {step > 0 ? (
            <button
              onClick={() => go(step - 1)}
              className="text-sm text-slate-400 hover:text-white transition-colors px-3 py-1.5"
            >
              Back
            </button>
          ) : <div />}

          {step < STEPS.length - 1 ? (
            <button
              onClick={() => go(step + 1)}
              className="flex items-center gap-2 px-5 py-2.5 rounded-lg text-sm font-semibold transition-all"
              style={{
                background: `${color}20`,
                border: `1px solid ${color}50`,
                color,
              }}
            >
              Next <ArrowRight size={14} />
            </button>
          ) : (
            <button
              onClick={onComplete}
              className="flex items-center gap-2 px-5 py-2.5 rounded-lg text-sm font-semibold"
              style={{
                background: 'rgba(0,245,212,0.15)',
                border: '1px solid rgba(0,245,212,0.4)',
                color: '#00f5d4',
                boxShadow: '0 0 12px rgba(0,245,212,0.2)',
              }}
            >
              Start <ArrowRight size={14} />
            </button>
          )}
        </div>
      </div>
    </div>
  );
}