frontend: add LoginGate, wire session into App, add logout link
This commit is contained in:
50
frontend/src/LoginGate.tsx
Normal file
50
frontend/src/LoginGate.tsx
Normal file
@@ -0,0 +1,50 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { api } from "./api/client";
|
||||
import "./LoginGate.css";
|
||||
import App from "./App";
|
||||
import type { SessionInfo } from "./types/api";
|
||||
|
||||
type Status = "loading" | "authenticated" | "unauthenticated";
|
||||
|
||||
const AUTH_ERROR_MESSAGES: Record<string, string> = {
|
||||
forbidden: "Your account isn't authorized for geniusrun.",
|
||||
failed: "Login failed, please try again.",
|
||||
};
|
||||
|
||||
// Wraps App: on mount, asks the backend whether this browser already has a
|
||||
// valid session (GET /api/session/me). geniusrun has no anonymous view, so
|
||||
// this is the only fork in the whole frontend between "show the login
|
||||
// screen" and "show the app."
|
||||
export function LoginGate() {
|
||||
const [status, setStatus] = useState<Status>("loading");
|
||||
const [session, setSession] = useState<SessionInfo | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
api
|
||||
.getSessionInfo()
|
||||
.then((s) => {
|
||||
setSession(s);
|
||||
setStatus("authenticated");
|
||||
})
|
||||
.catch(() => setStatus("unauthenticated"));
|
||||
}, []);
|
||||
|
||||
if (status === "loading") {
|
||||
return <div className="login-gate-loading">Loading…</div>;
|
||||
}
|
||||
|
||||
if (status === "unauthenticated") {
|
||||
const authError = new URLSearchParams(window.location.search).get("auth_error");
|
||||
return (
|
||||
<div className="login-gate">
|
||||
<h1>🧞♀️ geniusrun</h1>
|
||||
{authError && <p className="login-gate-error">{AUTH_ERROR_MESSAGES[authError] ?? "Login failed, please try again."}</p>}
|
||||
<a className="login-gate-button" href="/api/session/login">
|
||||
Log in
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return <App session={session!} />;
|
||||
}
|
||||
Reference in New Issue
Block a user