fix(login): show backend-health banner before the operator types (#5)
build-and-publish / test (push) Has been cancelled
build-and-publish / image (push) Has been cancelled

This commit was merged in pull request #5.
This commit is contained in:
2026-06-14 21:31:22 +00:00
parent 0864e21d71
commit 0f508293ea
2 changed files with 36 additions and 0 deletions
+24
View File
@@ -12,6 +12,7 @@ export default function Login() {
const buildAllowsDev = (import.meta.env.VITE_ENABLE_DEV_LOGIN ?? "true") !== "false";
const [devLoginEnabled, setDevLoginEnabled] = useState(buildAllowsDev);
const [ssoState, setSsoState] = useState<"unknown" | "ready" | "not-configured" | "not-wired">("unknown");
const [backendState, setBackendState] = useState<"unknown" | "up" | "auth-down" | "proxy-down">("unknown");
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
@@ -30,6 +31,18 @@ export default function Login() {
else setSsoState("not-wired");
})
.catch(() => setSsoState("not-wired"));
// Backend health precheck. /api/v1/auth/me with no token should return 401
// when the backend is up. 502/504 means the proxy is down; 503 means the
// auth service is down. We surface this so the operator knows BEFORE they
// type their password.
fetch("/api/v1/auth/me", { method: "GET" })
.then((r) => {
if (r.status === 401 || r.status === 403 || r.status === 200) setBackendState("up");
else if (r.status === 502 || r.status === 504) setBackendState("proxy-down");
else if (r.status === 503) setBackendState("auth-down");
else setBackendState("up");
})
.catch(() => setBackendState("proxy-down"));
}, [buildAllowsDev]);
const handleSubmit = async (e: React.FormEvent) => {
@@ -106,6 +119,17 @@ export default function Login() {
<div className="login-sub">MISSION CONTROL VERIFICATION REQUIRED</div>
</div>
{backendState === "proxy-down" && (
<div className="login-banner login-banner-warn">
The FlowMaster backend is not reachable from this environment right now. Sign-in will fail until it is restored.
</div>
)}
{backendState === "auth-down" && (
<div className="login-banner login-banner-warn">
The authentication service is temporarily down. Sign-in will fail until it is restored.
</div>
)}
{error && <div className="login-error">{error}</div>}
<form className="login-form" onSubmit={handleSubmit}>