File size: 3,763 Bytes
c6537a8
 
 
 
7a97213
c6537a8
 
 
7a97213
c6537a8
7a97213
c6537a8
 
 
 
7a97213
c6537a8
 
 
 
 
 
 
 
 
7a97213
c6537a8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import React, { useState, useEffect } from 'react';
import Icon from './CanvasIcon';
import { MOD } from './platform';

const TOUR_KEY = 'canvas-tour-seen-musclegrowth-v1';

const STEPS = [
  {
    title: 'Welcome to your Fitness Canvas',
    icon: 'shield',
    body: 'This is your training workspace. Two views — Insights (highlights from your chats) and Workspace (a customizable dashboard of widgets). It starts empty so you can build it the way you want.',
  },
  {
    title: 'Add widgets from the palette',
    icon: 'plus',
    body: `Click "Add widget" on the Workspace view, or hit ${MOD}+K and search. There are 30+ widgets — workouts, deadlines, tracking, notes, plus challenge widgets that push back on weak plans.`,
  },
  {
    title: 'Make it yours',
    icon: 'layout',
    body: 'Drag widget headers to reorder. Click the size pill (S/M/L) to resize. Hover and click trash to remove. Layout and content auto-save to your browser.',
  },
  {
    title: 'Try the challenge widgets',
    icon: 'gavel',
    body: 'Reviewer 2, Devil\'s Advocate, and Scope Realism are tuned to push back, not validate. They\'re where your program gets sharpened. Add them last — when you\'re ready for honest feedback.',
  },
];

const CanvasWelcomeTour = ({ forceShow = false, onClose }) => {
  const [step, setStep] = useState(0);
  const [visible, setVisible] = useState(false);

  useEffect(() => {
    const seen = localStorage.getItem(TOUR_KEY);
    if (forceShow || !seen) setVisible(true);
  }, [forceShow]);

  const dismiss = () => {
    localStorage.setItem(TOUR_KEY, '1');
    setVisible(false);
    if (onClose) onClose();
  };

  if (!visible) return null;

  const s = STEPS[step];
  const isLast = step === STEPS.length - 1;

  return (
    <div className="canvas-modal-backdrop" onClick={(e) => { if (e.target === e.currentTarget) dismiss(); }}>
      <div className="canvas-modal canvas-tour" onClick={(e) => e.stopPropagation()}>
        <div className="modal-head">
          <div className="modal-icon"><Icon name={s.icon} size={18}/></div>
          <div style={{ flex: 1 }}>
            <div className="modal-title">{s.title}</div>
            <div className="modal-sub">Step {step + 1} of {STEPS.length}</div>
          </div>
          <button className="icon-btn" onClick={dismiss} title="Skip"><Icon name="x" size={16}/></button>
        </div>
        <div className="modal-body" style={{ minHeight: 80 }}>
          <p style={{ margin: 0, fontSize: 13.5, lineHeight: 1.6, color: 'var(--canvas-text-2)' }}>{s.body}</p>
        </div>
        <div className="modal-foot" style={{ justifyContent: 'space-between' }}>
          <div style={{ display: 'flex', gap: 6 }}>
            {STEPS.map((_, i) => (
              <span key={i}
                onClick={() => setStep(i)}
                style={{
                  width: 8, height: 8, borderRadius: '50%', cursor: 'pointer',
                  background: i === step ? 'var(--canvas-accent)' : 'var(--canvas-surface-3)',
                  transition: 'background .15s',
                }}/>
            ))}
          </div>
          <div style={{ display: 'flex', gap: 8 }}>
            {step > 0 && (
              <button className="btn btn-ghost" onClick={() => setStep(s => s - 1)}>Back</button>
            )}
            {!isLast && (
              <button className="btn btn-ghost" onClick={dismiss}>Skip</button>
            )}
            <button className="btn btn-primary" onClick={() => isLast ? dismiss() : setStep(s => s + 1)}>
              {isLast ? <><Icon name="check" size={13}/>Get started</> : <>Next<Icon name="arrow" size={13}/></>}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
};

export default CanvasWelcomeTour;