feat: production-ready domain control dashboard
Container-Image veröffentlichen / container (push) Has been cancelled

This commit is contained in:
admin committed 2026-07-12 20:56:45 +02:00
1 parent 9c60eaf3fe
commit df7516e7ab
45 files changed
+7932 -1

No files matched your search

+71
View File
@@ -0,0 +1,71 @@
{{define "layout"}}
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="color-scheme" content="light">
<title>{{.Title}} · Hetzner DynDNS</title>
<link rel="stylesheet" href="/static/styles.css?v=features-5">
<script src="/static/app.js?v=features-5" defer></script>
</head>
<body class="page-{{.Page}}">
<a class="skip-link" href="#main">Zum Inhalt springen</a>
{{if and (ne .Page "setup") (ne .Page "login")}}
<div class="admin-layout">
<aside class="sidebar">
<a class="brand" href="/" aria-label="Hetzner DynDNS Startseite">
<span class="brand-mark">DD</span>
<span><strong>DynDNS Console</strong><small>Hetzner DNS</small></span>
</a>
<div class="instance-state {{if not .UpdaterEnabled}}is-inactive{{end}}"><span></span> Dienst {{if .UpdaterEnabled}}aktiv{{else}}inaktiv{{end}}</div>
<nav aria-label="Hauptnavigation">
<a href="/" {{if eq .Page "dashboard"}}aria-current="page"{{end}}><span class="nav-icon">01</span>Übersicht</a>
<a href="/domains" {{if eq .Page "domains"}}aria-current="page"{{end}}><span class="nav-icon">02</span>Domains</a>
{{if .IsAdmin}}
<a href="/settings" {{if eq .Page "settings"}}aria-current="page"{{end}}><span class="nav-icon">03</span>Updater</a>
<a href="/errors" {{if eq .Page "errors"}}aria-current="page"{{end}}><span class="nav-icon">04</span>Fehler</a>
<a href="/users" {{if eq .Page "users"}}aria-current="page"{{end}}><span class="nav-icon">05</span>Benutzer</a>
{{end}}
<a href="/security" {{if eq .Page "security"}}aria-current="page"{{end}}><span class="nav-icon">{{if .IsAdmin}}06{{else}}03{{end}}</span>Sicherheit</a>
</nav>
<div class="sidebar-account">
<span class="account-avatar">{{initial .User.DisplayName}}</span>
<span><strong>{{.User.DisplayName}}</strong><small>@{{.User.Username}} · {{if .IsAdmin}}Admin{{else}}Mitglied{{end}}</small></span>
<form action="/logout" method="post">
<input type="hidden" name="csrf" value="{{.CSRF}}">
<button type="submit" title="Abmelden" aria-label="Abmelden">↪</button>
</form>
</div>
</aside>
<div class="workspace">
<header class="workspace-bar">
<div><span>DynDNS</span><strong>/ {{.Title}}</strong></div>
{{if eq .Mode "lan"}}<span class="environment-badge">LAN · HTTP</span>{{else}}<span class="environment-badge secure">HTTPS</span>{{end}}
</header>
<main id="main" class="app-shell">
{{template "content" .}}
</main>
</div>
</div>
{{else}}
<main id="main" class="auth-shell">
{{template "content" .}}
</main>
{{end}}
{{if .Flash}}
<div class="toast-region">
<div class="toast toast-{{.Flash.Kind}}" data-toast role="{{if eq .Flash.Kind "error"}}alert{{else}}status{{end}}" aria-atomic="true">
<span class="toast-icon" aria-hidden="true">{{if eq .Flash.Kind "error"}}!{{else if eq .Flash.Kind "info"}}i{{else}}✓{{end}}</span>
<div class="toast-copy">
<span class="toast-eyebrow">{{if eq .Flash.Kind "error"}}Bitte prüfen{{else if eq .Flash.Kind "info"}}Hinweis{{else}}Erledigt{{end}}</span>
<p>{{.Flash.Message}}</p>
</div>
<button class="toast-close" type="button" data-toast-close aria-label="Meldung schließen">×</button>
<span class="toast-progress" aria-hidden="true"></span>
</div>
</div>
{{end}}
</body>
</html>
{{end}}