Files
wevads-platform/public/native-ads.html
2026-02-26 04:53:11 +01:00

283 lines
17 KiB
HTML
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.
<!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">
</body>
</html>
</script>