restrukturierung
This commit is contained in:
13
raspi/templates/base.html
Normal file
13
raspi/templates/base.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title>{% block title %}Smart Mirror{% endblock %}</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/mirror.css') }}"/>
|
||||
{% block extra_head %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
{% block body %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
141
raspi/templates/dashboard.html
Normal file
141
raspi/templates/dashboard.html
Normal file
@@ -0,0 +1,141 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{{ title }}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
{# Root element carries config as data-attributes for dashboard.js #}
|
||||
<div id="mirror-root"
|
||||
data-poll-ms="{{ poll_ms }}"
|
||||
data-sensors="{{ sensors_json | e }}">
|
||||
|
||||
<div class="mirror-layout">
|
||||
|
||||
{# ══════════════════════════════════
|
||||
HEADER — clock + connection badge
|
||||
══════════════════════════════════ #}
|
||||
<header class="mirror-header glass">
|
||||
|
||||
<span class="mirror-title">{{ title }}</span>
|
||||
|
||||
<div class="mirror-clock">
|
||||
<div class="clock-time" id="clock-time">00:00:00</div>
|
||||
<div class="clock-date" id="clock-date">—</div>
|
||||
</div>
|
||||
|
||||
<div class="conn-badge glass" id="conn-badge">
|
||||
<div class="conn-dot" id="conn-dot"></div>
|
||||
<span id="conn-text">Verbinde …</span>
|
||||
</div>
|
||||
|
||||
</header>
|
||||
|
||||
|
||||
{# ══════════════════════════════════
|
||||
BODY — sensors / chart / log
|
||||
══════════════════════════════════ #}
|
||||
<main class="mirror-body">
|
||||
|
||||
{# ── Sensor tiles (one per configured sensor) ── #}
|
||||
{% for s in sensors %}
|
||||
<div class="sensor-tile glass" id="sc-{{ loop.index0 }}">
|
||||
<div class="sensor-label">{{ s.name }}</div>
|
||||
<div class="sensor-value" id="sv-{{ loop.index0 }}">–</div>
|
||||
<div class="sensor-threshold">
|
||||
{%- if s.threshold_low is not none -%}
|
||||
↓ {{ s.threshold_low }}{{ s.unit }}
|
||||
{%- endif -%}
|
||||
{%- if s.threshold_high is not none -%}
|
||||
↑ {{ s.threshold_high }}{{ s.unit }}
|
||||
{%- endif -%}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
{# ── Stat row ── #}
|
||||
<div class="stat-row">
|
||||
|
||||
<div class="stat-card glass">
|
||||
<div class="stat-label">Letzter Wert</div>
|
||||
<div class="stat-value" id="stat-last">–</div>
|
||||
<div class="stat-sub" id="stat-ts">–</div>
|
||||
</div>
|
||||
|
||||
<div class="stat-card glass">
|
||||
<div class="stat-label">Zeilen gesamt</div>
|
||||
<div class="stat-value" id="stat-total">0</div>
|
||||
<div class="stat-sub">empfangen</div>
|
||||
</div>
|
||||
|
||||
<div class="stat-card glass">
|
||||
<div class="stat-label">Fehler</div>
|
||||
<div class="stat-value red" id="stat-errors">0</div>
|
||||
<div class="stat-sub">Verbindungsabbrüche</div>
|
||||
</div>
|
||||
|
||||
<div class="stat-card glass">
|
||||
<div class="stat-label">Verbindung</div>
|
||||
<div class="stat-value" id="stat-port" style="font-size:1rem;padding-top:.35rem">–</div>
|
||||
<div class="stat-sub" id="stat-baud">–</div>
|
||||
</div>
|
||||
|
||||
</div>{# /stat-row #}
|
||||
|
||||
|
||||
{# ── Chart panel ── #}
|
||||
<div class="chart-panel glass">
|
||||
<div class="panel-label">Verlauf — Kanal 1 (letzte 80 Messpunkte)</div>
|
||||
<canvas id="chart"></canvas>
|
||||
</div>
|
||||
|
||||
|
||||
{# ── Log + Alerts panel ── #}
|
||||
<div class="log-panel glass">
|
||||
|
||||
<div class="tab-bar">
|
||||
<div class="tab active" data-tab="log" onclick="switchTab('log')">Rohdaten</div>
|
||||
<div class="tab" data-tab="alerts" onclick="switchTab('alerts')">
|
||||
Alerts
|
||||
<span class="alert-badge" id="alert-badge"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-body">
|
||||
<div class="tab-pane active" id="pane-log">
|
||||
<div class="log-entry" style="color:var(--frost-ghost)">
|
||||
<span>Warte auf Daten …</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane" id="pane-alerts">
|
||||
<div class="alert-entry" style="color:var(--frost-ghost)">
|
||||
<span>Keine Alerts.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>{# /log-panel #}
|
||||
|
||||
</main>{# /mirror-body #}
|
||||
|
||||
|
||||
{# ══════════════════════════════════
|
||||
FOOTER
|
||||
══════════════════════════════════ #}
|
||||
<footer class="mirror-footer">
|
||||
<span>Smart Mirror · Arduino USB Monitor</span>
|
||||
<span id="footer-ts">–</span>
|
||||
</footer>
|
||||
|
||||
</div>{# /mirror-layout #}
|
||||
|
||||
</div>{# /mirror-root #}
|
||||
|
||||
<script src="{{ url_for('static', filename='js/dashboard.js') }}"></script>
|
||||
|
||||
{# Keep footer timestamp fresh #}
|
||||
<script>
|
||||
setInterval(() => {
|
||||
document.getElementById('footer-ts').textContent =
|
||||
new Date().toLocaleString('de-DE');
|
||||
}, 1000);
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user