Files
shadow-gunbuilder-ai-proto/app/beta/magic/page.tsx
T

78 lines
2.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { useEffect, useRef, useState } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import { useAuth } from "@/context/AuthContext";
export default function BetaMagicPage() {
const params = useSearchParams();
const token = params.get("token");
const router = useRouter();
const { setSession } = useAuth();
const ran = useRef(false);
const [status, setStatus] = useState<"loading" | "success" | "error">("loading");
const [message, setMessage] = useState("Signing you in…");
useEffect(() => {
if (!token) {
setStatus("error");
setMessage("Missing token.");
return;
}
// ✅ Prevent double-call (Strict Mode / rerenders)
if (ran.current) return;
ran.current = true;
(async () => {
try {
const res = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"}/api/auth/magic/exchange`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ token }),
});
if (!res.ok) {
const text = await res.text().catch(() => "");
throw new Error(text || "Magic link failed");
}
const data = await res.json();
// Your AuthContext expects { token, email, displayName, role }
// and stores it in localStorage.
// We can simulate "login" by directly setting localStorage like AuthContext does,
// but easiest is just to store it here in the same shape.
setSession(data.token ?? data.accessToken, {
uuid: data.uuid ?? data.id,
email: data.email,
displayName: data.displayName ?? null,
role: data.role ?? "USER",
});
setStatus("success");
setMessage("Youre in. Redirecting…");
router.replace("/account?welcome=1");
} catch (e: any) {
setStatus("error");
setMessage(e?.message || "Magic link expired. Request a new one.");
}
})();
}, [token, router, setSession]);
return (
<main className="min-h-screen bg-black text-zinc-50 flex items-center justify-center px-4">
<div className="max-w-md w-full rounded-xl border border-white/10 bg-white/5 p-6">
<h1 className="text-lg font-semibold">Battl Builders</h1>
<p className="mt-2 text-sm text-zinc-300">{message}</p>
{status === "error" && (
<div className="mt-4 text-xs text-zinc-400">
Try going back to your inbox and requesting a fresh sign-in link.
</div>
)}
</div>
</main>
);
}