- Removed TTS server status popup from main frontend interface - Commented out checkTtsServer() function and all its calls - Removed TTS configuration UI elements from index.html - Added comprehensive TTS server monitoring to admin dashboard: - Configuration status (URL, API key) - Server health monitoring - Available voices display - Usage statistics and performance metrics - Real-time status updates - Enhanced system health check to include TTS server - Created dedicated /api/tts/status endpoint for detailed info The TTS functionality remains fully operational for users, but status monitoring is now exclusive to the admin dashboard for cleaner UX. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
326 lines
12 KiB
HTML
326 lines
12 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Dashboard - Talk2Me Admin{% endblock %}
|
|
|
|
{% block content %}
|
|
<!-- Quick Actions -->
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<div class="card bg-light">
|
|
<div class="card-body">
|
|
<h5 class="card-title">Quick Actions</h5>
|
|
<div class="btn-group" role="group">
|
|
<a href="{{ url_for('admin.users') }}" class="btn btn-primary">
|
|
<i class="fas fa-users"></i> Manage Users
|
|
</a>
|
|
<button onclick="exportData('all')" class="btn btn-secondary">
|
|
<i class="fas fa-download"></i> Export Data
|
|
</button>
|
|
<button onclick="clearCache()" class="btn btn-warning">
|
|
<i class="fas fa-trash"></i> Clear Cache
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Overview Cards -->
|
|
<div class="row mb-4">
|
|
<div class="col-md-3 mb-3">
|
|
<div class="card text-white bg-primary">
|
|
<div class="card-body">
|
|
<h5 class="card-title">Total Requests</h5>
|
|
<h2 class="card-text" id="total-requests">
|
|
<div class="spinner-border spinner-border-sm" role="status"></div>
|
|
</h2>
|
|
<p class="card-text"><small>Today: <span id="today-requests">-</span></small></p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3 mb-3">
|
|
<div class="card text-white bg-success">
|
|
<div class="card-body">
|
|
<h5 class="card-title">Active Sessions</h5>
|
|
<h2 class="card-text" id="active-sessions">
|
|
<div class="spinner-border spinner-border-sm" role="status"></div>
|
|
</h2>
|
|
<p class="card-text"><small>Live users</small></p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3 mb-3">
|
|
<div class="card text-white bg-warning">
|
|
<div class="card-body">
|
|
<h5 class="card-title">Error Rate</h5>
|
|
<h2 class="card-text" id="error-rate">
|
|
<div class="spinner-border spinner-border-sm" role="status"></div>
|
|
</h2>
|
|
<p class="card-text"><small>Last 24 hours</small></p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3 mb-3">
|
|
<div class="card text-white bg-info">
|
|
<div class="card-body">
|
|
<h5 class="card-title">Cache Hit Rate</h5>
|
|
<h2 class="card-text" id="cache-hit-rate">
|
|
<div class="spinner-border spinner-border-sm" role="status"></div>
|
|
</h2>
|
|
<p class="card-text"><small>Performance metric</small></p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- System Health Status -->
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="mb-0"><i class="fas fa-heartbeat"></i> System Health</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-4">
|
|
<div class="d-flex align-items-center">
|
|
<i class="fas fa-database fa-2x me-3"></i>
|
|
<div>
|
|
<h6 class="mb-0">Redis</h6>
|
|
<span class="badge" id="redis-status">Checking...</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="d-flex align-items-center">
|
|
<i class="fas fa-server fa-2x me-3"></i>
|
|
<div>
|
|
<h6 class="mb-0">PostgreSQL</h6>
|
|
<span class="badge" id="postgresql-status">Checking...</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="d-flex align-items-center">
|
|
<i class="fas fa-microphone fa-2x me-3"></i>
|
|
<div>
|
|
<h6 class="mb-0">Whisper/TTS</h6>
|
|
<span class="badge" id="ml-status">Checking...</span>
|
|
<small class="d-block text-muted" id="tts-details"></small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- TTS Server Status Card -->
|
|
<div class="row mb-4">
|
|
<div class="col-md-12">
|
|
<div class="card">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<h5 class="mb-0">TTS Server Status</h5>
|
|
<button class="btn btn-sm btn-outline-primary" onclick="loadTTSStatus()">
|
|
<i class="fas fa-sync"></i> Refresh
|
|
</button>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row" id="tts-status-container">
|
|
<div class="col-md-4">
|
|
<h6>Configuration</h6>
|
|
<ul class="list-unstyled mb-0">
|
|
<li><strong>Status:</strong> <span id="tts-config-status" class="badge">Loading...</span></li>
|
|
<li><strong>Server URL:</strong> <span id="tts-server-url">-</span></li>
|
|
<li><strong>API Key:</strong> <span id="tts-api-key-status">-</span></li>
|
|
</ul>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<h6>Server Health</h6>
|
|
<ul class="list-unstyled mb-0">
|
|
<li><strong>Health:</strong> <span id="tts-health-status" class="badge">Loading...</span></li>
|
|
<li><strong>Available Voices:</strong> <span id="tts-voice-count">-</span></li>
|
|
<li><strong>Error:</strong> <span id="tts-error-message" class="text-danger">-</span></li>
|
|
</ul>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<h6>Usage & Performance</h6>
|
|
<ul class="list-unstyled mb-0">
|
|
<li><strong>Today's Requests:</strong> <span id="tts-usage-today">-</span></li>
|
|
<li><strong>Avg Response Time:</strong> <span id="tts-avg-response">-</span></li>
|
|
<li><strong>Total Requests:</strong> <span id="tts-usage-total">-</span></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<div class="row mt-3" id="tts-voices-container" style="display: none;">
|
|
<div class="col-md-12">
|
|
<h6>Available Voices</h6>
|
|
<div id="tts-voices-list" class="d-flex flex-wrap gap-2"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Charts Row 1 -->
|
|
<div class="row mb-4">
|
|
<div class="col-md-8">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">Request Volume</h5>
|
|
<div class="btn-group btn-group-sm float-end" role="group">
|
|
<button type="button" class="btn btn-outline-primary active" onclick="updateRequestChart('minute')">Minute</button>
|
|
<button type="button" class="btn btn-outline-primary" onclick="updateRequestChart('hour')">Hour</button>
|
|
<button type="button" class="btn btn-outline-primary" onclick="updateRequestChart('day')">Day</button>
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
<canvas id="requestChart" height="100"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-4">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">Language Pairs</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<canvas id="languageChart" height="200"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Charts Row 2 -->
|
|
<div class="row mb-4">
|
|
<div class="col-md-6">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">Operations</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<canvas id="operationsChart" height="120"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">Response Times (ms)</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<canvas id="responseTimeChart" height="120"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Error Analysis -->
|
|
<div class="row mb-4">
|
|
<div class="col-md-6">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">Error Types</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<canvas id="errorTypeChart" height="150"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">Recent Errors</h5>
|
|
</div>
|
|
<div class="card-body" style="max-height: 300px; overflow-y: auto;">
|
|
<div id="recent-errors-list">
|
|
<div class="text-center">
|
|
<div class="spinner-border" role="status"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Performance Metrics -->
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">Performance Metrics</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="table-responsive">
|
|
<table class="table table-striped">
|
|
<thead>
|
|
<tr>
|
|
<th>Operation</th>
|
|
<th>Average (ms)</th>
|
|
<th>95th Percentile (ms)</th>
|
|
<th>99th Percentile (ms)</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="performance-table">
|
|
<tr>
|
|
<td colspan="4" class="text-center">
|
|
<div class="spinner-border" role="status"></div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Real-time Updates Status -->
|
|
<div class="position-fixed bottom-0 end-0 p-3" style="z-index: 1000">
|
|
<div class="toast" id="update-toast" role="alert">
|
|
<div class="toast-header">
|
|
<i class="fas fa-sync-alt me-2"></i>
|
|
<strong class="me-auto">Real-time Updates</strong>
|
|
<small id="last-update">Just now</small>
|
|
<button type="button" class="btn-close" data-bs-dismiss="toast"></button>
|
|
</div>
|
|
<div class="toast-body">
|
|
<span id="update-status">Connected</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{% endblock %}
|
|
|
|
{% block extra_js %}
|
|
<script>
|
|
// Initialize dashboard
|
|
$(document).ready(function() {
|
|
initializeDashboard();
|
|
|
|
// Start real-time updates
|
|
startRealtimeUpdates();
|
|
|
|
// Load initial data
|
|
loadOverviewStats();
|
|
loadRequestChart('minute');
|
|
loadOperationStats();
|
|
loadErrorStats();
|
|
loadPerformanceStats();
|
|
|
|
// Refresh data periodically
|
|
setInterval(loadOverviewStats, 10000); // Every 10 seconds
|
|
setInterval(function() {
|
|
loadRequestChart(currentTimeframe);
|
|
}, 30000); // Every 30 seconds
|
|
});
|
|
</script>
|
|
{% endblock %} |