// app/login/page.tsx "use client"; import { FormEvent, useMemo, useState, Suspense } from "react"; import { useRouter, useSearchParams } from "next/navigation"; import Link from "next/link"; import { useAuth } from "@/context/AuthContext"; import { Button, Field, Input } from "@/components/ui/form"; const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; function LoginPageContent() { const router = useRouter(); const searchParams = useSearchParams(); const { login, loading } = useAuth(); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [error, setError] = useState(null); // Magic link UI state (separate from password login) const [magicLoading, setMagicLoading] = useState(false); const [magicMessage, setMagicMessage] = useState(null); const [magicError, setMagicError] = useState(null); const next = useMemo( () => searchParams.get("next") || "/builder", [searchParams] ); async function handleSubmit(e: FormEvent) { e.preventDefault(); setError(null); try { await login({ email, password }); router.push(next); } catch (err: any) { setError(err?.message ?? "Failed to log in"); } } async function handleMagicLinkRequest() { setMagicMessage(null); setMagicError(null); const normalizedEmail = email.trim(); if (!normalizedEmail) { setMagicError("Please enter your email above first."); return; } setMagicLoading(true); try { // ✅ This endpoint exists in your AuthController: // POST /api/auth/beta/signup { email, useCase } const res = await fetch(`${API_BASE_URL}/api/auth/beta/signup`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email: normalizedEmail, useCase: "login_magic", }), }); // Soft-fail (avoid email enumeration) if (!res.ok) { const text = await res.text().catch(() => ""); console.error("Magic link request failed:", res.status, text); } setMagicMessage( "If that email is eligible, you’ll get a sign-in link shortly ✨" ); } catch (e) { console.error(e); // Soft-fail setMagicMessage( "If that email is eligible, you’ll get a sign-in link shortly ✨" ); } finally { setMagicLoading(false); } } return (

Log In to The Builder

Use your beta credentials to get back to your saved builds.

{/* Password Login */}
{error && (
{error}
)} setEmail(e.target.value)} /> setPassword(e.target.value)} />
{/* Divider */}
or
{/* Magic Link Request */}

Already a beta user?

Request a one-time sign-in link (no password needed).

{magicError && (
{magicError}
)} {magicMessage && (
{magicMessage}
)}

Tip: check spam/promotions. Links expire.

New here?{" "} Join the beta .

); } export default function LoginPage() { return (
}> ); }