67 lines
2.2 KiB
TypeScript
67 lines
2.2 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useRef } from "react";
|
|
import { useSearchParams, useRouter } from "next/navigation";
|
|
|
|
export default function AuthCallbackClient() {
|
|
const params = useSearchParams();
|
|
const router = useRouter();
|
|
const ran = useRef(false);
|
|
|
|
useEffect(() => {
|
|
if (ran.current) return;
|
|
ran.current = true;
|
|
|
|
const token = params.get("token");
|
|
if (!token) {
|
|
router.replace("/login");
|
|
return;
|
|
}
|
|
|
|
fetch("/api/auth/callback", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({ token }),
|
|
})
|
|
.then(async (res) => {
|
|
if (!res.ok) throw new Error(await res.text());
|
|
router.replace("/app");
|
|
})
|
|
.catch(() => {
|
|
router.replace("/login");
|
|
});
|
|
}, [params, router]);
|
|
|
|
return (
|
|
<div className="min-h-screen bg-gradient-to-b from-slate-50 to-white flex items-center justify-center">
|
|
<div className="text-center">
|
|
{/* Animated loader */}
|
|
<div className="mb-6">
|
|
<div className="inline-flex items-center justify-center w-16 h-16 rounded-full bg-blue-100">
|
|
<div className="relative w-12 h-12">
|
|
<div className="absolute inset-0 rounded-full border-2 border-slate-200"></div>
|
|
<div className="absolute inset-0 rounded-full border-2 border-transparent border-t-blue-600 border-r-blue-600 animate-spin"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Text */}
|
|
<h1 className="text-2xl font-bold text-slate-900 mb-2">Signing you in…</h1>
|
|
<p className="text-slate-600">
|
|
Please wait while we authenticate your account
|
|
</p>
|
|
|
|
{/* Progress indication */}
|
|
<div className="mt-8">
|
|
<div className="inline-flex items-center gap-2">
|
|
<div className="flex gap-1">
|
|
<span className="w-2 h-2 bg-blue-600 rounded-full animate-pulse"></span>
|
|
<span className="w-2 h-2 bg-blue-600 rounded-full animate-pulse" style={{ animationDelay: "0.2s" }}></span>
|
|
<span className="w-2 h-2 bg-blue-600 rounded-full animate-pulse" style={{ animationDelay: "0.4s" }}></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|