import React from "react"; import { toast } from "sonner"; import { Button } from "../ui/button"; import { Input } from "../ui/input"; import { Label } from "../ui/label"; import { PasswordInput } from "../ui/password-input"; import { login } from "../../services/accountService"; import { confirmPasswordReset, sendPasswordResetCode } from "../../services/passwordResetService"; import { useAuth } from "./AuthProvider"; const brandLogo = new URL("../../assets/773f0c39e1986271e9144596caac519f934a6ae6.png", import.meta.url).href; const CODE_COOLDOWN_SEC = 60; const MIN_PASSWORD_LEN = 6; type Mode = "signin" | "forgot"; export function LoginView() { const auth = useAuth(); const [mode, setMode] = React.useState("signin"); const [email, setEmail] = React.useState(""); const [password, setPassword] = React.useState(""); const [submitting, setSubmitting] = React.useState(false); const [fpEmail, setFpEmail] = React.useState(""); const [fpCode, setFpCode] = React.useState(""); const [fpNew, setFpNew] = React.useState(""); const [fpConfirm, setFpConfirm] = React.useState(""); const [sendingCode, setSendingCode] = React.useState(false); const [resetting, setResetting] = React.useState(false); const [cooldown, setCooldown] = React.useState(0); React.useEffect(() => { if (cooldown <= 0) return; const id = window.setTimeout(() => setCooldown((c) => Math.max(0, c - 1)), 1000); return () => window.clearTimeout(id); }, [cooldown]); const canSubmit = Boolean(email.trim() && password.trim() && !submitting); const submit = async () => { if (!canSubmit) return; const emailText = email.trim(); setSubmitting(true); try { await login({ userName: emailText, password: password.trim() }); await auth.refresh(); toast.success("Signed in"); } catch (e: unknown) { toast.error("Sign-in failed", { description: e instanceof Error ? e.message : "Please check your email/password and try again.", }); } finally { setSubmitting(false); } }; const goForgot = () => { setFpEmail(email.trim()); setFpCode(""); setFpNew(""); setFpConfirm(""); setCooldown(0); setMode("forgot"); }; const goSignIn = () => { setMode("signin"); setFpCode(""); setFpNew(""); setFpConfirm(""); setCooldown(0); }; const sendCode = async () => { const em = fpEmail.trim(); if (!em) { toast.error("Email required", { description: "Enter the email address for your account." }); return; } if (cooldown > 0 || sendingCode) return; setSendingCode(true); try { await sendPasswordResetCode(em); setCooldown(CODE_COOLDOWN_SEC); toast.success("Verification code sent", { description: "Check your inbox for the code.", }); } catch (e: unknown) { toast.error("Could not send code", { description: e instanceof Error ? e.message : "Please try again.", }); } finally { setSendingCode(false); } }; const submitReset = async () => { const em = fpEmail.trim(); const code = fpCode.trim(); const np = fpNew; const cf = fpConfirm; if (!em || !code) { toast.error("Missing fields", { description: "Email and verification code are required." }); return; } if (np.length < MIN_PASSWORD_LEN) { toast.error("Password too short", { description: `Use at least ${MIN_PASSWORD_LEN} characters.`, }); return; } if (np !== cf) { toast.error("Passwords do not match", { description: "Re-enter the new password in both fields." }); return; } setResetting(true); try { await confirmPasswordReset({ email: em, code, newPassword: np }); toast.success("Password updated", { description: "You can sign in with your new password." }); setEmail(em); setPassword(""); goSignIn(); } catch (e: unknown) { toast.error("Reset failed", { description: e instanceof Error ? e.message : "Please try again.", }); } finally { setResetting(false); } }; const title = mode === "signin" ? "Platform Sign In" : "Reset password"; return (
MedVantage
{title}
{mode === "signin" ? (
setEmail(e.target.value)} placeholder="Enter your email" autoComplete="username" onKeyDown={(e) => { if (e.key === "Enter") submit(); }} />
setPassword(e.target.value)} placeholder="Enter your password" autoComplete="current-password" onKeyDown={(e) => { if (e.key === "Enter") submit(); }} />
) : (
setFpEmail(e.target.value)} placeholder="Enter your email" autoComplete="email" />
setFpCode(e.target.value)} placeholder="Enter the code from email" onKeyDown={(e) => { if (e.key === "Enter") submitReset(); }} />
setFpNew(e.target.value)} placeholder={`At least ${MIN_PASSWORD_LEN} characters`} autoComplete="new-password" />
setFpConfirm(e.target.value)} placeholder="Re-enter new password" autoComplete="new-password" onKeyDown={(e) => { if (e.key === "Enter") submitReset(); }} />
)}
); }