All checks were successful
Build and Push Image / build-and-push (push) Successful in 1m26s
223 lines
7.5 KiB
HTML
223 lines
7.5 KiB
HTML
{% extends "base.html" %}
|
||
|
||
{% block title %}Statistieken - Snauw Counter{% endblock %}
|
||
|
||
{% block head %}
|
||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||
{% endblock %}
|
||
|
||
{% block content %}
|
||
<h2>📈 Statistieken & Trends</h2>
|
||
|
||
<!-- Statistiek overzicht -->
|
||
<div class="stats-grid">
|
||
<div class="stat-card">
|
||
<span class="stat-number">{{ stats.total_incidents }}</span>
|
||
<span class="stat-label">Totaal incidenten</span>
|
||
</div>
|
||
<div class="stat-card">
|
||
<span class="stat-number">{{ stats.incidents_today }}</span>
|
||
<span class="stat-label">Vandaag</span>
|
||
</div>
|
||
<div class="stat-card">
|
||
<span class="stat-number">{{ stats.avg_severity }}</span>
|
||
<span class="stat-label">Gemiddelde Snauw-index</span>
|
||
</div>
|
||
<div class="stat-card">
|
||
<span class="stat-number">{{ stats.most_severe }}</span>
|
||
<span class="stat-label">Hoogste Snauw-index</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Trend grafiek -->
|
||
{% if stats.total_incidents > 0 %}
|
||
<div class="card">
|
||
<h3>📊 Trend laatste 7 dagen</h3>
|
||
<div class="chart-container">
|
||
<canvas id="trendChart"></canvas>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Periode statistieken -->
|
||
<div class="card">
|
||
<h3>📅 Periode overzicht</h3>
|
||
<div class="stats-grid">
|
||
<div class="stat-card">
|
||
<span class="stat-number">{{ stats.incidents_this_week }}</span>
|
||
<span class="stat-label">Deze week</span>
|
||
</div>
|
||
<div class="stat-card">
|
||
<span class="stat-number">{{ stats.incidents_this_month }}</span>
|
||
<span class="stat-label">Deze maand</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Recent incidents -->
|
||
<div class="card">
|
||
<h3>🕒 Recente incidenten</h3>
|
||
{% if incidents %}
|
||
<div style="max-height: 300px; overflow-y: auto;">
|
||
{% for incident in incidents[:10] %}
|
||
<div style="display: flex; justify-content: space-between; align-items: center; padding: 0.5rem 0; border-bottom: 1px solid #e9ecef;">
|
||
<div>
|
||
<strong>Snauw-index {{ incident.severity }}/5</strong>
|
||
{% if incident.notes %}
|
||
<br><small style="color: #6c757d;">{{ incident.notes[:50] }}{% if incident.notes|length > 50 %}...{% endif %}</small>
|
||
{% endif %}
|
||
</div>
|
||
<small style="color: #6c757d;">
|
||
{{ incident.timestamp.strftime('%d/%m %H:%M') }}
|
||
</small>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
{% if incidents|length > 10 %}
|
||
<p style="margin-top: 1rem; color: #6c757d; text-align: center;">
|
||
En {{ incidents|length - 10 }} andere incidenten...
|
||
</p>
|
||
{% endif %}
|
||
{% else %}
|
||
<p style="color: #6c757d;">Nog geen incidenten geregistreerd</p>
|
||
{% endif %}
|
||
</div>
|
||
|
||
{% else %}
|
||
<!-- Geen data yet -->
|
||
<div class="card" style="text-align: center; padding: 3rem;">
|
||
<h3>📊 Nog geen statistieken</h3>
|
||
<p style="color: #6c757d; margin-bottom: 2rem;">
|
||
Registreer je eerste incident om statistieken te zien
|
||
</p>
|
||
<a href="{{ url_for('main.index') }}" class="btn">📝 Eerste incident toevoegen</a>
|
||
</div>
|
||
{% endif %}
|
||
|
||
<!-- GDPR compliance section -->
|
||
<div class="card" style="border-left: 4px solid #ffc107;">
|
||
<h4>🔒 Privacy & Gegevensbeheer</h4>
|
||
<p>Je hebt altijd controle over je gegevens:</p>
|
||
|
||
<div style="display: flex; gap: 0.5rem; flex-wrap: wrap; margin-top: 1rem;">
|
||
<button onclick="exportData()" class="btn btn-secondary">📥 Data exporteren</button>
|
||
|
||
{% if current_user.is_authenticated %}
|
||
<form action="{{ url_for('main.delete_account') }}" method="POST" style="display: inline;"
|
||
onsubmit="return confirm('Type DELETE om te bevestigen') && prompt('Type DELETE:') === 'DELETE'">
|
||
<input type="hidden" name="confirm" value="DELETE">
|
||
<button type="submit" class="btn btn-danger">🗑️ Account verwijderen</button>
|
||
</form>
|
||
{% else %}
|
||
<button onclick="deleteAllData()" class="btn btn-danger">🗑️ Alle data wissen</button>
|
||
{% endif %}
|
||
</div>
|
||
|
||
<p style="margin-top: 1rem; font-size: 0.9rem; color: #6c757d;">
|
||
<a href="{{ url_for('main.privacy') }}" style="color: inherit;">Privacy beleid</a> |
|
||
Conform AVG/GDPR
|
||
</p>
|
||
</div>
|
||
{% endblock %}
|
||
|
||
{% block scripts %}
|
||
<script>
|
||
// Mark body as authenticated for JavaScript
|
||
document.body.dataset.isAuthenticated = {{ 'true' if current_user.is_authenticated else 'false' }};
|
||
|
||
{% if stats.total_incidents > 0 %}
|
||
// Chart.js implementation
|
||
const trendData = {{ stats.trend_data | tojson }};
|
||
|
||
const ctx = document.getElementById('trendChart').getContext('2d');
|
||
new Chart(ctx, {
|
||
type: 'bar',
|
||
data: {
|
||
labels: trendData.map(d => d.date),
|
||
datasets: [{
|
||
label: 'Aantal incidenten',
|
||
data: trendData.map(d => d.count),
|
||
backgroundColor: 'rgba(102, 126, 234, 0.6)',
|
||
borderColor: 'rgba(102, 126, 234, 1)',
|
||
borderWidth: 2,
|
||
yAxisID: 'y'
|
||
}, {
|
||
label: 'Gemiddelde Snauw-index',
|
||
data: trendData.map(d => d.avg_severity),
|
||
type: 'line',
|
||
borderColor: 'rgba(220, 53, 69, 1)',
|
||
backgroundColor: 'rgba(220, 53, 69, 0.1)',
|
||
borderWidth: 3,
|
||
fill: false,
|
||
yAxisID: 'y1'
|
||
}]
|
||
},
|
||
options: {
|
||
responsive: true,
|
||
maintainAspectRatio: false,
|
||
plugins: {
|
||
title: {
|
||
display: true,
|
||
text: 'Incident Trends (Laatste 7 dagen)'
|
||
},
|
||
legend: {
|
||
display: true
|
||
}
|
||
},
|
||
scales: {
|
||
y: {
|
||
type: 'linear',
|
||
display: true,
|
||
position: 'left',
|
||
beginAtZero: true,
|
||
title: {
|
||
display: true,
|
||
text: 'Aantal incidenten'
|
||
}
|
||
},
|
||
y1: {
|
||
type: 'linear',
|
||
display: true,
|
||
position: 'right',
|
||
min: 0,
|
||
max: 5,
|
||
title: {
|
||
display: true,
|
||
text: 'Gemiddelde Snauw-index'
|
||
},
|
||
grid: {
|
||
drawOnChartArea: false,
|
||
}
|
||
}
|
||
},
|
||
interaction: {
|
||
mode: 'index',
|
||
intersect: false,
|
||
}
|
||
}
|
||
});
|
||
{% endif %}
|
||
|
||
// Load anonymous user data if not authenticated
|
||
if (!{{ 'true' if current_user.is_authenticated else 'false' }}) {
|
||
// This would enhance the statistics with localStorage data
|
||
enhanceWithLocalData();
|
||
}
|
||
|
||
function enhanceWithLocalData() {
|
||
// For anonymous users, we could enhance server statistics
|
||
// with localStorage data that might not be synced yet
|
||
const localIncidents = JSON.parse(localStorage.getItem('snauw_incidents') || '[]');
|
||
|
||
if (localIncidents.length > 0) {
|
||
// Add notification about local data
|
||
const notice = document.createElement('div');
|
||
notice.className = 'alert alert-info';
|
||
notice.innerHTML = `
|
||
ℹ️ Je hebt ${localIncidents.length} lokaal opgeslagen incidenten.
|
||
<a href="{{ url_for('main.register') }}">Maak een account</a> om deze veilig op te slaan.
|
||
`;
|
||
document.querySelector('main').insertBefore(notice, document.querySelector('main').firstChild);
|
||
}
|
||
}
|
||
</script>
|
||
{% endblock %}
|