193 Zeilen
5.6 KiB
HTML
193 Zeilen
5.6 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Analytics{% endblock %}
|
|
|
|
{% block extra_css %}
|
|
<style>
|
|
.analytics-card {
|
|
background: white;
|
|
border-radius: 10px;
|
|
padding: 20px;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
margin-bottom: 20px;
|
|
height: 100%;
|
|
}
|
|
|
|
.chart-container {
|
|
position: relative;
|
|
height: 300px;
|
|
margin-top: 20px;
|
|
}
|
|
|
|
.stat-box {
|
|
text-align: center;
|
|
padding: 15px;
|
|
background: #f8f9fa;
|
|
border-radius: 8px;
|
|
margin-bottom: 15px;
|
|
}
|
|
|
|
.stat-value {
|
|
font-size: 2rem;
|
|
font-weight: bold;
|
|
color: #495057;
|
|
}
|
|
|
|
.stat-label {
|
|
font-size: 0.875rem;
|
|
color: #6c757d;
|
|
text-transform: uppercase;
|
|
margin-top: 5px;
|
|
}
|
|
|
|
.trend-up {
|
|
color: #28a745;
|
|
}
|
|
|
|
.trend-down {
|
|
color: #dc3545;
|
|
}
|
|
|
|
.date-range-selector {
|
|
background: white;
|
|
padding: 15px;
|
|
border-radius: 8px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.export-buttons {
|
|
margin-top: 20px;
|
|
}
|
|
|
|
.loading-spinner {
|
|
text-align: center;
|
|
padding: 50px;
|
|
}
|
|
|
|
.no-data {
|
|
text-align: center;
|
|
padding: 30px;
|
|
color: #6c757d;
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="row mb-4">
|
|
<div class="col">
|
|
<h2><i class="bi bi-bar-chart-line"></i> Analytics</h2>
|
|
<p class="text-muted">Detaillierte Analyse und Berichte</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Date Range Selector -->
|
|
<div class="date-range-selector">
|
|
<div class="row align-items-center">
|
|
<div class="col-md-6">
|
|
<label>Zeitraum auswählen:</label>
|
|
<select class="form-select" id="date-range" onchange="updateAnalytics()">
|
|
<option value="today">Heute</option>
|
|
<option value="week" selected>Letzte 7 Tage</option>
|
|
<option value="month">Letzte 30 Tage</option>
|
|
<option value="quarter">Letztes Quartal</option>
|
|
<option value="year">Letztes Jahr</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-6 text-end">
|
|
<button class="btn btn-outline-primary" onclick="refreshAnalytics()">
|
|
<i class="bi bi-arrow-clockwise"></i> Aktualisieren
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Key Metrics Overview -->
|
|
<div class="row mb-4">
|
|
<div class="col-md-4">
|
|
<div class="stat-box">
|
|
<div class="stat-value" id="active-licenses">-</div>
|
|
<div class="stat-label">Aktive Lizenzen</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="stat-box">
|
|
<div class="stat-value" id="total-validations">-</div>
|
|
<div class="stat-label">Validierungen</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="stat-box">
|
|
<div class="stat-value" id="active-devices">-</div>
|
|
<div class="stat-label">Aktive Geräte</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Analytics Notice -->
|
|
<div class="analytics-card">
|
|
<div class="no-data">
|
|
<i class="bi bi-info-circle" style="font-size: 3rem; color: #6c757d;"></i>
|
|
<h5 class="mt-3">Analytics-Daten werden gesammelt</h5>
|
|
<p>Die detaillierten Analysen stehen zur Verfügung, sobald genügend Daten vorhanden sind.</p>
|
|
<p>Nutzen Sie das <a href="{{ url_for('monitoring.live_dashboard') }}">Live Dashboard</a> für Echtzeit-Statistiken.</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Export Options -->
|
|
<div class="analytics-card mt-4">
|
|
<h5>Berichte exportieren</h5>
|
|
<div class="export-buttons">
|
|
<button class="btn btn-outline-primary me-2" onclick="exportReport('pdf')">
|
|
<i class="bi bi-file-pdf"></i> PDF Export
|
|
</button>
|
|
<button class="btn btn-outline-success me-2" onclick="exportReport('excel')">
|
|
<i class="bi bi-file-excel"></i> Excel Export
|
|
</button>
|
|
<button class="btn btn-outline-info" onclick="exportReport('csv')">
|
|
<i class="bi bi-file-text"></i> CSV Export
|
|
</button>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block extra_js %}
|
|
<script>
|
|
function loadAnalyticsData() {
|
|
// Load basic statistics from database
|
|
fetch('/monitoring/api/live-stats')
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
document.getElementById('active-licenses').textContent = data.active_licenses || '0';
|
|
document.getElementById('total-validations').textContent = data.validations_last_minute || '0';
|
|
document.getElementById('active-devices').textContent = data.active_devices || '0';
|
|
})
|
|
.catch(error => {
|
|
console.error('Error loading analytics:', error);
|
|
document.getElementById('active-licenses').textContent = '0';
|
|
document.getElementById('total-validations').textContent = '0';
|
|
document.getElementById('active-devices').textContent = '0';
|
|
});
|
|
}
|
|
|
|
function updateAnalytics() {
|
|
const range = document.getElementById('date-range').value;
|
|
console.log('Updating analytics for range:', range);
|
|
loadAnalyticsData();
|
|
}
|
|
|
|
function refreshAnalytics() {
|
|
loadAnalyticsData();
|
|
}
|
|
|
|
function exportReport(format) {
|
|
alert(`Export-Funktion wird implementiert für Format: ${format.toUpperCase()}`);
|
|
}
|
|
|
|
// Load data on page load
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
loadAnalyticsData();
|
|
// Refresh every 30 seconds
|
|
setInterval(loadAnalyticsData, 30000);
|
|
});
|
|
</script>
|
|
{% endblock %} |