Files
wevia-brain/s89-arsenal-screens/adhérence-monitor.html
2026-04-12 23:01:36 +02:00

124 lines
9.6 KiB
HTML
Executable File

<?php include_once("/opt/wevads-arsenal/public/api/wevads-metrics.php"); ?>
<!DOCTYPE html><html lang="fr"><head>
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate"><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>WEVADS - Adhérence Monitor — WEVADS</title>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
<style>
:root{--bg:#080b12;--surface:#0f1420;--surface2:#161d2e;--border:rgba(255,255,255,.06);--text:#c8d0e0;--text-dim:#6b7a94;--text-bright:#edf0f7;--green:#00e68a;--red:#ff4d6a;--amber:#ffb547;--cyan:#22d3ee;--purple:#a78bfa}
*{margin:0;padding:0;box-sizing:border-box}body{font-family:'DM Sans',sans-serif;background:var(--bg);color:var(--text);min-height:100vh}
.header{background:linear-gradient(135deg,rgba(34,211,238,.05),var(--bg) 60%);border-bottom:1px solid var(--border);padding:14px 28px;display:flex;align-items:center;gap:18px;position:sticky;top:0;z-index:100;backdrop-filter:blur(20px)}
.header .logo{font-size:28px}.header h1{font-size:22px;font-weight:700;color:var(--text-bright)}.header h1 span{color:var(--cyan)}
.header .badge{background:rgba(34,211,238,.15);color:var(--cyan);padding:4px 12px;border-radius:20px;font-size:11px;font-weight:600}
.header .back{color:var(--text-dim);text-decoration:none;font-size:13px;margin-left:auto}.header .back:hover{color:var(--cyan)}
.header .live{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--green);font-family:'JetBrains Mono',monospace}
.header .live::before{content:'';width:7px;height:7px;background:var(--green);border-radius:50%;animation:p 2s infinite}
@keyframes p{0%,100%{opacity:1}50%{opacity:.3}}
.content{padding:24px 28px}
.kpi-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:14px;margin-bottom:24px}
.kpi{background:var(--surface);border:1px solid var(--border);border-radius:12px;padding:18px 20px;transition:all .2s}
.kpi:hover{border-color:rgba(255,255,255,.12);transform:translateY(-2px)}
.kpi .label{font-size:11px;font-weight:500;color:var(--text-dim);text-transform:uppercase;letter-spacing:.8px;margin-bottom:8px}
.kpi .value{font-size:28px;font-weight:700;font-family:'JetBrains Mono',monospace;color:var(--text-bright)}
.kpi .sub{font-size:11px;color:var(--text-dim);margin-top:4px}
.ds{background:var(--surface);border:1px solid var(--border);border-radius:12px;overflow:hidden;margin-bottom:20px}
.dh{padding:14px 20px;display:flex;align-items:center;gap:12px;border-bottom:1px solid var(--border);background:rgba(255,255,255,.01)}
.dh h3{font-size:14px;font-weight:600;color:var(--text-bright);flex:1}
.svc{display:flex;align-items:center;gap:14px;padding:14px 20px;border-bottom:1px solid var(--border);transition:background .15s}
.svc:last-child{border-bottom:none}.svc:hover{background:rgba(255,255,255,.02)}
.svc .dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}
.svc .dot.up{background:var(--green);box-shadow:0 0 8px rgba(0,230,138,.4)}
.svc .dot.down{background:var(--red);box-shadow:0 0 8px rgba(255,77,106,.4)}
.svc .dot.checking{background:var(--amber);animation:p 1s infinite}
.svc .name{flex:1;font-weight:500;font-size:14px}
.svc .latency{font-family:'JetBrains Mono',monospace;font-size:12px;color:var(--text-dim);min-width:60px;text-align:right}
.svc .badge{padding:3px 10px;border-radius:20px;font-size:11px;font-weight:600}
.svc .badge.ok{background:rgba(0,230,138,.12);color:var(--green)}
.svc .badge.err{background:rgba(255,77,106,.12);color:var(--red)}
.svc .badge.warn{background:rgba(255,181,71,.12);color:var(--amber)}
.btn{padding:8px 18px;border-radius:8px;font-size:13px;font-weight:600;border:none;cursor:pointer;font-family:inherit;background:rgba(34,211,238,.15);color:var(--cyan);transition:all .15s}
.btn:hover{background:rgba(34,211,238,.25)}
.sync-bar{display:grid;grid-template-columns:repeat(2,1fr);gap:14px;margin-bottom:24px}
.sync-card{background:var(--surface);border:1px solid var(--border);border-radius:12px;padding:16px 20px}
.sync-card h4{font-size:12px;color:var(--text-dim);margin-bottom:10px;text-transform:uppercase;letter-spacing:.5px}
.sync-item{display:flex;justify-content:space-between;align-items:center;padding:6px 0;font-size:13px}
.sync-item .v{font-family:'JetBrains Mono',monospace;font-size:12px}
.sync-item .match{color:var(--green)}.sync-item .mismatch{color:var(--red)}
.sc,.card,[class*="stat-card"]{transition:all .25s ease;position:relative;overflow:hidden}
.sc:hover,.card:hover,[class*="stat-card"]:hover{transform:translateY(-2px);box-shadow:0 8px 24px rgba(0,0,0,.25)}
.sc::after,.card::after{content:'';position:absolute;bottom:0;left:0;right:0;height:2px;background:var(--cy,#22d3ee);opacity:0;transition:opacity .25s}
.sc:hover::after,.card:hover::after{opacity:.7}
.btn,.button,[class*="btn-"]{transition:all .2s ease}
.btn:hover,.button:hover{transform:translateY(-1px)}
@keyframes fadeIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
.sc,.card{animation:fadeIn .4s ease both}
.sc:nth-child(2),.card:nth-child(2){animation-delay:.05s}
.sc:nth-child(3),.card:nth-child(3){animation-delay:.1s}
.sc:nth-child(4),.card:nth-child(4){animation-delay:.15s}
.sc:nth-child(5),.card:nth-child(5){animation-delay:.2s}
.sc:nth-child(6),.card:nth-child(6){animation-delay:.25s}
</style><link rel="stylesheet" href="wevads-global.css?v1770777318">
</head><body>
<div class="header">
<div class="logo">🔄</div><h1>Adhérence <span>Monitor</span></h1>
<p style="font-size:12px;color:#64748b;margin:6px 0 16px;max-width:600px;line-height:1.6">Suivi de l'adhérence des campagnes — conformité, déviation vs plan, alertes.</p>
<div class="badge">ADX ↔ ARSENAL SYNC</div>
</div>
<div class="content">
<div class="kpi-grid">
<div class="kpi" id="kUp"><div class="label">Services Up</div><div class="value"></div></div>
<div class="kpi" id="kDown"><div class="label">Services Down</div><div class="value"></div></div>
<div class="kpi" id="kSync"><div class="label">Files Synced</div><div class="value"></div></div>
<div class="kpi" id="kLat"><div class="label">Avg Latency</div><div class="value"></div></div>
</div>
<div class="sync-bar">
<div class="sync-card"><h4>🖥️ ADX (Port 5821)</h4><div id="adxSync"></div></div>
<div class="sync-card"><h4>🛡️ Arsenal (Port 5890)</h4><div id="arsSync"></div></div>
</div>
<div class="ds"><div class="dh"><h3>🔌 Service Health</h3><button class="btn" onclick="checkAll()">🔍 Check Now</button></div><div id="services"></div></div>
</div>
<script>
const checks=[
{name:'PostgreSQL',url:'/api/health-check.php?action=basic',icon:'🐘'},
{name:'Apache / ADX 5821',url:'/api/health-check.php?action=basic',icon:'🌐'},
{name:'Brain Engine',url:'/api/brain-combo.php?action=stats',icon:'🧠'},
{name:'Offer Engine',url:'/api/offer-engine.php?action=stats',icon:'💰'},
{name:'HAMID IA',url:'/api/hamid-api.php?action=status',icon:'🤖'},
{name:'Warmup Engine',url:'/api/warmup.php?action=status',icon:'🔥'},
{name:'PowerMTA',url:'/api/mta.php?action=stats',icon:'📮'},
{name:'Tracking (OVH)',url:'/api/tracking-status.php?action=check',icon:'📡'},
{name:'Vault Guard',url:'/api/vault-guard.php?action=status',icon:'🔒'},
{name:'N8N Workflows',url:'/api/n8n.php?action=status',icon:'⚙️'}
];
function uc(){document.getElementById('clock').textContent='LIVE '+new Date().toLocaleTimeString('fr-FR')}setInterval(uc,1000);uc();
async function checkAll(){
const el=document.getElementById('services');el.innerHTML='';
let up=0,down=0,totalMs=0;
for(const svc of checks){
const row=document.createElement('div');row.className='svc';
row.innerHTML=`<div class="dot checking"></div><div class="name">${svc.icon} ${svc.name}</div><div class="latency">...</div><div class="badge warn">Checking</div>`;
el.appendChild(row);
const t0=performance.now();
try{
const r=await fetch(svc.url,{signal:AbortSignal.timeout(5000)});
const ms=Math.round(performance.now()-t0);totalMs+=ms;
if(r.ok){up++;row.innerHTML=`<div class="dot up"></div><div class="name">${svc.icon} ${svc.name}</div><div class="latency">${ms}ms</div><div class="badge ok">Operational</div>`}
else{down++;row.innerHTML=`<div class="dot down"></div><div class="name">${svc.icon} ${svc.name}</div><div class="latency">HTTP ${r.status}</div><div class="badge err">Error</div>`}
}catch(e){down++;row.innerHTML=`<div class="dot down"></div><div class="name">${svc.icon} ${svc.name}</div><div class="latency">Timeout</div><div class="badge err">Down</div>`}
}
document.querySelector('#kUp .value').textContent=up;document.querySelector('#kUp .value').style.color=up>0?'var(--green)':'var(--red)';
document.querySelector('#kDown .value').textContent=down;document.querySelector('#kDown .value').style.color=down>0?'var(--red)':'var(--green)';
document.querySelector('#kLat .value').textContent=Math.round(totalMs/checks.length)+'ms';
document.querySelector('#kSync .value').textContent=up+'/'+checks.length;
const syncItems=[{n:'menu.html',p:'/menu.html'},{n:'youtube-factory.html',p:'/youtube-factory.html'},{n:'ads-commander.html',p:'/ads-commander.html'},{n:'offer-engine.html',p:'/offer-engine.html'},{n:'brain-report.html',p:'/brain-report.html'}];
['adxSync','arsSync'].forEach(id=>{
document.getElementById(id).innerHTML=syncItems.map(s=>`<div class="sync-item"><span>${s.n}</span><span class="v match">✅ Present</span></div>`).join('')});
}
checkAll();setInterval(checkAll,30000);
document.addEventListener("DOMContentLoaded",checkAll);
</script><script src="arsenal-common.js?v1770778169">
<?php include("/opt/wevads-arsenal/public/universal-drill.html"); ?>
</body></html></script>