// Admin Dashboard JavaScript // Use relative URL to go through frontend proxy const API_BASE = window.location.origin; // Load all data on page load document.addEventListener('DOMContentLoaded', () => { loadSystemStats(); loadOllamaStatus(); loadGPUStatus(); loadPerformanceTest(); loadModels(); loadConfig(); loadClusteringStats(); }); // Refresh all data function refreshAll() { loadSystemStats(); loadOllamaStatus(); loadGPUStatus(); loadPerformanceTest(); loadModels(); loadConfig(); loadClusteringStats(); } // Load system statistics async function loadSystemStats() { try { const response = await fetch(`${API_BASE}/api/stats`); const data = await response.json(); const html = `
Total Articles ${data.articles || 0}
Crawled Articles ${data.crawled_articles || 0}
AI Summarized ${data.summarized_articles || 0}
Clustered Articles ${data.clustered_articles || 0}
Neutral Summaries ${data.neutral_summaries || 0}
Active Subscribers ${data.subscribers || 0}
`; document.getElementById('systemStats').innerHTML = html; } catch (error) { document.getElementById('systemStats').innerHTML = `
Error loading stats: ${error.message}
`; } } // Load Ollama status async function loadOllamaStatus() { try { const response = await fetch(`${API_BASE}/api/ollama/ping`); const data = await response.json(); const isActive = data.status === 'success'; const statusClass = isActive ? 'status-active' : 'status-inactive'; const html = `
Status ${isActive ? 'Active' : 'Inactive'}
Base URL ${data.ollama_config?.base_url || 'N/A'}
Current Model ${data.ollama_config?.model || 'N/A'}
Enabled ${data.ollama_config?.enabled ? 'Yes' : 'No'}
${isActive ? `
Response ${data.response?.substring(0, 50)}...
` : ''} `; document.getElementById('ollamaStatus').innerHTML = html; } catch (error) { document.getElementById('ollamaStatus').innerHTML = `
Error: ${error.message}
`; } } // Load GPU status async function loadGPUStatus() { try { const response = await fetch(`${API_BASE}/api/ollama/gpu-status`); const data = await response.json(); const gpuActive = data.gpu_in_use; const statusClass = gpuActive ? 'status-active' : 'status-warning'; const html = `
GPU Available ${data.gpu_available ? 'Yes' : 'No'}
GPU In Use ${gpuActive ? 'Yes' : 'No (CPU Mode)'}
Models Loaded ${data.models_loaded || 0}
${data.gpu_details ? `
GPU Model ${data.gpu_details.model}
GPU Layers ${data.gpu_details.gpu_layers}
` : ''} ${!gpuActive ? `
💡 Enable GPU for 5-10x faster processing
` : ''} `; document.getElementById('gpuStatus').innerHTML = html; } catch (error) { document.getElementById('gpuStatus').innerHTML = `
Error: ${error.message}
`; } } // Load performance test async function loadPerformanceTest() { document.getElementById('performanceTest').innerHTML = '
Click "Run Test" to check performance
'; } // Run performance test async function runPerformanceTest() { document.getElementById('performanceTest').innerHTML = '
Running test...
'; try { const response = await fetch(`${API_BASE}/api/ollama/test`); const data = await response.json(); let badgeClass = 'badge-fair'; if (data.duration_seconds < 5) badgeClass = 'badge-excellent'; else if (data.duration_seconds < 15) badgeClass = 'badge-good'; else if (data.duration_seconds > 30) badgeClass = 'badge-slow'; const html = `
Duration ${data.duration_seconds}s
Performance ${data.performance}
Model ${data.model}
${data.recommendation}
`; document.getElementById('performanceTest').innerHTML = html; } catch (error) { document.getElementById('performanceTest').innerHTML = `
Error: ${error.message}
`; } } // Load available models async function loadModels() { try { const response = await fetch(`${API_BASE}/api/ollama/models`); const data = await response.json(); if (data.models && data.models.length > 0) { const modelsList = data.models.map(model => { const isCurrent = model === data.current_model; return `
  • ${model} ${isCurrent ? '(current)' : ''}
  • `; }).join(''); const html = `
    Current: ${data.current_model}
    `; document.getElementById('modelsList').innerHTML = html; } else { document.getElementById('modelsList').innerHTML = '
    No models found
    '; } } catch (error) { document.getElementById('modelsList').innerHTML = `
    Error: ${error.message}
    `; } } // Load configuration async function loadConfig() { try { const response = await fetch(`${API_BASE}/api/ollama/config`); const data = await response.json(); const html = `
    Base URL ${data.ollama_config?.base_url || 'N/A'}
    Model ${data.ollama_config?.model || 'N/A'}
    Enabled ${data.ollama_config?.enabled ? 'Yes' : 'No'}
    Has API Key ${data.ollama_config?.has_api_key ? 'Yes' : 'No'}
    Config file: ${data.env_file_path || 'N/A'}
    Exists: ${data.env_file_exists ? 'Yes' : 'No'}
    `; document.getElementById('configInfo').innerHTML = html; } catch (error) { document.getElementById('configInfo').innerHTML = `
    Error: ${error.message}
    `; } } // Load clustering statistics async function loadClusteringStats() { try { const response = await fetch(`${API_BASE}/api/stats`); const data = await response.json(); const clusteringRate = data.clustered_articles > 0 ? ((data.neutral_summaries / data.clustered_articles) * 100).toFixed(1) : 0; const html = `
    Total Articles ${data.articles || 0}
    Clustered Articles ${data.clustered_articles || 0}
    Neutral Summaries ${data.neutral_summaries || 0}
    Clustering Rate ${clusteringRate}%
    Multi-Source Stories ${data.neutral_summaries || 0}
    AI Clustering: Automatically detects duplicate stories from different sources and generates neutral summaries.
    `; document.getElementById('clusteringStats').innerHTML = html; } catch (error) { document.getElementById('clusteringStats').innerHTML = `
    Error: ${error.message}
    `; } }