create_aio

This commit is contained in:
2025-09-27 09:33:40 +02:00
parent b5ad30cfbd
commit de22d7c0f2
13 changed files with 1387 additions and 907 deletions

View File

@@ -0,0 +1,39 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<title>Admin</title>
<script src="https://unpkg.com/htmx.org@1.9.12"></script>
<style>
:root { --bg:#0b1220; --card:#121a2b; --muted:#94a3b8; --text:#e5e7eb; --accent:#4f46e5; }
html,body { margin:0; background:var(--bg); color:var(--text); font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Ubuntu; }
.wrap { max-width: 980px; margin: 40px auto; padding: 0 16px; }
.nav { display:flex; gap:12px; margin-bottom:16px; }
.btn { background:var(--card); border:1px solid #243044; padding:8px 12px; border-radius:10px; color:var(--text); cursor:pointer; }
.btn:hover { border-color:#3b4a66; }
.btn-primary { background: var(--accent); border-color: var(--accent); color:white; }
.card { background:var(--card); border:1px solid #1f2937; border-radius:16px; padding:16px; box-shadow: 0 6px 30px rgba(0,0,0,.25); }
.row { display:flex; gap:16px; flex-wrap:wrap; }
table { width:100%; border-collapse: collapse; }
th, td { border-bottom: 1px solid #1f2937; padding:10px; text-align:left; }
input[type="text"] { background:#0f1626; border:1px solid #263246; color:var(--text); padding:8px 10px; border-radius:10px; width:100%; }
small { color: var(--muted); }
.muted { color: var(--muted); }
.pill { font-size: 12px; padding: 2px 8px; border:1px solid #2b364b; border-radius:999px; background:#0f1626; color:#bcd; }
</style>
</head>
<body>
<div class="wrap">
<h1 style="margin:0 0 10px 0;">Unified Admin</h1>
<div class="nav">
<button class="btn" hx-get="/admin/items" hx-target="#main" hx-swap="innerHTML">Dateien</button>
<button class="btn" hx-get="/admin/peers" hx-target="#main" hx-swap="innerHTML">Mesh</button>
</div>
<div id="main" class="card" hx-get="{{.Init}}" hx-trigger="load" hx-swap="innerHTML">
<div class="muted">Lade…</div>
</div>
<div style="margin-top:14px"><small>© Admin UI</small></div>
</div>
</body>
</html>

View File

@@ -0,0 +1,57 @@
<div class="row">
<div style="flex: 1 1 360px">
<form hx-post="/admin/items/create" hx-target="#items" hx-get="/admin/items" hx-swap="outerHTML">
<label>Neue Datei</label>
<div style="display:flex; gap:8px; margin-top:6px">
<input type="text" name="name" placeholder="z.B. notes.txt" required>
<button class="btn btn-primary" type="submit">Anlegen</button>
</div>
</form>
</div>
</div>
<div id="items" style="margin-top:14px">
<table>
<thead>
<tr>
<th>ID</th><th>Name</th><th>Updated</th><th style="width:200px">Aktionen</th>
</tr>
</thead>
<tbody>
{{ range .Items }}
<tr>
<td>{{ .ID }}</td>
<td>{{ .Name }}</td>
<td><small class="muted">{{ printf "%.19s" (timeRFC3339 .UpdatedAt) }}</small></td>
<td>
<form style="display:inline-flex; gap:6px"
hx-post="/admin/items/rename"
hx-target="#items" hx-get="/admin/items" hx-swap="outerHTML">
<input type="hidden" name="id" value="{{ .ID }}">
<input type="text" name="name" placeholder="Neuer Name">
<button class="btn" type="submit" title="Umbenennen">Rename</button>
</form>
<form style="display:inline"
hx-post="/admin/items/delete"
hx-target="#items" hx-get="/admin/items" hx-swap="outerHTML"
onsubmit="return confirm('Wirklich löschen?');">
<input type="hidden" name="id" value="{{ .ID }}">
<button class="btn" type="submit" title="Löschen">Delete</button>
</form>
</td>
</tr>
{{ else }}
<tr><td colspan="4" class="muted">Keine Dateien vorhanden.</td></tr>
{{ end }}
</tbody>
</table>
{{ if .Next }}
<div style="margin-top:10px">
<button class="btn"
hx-get="/admin/items?next={{ .Next }}"
hx-target="#items" hx-swap="outerHTML">Mehr laden</button>
<span class="pill">next={{ .Next }}</span>
</div>
{{ end }}
</div>

View File

@@ -0,0 +1,23 @@
<div style="display:flex; justify-content:space-between; align-items:center">
<h3 style="margin:0">Mesh Peers</h3>
<form hx-post="/admin/mesh/syncnow" hx-target="#peers" hx-get="/admin/peers" hx-swap="outerHTML">
<button class="btn btn-primary" type="submit">Jetzt synchronisieren</button>
</form>
</div>
<div id="peers" style="margin-top:10px">
<table>
<thead><tr><th>URL</th><th>Self</th><th>Last Seen</th></tr></thead>
<tbody>
{{ range .Peers }}
<tr>
<td>{{ .URL }}</td>
<td>{{ if .Self }}✅{{ else }}—{{ end }}</td>
<td><small class="muted">{{ .LastSeen }}</small></td>
</tr>
{{ else }}
<tr><td colspan="3" class="muted">Keine Peers bekannt.</td></tr>
{{ end }}
</tbody>
</table>
<div class="muted" style="margin-top:8px"><small>Stand: {{ .Now }}</small></div>
</div>