feat: UI redesign (CSS system, DNS widget, Traefik dashboard widget)

- Replace base.html style block with full CSS design system using custom properties (dark theme, cards, tables, badges, dots, widgets)
- Add DNS blueprint (fablednetmon/dns/) with /dns/ and /dns/rows routes + templates
- Add Traefik /widget route and widget.html fragment for dashboard
- Update dashboard: DNS + Traefik widgets, traefik_enabled config detection
- Update all templates to use new CSS classes (page-title, section-title, card-flush, table, badge-*, dot-*, btn-*)
- Register dns_bp in app.py

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-18 23:37:46 -04:00
parent d29c5b3eab
commit 165a202ba4
22 changed files with 495 additions and 236 deletions
+16
View File
@@ -0,0 +1,16 @@
{% extends "base.html" %}
{% block title %}DNS Monitor — FabledNetMon{% endblock %}
{% block content %}
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:1.5rem;">
<h1 class="page-title" style="margin-bottom:0;">DNS Monitor</h1>
<span style="color:var(--text-muted);font-size:0.85rem;">polling every {{ poll_interval }}s</span>
</div>
<div class="card ping-card">
<div id="dns-rows"
hx-get="/dns/rows"
hx-trigger="every {{ poll_interval }}s"
hx-swap="innerHTML">
{% include "dns/rows.html" %}
</div>
</div>
{% endblock %}
+29
View File
@@ -0,0 +1,29 @@
{% if hosts %}
{% for host in hosts %}
{% set d = latest.get(host.id) %}
<div class="ping-row">
<div class="ping-meta">
<span class="ping-name">{{ host.name }}</span>
<span class="ping-addr">{{ host.address }}</span>
</div>
<div style="flex:1;">
{% if d is none %}
<span style="color:var(--text-dim);font-size:0.85rem;"></span>
{% elif d.status.value == 'resolved' %}
<span class="dot dot-up" style="margin-right:0.5rem;"></span>
<span style="font-size:0.85rem;color:var(--green);">{{ d.resolved_ip or 'resolved' }}</span>
{% else %}
<span class="dot dot-down" style="margin-right:0.5rem;"></span>
<span style="font-size:0.85rem;color:var(--red);">Failed</span>
{% endif %}
</div>
<div class="ping-cur">
{% if d %}
<span style="color:var(--text-muted);font-size:0.75rem;">{{ d.resolved_at.strftime('%H:%M:%S') }} UTC</span>
{% endif %}
</div>
</div>
{% endfor %}
{% else %}
<p class="empty" style="padding:0.5rem 0;">No DNS-enabled hosts. <a href="/hosts/">Enable DNS on a host →</a></p>
{% endif %}