"use client"; import { Suspense, useEffect, useState } from "react"; import { useRouter, useSearchParams } from "next/navigation"; import { storeAuthTokens } from "@/lib/api"; type ApiResponse = { data: T; meta: { timestamp: string; version: "v1" }; error: null | { message: string; code?: string }; }; type SocialAuthData = { user: { id: string; email: string; fullName?: string; emailVerified?: boolean }; accessToken?: string; refreshToken?: string; next?: string; }; function decodeProvider(state: string | null) { if (!state) return ""; try { const [body] = state.split("."); const normalized = body.replace(/-/g, "+").replace(/_/g, "/").padEnd(Math.ceil(body.length / 4) * 4, "="); const json = JSON.parse(atob(normalized)) as { provider?: string }; return json.provider === "apple" || json.provider === "google" ? json.provider : ""; } catch { return ""; } } function SocialCallbackContent() { const router = useRouter(); const searchParams = useSearchParams(); const [status, setStatus] = useState<"loading" | "success" | "error">("loading"); const [message, setMessage] = useState("Completing sign in..."); useEffect(() => { const error = searchParams.get("error"); const code = searchParams.get("code"); const state = searchParams.get("state"); const provider = decodeProvider(state); if (error) { setStatus("error"); setMessage(error === "access_denied" ? "You declined social sign in." : `Provider returned an error: ${error}`); return; } if (!provider || !code || !state) { setStatus("error"); setMessage("Social sign in callback is missing required data."); return; } fetch(`/api/auth/social/${provider}/callback`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ code, state }), }) .then(async (res) => { const payload = (await res.json()) as ApiResponse; if (!res.ok || payload.error) throw new Error(payload.error?.message ?? "Social sign in failed."); storeAuthTokens({ user: payload.data.user, }); setStatus("success"); setMessage(`Signed in as ${payload.data.user.email}.`); setTimeout(() => router.replace(payload.data.next || "/app"), 800); }) .catch((err: Error) => { setStatus("error"); setMessage(err.message || "Social sign in failed."); }); }, [router, searchParams]); return (
{status === "loading" && ( <>

{message}

)} {status === "success" && ( <>

Signed in

{message}

)} {status === "error" && ( <>

Sign in failed

{message}

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