Files
wevia-brain/s89-arsenal-screens/ads-commander.html
2026-04-12 23:01:36 +02:00

137 lines
13 KiB
HTML
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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 - Ads Commander — WEVADS</title>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@300;400;500;600;700;800&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);--border-h:rgba(255,255,255,.12);--text:#c8d0e0;--text-dim:#6b7a94;--text-bright:#edf0f7;--red:#ff4d6a;--green:#00e68a;--blue:#3d8bfd;--amber:#ffb547;--purple:#a78bfa;--cyan:#22d3ee;--accent:#3d8bfd;--accent-dark:#0a1a3a}
*{margin:0;padding:0;box-sizing:border-box}body{font-family:'DM Sans',sans-serif;background:#060a14;color:var(--text);min-height:100vh}
.header{background:linear-gradient(135deg,var(--accent-dark),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(--accent)}
.header .badge{background:rgba(61,139,253,.15);color:var(--accent);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(--accent)}
.tabs{display:flex;gap:2px;padding:0 28px;background:var(--surface);border-bottom:1px solid var(--border)}
.tab{padding:12px 22px;font-size:13px;font-weight:500;color:var(--text-dim);cursor:pointer;border-bottom:2px solid transparent;transition:all .2s;user-select:none}
.tab:hover{color:var(--text)}.tab.active{color:var(--accent);border-bottom-color:var(--accent);font-weight:600}
.panel{display:none;padding:24px 28px}.panel.active{display:block}
.kpi-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,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:var(--border-h);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}
.kpi.green .value{color:var(--green)}.kpi.red .value{color:var(--red)}.kpi.blue .value{color:var(--accent)}.kpi.amber .value{color:var(--amber)}
.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}.dh .ct{font-size:12px;color:var(--text-dim);font-family:'JetBrains Mono',monospace}
table{width:100%;border-collapse:collapse;font-size:13px}th{text-align:left;padding:10px 16px;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.6px;color:var(--text-dim);background:rgba(0,0,0,.2);border-bottom:1px solid var(--border)}
td{padding:10px 16px;border-bottom:1px solid var(--border);color:var(--text)}tr:hover td{background:rgba(255,255,255,.02)}tr:last-child td{border-bottom:none}
.bs{display:inline-block;padding:3px 10px;border-radius:20px;font-size:11px;font-weight:600}
.bs.active,.bs.active_boosted{background:rgba(0,230,138,.12);color:var(--green)}.bs.paused{background:rgba(255,181,71,.12);color:var(--amber)}.bs.draft{background:rgba(107,122,148,.2);color:var(--text-dim)}.bs.killed{background:rgba(255,77,106,.12);color:var(--red)}.bs.boost{background:rgba(0,230,138,.12);color:var(--green)}.bs.kill{background:rgba(255,77,106,.12);color:var(--red)}.bs.pause{background:rgba(255,181,71,.12);color:var(--amber)}
.controls{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:18px;align-items:center}
.btn{padding:8px 18px;border-radius:8px;font-size:13px;font-weight:600;border:none;cursor:pointer;font-family:inherit;transition:all .15s;display:inline-flex;align-items:center;gap:6px}
.btn-primary{background:var(--accent);color:#fff}.btn-primary:hover{filter:brightness(1.15)}
.btn-secondary{background:var(--surface2);color:var(--text);border:1px solid var(--border)}.btn-secondary:hover{border-color:var(--border-h)}
select.ctrl,input.ctrl{padding:8px 14px;border-radius:8px;font-size:13px;font-family:inherit;background:var(--surface2);color:var(--text);border:1px solid var(--border);outline:none}
.toast{position:fixed;top:20px;right:20px;padding:12px 20px;border-radius:10px;font-size:13px;font-weight:500;z-index:999;animation:si .3s;max-width:400px}
.toast.info{background:rgba(61,139,253,.9);color:#fff}.toast.success{background:rgba(0,230,138,.9);color:#e2e8f0}.toast.error{background:rgba(255,77,106,.9);color:#fff}
@keyframes si{from{transform:translateX(100px);opacity:0}to{transform:translateX(0);opacity:1}}
.empty{text-align:center;padding:60px 20px;color:var(--text-dim)}.empty .icon{font-size:48px;margin-bottom:12px;opacity:.5}
.fg{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:20px}.fi{display:flex;flex-direction:column;gap:6px}.fi label{font-size:12px;color:var(--text-dim);font-weight:500}
.wv-status{position:fixed;top:12px;right:140px;z-index:9998;background:rgba(52,211,153,.15);border:1px solid #34d399;border-radius:12px;padding:3px 10px;color:#34d399;font-size:10px;font-weight:700;font-family:'JetBrains Mono',monospace}
.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>Ads <span>Commander</span></h1>
<p style="font-size:12px;color:#64748b;margin:6px 0 16px;max-width:600px;line-height:1.6">Centre de commande publicitaire — pilotage multi-plateforme, budgets, enchères.</p>
<div class="badge">CROSS-CHANNEL ADS</div><a href="menu.html" class="back">← Menu</a></div>
<div class="tabs">
<div class="tab active" data-tab="dashboard">📊 Dashboard</div>
<div class="tab" data-tab="campaigns">🚀 Campaigns</div>
<div class="tab" data-tab="create"> Create</div>
<div class="tab" data-tab="arbitrage">⚡ Arbitrage</div>
<div class="tab" data-tab="accounts">🔑 Accounts</div>
</div>
<div class="panel active" id="panel-dashboard">
<div class="kpi-grid" id="dK"></div>
<div class="ds"><div class="dh"><h3>⚡ Recent Decisions</h3><span class="ct" id="dC"></span></div><div id="dD"></div></div>
<div class="ds"><div class="dh"><h3>🚀 Active Campaigns</h3></div><div id="dA"></div></div>
</div>
<div class="panel" id="panel-campaigns">
<div class="controls"><select class="ctrl" id="cF" onchange="lC()"><option value="">All</option><option value="active">Active</option><option value="paused">Paused</option><option value="draft">Draft</option></select><button class="btn btn-secondary" onclick="lC()">🔄</button></div>
<div class="ds"><div class="dh"><h3>📊 All Campaigns</h3><span class="ct" id="cC"></span></div><div id="cT"></div></div>
</div>
<div class="panel" id="panel-create">
<div class="ds" style="padding:24px">
<h3 style="color:var(--text-bright);margin-bottom:20px"> Create New Campaign</h3>
<div class="fg">
<div class="fi"><label>Campaign Name</label><input class="ctrl" id="fN" placeholder="DE Winter Sale"></div>
<div class="fi"><label>Platform</label><select class="ctrl" id="fP"><option value="meta">📘 Meta</option><option value="tiktok">🎵 TikTok</option><option value="linkedin">💼 LinkedIn</option><option value="all">🌐 All</option></select></div>
<div class="fi"><label>Objective</label><select class="ctrl" id="fO"><option value="conversions">🎯 Conversions</option><option value="traffic">🔗 Traffic</option><option value="leads">📋 Leads</option></select></div>
<div class="fi"><label>Offer Link</label><input class="ctrl" id="fL" placeholder="https://..."></div>
<div class="fi"><label>Daily Budget (€)</label><input class="ctrl" type="number" id="fB" value="50"></div>
<div class="fi"><label>ROAS Target</label><input class="ctrl" type="number" id="fR" value="2.0" step="0.1"></div>
</div>
<button class="btn btn-primary" onclick="cC2()">🚀 Launch Campaign</button>
</div>
</div>
<div class="panel" id="panel-arbitrage">
<div class="controls"><button class="btn btn-primary" onclick="rA()">⚡ Run Arbitrage Now</button><button class="btn btn-secondary" onclick="lD()">🔄</button></div>
<div class="kpi-grid" id="aK"></div>
<div class="ds"><div class="dh"><h3>📋 Arbitrage History</h3><span class="ct" id="aC"></span></div><div id="aT"></div></div>
</div>
<div class="panel" id="panel-accounts">
<div class="ds"><div class="dh"><h3>🔑 Ad Accounts</h3></div><div id="acT"></div></div>
</div>
<script>
async function loadCommander(){
try{
const r=await fetch('/api/ads-platform.php?action=dashboard');
const d=await r.json();
if(d.status!=='success')return;
var t=d.totals||{};
// Update any stat elements
var sts=document.querySelectorAll('.stat-value,.kpi-value,.st .n,[class*="stat"]');
// Build platform table if container exists
var container=document.querySelector('.platforms-table,table tbody,.card-body,#platforms');
if(!container) container=document.querySelector('.card:first-child .card-b,table:first-of-type tbody');
if(container){
var colors={youtube:'#ff0000',meta:'#1877f2',google:'#060a14',tiktok:'#ff0050',linkedin:'#0a66c2',twitter:'#1da1f2',snapchat:'#fffc00',pinterest:'#e60023',native:'#f97316'};
var icons={youtube:'\u{1f3ac}',meta:'\u{1f4d8}',google:'\u{1f50d}',tiktok:'\u{1f3b5}',linkedin:'\u{1f4bc}',twitter:'\u{1f426}',snapchat:'\u{1f47b}',pinterest:'\u{1f4cc}',native:'\u{1f4f0}'};
container.innerHTML='<div style="display:grid;gap:8px">'+(d.platforms||[]).map(p=>{
var roi=parseFloat(p.spend)>0?((parseFloat(p.revenue)-parseFloat(p.spend))/parseFloat(p.spend)*100).toFixed(0):0;
return '<div style="display:flex;align-items:center;gap:12px;padding:10px;background:rgba(15,23,42,.6);border-radius:8px;border-left:3px solid '+(colors[p.platform]||'#666')+'"><span style="font-size:20px">'+(icons[p.platform]||'\u{1f4ca}')+'</span><div style="flex:1"><b>'+p.platform.toUpperCase()+'</b><br><span style="font-size:11px;color:#64748b">'+p.active+' actives / '+p.total+' total</span></div><div style="text-align:right"><div style="color:#22c55e;font-weight:700">\u20ac'+parseFloat(p.revenue).toLocaleString()+'</div><div style="font-size:11px;color:#64748b">Spend: \u20ac'+parseFloat(p.spend).toLocaleString()+' | ROI: '+roi+'%</div></div></div>'
}).join('')+'<div style="padding:12px;text-align:center;background:rgba(139,92,246,.1);border-radius:8px;margin-top:8px"><b style="color:#a78bfa">TOTAL: \u20ac'+t.revenue.toLocaleString()+' revenue | \u20ac'+t.spend.toLocaleString()+' spend | ROI: '+t.roi+'%</b></div></div>';
}
}catch(e){console.error(e)}
}
loadCommander();
setInterval(loadCommander,30000);
function lC(){loadDashboard?loadDashboard():location.reload()}
function rA(){fetch('/api/ads-platform.php?action=arbitrage').then(r=>r.json()).then(d=>{alert('Arbitrage: '+(d.status||'done'))}).catch(()=>{})}
function lD(){location.reload()}
function cC2(){var n=prompt('Campaign name?');if(n)fetch('/api/ads-platform.php?action=create_campaign',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({name:n})}).then(r=>r.json()).then(d=>{alert('Created: '+(d.campaign_id||d.status));location.reload()}).catch(()=>alert('Queued'))}
</script>
<script src="arsenal-common.js?v1770778169">
<?php include("/opt/wevads-arsenal/public/universal-drill.html"); ?>
</body></html></script>