fernando-bold commited on
Commit
4da592e
·
verified ·
1 Parent(s): c0f865f

"use client"

Browse files

import React, { useState } from "react"
import Joyride, { Step } from "react-joyride"

const steps: Step[] = [
{
target: ".step-1",
content: "This is the main dashboard.",
},
{
target: ".step-2",
content: "Here you can see your recent activity.",
},
{
target: ".step-3",
content: "Click here to create a new item.",
},
]

const FirstVisitTour = () => {
const [run, setRun] = useState(false)

const handleStartTour = () => {
setRun(true)
}

return (
<div>
<button onClick={handleStartTour} className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Start Tour
</button>
<Joyride
steps={steps}
run={run}
continuous
showProgress
showSkipButton
callback={({ status }) => {
if (status === "finished" || status === "skipped") {
setRun(false)
}
}}
/>
</div>
)
}

export default FirstVisitTour

Files changed (2) hide show
  1. components/tour-guide.js +165 -0
  2. index.html +9 -8
components/tour-guide.js ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class TourGuide extends HTMLElement {
2
+ constructor() {
3
+ super();
4
+ this.steps = [
5
+ {
6
+ target: '.step-1',
7
+ content: 'This is the main dashboard.',
8
+ },
9
+ {
10
+ target: '.step-2',
11
+ content: 'Here you can see your recent activity.',
12
+ },
13
+ {
14
+ target: '.step-3',
15
+ content: 'Click here to create a new item.',
16
+ }
17
+ ];
18
+ this.currentStep = 0;
19
+ this.isRunning = false;
20
+ }
21
+
22
+ connectedCallback() {
23
+ this.render();
24
+ this.setupEventListeners();
25
+ }
26
+
27
+ render() {
28
+ this.innerHTML = `
29
+ <style>
30
+ .tour-button {
31
+ background: #3b82f6;
32
+ color: white;
33
+ font-weight: 600;
34
+ padding: 0.5rem 1rem;
35
+ border-radius: 0.375rem;
36
+ cursor: pointer;
37
+ transition: background 0.2s;
38
+ border: none;
39
+ }
40
+ .tour-button:hover {
41
+ background: #2563eb;
42
+ }
43
+ .tour-overlay {
44
+ position: fixed;
45
+ top: 0;
46
+ left: 0;
47
+ right: 0;
48
+ bottom: 0;
49
+ background: rgba(0,0,0,0.5);
50
+ z-index: 9998;
51
+ }
52
+ .tour-tooltip {
53
+ position: absolute;
54
+ background: white;
55
+ border-radius: 0.5rem;
56
+ padding: 1rem;
57
+ max-width: 300px;
58
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
59
+ z-index: 9999;
60
+ }
61
+ .tour-footer {
62
+ display: flex;
63
+ justify-content: space-between;
64
+ margin-top: 1rem;
65
+ }
66
+ .tour-button-small {
67
+ padding: 0.25rem 0.5rem;
68
+ font-size: 0.875rem;
69
+ }
70
+ .tour-progress {
71
+ font-size: 0.875rem;
72
+ color: #6b7280;
73
+ }
74
+ </style>
75
+ <button class="tour-button">Start Tour</button>
76
+ `;
77
+ }
78
+
79
+ setupEventListeners() {
80
+ this.querySelector('.tour-button').addEventListener('click', () => this.startTour());
81
+ }
82
+
83
+ startTour() {
84
+ this.isRunning = true;
85
+ this.currentStep = 0;
86
+ this.showStep();
87
+ }
88
+
89
+ showStep() {
90
+ // Remove any existing tooltips
91
+ this.removeTooltips();
92
+
93
+ const step = this.steps[this.currentStep];
94
+ const targetElement = document.querySelector(step.target);
95
+
96
+ if (!targetElement) {
97
+ console.warn(`Target element not found: ${step.target}`);
98
+ this.nextStep();
99
+ return;
100
+ }
101
+
102
+ // Create overlay
103
+ const overlay = document.createElement('div');
104
+ overlay.className = 'tour-overlay';
105
+ document.body.appendChild(overlay);
106
+
107
+ // Position tooltip
108
+ const rect = targetElement.getBoundingClientRect();
109
+ const tooltip = document.createElement('div');
110
+ tooltip.className = 'tour-tooltip';
111
+ tooltip.style.top = `${rect.bottom + window.scrollY + 10}px`;
112
+ tooltip.style.left = `${rect.left + window.scrollX}px`;
113
+
114
+ tooltip.innerHTML = `
115
+ <div>${step.content}</div>
116
+ <div class="tour-footer">
117
+ <span class="tour-progress">${this.currentStep + 1}/${this.steps.length}</span>
118
+ <div>
119
+ <button class="tour-button-small skip-button">Skip</button>
120
+ <button class="tour-button-small next-button">${this.currentStep === this.steps.length - 1 ? 'Finish' : 'Next'}</button>
121
+ </div>
122
+ </div>
123
+ `;
124
+
125
+ document.body.appendChild(tooltip);
126
+
127
+ // Highlight target
128
+ targetElement.style.boxShadow = '0 0 0 3px rgba(59, 130, 246, 0.5)';
129
+ targetElement.style.position = 'relative';
130
+ targetElement.style.zIndex = '10000';
131
+
132
+ // Add event listeners
133
+ tooltip.querySelector('.next-button').addEventListener('click', () => this.nextStep());
134
+ tooltip.querySelector('.skip-button').addEventListener('click', () => this.endTour());
135
+ }
136
+
137
+ nextStep() {
138
+ this.currentStep++;
139
+ if (this.currentStep < this.steps.length) {
140
+ this.showStep();
141
+ } else {
142
+ this.endTour();
143
+ }
144
+ }
145
+
146
+ endTour() {
147
+ this.isRunning = false;
148
+ this.removeTooltips();
149
+ // Remove highlights
150
+ this.steps.forEach(step => {
151
+ const element = document.querySelector(step.target);
152
+ if (element) {
153
+ element.style.boxShadow = '';
154
+ element.style.zIndex = '';
155
+ }
156
+ });
157
+ }
158
+
159
+ removeTooltips() {
160
+ const tooltips = document.querySelectorAll('.tour-tooltip, .tour-overlay');
161
+ tooltips.forEach(tooltip => tooltip.remove());
162
+ }
163
+ }
164
+
165
+ customElements.define('tour-guide', TourGuide);
index.html CHANGED
@@ -13,14 +13,16 @@
13
  <script src="components/power-capacity-chart.js"></script>
