/* global React */ // ======================================================================= // BlazeConnector Admin v3 — Gate de conexión + chip de estado // Pantalla inicial para conectar el UI a un backend BlazeConnector real // (base URL + X-Admin-Token), o entrar en modo demo (mocks). // ======================================================================= const { useState: _cs, useEffect: _ce } = React; function ConnectGate() { const bc = window.useBC(); const cfg = window.BC.getConfig(); const [baseUrl, setBaseUrl] = _cs((cfg && cfg.baseUrl) || 'http://localhost:8080'); const [token, setToken] = _cs((cfg && cfg.token) || ''); const [testing, setTesting] = _cs(false); const [test, setTest] = _cs(null); // { ok:bool, msg:string } const [busy, setBusy] = _cs(false); // Visible mientras no estemos conectados y el usuario no haya elegido demo. const visible = bc.status !== 'connected' && !bc.demoChosen; if (!visible) return null; async function doTest() { setTesting(true); setTest(null); try { const n = await window.BC.test(baseUrl, token); setTest({ ok: true, msg: 'Conexión OK · ' + n + ' tenant(s) visibles' }); } catch (e) { setTest({ ok: false, msg: e.message || 'Falló la conexión' }); } finally { setTesting(false); } } async function doConnect() { setBusy(true); setTest(null); try { await window.BC.connect(baseUrl, token); // status pasa a 'connected' → el gate se oculta solo. } catch (e) { setTest({ ok: false, msg: e.message || 'Falló la conexión' }); } finally { setBusy(false); } } const connecting = bc.status === 'connecting' || busy; return (
e.stopPropagation()}>
BLAZE

Conectar a BlazeConnector

Panel de administración · v3

{test && (
{test.msg}
)}
El token queda solo en localStorage de este navegador. Para local usa el ADMIN_TOKEN de tu .env.
); } const inputStyle = { background: 'var(--app-input-bg)', border: '1px solid var(--app-border)', borderRadius: 6, padding: '9px 11px', color: 'var(--app-fg1)', fontFamily: 'inherit', fontSize: 13 }; // Chip de estado en el Topbar: live / demo / connecting / error. function ConnectionChip() { const bc = window.useBC(); const [open, setOpen] = _cs(false); const ref = React.useRef(null); _ce(() => { if (!open) return; const fn = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); }; document.addEventListener('mousedown', fn); return () => document.removeEventListener('mousedown', fn); }, [open]); const map = { connected: { tone: '', lbl: 'live', ico: 'plug' }, connecting: { tone: 'is-degraded', lbl: 'conectando…', ico: 'loader' }, error: { tone: 'is-down', lbl: 'error', ico: 'circle-x' }, disconnected: { tone: 'is-degraded', lbl: 'demo', ico: 'flask-conical' } }; const m = bc.mode === 'demo' && bc.status !== 'connecting' ? { tone: 'is-degraded', lbl: 'demo', ico: 'flask-conical' } : (map[bc.status] || map.disconnected); return (
{open && (
{bc.mode === 'live' ? 'Conectado (live)' : 'Modo demo (mocks)'}
{bc.baseUrl || 'datos de ejemplo · sin backend'}
{bc.error &&
{bc.error}
}
{bc.mode === 'live' ? : }
)}
); } const popItem = { background: 'none', border: 'none', width: '100%', textAlign: 'left' }; Object.assign(window, { ConnectGate, ConnectionChip });