160 lines
4.2 KiB
HTML
160 lines
4.2 KiB
HTML
{# templates/connections.html #}
|
|
{% extends 'base.html' %}
|
|
|
|
{% block title %}Recent Connections{% endblock %}
|
|
{% block page_id %}connections{% endblock %}
|
|
|
|
{% block head_extra %}
|
|
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" data-page-head />
|
|
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" data-page-head></script>
|
|
<script src="https://cdn.socket.io/4.0.0/socket.io.min.js" data-page-head></script>
|
|
<style data-page-head>
|
|
/* page-specific styles */
|
|
.split-view {
|
|
display: flex;
|
|
gap: 20px;
|
|
height: 85vh;
|
|
}
|
|
.map-section {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-width: 0;
|
|
min-height: 0;
|
|
}
|
|
.table-section {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-width: 0;
|
|
}
|
|
#map {
|
|
width: 100%;
|
|
flex: 1;
|
|
height: auto;
|
|
min-height: 320px;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
|
|
}
|
|
.section-header {
|
|
background: white;
|
|
padding: 15px;
|
|
border-radius: 8px;
|
|
margin-bottom: 15px;
|
|
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
|
|
}
|
|
.page-content {
|
|
padding: 20px;
|
|
}
|
|
.stats {
|
|
display: flex;
|
|
gap: 20px;
|
|
flex-wrap: wrap;
|
|
margin-top: 10px;
|
|
}
|
|
.stat-item {
|
|
flex: 1;
|
|
min-width: 120px;
|
|
}
|
|
.stat-label {
|
|
font-size: 11px;
|
|
color: #666;
|
|
text-transform: uppercase;
|
|
}
|
|
.stat-value {
|
|
font-size: 20px;
|
|
font-weight: bold;
|
|
color: #333;
|
|
}
|
|
.table-container {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
background: white;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
|
|
}
|
|
#connectionsTableBody {
|
|
transition: transform 0.5s ease-out;
|
|
transform: translateY(0);
|
|
}
|
|
@keyframes slideIn {
|
|
0% { opacity: 0; transform: scale(0.8); }
|
|
100% { opacity: 1; transform: scale(1); }
|
|
}
|
|
.slide-in { animation: slideIn 0.5s ease-out; }
|
|
@keyframes slideOut {
|
|
0% { opacity: 1; transform: scale(1); }
|
|
100% { opacity: 0; transform: scale(0.1); }
|
|
}
|
|
.slide-out { animation: slideOut 0.5s ease-in forwards; }
|
|
|
|
@media (max-width: 1200px) {
|
|
.split-view {
|
|
flex-direction: column;
|
|
height: auto;
|
|
}
|
|
.map-section, .table-section {
|
|
min-height: 400px;
|
|
}
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="page-content">
|
|
<div class="section-header">
|
|
<h2 style="margin: 0;">Verbindungen der letzten 10 Minuten (nur Audio)</h2>
|
|
<p class="text-muted" style="margin: 4px 0 0 0;">Diese Ansicht listet ausschließlich Zugriffe auf Audio-Dateien.</p>
|
|
<div class="stats">
|
|
<div class="stat-item">
|
|
<div class="stat-label">Last Connection</div>
|
|
<div class="stat-value" id="last-connection" style="font-size: 14px;">-</div>
|
|
</div>
|
|
<div class="stat-item">
|
|
<div class="stat-label">Total Connections</div>
|
|
<div class="stat-value" id="totalConnections">0</div>
|
|
</div>
|
|
<div class="stat-item">
|
|
<div class="stat-label">Total File Size</div>
|
|
<div class="stat-value" id="totalSize">0 B</div>
|
|
</div>
|
|
<div class="stat-item">
|
|
<div class="stat-label">Cached %</div>
|
|
<div class="stat-value" id="cachedPercent">0%</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="split-view">
|
|
<!-- Map Section -->
|
|
<div class="map-section">
|
|
<div id="map"></div>
|
|
</div>
|
|
|
|
<!-- Table Section -->
|
|
<div class="table-section">
|
|
<div class="table-container">
|
|
<table class="table table-hover">
|
|
<thead class="table-secondary">
|
|
<tr>
|
|
<th>Timestamp</th>
|
|
<th>Location</th>
|
|
<th>User Agent</th>
|
|
<th>File Path</th>
|
|
<th>File Size</th>
|
|
<th>MIME-Typ</th>
|
|
<th>Cached</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="connectionsTableBody">
|
|
{# dynamically populated via Socket.IO #}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block scripts %}{% endblock %}
|