gwoe-antragspruefer/app/templates/v2/components/auth_modal.html

186 lines
9.7 KiB
HTML
Raw Normal View History

{#
auth_modal.html — Login- und Registrierungs-Modal für v2
Einbinden via: {% include "v2/components/auth_modal.html" %}
Öffnen via: document.getElementById('v2-auth-modal').style.display = 'flex'
#}
{% from "v2/components/icon.html" import icon %}
<!-- ── v2 Auth Modal ──────────────────────────────────────────────────── -->
<div id="v2-auth-modal"
role="dialog" aria-modal="true" aria-labelledby="v2-auth-modal-title"
style="display:none;position:fixed;inset:0;background:rgba(0,0,0,0.45);z-index:400;justify-content:center;align-items:center;"
onclick="if(event.target===this)v2AuthModalClose()">
<div style="background:var(--paper);border-radius:8px;padding:var(--space-6);max-width:440px;width:90%;box-shadow:0 8px 32px rgba(0,0,0,0.22);font-family:var(--font-sans);">
<!-- Header -->
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:var(--space-5);">
<h3 id="v2-auth-modal-title"
style="margin:0;font-family:var(--font-sans);font-size:1.1rem;font-weight:700;color:var(--ecg-blue);letter-spacing:0.03em;">
Anmelden
</h3>
<button onclick="v2AuthModalClose()"
aria-label="Modal schließen"
style="background:none;border:none;cursor:pointer;color:var(--ecg-dark);opacity:0.6;font-size:1.2rem;line-height:1;padding:0;">✕</button>
</div>
<!-- Tabs -->
<div style="display:flex;border-bottom:2px solid var(--hairline);margin-bottom:var(--space-5);">
<button id="v2-auth-tab-login"
onclick="v2AuthSwitchTab('login')"
style="flex:1;padding:var(--space-2) var(--space-3);border:none;background:none;cursor:pointer;font-family:var(--font-sans);font-size:0.9rem;font-weight:700;color:var(--ecg-blue);border-bottom:2px solid var(--ecg-blue);margin-bottom:-2px;">
Anmelden
</button>
<button id="v2-auth-tab-register"
onclick="v2AuthSwitchTab('register')"
style="flex:1;padding:var(--space-2) var(--space-3);border:none;background:none;cursor:pointer;font-family:var(--font-sans);font-size:0.9rem;font-weight:400;color:var(--ecg-light);margin-bottom:-2px;">
Registrieren
</button>
</div>
<!-- Login Form -->
<form id="v2-auth-login-form" onsubmit="v2AuthSubmitLogin(event)"
style="display:flex;flex-direction:column;gap:var(--space-3);">
<input name="username" placeholder="Benutzername" required autocomplete="username"
style="padding:var(--space-2) var(--space-3);border:1px solid var(--hairline);border-radius:4px;font-family:var(--font-sans);font-size:0.95rem;background:var(--surface);color:var(--ecg-dark);outline:none;">
<input name="password" type="password" placeholder="Passwort" required autocomplete="current-password"
style="padding:var(--space-2) var(--space-3);border:1px solid var(--hairline);border-radius:4px;font-family:var(--font-sans);font-size:0.95rem;background:var(--surface);color:var(--ecg-dark);outline:none;">
<button type="submit"
style="padding:var(--space-3);background:var(--ecg-blue);color:#fff;border:none;border-radius:4px;cursor:pointer;font-family:var(--font-sans);font-size:0.95rem;font-weight:700;letter-spacing:0.04em;">
Anmelden
</button>
<a href="/api/auth/forgot-password" target="_blank" rel="noopener"
style="font-family:var(--font-mono);font-size:0.78rem;color:var(--ecg-blue);text-align:right;text-decoration:none;border-bottom:1px solid rgba(0,157,165,0.35);align-self:flex-end;">
Passwort vergessen?
</a>
</form>
<!-- Register Form -->
<form id="v2-auth-register-form" onsubmit="v2AuthSubmitRegister(event)"
style="display:none;flex-direction:column;gap:var(--space-3);">
<input name="firstName" placeholder="Vorname" required autocomplete="given-name"
style="padding:var(--space-2) var(--space-3);border:1px solid var(--hairline);border-radius:4px;font-family:var(--font-sans);font-size:0.95rem;background:var(--surface);color:var(--ecg-dark);outline:none;">
<input name="lastName" placeholder="Nachname" required autocomplete="family-name"
style="padding:var(--space-2) var(--space-3);border:1px solid var(--hairline);border-radius:4px;font-family:var(--font-sans);font-size:0.95rem;background:var(--surface);color:var(--ecg-dark);outline:none;">
<input name="email" type="email" placeholder="E-Mail-Adresse" required autocomplete="email"
style="padding:var(--space-2) var(--space-3);border:1px solid var(--hairline);border-radius:4px;font-family:var(--font-sans);font-size:0.95rem;background:var(--surface);color:var(--ecg-dark);outline:none;">
<input name="username" placeholder="Benutzername (frei wählbar)" required autocomplete="username"
style="padding:var(--space-2) var(--space-3);border:1px solid var(--hairline);border-radius:4px;font-family:var(--font-sans);font-size:0.95rem;background:var(--surface);color:var(--ecg-dark);outline:none;">
<button type="submit"
style="padding:var(--space-3);background:var(--ecg-green);color:#fff;border:none;border-radius:4px;cursor:pointer;font-family:var(--font-sans);font-size:0.95rem;font-weight:700;letter-spacing:0.04em;">
Freischaltung beantragen
</button>
<p style="margin:0;font-size:0.78rem;color:var(--ecg-light);">
Nach Freischaltung erhalten Sie eine E-Mail zum Passwort setzen.
</p>
</form>
<!-- Status-Anzeige (Fehler / Erfolg) -->
<div id="v2-auth-status" style="margin-top:var(--space-3);font-size:0.875rem;min-height:1.2em;"></div>
</div>
</div>
<script>
/* ── v2 Auth Modal ───────────────────────────────────────────────────── */
(function () {
function open() {
const modal = document.getElementById('v2-auth-modal');
if (modal) modal.style.display = 'flex';
// Status leeren bei jedem Öffnen
const status = document.getElementById('v2-auth-status');
if (status) status.innerHTML = '';
}
function close() {
const modal = document.getElementById('v2-auth-modal');
if (modal) modal.style.display = 'none';
}
function switchTab(tab) {
const loginForm = document.getElementById('v2-auth-login-form');
const registerForm = document.getElementById('v2-auth-register-form');
const tabLogin = document.getElementById('v2-auth-tab-login');
const tabRegister = document.getElementById('v2-auth-tab-register');
const title = document.getElementById('v2-auth-modal-title');
const status = document.getElementById('v2-auth-status');
if (!loginForm || !registerForm) return;
const isLogin = tab === 'login';
loginForm.style.display = isLogin ? 'flex' : 'none';
registerForm.style.display = isLogin ? 'none' : 'flex';
// Tab-Stile
const activeStyle = 'color:var(--ecg-blue);font-weight:700;border-bottom:2px solid var(--ecg-blue);margin-bottom:-2px;';
const inactiveStyle = 'color:var(--ecg-light);font-weight:400;margin-bottom:-2px;';
tabLogin.style.cssText += isLogin ? activeStyle : inactiveStyle;
tabRegister.style.cssText += isLogin ? inactiveStyle : activeStyle;
if (title) title.textContent = isLogin ? 'Anmelden' : 'Registrieren';
if (status) status.innerHTML = '';
}
async function submitLogin(e) {
e.preventDefault();
const form = e.target;
const status = document.getElementById('v2-auth-status');
status.innerHTML = '<span style="color:var(--ecg-blue);">Anmeldung läuft\u2026</span>';
try {
const resp = await fetch('/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams(new FormData(form)).toString()
});
const data = await resp.json();
if (resp.ok && data.authenticated) {
status.innerHTML = '<span style="color:var(--ecg-green);">Angemeldet.</span>';
close();
location.reload();
} else {
status.innerHTML = '<span style="color:#c33;">' + (data.detail || 'Anmeldung fehlgeschlagen') + '</span>';
}
} catch (err) {
status.innerHTML = '<span style="color:#c33;">' + err.message + '</span>';
}
}
async function submitRegister(e) {
e.preventDefault();
const form = e.target;
const status = document.getElementById('v2-auth-status');
status.innerHTML = '<span style="color:var(--ecg-blue);">Wird registriert\u2026</span>';
try {
const resp = await fetch('/api/auth/register', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams(new FormData(form)).toString()
});
const data = await resp.json();
if (resp.ok) {
status.innerHTML = '<span style="color:var(--ecg-green);">Freischaltung beantragt. Sie erhalten eine E-Mail, sobald Ihr Konto aktiviert ist.</span>';
form.reset();
} else {
status.innerHTML = '<span style="color:#c33;">' + (data.detail || 'Registrierung fehlgeschlagen') + '</span>';
}
} catch (err) {
status.innerHTML = '<span style="color:#c33;">' + err.message + '</span>';
}
}
// ESC schließt Modal
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape') close();
});
// Globale API für Topbar-Button und externe Aufrufer
window.v2AuthModalOpen = open;
window.v2AuthModalClose = close;
window.v2AuthSwitchTab = switchTab;
window.v2AuthSubmitLogin = submitLogin;
window.v2AuthSubmitRegister = submitRegister;
})();
</script>