yazrkisvs3vvvsv33svrhetrjsvyvsvvyjsvsvs
tavsuysvssvvjvvyjyjkvsvqd
qfogsvvsvsegjdgdfgdskhgdksvqsvshdqsd
<?php
// analytics-public.php — Vista pública (cliente final): elige sus métricas GA4 y ve sus datos.
// Auth por token (sin login), estilo propuesta.php. La API (ga4-data.php) resuelve el cliente por token.
require_once __DIR__ . '/config.php';
require_once __DIR__ . '/db.php';

$token = preg_replace('/[^a-f0-9\-]/i', '', $_GET['token'] ?? '');
$client_name = '';
$valid = false;
if ($token !== '') {
    try {
        $st = $pdo->prepare('SELECT name FROM dm_clients WHERE ga4_public_token = ? LIMIT 1');
        $st->execute([$token]);
        $row = $st->fetch(PDO::FETCH_ASSOC);
        if ($row) { $valid = true; $client_name = $row['name']; }
    } catch (\Throwable $e) { $valid = false; }
}
?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="robots" content="noindex,nofollow">
<title>Tu Analytics — DIMARK</title>
<link href="https://fonts.googleapis.com/css2?family=Syne:wght@400;600;700&family=DM+Sans:wght@300;400;500&display=swap" rel="stylesheet">
<style>
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{--red:#E8272A;--org:#e8730c;--bg:#0f0f0f;--bg2:#181818;--bg3:#222;--br:rgba(255,255,255,.07);--br2:rgba(255,255,255,.13);--t:#f0f0f0;--m:rgba(240,240,240,.42);--g:#22c97a;--y:#f5c543;--teal:#22c9b8;--fh:'Syne',sans-serif;--fb:'DM Sans',sans-serif}
html,body{background:var(--bg);color:var(--t);font-family:var(--fb);font-size:14px;min-height:100vh}
header{background:var(--bg2);border-bottom:1px solid var(--br);padding:14px 24px;display:flex;align-items:center;gap:10px}
.lm{width:28px;height:28px;background:var(--org);border-radius:6px;display:flex;align-items:center;justify-content:center;font-family:var(--fh);font-weight:700;font-size:13px;color:#fff}
.ln{font-family:var(--fh);font-weight:700;font-size:14px}
.container{max-width:1100px;margin:0 auto;padding:28px 22px}
.hero h1{font-family:var(--fh);font-size:24px;font-weight:700;margin-bottom:6px}
.hero p{color:var(--m);font-size:13px;max-width:620px;margin-bottom:24px}
.card{background:var(--bg2);border:1px solid var(--br2);border-radius:12px;padding:16px;margin-bottom:18px}
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px}
.kpi{background:var(--bg3);border:1px solid var(--br);border-radius:8px;padding:12px 14px}
.kpi .l{font-size:11px;color:var(--m);margin-bottom:4px}
.kpi .v{font-size:20px;font-weight:700}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:16px}
@media(max-width:760px){.grid2{grid-template-columns:1fr}}
.catbox{max-height:300px;overflow:auto;font-size:12px}
label.row{display:flex;align-items:center;gap:7px;padding:3px 0;cursor:pointer}
select,button{font-family:var(--fb)}
select{background:var(--bg3);border:1px solid var(--br2);border-radius:7px;padding:7px 10px;font-size:12px;color:var(--t)}
.btn{padding:9px 18px;border-radius:8px;font-size:13px;font-weight:600;background:var(--org);border:none;color:#fff;cursor:pointer}
.muted{font-size:11px;color:var(--m)}
table{width:100%;border-collapse:collapse;font-size:12px}
th{text-align:left;color:var(--m);border-bottom:1px solid var(--br2);padding:8px 10px}
td{padding:8px 10px;border-bottom:1px solid var(--br);color:var(--t)}
</style>
</head>
<body>
<header>
  <div class="lm">B</div>
  <div><div class="ln">BRAIN <span style="color:var(--org)">Analytics</span></div></div>
</header>

<?php if(!$valid): ?>
<div class="container"><div class="card"><h1 style="font-family:var(--fh)">Enlace inválido</h1><p class="muted">Este enlace no es válido o fue desactivado. Contacta a tu equipo de DIMARK.</p></div></div>
<?php else: ?>
<div class="container">
  <div class="hero">
    <h1>Tu Analytics<?= $client_name ? ' · <span style="color:var(--org)">'.htmlspecialchars($client_name).'</span>' : '' ?></h1>
    <p>Elige las métricas que más te importan y míralas en tiempo real. Lo que selecciones aquí también guía las recomendaciones de tu equipo.</p>
  </div>

  <div class="card">
    <div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:10px;margin-bottom:14px">
      <div style="font-family:var(--fh);font-weight:700">Resumen</div>
      <select id="period" onchange="loadAll()">
        <option value="7d">Últimos 7 días</option>
        <option value="30d" selected>Últimos 30 días</option>
        <option value="90d">Últimos 90 días</option>
      </select>
    </div>
    <div id="kpis" class="kpis"><div class="muted">Cargando…</div></div>
  </div>

  <div class="grid2">
    <div class="card">
      <div style="font-family:var(--fh);font-weight:700;margin-bottom:4px">Elige tus métricas</div>
      <div class="muted" style="margin-bottom:10px">Máx 10 métricas y 9 dimensiones.</div>
      <div class="grid2">
        <div><div class="muted" style="margin-bottom:6px;font-weight:600;color:var(--t)">Métricas</div><div id="cat-m" class="catbox">Cargando…</div></div>
        <div><div class="muted" style="margin-bottom:6px;font-weight:600;color:var(--t)">Dimensiones</div><div id="cat-d" class="catbox"></div></div>
      </div>
      <div style="display:flex;align-items:center;gap:10px;margin-top:12px">
        <button class="btn" onclick="saveCfg()">Guardar mi selección</button>
        <span id="msg" class="muted"></span>
      </div>
    </div>
    <div class="card">
      <div style="display:flex;gap:6px;flex-wrap:wrap;margin-bottom:10px">
        <button class="tab btn-tab" data-t="channels" onclick="setTab('channels')">Canales</button>
        <button class="tab btn-tab" data-t="landing" onclick="setTab('landing')">Páginas</button>
        <button class="tab btn-tab" data-t="source" onclick="setTab('source')">Fuente/medio</button>
      </div>
      <div id="tbl"><div class="muted">Cargando…</div></div>
    </div>
  </div>
</div>

<script>
const TOKEN = <?= json_encode($token) ?>;
let CAT = {metrics:[],dimensions:[]};
let TAB = 'channels';
function period(){ return document.getElementById('period').value; }
function api(action, extra){ return `api/ga4-data.php?action=${action}&token=${encodeURIComponent(TOKEN)}&period=${period()}${extra||''}`; }
function fmt(v,m){ const n=Number(v); if(isNaN(n)) return v??'—';
  if(/rate|ratio/i.test(m)) return ((n<=1?n*100:n).toFixed(1))+'%';
  if(/revenue|value|amount|cost/i.test(m)) return '$'+n.toLocaleString('es-CO',{maximumFractionDigits:0});
  return n.toLocaleString('es-CO',{maximumFractionDigits:n%1===0?0:2}); }
function lbl(api){ const x=CAT.metrics.find(i=>i.api===api)||CAT.dimensions.find(i=>i.api===api); return x?x.name:api; }

async function loadAll(){ loadKpis(); loadTab(); }
async function loadKpis(){
  const box=document.getElementById('kpis'); box.innerHTML='<div class="muted">Cargando…</div>';
  try{ const d=await fetch(api('report','&preset=overview')).then(r=>r.json());
    if(!d.ok){ box.innerHTML=`<div class="muted" style="color:var(--y)">${d.error||'Sin datos'}</div>`; return; }
    const t=d.data.totals||{},m=d.data.metrics||[];
    box.innerHTML = m.map(k=>`<div class="kpi"><div class="l">${lbl(k)}</div><div class="v">${fmt(t[k],k)}</div></div>`).join('')||'<div class="muted">Selecciona métricas abajo</div>';
  }catch(e){ box.innerHTML='<div class="muted" style="color:var(--red)">Error de red</div>'; }
}
function setTab(t){ TAB=t; document.querySelectorAll('.btn-tab').forEach(b=>b.style.opacity=b.getAttribute('data-t')===t?'1':'.5'); loadTab(); }
async function loadTab(){
  const el=document.getElementById('tbl'); el.innerHTML='<div class="muted">Cargando…</div>';
  try{ const d=await fetch(api('report','&preset='+TAB)).then(r=>r.json());
    if(!d.ok){ el.innerHTML=`<div class="muted" style="color:var(--y)">${d.error||'Sin datos'}</div>`; return; }
    const rows=d.data.rows||[],mets=d.data.metrics||[];
    if(!rows.length){ el.innerHTML='<div class="muted">Sin filas en este período.</div>'; return; }
    const dk=Object.keys(rows[0].dimensions||{});
    let h='<div style="overflow:auto"><table><thead><tr>';
    dk.forEach(k=>h+=`<th>${lbl(k)}</th>`); mets.forEach(m=>h+=`<th style="text-align:right">${lbl(m)}</th>`);
    h+='</tr></thead><tbody>';
    rows.forEach(r=>{ h+='<tr>'; dk.forEach(k=>h+=`<td>${r.dimensions[k]??'—'}</td>`); mets.forEach(m=>h+=`<td style="text-align:right">${fmt(r.metrics[m],m)}</td>`); h+='</tr>'; });
    el.innerHTML=h+'</tbody></table></div>';
  }catch(e){ el.innerHTML='<div class="muted" style="color:var(--red)">Error de red</div>'; }
}
async function loadCatalog(){
  try{
    const [meta,cfg]=await Promise.all([fetch(api('metadata')).then(r=>r.json()),fetch(api('get_config')).then(r=>r.json())]);
    if(!meta.ok){ document.getElementById('cat-m').innerHTML=`<span style="color:var(--y)">${meta.error}</span>`; return; }
    CAT=meta.data;
    const sm=(cfg.ok&&cfg.data.metrics.length)?cfg.data.metrics:(cfg.data?.defaults?.metrics||[]);
    const sd=(cfg.ok&&cfg.data.dimensions.length)?cfg.data.dimensions:(cfg.data?.defaults?.dimensions||[]);
    const row=(kind,i,sel)=>`<label class="row"><input type="checkbox" class="ck-${kind}" value="${i.api}" ${sel.includes(i.api)?'checked':''}><span>${i.name}</span></label>`;
    document.getElementById('cat-m').innerHTML=CAT.metrics.map(i=>row('m',i,sm)).join('');
    document.getElementById('cat-d').innerHTML=CAT.dimensions.map(i=>row('d',i,sd)).join('');
    loadAll();
  }catch(e){ document.getElementById('cat-m').innerHTML='<span style="color:var(--red)">Error de red</span>'; }
}
async function saveCfg(){
  const metrics=[...document.querySelectorAll('.ck-m:checked')].map(c=>c.value);
  const dimensions=[...document.querySelectorAll('.ck-d:checked')].map(c=>c.value);
  const msg=document.getElementById('msg'); msg.textContent='Guardando…';
  try{ const d=await fetch('api/ga4-data.php?action=save_config',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({token:TOKEN,metrics,dimensions})}).then(r=>r.json());
    if(d.ok){ msg.textContent='✓ Guardado'; msg.style.color='var(--teal)'; loadAll(); } else { msg.textContent=d.error||'Error'; msg.style.color='var(--red)'; }
  }catch(e){ msg.textContent='Error de red'; msg.style.color='var(--red)'; }
}
setTab('channels'); loadCatalog();
</script>
<?php endif ?>
</body>
</html>
