(function(){ const { useState } = React; function LoginScreen({ onLogin }) { const [mode, setMode] = useState("login"); // "login" | "register" const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [password2, setPassword2] = useState(""); const [email, setEmail] = useState(""); const [loading, setLoading] = useState(false); const [err, setErr] = useState(null); function switchMode(m) { setMode(m); setErr(null); setPassword(""); setPassword2(""); setEmail(""); } async function handleSubmit(e) { e.preventDefault(); if (!username.trim() || !password) { setErr(window.t("auth.fillAllFields")); return; } if (mode === "register") { if (password !== password2) { setErr(window.t("auth.passwordMismatch")); return; } if (password.length < 4) { setErr(window.t("auth.passwordMinLength")); return; } } setLoading(true); setErr(null); try { const endpoint = mode === "login" ? "/api/login" : "/api/register"; const r = await fetch(endpoint, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ username: username.trim().toLowerCase(), password, ...(mode === "register" && email.trim() ? { email: email.trim() } : {}) }) }); const data = await r.json(); if (!r.ok) { setErr(data.error || (mode === "login" ? window.t("auth.loginFailed") : window.t("auth.registerFailed"))); return; } onLogin(data.token, data.username); } catch { setErr(window.t("auth.connectionError")); } finally { setLoading(false); } } const inputStyle = { width: "100%", boxSizing: "border-box", fontSize: 14, padding: "10px 12px", borderRadius: 8, border: "1px solid var(--col-border)", background: "var(--col-bg)", color: "var(--col-text)", fontFamily: "var(--sans)", outline: "none" }; const labelStyle = { display: "block", fontSize: 10, color: "var(--col-text-sec)", letterSpacing: "0.08em", textTransform: "uppercase", marginBottom: 6, fontFamily: "var(--mono)" }; return (
{/* Logo */}
P

Mein Planer

{mode === "login" ? window.t("auth.loginSubtitle") : window.t("auth.registerSubtitle")}

{/* Card */}
setUsername(e.target.value)} placeholder={window.t("auth.usernamePlaceholder")} autoFocus autoCapitalize="none" autoCorrect="off" autoComplete="username" spellCheck={false} style={inputStyle} />
setPassword(e.target.value)} placeholder="••••••••" autoComplete={mode === "login" ? "current-password" : "new-password"} style={inputStyle} />
{mode === "register" && (
setPassword2(e.target.value)} placeholder="••••••••" autoComplete="new-password" style={inputStyle} />
)} {mode === "register" && (
setEmail(e.target.value)} placeholder={window.t("auth.emailPlaceholder")} autoComplete="email" style={inputStyle} />
)} {err && (
{err}
)}
{/* FIXED B5b: registration hidden behind toggle */} switchMode(mode === "login" ? "register" : "login")}> {mode === "login" ? window.t("auth.createAccount") : window.t("auth.backToLogin")}

{window.t("auth.runningOnPi")}

); } Object.assign(window, { LoginScreen }); })();