Initial commit: Whisper API with FastAPI, GPU support and Admin Dashboard
This commit is contained in:
116
src/templates/dashboard.html
Normal file
116
src/templates/dashboard.html
Normal file
@@ -0,0 +1,116 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Dashboard - Whisper API Admin{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>🎯 Whisper API Dashboard</h1>
|
||||
<div class="nav">
|
||||
<a href="/admin" class="active">Dashboard</a>
|
||||
<a href="/admin/keys">API Keys</a>
|
||||
<a href="/admin/logout">Logout</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="stats-grid">
|
||||
<div class="stat-card">
|
||||
<div class="stat-value">{{ stats.total_requests }}</div>
|
||||
<div class="stat-label">Requests (30 Tage)</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-value">{{ stats.success_rate }}%</div>
|
||||
<div class="stat-label">Success Rate</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-value">{{ stats.avg_processing_time_ms }}ms</div>
|
||||
<div class="stat-label">Ø Processing Time</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-value">{{ model }}</div>
|
||||
<div class="stat-label">Model</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>📊 Usage Chart (Last 30 Days)</h2>
|
||||
<canvas id="usageChart" height="100"></canvas>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>📝 Recent Activity</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Time</th>
|
||||
<th>Endpoint</th>
|
||||
<th>Duration</th>
|
||||
<th>Status</th>
|
||||
<th>Processing</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for log in stats.recent_logs[:10] %}
|
||||
<tr>
|
||||
<td>{{ log.created_at.strftime('%Y-%m-%d %H:%M:%S') }}</td>
|
||||
<td>{{ log.endpoint }}</td>
|
||||
<td>
|
||||
{% if log.duration_seconds %}
|
||||
{{ "%.1f"|format(log.duration_seconds) }}s
|
||||
{% else %}
|
||||
-
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge badge-{{ 'success' if log.status == 'success' else 'danger' }}">
|
||||
{{ log.status }}
|
||||
</span>
|
||||
</td>
|
||||
<td>{{ log.processing_time_ms }}ms</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>ℹ️ System Info</h2>
|
||||
<p><strong>Model:</strong> {{ model }}</p>
|
||||
<p><strong>Log Retention:</strong> {{ retention_days }} days</p>
|
||||
<p><strong>API Version:</strong> v1.0.0</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
<script>
|
||||
const ctx = document.getElementById('usageChart').getContext('2d');
|
||||
const dailyStats = {{ stats.daily_stats | tojson }};
|
||||
|
||||
new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: dailyStats.map(s => s.date),
|
||||
datasets: [{
|
||||
label: 'Requests',
|
||||
data: dailyStats.map(s => s.count),
|
||||
backgroundColor: 'rgba(102, 126, 234, 0.2)',
|
||||
borderColor: 'rgba(102, 126, 234, 1)',
|
||||
borderWidth: 2,
|
||||
tension: 0.4
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
ticks: {
|
||||
stepSize: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user