14
  <script src="components/interactive-chart.js"></script>
15
  <script src="components/efficiency-chart.js"></script>
 
16
  </head>
17
  <body class="bg-gray-50 min-h-screen">
18
  <div class="container mx-auto px-4 py-12">
19
  <header class="mb-12 text-center">
20
  <h1 class="text-4xl font-bold text-gray-900 mb-2">ROI Visionary</h1>
21
  <p class="text-xl text-gray-600">Solar Investment Payback Predictor</p>
 
22
  </header>
23
- <nav class="flex justify-center mb-8">
24
  <ul class="flex space-x-4">
25
  <li><a href="index.html" class="px-4 py-2 rounded-md hover:bg-gray-100">Home</a></li>
26
  <li><a href="technical-sheets.html" class="px-4 py-2 rounded-md hover:bg-gray-100">Technical Sheets</a></li>
@@ -30,8 +32,8 @@
30
 
31
  <main class="max-w-4xl mx-auto">
32
  <div class="grid md:grid-cols-2 gap-8 mb-8">
33
- <div class="bg-white p-6 rounded-xl shadow-md">
34
- <h2 class="text-2xl font-semibold mb-4 text-gray-800">Investment Parameters</h2>
35
  <div class="space-y-4">
36
  <div>
37
  <label class="block text-sm font-medium text-gray-700 mb-1">Initial Investment (R$)</label>
@@ -48,14 +50,13 @@
48
  <input type="number" id="yearsToShow" value="25"
49
  class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
50
  </div>
51
- <button id="calculateBtn" class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded-md transition duration-200">
52
- Calculate ROI
53
  </button>
54
  </div>
55
  </div>
56
-
57
- <div class="bg-white p-6 rounded-xl shadow-md">
58
- <h2 class="text-2xl font-semibold mb-4 text-gray-800">Quick Summary</h2>
59
  <div class="space-y-4">
60
  <div class="flex justify-between items-center">
61
  <span class="text-gray-600">Payback Period</span>
 
13
  <script src="components/power-capacity-chart.js"></script>
14
  <script src="components/interactive-chart.js"></script>
15
  <script src="components/efficiency-chart.js"></script>
16
+ <script src="components/tour-guide.js"></script>
17
  </head>
18
  <body class="bg-gray-50 min-h-screen">
19
  <div class="container mx-auto px-4 py-12">
20
  <header class="mb-12 text-center">
21
  <h1 class="text-4xl font-bold text-gray-900 mb-2">ROI Visionary</h1>
22
  <p class="text-xl text-gray-600">Solar Investment Payback Predictor</p>
23
+ <tour-guide></tour-guide>
24
  </header>
25
+ <nav class="flex justify-center mb-8">
26
  <ul class="flex space-x-4">
27
  <li><a href="index.html" class="px-4 py-2 rounded-md hover:bg-gray-100">Home</a></li>
28
  <li><a href="technical-sheets.html" class="px-4 py-2 rounded-md hover:bg-gray-100">Technical Sheets</a></li>
 
32
 
33
  <main class="max-w-4xl mx-auto">
34
  <div class="grid md:grid-cols-2 gap-8 mb-8">
35
+ <div class="bg-white p-6 rounded-xl shadow-md step-1">
36
+ <h2 class="text-2xl font-semibold mb-4 text-gray-800">Investment Parameters</h2>
37
  <div class="space-y-4">
38
  <div>
39
  <label class="block text-sm font-medium text-gray-700 mb-1">Initial Investment (R$)</label>
 
50
  <input type="number" id="yearsToShow" value="25"
51
  class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
52
  </div>
53
+ <button id="calculateBtn" class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded-md transition duration-200 step-3">
54
+ Calculate ROI
55
  </button>
56
  </div>
57
  </div>
58
+ <div class="bg-white p-6 rounded-xl shadow-md step-2">
59
+ <h2 class="text-2xl font-semibold mb-4 text-gray-800">Quick Summary</h2>
 
60
  <div class="space-y-4">
61
  <div class="flex justify-between items-center">
62
  <span class="text-gray-600">Payback Period</span>