admin_fetch_user_stats($pdo),
'videos' => admin_fetch_video_stats($pdo),
'streams' => admin_fetch_stream_stats($pdo),
'totalViews' => admin_fetch_total_views($pdo),
'health' => admin_fetch_system_health($pdo),
]);
break;
case 'activity':
echo json_encode(['activity' => admin_fetch_recent_activity($pdo, 12)]);
break;
case 'pending':
echo json_encode(['pending' => admin_fetch_pending_videos($pdo, 10)]);
break;
default:
http_response_code(400);
echo json_encode(['error' => 'Unknown action']);
}
exit;
}
$userStats = admin_fetch_user_stats($pdo);
$videoStats = admin_fetch_video_stats($pdo);
$streamStats = admin_fetch_stream_stats($pdo);
$totalViews = admin_fetch_total_views($pdo);
$health = admin_fetch_system_health($pdo);
$recentActivity = admin_fetch_recent_activity($pdo);
$pendingContent = admin_fetch_pending_videos($pdo);
$quickActions = [
['label' => 'User Management', 'description' => 'Review members, roles, and status', 'icon' => '👥', 'url' => '/admin_users.php'],
['label' => 'Content Moderation', 'description' => 'Approve, reject, or feature uploads', 'icon' => '🎬', 'url' => '/admin_content_management.php'],
['label' => 'Token Economy', 'description' => 'Monitor purchases and balances', 'icon' => '💰', 'url' => '/admin_token_dashboard.php'],
['label' => 'Background Jobs', 'description' => 'Track queue throughput', 'icon' => '⚙', 'url' => '/f_modules/m_backend/queue_management.php'],
['label' => 'System Logs', 'description' => 'Audit platform health and errors', 'icon' => '📝', 'url' => '/f_modules/m_backend/log_viewer.php'],
['label' => 'Security Center', 'description' => 'Manage bans, fingerprints, and IPs', 'icon' => '🔐', 'url' => '/f_modules/m_backend/ip_management.php'],
];
admin_page_start('Platform Dashboard', 'dashboard');
?>
👥
Total Users
= admin_format_number($userStats['total']) ?>
= admin_format_number($userStats['today']) ?> today
= admin_format_number($userStats['active']) ?> active
🎬
Video Library
= admin_format_number($videoStats['total']) ?>
= admin_format_number($videoStats['approved']) ?> approved
= admin_format_number($videoStats['pending']) ?> awaiting review
📡
Live Streams
= admin_format_number($streamStats['total']) ?>
= admin_format_number($streamStats['active']) ?> live now
= admin_format_number($streamStats['today']) ?> started today
📈
Total Views
= admin_format_number($totalViews) ?>
Platform-wide engagement this week
No recent activity recorded.
🧭
= admin_escape($activity['request_uri']) ?>
= admin_escape($activity['ip_address']) ?> · = admin_format_datetime($activity['timestamp']) ?>
= admin_escape($activity['user_agent'] ?? 'Unknown client') ?>
$status): ?>
'success',
'warning' => 'warning',
'error' => 'danger',
default => 'muted',
};
$iconEntity = [
'success' => '✅',
'warning' => '⚠',
'danger' => '❌',
'muted' => 'ℹ',
][$state];
?>
= $iconEntity ?>
= admin_escape(ucfirst($key)) ?>
= admin_escape($status['details'] ?? 'No data') ?>
All submissions are currently reviewed.
| Title |
User |
Uploaded |
Status |
|
| = admin_escape($item['file_title']) ?> |
#= admin_escape((string) $item['usr_id']) ?> |
= admin_format_datetime($item['upload_date']) ?> |
= admin_escape(ucfirst($item['processing_status'] ?? 'pending')) ?>
|
Review
|
data.users.total,
'metric-users-today': data => data.users.today,
'metric-users-active': data => data.users.active,
'metric-videos-total': data => data.videos.total,
'metric-videos-approved': data => data.videos.approved,
'metric-videos-pending': data => data.videos.pending,
'metric-streams-total': data => data.streams.total,
'metric-streams-active': data => data.streams.active,
'metric-streams-today': data => data.streams.today,
'metric-views-total': data => data.totalViews,
};
const healthList = document.getElementById('health-list');
const activityList = document.getElementById('activity-list');
const pendingList = document.getElementById('pending-list');
const refreshButton = document.getElementById('refresh-button');
const activitySpinner = document.getElementById('activity-spinner');
function renderHealth(health) {
if (!healthList) return;
const fragments = [];
const icons = { success: '\u2705', warning: '\u26A0', danger: '\u274C', muted: '\u2139' };
for (const [key, status] of Object.entries(health)) {
const state = status.status === 'healthy' ? 'success'
: status.status === 'warning' ? 'warning'
: status.status === 'error' ? 'danger'
: 'muted';
fragments.push(`
${icons[state]}
${key.charAt(0).toUpperCase() + key.slice(1)}
${status.details ?? 'No data'}
`);
}
healthList.innerHTML = fragments.join('');
}
function renderActivity(items) {
if (!activityList) return;
if (!items || !items.length) {
activityList.innerHTML = 'No recent activity recorded.
';
return;
}
activityList.innerHTML = items.map(item => `
🧭
${item.request_uri ?? '/'}
${item.ip_address ?? 'Unknown IP'} · ${item.timestamp ?? ''}
${item.user_agent ?? 'Unknown client'}
`).join('');
}
function renderPending(items) {
if (!pendingList) return;
if (!items || !items.length) {
pendingList.innerHTML = 'All submissions are currently reviewed.
';
return;
}
pendingList.innerHTML = `
| Title |
User |
Uploaded |
Status |
|
${items.map(item => `
| ${item.file_title ?? 'Untitled'} |
#${item.usr_id ?? 'N/A'} |
${item.upload_date ?? ''} |
${(item.processing_status ?? 'pending').toUpperCase()} |
Review |
`).join('')}
`;
}
async function refreshData() {
if (activitySpinner) activitySpinner.hidden = false;
try {
const [statsRes, activityRes, pendingRes] = await Promise.all([
fetch('?action=stats').then(r => r.json()),
fetch('?action=activity').then(r => r.json()),
fetch('?action=pending').then(r => r.json()),
]);
Object.entries(metricMap).forEach(([id, getter]) => {
const el = document.getElementById(id);
if (el) {
const value = getter(statsRes);
el.textContent = Number.isFinite(value) ? value.toLocaleString() : value;
}
});
renderHealth(statsRes.health);
renderActivity(activityRes.activity);
renderPending(pendingRes.pending);
} catch (error) {
console.error('Failed to refresh dashboard data', error);
} finally {
if (activitySpinner) activitySpinner.hidden = true;
}
}
if (refreshButton) {
refreshButton.addEventListener('click', refreshData);
}
setInterval(refreshData, 30000);
JS;
admin_page_end($script);