Dateien
Hetzner-Backup/v2_adminpanel/templates/sessions.html
2025-06-18 01:35:54 +02:00

183 Zeilen
8.2 KiB
HTML

{% extends "base.html" %}
{% block title %}Session-Tracking{% endblock %}
{% macro active_sortable_header(label, field, current_sort, current_order) %}
<th>
{% if current_sort == field %}
<a href="{{ url_for('sessions.sessions', active_sort=field, active_order='desc' if current_order == 'asc' else 'asc', ended_sort=ended_sort, ended_order=ended_order) }}"
class="server-sortable">
{% else %}
<a href="{{ url_for('sessions.sessions', active_sort=field, active_order='asc', ended_sort=ended_sort, ended_order=ended_order) }}"
class="server-sortable">
{% endif %}
{{ label }}
<span class="sort-indicator{% if current_sort == field %} active{% endif %}">
{% if current_sort == field %}
{% if current_order == 'asc' %}↑{% else %}↓{% endif %}
{% else %}
{% endif %}
</span>
</a>
</th>
{% endmacro %}
{% macro ended_sortable_header(label, field, current_sort, current_order) %}
<th>
{% if current_sort == field %}
<a href="{{ url_for('sessions.sessions', active_sort=active_sort, active_order=active_order, ended_sort=field, ended_order='desc' if current_order == 'asc' else 'asc') }}"
class="server-sortable">
{% else %}
<a href="{{ url_for('sessions.sessions', active_sort=active_sort, active_order=active_order, ended_sort=field, ended_order='asc') }}"
class="server-sortable">
{% endif %}
{{ label }}
<span class="sort-indicator{% if current_sort == field %} active{% endif %}">
{% if current_sort == field %}
{% if current_order == 'asc' %}↑{% else %}↓{% endif %}
{% else %}
{% endif %}
</span>
</a>
</th>
{% endmacro %}
{% block extra_css %}
<style>
.session-active { background-color: #d4edda; }
.session-warning { background-color: #fff3cd; }
.session-inactive { background-color: #f8f9fa; }
</style>
{% endblock %}
{% block content %}
<div class="container py-5">
<div class="d-flex justify-content-between align-items-center mb-4">
<h2>Session-Tracking</h2>
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown">
<i class="bi bi-download"></i> Export
</button>
<ul class="dropdown-menu">
<li><h6 class="dropdown-header">Aktive Sessions</h6></li>
<li><a class="dropdown-item" href="{{ url_for('export.export_sessions', type='active', format='excel') }}">
<i class="bi bi-file-earmark-excel text-success"></i> Excel Export</a></li>
<li><a class="dropdown-item" href="{{ url_for('export.export_sessions', type='active', format='csv') }}">
<i class="bi bi-file-earmark-text"></i> CSV Export</a></li>
<li><hr class="dropdown-divider"></li>
<li><h6 class="dropdown-header">Beendete Sessions</h6></li>
<li><a class="dropdown-item" href="{{ url_for('export.export_sessions', type='ended', format='excel') }}">
<i class="bi bi-file-earmark-excel text-success"></i> Excel Export</a></li>
<li><a class="dropdown-item" href="{{ url_for('export.export_sessions', type='ended', format='csv') }}">
<i class="bi bi-file-earmark-text"></i> CSV Export</a></li>
</ul>
</div>
</div>
<!-- Aktive Sessions -->
<div class="card mb-4">
<div class="card-header bg-success text-white">
<h5 class="mb-0">🟢 Aktive Sessions ({{ active_sessions|length }})</h5>
</div>
<div class="card-body">
{% if active_sessions %}
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Kunde</th>
<th>Lizenz</th>
<th>IP-Adresse</th>
<th>Gestartet</th>
<th>Letzter Heartbeat</th>
<th>Inaktiv seit</th>
<th>Aktion</th>
</tr>
</thead>
<tbody>
{% for session in active_sessions %}
<tr class="{% if session[8] > 5 %}session-warning{% else %}session-active{% endif %}">
<td>{{ session[3] }}</td>
<td><small><code>{{ session[2][:12] }}...</code></small></td>
<td>{{ session[4] or '-' }}</td>
<td>{{ session[6].strftime('%d.%m %H:%M') }}</td>
<td>{{ session[7].strftime('%d.%m %H:%M') }}</td>
<td>
{% if session[8] < 1 %}
<span class="badge bg-success">Aktiv</span>
{% elif session[8] < 5 %}
<span class="badge bg-warning">{{ session[8]|round|int }} Min.</span>
{% else %}
<span class="badge bg-danger">{{ session[8]|round|int }} Min.</span>
{% endif %}
</td>
<td>
<form method="post" action="{{ url_for('sessions.end_session', session_id=session[0]) }}" style="display: inline;">
<button type="submit" class="btn btn-sm btn-outline-danger"
onclick="return confirm('Session wirklich beenden?');">
⏹️ Beenden
</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<small class="text-muted">
Sessions gelten als inaktiv nach 5 Minuten ohne Heartbeat
</small>
{% else %}
<p class="text-muted mb-0">Keine aktiven Sessions vorhanden.</p>
{% endif %}
</div>
</div>
<!-- Beendete Sessions -->
<div class="card">
<div class="card-header bg-secondary text-white">
<h5 class="mb-0">⏸️ Beendete Sessions (letzte 24 Stunden)</h5>
</div>
<div class="card-body">
{% if recent_sessions %}
<div class="table-responsive">
<table class="table table-sm">
<thead>
<tr>
<th>Kunde</th>
<th>Lizenz</th>
<th>IP-Adresse</th>
<th>Gestartet</th>
<th>Beendet</th>
<th>Dauer</th>
</tr>
</thead>
<tbody>
{% for session in recent_sessions %}
<tr class="session-inactive">
<td>{{ session[3] }}</td>
<td><small><code>{{ session[2][:12] }}...</code></small></td>
<td>{{ session[4] or '-' }}</td>
<td>{{ session[5].strftime('%d.%m %H:%M') }}</td>
<td>{{ session[6].strftime('%d.%m %H:%M') }}</td>
<td>
{% if session[7] < 60 %}
{{ session[7]|round|int }} Min.
{% else %}
{{ (session[7]/60)|round(1) }} Std.
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<p class="text-muted mb-0">Keine beendeten Sessions in den letzten 24 Stunden.</p>
{% endif %}
</div>
</div>
</div>
{% endblock %}