T.ME/BIBIL_0DAY
CasperSecurity


Server : Apache/2
System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64
User : gositeme ( 1004)
PHP Version : 8.2.29
Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname
Directory :  /home/gositeme/domains/soundstudiopro.com/private_html/admin_includes/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/soundstudiopro.com/private_html/admin_includes/online_users.php
<?php
// Online Users Tab
// This file displays all currently online users with detailed information

// First, ensure users table has last_activity column
try {
    $columns = $pdo->query("SHOW COLUMNS FROM users LIKE 'last_activity'")->fetchAll();
    if (empty($columns)) {
        $pdo->exec("ALTER TABLE users ADD COLUMN last_activity TIMESTAMP NULL DEFAULT NULL");
        $pdo->exec("CREATE INDEX idx_users_last_activity ON users(last_activity)");
    }
} catch (Exception $e) {
    // Column might already exist or table doesn't exist, ignore error
    error_log("Could not add last_activity column: " . $e->getMessage());
}

// Get currently online users (active within last 15 minutes)
// Try multiple sources: last_activity column, page_visits, then user_login_history
try {
    // First, check if page_visits table exists and has data
    $pageVisitsExists = false;
    try {
        $pdo->query("SELECT 1 FROM page_visits LIMIT 1");
        $pageVisitsExists = true;
    } catch (Exception $e) {
        // Table doesn't exist or has no data
    }
    
    // First, try using last_activity column in users table (most reliable)
    $userColumns = $pdo->query("SHOW COLUMNS FROM users")->fetchAll(PDO::FETCH_COLUMN);
    $hasLastActivity = in_array('last_activity', $userColumns);
    
    if ($hasLastActivity) {
        // Get users with recent last_activity
        try {
            $online_users = $pdo->query("
            SELECT DISTINCT
                u.id,
                u.name,
                u.email,
                u.plan,
                u.is_admin,
                u.credits,
                u.created_at as account_created,
                u.last_activity,
                COALESCE(
                    (SELECT MAX(pv.ip_address) FROM page_visits pv WHERE pv.user_id = u.id AND pv.visit_time >= DATE_SUB(NOW(), INTERVAL 1 HOUR)),
                    (SELECT MAX(ulh.ip_address) FROM user_login_history ulh WHERE ulh.user_id = u.id),
                    'Unknown'
                ) as last_ip,
                COALESCE(
                    (SELECT MAX(pv.country) FROM page_visits pv WHERE pv.user_id = u.id AND pv.visit_time >= DATE_SUB(NOW(), INTERVAL 1 HOUR)),
                    (SELECT MAX(ulh.country) FROM user_login_history ulh WHERE ulh.user_id = u.id),
                    NULL
                ) as country,
                COALESCE(
                    (SELECT MAX(pv.city) FROM page_visits pv WHERE pv.user_id = u.id AND pv.visit_time >= DATE_SUB(NOW(), INTERVAL 1 HOUR)),
                    (SELECT MAX(ulh.city) FROM user_login_history ulh WHERE ulh.user_id = u.id),
                    NULL
                ) as city,
                0 as login_count_today,
                TIMESTAMPDIFF(MINUTE, u.last_activity, NOW()) as minutes_ago,
                (SELECT pv.page_url FROM page_visits pv WHERE pv.user_id = u.id ORDER BY pv.visit_time DESC LIMIT 1) as current_page
            FROM users u
            WHERE u.last_activity IS NOT NULL
            AND u.last_activity >= DATE_SUB(NOW(), INTERVAL 15 MINUTE)
            ORDER BY u.last_activity DESC
        ")->fetchAll();
        
            // Get user stats (tracks created) for last_activity users
            foreach ($online_users as &$user) {
                $stats = $pdo->prepare("
                    SELECT 
                        COUNT(*) as total_tracks,
                        COUNT(CASE WHEN status = 'complete' THEN 1 END) as completed_tracks
                    FROM music_tracks
                    WHERE user_id = ?
                ");
                $stats->execute([$user['id']]);
                $track_stats = $stats->fetch(PDO::FETCH_ASSOC);
                $user['total_tracks'] = $track_stats['total_tracks'] ?? 0;
                $user['completed_tracks'] = $track_stats['completed_tracks'] ?? 0;
            }
            unset($user);
        } catch (Exception $queryError) {
            error_log("Error in last_activity query: " . $queryError->getMessage());
            $online_users = [];
        }
        
        // If no results, try page_visits
        if (empty($online_users) && $pageVisitsExists) {
            throw new Exception("No last_activity found, trying page_visits");
        } elseif (empty($online_users)) {
            throw new Exception("No last_activity found, trying login history");
        }
    } elseif ($pageVisitsExists) {
        // Use page_visits table - this tracks actual user activity
        $online_users = $pdo->query("
            SELECT DISTINCT
                u.id,
                u.name,
                u.email,
                u.plan,
                u.is_admin,
                u.credits,
                u.created_at as account_created,
                MAX(pv.visit_time) as last_activity,
                MAX(pv.ip_address) as last_ip,
                MAX(pv.country) as country,
                MAX(pv.city) as city,
                COUNT(DISTINCT DATE(pv.visit_time)) as login_count_today,
                TIMESTAMPDIFF(MINUTE, MAX(pv.visit_time), NOW()) as minutes_ago,
                MAX(pv.page_url) as current_page
            FROM users u
            INNER JOIN page_visits pv ON u.id = pv.user_id
            WHERE pv.user_id IS NOT NULL
            AND pv.visit_time >= DATE_SUB(NOW(), INTERVAL 15 MINUTE)
            GROUP BY u.id, u.name, u.email, u.plan, u.is_admin, u.credits, u.created_at
            ORDER BY last_activity DESC
        ")->fetchAll();
        
        // Get user stats (tracks created) for page_visits users
        foreach ($online_users as &$user) {
            $stats = $pdo->prepare("
                SELECT 
                    COUNT(*) as total_tracks,
                    COUNT(CASE WHEN status = 'complete' THEN 1 END) as completed_tracks
                FROM music_tracks
                WHERE user_id = ?
            ");
            $stats->execute([$user['id']]);
            $track_stats = $stats->fetch(PDO::FETCH_ASSOC);
            $user['total_tracks'] = $track_stats['total_tracks'] ?? 0;
            $user['completed_tracks'] = $track_stats['completed_tracks'] ?? 0;
        }
        unset($user);
        
        // If no results from page_visits, try login_history as fallback
        if (empty($online_users)) {
            throw new Exception("No page visits found, trying login history");
        }
    } else {
        throw new Exception("page_visits table not available");
    }
} catch (Exception $e) {
    // Fallback to user_login_history if page_visits doesn't work
    try {
        // Check which columns exist in user_login_history table
        $historyColumns = $pdo->query("SHOW COLUMNS FROM user_login_history")->fetchAll(PDO::FETCH_COLUMN);
        $hasLoginTime = in_array('login_time', $historyColumns);
        $hasSuccess = in_array('success', $historyColumns);
        $hasLoginSuccess = in_array('login_success', $historyColumns);
        $hasCountry = in_array('country', $historyColumns);
        $hasCity = in_array('city', $historyColumns);
        
        // Determine which success column to use
        $hasSuccessColumn = $hasSuccess || $hasLoginSuccess;
        $successColumn = $hasSuccess ? 'success' : ($hasLoginSuccess ? 'login_success' : null);
        // Determine which time column to use
        $timeColumn = $hasLoginTime ? 'login_time' : 'created_at';
        
        // Build success condition
        if ($hasSuccessColumn && $successColumn) {
            $successCondition = "((ulh.{$successColumn} = 1 OR ulh.{$successColumn} = TRUE OR ulh.{$successColumn} IS TRUE) OR ulh.{$successColumn} IS NULL) AND ";
        } else {
            $successCondition = "";
        }
        
        // Get online users from login history
        $online_users = $pdo->query("
            SELECT DISTINCT
                u.id,
                u.name,
                u.email,
                u.plan,
                u.is_admin,
                u.credits,
                u.created_at as account_created,
                MAX(ulh.{$timeColumn}) as last_activity,
                MAX(ulh.ip_address) as last_ip,
                " . ($hasCountry ? "MAX(ulh.country) as country," : "NULL as country,") . "
                " . ($hasCity ? "MAX(ulh.city) as city," : "NULL as city,") . "
                COUNT(DISTINCT ulh.id) as login_count_today,
                TIMESTAMPDIFF(MINUTE, MAX(ulh.{$timeColumn}), NOW()) as minutes_ago,
                NULL as current_page
            FROM users u
            INNER JOIN user_login_history ulh ON u.id = ulh.user_id
            WHERE {$successCondition}ulh.{$timeColumn} >= DATE_SUB(NOW(), INTERVAL 15 MINUTE)
            GROUP BY u.id, u.name, u.email, u.plan, u.is_admin, u.credits, u.created_at
            ORDER BY last_activity DESC
        ")->fetchAll();
    
    // Get user stats (tracks created)
    foreach ($online_users as &$user) {
        $stats = $pdo->prepare("
            SELECT 
                COUNT(*) as total_tracks,
                COUNT(CASE WHEN status = 'complete' THEN 1 END) as completed_tracks
            FROM music_tracks
            WHERE user_id = ?
        ");
        $stats->execute([$user['id']]);
        $track_stats = $stats->fetch(PDO::FETCH_ASSOC);
        $user['total_tracks'] = $track_stats['total_tracks'] ?? 0;
        $user['completed_tracks'] = $track_stats['completed_tracks'] ?? 0;
    }
    unset($user);
    
    } catch (Exception $e) {
        error_log("Error fetching online users from login history: " . $e->getMessage());
        $online_users = [];
    }
}

// Ensure variables are always defined
if (!isset($online_users)) {
    $online_users = [];
}
$online_count = count($online_users);

// Get anonymous visitors (non-logged-in users) from page_visits
$anonymous_visitors = [];
$all_recent_visits = [];
$debug_info = [];
try {
    // Check if page_visits table exists
    $pdo->query("SELECT 1 FROM page_visits LIMIT 1");
    
    // DEBUG: Get ALL visits in last hour to see what's being recorded
    $debug_query = $pdo->query("
        SELECT 
            pv.id,
            pv.user_id,
            pv.ip_address,
            pv.page_url,
            pv.visit_time,
            NOW() as server_time
        FROM page_visits pv
        ORDER BY pv.visit_time DESC
        LIMIT 20
    ");
    $all_recent_visits = $debug_query->fetchAll(PDO::FETCH_ASSOC);
    
    // Get total count
    $count_query = $pdo->query("SELECT COUNT(*) as total FROM page_visits");
    $debug_info['total_visits'] = $count_query->fetch()['total'];
    $debug_info['server_time'] = date('Y-m-d H:i:s');
    
    // Get anonymous visitors active in last 15 minutes
    $anon_query = $pdo->query("
        SELECT 
            pv.ip_address,
            pv.country,
            pv.city,
            pv.user_agent,
            MAX(pv.visit_time) as last_activity,
            COUNT(*) as page_views,
            MAX(pv.page_url) as current_page,
            MIN(pv.visit_time) as session_start,
            TIMESTAMPDIFF(MINUTE, MAX(pv.visit_time), NOW()) as minutes_ago
        FROM page_visits pv
        WHERE (pv.user_id IS NULL OR pv.user_id = 0)
        AND pv.visit_time >= DATE_SUB(NOW(), INTERVAL 15 MINUTE)
        GROUP BY pv.ip_address, pv.country, pv.city, pv.user_agent
        ORDER BY last_activity DESC
        LIMIT 50
    ");
    $anonymous_visitors = $anon_query->fetchAll(PDO::FETCH_ASSOC);
} catch (Exception $e) {
    // page_visits table doesn't exist or query failed
    error_log("Error fetching anonymous visitors: " . $e->getMessage());
    $debug_info['error'] = $e->getMessage();
}
$anonymous_count = count($anonymous_visitors);

// Check if IP belongs to known bot ranges
function isKnownBotIP($ip) {
    // Google bot IP ranges (66.249.x.x, 64.233.x.x, etc.)
    $botRanges = [
        '66.249.',    // Googlebot
        '64.233.',    // Google
        '72.14.',     // Google
        '209.85.',    // Google
        '216.239.',   // Google
        '74.125.',    // Google
        '207.46.',    // Bingbot
        '40.77.',     // Bingbot
        '157.55.',    // Bingbot
        '199.30.',    // Apple
        '17.0.',      // Apple
    ];
    
    foreach ($botRanges as $range) {
        if (strpos($ip, $range) === 0) {
            return true;
        }
    }
    return false;
}

// Parse user agent to get browser/device info
function parseUserAgent($ua, $ip = null) {
    $browser = 'Unknown';
    $device = 'Desktop';
    $os = 'Unknown';
    
    if (empty($ua)) return ['browser' => $browser, 'device' => $device, 'os' => $os];
    
    // Detect browser
    if (preg_match('/Firefox\//i', $ua)) $browser = 'Firefox';
    elseif (preg_match('/Edg\//i', $ua)) $browser = 'Edge';
    elseif (preg_match('/Chrome\//i', $ua)) $browser = 'Chrome';
    elseif (preg_match('/Safari\//i', $ua) && !preg_match('/Chrome/i', $ua)) $browser = 'Safari';
    elseif (preg_match('/Opera|OPR\//i', $ua)) $browser = 'Opera';
    elseif (preg_match('/MSIE|Trident/i', $ua)) $browser = 'IE';
    
    // Detect device - check user agent AND IP for bots
    if (preg_match('/Mobile|Android|iPhone|iPad/i', $ua)) {
        $device = preg_match('/iPad/i', $ua) ? 'Tablet' : 'Mobile';
    }
    if (preg_match('/bot|crawl|spider|slurp|googlebot|bingbot|yandex|baidu|duckduck/i', $ua)) {
        $device = 'Bot';
    }
    // Also check IP for known bot ranges
    if ($ip && isKnownBotIP($ip)) {
        $device = 'Bot';
        $browser = 'Googlebot'; // Most common
    }
    
    // Detect OS
    if (preg_match('/Windows/i', $ua)) $os = 'Windows';
    elseif (preg_match('/Mac OS X/i', $ua)) $os = 'macOS';
    elseif (preg_match('/Linux/i', $ua)) $os = 'Linux';
    elseif (preg_match('/Android/i', $ua)) $os = 'Android';
    elseif (preg_match('/iPhone|iPad/i', $ua)) $os = 'iOS';
    
    return ['browser' => $browser, 'device' => $device, 'os' => $os];
}
?>

<style>
.online-users-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 2rem;
    padding: 1.5rem;
    background: linear-gradient(135deg, rgba(72, 187, 120, 0.1), rgba(56, 161, 105, 0.1));
    border-radius: 12px;
    border: 1px solid rgba(72, 187, 120, 0.3);
}

.online-indicator {
    display: inline-block;
    width: 12px;
    height: 12px;
    background: #48bb78;
    border-radius: 50%;
    margin-right: 0.5rem;
    animation: pulse 2s infinite;
}

@keyframes pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.5; }
}

.user-card {
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 12px;
    padding: 1.5rem;
    margin-bottom: 1rem;
    transition: all 0.3s ease;
}

.user-card:hover {
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(72, 187, 120, 0.5);
    transform: translateY(-2px);
}

.user-card-header {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 1rem;
}

.user-avatar-large {
    width: 60px;
    height: 60px;
    border-radius: 50%;
    background: linear-gradient(135deg, #48bb78, #38a169);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: bold;
    font-size: 1.5rem;
    color: white;
    position: relative;
    flex-shrink: 0;
}

.user-avatar-large::after {
    content: '';
    position: absolute;
    bottom: 2px;
    right: 2px;
    width: 16px;
    height: 16px;
    background: #48bb78;
    border: 3px solid #0f172a;
    border-radius: 50%;
}

.user-info-main {
    flex: 1;
}

.user-name-large {
    font-size: 1.6rem;
    font-weight: 700;
    color: white;
    margin-bottom: 0.3rem;
}

.user-email {
    font-size: 1.2rem;
    color: #60a5fa;
}

.user-stats-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 1rem;
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid rgba(255, 255, 255, 0.1);
}

.stat-item {
    text-align: center;
}

.stat-value {
    font-size: 1.8rem;
    font-weight: 700;
    color: #667eea;
    margin-bottom: 0.3rem;
}

.stat-label {
    font-size: 1.1rem;
    color: #a0aec0;
}

.location-info {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: #a0aec0;
    font-size: 1.2rem;
}

.refresh-btn {
    background: linear-gradient(135deg, #48bb78, #38a169);
    color: white;
    border: none;
    padding: 0.75rem 1.5rem;
    border-radius: 8px;
    font-weight: 600;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    transition: all 0.3s ease;
}

.refresh-btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(72, 187, 120, 0.4);
}

.empty-state {
    text-align: center;
    padding: 4rem 2rem;
    color: #94a3b8;
}

.empty-state i {
    font-size: 4rem;
    margin-bottom: 1rem;
    opacity: 0.5;
}

.time-ago {
    color: #48bb78;
    font-weight: 600;
    font-size: 1.2rem;
}

/* Anonymous Visitors Styles */
.anonymous-section {
    margin-top: 3rem;
    padding-top: 2rem;
    border-top: 2px solid rgba(255, 255, 255, 0.1);
}

.anonymous-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1.5rem;
    padding: 1rem 1.5rem;
    background: linear-gradient(135deg, rgba(99, 102, 241, 0.1), rgba(139, 92, 246, 0.1));
    border-radius: 12px;
    border: 1px solid rgba(99, 102, 241, 0.3);
}

.visitor-card {
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 10px;
    padding: 1rem 1.25rem;
    display: flex;
    align-items: center;
    gap: 1rem;
    transition: all 0.2s ease;
}

.visitor-card:hover {
    background: rgba(255, 255, 255, 0.06);
    border-color: rgba(99, 102, 241, 0.4);
}

.visitor-icon {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    background: linear-gradient(135deg, #6366f1, #8b5cf6);
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    font-size: 1.1rem;
    flex-shrink: 0;
}

.visitor-icon.bot {
    background: linear-gradient(135deg, #f59e0b, #d97706);
}

.visitor-info {
    flex: 1;
    min-width: 0;
}

.visitor-ip {
    font-weight: 600;
    color: #e2e8f0;
    font-size: 1rem;
    font-family: 'Consolas', monospace;
}

.visitor-location {
    color: #94a3b8;
    font-size: 0.9rem;
    margin-top: 0.2rem;
}

.visitor-meta {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
    align-items: center;
}

.visitor-badge {
    background: rgba(255, 255, 255, 0.1);
    padding: 0.25rem 0.6rem;
    border-radius: 6px;
    font-size: 0.8rem;
    color: #cbd5e1;
}

.visitor-badge.browser {
    background: rgba(59, 130, 246, 0.2);
    color: #93c5fd;
}

.visitor-badge.os {
    background: rgba(16, 185, 129, 0.2);
    color: #6ee7b7;
}

.visitor-badge.pages {
    background: rgba(249, 115, 22, 0.2);
    color: #fdba74;
}

.visitor-page {
    max-width: 180px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: #64748b;
    font-size: 0.85rem;
}

.visitors-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
    gap: 0.75rem;
}

@media (max-width: 768px) {
    .visitors-grid {
        grid-template-columns: 1fr;
    }
    .visitor-card {
        flex-wrap: wrap;
    }
}
</style>

<div class="online-users-header">
    <div>
        <h2 style="color: white; margin: 0; display: flex; align-items: center;">
            <span class="online-indicator"></span>
            Online Activity
        </h2>
        <p style="color: #a0aec0; margin: 0.5rem 0 0 0; font-size: 1.2rem;">
            <strong style="color: #48bb78;"><?= $online_count ?></strong> logged-in user<?= $online_count != 1 ? 's' : '' ?> 
            + <strong style="color: #8b5cf6;"><?= $anonymous_count ?></strong> anonymous visitor<?= $anonymous_count != 1 ? 's' : '' ?>
            <span style="color: #64748b;">(last 15 min)</span>
        </p>
    </div>
    <button class="refresh-btn" onclick="location.reload()">
        <i class="fas fa-sync-alt"></i>
        Refresh
    </button>
</div>

<?php if (empty($online_users)): ?>
    <div class="empty-state">
        <i class="fas fa-user-slash"></i>
        <h3 style="color: white; font-size: 2rem; margin-bottom: 0.5rem;">No Users Online</h3>
        <p style="font-size: 1.4rem;">No users have been active in the last 15 minutes.</p>
    </div>
<?php else: ?>
    <!-- Summary Stats -->
    <div class="stats-grid" style="margin-bottom: 2rem;">
        <div class="stat-card" style="background: linear-gradient(135deg, rgba(72, 187, 120, 0.2), rgba(56, 161, 105, 0.2)); border: 1px solid rgba(72, 187, 120, 0.3);">
            <div class="stat-number" style="color: #48bb78;"><?= $online_count ?></div>
            <div class="stat-label">Logged-in Users</div>
        </div>
        <div class="stat-card" style="background: linear-gradient(135deg, rgba(139, 92, 246, 0.2), rgba(99, 102, 241, 0.2)); border: 1px solid rgba(139, 92, 246, 0.3);">
            <div class="stat-number" style="color: #8b5cf6;"><?= $anonymous_count ?></div>
            <div class="stat-label">Anonymous</div>
        </div>
        <div class="stat-card">
            <div class="stat-number"><?= count(array_filter($online_users, function($u) { return $u['is_admin'] == 1; })) ?></div>
            <div class="stat-label">Admins Online</div>
        </div>
        <div class="stat-card">
            <div class="stat-number"><?= count(array_filter($online_users, function($u) { return strtolower($u['plan']) != 'free'; })) ?></div>
            <div class="stat-label">Paid Users</div>
        </div>
        <div class="stat-card">
            <div class="stat-number"><?= $online_count + $anonymous_count ?></div>
            <div class="stat-label">Total Active</div>
        </div>
    </div>

    <!-- Online Users List -->
    <div style="display: grid; gap: 1.5rem;">
        <?php foreach ($online_users as $user): ?>
        <div class="user-card">
            <div class="user-card-header">
                <div class="user-avatar-large">
                    <?= strtoupper(substr($user['name'], 0, 1)) ?>
                </div>
                <div class="user-info-main">
                    <div class="user-name-large">
                        <?= htmlspecialchars($user['name']) ?>
                        <?php if ($user['is_admin']): ?>
                            <span style="background: linear-gradient(135deg, #f59e0b, #d97706); color: white; padding: 0.2rem 0.6rem; border-radius: 6px; font-size: 1rem; margin-left: 0.5rem;">ADMIN</span>
                        <?php endif; ?>
                    </div>
                    <div class="user-email"><?= htmlspecialchars($user['email']) ?></div>
                </div>
                <div style="text-align: right;">
                    <div class="time-ago">
                        <?php 
                        $minutes = $user['minutes_ago'] ?? 0;
                        if ($minutes < 1) {
                            echo 'Just now';
                        } elseif ($minutes == 1) {
                            echo '1 minute ago';
                        } else {
                            echo $minutes . ' minutes ago';
                        }
                        ?>
                    </div>
                    <div style="color: #a0aec0; font-size: 1.1rem; margin-top: 0.3rem;">
                        <?= date('H:i:s', strtotime($user['last_activity'] ?? $user['last_login'] ?? 'now')) ?>
                    </div>
                    <?php if (!empty($user['current_page'])): ?>
                    <div style="color: #64748b; font-size: 1rem; margin-top: 0.3rem; max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;" title="<?= htmlspecialchars($user['current_page']) ?>">
                        <i class="fas fa-file"></i> <?= htmlspecialchars(basename(parse_url($user['current_page'], PHP_URL_PATH))) ?>
                    </div>
                    <?php endif; ?>
                </div>
            </div>
            
            <div class="user-stats-grid">
                <div class="stat-item">
                    <div class="stat-value"><?= ucfirst($user['plan']) ?></div>
                    <div class="stat-label">Plan</div>
                </div>
                <div class="stat-item">
                    <div class="stat-value"><?= $user['credits'] ?></div>
                    <div class="stat-label">Credits</div>
                </div>
                <div class="stat-item">
                    <div class="stat-value"><?= $user['total_tracks'] ?></div>
                    <div class="stat-label">Total Tracks</div>
                </div>
                <div class="stat-item">
                    <div class="stat-value" style="color: #48bb78;"><?= $user['completed_tracks'] ?></div>
                    <div class="stat-label">Completed</div>
                </div>
                <div class="stat-item">
                    <div class="stat-value"><?= $user['login_count_today'] ?? 0 ?></div>
                    <div class="stat-label">Logins Today</div>
                </div>
            </div>
            
            <div style="display: flex; justify-content: space-between; align-items: center; margin-top: 1rem; padding-top: 1rem; border-top: 1px solid rgba(255, 255, 255, 0.1);">
                <div class="location-info">
                    <i class="fas fa-map-marker-alt"></i>
                    <span>
                        <?php if ($user['city'] || $user['country']): ?>
                            <?= htmlspecialchars($user['city'] ?? '') ?><?= ($user['city'] && $user['country']) ? ', ' : '' ?><?= htmlspecialchars($user['country'] ?? '') ?>
                        <?php else: ?>
                            Location unknown
                        <?php endif; ?>
                    </span>
                    <span style="color: #64748b; margin-left: 1rem;">
                        <i class="fas fa-network-wired"></i> <?= htmlspecialchars($user['last_ip'] ?? 'Unknown IP') ?>
                    </span>
                </div>
                <div style="display: flex; gap: 0.5rem;">
                    <button class="btn btn-primary btn-sm" onclick="loginAsUser(<?= $user['id'] ?>)" title="Login as this user">
                        <i class="fas fa-sign-in-alt"></i> Login As
                    </button>
                    <button class="btn btn-secondary btn-sm" onclick="location.href='?tab=users&user_id=<?= $user['id'] ?>'" title="View user details">
                        <i class="fas fa-user"></i> View
                    </button>
                    <button class="btn btn-secondary btn-sm" onclick="location.href='/artist_profile.php?id=<?= $user['id'] ?>'" title="View profile" target="_blank">
                        <i class="fas fa-external-link-alt"></i> Profile
                    </button>
                </div>
            </div>
        </div>
        <?php endforeach; ?>
    </div>
<?php endif; ?>

<!-- Anonymous Visitors Section -->
<div class="anonymous-section">
    <div class="anonymous-header">
        <div>
            <h3 style="color: white; margin: 0; display: flex; align-items: center; gap: 0.5rem;">
                <i class="fas fa-user-secret" style="color: #8b5cf6;"></i>
                Anonymous Visitors
            </h3>
            <p style="color: #a0aec0; margin: 0.3rem 0 0 0; font-size: 1rem;">
                <?= $anonymous_count ?> visitor<?= $anonymous_count != 1 ? 's' : '' ?> browsing without login
            </p>
        </div>
    </div>
    
    <?php if (empty($anonymous_visitors)): ?>
        <div style="text-align: center; padding: 2rem; color: #64748b;">
            <i class="fas fa-ghost" style="font-size: 2rem; margin-bottom: 0.5rem; opacity: 0.5;"></i>
            <p>No anonymous visitors in the last 15 minutes</p>
        </div>
    <?php else: ?>
        <div class="visitors-grid">
            <?php foreach ($anonymous_visitors as $visitor): 
                $ua_info = parseUserAgent($visitor['user_agent'] ?? '', $visitor['ip_address'] ?? null);
                $is_bot = $ua_info['device'] === 'Bot';
            ?>
            <div class="visitor-card">
                <div class="visitor-icon <?= $is_bot ? 'bot' : '' ?>">
                    <i class="fas fa-<?= $is_bot ? 'robot' : ($ua_info['device'] === 'Mobile' ? 'mobile-alt' : 'desktop') ?>"></i>
                </div>
                <div class="visitor-info">
                    <div class="visitor-ip"><?= htmlspecialchars($visitor['ip_address'] ?? 'Unknown') ?></div>
                    <div class="visitor-location">
                        <i class="fas fa-map-marker-alt" style="margin-right: 0.3rem;"></i>
                        <?php if ($visitor['city'] || $visitor['country']): ?>
                            <?= htmlspecialchars($visitor['city'] ?? '') ?><?= ($visitor['city'] && $visitor['country']) ? ', ' : '' ?><?= htmlspecialchars($visitor['country'] ?? '') ?>
                        <?php else: ?>
                            Unknown location
                        <?php endif; ?>
                    </div>
                </div>
                <div class="visitor-meta">
                    <span class="visitor-badge browser" title="Browser">
                        <i class="fas fa-globe"></i> <?= $ua_info['browser'] ?>
                    </span>
                    <span class="visitor-badge os" title="OS">
                        <i class="fas fa-laptop"></i> <?= $ua_info['os'] ?>
                    </span>
                    <span class="visitor-badge pages" title="Page views">
                        <i class="fas fa-file"></i> <?= $visitor['page_views'] ?> pages
                    </span>
                </div>
                <div style="text-align: right; min-width: 80px;">
                    <div style="color: #8b5cf6; font-weight: 600; font-size: 0.9rem;">
                        <?php 
                        $mins = $visitor['minutes_ago'] ?? 0;
                        echo $mins < 1 ? 'Now' : $mins . 'm ago';
                        ?>
                    </div>
                    <?php if (!empty($visitor['current_page'])): ?>
                    <div class="visitor-page" title="<?= htmlspecialchars($visitor['current_page']) ?>">
                        <?= htmlspecialchars(basename(parse_url($visitor['current_page'], PHP_URL_PATH) ?: '/')) ?>
                    </div>
                    <?php endif; ?>
                </div>
            </div>
            <?php endforeach; ?>
        </div>
    <?php endif; ?>
</div>

<!-- DEBUG: Recent page visits -->
<div style="margin-top: 3rem; padding: 1.5rem; background: rgba(239, 68, 68, 0.1); border: 1px solid rgba(239, 68, 68, 0.3); border-radius: 12px;">
    <h3 style="color: #ef4444; margin: 0 0 1rem 0;"><i class="fas fa-bug"></i> Debug: Recent Page Visits</h3>
    <p style="color: #a0aec0; margin-bottom: 1rem;">
        Server time: <strong><?= $debug_info['server_time'] ?? 'N/A' ?></strong> | 
        Total visits in DB: <strong><?= $debug_info['total_visits'] ?? 0 ?></strong>
        <?php if (isset($debug_info['error'])): ?>
        | <span style="color: #ef4444;">Error: <?= htmlspecialchars($debug_info['error']) ?></span>
        <?php endif; ?>
    </p>
    
    <?php if (empty($all_recent_visits)): ?>
        <p style="color: #f87171;">No visits recorded in the database at all!</p>
    <?php else: ?>
        <table style="width: 100%; border-collapse: collapse; font-size: 0.9rem;">
            <thead>
                <tr style="border-bottom: 1px solid rgba(255,255,255,0.2);">
                    <th style="padding: 0.5rem; text-align: left; color: #94a3b8;">ID</th>
                    <th style="padding: 0.5rem; text-align: left; color: #94a3b8;">User ID</th>
                    <th style="padding: 0.5rem; text-align: left; color: #94a3b8;">IP</th>
                    <th style="padding: 0.5rem; text-align: left; color: #94a3b8;">Page</th>
                    <th style="padding: 0.5rem; text-align: left; color: #94a3b8;">Visit Time</th>
                </tr>
            </thead>
            <tbody>
                <?php foreach ($all_recent_visits as $visit): ?>
                <tr style="border-bottom: 1px solid rgba(255,255,255,0.1);">
                    <td style="padding: 0.5rem; color: #e2e8f0;"><?= $visit['id'] ?></td>
                    <td style="padding: 0.5rem; color: <?= $visit['user_id'] ? '#48bb78' : '#8b5cf6' ?>;">
                        <?= $visit['user_id'] ?? 'Anonymous' ?>
                    </td>
                    <td style="padding: 0.5rem; color: #e2e8f0; font-family: monospace;"><?= htmlspecialchars($visit['ip_address']) ?></td>
                    <td style="padding: 0.5rem; color: #94a3b8; max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">
                        <?= htmlspecialchars(basename($visit['page_url'])) ?>
                    </td>
                    <td style="padding: 0.5rem; color: #94a3b8;"><?= $visit['visit_time'] ?></td>
                </tr>
                <?php endforeach; ?>
            </tbody>
        </table>
    <?php endif; ?>
</div>

<script>
// Auto-refresh every 30 seconds
setInterval(function() {
    if (document.visibilityState === 'visible') {
        location.reload();
    }
}, 30000);
</script>


CasperSecurity Mini