function LoginForm({ tokenInput, setTokenInput, setToken, setAccount, address, setAddress, password, setPassword, loginMode, setLoginMode, loginError, setLoginError, resetToken, setResetToken, setResetMode }) { const { t } = useI18n(); const [forgotSent, setForgotSent] = React.useState(false); const [remember, setRemember] = React.useState(() => !!getRememberedCreds()); React.useEffect(() => { const saved = getRememberedCreds(); if (saved) { setAddress(saved.address); setPassword(saved.password); } }, [setAddress, setPassword]); const onLogin = (e) => { e.preventDefault(); if (!address.trim() || !password.trim()) return; setLoginError(""); fetch("/api/login", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ address: address.trim(), password: password.trim() }), }) .then(async (r) => { const j = await r.json().catch(() => ({})); if (!j.ok) throw new Error(j.error?.message || j.error || "login failed"); return j.data; }) .then((data) => { setToken(data.token); if (data.address) { setAccount({ address: data.address, name: data.name || "", brand: data.brand || "" }); } if (remember) { setRememberedCreds({ address: address.trim(), password: password.trim() }); } else { clearRememberedCreds(); } }) .catch((e) => setLoginError(String(e.message || e))); }; const onToken = (e) => { e.preventDefault(); if (tokenInput.trim()) setToken(tokenInput.trim()); }; const onForgot = (e) => { e.preventDefault(); if (!address.trim()) return; setLoginError(""); setForgotSent(false); fetch("/api/forgot-password", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ address: address.trim() }), }) .then(async (r) => { const j = await r.json().catch(() => ({})); if (!j.ok) throw new Error(j.error?.message || j.error || "request failed"); setForgotSent(true); }) .catch((e) => setLoginError(String(e.message || e))); }; const onResetPassword = (e) => { e.preventDefault(); if (!resetToken.trim() || !password.trim()) return; setLoginError(""); fetch("/api/reset-password", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ token: resetToken.trim(), new_password: password.trim() }), }) .then(async (r) => { const j = await r.json().catch(() => ({})); if (!j.ok) throw new Error(j.error?.message || j.error || "reset failed"); setResetMode(false); setResetToken(""); setLoginMode("password"); setLoginError(""); alert("Password reset. Please log in with your new password."); }) .catch((e) => setLoginError(String(e.message || e))); }; // ─── reset password screen ────────────────────────────────────────── if (loginMode === "reset") { return (

{t("reset_title")}

Enter the reset token and your new password.

{loginError && (
{loginError}
)}
setResetToken(e.target.value)} className="w-full bg-paper border border-paper-line rounded px-2 py-1.5 text-sm font-mono" placeholder={t("reset_token")} autoFocus /> setPassword(e.target.value)} className="w-full bg-paper border border-paper-line rounded px-2 py-1.5 text-sm" placeholder={t("reset_new")} />
); } // ─── admin token screen ───────────────────────────────────────────── if (loginMode === "token") { return (

{t("token_title")}

{t("token_hint")}

setTokenInput(e.target.value)} className="flex-1 bg-paper border border-paper-line rounded px-2 py-1.5 text-sm" placeholder={t("token_placeholder")} />
); } // ─── default: password login ──────────────────────────────────────── return (

{t("login_title")}

{t("login_hint")}

{loginError && (
{loginError}
)} {forgotSent && (
{t("forgot_sent")}
)}
setAddress(e.target.value)} className="w-full bg-paper border border-paper-line rounded px-2 py-1.5 text-sm" placeholder={t("login_address")} autoFocus /> setPassword(e.target.value)} className="w-full bg-paper border border-paper-line rounded px-2 py-1.5 text-sm" placeholder={t("login_password")} />
); }