Files
grotti/web/templates/setup.html
T
Dominic Gundel 4ddffbbeb1 Grotti 3.2.0: Jetzt-Liste, Filament-Pause, Strom-Torte, UI-Polish.
Jetzt/Topbar und Material-Routing, Pause bei Filament-Ende, Druckbericht mit Stromanteilen, Design- und Kamera-Stream-Polish; Bedarf-Alert-Spam und Platte-belegt-Bugs behoben.
2026-10-18 14:58:32 +02:00

66 lines
2.5 KiB
HTML

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf" content="{{ csrf }}">
<title>Setup · Grotti</title>
<link rel="icon" type="image/png" sizes="32x32" href="{{ url_for('static', filename='brand/favicon-32.png') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='grotti.css') }}?v=62">
</head>
<body class="auth-body">
<main class="auth-card">
<h1 class="auth-brand"><img src="{{ url_for('static', filename='brand/logo.png') }}" alt="" width="44" height="44" decoding="async"><span>Grotti einrichten</span></h1>
<p class="tiny">Lege den ersten Administrator an. Danach ist Login Pflicht.</p>
<form id="setup-form" class="stack">
<div class="field">
<label for="username">Admin-Benutzer</label>
<input id="username" name="username" autocomplete="username" required autofocus minlength="2">
</div>
<div class="field">
<label for="password">Passwort</label>
<input id="password" name="password" type="password" autocomplete="new-password" required minlength="8">
</div>
<div class="field">
<label for="password2">Passwort wiederholen</label>
<input id="password2" name="password2" type="password" autocomplete="new-password" required minlength="8">
</div>
<button type="submit">Admin anlegen</button>
<p class="msg" id="note" hidden></p>
</form>
</main>
<script>
document.getElementById("setup-form").addEventListener("submit", async (event) => {
event.preventDefault();
const note = document.getElementById("note");
note.hidden = true;
const password = document.getElementById("password").value;
if (password !== document.getElementById("password2").value) {
note.hidden = false;
note.textContent = "Passwörter stimmen nicht überein.";
note.className = "msg";
return;
}
try {
const response = await fetch("/api/v1/auth/setup", {
method: "POST",
credentials: "same-origin",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
username: document.getElementById("username").value,
password,
}),
});
const payload = await response.json().catch(() => ({}));
if (!response.ok) throw new Error(payload.error || response.statusText);
location.href = "/";
} catch (error) {
note.hidden = false;
note.textContent = error.message || String(error);
note.className = "msg";
}
});
</script>
</body>
</html>