Initial commit: Proyecto Portal ePromos completo con documentación unificada y seguridad base
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
// ruleta/admin/dashboard_landing_widgets.php
|
||||
if (!isset($conn)) { require_once __DIR__ . '/db.php'; }
|
||||
if (session_status() === PHP_SESSION_NONE) { session_start(); }
|
||||
if (empty($_SESSION['admin_id'])) { header('Location: ../index.php'); exit; }
|
||||
|
||||
// ---- Totales generales módulo landing ----
|
||||
$tot_landings = (int)$conn->query("SELECT COUNT(*) c FROM landing_pages")->fetch_assoc()['c'];
|
||||
$tot_variants = (int)$conn->query("SELECT COUNT(*) c FROM landing_variants")->fetch_assoc()['c'];
|
||||
$tot_blocks = (int)$conn->query("SELECT COUNT(*) c FROM landing_blocks")->fetch_assoc()['c'];
|
||||
$tot_leads_30d = (int)$conn->query("SELECT COUNT(*) c FROM landing_forms WHERE created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)")->fetch_assoc()['c'];
|
||||
|
||||
// ---- Top landings por CR últimos 30 días (impresiones/conversiones) ----
|
||||
$top = [];
|
||||
$st = $conn->prepare("
|
||||
SELECT
|
||||
lp.id AS landing_id, lp.titulo,
|
||||
SUM(lvs.event_type='impression') AS impresiones,
|
||||
SUM(lvs.event_type='conversion') AS conversiones,
|
||||
ROUND(SUM(lvs.event_type='conversion')/NULLIF(SUM(lvs.event_type='impression'),0)*100,2) AS cr
|
||||
FROM landing_pages lp
|
||||
LEFT JOIN landing_variant_stats lvs
|
||||
ON lvs.landing_id = lp.id
|
||||
AND lvs.created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)
|
||||
GROUP BY lp.id, lp.titulo
|
||||
ORDER BY cr DESC IS NULL, cr DESC, impresiones DESC
|
||||
LIMIT 10
|
||||
");
|
||||
$st->execute();
|
||||
$top_rs = $st->get_result();
|
||||
while($r = $top_rs->fetch_assoc()){ $top[] = $r; }
|
||||
|
||||
// ---- Listado rápido de landings con accesos (últimos 8) ----
|
||||
$list = $conn->query("
|
||||
SELECT id, titulo, slug, activo, DATE_FORMAT(fecha_creacion,'%Y-%m-%d %H:%i') AS fc
|
||||
FROM landing_pages
|
||||
ORDER BY id DESC
|
||||
LIMIT 8
|
||||
");
|
||||
?>
|
||||
<div class="container-fluid px-0">
|
||||
<!-- Resumen de tarjetas -->
|
||||
<div class="row g-3">
|
||||
<div class="col-md-3">
|
||||
<div class="card shadow-sm border-0">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div><h6 class="text-muted mb-1">Landings</h6><h3 class="mb-0"><?= number_format($tot_landings) ?></h3></div>
|
||||
<div class="fs-3">🧭</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card shadow-sm border-0">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div><h6 class="text-muted mb-1">Variantes A/B</h6><h3 class="mb-0"><?= number_format($tot_variants) ?></h3></div>
|
||||
<div class="fs-3">🧪</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card shadow-sm border-0">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div><h6 class="text-muted mb-1">Bloques</h6><h3 class="mb-0"><?= number_format($tot_blocks) ?></h3></div>
|
||||
<div class="fs-3">🧱</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card shadow-sm border-0">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div><h6 class="text-muted mb-1">Leads (30d)</h6><h3 class="mb-0"><?= number_format($tot_leads_30d) ?></h3></div>
|
||||
<div class="fs-3">📈</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tabla: Top 10 por CR (30d) -->
|
||||
<div class="card shadow-sm mt-3">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<h5 class="mb-0">Top CR por Landing (30 días)</h5>
|
||||
<a href="landing.php" class="btn btn-sm btn-outline-primary">Ver todas</a>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Landing</th>
|
||||
<th class="text-end">Impresiones</th>
|
||||
<th class="text-end">Conversiones</th>
|
||||
<th class="text-end">CR %</th>
|
||||
<th class="text-nowrap">Acciones</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if($top): foreach($top as $r): ?>
|
||||
<tr>
|
||||
<td class="fw-semibold"><?= htmlspecialchars($r['titulo']) ?></td>
|
||||
<td class="text-end"><?= (int)$r['impresiones'] ?></td>
|
||||
<td class="text-end"><?= (int)$r['conversiones'] ?></td>
|
||||
<td class="text-end"><?= $r['cr'] !== null ? number_format((float)$r['cr'],2) : '—' ?></td>
|
||||
<td class="text-nowrap">
|
||||
<a class="btn btn-sm btn-outline-secondary" href="landing_stats.php?landing_id=<?= (int)$r['landing_id'] ?>">Stats</a>
|
||||
<a class="btn btn-sm btn-outline-secondary" href="landing_variants.php?landing_id=<?= (int)$r['landing_id'] ?>">Variantes</a>
|
||||
<a class="btn btn-sm btn-outline-secondary" href="landing_builder.php?landing_id=<?= (int)$r['landing_id'] ?>">Builder</a>
|
||||
<a class="btn btn-sm btn-outline-secondary" href="landing_crm.php?landing_id=<?= (int)$r['landing_id'] ?>">CRM</a>
|
||||
<a class="btn btn-sm btn-outline-secondary" href="landing_forms.php?landing_id=<?= (int)$r['landing_id'] ?>">Leads</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; else: ?>
|
||||
<tr><td colspan="5" class="text-center text-muted">Sin datos</td></tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Últimas landings creadas (accesos rápidos) -->
|
||||
<div class="card shadow-sm mt-3">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<h5 class="mb-0">Accesos rápidos</h5>
|
||||
<a href="landing.php" class="btn btn-sm btn-primary">Nueva landing</a>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Landing</th>
|
||||
<th>Slug</th>
|
||||
<th>Creada</th>
|
||||
<th>Estado</th>
|
||||
<th class="text-nowrap">Acciones</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if($list && $list->num_rows): while($r=$list->fetch_assoc()): ?>
|
||||
<tr>
|
||||
<td class="fw-semibold"><?= htmlspecialchars($r['titulo']) ?></td>
|
||||
<td><code><?= htmlspecialchars($r['slug']) ?></code></td>
|
||||
<td><?= htmlspecialchars($r['fc']) ?></td>
|
||||
<td><?= $r['activo'] ? '<span class="badge text-bg-success">Activo</span>' : '<span class="badge text-bg-secondary">Inactivo</span>' ?></td>
|
||||
<td class="text-nowrap d-flex gap-1">
|
||||
<a class="btn btn-sm btn-outline-primary" href="landing_variants.php?landing_id=<?= (int)$r['id'] ?>">Variantes</a>
|
||||
<a class="btn btn-sm btn-outline-primary" href="landing_schedule.php?landing_id=<?= (int)$r['id'] ?>">Schedule</a>
|
||||
<a class="btn btn-sm btn-outline-primary" href="landing_page_blocks.php?landing_id=<?= (int)$r['id'] ?>">Bloques</a>
|
||||
<a class="btn btn-sm btn-outline-primary" href="landing_builder.php?landing_id=<?= (int)$r['id'] ?>">Builder</a>
|
||||
<a class="btn btn-sm btn-outline-primary" href="landing_stats.php?landing_id=<?= (int)$r['id'] ?>">Stats</a>
|
||||
<a class="btn btn-sm btn-outline-primary" href="landing_crm.php?landing_id=<?= (int)$r['id'] ?>">CRM</a>
|
||||
<a class="btn btn-sm btn-outline-primary" href="landing_forms.php?landing_id=<?= (int)$r['id'] ?>">Leads</a>
|
||||
<a class="btn btn-sm btn-outline-secondary" target="_blank" href="../landing.php?slug=<?= urlencode($r['slug']) ?>">Ver</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endwhile; else: ?>
|
||||
<tr><td colspan="5" class="text-center text-muted">Aún no hay landings</td></tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user