108 lines
6.8 KiB
PHP
108 lines
6.8 KiB
PHP
<?php
|
|
require_once('/opt/wevads/config/credentials.php');
|
|
error_reporting(E_ALL);
|
|
ini_set('display_errors', 0);
|
|
|
|
function getDb() {
|
|
static $pdo = null;
|
|
if ($pdo === null) {
|
|
$pdo = get_pdo('adx_system');
|
|
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
}
|
|
return $pdo;
|
|
}
|
|
|
|
if (isset($_GET['action'])) {
|
|
header('Content-Type: application/json');
|
|
$pdo = getDb();
|
|
|
|
switch ($_GET['action']) {
|
|
case 'overview':
|
|
$data = [];
|
|
try { $data['campaigns'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.campaigns")->fetchColumn(); } catch (Exception $e) { $data['campaigns'] = 0; }
|
|
try { $data['o365_total'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.office_accounts")->fetchColumn(); } catch (Exception $e) { $data['o365_total'] = 0; }
|
|
try { $data['o365_active'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.office_accounts WHERE status = 'Active'")->fetchColumn(); } catch (Exception $e) { $data['o365_active'] = 0; }
|
|
try { $data['gsuite_users'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.gsuite_users")->fetchColumn(); } catch (Exception $e) { $data['gsuite_users'] = 0; }
|
|
try { $data['leads'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.import_leads")->fetchColumn(); } catch (Exception $e) { $data['leads'] = 0; }
|
|
try { $data['firebase_tokens'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.firebase_tokens")->fetchColumn(); } catch (Exception $e) { $data['firebase_tokens'] = 0; }
|
|
echo json_encode($data);
|
|
break;
|
|
|
|
case 'daily_stats':
|
|
$days = intval($_GET['days'] ?? 7);
|
|
$stats = [];
|
|
for ($i = $days - 1; $i >= 0; $i--) {
|
|
$date = date('Y-m-d', strtotime("-$i days"));
|
|
$row = ['date' => $date, 'leads' => 0, 'emails' => 0];
|
|
try { $row['leads'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.import_leads WHERE DATE(created_at) = '$date'")->fetchColumn(); } catch (Exception $e) {}
|
|
$stats[] = $row;
|
|
}
|
|
echo json_encode($stats);
|
|
break;
|
|
|
|
case 'o365_breakdown':
|
|
$breakdown = [];
|
|
try {
|
|
$result = $pdo->query("SELECT status, COUNT(*) as count FROM admin.office_accounts GROUP BY status ORDER BY count DESC");
|
|
$breakdown = $result->fetchAll(PDO::FETCH_ASSOC);
|
|
} catch (Exception $e) {}
|
|
echo json_encode($breakdown);
|
|
break;
|
|
|
|
default:
|
|
echo json_encode(['error' => 'Unknown action']);
|
|
}
|
|
exit;
|
|
}
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Analytics - WEVAL SEND</title>
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
<style>
|
|
:root{--bg:#0a0a0f;--card:#12121a;--card2:#1a1a25;--border:#2a2a3a;--text:#e4e4e7;--text2:#9ca3af;--primary:#6366f1;--success:#10b981;--warning:#f59e0b;--danger:#ef4444}
|
|
*{margin:0;padding:0;box-sizing:border-box}body{font-family:'Inter',sans-serif;background:var(--bg);color:var(--text);min-height:100vh;padding:20px}.container{max-width:1400px;margin:0 auto}h1{font-size:24px;margin-bottom:24px;display:flex;align-items:center;gap:12px}h1 i{color:var(--primary)}
|
|
.stats-grid{display:grid;grid-template-columns:repeat(6,1fr);gap:16px;margin-bottom:24px}.stat-card{background:var(--card);border-radius:12px;padding:20px;border:1px solid var(--border)}.stat-value{font-size:28px;font-weight:700}.stat-label{color:var(--text2);font-size:12px;margin-top:4px}
|
|
.charts-grid{display:grid;grid-template-columns:2fr 1fr;gap:20px;margin-bottom:20px}.chart-card{background:var(--card);border-radius:12px;border:1px solid var(--border);padding:20px}.chart-card h2{font-size:16px;margin-bottom:16px}
|
|
@media(max-width:1200px){.stats-grid{grid-template-columns:repeat(3,1fr)}.charts-grid{grid-template-columns:1fr}}
|
|
</style>
|
|
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<h1><i class="fas fa-chart-line"></i> Analytics Dashboard</h1>
|
|
<div class="stats-grid">
|
|
<div class="stat-card"><div class="stat-value" id="statCampaigns">-</div><div class="stat-label">Campaigns</div></div>
|
|
<div class="stat-card"><div class="stat-value" id="statO365">-</div><div class="stat-label">O365 Total</div></div>
|
|
<div class="stat-card"><div class="stat-value" style="color:var(--success)" id="statO365Active">-</div><div class="stat-label">O365 Active</div></div>
|
|
<div class="stat-card"><div class="stat-value" id="statGSuite">-</div><div class="stat-label">GSuite Users</div></div>
|
|
<div class="stat-card"><div class="stat-value" id="statLeads">-</div><div class="stat-label">Total Leads</div></div>
|
|
<div class="stat-card"><div class="stat-value" id="statTokens">-</div><div class="stat-label">FCM Tokens</div></div>
|
|
</div>
|
|
<div class="charts-grid">
|
|
<div class="chart-card"><h2><i class="fas fa-chart-area"></i> Daily Leads (7 days)</h2><canvas id="leadsChart"></canvas></div>
|
|
<div class="chart-card"><h2><i class="fas fa-chart-pie"></i> O365 Status</h2><canvas id="o365Chart"></canvas></div>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
let leadsChart, o365Chart;
|
|
async function loadOverview(){const d=await fetch('?action=overview').then(r=>r.json());document.getElementById('statCampaigns').textContent=d.campaigns;document.getElementById('statO365').textContent=d.o365_total;document.getElementById('statO365Active').textContent=d.o365_active;document.getElementById('statGSuite').textContent=d.gsuite_users;document.getElementById('statLeads').textContent=d.leads;document.getElementById('statTokens').textContent=d.firebase_tokens;}
|
|
async function loadCharts(){
|
|
const daily=await fetch('?action=daily_stats&days=7').then(r=>r.json());
|
|
const o365=await fetch('?action=o365_breakdown').then(r=>r.json());
|
|
if(leadsChart)leadsChart.destroy();
|
|
leadsChart=new Chart(document.getElementById('leadsChart'),{type:'line',data:{labels:daily.map(d=>d.date.substring(5)),datasets:[{label:'Leads',data:daily.map(d=>d.leads),borderColor:'#6366f1',backgroundColor:'rgba(99,102,241,0.1)',fill:true,tension:0.4}]},options:{responsive:true,plugins:{legend:{display:false}},scales:{y:{beginAtZero:true,grid:{color:'#2a2a3a'}},x:{grid:{color:'#2a2a3a'}}}}});
|
|
if(o365Chart)o365Chart.destroy();
|
|
const colors={'Active':'#10b981','Blocked':'#ef4444','Pending':'#f59e0b','Invalid':'#6366f1','Unknown':'#9ca3af'};
|
|
o365Chart=new Chart(document.getElementById('o365Chart'),{type:'doughnut',data:{labels:o365.map(d=>d.status),datasets:[{data:o365.map(d=>d.count),backgroundColor:o365.map(d=>colors[d.status]||'#6366f1')}]},options:{responsive:true,plugins:{legend:{position:'bottom',labels:{color:'#e4e4e7'}}}}});
|
|
}
|
|
loadOverview();loadCharts();setInterval(loadOverview,30000);
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|