/* global React */
// =======================================================================
// BlazeConnector Admin v3 — Integraciones pages
// ISP Providers · Pagos
// =======================================================================
const { useState: _is } = React;
function ProviderCard({ p, kind }) {
const tone = p.status === 'healthy' ? 'success' : p.status === 'degraded' ? 'warn' : 'danger';
return (
Latencia
500 ? 'var(--st-warn-fg)' : 'var(--app-fg1)', fontFamily: 'var(--font-display)', fontVariantNumeric: 'tabular-nums' }}>{p.latency != null ? p.latency + 'ms' : '—'}
{kind === 'pagos' ? 'Moneda' : 'Vendor'}
{kind === 'pagos' ? p.currency : p.vendor}
{p.apiBase &&
{p.apiBase}
}
{p.authMode &&
Auth: {p.authMode}
}
);
}
function PageIsps() {
return (
ISP Providers
{window.PROVIDERS_ISP.length} integraciones billing/OSS · {window.PROVIDERS_ISP.filter(p => p.status === 'healthy').length} sanos · {window.PROVIDERS_ISP.filter(p => p.status === 'degraded').length} degradados
Health overview · últimas 4h
{window.PROVIDERS_ISP.map(p => (
{p.name}
p.latency + Math.sin(i * 0.5) * 40 + (Math.random() - 0.5) * 30)} color={p.status === 'healthy' ? 'green' : p.status === 'degraded' ? 'warn' : 'danger'} />
{p.latency}ms avg
{p.tenants} tenants
))}
{window.PROVIDERS_ISP.map(p =>
)}
{t.name} },
{ label: 'ID', width: 100, render: (t) => {t.id} },
{ label: 'Billing provider', width: 160, render: (t) => {t.billing[0].toUpperCase()}{(window.PROVIDERS_ISP.find(p => p.id === t.billing) || {}).name} },
{ label: 'Estado provider', width: 140, render: (t) => { const p = window.PROVIDERS_ISP.find(x => x.id === t.billing); return ; } },
{ label: 'Última sync', width: 130, render: () => hace {Math.floor(Math.random() * 15) + 1}m },
{ label: 'Diffs pendientes', width: 140, numeric: true, render: () => {Math.floor(Math.random() * 12)} }
]} rows={window.TENANTS.slice(0, 8)} />
);
}
function PagePagos() {
return (
Pagos · Gateways
{window.PROVIDERS_PAY.length} gateways · {window.PROVIDERS_PAY.filter(p => p.status === 'healthy').length} OK · {window.PROVIDERS_PAY.filter(p => p.status === 'down').length} caídos
v / 3)} color="blue" />
{window.PROVIDERS_PAY.map(p =>
)}
{window.fmtTime(r.ts)} },
{ label: 'Tenant', width: 160, render: (r) => {r.tenantName} },
{ label: 'Gateway', width: 100, render: (r) => {r.gateway[0]}{r.gateway} },
{ label: 'Método', width: 90, render: (r) => {r.method} },
{ label: 'Cliente', width: 200, render: (r) => {r.last4} {r.contact} },
{ label: 'Monto', width: 130, numeric: true, render: (r) => {r.currency}$ {r.amount.toLocaleString()} },
{ label: 'Estado', width: 100, render: (r) => },
{ label: 'txn_id', width: 140, render: (r) => {r.txnId} }
]} rows={genTransactions()} />
);
}
function genTransactions() {
const now = Date.now();
const out = [];
const gateways = ['CardNET', 'Azul', 'PayPal'];
const methods = ['VISA', 'Mastercard', 'Amex', 'OXXO', 'PayPal'];
const statuses = [{ v: 'captured', wt: 7 }, { v: 'pending', wt: 2 }, { v: 'failed', wt: 1 }];
for (let i = 0; i < 12; i++) {
const tnt = window.randomFrom(window.TENANTS.filter(t => t.status === 'active' && t.pagos.length > 0));
const w = statuses.reduce((a, s) => a + s.wt, 0);
let r = Math.random() * w; let st = 'captured';
for (const s of statuses) { r -= s.wt; if (r <= 0) { st = s.v; break; } }
out.push({
id: 'tx_' + window.randHex(10),
ts: new Date(now - i * (Math.random() * 200000 + 30000)).toISOString(),
tenant: tnt.id, tenantName: tnt.name,
gateway: window.randomFrom(gateways),
method: window.randomFrom(methods),
last4: '•••• ' + (Math.floor(Math.random() * 9000) + 1000),
contact: window.randomFrom(window.DR_NAMES),
currency: 'RD',
amount: Math.floor(Math.random() * 4000) + 350,
status: st,
txnId: 'CN' + window.randHex(10).toUpperCase()
});
}
return out;
}
Object.assign(window, { PageIsps, PagePagos });