LLM / private /admin /index.html
Rox-Turbo's picture
Update private/admin/index.html
d00701c verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<meta name="robots" content="noindex, nofollow">
<title>Rox Admin Panel</title>
<meta name="description" content="Rox AI Admin Panel - Secure administration interface">
<meta name="theme-color" content="#667eea">
<!-- Favicon -->
<link rel="icon" type="image/svg+xml" href="/admin/icon-admin-192.svg">
<!-- KaTeX for Math Rendering -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js" crossorigin="anonymous"></script>
<script>
// Ensure KaTeX is globally available
window.katexReady = new Promise((resolve) => {
if (typeof katex !== 'undefined') {
resolve(true);
} else {
// Fallback check
const checkKatex = setInterval(() => {
if (typeof katex !== 'undefined') {
clearInterval(checkKatex);
resolve(true);
}
}, 50);
// Timeout after 5 seconds
setTimeout(() => {
clearInterval(checkKatex);
resolve(false);
}, 5000);
}
});
</script>
<link rel="stylesheet" href="admin.css">
</head>
<body>
<!-- Login Overlay -->
<div class="login-overlay" id="loginOverlay">
<div class="login-box">
<div class="login-logo">
<svg width="64" height="64" viewBox="0 0 64 64">
<defs>
<linearGradient id="loginGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#667eea"/>
<stop offset="100%" stop-color="#764ba2"/>
</linearGradient>
</defs>
<path d="M32 8 L56 20 L56 44 L32 56 L8 44 L8 20 Z" fill="none" stroke="url(#loginGrad)" stroke-width="2"/>
<circle cx="32" cy="32" r="8" fill="url(#loginGrad)"/>
</svg>
</div>
<h2>Admin Access</h2>
<p>Enter credentials to continue</p>
<form id="loginForm">
<div class="input-group">
<input type="password" id="passwordInput" placeholder="Admin Password" required autocomplete="current-password">
</div>
<button type="submit" class="btn btn-primary" id="loginBtn">
<span class="btn-text">Login</span>
<span class="btn-loading" style="display:none;">
<svg class="spinner" width="16" height="16" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="3" fill="none" stroke-dasharray="31.4 31.4" stroke-linecap="round"/>
</svg>
</span>
</button>
</form>
<div class="login-error" id="loginError"></div>
<div class="login-attempts" id="loginAttempts"></div>
</div>
</div>
<!-- Main App -->
<div class="app" id="app" style="display: none;">
<!-- Mobile Menu Button -->
<button class="mobile-menu-btn" id="mobileMenuBtn" aria-label="Open menu">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<line x1="3" y1="6" x2="21" y2="6"/>
<line x1="3" y1="12" x2="21" y2="12"/>
<line x1="3" y1="18" x2="21" y2="18"/>
</svg>
</button>
<!-- Sidebar Overlay -->
<div class="sidebar-overlay" id="sidebarOverlay"></div>
<!-- Sidebar - Users List -->
<aside class="sidebar" id="sidebar">
<!-- Mobile Close Button -->
<button class="panel-close-btn mobile-only" id="sidebarCloseBtn" aria-label="Close sidebar">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<line x1="18" y1="6" x2="6" y2="18"/>
<line x1="6" y1="6" x2="18" y2="18"/>
</svg>
</button>
<div class="sidebar-header">
<div class="logo-section">
<svg width="28" height="28" viewBox="0 0 64 64">
<defs>
<linearGradient id="sidebarGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#667eea"/>
<stop offset="100%" stop-color="#764ba2"/>
</linearGradient>
</defs>
<path d="M32 8 L56 20 L56 44 L32 56 L8 44 L8 20 Z" fill="none" stroke="url(#sidebarGrad)" stroke-width="2"/>
<circle cx="32" cy="32" r="6" fill="url(#sidebarGrad)"/>
</svg>
<h1>Rox Admin</h1>
</div>
<button class="btn-logout" id="btnLogout" title="Logout">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4"/>
<polyline points="16 17 21 12 16 7"/>
<line x1="21" y1="12" x2="9" y2="12"/>
</svg>
</button>
</div>
<div class="stats-row">
<div class="stat-box" title="Total unique users who have interacted with Rox AI">
<div class="stat-val" id="totalUsers">0</div>
<div class="stat-lbl">Users</div>
<div class="stat-trend" id="usersTrend"></div>
</div>
<div class="stat-box" title="Total conversation threads created">
<div class="stat-val" id="totalChats">0</div>
<div class="stat-lbl">Chats</div>
<div class="stat-trend" id="chatsTrend"></div>
</div>
<div class="stat-box" title="Messages sent today (resets at midnight)">
<div class="stat-val" id="todayQueries">0</div>
<div class="stat-lbl">Today</div>
<div class="stat-trend" id="todayTrend"></div>
</div>
</div>
<div class="sidebar-tabs">
<button class="tab-btn active" data-tab="users" title="Users (Ctrl+1)">
Users
<kbd class="tab-shortcut">1</kbd>
</button>
<button class="tab-btn" data-tab="stats" title="Statistics (Ctrl+2)">
Stats
<kbd class="tab-shortcut">2</kbd>
</button>
</div>
<div class="tab-content" id="usersTab">
<div class="search-box">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="11" cy="11" r="8"/>
<path d="M21 21l-4.35-4.35"/>
</svg>
<input type="text" id="userSearch" placeholder="Search users... (Ctrl+F)" autocomplete="off">
<div class="search-results-count" id="searchResultsCount" style="display: none;"></div>
</div>
<div class="users-section">
<div class="section-title">
Active Users
<div class="section-actions">
<button class="btn-icon" id="sortUsersBtn" title="Sort users">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M3 6h18M7 12h10m-7 6h4"/>
</svg>
</button>
</div>
</div>
<div class="user-list" id="userList">
<div class="loading-skeleton">
<div class="skeleton-item"></div>
<div class="skeleton-item"></div>
<div class="skeleton-item"></div>
</div>
</div>
</div>
</div>
<div class="tab-content" id="statsTab" style="display:none;">
<div class="stats-summary">
<div class="summary-title">📊 Quick Overview</div>
<div class="summary-grid">
<div class="summary-item">
<span class="summary-value" id="summaryTotalUsers">0</span>
<span class="summary-label">Total Users</span>
</div>
<div class="summary-item">
<span class="summary-value" id="summaryOnline">0</span>
<span class="summary-label">Online Now</span>
</div>
<div class="summary-item">
<span class="summary-value" id="summaryToday">0</span>
<span class="summary-label">Today</span>
</div>
</div>
</div>
<!-- Enhanced Analytics Section -->
<div class="analytics-section">
<div class="section-title">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 3v18h18"/><path d="M18 17V9"/><path d="M13 17V5"/><path d="M8 17v-3"/></svg>
Analytics Overview
</div>
<div class="analytics-grid">
<div class="analytics-card">
<div class="analytics-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg>
</div>
<div class="analytics-content">
<div class="analytics-value" id="yesterdayQueries">0</div>
<div class="analytics-label">Yesterday</div>
</div>
</div>
<div class="analytics-card">
<div class="analytics-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/><path d="M8 14h.01M12 14h.01M16 14h.01M8 18h.01M12 18h.01M16 18h.01"/></svg>
</div>
<div class="analytics-content">
<div class="analytics-value" id="weekQueries">0</div>
<div class="analytics-label">This Week</div>
</div>
</div>
<div class="analytics-card">
<div class="analytics-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 20V10"/><path d="M12 20V4"/><path d="M6 20v-6"/></svg>
</div>
<div class="analytics-content">
<div class="analytics-value" id="monthQueries">0</div>
<div class="analytics-label">This Month</div>
</div>
</div>
<div class="analytics-card highlight">
<div class="analytics-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><line x1="19" y1="8" x2="19" y2="14"/><line x1="22" y1="11" x2="16" y2="11"/></svg>
</div>
<div class="analytics-content">
<div class="analytics-value" id="newUsersToday">0</div>
<div class="analytics-label">New Today</div>
</div>
</div>
</div>
</div>
<!-- Real-time Metrics -->
<div class="realtime-section">
<div class="section-title">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>
Real-time Metrics
</div>
<div class="realtime-grid">
<div class="realtime-card">
<div class="realtime-icon pulse">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="var(--success)" stroke-width="2"><circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="3" fill="var(--success)"/></svg>
</div>
<div class="realtime-info">
<div class="realtime-value" id="realtimeOnline">0</div>
<div class="realtime-label">Online Now</div>
</div>
</div>
<div class="realtime-card">
<div class="realtime-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
</div>
<div class="realtime-info">
<div class="realtime-value" id="lastHourQueries">0</div>
<div class="realtime-label">Last Hour</div>
</div>
</div>
<div class="realtime-card">
<div class="realtime-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17 1l4 4-4 4"/><path d="M3 11V9a4 4 0 0 1 4-4h14"/><path d="M7 23l-4-4 4-4"/><path d="M21 13v2a4 4 0 0 1-4 4H3"/></svg>
</div>
<div class="realtime-info">
<div class="realtime-value" id="returningUsers">0</div>
<div class="realtime-label">Returning</div>
</div>
</div>
<div class="realtime-card">
<div class="realtime-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="23 6 13.5 15.5 8.5 10.5 1 18"/><polyline points="17 6 23 6 23 12"/></svg>
</div>
<div class="realtime-info">
<div class="realtime-value" id="returningRate">0%</div>
<div class="realtime-label">Return Rate</div>
</div>
</div>
</div>
</div>
<!-- Engagement Metrics -->
<div class="engagement-section">
<div class="section-title">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/></svg>
Engagement Metrics
</div>
<div class="engagement-grid">
<div class="engagement-card">
<div class="engagement-header">
<span class="engagement-icon">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>
</span>
<span class="engagement-title">Page Views</span>
</div>
<div class="engagement-value" id="totalPageViews">0</div>
<div class="engagement-sub">Avg: <span id="avgPageViews">0</span>/user</div>
</div>
<div class="engagement-card">
<div class="engagement-header">
<span class="engagement-icon">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
</span>
<span class="engagement-title">Avg Session</span>
</div>
<div class="engagement-value" id="avgSessionDuration">0m</div>
<div class="engagement-sub">Total: <span id="totalSessions">0</span> sessions</div>
</div>
<div class="engagement-card">
<div class="engagement-header">
<span class="engagement-icon">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg>
</span>
<span class="engagement-title">Bounce Rate</span>
</div>
<div class="engagement-value" id="bounceRate">0%</div>
<div class="engagement-sub">Single page visits</div>
</div>
<div class="engagement-card">
<div class="engagement-header">
<span class="engagement-icon">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><line x1="19" y1="8" x2="19" y2="14"/><line x1="22" y1="11" x2="16" y2="11"/></svg>
</span>
<span class="engagement-title">New This Month</span>
</div>
<div class="engagement-value" id="newUsersMonth">0</div>
<div class="engagement-sub">User acquisition</div>
</div>
</div>
</div>
<!-- Error & Performance Tracking -->
<div class="error-section">
<div class="section-title">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
Error & Performance
</div>
<div class="error-grid">
<div class="error-card">
<div class="error-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="var(--error)" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>
</div>
<div class="error-content">
<div class="error-value" id="totalErrors">0</div>
<div class="error-label">Total Errors</div>
</div>
</div>
<div class="error-card">
<div class="error-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="23 18 13.5 8.5 8.5 13.5 1 6"/><polyline points="17 18 23 18 23 12"/></svg>
</div>
<div class="error-content">
<div class="error-value" id="errorRate">0%</div>
<div class="error-label">Error Rate</div>
</div>
</div>
<div class="error-card">
<div class="error-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="var(--warning)" stroke-width="2"><path d="M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z"/></svg>
</div>
<div class="error-content">
<div class="error-value" id="recentErrors">0</div>
<div class="error-label">Recent Errors</div>
</div>
</div>
<div class="error-card">
<div class="error-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="var(--accent)" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg>
</div>
<div class="error-content">
<div class="error-value" id="totalTokens">0</div>
<div class="error-label">Total Tokens</div>
</div>
</div>
</div>
</div>
<!-- Top Users Section -->
<div class="top-users-section">
<div class="section-title">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="8" r="7"/><polyline points="8.21 13.89 7 23 12 20 17 23 15.79 13.88"/></svg>
Top Users
</div>
<div id="topUsersChart" class="top-users-chart"></div>
</div>
<!-- Daily Activity Chart -->
<div class="daily-activity">
<div class="section-title">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 3v18h18"/><path d="M18 17V9"/><path d="M13 17V5"/><path d="M8 17v-3"/></svg>
7-Day Activity
</div>
<div id="dailyActivityChart" class="daily-chart"></div>
</div>
<div class="stats-detail">
<div class="stat-card">
<div class="stat-card-title">Avg Response Time</div>
<div class="stat-card-value" id="avgResponseTime">0ms</div>
<div class="stat-sparkline" id="responseTimeSparkline"></div>
</div>
<div class="stat-card">
<div class="stat-card-title">Total Messages</div>
<div class="stat-card-value" id="totalMessages">0</div>
<div class="stat-sparkline" id="messagesSparkline"></div>
</div>
<div class="stat-card">
<div class="stat-card-title">Active Sessions</div>
<div class="stat-card-value" id="activeSessions">0</div>
<div class="activity-indicator" id="activityIndicator"></div>
</div>
<div class="stat-card">
<div class="stat-card-title">Peak Usage Hour</div>
<div class="stat-card-value" id="peakHour">--</div>
<div class="stat-card-subtitle" id="peakHourLabel">Most active time</div>
</div>
<div class="stat-card">
<div class="stat-card-title">Online Users</div>
<div class="stat-card-value" id="onlineUsers">0</div>
<div class="stat-card-subtitle">Currently active</div>
</div>
<div class="stat-card">
<div class="stat-card-title">Avg Chats/User</div>
<div class="stat-card-value" id="avgChatsPerUser">0</div>
<div class="stat-card-subtitle">Engagement metric</div>
</div>
<div class="stat-card">
<div class="stat-card-title">Avg Msgs/Chat</div>
<div class="stat-card-value" id="avgMessagesPerChat">0</div>
<div class="stat-card-subtitle">Conversation depth</div>
</div>
<div class="stat-card">
<div class="stat-card-title">New This Week</div>
<div class="stat-card-value" id="newUsersWeek">0</div>
<div class="stat-card-subtitle">User growth</div>
</div>
</div>
<!-- Browser & OS Distribution -->
<div class="distribution-section">
<div class="section-title">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
User Distribution
</div>
<div class="distribution-grid">
<div class="distribution-card">
<div class="distribution-title">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
Browser Usage
</div>
<div id="browserDistribution" class="distribution-chart"></div>
</div>
<div class="distribution-card">
<div class="distribution-title">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>
Operating System
</div>
<div id="osDistribution" class="distribution-chart"></div>
</div>
<div class="distribution-card">
<div class="distribution-title">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="5" y="2" width="14" height="20" rx="2" ry="2"/><line x1="12" y1="18" x2="12.01" y2="18"/></svg>
Device Type
</div>
<div id="deviceDistribution" class="distribution-chart"></div>
</div>
<div class="distribution-card">
<div class="distribution-title">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M2 12h20"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
Language
</div>
<div id="languageDistribution" class="distribution-chart"></div>
</div>
<div class="distribution-card">
<div class="distribution-title">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg>
Traffic Source
</div>
<div id="refererDistribution" class="distribution-chart"></div>
</div>
<div class="distribution-card">
<div class="distribution-title">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>
Country
</div>
<div id="countryDistribution" class="distribution-chart"></div>
</div>
<div class="distribution-card">
<div class="distribution-title">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><line x1="3" y1="9" x2="21" y2="9"/><line x1="9" y1="21" x2="9" y2="9"/></svg>
Screen Resolution
</div>
<div id="screenDistribution" class="distribution-chart"></div>
</div>
</div>
</div>
<div class="hourly-usage">
<div class="section-title">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Hourly Activity
</div>
<div id="hourlyUsageChart" class="hourly-chart"></div>
</div>
<div class="model-usage">
<div class="section-title">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/></svg>
Model Usage
</div>
<div id="modelUsageChart" class="usage-chart"></div>
</div>
<div class="system-health">
<div class="section-title">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 12h-4l-3 9L9 3l-3 9H2"/></svg>
System Health
</div>
<div id="systemHealthChart" class="health-chart"></div>
<div class="performance-indicators" id="performanceIndicators">
<div class="perf-indicator">
<div class="perf-dot loading"></div>
<span>Loading...</span>
</div>
</div>
</div>
<div class="server-info">
<div class="section-title">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="2" width="20" height="8" rx="2" ry="2"/><rect x="2" y="14" width="20" height="8" rx="2" ry="2"/><line x1="6" y1="6" x2="6.01" y2="6"/><line x1="6" y1="18" x2="6.01" y2="18"/></svg>
Server Information
</div>
<div id="serverInfoChart" class="server-info-chart"></div>
</div>
<!-- User Insights Section -->
<div class="user-insights-section">
<div class="section-title">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
User Insights
</div>
<div class="insights-grid">
<div class="insight-card">
<div class="insight-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/></svg>
</div>
<div class="insight-content">
<div class="insight-value" id="avgEngagement">0%</div>
<div class="insight-label">Avg Engagement</div>
</div>
</div>
<div class="insight-card">
<div class="insight-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
</div>
<div class="insight-content">
<div class="insight-value" id="avgTimeOnSite">0m</div>
<div class="insight-label">Avg Time on Site</div>
</div>
</div>
<div class="insight-card">
<div class="insight-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="5" y="2" width="14" height="20" rx="2" ry="2"/><line x1="12" y1="18" x2="12.01" y2="18"/></svg>
</div>
<div class="insight-content">
<div class="insight-value" id="mobilePercent">0%</div>
<div class="insight-label">Mobile Users</div>
</div>
</div>
<div class="insight-card">
<div class="insight-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17 1l4 4-4 4"/><path d="M3 11V9a4 4 0 0 1 4-4h14"/><path d="M7 23l-4-4 4-4"/><path d="M21 13v2a4 4 0 0 1-4 4H3"/></svg>
</div>
<div class="insight-content">
<div class="insight-value" id="avgSessionsPerUser">0</div>
<div class="insight-label">Avg Sessions/User</div>
</div>
</div>
</div>
</div>
<!-- Activity Heatmap Section -->
<div class="heatmap-section">
<div class="section-title">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg>
Weekly Activity Heatmap
</div>
<div id="weeklyHeatmap" class="weekly-heatmap"></div>
</div>
</div>
</aside>
<!-- Main Content -->
<main class="main">
<header class="main-header">
<div class="header-left">
<button class="menu-btn" id="menuBtn">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M3 12h18M3 6h18M3 18h18"/>
</svg>
</button>
<nav class="breadcrumb" id="breadcrumb">
<span class="breadcrumb-item active">Dashboard</span>
</nav>
<div class="connection-status" id="connectionStatus" title="Connection status">
<div class="connection-dot"></div>
<span>Connected</span>
</div>
<span class="last-updated" id="lastUpdated">Updated just now</span>
<div class="auto-refresh-indicator" id="autoRefreshIndicator" title="Auto-refresh active">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M23 4v6h-6M1 20v-6h6"/>
<path d="M3.51 9a9 9 0 0114.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0020.49 15"/>
</svg>
</div>
</div>
<div class="header-actions">
<button class="btn btn-secondary" id="refreshBtn" title="Refresh data (Ctrl+R)">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M23 4v6h-6M1 20v-6h6"/>
<path d="M3.51 9a9 9 0 0114.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0020.49 15"/>
</svg>
<span>Refresh</span>
<div class="btn-progress" id="refreshProgress"></div>
</button>
<button class="btn btn-secondary" id="helpBtn" title="Keyboard shortcuts">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="10"/>
<path d="M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3"/>
<line x1="12" y1="17" x2="12.01" y2="17"/>
</svg>
<span>Help</span>
</button>
<div class="dropdown" id="exportDropdown">
<button class="btn btn-secondary dropdown-toggle" id="exportBtn" title="Export options">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/>
<polyline points="7 10 12 15 17 10"/>
<line x1="12" y1="15" x2="12" y2="3"/>
</svg>
<span>Export</span>
<svg class="dropdown-arrow" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<polyline points="6 9 12 15 18 9"/>
</svg>
</button>
<div class="dropdown-menu" id="exportMenu">
<button class="dropdown-item" id="exportJsonBtn">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/>
<polyline points="14 2 14 8 20 8"/>
</svg>
Export All (JSON)
</button>
<button class="dropdown-item" id="exportPdfBtn">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/>
<polyline points="14 2 14 8 20 8"/>
<line x1="16" y1="13" x2="8" y2="13"/>
<line x1="16" y1="17" x2="8" y2="17"/>
</svg>
Export Stats (PDF)
</button>
<button class="dropdown-item" id="exportUsersPdfBtn">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2"/>
<circle cx="9" cy="7" r="4"/>
<path d="M23 21v-2a4 4 0 00-3-3.87"/>
<path d="M16 3.13a4 4 0 010 7.75"/>
</svg>
Export Users (PDF)
</button>
</div>
</div>
<button class="btn btn-danger" id="clearBtn" title="Clear all logs">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M3 6h18M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2"/>
</svg>
<span>Clear</span>
</button>
</div>
</header>
<div class="content-area">
<!-- User Details Panel -->
<div class="user-details-panel" id="userDetailsPanel">
<div class="user-details-header">
<h3>User Details</h3>
<button class="btn-close-panel" id="closeUserDetails">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
</button>
</div>
<div class="user-details-content" id="userDetailsContent">
<div class="empty-state">
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>
</svg>
<p>Select a user to view details</p>
</div>
</div>
</div>
<!-- Chats Panel -->
<div class="chats-panel" id="chatsPanel">
<!-- Mobile Close Button -->
<button class="panel-close-btn mobile-only" id="chatsPanelCloseBtn" aria-label="Close chats panel">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<line x1="18" y1="6" x2="6" y2="18"/>
<line x1="6" y1="6" x2="18" y2="18"/>
</svg>
</button>
<div class="chats-header">
<span>Chats by </span>
<span id="selectedUserName">-</span>
<div class="chat-count-badge" id="chatCountBadge" style="display: none;">
<span id="chatCount">0</span>
</div>
</div>
<div class="chats-list" id="chatsList">
<div class="empty-state">
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
<path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z"/>
</svg>
<p>Select a user to view chats</p>
</div>
</div>
</div>
<!-- Messages View -->
<div class="chat-view" id="chatView">
<div class="chat-view-header" id="chatHeader" style="display: none;">
<div class="chat-info">
<h3 id="chatTitle">Chat</h3>
<p id="chatMeta"></p>
</div>
<div class="chat-actions">
<button class="btn btn-sm" id="exportChatJsonBtn" title="Export chat as JSON">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/>
<polyline points="14 2 14 8 20 8"/>
</svg>
<span>JSON</span>
</button>
<button class="btn btn-sm btn-primary" id="exportChatPdfBtn" title="Export chat as PDF">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/>
<polyline points="14 2 14 8 20 8"/>
<line x1="16" y1="13" x2="8" y2="13"/>
<line x1="16" y1="17" x2="8" y2="17"/>
</svg>
<span>PDF</span>
</button>
</div>
</div>
<div class="messages-area" id="messagesArea">
<div class="empty-state">
<svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
<path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z"/>
</svg>
<p>Select a user, then select a chat to view messages</p>
</div>
</div>
</div>
</div>
</main>
</div>
<!-- Chats Panel Overlay for Mobile -->
<div class="chats-panel-overlay" id="chatsPanelOverlay"></div>
<!-- Toast Container -->
<div class="toast-container" id="toastContainer"></div>
<!-- Confirm Dialog -->
<div class="dialog-overlay" id="dialogOverlay" style="display:none;">
<div class="dialog-box">
<div class="dialog-icon" id="dialogIcon"></div>
<h3 id="dialogTitle">Confirm</h3>
<p id="dialogMessage">Are you sure?</p>
<div class="dialog-actions">
<button class="btn btn-secondary" id="dialogCancel">Cancel</button>
<button class="btn btn-danger" id="dialogConfirm">Confirm</button>
</div>
</div>
</div>
<!-- Help Dialog -->
<div class="dialog-overlay" id="helpOverlay" style="display:none;">
<div class="dialog-box help-dialog">
<div class="dialog-icon help">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="10"/>
<path d="M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3"/>
<line x1="12" y1="17" x2="12.01" y2="17"/>
</svg>
</div>
<h3>Keyboard Shortcuts</h3>
<div class="shortcuts-grid">
<div class="shortcut-item">
<kbd>Ctrl + R</kbd>
<span>Refresh data</span>
</div>
<div class="shortcut-item">
<kbd>Ctrl + F</kbd>
<span>Focus search</span>
</div>
<div class="shortcut-item">
<kbd>Ctrl + 1</kbd>
<span>Users tab</span>
</div>
<div class="shortcut-item">
<kbd>Ctrl + 2</kbd>
<span>Stats tab</span>
</div>
<div class="shortcut-item">
<kbd>Esc</kbd>
<span>Close dialogs</span>
</div>
<div class="shortcut-item">
<kbd>Enter / Space</kbd>
<span>Select item</span>
</div>
</div>
<div class="dialog-actions">
<button class="btn btn-primary" id="helpClose">Got it</button>
</div>
</div>
</div>
<!-- Scripts -->
<script src="admin.js" type="module"></script>
</body>
</html>