// 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}
`;
}
}