Files
oikos/public/pages/login.js
T
ulsklyc 7244fc95f1 fix: Session-Store, DOM-Timing und API-Pfad-Fehler beheben
- connect-sqlite3 durch eigenen BetterSQLiteStore ersetzt (sessions-Tabelle
  in der bestehenden DB, keine native Kompilierung nötig)
- db.init() vor require('./auth') gezogen damit BetterSQLiteStore-Konstruktor
  db.get() erfolgreich aufrufen kann
- router.js: App-Shell und pageWrapper vor module.render() in DOM einfügen
  damit document.getElementById() in Seiten-Modulen funktioniert
- Seiten-Module (meals, notes, contacts, calendar, budget): _container-Referenz
  eingeführt, alle document.getElementById() auf _container.querySelector() bzw.
  document.querySelector() für body-Elemente umgestellt
- login.js: User-Objekt nach erfolgreichem Login an navigate() übergeben
  damit auth.me()-Roundtrip entfällt
- calendar.js: /users → /auth/users korrigiert (404-Fix)
- SW-Cache v8 (erzwingt Reload aller gecachten Seiten-Module)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 11:49:10 +01:00

97 lines
2.7 KiB
JavaScript

/**
* Modul: Login-Seite
* Zweck: Anmeldeformular mit Username/Passwort, Fehlerbehandlung, Session-Start
* Abhängigkeiten: /api.js
*/
import { auth } from '/api.js';
/**
* Rendert die Login-Seite in den gegebenen Container.
* @param {HTMLElement} container
*/
export async function render(container) {
container.innerHTML = `
<main class="login-page" id="main-content">
<div class="login-card card card--padded">
<h1 class="login-card__title">Oikos</h1>
<p class="login-card__subtitle">Familienplaner</p>
<form class="login-form" id="login-form" novalidate>
<div class="form-group">
<label class="label" for="username">Benutzername</label>
<input
class="input"
type="text"
id="username"
name="username"
autocomplete="username"
autocapitalize="none"
autocorrect="off"
placeholder="benutzername"
required
/>
</div>
<div class="form-group">
<label class="label" for="password">Passwort</label>
<input
class="input"
type="password"
id="password"
name="password"
autocomplete="current-password"
placeholder="••••••••"
required
/>
</div>
<div class="login-error" id="login-error" role="alert" aria-live="polite" hidden></div>
<button type="submit" class="btn btn--primary login-form__submit" id="login-btn">
Anmelden
</button>
</form>
</div>
</main>
`;
const form = container.querySelector('#login-form');
const errorEl = container.querySelector('#login-error');
const submitBtn = container.querySelector('#login-btn');
form.addEventListener('submit', async (e) => {
e.preventDefault();
errorEl.hidden = true;
const username = form.username.value.trim();
const password = form.password.value;
if (!username || !password) {
showError(errorEl, 'Bitte alle Felder ausfüllen.');
return;
}
submitBtn.disabled = true;
submitBtn.textContent = 'Wird angemeldet …';
try {
const result = await auth.login(username, password);
window.oikos.navigate('/', result.user);
} catch (err) {
showError(errorEl, err.status === 429
? 'Zu viele Versuche. Bitte warte kurz.'
: 'Ungültige Anmeldedaten.'
);
} finally {
submitBtn.disabled = false;
submitBtn.textContent = 'Anmelden';
}
});
}
function showError(el, message) {
el.textContent = message;
el.hidden = false;
}