import { useState, type FormEvent } from "react"; import { useAuth } from "../hooks/useAuth"; /** * Full-screen password gate rendered when no valid session token is present. * * Visual style: * - Violet gradient background: #3500B0 → #0F0027 * - Instrument Sans typeface (loaded globally via index.html) * - rgba(255,255,255,0.06) input surface * * On submit: calls useAuth.login(); shows inline error on 401. * * Requirements: 3.1, 3.2, 3.3, 3.5 */ export function PasswordGate() { const { login } = useAuth(); const [password, setPassword] = useState(""); const [error, setError] = useState(null); const [isSubmitting, setIsSubmitting] = useState(false); async function handleSubmit(e: FormEvent) { e.preventDefault(); setError(null); setIsSubmitting(true); try { await login(password); // On success, useAuth sets isAuthenticated = true and the parent // (App.tsx) will unmount this gate and render the main UI. } catch (err: unknown) { // api.ts throws Error("Invalid password") on HTTP 401 if ( err instanceof Error && (err.message === "Invalid password" || err.message.includes("401")) ) { setError("Incorrect password. Please try again."); } else { setError("Something went wrong. Please try again."); } } finally { setIsSubmitting(false); } } return (
{/* Hero title */}

Health Marketing Compliance

Enter your access password to continue.

{/* Auth card */}
setPassword(e.target.value)} disabled={isSubmitting} placeholder="••••••••" className="w-full rounded-lg px-4 py-3 text-sm text-white placeholder-white/30 outline-none transition-all duration-150 focus:ring-2 focus:ring-white/30 disabled:opacity-50 disabled:cursor-not-allowed" style={{ background: "rgba(255,255,255,0.06)", border: "1px solid rgba(255,255,255,0.12)", }} />
{/* Inline error — shown on 401 */} {error && (

{error}

)}
); }