Files
crushdb/backend/static/index.html
T
jhkaktus c82de902a8 feat: free-text timestamps instead of datetime pickers
Users wanted to type things like "unbekannt" or comments for the date
fields. Start/End are now plain text inputs (max 120 chars) and are
stored/displayed verbatim - no Date parsing, no formatting. Existing
records that contain ISO strings keep working: they render exactly as
stored and refill the edit form unchanged. Also removes a duplicated
block in setup() that had slipped in earlier (double reload/flash).

Verified: node --check, no datetime-local/Date-parsing remnants,
crypto roundtrip with free-text and legacy ISO timestamps, pytest 3/3.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
2026-10-11 00:58:19 +02:00

116 lines
4.0 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>crushdb</title>
<link rel="stylesheet" href="/static/style.css" />
</head>
<body>
<h1>crushdb</h1>
<p class="tagline">Verschlüsselte Datensätze zwischen zwei Personen</p>
<section id="flash" class="flash" aria-live="polite"></section>
<!-- First visit: NO records exist yet → user chooses a new passphrase -->
<section id="setup" hidden>
<form id="setup-form" autocomplete="off">
<h2>Willkommen bei crushdb!</h2>
<p class="intro">
Du benutzt crushdb zum ersten Mal. Wähle jetzt eine Passphrase –
sie ist das Master-Passwort für alle deine Daten. Es gibt keine
Zurücksetzung, speichere sie sicher!
</p>
<label>Neue Passphrase
<input type="password" id="setup-pass1" autocomplete="new-password"
required minlength="8" placeholder="mindestens 8 Zeichen" />
</label>
<label>Passphrase wiederholen
<input type="password" id="setup-pass2" autocomplete="new-password"
required placeholder="gleiche Passphrase nochmal" />
</label>
<button type="submit" id="setup-btn">Konto einrichten →</button>
<p id="setup-progress" class="hint" hidden>Schlüssel wird abgeleitet …</p>
<p class="hint">
Wichtig: Die Passphrase wird <strong>nicht am Server gespeichert</strong>.
Sie bleibt nur in deinem Browser-Arbeitsspeicher. Wer sie vergisst,
verliert Zugriff auf alle Daten (absichtlich so).
</p>
</form>
</section>
<!-- Returning user: records exist but are undecryptable → enter passphrase -->
<section id="unlock">
<form id="unlock-form" autocomplete="off">
<h2>Entsperren</h2>
<p class="intro">
Du hast bereits verschlüsselte Datensätze hinterlegt.
Gib deine Passphrase ein, um sie zu lesen.
</p>
<label>Passphrase
<input type="password" id="passphrase" autocomplete="current-password"
required placeholder="deine Passphrase …" />
</label>
<button type="submit" id="unlock-btn">Entsperren</button>
<p id="unlock-progress" class="hint" hidden>Schlüssel wird abgeleitet …</p>
<p class="hint">
Die Passphrase verlässt niemals deinen Browser. Sie wird per
Argon2id lokal abgeleitet und nur im Arbeitsspeicher gehalten.
</p>
</form>
</section>
<!-- main app, hidden until unlocked -->
<section id="app" hidden>
<div class="toolbar">
<button id="new-btn" type="button">+ Neuer Datensatz</button>
<button id="lock-btn" type="button">Sperren</button>
</div>
<table id="records">
<thead>
<tr>
<th>Person A</th>
<th>Person B</th>
<th>Start</th>
<th>Ende</th>
<th>Aktion</th>
<th></th>
</tr>
</thead>
<tbody></tbody>
</table>
</section>
<!-- create/edit modal -->
<div id="editor-backdrop" hidden>
<form id="editor" autocomplete="off">
<h2 id="editor-title">Neuer Datensatz</h2>
<label>Person A
<input id="f-persona" type="text" required maxlength="120" />
</label>
<label>Person B
<input id="f-personb" type="text" required maxlength="120" />
</label>
<label>Start (optional, beliebiger Text)
<input id="f-tsstart" type="text" maxlength="120"
placeholder="z. B. 12.03.2026, Sommer 2025, unbekannt …" />
</label>
<label>Ende (optional, beliebiger Text)
<input id="f-tsend" type="text" maxlength="120"
placeholder="z. B. laufend, unbekannt, März 2026 …" />
</label>
<label>Aktion
<input id="f-action" type="text" required maxlength="500" />
</label>
<div class="actions">
<button type="submit">Speichern</button>
<button type="button" id="editor-cancel">Abbrechen</button>
</div>
</form>
</div>
<script type="module" src="/static/ui.js"></script>
</body>
</html>