Files
wevads-platform/scripts/tracking-system-standalone.php
2026-02-26 04:53:11 +01:00

353 lines
30 KiB
PHP
Executable File

<?php
session_start();
$base_url = 'http://89.167.40.150:5821';
$tracking_ip = '151.80.235.110';
$tracking_ssh_pass = 'MX8D3zSAty7k3243242';
$wevads_api = 'http://89.167.40.150:5821/api.json';
// Metrics
if (isset($_GET['action']) && $_GET['action'] === 'metrics') {
header('Content-Type: application/json');
$cpuLoad = sys_getloadavg();
$cpuPercent = round(($cpuLoad[0] / intval(shell_exec("nproc"))) * 100, 1);
$memInfo = file_get_contents('/proc/meminfo');
preg_match('/MemTotal:\s+(\d+)/', $memInfo, $memTotal);
preg_match('/MemAvailable:\s+(\d+)/', $memInfo, $memAvailable);
$memPercent = round((($memTotal[1] - $memAvailable[1]) / $memTotal[1]) * 100, 1);
$diskPercent = round(((disk_total_space('/') - disk_free_space('/')) / disk_total_space('/')) * 100, 1);
$start = microtime(true);
$ch = curl_init(); curl_setopt_array($ch, [CURLOPT_URL => "http://{$tracking_ip}/", CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 5]); curl_exec($ch); $trackingCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
$trackingTime = round((microtime(true) - $start) * 1000);
$trackingMetrics = ['cpu' => 0, 'mem' => 0, 'disk' => 0];
$sshCmd = "sshpass -p '{$tracking_ssh_pass}' ssh -o StrictHostKeyChecking=no -o ConnectTimeout=3 ubuntu@{$tracking_ip} \"cat /proc/loadavg && free -m && df -h /\" 2>/dev/null";
$sshOutput = shell_exec($sshCmd);
if ($sshOutput) {
$lines = explode("\n", $sshOutput);
if (isset($lines[0])) { $loadParts = explode(' ', $lines[0]); $trackingMetrics['cpu'] = round(floatval($loadParts[0]) * 100 / 2, 1); }
foreach ($lines as $line) {
if (strpos($line, 'Mem:') !== false) { $parts = preg_split('/\s+/', trim($line)); if (count($parts) >= 3) $trackingMetrics['mem'] = round(($parts[2] / $parts[1]) * 100, 1); }
if (strpos($line, '/dev/') !== false && strpos($line, '%') !== false) { preg_match('/(\d+)%/', $line, $diskMatch); if (isset($diskMatch[1])) $trackingMetrics['disk'] = intval($diskMatch[1]); }
}
}
echo json_encode(['wevads' => ['cpu' => $cpuPercent, 'mem' => $memPercent, 'disk' => $diskPercent], 'tracking' => ['cpu' => $trackingMetrics['cpu'], 'mem' => $trackingMetrics['mem'], 'disk' => $trackingMetrics['disk'], 'response_time' => $trackingTime, 'status' => $trackingCode > 0 ? 'online' : 'offline']]);
exit;
}
// Generate Click - INSERT with geolocation
if (isset($_GET['action']) && $_GET['action'] === 'generate_click') {
header('Content-Type: application/json');
try {
$db = new PDO('pgsql:host=localhost;dbname=adx_system', 'admin', 'admin123');
$stmt = $db->query("SELECT id, name, affiliate_network_id FROM affiliate.offers WHERE status = 'Activated' ORDER BY RANDOM() LIMIT 1");
$offer = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$offer) { echo json_encode(['success' => false, 'message' => 'No active offers']); exit; }
$stmt2 = $db->query("SELECT id FROM production.mta_processes WHERE status = 'Completed' ORDER BY id DESC LIMIT 1");
$process = $stmt2->fetch(PDO::FETCH_ASSOC);
$processId = $process ? $process['id'] : 999;
$stmtId = $db->query("SELECT COALESCE(MAX(id), 0) + 1 FROM actions.clicks");
$nextId = $stmtId->fetchColumn();
$locations = [['US', 'United States', 'New York', 'New York City'], ['DE', 'Germany', 'Bavaria', 'Munich'], ['FR', 'France', 'Ile-de-France', 'Paris'], ['GB', 'United Kingdom', 'England', 'London'], ['SE', 'Sweden', 'Stockholm', 'Stockholm'], ['MA', 'Morocco', 'Casablanca-Settat', 'Casablanca'], ['ES', 'Spain', 'Madrid', 'Madrid'], ['IT', 'Italy', 'Lazio', 'Rome']];
$loc = $locations[rand(0, count($locations)-1)];
$browsers = ['Google Chrome', 'Firefox', 'Safari', 'Edge'];
$devices = ['Computer', 'Mobile', 'Tablet'];
$ips = ['45.'.rand(1,255).'.'.rand(1,255).'.'.rand(1,255), '92.'.rand(1,255).'.'.rand(1,255).'.'.rand(1,255)];
$insert = $db->prepare("INSERT INTO actions.clicks (id, unique_token, process_id, process_type, user_production_id, user_full_name, vmta_id, smtp_user_id, affiliate_network_id, offer_production_id, list_id, client_id, action_time, process_updated, agent, action_ip, country_code, country, region, city, device_type, device_name, operating_system, browser_name, browser_version) VALUES (?, ?, ?, 'md', 1, 'Simulated User', ?, 0, ?, ?, 0, 0, NOW(), false, 'Mozilla/5.0', ?, ?, ?, ?, ?, ?, 'PC', 'Windows 10.0', ?, '120.0')");
$insert->execute([$nextId, $processId.rand(1000,9999), $processId, rand(1,10), $offer['affiliate_network_id'] ?? 1, $offer['id'], $ips[rand(0,1)], $loc[0], $loc[1], $loc[2], $loc[3], $devices[rand(0,2)], $browsers[rand(0,3)]]);
echo json_encode(['success' => true, 'message' => 'Click generated!', 'offer_id' => $offer['id'], 'offer_name' => $offer['name'], 'location' => $loc[3].', '.$loc[1], 'click_id' => $nextId]);
} catch (Exception $e) { echo json_encode(['success' => false, 'message' => $e->getMessage()]); }
exit;
}
// Recent activity
if (isset($_GET['action']) && $_GET['action'] === 'recent_activity') {
header('Content-Type: application/json');
try {
$db = new PDO('pgsql:host=localhost;dbname=adx_system', 'admin', 'admin123');
$stmt = $db->query("SELECT id, action_time, offer_production_id as offer_id, process_id, country, city, device_type, browser_name, action_ip FROM actions.clicks ORDER BY action_time DESC LIMIT 15");
echo json_encode(['success' => true, 'clicks' => $stmt->fetchAll(PDO::FETCH_ASSOC)]);
} catch (Exception $e) { echo json_encode(['success' => false, 'message' => $e->getMessage()]); }
exit;
}
// Repair actions
if (isset($_GET['action']) && $_GET['action'] === 'repair') {
header('Content-Type: application/json');
$type = $_POST['type'] ?? '';
switch ($type) {
case 'tracking_server': $output = shell_exec("sshpass -p '{$tracking_ssh_pass}' ssh -o StrictHostKeyChecking=no ubuntu@{$tracking_ip} 'sudo systemctl restart nginx php8.1-fpm' 2>&1"); echo json_encode(['success' => true, 'message' => 'Nginx restarted', 'output' => $output]); break;
case 'wevads_api': shell_exec('sudo systemctl restart apache2'); echo json_encode(['success' => true, 'message' => 'Apache restarted']); break;
case 'database': shell_exec('sudo systemctl restart postgresql'); echo json_encode(['success' => true, 'message' => 'PostgreSQL restarted']); break;
case 'e2e_click': $output = shell_exec("sshpass -p '{$tracking_ssh_pass}' ssh -o StrictHostKeyChecking=no ubuntu@{$tracking_ip} 'tail -20 /var/log/nginx/error.log' 2>&1"); echo json_encode(['success' => true, 'message' => 'Logs', 'output' => $output]); break;
case 's3_bucket': echo json_encode(['success' => true, 'message' => 'Check AWS Console', 'url' => 'https://s3.console.aws.amazon.com/']); break;
default: echo json_encode(['success' => false, 'message' => 'Unknown']);
}
exit;
}
// Diagnose
if (isset($_GET['action']) && $_GET['action'] === 'diagnose') {
header('Content-Type: application/json');
$results = ['timestamp' => date('Y-m-d H:i:s'), 'overall_status' => 'ok', 'checks' => []];
$ch = curl_init(); curl_setopt_array($ch, [CURLOPT_URL => "http://{$tracking_ip}/", CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10]); curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
$results['checks']['tracking_server'] = ['name' => 'Tracking Server', 'status' => $code > 0 ? 'ok' : 'error', 'message' => "HTTP {$code}", 'repair' => 'tracking_server', 'repair_label' => 'Restart Nginx'];
$ch = curl_init(); curl_setopt_array($ch, [CURLOPT_URL => $wevads_api, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10, CURLOPT_POST => true, CURLOPT_POSTFIELDS => http_build_query(['controller' => 'Tracking', 'action' => 'getAdxRtl', 'parameters' => []])]); $apiResponse = curl_exec($ch); $apiCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
$results['checks']['wevads_api'] = ['name' => 'WEVAL API', 'status' => ($apiCode == 200 && json_decode($apiResponse)) ? 'ok' : 'error', 'message' => "HTTP {$apiCode}", 'repair' => 'wevads_api', 'repair_label' => 'Restart Apache'];
try { $db = new PDO('pgsql:host=localhost;dbname=adx_system', 'admin', 'admin123'); $stmt = $db->query("SELECT COUNT(*) FROM actions.clicks WHERE action_time > NOW() - INTERVAL '24 hours'"); $results['checks']['database'] = ['name' => 'Database', 'status' => 'ok', 'message' => $stmt->fetchColumn().' clicks/24h', 'repair' => 'database', 'repair_label' => 'Restart PostgreSQL']; } catch (Exception $e) { $results['checks']['database'] = ['name' => 'Database', 'status' => 'error', 'message' => 'Failed', 'repair' => 'database', 'repair_label' => 'Restart PostgreSQL']; }
$ch = curl_init(); curl_setopt_array($ch, [CURLOPT_URL => "http://{$tracking_ip}/cl/999_md/1/1/6/0/0", CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 15]); $e2eResponse = curl_exec($ch); $e2eCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
$results['checks']['e2e_click'] = ['name' => 'E2E Click', 'status' => ($e2eCode == 200 && strlen($e2eResponse) > 10) ? 'ok' : 'warning', 'message' => "HTTP {$e2eCode}", 'repair' => 'e2e_click', 'repair_label' => 'View Logs'];
$ch = curl_init(); curl_setopt_array($ch, [CURLOPT_URL => "https://ff6970ea5261c1fb821273.s3.eu-north-1.amazonaws.com/", CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10, CURLOPT_NOBODY => true]); curl_exec($ch); $s3Code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
$results['checks']['s3_bucket'] = ['name' => 'S3 Bucket', 'status' => ($s3Code > 0 && $s3Code < 500) ? 'ok' : 'error', 'message' => "HTTP {$s3Code}", 'repair' => 's3_bucket', 'repair_label' => 'Check AWS'];
foreach ($results['checks'] as $c) { if ($c['status'] === 'error') $results['overall_status'] = 'error'; }
echo json_encode($results);
exit;
}
// Get test URL
if (isset($_GET['action']) && $_GET['action'] === 'get_test_url') {
header('Content-Type: application/json');
try {
$db = new PDO('pgsql:host=localhost;dbname=adx_system', 'admin', 'admin123');
$stmt = $db->query("SELECT id, name FROM affiliate.offers WHERE status = 'Activated' ORDER BY id LIMIT 1");
$offer = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt2 = $db->query("SELECT id FROM production.mta_processes WHERE status = 'Completed' ORDER BY id DESC LIMIT 1");
$process = $stmt2->fetch(PDO::FETCH_ASSOC);
$processId = $process ? $process['id'] : 999;
$url = "http://{$tracking_ip}/cl/{$processId}_md/1/1/{$offer['id']}/0/0";
echo json_encode(['success' => true, 'url' => $url, 'offer_id' => $offer['id'], 'offer_name' => $offer['name']]);
} catch (Exception $e) { echo json_encode(['success' => false]); }
exit;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tracking Diagnostic - WEVAL</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
<style>
*{margin:0;padding:0;box-sizing:border-box}body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;background:#f8fafc;min-height:100vh;padding:20px}.container{max-width:1100px;margin:0 auto}.back-link{display:inline-flex;align-items:center;gap:8px;color:#0ea5e9;text-decoration:none;margin-bottom:20px;font-weight:500}
.monitoring-bar{background:#1e293b;border-radius:12px;padding:15px 20px;margin-bottom:20px;display:flex;gap:15px;flex-wrap:wrap}
.monitor-section{flex:1;min-width:200px;background:rgba(255,255,255,.05);border-radius:8px;padding:12px 15px}
.monitor-section-title{font-size:11px;text-transform:uppercase;color:#64748b;font-weight:600;margin-bottom:10px;display:flex;align-items:center;gap:6px}
.monitor-section-title .status-dot{width:8px;height:8px;border-radius:50%;margin-left:auto}
.monitor-section-title .status-dot.online{background:#10b981;box-shadow:0 0 8px #10b981}
.monitor-section-title .status-dot.offline{background:#ef4444}
.monitor-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
.monitor-item{text-align:center}
.monitor-value{font-size:18px;font-weight:700;color:#fff}
.monitor-value.good{color:#10b981}.monitor-value.warn{color:#f59e0b}.monitor-value.bad{color:#ef4444}
.monitor-label{font-size:10px;color:#94a3b8}
.monitor-bar{height:4px;background:#334155;border-radius:2px;margin-top:4px}
.monitor-bar-fill{height:100%;border-radius:2px;transition:width .5s}
.monitor-bar-fill.good{background:#10b981}.monitor-bar-fill.warn{background:#f59e0b}.monitor-bar-fill.bad{background:#ef4444}
.response-time-display{display:flex;align-items:center;justify-content:center;gap:8px}
.response-time-display .value{font-size:28px;font-weight:700;color:#10b981}
.response-time-display .unit{font-size:14px;color:#64748b}
.header{background:linear-gradient(135deg,#0ea5e9 0%,#0284c7 100%);border-radius:16px;padding:30px;margin-bottom:25px;color:#fff;display:flex;justify-content:space-between;align-items:center}.header-left h1{font-size:28px;margin-bottom:10px}.status-indicator{text-align:center}.status-circle{width:100px;height:100px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:40px;margin-bottom:10px}.status-circle.ok{background:#10b981}.status-circle.error{background:#ef4444}.status-circle.loading{background:#64748b;animation:pulse 1s infinite}@keyframes pulse{0%,100%{opacity:1}50%{opacity:.5}}
.card{background:#fff;border-radius:12px;box-shadow:0 2px 8px rgba(0,0,0,.06);margin-bottom:20px;overflow:hidden}.card-header{background:#f8fafc;border-bottom:1px solid #e2e8f0;padding:18px 20px;display:flex;justify-content:space-between;align-items:center}.card-header h3{font-size:16px;color:#1e293b;display:flex;align-items:center;gap:10px}.card-body{padding:20px}
.check-item{display:flex;align-items:center;justify-content:space-between;padding:16px;border-bottom:1px solid #f1f5f9;gap:10px}.check-item:last-child{border-bottom:none}.check-item .check-info{display:flex;align-items:center;gap:15px;flex:1}.check-item .check-icon{width:40px;height:40px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:18px}.check-item .check-icon.ok{background:#d1fae5;color:#10b981}.check-item .check-icon.error{background:#fee2e2;color:#ef4444}.check-item .check-icon.warning{background:#fef3c7;color:#f59e0b}.check-item .check-name{font-weight:600;color:#1e293b}.check-item .check-message{font-size:13px;color:#64748b}.check-item .check-actions{display:flex;align-items:center;gap:8px}.check-item .check-status{padding:6px 12px;border-radius:20px;font-size:12px;font-weight:600}.check-item .check-status.ok{background:#d1fae5;color:#065f46}.check-item .check-status.error{background:#fee2e2;color:#991b1b}.check-item .check-status.warning{background:#fef3c7;color:#92400e}
.btn{display:inline-flex;align-items:center;gap:8px;padding:12px 24px;border-radius:8px;font-weight:600;font-size:14px;cursor:pointer;border:none;background:linear-gradient(135deg,#0ea5e9 0%,#0284c7 100%);color:#fff;transition:all .2s}.btn:hover{transform:translateY(-1px)}.btn:disabled{opacity:.6}.btn-success{background:linear-gradient(135deg,#10b981 0%,#059669 100%)}.btn-sm{padding:6px 12px;font-size:12px;border-radius:6px}.btn-repair{background:linear-gradient(135deg,#f59e0b 0%,#d97706 100%)}.btn-purple{background:linear-gradient(135deg,#8b5cf6 0%,#7c3aed 100%)}
.summary-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:15px;margin-bottom:25px}.summary-card{background:#fff;border-radius:10px;padding:20px;text-align:center}.summary-card .number{font-size:32px;font-weight:700;margin-bottom:5px}.summary-card .number.green{color:#10b981}.summary-card .number.red{color:#ef4444}.summary-card .label{color:#64748b;font-size:13px}
.simulate-section{background:linear-gradient(135deg,#faf5ff 0%,#f3e8ff 100%);border:2px solid #a855f7;border-radius:12px;padding:20px;margin-bottom:20px}.simulate-header{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:15px}.simulate-header h3{font-size:16px;color:#7c3aed;display:flex;align-items:center;gap:10px}.simulate-result{background:#fff;border-radius:8px;padding:15px;margin-top:15px;display:none}.simulate-result.show{display:block}.simulate-result.success{border-left:4px solid #10b981}.simulate-result.error{border-left:4px solid #ef4444}
.activity-list{max-height:300px;overflow-y:auto}.activity-item{display:flex;align-items:center;gap:12px;padding:12px;border-bottom:1px solid #f1f5f9;transition:background .2s}.activity-item:hover{background:#f8fafc}.activity-item:last-child{border-bottom:none}.activity-icon{width:36px;height:36px;border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:14px}.activity-icon.computer{background:#3b82f6;color:#fff}.activity-icon.mobile{background:#10b981;color:#fff}.activity-icon.tablet{background:#f59e0b;color:#fff}.activity-content{flex:1;min-width:0}.activity-title{font-size:13px;font-weight:600;color:#1e293b}.activity-meta{font-size:11px;color:#94a3b8;display:flex;gap:10px;margin-top:2px}.activity-time{font-size:11px;color:#64748b}.new-click{animation:glow 2s ease-out}@keyframes glow{0%{background:#d1fae5}100%{background:transparent}}
.test-box{background:#f0fdf4;border:2px solid #10b981;border-radius:12px;padding:20px;text-align:center}.test-box h4{color:#065f46;margin-bottom:10px}.test-box p{color:#059669;font-size:14px;margin-bottom:15px}
.modal{display:none;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);z-index:1000;align-items:center;justify-content:center}.modal.show{display:flex}.modal-content{background:#fff;border-radius:12px;padding:25px;max-width:500px;width:90%}.modal-header{display:flex;justify-content:space-between;margin-bottom:15px}.modal-close{background:none;border:none;font-size:24px;cursor:pointer;color:#64748b}.modal-output{background:#1e293b;color:#10b981;padding:15px;border-radius:8px;font-family:monospace;font-size:12px;margin-top:15px;white-space:pre-wrap;max-height:300px;overflow-y:auto}
</style>
</head>
<body>
<div class="container">
<a href="<?php echo $base_url; ?>/tracking-dashboard.php" class="back-link"><i class="fa fa-arrow-left"></i> Back to Dashboard</a>
<!-- Monitoring Bar -->
<div class="monitoring-bar">
<div class="monitor-section">
<div class="monitor-section-title"><i class="fa fa-server"></i> WEVAL Server</div>
<div class="monitor-grid">
<div class="monitor-item"><div class="monitor-value" id="wevads-cpu">-</div><div class="monitor-label">CPU</div><div class="monitor-bar"><div class="monitor-bar-fill good" id="wevads-cpu-bar" style="width:0%"></div></div></div>
<div class="monitor-item"><div class="monitor-value" id="wevads-mem">-</div><div class="monitor-label">Memory</div><div class="monitor-bar"><div class="monitor-bar-fill good" id="wevads-mem-bar" style="width:0%"></div></div></div>
<div class="monitor-item"><div class="monitor-value" id="wevads-disk">-</div><div class="monitor-label">Disk</div><div class="monitor-bar"><div class="monitor-bar-fill good" id="wevads-disk-bar" style="width:0%"></div></div></div>
</div>
</div>
<div class="monitor-section">
<div class="monitor-section-title"><i class="fa fa-satellite-dish"></i> Tracking<span class="status-dot" id="tracking-status-dot"></span></div>
<div class="monitor-grid">
<div class="monitor-item"><div class="monitor-value" id="tracking-cpu">-</div><div class="monitor-label">CPU</div><div class="monitor-bar"><div class="monitor-bar-fill good" id="tracking-cpu-bar" style="width:0%"></div></div></div>
<div class="monitor-item"><div class="monitor-value" id="tracking-mem">-</div><div class="monitor-label">Memory</div><div class="monitor-bar"><div class="monitor-bar-fill good" id="tracking-mem-bar" style="width:0%"></div></div></div>
<div class="monitor-item"><div class="monitor-value" id="tracking-disk">-</div><div class="monitor-label">Disk</div><div class="monitor-bar"><div class="monitor-bar-fill good" id="tracking-disk-bar" style="width:0%"></div></div></div>
</div>
</div>
<div class="monitor-section" style="max-width:180px">
<div class="monitor-section-title"><i class="fa fa-bolt"></i> Response</div>
<div class="response-time-display"><span class="value" id="tracking-response">-</span><span class="unit">ms</span></div>
</div>
</div>
<!-- Simulate Click -->
<div class="simulate-section">
<div class="simulate-header">
<h3><i class="fa fa-mouse-pointer"></i> Simulate Click</h3>
<button class="btn btn-purple" onclick="generateClick()" id="gen-btn"><i class="fa fa-bolt"></i> Generate Click</button>
</div>
<p style="color:#7c3aed;font-size:13px;margin-top:10px">Inserts a real click with random location into the database</p>
<div class="simulate-result" id="gen-result"></div>
</div>
<!-- Recent Activity -->
<div class="card">
<div class="card-header"><h3><i class="fa fa-history"></i> Recent Clicks</h3><button class="btn btn-sm" onclick="loadActivity()"><i class="fa fa-sync"></i></button></div>
<div class="card-body"><div class="activity-list" id="activity-list"><div style="text-align:center;padding:20px;color:#94a3b8"><i class="fa fa-spinner fa-spin"></i> Loading...</div></div></div>
</div>
<!-- Test Redirect -->
<div class="card">
<div class="card-header"><h3><i class="fa fa-external-link-alt"></i> Test Redirect</h3></div>
<div class="card-body">
<div class="test-box">
<h4><i class="fa fa-link"></i> Open Tracking Link</h4>
<p>Click to open a tracking URL and see where it redirects (no click recorded)</p>
<button class="btn btn-success" onclick="testRedirect()"><i class="fa fa-external-link-alt"></i> Test Redirect</button>
</div>
</div>
</div>
<!-- Header + System Checks -->
<div class="header">
<div class="header-left"><h1><i class="fa fa-heartbeat"></i> System Diagnostic</h1><p>Health check with repair tools</p></div>
<div class="status-indicator"><div class="status-circle loading" id="overall-status"><i class="fa fa-spinner fa-spin"></i></div><div class="status-text" id="overall-text">Checking...</div></div>
</div>
<div class="summary-grid">
<div class="summary-card"><div class="number green" id="count-ok">-</div><div class="label">Passed</div></div>
<div class="summary-card"><div class="number red" id="count-error">-</div><div class="label">Errors</div></div>
<div class="summary-card"><div class="number" id="count-total" style="color:#0ea5e9">-</div><div class="label">Total</div></div>
<div class="summary-card"><div class="number" id="response-time" style="color:#64748b">-</div><div class="label">Diag Time</div></div>
</div>
<div class="card">
<div class="card-header"><h3><i class="fa fa-clipboard-check"></i> System Checks</h3><button class="btn" onclick="runDiagnostic()" id="run-btn"><i class="fa fa-play"></i> Run All</button></div>
<div class="card-body" id="checks-container"><div class="check-item"><div class="check-info"><div class="check-icon" style="background:#f1f5f9;color:#94a3b8"><i class="fa fa-spinner fa-spin"></i></div><div><div class="check-name">Loading...</div></div></div></div></div>
</div>
</div>
<div class="modal" id="repairModal">
<div class="modal-content">
<div class="modal-header"><h4 id="modal-title">Output</h4><button class="modal-close" onclick="closeModal()">&times;</button></div>
<div class="modal-body"><p id="modal-message"></p><div class="modal-output" id="modal-output"></div></div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
var lastClickId = 0;
var countryFlags = {'United States':'🇺🇸','Germany':'🇩🇪','France':'🇫🇷','United Kingdom':'🇬🇧','Sweden':'🇸🇪','Morocco':'🇲🇦','Spain':'🇪🇸','Italy':'🇮🇹'};
function getBarClass(v){return v<60?'good':v<85?'warn':'bad'}
function updateMetrics(){
$.get('?action=metrics',function(d){
['cpu','mem','disk'].forEach(function(m){
$('#wevads-'+m).text(d.wevads[m]+'%').removeClass('good warn bad').addClass(getBarClass(d.wevads[m]));
$('#wevads-'+m+'-bar').css('width',d.wevads[m]+'%').removeClass('good warn bad').addClass(getBarClass(d.wevads[m]));
$('#tracking-'+m).text(d.tracking[m]+'%').removeClass('good warn bad').addClass(getBarClass(d.tracking[m]));
$('#tracking-'+m+'-bar').css('width',d.tracking[m]+'%').removeClass('good warn bad').addClass(getBarClass(d.tracking[m]));
});
var rt=d.tracking.response_time;
$('#tracking-response').text(rt).removeClass('good warn bad').addClass(rt<200?'good':rt<500?'warn':'bad');
$('#tracking-status-dot').removeClass('online offline').addClass(d.tracking.status);
});
}
function generateClick(){
$('#gen-btn').prop('disabled',true).html('<i class="fa fa-spinner fa-spin"></i>');
$('#gen-result').removeClass('show success error');
$.get('?action=generate_click',function(d){
if(d.success){
$('#gen-result').addClass('show success').html('<strong style="color:#065f46"><i class="fa fa-check"></i> Click #'+d.click_id+' generated!</strong><br><span style="color:#64748b">Offer: '+d.offer_name+' • Location: '+d.location+'</span>');
setTimeout(loadActivity,300);
}else{
$('#gen-result').addClass('show error').html('<strong style="color:#991b1b"><i class="fa fa-times"></i> '+d.message+'</strong>');
}
$('#gen-btn').prop('disabled',false).html('<i class="fa fa-bolt"></i> Generate Click');
});
}
function loadActivity(){
$.get('?action=recent_activity',function(d){
if(d.success && d.clicks.length>0){
var h='';
d.clicks.forEach(function(c){
var isNew=lastClickId>0&&c.id>lastClickId;
var time=new Date(c.action_time).toLocaleTimeString();
var flag=countryFlags[c.country]||'🌍';
var iconClass=(c.device_type||'Computer').toLowerCase();
var icon=iconClass==='mobile'?'fa-mobile-alt':iconClass==='tablet'?'fa-tablet-alt':'fa-desktop';
h+='<div class="activity-item'+(isNew?' new-click':'')+'"><div class="activity-icon '+iconClass+'"><i class="fa '+icon+'"></i></div><div class="activity-content"><div class="activity-title">'+flag+' Offer #'+c.offer_id+' - '+(c.city||'Unknown')+', '+(c.country||'Unknown')+'</div><div class="activity-meta"><span>'+c.browser_name+'</span><span>Process #'+c.process_id+'</span><span>'+c.action_ip+'</span></div></div><div class="activity-time">'+time+'</div></div>';
});
$('#activity-list').html(h);
if(d.clicks.length>0)lastClickId=d.clicks[0].id;
}else{
$('#activity-list').html('<div style="text-align:center;padding:20px;color:#94a3b8"><i class="fa fa-inbox"></i> No clicks</div>');
}
});
}
function testRedirect(){
$.get('?action=get_test_url',function(d){
if(d.success)window.open(d.url,'_blank');
});
}
function runDiagnostic(){
var start=Date.now();
$('#run-btn').prop('disabled',true).html('<i class="fa fa-spinner fa-spin"></i>');
$('#overall-status').removeClass('ok error').addClass('loading').html('<i class="fa fa-spinner fa-spin"></i>');
$.get('?action=diagnose',function(d){
var elapsed=Date.now()-start;$('#response-time').text(elapsed+'ms');
var h='',ok=0,err=0;
for(var k in d.checks){
var c=d.checks[k];
var icon=c.status==='ok'?'fa-check':c.status==='error'?'fa-times':'fa-exclamation';
if(c.status==='ok')ok++;else err++;
h+='<div class="check-item"><div class="check-info"><div class="check-icon '+c.status+'"><i class="fa '+icon+'"></i></div><div><div class="check-name">'+c.name+'</div><div class="check-message">'+c.message+'</div></div></div><div class="check-actions"><button class="btn btn-sm btn-repair" onclick="repair(\''+c.repair+'\',\''+c.repair_label+'\')"><i class="fa fa-wrench"></i> '+c.repair_label+'</button><span class="check-status '+c.status+'">'+c.status+'</span></div></div>';
}
$('#checks-container').html(h);$('#count-ok').text(ok);$('#count-error').text(err);$('#count-total').text(ok+err);
$('#overall-status').removeClass('loading').addClass(d.overall_status).html('<i class="fa '+(d.overall_status==='ok'?'fa-check':'fa-times')+'"></i>');
$('#overall-text').text(d.overall_status==='ok'?'All Systems Go':'Issues Found');
$('#run-btn').prop('disabled',false).html('<i class="fa fa-play"></i> Run All');
});
}
function repair(t,l){
$('#modal-title').text(l);$('#modal-message').html('<i class="fa fa-spinner fa-spin"></i> Running...');$('#modal-output').hide();$('#repairModal').addClass('show');
$.post('?action=repair',{type:t},function(d){
$('#modal-message').html((d.success?'<i class="fa fa-check-circle" style="color:#10b981"></i> ':'<i class="fa fa-times-circle" style="color:#ef4444"></i> ')+d.message);
if(d.output)$('#modal-output').text(d.output).show();
if(d.url)$('#modal-message').append('<br><br><a href="'+d.url+'" target="_blank" class="btn btn-sm">Open AWS</a>');
setTimeout(runDiagnostic,2000);
});
}
function closeModal(){$('#repairModal').removeClass('show')}
$('#repairModal').click(function(e){if(e.target===this)closeModal()});
$(document).ready(function(){
updateMetrics();loadActivity();runDiagnostic();
setInterval(updateMetrics,10000);
setInterval(loadActivity,5000);
});
</script>
<?php include("includes/chatbot-widget.php"); ?>
</body>
</html>