/** * OAuth Callback Handler Page * Handles the redirect from Google OAuth and exchanges code for token */ "use client"; import { useEffect, useState, Suspense } from "react"; import { useRouter, useSearchParams } from "next/navigation"; import { useAuth } from "@/contexts/auth-context"; function AuthCallbackContent() { const router = useRouter(); const searchParams = useSearchParams(); const { setAuthFromCallback } = useAuth(); const [error, setError] = useState(null); const [isProcessing, setIsProcessing] = useState(true); useEffect(() => { const handleCallback = async () => { // Check if we have a token directly (backend-handled flow) const token = searchParams.get("token"); if (token) { setAuthFromCallback(token); router.replace("/"); return; } // Check if we have a code (frontend-handled flow) const code = searchParams.get("code"); if (!code) { const errorParam = searchParams.get("error"); setError(errorParam || "No authorization code received"); setIsProcessing(false); return; } try { // Exchange code for token via backend const redirectUri = `${window.location.origin}/api/auth/callback/google`; const response = await fetch("/api/auth/google/token", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ code, redirect_uri: redirectUri, }), }); if (!response.ok) { const errorData = await response.json(); // Handle various error response formats const errorMessage = typeof errorData.detail === 'string' ? errorData.detail : typeof errorData.error === 'string' ? errorData.error : errorData.message || JSON.stringify(errorData) || "Failed to exchange token"; throw new Error(errorMessage); } const data = await response.json(); setAuthFromCallback(data.access_token); router.replace("/"); } catch (err: any) { console.error("Auth callback error:", err); const msg = err.message || "Authentication failed"; setError(typeof msg === 'string' ? msg : "Authentication failed"); setIsProcessing(false); } }; handleCallback(); }, [searchParams, setAuthFromCallback, router]); if (error) { return (
⚠️

登入失敗

{error}

); } return (

正在登入...

請稍候

); } function LoadingFallback() { return (

載入中...

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