Feature: HTMX + Jinja2 Frontend ersetzt Next.js komplett

- Kein Node.js, kein npm, kein Build-Schritt mehr
- HTMX 2.0.4 + PicoCSS 2 vendored in backend/static/
- Jinja2 Templates für alle 9 Seiten (Dashboard, ZFS, Snapshots,
  Shares, Identities, Logs, Services, Navigator, Login)
- HTMX Fragments für Live-Updates (30s Polling Dashboard)
- JWT als httpOnly Cookie statt localStorage
- Disk Usage zeigt TB/PB korrekt (Jinja2 serverseitig formatiert)
- Update-safe: nur Python-Deps, keine npm-Abhängigkeiten

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-05 18:45:46 +02:00
parent 654df5b98f
commit 5ecd143535
44 changed files with 1123 additions and 6129 deletions
@@ -0,0 +1,40 @@
{% macro fmt_bytes(b) %}
{%- if b == 0 %}0 B
{%- elif b < 1024 %}{{ b }} B
{%- elif b < 1048576 %}{{ "%.1f"|format(b/1024) }} KB
{%- elif b < 1073741824 %}{{ "%.1f"|format(b/1048576) }} MB
{%- elif b < 1099511627776 %}{{ "%.1f"|format(b/1073741824) }} GB
{%- else %}{{ "%.1f"|format(b/1099511627776) }} TB
{%- endif %}
{%- endmacro %}
<div class="stat-card">
<h3>CPU Load</h3>
<p class="value">{{ cpu.load_average[0] if cpu.load_average else '' }}</p>
<small>{{ cpu.count }} Kerne</small>
</div>
<div class="stat-card">
<h3>RAM</h3>
<p class="value">{{ fmt_bytes(mem.used) }}</p>
<small>von {{ fmt_bytes(mem.total) }}</small>
{% set pct = (mem.used / mem.total * 100)|int if mem.total else 0 %}
<div class="progress-bar-wrap" style="margin-top:0.4rem">
<div class="progress-bar {% if pct > 85 %}bar-red{% elif pct > 70 %}bar-yellow{% else %}bar-blue{% endif %}" style="width:{{ pct }}%"></div>
</div>
</div>
<div class="stat-card">
<h3>Uptime</h3>
<p class="value">{{ uptime.uptime_string if uptime else '' }}</p>
</div>
<div class="stat-card">
<h3>Pools</h3>
<p class="value">{{ pools|length }}</p>
<small>
{% for p in pools %}
<span class="badge {% if p.health == 'ONLINE' %}badge-green{% elif p.health == 'DEGRADED' %}badge-yellow{% else %}badge-red{% endif %}">{{ p.name }}</span>
{% endfor %}
</small>
</div>