admin / Apex
publicBid Management and Orchestration Tool with AI Capability
Apex / Synapse-Apexv2 / frontend / src / pages / Login.tsx
3125 B · main
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | import { useState } from "react"; import { api, setToken } from "../lib/api"; import { useAuth } from "../lib/auth"; export default function Login({ forceChange = false }: { forceChange?: boolean }) { const { refresh } = useAuth(); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [otp, setOtp] = useState(""); const [mfaStep, setMfaStep] = useState(false); const [err, setErr] = useState(""); const [busy, setBusy] = useState(false); // forced password change (must_change_password) const [newPw, setNewPw] = useState(""); const [curPw, setCurPw] = useState(""); async function submit(e: React.FormEvent) { e.preventDefault(); setErr(""); setBusy(true); try { const res = await api.post("/auth/login", { email, password, otp: otp || undefined }); if (res.mfa_required) { setMfaStep(true); setBusy(false); return; } setToken(res.access_token); await refresh(); } catch (e: any) { setErr(e.message); } finally { setBusy(false); } } async function changePassword(e: React.FormEvent) { e.preventDefault(); setErr(""); try { await api.post("/auth/change-password", { current_password: curPw, new_password: newPw }); await refresh(); } catch (e: any) { setErr(e.message); } } if (forceChange) { return ( <div className="login-wrap"> <form className="card login-card" onSubmit={changePassword}> <h1>Set a new password</h1> <p className="muted">Your account requires a password change before continuing.</p> <label>Current password</label> <input type="password" value={curPw} onChange={(e) => setCurPw(e.target.value)} /> <label>New password</label> <input type="password" value={newPw} onChange={(e) => setNewPw(e.target.value)} /> {err && <div className="err">{err}</div>} <button style={{ marginTop: 14 }}>Update password</button> </form> </div> ); } return ( <div className="login-wrap"> <form className="card login-card" onSubmit={submit}> <div className="row" style={{ marginBottom: 8 }}> <img src="/icon.svg" width={36} height={36} alt="" /> <h1 style={{ margin: 0 }}>Synapse-Apex</h1> </div> <p className="muted">Sign in to the bid workspace.</p> <label>Email</label> <input value={email} onChange={(e) => setEmail(e.target.value)} autoFocus /> <label>Password</label> <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} /> {mfaStep && ( <> <label>Authentication code</label> <input value={otp} onChange={(e) => setOtp(e.target.value)} placeholder="6-digit or recovery code" autoFocus /> </> )} {err && <div className="err">{err}</div>} <button style={{ marginTop: 14, width: "100%" }} disabled={busy}> {mfaStep ? "Verify" : "Sign in"} </button> </form> </div> ); } |