/* 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 (
{p.name[0]}
{p.name}
{p.version}
Latencia
500 ? 'var(--st-warn-fg)' : 'var(--app-fg1)', fontFamily: 'var(--font-display)', fontVariantNumeric: 'tabular-nums' }}>{p.latency != null ? p.latency + 'ms' : '—'}
Tenants
{p.tenants}
{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 });