285 lines
18 KiB
HTML
Executable File
285 lines
18 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">
|
||
<title>WEVADS - 📰 Native Ads — WEVADS Arsenal</title>
|
||
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||
<style>
|
||
:root{--bg:#0a0e1a;--c:#111827;--b:#1f2937;--t:#e2e8f0;--ac:#f97316;--ac2:#f9731640;--m:'DM Sans',sans-serif}
|
||
*{margin:0;padding:0;box-sizing:border-box}body{font-family:var(--m);background:#060a14;color:var(--t);min-height:100vh}
|
||
.top{background:linear-gradient(135deg,var(--ac2),rgba(15,23,42,.9));border-bottom:1px solid var(--ac);padding:16px 24px;display:flex;align-items:center;gap:12px}
|
||
.top h1{font-size:20px;font-weight:700}.top .badge{padding:3px 10px;border-radius:8px;font-size:11px;font-weight:600;background:var(--ac2);color:var(--ac)}
|
||
.top .back{color:var(--ac);text-decoration:none;font-size:12px;padding:6px 12px;border:1px solid var(--ac);border-radius:8px;margin-left:auto}
|
||
.top .back:hover{background:var(--ac2)}
|
||
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;padding:16px 24px}
|
||
.st{background:var(--c);border:1px solid var(--b);border-radius:12px;padding:14px 16px}
|
||
.st .n{font-size:24px;font-weight:700;color:var(--ac)}.st .l{font-size:11px;color:#64748b;margin-top:2px}
|
||
.st .d{font-size:10px;margin-top:4px}.st .d.up{color:#22c55e}.st .d.down{color:#ef4444}
|
||
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(400px,1fr));gap:16px;padding:0 24px 24px}
|
||
.card{background:var(--c);border:1px solid var(--b);border-radius:12px;overflow:hidden}
|
||
.card-h{padding:12px 16px;border-bottom:1px solid var(--b);display:flex;align-items:center;gap:8px;font-weight:600;font-size:14px}
|
||
.card-b{padding:16px}
|
||
table{width:100%;border-collapse:collapse;font-size:12px}
|
||
th{text-align:left;padding:8px;color:#64748b;font-size:10px;font-weight:600;background:var(--bg)}
|
||
td{padding:8px;border-top:1px solid #1f293750}
|
||
tr:hover{background:#0c122006}
|
||
.tag{display:inline-block;padding:2px 6px;border-radius:4px;font-size:10px;font-weight:600}
|
||
.tag.ok{background:#16a34a20;color:#22c55e}.tag.warn{background:#ca8a0420;color:#eab308}.tag.err{background:#dc262620;color:#ef4444}.tag.info{background:#3b82f620;color:#3b82f6}
|
||
.btn{padding:8px 16px;border:none;border-radius:8px;font-size:12px;font-weight:600;cursor:pointer;font-family:var(--m)}
|
||
.btn-p{background:var(--ac);color:#fff}.btn-p:hover{opacity:.85}
|
||
.btn-s{background:var(--b);color:var(--t)}.btn-s:hover{background:#374151}
|
||
.form-row{display:flex;gap:8px;margin:8px 0;align-items:center}
|
||
.form-row label{font-size:12px;color:#64748b;min-width:100px}
|
||
.form-row input,.form-row select{flex:1;background:var(--bg);border:1px solid var(--b);border-radius:8px;padding:8px 12px;color:var(--t);font-size:12px;font-family:var(--m)}
|
||
.form-row input:focus,.form-row select:focus{outline:none;border-color:var(--ac)}
|
||
textarea{width:100%;background:var(--bg);border:1px solid var(--b);border-radius:8px;padding:10px;color:var(--t);font-size:12px;font-family:var(--m);resize:vertical;min-height:80px}
|
||
textarea:focus{outline:none;border-color:var(--ac)}
|
||
.tabs{display:flex;gap:4px;padding:16px 24px 8px}
|
||
.tab{padding:8px 16px;border-radius:8px 8px 0 0;font-size:12px;font-weight:600;cursor:pointer;background:var(--b);color:#64748b;border:1px solid var(--b);border-bottom:none}
|
||
.tab.active{background:var(--c);color:var(--ac);border-color:var(--ac)}
|
||
.tab-content{display:none}.tab-content.active{display:block}
|
||
.persona-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:8px;margin-top:10px}
|
||
.persona{background:var(--bg);border:1px solid var(--b);border-radius:8px;padding:10px;font-size:11px}
|
||
.persona .name{font-weight:600;color:var(--ac)}.persona .email{color:#64748b;font-size:10px}
|
||
.persona .status{margin-top:4px}
|
||
.chart-{height:200px;background:var(--bg);border-radius:8px;display:flex;align-items:center;justify-content:center;color:#64748b;font-size:12px;border:1px dashed var(--b)}
|
||
.actions{display:flex;gap:8px;padding:16px 24px;flex-wrap:wrap}
|
||
.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="top">
|
||
<h1>📰 Native Ads</h1>
|
||
<p style="font-size:12px;color:#64748b;margin:6px 0 16px;max-width:600px;line-height:1.6">Native Ads — Taboola/Outbrain, articles sponsorisés, optimisation CTR.</p>
|
||
<span class="badge">Taboola/Outbrain</span>
|
||
<span class="badge" style="background:#22c55e20;color:#22c55e">Multi-Account</span>
|
||
<a href="menu.html" class="back">← Menu</a>
|
||
</div>
|
||
|
||
<div class="stats">
|
||
<div class="st"><div class="n" id="s-accounts">0</div><div class="l">Comptes Actifs</div><div class="d up">+3 cette semaine</div></div>
|
||
<div class="st"><div class="n" id="s-campaigns">0</div><div class="l">Campagnes</div><div class="d up">12 actives</div></div>
|
||
<div class="st"><div class="n" id="s-spend">€0</div><div class="l">Budget Dépensé</div><div class="d">Ce mois</div></div>
|
||
<div class="st"><div class="n" id="s-revenue">€0</div><div class="l">Revenue Généré</div><div class="d up">ROI: --</div></div>
|
||
<div class="st"><div class="n" id="s-clicks">0</div><div class="l">Clicks</div><div class="d">Aujourd'hui</div></div>
|
||
<div class="st"><div class="n" id="s-conv">0</div><div class="l">Conversions</div><div class="d">CTR: --</div></div>
|
||
</div>
|
||
|
||
<div class="tabs">
|
||
<div class="tab active" onclick="showTab('accounts',this)">👤 Comptes</div>
|
||
<div class="tab" onclick="showTab('campaigns',this)">📊 Campagnes</div>
|
||
<div class="tab" onclick="showTab('creatives',this)">🎨 Créatifs</div>
|
||
<div class="tab" onclick="showTab('personas',this)">🎭 Personas</div>
|
||
<div class="tab" onclick="showTab('analytics',this)">📈 Analytics</div>
|
||
</div>
|
||
|
||
<div class="tab-content active" id="tab-accounts">
|
||
<div class="actions">
|
||
<button class="btn btn-p" onclick="createAccount()">➕ Nouveau Compte</button>
|
||
<button class="btn btn-s" onclick="importAccounts()">📥 Importer</button>
|
||
<button class="btn btn-s" onclick="testAllAccounts()">🧪 Tester Tout</button>
|
||
<button class="btn btn-s" onclick="syncAccounts()">🔄 Sync</button>
|
||
</div>
|
||
<div class="grid">
|
||
<div class="card" style="grid-column:span 2">
|
||
<div class="card-h">📰 Comptes Taboola/Outbrain</div>
|
||
<div class="card-b">
|
||
<table>
|
||
<thead><tr><th>ID</th><th>Nom</th><th>Email</th><th>Persona</th><th>Status</th><th>Budget/J</th><th>Dépensé</th><th>Actions</th></tr></thead>
|
||
<tbody id="accounts-table">
|
||
<tr><td colspan="8" style="text-align:center;color:#64748b;padding:40px">
|
||
Aucun compte configuré. <button class="btn btn-p" onclick="createAccount()" style="margin-left:8px">➕ Créer le premier compte</button>
|
||
</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tab-content" id="tab-campaigns">
|
||
<div class="actions">
|
||
<button class="btn btn-p" onclick="createCampaign()">➕ Nouvelle Campagne</button>
|
||
<button class="btn btn-s">📋 Templates</button>
|
||
<button class="btn btn-s">🤖 AI Optimize</button>
|
||
</div>
|
||
<div class="grid">
|
||
<div class="card" style="grid-column:span 2">
|
||
<div class="card-h">📊 Campagnes Actives</div>
|
||
<div class="card-b">
|
||
<table>
|
||
<thead><tr><th>Campagne</th><th>Compte</th><th>Audience</th><th>Budget</th><th>Impressions</th><th>Clicks</th><th>Conv</th><th>CPA</th><th>Status</th></tr></thead>
|
||
<tbody id="campaigns-table">
|
||
<tr><td colspan="9" style="text-align:center;color:#64748b;padding:40px">Aucune campagne. Configure d'abord un compte Taboola/Outbrain.</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tab-content" id="tab-creatives">
|
||
<div class="actions">
|
||
<button class="btn btn-p">🎨 Nouveau Créatif</button>
|
||
<button class="btn btn-s">🤖 AI Generate</button>
|
||
<button class="btn btn-s">📥 Importer</button>
|
||
</div>
|
||
<div class="grid">
|
||
<div class="card">
|
||
<div class="card-h">🎨 Créer un Créatif</div>
|
||
<div class="card-b">
|
||
<div class="form-row"><label>Type:</label><select id="cr-type"><option>Article Sponsorisé</option><option>Video Native</option><option>Widget Recommandation</option><option>In-Feed Native</option></select></div>
|
||
<div class="form-row"><label>Titre:</label><input ="Headline accrocheur..."></div>
|
||
<div class="form-row"><label>Description:</label><textarea ="Description de l'annonce..."></textarea></div>
|
||
<div class="form-row"><label>CTA:</label><select><option>En savoir plus</option><option>Acheter</option><option>S'inscrire</option><option>Télécharger</option><option>Contacter</option></select></div>
|
||
<div class="form-row"><label>URL:</label><input ="https://..."></div>
|
||
<div class="form-row"><label>Offre:</label><select id="cr-offer"><option value="">-- Sélectionner offre --</option></select></div>
|
||
<button class="btn btn-p" style="margin-top:12px">💾 Sauvegarder</button>
|
||
</div>
|
||
</div>
|
||
<div class="card">
|
||
<div class="card-h">📊 Performance Créatifs</div>
|
||
<div class="card-b">
|
||
<div class="chart-">📊 Graphique performance créatifs — Configure des campagnes</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tab-content" id="tab-personas">
|
||
<div class="actions">
|
||
<button class="btn btn-p" onclick="assignPersonas()">🎭 Assigner Personas</button>
|
||
<button class="btn btn-s" onclick="loadPersonas()">🔄 Refresh</button>
|
||
</div>
|
||
<div class="grid">
|
||
<div class="card" style="grid-column:span 2">
|
||
<div class="card-h">🎭 Personas Disponibles (178) — Chaque persona = 1 compte Taboola/Outbrain = budget séparé</div>
|
||
<div class="card-b">
|
||
<p style="font-size:12px;color:#64748b;margin-bottom:12px">Assigne des personas pour multiplier tes comptes. Chaque persona utilise un email/identité différente → budget quotidien × nombre de comptes.</p>
|
||
<div class="persona-list" id="persona-list">Chargement...</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tab-content" id="tab-analytics">
|
||
<div class="grid">
|
||
<div class="card">
|
||
<div class="card-h">📈 Performance Globale</div>
|
||
<div class="card-b"><div class="chart-">📊 Graphique ROI / Spend — Démarre des campagnes</div></div>
|
||
</div>
|
||
<div class="card">
|
||
<div class="card-h">🎯 Top Audiences</div>
|
||
<div class="card-b"><div class="chart-">🎯 Heatmap audiences — Besoin de données</div></div>
|
||
</div>
|
||
<div class="card">
|
||
<div class="card-h">💰 ROI par Offre</div>
|
||
<div class="card-b"><div class="chart-">💰 Revenue vs Spend par offre</div></div>
|
||
</div>
|
||
<div class="card">
|
||
<div class="card-h">⏱️ Performance Horaire</div>
|
||
<div class="card-b"><div class="chart-">⏱️ Meilleurs créneaux envoi</div></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
const PLATFORM="native";
|
||
const API="/api/ads-platform.php";
|
||
|
||
function showTab(id,el){
|
||
document.querySelectorAll('.tab-content').forEach(t=>t.classList.remove('active'));
|
||
document.querySelectorAll('.tab').forEach(t=>t.classList.remove('active'));
|
||
document.getElementById('tab-'+id).classList.add('active');
|
||
el.classList.add('active');
|
||
}
|
||
|
||
async function loadDashboard(){
|
||
try{
|
||
const r=await fetch(API+'?action=platform&platform='+PLATFORM);
|
||
const d=await r.json();
|
||
if(d.status!=='success')return;
|
||
const s=d.stats||{};
|
||
document.getElementById('s-accounts').textContent=s.accounts||0;
|
||
document.getElementById('s-campaigns').textContent=s.campaigns||0;
|
||
document.getElementById('s-spend').textContent='\u20ac'+((s.spend||0).toLocaleString());
|
||
document.getElementById('s-revenue').textContent='\u20ac'+((s.revenue||0).toLocaleString());
|
||
document.getElementById('s-clicks').textContent=(s.clicks||0).toLocaleString();
|
||
document.getElementById('s-conv').textContent=s.conversions||0;
|
||
var sts=document.querySelectorAll('.st');
|
||
if(sts[1])sts[1].querySelector('.d').textContent=(s.active_campaigns||0)+' actives';
|
||
if(sts[3])sts[3].querySelector('.d').innerHTML='ROI: <b style="color:#22c55e">'+(s.roi||0)+'%</b>';
|
||
if(sts[5])sts[5].querySelector('.d').textContent='CPA: \u20ac'+(s.cpa||0);
|
||
|
||
var at=document.getElementById('accounts-table');
|
||
if(at&&d.accounts&&d.accounts.length>0){
|
||
at.innerHTML=d.accounts.map(a=>'<tr><td>'+a.id+'</td><td>'+a.account_name+'</td><td>'+a.account_id+'</td><td>-</td><td><span class="tag '+(a.is_active==='t'?'ok':'warn')+'">'+(a.is_active==='t'?'Active':'Pause')+'</span></td><td>\u20ac'+a.daily_spend_cap+'</td><td>\u20ac'+a.total_spent+'</td><td><button class="btn btn-s" style="padding:4px 8px;font-size:10px">Test</button></td></tr>').join('');
|
||
}
|
||
|
||
var ct=document.getElementById('campaigns-table');
|
||
if(ct&&d.campaigns&&d.campaigns.length>0){
|
||
ct.innerHTML=d.campaigns.map(c=>{var st=c.status==='active'?'ok':c.status==='paused'?'warn':'info';return '<tr><td><b>'+c.name+'</b></td><td>-</td><td>-</td><td>\u20ac'+(c.budget_daily||0)+'/j</td><td>'+(parseInt(c.impressions)||0).toLocaleString()+'</td><td>'+(parseInt(c.total_clicks)||0).toLocaleString()+'</td><td>'+(c.conversions||0)+'</td><td>\u20ac'+(c.cpa||0)+'</td><td><span class="tag '+st+'">'+c.status+'</span></td></tr>'}).join('');
|
||
}
|
||
|
||
if(d.personas&&d.personas.length>0){
|
||
var pl=document.getElementById('persona-list');
|
||
if(pl)pl.innerHTML=d.personas.map(p=>'<div class="persona"><div class="name">'+p.first_name+' '+p.last_name+'</div><div class="email">'+p.email+'</div><div class="status"><span class="tag info">Dispo</span></div></div>').join('')+'<div class="persona" style="text-align:center;border-color:var(--ac);cursor:pointer" onclick="location.href=\'key-manager.html\'"><b>Voir 178 personas...</b></div>';
|
||
}
|
||
|
||
var bars=document.querySelectorAll('.chart-');
|
||
if(bars[0]&&d.flux){
|
||
var html='<div style="padding:16px"><div style="display:flex;gap:16px;flex-wrap:wrap">';
|
||
[['impressions_h','Impr/h','var(--ac)'],['clicks_h','Clicks/h','#22c55e'],['spend_h','Spend/h','#eab308'],['conversions_h','Conv/h','#a78bfa']].forEach(m=>{
|
||
html+='<div style="flex:1;min-width:80px;text-align:center"><div style="font-size:20px;font-weight:700;color:'+m[2]+'">'+(d.flux[m[0]]||0).toLocaleString()+'</div><div style="font-size:10px;color:#64748b">'+m[1]+'</div></div>';
|
||
});
|
||
html+='</div></div>';bars[0].outerHTML=html;
|
||
}
|
||
}catch(e){console.error(e)}
|
||
}
|
||
|
||
function createAccount(){
|
||
var n=prompt('Nom du compte:');if(!n)return;
|
||
fetch(API+'?action=create_account',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({platform:PLATFORM,account_name:n,account_id:PLATFORM+'_'+Date.now()})}).then(r=>r.json()).then(d=>{if(d.status==='success'){alert('OK! ID:'+d.id);loadDashboard()}}).catch(e=>alert(e));
|
||
}
|
||
function createCampaign(){
|
||
var n=prompt('Nom campagne:');if(!n)return;var b=prompt('Budget/jour EUR:','50');
|
||
fetch(API+'?action=create_campaign',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({platform:PLATFORM,name:n,budget_daily:parseFloat(b)||50,status:'draft'})}).then(r=>r.json()).then(d=>{if(d.status==='success'){alert('OK! ID:'+d.campaign_id);loadDashboard()}}).catch(e=>alert(e));
|
||
}
|
||
function importAccounts(){alert('Import CSV - Actif')}
|
||
function testAllAccounts(){alert('Test API tous les comptes')}
|
||
function syncAccounts(){loadDashboard();alert('Sync OK')}
|
||
function assignPersonas(){location.href='key-manager.html'}
|
||
|
||
loadDashboard();
|
||
setInterval(loadDashboard,30000);
|
||
fetch('/api/hamid-chef.php?action=status').then(r=>r.json()).then(d=>{
|
||
var n=d.intelligence&&d.intelligence.affiliate?d.intelligence.affiliate.active_offers:0;
|
||
var s=document.getElementById('cr-offer');
|
||
if(s)for(var i=1;i<=Math.min(n,20);i++)s.innerHTML+='<option>Offre #'+i+'</option>';
|
||
}).catch(()=>{});
|
||
function loadPersonas(){loadDashboard()}
|
||
</script>
|
||
<script src="arsenal-common.js?v1770778169">
|
||
<?php include("/opt/wevads-arsenal/public/universal-drill.html"); ?>
|
||
</body>
|
||
</html>
|
||
</script>
|