/* 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
);
}
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 });