Files
wevads-platform/scripts/world-dashboard.php
2026-02-26 04:53:11 +01:00

353 lines
18 KiB
PHP
Executable File

<?php
/**
* WEVAL SEND - WORLD DASHBOARD V2
* Real data from database + flexible import
*/
$pdo = new PDO("pgsql:host=localhost;dbname=adx_system", "admin", "admin123", [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
// Get real stats from DB
$totalLeads = $pdo->query("SELECT COUNT(*) FROM admin.leads")->fetchColumn();
$totalDomains = $pdo->query("SELECT COUNT(*) FROM admin.domains")->fetchColumn();
$totalCampaigns = $pdo->query("SELECT COUNT(*) FROM admin.campaigns")->fetchColumn();
$completedCampaigns = $pdo->query("SELECT COUNT(*) FROM admin.campaigns WHERE status = 'completed'")->fetchColumn();
// Get country stats
$countryStats = $pdo->query("SELECT * FROM admin.country_daily_stats ORDER BY sent DESC")->fetchAll(PDO::FETCH_ASSOC);
// Get brain winners
$brainWinners = $pdo->query("SELECT isp_target, inbox_rate, stability_score FROM admin.brain_winners ORDER BY inbox_rate DESC LIMIT 6")->fetchAll(PDO::FETCH_ASSOC);
// Get country profiles
$countryProfiles = $pdo->query("SELECT * FROM admin.country_profiles ORDER BY avg_open_rate DESC")->fetchAll(PDO::FETCH_ASSOC);
// Calculate totals
$totalSent = $pdo->query("SELECT COALESCE(SUM(sent), 0) FROM admin.country_daily_stats")->fetchColumn();
$totalOpens = $pdo->query("SELECT COALESCE(SUM(opens), 0) FROM admin.country_daily_stats")->fetchColumn();
$totalClicks = $pdo->query("SELECT COALESCE(SUM(clicks), 0) FROM admin.country_daily_stats")->fetchColumn();
$totalLeadsGen = $pdo->query("SELECT COALESCE(SUM(leads), 0) FROM admin.country_daily_stats")->fetchColumn();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WEVAL SEND - World Dashboard</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: 'Segoe UI', sans-serif; background: #0a0a1a; color: #fff; min-height: 100vh; }
.header { background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%); padding: 15px 25px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #333; }
.header h1 { font-size: 22px; display: flex; align-items: center; gap: 10px; }
.header h1 span { color: #00d4ff; }
.live-badge { display: flex; align-items: center; gap: 8px; background: rgba(0,255,136,0.1); padding: 8px 15px; border-radius: 20px; }
.live-dot { width: 8px; height: 8px; background: #00ff88; border-radius: 50%; animation: pulse 1s infinite; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } }
.nav-tabs { display: flex; gap: 10px; }
.nav-tab { padding: 8px 20px; background: rgba(255,255,255,0.05); border: none; color: #888; border-radius: 8px; cursor: pointer; transition: all 0.3s; }
.nav-tab:hover, .nav-tab.active { background: #00d4ff; color: #000; }
.main-container { display: grid; grid-template-columns: 1fr 380px; gap: 20px; padding: 20px; }
.map-section { background: #1a1a2e; border-radius: 15px; padding: 20px; }
#worldMap { height: 450px; border-radius: 10px; background: #0d1b2a; }
.stats-bar { display: grid; grid-template-columns: repeat(4, 1fr); gap: 15px; margin-bottom: 20px; }
.stat-card { background: linear-gradient(135deg, #1a1a2e, #16213e); padding: 20px; border-radius: 12px; text-align: center; border: 1px solid #333; }
.stat-card .icon { font-size: 24px; margin-bottom: 8px; }
.stat-card .value { font-size: 32px; font-weight: bold; }
.stat-card .label { font-size: 12px; color: #888; margin-top: 5px; }
.stat-card.blue .value { color: #00d4ff; }
.stat-card.green .value { color: #00ff88; }
.stat-card.orange .value { color: #ff9500; }
.stat-card.purple .value { color: #a855f7; }
.sidebar { display: flex; flex-direction: column; gap: 15px; }
.card { background: #1a1a2e; border-radius: 12px; padding: 18px; border: 1px solid #333; }
.card h3 { color: #888; font-size: 11px; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 12px; display: flex; align-items: center; gap: 8px; }
.country-item { display: flex; justify-content: space-between; align-items: center; padding: 10px 0; border-bottom: 1px solid rgba(255,255,255,0.05); }
.country-item:last-child { border: none; }
.country-info { display: flex; align-items: center; gap: 10px; }
.country-flag { font-size: 20px; }
.country-name { font-size: 14px; }
.country-stats { display: flex; gap: 12px; font-size: 12px; }
.country-stats span { padding: 3px 8px; background: rgba(255,255,255,0.05); border-radius: 4px; }
.tz-item { display: flex; justify-content: space-between; align-items: center; padding: 10px; background: rgba(255,255,255,0.03); border-radius: 8px; margin-bottom: 8px; }
.tz-time { font-size: 18px; font-weight: bold; font-family: monospace; }
.tz-status { padding: 4px 12px; border-radius: 15px; font-size: 10px; font-weight: bold; }
.tz-status.optimal { background: #00ff88; color: #000; }
.tz-status.waiting { background: #ff9500; color: #000; }
.tz-status.sleeping { background: #444; color: #888; }
.isp-item { display: flex; justify-content: space-between; align-items: center; padding: 8px 0; }
.isp-name { font-size: 14px; }
.isp-rate { font-size: 16px; font-weight: bold; color: #00ff88; }
.isp-bar { height: 4px; background: #333; border-radius: 2px; margin-top: 4px; }
.isp-bar-fill { height: 100%; background: linear-gradient(90deg, #00d4ff, #00ff88); border-radius: 2px; }
.btn-action { width: 100%; padding: 15px; background: linear-gradient(135deg, #00d4ff, #00ff88); border: none; border-radius: 10px; font-size: 14px; font-weight: bold; color: #000; cursor: pointer; margin-top: 10px; display: flex; align-items: center; justify-content: center; gap: 8px; }
.btn-action:hover { transform: translateY(-2px); box-shadow: 0 5px 20px rgba(0,212,255,0.3); }
.btn-secondary { background: rgba(255,255,255,0.1); color: #fff; }
.btn-secondary:hover { background: rgba(255,255,255,0.2); box-shadow: none; }
.legend { display: flex; gap: 20px; margin-top: 15px; justify-content: center; }
.legend-item { display: flex; align-items: center; gap: 6px; font-size: 12px; color: #888; }
.legend-dot { width: 10px; height: 10px; border-radius: 50%; }
.resources-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
.resource-item { background: rgba(255,255,255,0.03); padding: 12px; border-radius: 8px; text-align: center; }
.resource-value { font-size: 20px; font-weight: bold; color: #00d4ff; }
.resource-label { font-size: 11px; color: #888; margin-top: 4px; }
</style>
</head>
<body>
<div class="header">
<h1>🌍 <span>WEVAL SEND</span> World Command Center</h1>
<div class="nav-tabs">
<button class="nav-tab active">📊 Dashboard</button>
<button class="nav-tab" onclick="location.href='data-import.php'">📥 Import Data</button>
<button class="nav-tab" onclick="location.href='api-config.php'">⚙️ Config</button>
</div>
<div class="live-badge">
<div class="live-dot"></div>
<span>LIVE</span>
<span id="currentTime"></span>
</div>
</div>
<!-- Stats Bar -->
<div style="padding: 20px 20px 0;">
<div class="stats-bar">
<div class="stat-card blue">
<div class="icon">📤</div>
<div class="value"><?= number_format($totalSent) ?></div>
<div class="label">EMAILS SENT</div>
</div>
<div class="stat-card green">
<div class="icon">📬</div>
<div class="value"><?= number_format($totalOpens) ?></div>
<div class="label">OPENS</div>
</div>
<div class="stat-card orange">
<div class="icon">🖱️</div>
<div class="value"><?= number_format($totalClicks) ?></div>
<div class="label">CLICKS</div>
</div>
<div class="stat-card purple">
<div class="icon">🎯</div>
<div class="value"><?= number_format($totalLeadsGen) ?></div>
<div class="label">LEADS GENERATED</div>
</div>
</div>
</div>
<div class="main-container">
<!-- Map Section -->
<div class="map-section">
<h3 style="margin-bottom:15px; color:#888; font-size:12px;">📍 GLOBAL TRAFFIC HEATMAP</h3>
<div id="worldMap"></div>
<div class="legend">
<div class="legend-item"><div class="legend-dot" style="background:#00ff88;"></div> High Engagement (>25%)</div>
<div class="legend-item"><div class="legend-dot" style="background:#ff9500;"></div> Medium (15-25%)</div>
<div class="legend-item"><div class="legend-dot" style="background:#ff4444;"></div> Low (<15%)</div>
</div>
</div>
<!-- Sidebar -->
<div class="sidebar">
<!-- Resources -->
<div class="card">
<h3>📦 Platform Resources</h3>
<div class="resources-grid">
<div class="resource-item">
<div class="resource-value"><?= number_format($totalLeads) ?></div>
<div class="resource-label">Total Leads</div>
</div>
<div class="resource-item">
<div class="resource-value"><?= $totalDomains ?></div>
<div class="resource-label">Domains</div>
</div>
<div class="resource-item">
<div class="resource-value"><?= $totalCampaigns ?></div>
<div class="resource-label">Campaigns</div>
</div>
<div class="resource-item">
<div class="resource-value"><?= $completedCampaigns ?></div>
<div class="resource-label">Completed</div>
</div>
</div>
</div>
<!-- Top Countries -->
<div class="card">
<h3>🏆 Top Performing Countries</h3>
<?php
$flags = ['DE'=>'🇩🇪','FR'=>'🇫🇷','NL'=>'🇳🇱','US'=>'🇺🇸','UK'=>'🇬🇧','ES'=>'🇪🇸','IT'=>'🇮🇹','CA'=>'🇨🇦','AU'=>'🇦🇺','BR'=>'🇧🇷'];
foreach(array_slice($countryStats, 0, 5) as $c):
$flag = $flags[$c['country_code']] ?? '🌍';
?>
<div class="country-item">
<div class="country-info">
<span class="country-flag"><?= $flag ?></span>
<span class="country-name"><?= $c['country_code'] ?></span>
</div>
<div class="country-stats">
<span>📬 <?= number_format($c['opens']) ?></span>
<span>🖱️ <?= number_format($c['clicks']) ?></span>
</div>
</div>
<?php endforeach; ?>
<?php if(empty($countryStats)): ?>
<div style="text-align:center; color:#666; padding:20px;">
No data yet. <a href="data-import.php" style="color:#00d4ff;">Import data</a>
</div>
<?php endif; ?>
</div>
<!-- Timezone Scheduler -->
<div class="card">
<h3>⏰ Timezone Auto-Schedule</h3>
<div id="tzScheduler"></div>
</div>
<!-- Brain Winners -->
<div class="card" style="background: linear-gradient(135deg, rgba(0,212,255,0.1), rgba(0,255,136,0.1)); border-color: #00d4ff44;">
<h3>🧠 Brain Winners (Best ISPs)</h3>
<?php foreach(array_slice($brainWinners, 0, 4) as $w):
$pct = min(100, $w['inbox_rate']);
?>
<div class="isp-item">
<div>
<div class="isp-name"><?= $w['isp_target'] ?></div>
<div class="isp-bar" style="width:150px;">
<div class="isp-bar-fill" style="width:<?= $pct ?>%;"></div>
</div>
</div>
<div class="isp-rate"><?= $w['inbox_rate'] ?>%</div>
</div>
<?php endforeach; ?>
</div>
<!-- Actions -->
<button class="btn-action" onclick="location.href='data-import.php'">
📥 IMPORT DATA
</button>
<button class="btn-action btn-secondary" onclick="launchCampaign()">
🚀 LAUNCH AUTO CAMPAIGN
</button>
</div>
</div>
<script>
// Initialize map
const map = L.map('worldMap', {
center: [30, 10],
zoom: 2,
minZoom: 2,
maxZoom: 6
});
L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', {
attribution: '©WEVAL SEND'
}).addTo(map);
// Country data from PHP
const countryData = <?= json_encode(array_column($countryStats, null, 'country_code')) ?>;
const countryCoords = {
'DE': [51.1657, 10.4515],
'FR': [46.2276, 2.2137],
'NL': [52.1326, 5.2913],
'US': [39.8283, -98.5795],
'UK': [55.3781, -3.4360],
'ES': [40.4637, -3.7492],
'IT': [41.8719, 12.5674],
'CA': [56.1304, -106.3468],
'AU': [-25.2744, 133.7751],
'BR': [-14.2350, -51.9253]
};
const countryFlags = {
'DE': '🇩🇪', 'FR': '🇫🇷', 'NL': '🇳🇱', 'US': '🇺🇸', 'UK': '🇬🇧',
'ES': '🇪🇸', 'IT': '🇮🇹', 'CA': '🇨🇦', 'AU': '🇦🇺', 'BR': '🇧🇷'
};
// Add markers
Object.entries(countryData).forEach(([code, data]) => {
if (!countryCoords[code]) return;
const openRate = data.sent > 0 ? (data.opens / data.sent * 100) : 0;
const color = openRate > 25 ? '#00ff88' : openRate > 15 ? '#ff9500' : '#ff4444';
const size = Math.min(25, Math.max(8, data.sent / 3000));
L.circleMarker(countryCoords[code], {
radius: size,
fillColor: color,
color: '#fff',
weight: 2,
opacity: 1,
fillOpacity: 0.7
}).addTo(map).bindPopup(`
<div style="min-width:150px;">
<b>${countryFlags[code] || ''} ${code}</b><br>
<hr style="margin:5px 0;border-color:#333;">
📤 Sent: <b>${parseInt(data.sent).toLocaleString()}</b><br>
📬 Opens: <b>${parseInt(data.opens).toLocaleString()}</b> (${openRate.toFixed(1)}%)<br>
🖱️ Clicks: <b>${parseInt(data.clicks).toLocaleString()}</b><br>
🎯 Leads: <b>${parseInt(data.leads).toLocaleString()}</b>
</div>
`);
});
// Timezone scheduler
function updateTimezones() {
const timezones = [
{ name: 'Europe (CET)', offset: 1 },
{ name: 'US East (EST)', offset: -5 },
{ name: 'US West (PST)', offset: -8 },
{ name: 'Asia (SGT)', offset: 8 }
];
const now = new Date();
const html = timezones.map(tz => {
const localHour = (now.getUTCHours() + tz.offset + 24) % 24;
const localTime = `${String(localHour).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;
const isOptimal = [9,10,11,14,15,16].includes(localHour);
const isSleeping = localHour < 7 || localHour > 21;
let status = 'waiting', statusText = 'Waiting';
if (isOptimal) { status = 'optimal'; statusText = 'OPTIMAL'; }
if (isSleeping) { status = 'sleeping'; statusText = 'Sleep'; }
return `
<div class="tz-item">
<div>
<div style="font-size:11px;color:#666;">${tz.name}</div>
<div class="tz-time">${localTime}</div>
</div>
<div class="tz-status ${status}">${statusText}</div>
</div>
`;
}).join('');
document.getElementById('tzScheduler').innerHTML = html;
}
function updateTime() {
document.getElementById('currentTime').textContent = new Date().toLocaleTimeString();
}
function launchCampaign() {
if(confirm('🚀 Launch autonomous campaign to optimal countries?')) {
alert('Campaign queued! Check the scheduler for status.');
}
}
updateTimezones();
updateTime();
setInterval(updateTime, 1000);
setInterval(updateTimezones, 60000);
</script>
</body>
</html>