my-fleetbo-react-v1 1.0.5 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data.schema.json +14 -0
- package/package.json +1 -2
- package/src/App.jsx +21 -8
- package/src/app/mocks/SampleTab1.jsx +1 -1
- package/src/app/mocks/login/LoginWeb.jsx +369 -0
- package/src/app/tabs/Tab1.jsx +0 -13
package/data.schema.json
ADDED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "my-fleetbo-react-v1",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.6",
|
|
5
5
|
"description": "React template optimized for the Fleetbo ecosystem.",
|
|
6
6
|
"author": "Jean Aubain Noucti",
|
|
7
7
|
"license": "MIT",
|
|
@@ -29,7 +29,6 @@
|
|
|
29
29
|
"@types/react": "^19.2.14",
|
|
30
30
|
"@types/react-dom": "^19.2.3",
|
|
31
31
|
"@vitejs/plugin-react": "^6.0.0",
|
|
32
|
-
"cloudflared": "^0.7.1",
|
|
33
32
|
"eslint": "^9.39.4",
|
|
34
33
|
"eslint-plugin-react-hooks": "^7.0.1",
|
|
35
34
|
"eslint-plugin-react-refresh": "^0.5.2",
|
package/src/App.jsx
CHANGED
|
@@ -12,6 +12,7 @@ import NotFound from './app/core/NotFound';
|
|
|
12
12
|
|
|
13
13
|
// FLEETBO_IMPORTS
|
|
14
14
|
import Login from "./app/mocks/login/Login";
|
|
15
|
+
import LoginWeb from "./app/mocks/login/LoginWeb";
|
|
15
16
|
import SampleTab1 from './app/mocks/SampleTab1';
|
|
16
17
|
import SampleTab2 from './app/mocks/SampleTab2';
|
|
17
18
|
import SampleTab3 from './app/mocks/SampleTab3';
|
|
@@ -24,18 +25,18 @@ const TabRedirector = ({ children }) => {
|
|
|
24
25
|
return children;
|
|
25
26
|
};
|
|
26
27
|
|
|
27
|
-
const InitializingScreen = ({ error }) => (
|
|
28
|
+
const InitializingScreen = ({ error, isWeb }) => (
|
|
28
29
|
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100vh', flexDirection: 'column', padding: '20px', textAlign: 'center' }}>
|
|
29
30
|
{error ? (
|
|
30
31
|
<>
|
|
31
|
-
<i className=
|
|
32
|
-
<h5 className="text-danger">System Halt</h5>
|
|
32
|
+
<i className={`fa-solid ${isWeb ? 'fa-circle-exclamation text-warning' : 'fa-triangle-exclamation text-danger'} fa-3x mb-3`}></i>
|
|
33
|
+
<h5 className={isWeb ? "text-dark" : "text-danger"}>{isWeb ? "Synchronisation Fleetbo Engine" : "System Halt"}</h5>
|
|
33
34
|
<p style={{ marginTop: '1rem', color: '#6c757d' }}>{error}</p>
|
|
34
|
-
<button className="btn btn-outline-secondary mt-3" onClick={() => window.location.reload()}>Reboot</button>
|
|
35
|
+
<button className="btn btn-outline-secondary mt-3" onClick={() => window.location.reload()}>{isWeb ? "Recharger" : "Reboot"}</button>
|
|
35
36
|
</>
|
|
36
37
|
) : (
|
|
37
38
|
<div className="spinner-border text-success" role="status">
|
|
38
|
-
<span className="visually-hidden">Booting
|
|
39
|
+
<span className="visually-hidden">Booting...</span>
|
|
39
40
|
</div>
|
|
40
41
|
)}
|
|
41
42
|
</div>
|
|
@@ -44,6 +45,18 @@ const InitializingScreen = ({ error }) => (
|
|
|
44
45
|
function App() {
|
|
45
46
|
const { isEngineReady, isAuthenticated, sessionData, error } = useStartupEffect();
|
|
46
47
|
const [iframeAuthOverride, setIframeAuthOverride] = useState(false);
|
|
48
|
+
|
|
49
|
+
const isWeb = process.env.FLEETBO_TARGET === 'web'
|
|
50
|
+
|| !window.location.href.includes('localhost')
|
|
51
|
+
|| window.location.protocol === 'https:';
|
|
52
|
+
|
|
53
|
+
const isWebAuthError = isWeb && error && (
|
|
54
|
+
error.toLowerCase().includes("authentication") ||
|
|
55
|
+
error.toLowerCase().includes("outside of fleetbo") ||
|
|
56
|
+
error.toLowerCase().includes("required") ||
|
|
57
|
+
error.toLowerCase().includes("401") ||
|
|
58
|
+
error.toLowerCase().includes("unauthorized")
|
|
59
|
+
);
|
|
47
60
|
|
|
48
61
|
const location = useLocation();
|
|
49
62
|
const isNavbarRoute = location.pathname.includes('navbar') || location.hash.includes('navbar') || window.location.href.includes('navbar');
|
|
@@ -58,14 +71,14 @@ function App() {
|
|
|
58
71
|
}
|
|
59
72
|
}, [isNavbarRoute]);
|
|
60
73
|
|
|
61
|
-
if (error) return <InitializingScreen error={error} />;
|
|
74
|
+
if (error && !isWebAuthError) return <InitializingScreen error={error} isWeb={isWeb} />;
|
|
62
75
|
|
|
63
76
|
const isSimulator = !!window.__FLEETBO_SIMULATOR
|
|
64
77
|
|| window.location.hash.includes('simulator=1')
|
|
65
78
|
|| new URLSearchParams(window.location.search).get('simulator') === '1';
|
|
66
79
|
|
|
67
|
-
|
|
68
|
-
return <InitializingScreen />;
|
|
80
|
+
if (!isEngineReady && !isNavbarRoute && !isWebAuthError) {
|
|
81
|
+
return <InitializingScreen isWeb={isWeb} />;
|
|
69
82
|
}
|
|
70
83
|
|
|
71
84
|
const isActuallyAuthenticated = isAuthenticated || iframeAuthOverride;
|
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
import React, { useState, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
export default function LoginWeb() {
|
|
4
|
+
const [email, setEmail] = useState('');
|
|
5
|
+
const [otp, setOtp] = useState('');
|
|
6
|
+
const [step, setStep] = useState('email'); // 'email' | 'otp'
|
|
7
|
+
const [loading, setLoading] = useState(false);
|
|
8
|
+
const [error, setError] = useState('');
|
|
9
|
+
const [appInfo, setAppInfo] = useState({ name: 'Fleetbo App', description: 'Loading infrastructure...' });
|
|
10
|
+
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
const checkStatus = async () => {
|
|
13
|
+
if (window.Fleetbo && typeof window.Fleetbo.checkAuthStatusAndRedirect === 'function') {
|
|
14
|
+
try {
|
|
15
|
+
const res = await window.Fleetbo.checkAuthStatusAndRedirect();
|
|
16
|
+
if (res && res.success) {
|
|
17
|
+
setAppInfo({
|
|
18
|
+
name: res.appName || 'Fleetbo App',
|
|
19
|
+
description: res.description || 'DevTool Workspace'
|
|
20
|
+
});
|
|
21
|
+
if (res.isLoggedIn) {
|
|
22
|
+
window.Fleetbo.openView('Tab1', true);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
} catch (err) {
|
|
26
|
+
console.error("Infrastructure connection error:", err);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
checkStatus();
|
|
31
|
+
}, []);
|
|
32
|
+
|
|
33
|
+
const handleRequestOTP = async (e) => {
|
|
34
|
+
e.preventDefault();
|
|
35
|
+
if (!email) return setError('Email standard requis.');
|
|
36
|
+
setLoading(true);
|
|
37
|
+
setError('');
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
setTimeout(() => {
|
|
41
|
+
setLoading(false);
|
|
42
|
+
setStep('otp');
|
|
43
|
+
}, 1000);
|
|
44
|
+
} catch (err) {
|
|
45
|
+
setLoading(false);
|
|
46
|
+
setError('Échec de transmission de la clé d\'accès.');
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const handleVerifyLogin = async (e) => {
|
|
51
|
+
e.preventDefault();
|
|
52
|
+
if (!otp) return setError('Code OTP obligatoire.');
|
|
53
|
+
setLoading(true);
|
|
54
|
+
setError('');
|
|
55
|
+
|
|
56
|
+
if (window.Fleetbo && typeof window.Fleetbo.fleetboLog === 'function') {
|
|
57
|
+
try {
|
|
58
|
+
const res = await window.Fleetbo.fleetboLog();
|
|
59
|
+
if (res && res.success) {
|
|
60
|
+
window.Fleetbo.openView('Tab1', true);
|
|
61
|
+
} else {
|
|
62
|
+
throw new Error(res?.message || 'Access Denied.');
|
|
63
|
+
}
|
|
64
|
+
} catch (err) {
|
|
65
|
+
setLoading(false);
|
|
66
|
+
setError(err.message || 'Clé invalide ou environnement corrompu.');
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
setTimeout(() => {
|
|
70
|
+
setLoading(false);
|
|
71
|
+
alert('Mode Simulation : Connexion validée.');
|
|
72
|
+
}, 800);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<div className="fleetbo-web-production devtool-container">
|
|
78
|
+
<style>{`
|
|
79
|
+
.fleetbo-web-production.devtool-container {
|
|
80
|
+
background-color: #0B0F17;
|
|
81
|
+
color: #E2E8F0;
|
|
82
|
+
font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
83
|
+
min-height: 100vh;
|
|
84
|
+
display: flex;
|
|
85
|
+
align-items: center;
|
|
86
|
+
justify-content: center;
|
|
87
|
+
padding: 40px;
|
|
88
|
+
box-sizing: border-box;
|
|
89
|
+
overflow-x: hidden;
|
|
90
|
+
position: relative;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/* Background Glow Effects */
|
|
94
|
+
.fleetbo-web-production .grid-bg {
|
|
95
|
+
position: absolute;
|
|
96
|
+
top: 0; left: 0; right: 0; bottom: 0;
|
|
97
|
+
background-image: linear-gradient(rgba(14, 144, 77, 0.04) 1px, transparent 1px),
|
|
98
|
+
linear-gradient(90deg, rgba(14, 144, 77, 0.04) 1px, transparent 1px);
|
|
99
|
+
background-size: 32px 32px;
|
|
100
|
+
z-index: 1;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.fleetbo-web-production .glow-orb {
|
|
104
|
+
position: absolute;
|
|
105
|
+
width: 500px; height: 500px;
|
|
106
|
+
background: radial-gradient(circle, rgba(14, 144, 77, 0.08) 0%, transparent 70%);
|
|
107
|
+
top: -100px; right: -100px;
|
|
108
|
+
z-index: 1;
|
|
109
|
+
pointer-events: none;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/* Split Workspace Layout */
|
|
113
|
+
.fleetbo-web-production .workspace {
|
|
114
|
+
display: grid;
|
|
115
|
+
grid-template-columns: 1.1fr 0.9fr;
|
|
116
|
+
width: 100%;
|
|
117
|
+
max-width: 1200px;
|
|
118
|
+
background: rgba(17, 24, 39, 0.7);
|
|
119
|
+
border: 1px solid rgba(255, 255, 255, 0.06);
|
|
120
|
+
backdrop-filter: blur(20px);
|
|
121
|
+
border-radius: 16px;
|
|
122
|
+
box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5);
|
|
123
|
+
z-index: 10;
|
|
124
|
+
overflow: hidden;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/* Left Side: Brand & Live Architecture Showcase */
|
|
128
|
+
.fleetbo-web-production .showcase-panel {
|
|
129
|
+
padding: 60px;
|
|
130
|
+
border-right: 1px solid rgba(255, 255, 255, 0.05);
|
|
131
|
+
display: flex;
|
|
132
|
+
flex-direction: column;
|
|
133
|
+
justify-content: space-between;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.fleetbo-web-production .brand-header {
|
|
137
|
+
display: flex;
|
|
138
|
+
align-items: center;
|
|
139
|
+
gap: 12px;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.fleetbo-web-production .brand-logo {
|
|
143
|
+
width: 32px; height: 32px;
|
|
144
|
+
background: #0E904D;
|
|
145
|
+
border-radius: 6px;
|
|
146
|
+
box-shadow: 0 0 15px #0E904D;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.fleetbo-web-production .brand-title {
|
|
150
|
+
font-size: 20px; font-weight: 700; letter-spacing: -0.5px;
|
|
151
|
+
color: #FFF;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.fleetbo-web-production .hero-title {
|
|
155
|
+
font-size: 38px; font-weight: 800; line-height: 1.2;
|
|
156
|
+
letter-spacing: -1px; color: #FFF; margin: 40px 0 16px 0;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.fleetbo-web-production .hero-title span {
|
|
160
|
+
color: #0E904D;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.fleetbo-web-production .hero-desc {
|
|
164
|
+
color: #94A3B8; font-size: 16px; line-height: 1.5; margin-bottom: 30px;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/* Simulated Terminal Component */
|
|
168
|
+
.fleetbo-web-production .terminal-window {
|
|
169
|
+
background: #070A0F;
|
|
170
|
+
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
171
|
+
border-radius: 10px;
|
|
172
|
+
font-family: 'Fira Code', 'Courier New', monospace;
|
|
173
|
+
padding: 16px; font-size: 13px; box-shadow: inset 0 0 20px rgba(0,0,0,0.6);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.fleetbo-web-production .terminal-header {
|
|
177
|
+
display: flex; gap: 6px; margin-bottom: 12px;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.fleetbo-web-production .dot {
|
|
181
|
+
width: 8px; height: 8px; border-radius: 50%; background: #444;
|
|
182
|
+
}
|
|
183
|
+
.fleetbo-web-production .dot.red { background: #EF4444; }
|
|
184
|
+
.fleetbo-web-production .dot.yellow { background: #F59E0B; }
|
|
185
|
+
.fleetbo-web-production .dot.green { background: #10B981; }
|
|
186
|
+
|
|
187
|
+
.fleetbo-web-production .terminal-line {
|
|
188
|
+
margin-bottom: 6px; line-height: 1.4;
|
|
189
|
+
}
|
|
190
|
+
.fleetbo-web-production .t-cyan { color: #38BDF8; }
|
|
191
|
+
.fleetbo-web-production .t-green { color: #0E904D; }
|
|
192
|
+
.fleetbo-web-production .t-gray { color: #475569; }
|
|
193
|
+
|
|
194
|
+
/* Right Side: Gatekeeper Security Login Form */
|
|
195
|
+
.fleetbo-web-production .gatekeeper-panel {
|
|
196
|
+
padding: 60px;
|
|
197
|
+
background: rgba(10, 14, 22, 0.4);
|
|
198
|
+
display: flex; flex-direction: column; justify-content: center;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.fleetbo-web-production .form-box {
|
|
202
|
+
width: 100%; max-width: 360px; margin: 0 auto;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.fleetbo-web-production .gatekeeper-title {
|
|
206
|
+
font-size: 24px; font-weight: 700; color: #FFF; margin-bottom: 8px;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.fleetbo-web-production .gatekeeper-subtitle {
|
|
210
|
+
color: #64748B; font-size: 14px; margin-bottom: 32px;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.fleetbo-web-production .input-group {
|
|
214
|
+
margin-bottom: 20px; position: relative;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.fleetbo-web-production .input-label {
|
|
218
|
+
display: block; font-size: 12px; font-weight: 600; color: #94A3B8;
|
|
219
|
+
text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 8px;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.fleetbo-web-production .input-field {
|
|
223
|
+
width: 100%; padding: 12px 16px; background: #070A0F;
|
|
224
|
+
border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 8px;
|
|
225
|
+
color: #FFF; font-size: 14px; transition: all 0.2s; box-sizing: border-box;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.fleetbo-web-production .input-field:focus {
|
|
229
|
+
outline: none; border-color: #0E904D; box-shadow: 0 0 10px rgba(14, 144, 77, 0.2);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.fleetbo-web-production .btn-propulsion {
|
|
233
|
+
width: 100%; padding: 14px; background: #0E904D;
|
|
234
|
+
color: white; border: none; border-radius: 8px; font-size: 14px;
|
|
235
|
+
font-weight: 600; cursor: pointer; transition: all 0.2s;
|
|
236
|
+
box-shadow: 0 4px 15px rgba(14, 144, 77, 0.3);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.fleetbo-web-production .btn-propulsion:hover {
|
|
240
|
+
background: #11ab5c; box-shadow: 0 4px 20px rgba(14, 144, 77, 0.5);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.fleetbo-web-production .btn-propulsion:disabled {
|
|
244
|
+
background: #1E293B; color: #64748B; cursor: not-allowed; box-shadow: none;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.fleetbo-web-production .error-banner {
|
|
248
|
+
background: rgba(239, 68, 68, 0.1); border: 1px solid rgba(239, 68, 68, 0.2);
|
|
249
|
+
padding: 12px; border-radius: 8px; color: #FCA5A5; font-size: 13px; margin-bottom: 20px;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.fleetbo-web-production .back-link {
|
|
253
|
+
display: block; text-align: center; font-size: 13px; color: #64748B;
|
|
254
|
+
text-decoration: none; margin-top: 20px; cursor: pointer; transition: color 0.2s;
|
|
255
|
+
}
|
|
256
|
+
.fleetbo-web-production .back-link:hover { color: #0E904D; }
|
|
257
|
+
|
|
258
|
+
.fleetbo-web-production .footer-node {
|
|
259
|
+
margin-top: 40px; font-size: 12px; color: #475569; text-align: center;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
@media (max-width: 900px) {
|
|
263
|
+
.fleetbo-web-production .workspace { grid-template-columns: 1fr; }
|
|
264
|
+
.fleetbo-web-production .showcase-panel { display: none; }
|
|
265
|
+
.fleetbo-web-production .gatekeeper-panel { padding: 40px; }
|
|
266
|
+
}
|
|
267
|
+
`}</style>
|
|
268
|
+
|
|
269
|
+
<div className="grid-bg"></div>
|
|
270
|
+
<div className="glow-orb"></div>
|
|
271
|
+
|
|
272
|
+
<div className="workspace">
|
|
273
|
+
|
|
274
|
+
<div className="showcase-panel">
|
|
275
|
+
<div className="brand-header">
|
|
276
|
+
<div className="brand-logo"></div>
|
|
277
|
+
<div className="brand-title">Fleetbo Studio</div>
|
|
278
|
+
</div>
|
|
279
|
+
|
|
280
|
+
<div>
|
|
281
|
+
<h1 className="hero-title">
|
|
282
|
+
The Mobile Cloud OS. <br />
|
|
283
|
+
Engineered for <span>Web & Native</span>.
|
|
284
|
+
</h1>
|
|
285
|
+
<p className="hero-desc">
|
|
286
|
+
Forge complete applications at 120 FPS using only JavaScript.
|
|
287
|
+
Zero servers to configure, zero complex backend architecture, native deployment readiness.
|
|
288
|
+
</p>
|
|
289
|
+
|
|
290
|
+
<div className="terminal-window">
|
|
291
|
+
<div className="terminal-header">
|
|
292
|
+
<div className="dot red"></div>
|
|
293
|
+
<div className="dot yellow"></div>
|
|
294
|
+
<div className="dot green"></div>
|
|
295
|
+
</div>
|
|
296
|
+
<div className="terminal-line"><span className="t-gray">[system]</span> Initializing Ghost Memory Compilation...</div>
|
|
297
|
+
<div className="terminal-line"><span className="t-cyan">✔ [Vite]</span> 67 modules successfully transformed in 502ms.</div>
|
|
298
|
+
<div className="terminal-line"><span className="t-gray">[system]</span> Injecting sovereign Firebase and MongoDB data streams...</div>
|
|
299
|
+
<div className="terminal-line"><span className="t-green">✔ [Uplink]</span> Environment secure. Linked onto {appInfo.name}.</div>
|
|
300
|
+
</div>
|
|
301
|
+
</div>
|
|
302
|
+
|
|
303
|
+
<div className="t-gray" style={{ fontSize: '12px' }}>
|
|
304
|
+
Fleetbo Engine v8.0.0 · Core System Production Link
|
|
305
|
+
</div>
|
|
306
|
+
</div>
|
|
307
|
+
|
|
308
|
+
<div className="gatekeeper-panel">
|
|
309
|
+
<div className="form-box">
|
|
310
|
+
<h2 className="gatekeeper-title">Workspace Login</h2>
|
|
311
|
+
<p className="gatekeeper-subtitle">
|
|
312
|
+
Target Infrastructure: <span style={{ color: '#0E904D', fontWeight: '600' }}>{appInfo.name}</span>
|
|
313
|
+
</p>
|
|
314
|
+
|
|
315
|
+
{error && <div className="error-banner">✕ {error}</div>}
|
|
316
|
+
|
|
317
|
+
{step === 'email' ? (
|
|
318
|
+
<form onSubmit={handleRequestOTP}>
|
|
319
|
+
<div className="input-group">
|
|
320
|
+
<label className="input-label">Developer Identity (Email)</label>
|
|
321
|
+
<input
|
|
322
|
+
type="email"
|
|
323
|
+
className="input-field"
|
|
324
|
+
placeholder="pilot@fleetbo.io"
|
|
325
|
+
value={email}
|
|
326
|
+
onChange={(e) => setEmail(e.target.value)}
|
|
327
|
+
disabled={loading}
|
|
328
|
+
required
|
|
329
|
+
/>
|
|
330
|
+
</div>
|
|
331
|
+
<button type="submit" className="btn-propulsion" disabled={loading}>
|
|
332
|
+
{loading ? 'Requesting Keys...' : 'Request Activation Code'}
|
|
333
|
+
</button>
|
|
334
|
+
</form>
|
|
335
|
+
) : (
|
|
336
|
+
<form onSubmit={handleVerifyLogin}>
|
|
337
|
+
<div className="input-group">
|
|
338
|
+
<label className="input-label">Security Activation Code (OTP)</label>
|
|
339
|
+
<input
|
|
340
|
+
type="text"
|
|
341
|
+
className="input-field"
|
|
342
|
+
placeholder="000000"
|
|
343
|
+
maxLength={6}
|
|
344
|
+
value={otp}
|
|
345
|
+
onChange={(e) => setOtp(e.target.value)}
|
|
346
|
+
disabled={loading}
|
|
347
|
+
style={{ letterSpacing: '4px', textIndent: '4px', textAlign: 'center', fontSize: '18px', fontWeight: 'bold' }}
|
|
348
|
+
required
|
|
349
|
+
/>
|
|
350
|
+
</div>
|
|
351
|
+
<button type="submit" className="btn-propulsion" disabled={loading}>
|
|
352
|
+
{loading ? 'Engaging Propulsion...' : 'Verify & Launch System'}
|
|
353
|
+
</button>
|
|
354
|
+
<span className="back-link" onClick={() => setStep('email')}>
|
|
355
|
+
← Use a different account
|
|
356
|
+
</span>
|
|
357
|
+
</form>
|
|
358
|
+
)}
|
|
359
|
+
|
|
360
|
+
<div className="footer-node">
|
|
361
|
+
Protected by Fleetbo WebGatekeeper Layer. <br />
|
|
362
|
+
Unauthorized access attempts are audited globally.
|
|
363
|
+
</div>
|
|
364
|
+
</div>
|
|
365
|
+
</div>
|
|
366
|
+
</div>
|
|
367
|
+
</div>
|
|
368
|
+
);
|
|
369
|
+
}
|
package/src/app/tabs/Tab1.jsx
CHANGED
|
@@ -1,18 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tab1.jsx — Fleetbo JS in Action
|
|
3
|
-
*
|
|
4
|
-
* JS = Brain (orchestrates) | Native = Muscle (executes) | Alex = Architect (forges)
|
|
5
|
-
*
|
|
6
|
-
* Two patterns:
|
|
7
|
-
* Manager → List + Create in one module. Fleetbo.openView('GuestManager', true)
|
|
8
|
-
* Atomic → One action, closes. await Fleetbo.exec('Scanner', 'open', {})
|
|
9
|
-
*
|
|
10
|
-
* Alex (npm run alex):
|
|
11
|
-
* "Forge a guest manager with list and photo" → Alex builds
|
|
12
|
-
* "A guest manager with list and photo" → Alex stays conversational
|
|
13
|
-
*
|
|
14
|
-
* Rule: use "forge", "patch" before prompt code generation.
|
|
15
|
-
*
|
|
16
3
|
* Quick ref:
|
|
17
4
|
* Fleetbo.openView('Module', true) → Full Native view/tab (120 FPS)
|
|
18
5
|
* Fleetbo.exec('Module', 'action', {}) → Native overlay (Atomic)
|