| Current Path : /home/seto/888mirror.pm/admin/ |
| Current File : /home/seto/888mirror.pm/admin/landing_stats.php |
<?php
require_once __DIR__ . '/../includes/auth.php';
require_once __DIR__ . '/../includes/helpers.php';
auth_check();
$id = (int)($_GET['id'] ?? 0);
if (!$id) { header('Location: /admin/landings.php'); exit(); }
$stmt = db()->prepare("SELECT * FROM landings WHERE id=?");
$stmt->execute([$id]);
$lnd = $stmt->fetch();
if (!$lnd) { header('Location: /admin/landings.php'); exit(); }
$period = $_GET['period'] ?? '30d';
$since = match($period) {
'7d' => "datetime('now','-7 days')",
'all' => "'1970-01-01'",
default => "datetime('now','-30 days')",
};
// Общая статистика
$totals = db()->query("
SELECT
SUM(CASE WHEN event_type='impression' THEN 1 ELSE 0 END) as imp,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END) as clk
FROM stats WHERE landing_id=$id AND created_at >= $since
")->fetch();
$imp = (int)($totals['imp'] ?? 0);
$clk = (int)($totals['clk'] ?? 0);
$ctr = $imp > 0 ? round($clk / $imp * 100, 1) : 0;
// Топ брендов
$top_brands = db()->query("
SELECT b.name, b.logo,
SUM(CASE WHEN s.event_type='impression' THEN 1 ELSE 0 END) as imp,
SUM(CASE WHEN s.event_type='click' THEN 1 ELSE 0 END) as clk
FROM stats s
JOIN brands b ON b.id=s.brand_id
WHERE s.landing_id=$id AND s.created_at >= $since
GROUP BY s.brand_id
ORDER BY imp DESC LIMIT 20
")->fetchAll();
// По дням (последние 30)
$daily = db()->query("
SELECT date(created_at) as day,
SUM(CASE WHEN event_type='impression' THEN 1 ELSE 0 END) as imp,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END) as clk
FROM stats WHERE landing_id=$id AND created_at >= $since
GROUP BY day ORDER BY day DESC LIMIT 30
")->fetchAll();
// По GEO
$geo_stats = db()->query("
SELECT country,
SUM(CASE WHEN event_type='impression' THEN 1 ELSE 0 END) as imp,
SUM(CASE WHEN event_type='click' THEN 1 ELSE 0 END) as clk
FROM stats WHERE landing_id=$id AND created_at >= $since AND country != '-'
GROUP BY country ORDER BY imp DESC LIMIT 20
")->fetchAll();
?>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Статистика: <?= h($lnd['name']) ?> — Admin</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" rel="stylesheet">
</head>
<body>
<?= admin_nav('landings') ?>
<div class="container-fluid px-4" style="max-width:1000px">
<div class="d-flex align-items-center gap-2 mb-3 flex-wrap">
<a href="/admin/landings.php" class="btn btn-outline-secondary btn-sm">← Landings</a>
<h5 class="mb-0"><i class="bi bi-bar-chart-line me-1"></i><?= h($lnd['name']) ?></h5>
<small class="text-muted">/<?= h($lnd['slug']) ?></small>
<div class="btn-group btn-group-sm ms-auto">
<a href="?id=<?= $id ?>&period=7d" class="btn btn-outline-secondary <?= $period==='7d' ?'active':'' ?>">7д</a>
<a href="?id=<?= $id ?>&period=30d" class="btn btn-outline-secondary <?= $period==='30d'?'active':'' ?>">30д</a>
<a href="?id=<?= $id ?>&period=all" class="btn btn-outline-secondary <?= $period==='all'?'active':'' ?>">Всё время</a>
</div>
<a href="/<?= h($lnd['slug']) ?>?preview=1" target="_blank" class="btn btn-outline-secondary btn-sm"><i class="bi bi-eye me-1"></i>Превью</a>
<a href="/admin/landing_edit.php?id=<?= $id ?>" class="btn btn-outline-primary btn-sm"><i class="bi bi-pencil me-1"></i>Редактировать</a>
</div>
<!-- Сводка -->
<div class="row g-3 mb-4">
<div class="col-md-4">
<div class="card text-center shadow-sm">
<div class="card-body py-3">
<div class="fs-2 fw-bold"><?= number_format($imp) ?></div>
<div class="text-muted small">Показы</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card text-center shadow-sm">
<div class="card-body py-3">
<div class="fs-2 fw-bold"><?= number_format($clk) ?></div>
<div class="text-muted small">Клики</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card text-center shadow-sm">
<div class="card-body py-3">
<div class="fs-2 fw-bold <?= $ctr > 5 ? 'text-success' : ($ctr > 0 ? 'text-warning' : '') ?>"><?= $ctr ?>%</div>
<div class="text-muted small">CTR</div>
</div>
</div>
</div>
</div>
<div class="row g-4">
<!-- По дням -->
<div class="col-md-6">
<div class="card shadow-sm h-100">
<div class="card-header fw-semibold">По дням</div>
<div class="card-body p-0">
<?php if (empty($daily)): ?>
<p class="text-muted text-center py-3 mb-0">Нет данных</p>
<?php else: ?>
<table class="table table-sm table-hover mb-0">
<thead class="table-light"><tr><th>Дата</th><th class="text-center">Показы</th><th class="text-center">Клики</th><th class="text-center">CTR</th></tr></thead>
<tbody>
<?php foreach ($daily as $d):
$d_ctr = $d['imp']>0 ? round($d['clk']/$d['imp']*100,1).'%' : '—';
?>
<tr>
<td><?= h($d['day']) ?></td>
<td class="text-center"><?= number_format($d['imp']) ?></td>
<td class="text-center"><?= number_format($d['clk']) ?></td>
<td class="text-center"><?= $d_ctr ?></td>
</tr>
<?php endforeach ?>
</tbody>
</table>
<?php endif ?>
</div>
</div>
</div>
<!-- По GEO -->
<div class="col-md-6">
<div class="card shadow-sm mb-4">
<div class="card-header fw-semibold">По GEO</div>
<div class="card-body p-0">
<?php if (empty($geo_stats)): ?>
<p class="text-muted text-center py-3 mb-0">Нет данных</p>
<?php else: ?>
<table class="table table-sm table-hover mb-0">
<thead class="table-light"><tr><th>GEO</th><th class="text-center">Показы</th><th class="text-center">Клики</th><th class="text-center">CTR</th></tr></thead>
<tbody>
<?php foreach ($geo_stats as $g):
$g_ctr = $g['imp']>0 ? round($g['clk']/$g['imp']*100,1).'%' : '—';
$cc = $g['country'];
?>
<tr>
<td class="d-flex align-items-center gap-2">
<?php if ($cc === 'crypto'): ?>
<span>💎</span> <span>Crypto</span>
<?php elseif ($cc === 'en'): ?>
<span>🌐</span> <span>Global</span>
<?php elseif (strlen($cc) === 2): ?>
<img src="https://flagicons.lipis.dev/flags/4x3/<?= h($cc) ?>.svg" width="18" height="14" style="border-radius:2px">
<span><?= h(strtoupper($cc)) ?></span>
<?php else: ?>
<span><?= h($cc) ?></span>
<?php endif ?>
</td>
<td class="text-center"><?= number_format($g['imp']) ?></td>
<td class="text-center"><?= number_format($g['clk']) ?></td>
<td class="text-center"><?= $g_ctr ?></td>
</tr>
<?php endforeach ?>
</tbody>
</table>
<?php endif ?>
</div>
</div>
<!-- Топ брендов -->
<div class="card shadow-sm">
<div class="card-header fw-semibold">Топ брендов</div>
<div class="card-body p-0">
<?php if (empty($top_brands)): ?>
<p class="text-muted text-center py-3 mb-0">Нет данных</p>
<?php else: ?>
<table class="table table-sm table-hover mb-0">
<thead class="table-light"><tr><th>Бренд</th><th class="text-center">Показы</th><th class="text-center">Клики</th><th class="text-center">CTR</th></tr></thead>
<tbody>
<?php foreach ($top_brands as $b):
$b_ctr = $b['imp']>0 ? round($b['clk']/$b['imp']*100,1).'%' : '—';
?>
<tr>
<td class="d-flex align-items-center gap-2">
<?php if ($b['logo']): ?><img src="<?= h($b['logo']) ?>" height="20" style="object-fit:contain"><?php endif ?>
<span><?= h($b['name']) ?></span>
</td>
<td class="text-center"><?= number_format($b['imp']) ?></td>
<td class="text-center"><?= number_format($b['clk']) ?></td>
<td class="text-center"><?= $b_ctr ?></td>
</tr>
<?php endforeach ?>
</tbody>
</table>
<?php endif ?>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>