Files
mindflux/src/main/resources/templates/index.html
T
AliceDarkest e875c9a7d3
mindflux-ci / build (push) Successful in 15s
Collapse verification resend form
2026-07-15 11:30:38 +02:00

202 lines
9.8 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" data-theme="dark" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SysnaptiK Neural – Deine Zukunft beginnt hier</title>
<link rel="stylesheet" href="/css/theme.css?v=3">
<script src="/js/theme.js?v=4"></script>
<link rel="stylesheet" href="/css/auth.css">
</head>
<body>
<div class="mf-theme-float"><button class="mf-theme"></button></div>
<div class="mf-center">
<div class="auth-stage">
<div class="auth-container" id="authContainer">
<!-- ===== Sign In ===== -->
<div class="form-box login">
<div class="inner">
<div class="auth-head">
<span class="mark"></span>
<b>SYSNAPTIK NEURAL</b>
<h2>Willkommen zurück</h2>
<span class="sub">Melde dich an, um weiterzulernen.</span>
</div>
<div th:if="${param.error}" class="mf-alert err">Benutzername oder Passwort sind falsch.</div>
<div th:if="${param.logout}" class="mf-alert ok">Du hast dich erfolgreich abgemeldet.</div>
<div th:if="${param.registerSuccess}" class="mf-alert ok">Fast geschafft: Wir haben dir einen Bestätigungslink per E-Mail gesendet.</div>
<div th:if="${param.emailVerified}" class="mf-alert ok">Deine E-Mail-Adresse wurde bestätigt. Du kannst dich jetzt anmelden.</div>
<div th:if="${param.passwordReset}" class="mf-alert ok">Dein Passwort wurde geändert. Du kannst dich jetzt anmelden.</div>
<div th:if="${param.verificationSent}" class="mf-alert ok">Falls ein unbestätigter Account zu dieser Adresse existiert, wurde ein neuer Link versendet.</div>
<div th:if="${param.verificationInvalid}" class="mf-alert err">Dieser Bestätigungslink ist ungültig oder abgelaufen.</div>
<div th:if="${param.resetInvalid}" class="mf-alert err">Dieser Passwort-Link ist ungültig oder abgelaufen.</div>
<form th:action="@{/login}" method="post">
<div class="mf-field">
<label class="mf-label" for="login-username">Benutzername</label>
<input id="login-username" class="mf-input" type="text" name="username" placeholder="Benutzername" required th:value="${param.username}">
</div>
<div class="mf-field">
<label class="mf-label" for="login-password">Passwort</label>
<input id="login-password" class="mf-input" type="password" name="password" placeholder="Passwort" required>
</div>
<button class="neon-btn" type="submit">Login</button>
</form>
<p class="mobile-switch"><a href="/forgot-password">Passwort vergessen?</a></p>
<p class="mobile-switch">Noch keinen Account? <a data-goto="signup">Jetzt registrieren</a></p>
</div>
</div>
<!-- ===== Sign Up ===== -->
<div class="form-box signup">
<div class="inner">
<div class="auth-head">
<span class="mark"></span>
<b>SYSNAPTIK NEURAL</b>
<h2>Account erstellen</h2>
<span class="sub">Kostenlos – und in 30 Sekunden startklar.</span>
</div>
<div th:if="${param.registerError}" class="mf-alert err">Benutzername bereits vergeben.</div>
<div th:if="${param.passwordMismatch}" class="mf-alert err">Die Passwörter stimmen nicht überein. Bitte erneut eingeben.</div>
<div th:if="${param.passwordPolicy}" class="mf-alert err">Das Passwort muss mindestens 8 Zeichen lang sein.</div>
<div th:if="${param.emailInvalid}" class="mf-alert err">Bitte gib eine gültige E-Mail-Adresse an.</div>
<div th:if="${param.emailTaken}" class="mf-alert err">Diese E-Mail-Adresse wird bereits verwendet.</div>
<div th:if="${param.registerMailError}" class="mf-alert err">Der Account wurde angelegt, aber die Bestätigungs-E-Mail konnte nicht gesendet werden. Fordere unten einen neuen Link an.</div>
<form th:action="@{/register}" method="post">
<div class="mf-field">
<label class="mf-label" for="reg-username">Benutzername</label>
<input id="reg-username" class="mf-input" type="text" name="username" placeholder="Benutzername" required>
</div>
<div class="mf-field">
<label class="mf-label" for="reg-email">E-Mail</label>
<input id="reg-email" class="mf-input" type="email" name="email" placeholder="E-Mail" required>
</div>
<div class="mf-field">
<label class="mf-label" for="reg-password">Passwort</label>
<input id="reg-password" class="mf-input" type="password" name="password" placeholder="Passwort (min. 8 Zeichen)" required minlength="8">
</div>
<div class="mf-field">
<label class="mf-label" for="reg-password2">Passwort wiederholen</label>
<input id="reg-password2" class="mf-input" type="password" name="confirmPassword" placeholder="Passwort wiederholen" required>
</div>
<p id="reg-pw-msg" class="mf-alert err" style="display:none">Die Passwörter stimmen nicht überein.</p>
<button class="neon-btn" type="submit">Account erstellen</button>
</form>
<div class="auth-resend">
<button id="resend-toggle" class="auth-resend-toggle" type="button"
aria-expanded="false" aria-controls="resend-form">
Bestätigungslink erneut senden
</button>
<form id="resend-form" th:action="@{/verification/resend}" method="post" hidden>
<label class="mf-label" for="resend-email">E-Mail-Adresse</label>
<div class="auth-resend-fields">
<input id="resend-email" class="mf-input" type="email" name="email" placeholder="E-Mail-Adresse" required autocomplete="email">
<button class="mf-btn outline" type="submit">Link senden</button>
</div>
</form>
</div>
<p class="mobile-switch">Schon dabei? <a data-goto="login">Zum Login</a></p>
</div>
</div>
<!-- ===== Overlay ===== -->
<div class="overlay-container">
<div class="overlay">
<!-- sichtbar im Signup-Modus -> zurück zum Login -->
<div class="overlay-panel overlay-left">
<span class="o-emblem"></span>
<h3>Schon dabei?</h3>
<p>Melde dich an und setze dein Lernnetz genau dort fort, wo du aufgehört hast.</p>
<button type="button" class="ghost-btn" id="toLogin">Zum Login</button>
</div>
<!-- sichtbar im Login-Modus -> zum Signup -->
<div class="overlay-panel overlay-right">
<span class="o-emblem"></span>
<h3>Neu bei SysnaptiK Neural?</h3>
<p>Erstelle deinen kostenlosen Account und schalte die volle Lernplattform frei.</p>
<button type="button" class="ghost-btn" id="toSignup">Account erstellen</button>
</div>
</div>
</div>
</div>
<footer class="mf-footer">
<a href="#">Support</a>
<a href="#">Feedback</a>
<a href="/nutzungsbedingungen">Nutzungsbedingungen</a>
<a href="/richtlinien">Richtlinien</a>
<a href="/datenschutz">Datenschutz</a>
<a href="/impressum">Impressum</a>
</footer>
</div>
</div>
<script>
(function () {
var c = document.getElementById('authContainer');
var toSignup = document.getElementById('toSignup');
var toLogin = document.getElementById('toLogin');
if (toSignup) toSignup.addEventListener('click', function () { c.classList.add('active'); });
if (toLogin) toLogin.addEventListener('click', function () { c.classList.remove('active'); });
var resendToggle = document.getElementById('resend-toggle');
var resendForm = document.getElementById('resend-form');
if (resendToggle && resendForm) {
resendToggle.addEventListener('click', function () {
var expand = resendForm.hidden;
resendForm.hidden = !expand;
resendToggle.setAttribute('aria-expanded', String(expand));
if (expand) resendForm.querySelector('input').focus();
});
}
document.querySelectorAll('[data-goto="signup"]').forEach(function (el) {
el.addEventListener('click', function (e) { e.preventDefault(); c.classList.add('active'); });
});
document.querySelectorAll('[data-goto="login"]').forEach(function (el) {
el.addEventListener('click', function (e) { e.preventDefault(); c.classList.remove('active'); });
});
// Bei Registrierungs-/Passwortfehler direkt das Signup-Panel öffnen
var qp = new URLSearchParams(window.location.search);
if (qp.has('registerError') || qp.has('passwordMismatch') || qp.has('passwordPolicy') || qp.has('emailInvalid') || qp.has('emailTaken') || qp.has('registerMailError')) {
c.classList.add('active');
}
// Client-seitiger Passwort-Abgleich (sofortiges Feedback; der Server prüft zusätzlich)
var pw = document.getElementById('reg-password');
var pw2 = document.getElementById('reg-password2');
var pwMsg = document.getElementById('reg-pw-msg');
var signupForm = pw2 ? pw2.closest('form') : null;
function pwCheck() {
var mismatch = pw2.value.length > 0 && pw.value !== pw2.value;
if (pwMsg) pwMsg.style.display = mismatch ? 'block' : 'none';
pw2.setCustomValidity(pw.value !== pw2.value ? 'Passwörter stimmen nicht überein' : '');
return !mismatch;
}
if (pw && pw2) {
pw.addEventListener('input', pwCheck);
pw2.addEventListener('input', pwCheck);
if (signupForm) signupForm.addEventListener('submit', function (e) {
if (pw.value !== pw2.value) { e.preventDefault(); pwCheck(); c.classList.add('active'); }
});
}
})();
</script>
</body>
</html>