110 lines
3.6 KiB
HTML
110 lines
3.6 KiB
HTML
{% extends 'base.html' %}
|
|
{% block content %}
|
|
<div class="p-6">
|
|
<div class="mb-6">
|
|
<h1 class="text-2xl font-semibold text-slate-800">Sync Statistics</h1>
|
|
<p class="text-sm text-slate-500 mt-1">Last 14 days of sync activity</p>
|
|
</div>
|
|
|
|
<div class="bg-white rounded-lg shadow p-6">
|
|
<div class="h-80">
|
|
<canvas id="syncChart"></canvas>
|
|
</div>
|
|
<div class="flex justify-center gap-6 mt-4">
|
|
<div class="flex items-center gap-2">
|
|
<span class="w-4 h-4 rounded bg-emerald-500"></span>
|
|
<span class="text-sm text-slate-600">Recent Updates</span>
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<span class="w-4 h-4 rounded bg-sky-500"></span>
|
|
<span class="text-sm text-slate-600">Oldest Updates</span>
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<span class="w-4 h-4 rounded bg-rose-500"></span>
|
|
<span class="text-sm text-slate-600">Failures</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-6 bg-white rounded-lg shadow overflow-hidden">
|
|
<table class="w-full text-sm">
|
|
<thead class="bg-slate-50 text-slate-600">
|
|
<tr>
|
|
<th class="px-4 py-3 text-left font-medium">Date</th>
|
|
<th class="px-4 py-3 text-right font-medium">Recent Updates</th>
|
|
<th class="px-4 py-3 text-right font-medium">Oldest Updates</th>
|
|
<th class="px-4 py-3 text-right font-medium">Failures</th>
|
|
<th class="px-4 py-3 text-right font-medium">Total</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-slate-100">
|
|
{% for stat in stats %}
|
|
<tr class="hover:bg-slate-50">
|
|
<td class="px-4 py-3 text-slate-800">{{ stat.date }}</td>
|
|
<td class="px-4 py-3 text-right text-emerald-600">{{ stat.recent_successes }}</td>
|
|
<td class="px-4 py-3 text-right text-sky-600">{{ stat.oldest_successes }}</td>
|
|
<td class="px-4 py-3 text-right text-rose-600">{{ stat.failures }}</td>
|
|
<td class="px-4 py-3 text-right font-medium text-slate-800">
|
|
{{ stat.recent_successes + stat.oldest_successes + stat.failures }}
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
|
|
<script>
|
|
const ctx = document.getElementById('syncChart').getContext('2d');
|
|
const labels = {{ stats | map(attribute='date') | list | tojson }};
|
|
const recentSuccesses = {{ stats | map(attribute='recent_successes') | list | tojson }};
|
|
const oldestSuccesses = {{ stats | map(attribute='oldest_successes') | list | tojson }};
|
|
const failures = {{ stats | map(attribute='failures') | list | tojson }};
|
|
|
|
new Chart(ctx, {
|
|
type: 'bar',
|
|
data: {
|
|
labels: labels,
|
|
datasets: [
|
|
{
|
|
label: 'Recent Updates',
|
|
data: recentSuccesses,
|
|
backgroundColor: '#10b981',
|
|
stack: 'stack0'
|
|
},
|
|
{
|
|
label: 'Oldest Updates',
|
|
data: oldestSuccesses,
|
|
backgroundColor: '#0ea5e9',
|
|
stack: 'stack0'
|
|
},
|
|
{
|
|
label: 'Failures',
|
|
data: failures,
|
|
backgroundColor: '#f43f5e',
|
|
stack: 'stack0'
|
|
}
|
|
]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
plugins: {
|
|
legend: { display: false }
|
|
},
|
|
scales: {
|
|
x: {
|
|
stacked: true,
|
|
grid: { display: false }
|
|
},
|
|
y: {
|
|
stacked: true,
|
|
beginAtZero: true,
|
|
ticks: { stepSize: 1 }
|
|
}
|
|
}
|
|
}
|
|
});
|
|
</script>
|
|
{% endblock %} |