Files
falah-mobile/src/app/auth/callback/page.tsx
T

107 lines
3.4 KiB
TypeScript

"use client";
import { Suspense, useEffect, useState } from "react";
import { useRouter, useSearchParams } from "next/navigation";
function AuthCallbackContent() {
const router = useRouter();
const searchParams = useSearchParams();
const [status, setStatus] = useState<"processing" | "success" | "error">(
"processing"
);
const [errorMsg, setErrorMsg] = useState("");
useEffect(() => {
const token = searchParams.get("token");
const error = searchParams.get("error");
if (error) {
setStatus("error");
setErrorMsg(decodeURIComponent(error));
return;
}
if (!token) {
setStatus("error");
setErrorMsg("No authentication token received.");
return;
}
// Store token in localStorage
localStorage.setItem("flh_token", token);
// Dispatch a custom event so the AuthContext can pick it up
// (used by popup-based OAuth where the opener listens)
window.dispatchEvent(
new StorageEvent("storage", {
key: "flh_token",
newValue: token,
oldValue: null,
storageArea: localStorage,
})
);
setStatus("success");
// If this is a popup window, close it after a brief delay
if (window.opener) {
setTimeout(() => window.close(), 500);
} else {
// Redirect to home
setTimeout(() => router.push("/"), 500);
}
}, [searchParams, router]);
return (
<div className="min-h-dvh bg-[#0a0a0f] flex items-center justify-center">
<div className="text-center">
{status === "processing" && (
<div className="flex flex-col items-center gap-4">
<div className="w-10 h-10 rounded-full border-2 border-[#D4AF37]/30 border-t-[#D4AF37] animate-spin" />
<p className="text-sm text-gray-400">Signing you in...</p>
</div>
)}
{status === "success" && (
<div className="flex flex-col items-center gap-3">
<div className="w-12 h-12 rounded-full bg-green-900/30 border border-green-700/40 flex items-center justify-center">
<span className="text-green-400 text-xl"></span>
</div>
<p className="text-sm text-green-400">Signed in successfully!</p>
</div>
)}
{status === "error" && (
<div className="flex flex-col items-center gap-3">
<div className="w-12 h-12 rounded-full bg-red-900/30 border border-red-700/40 flex items-center justify-center">
<span className="text-red-400 text-xl"></span>
</div>
<p className="text-sm text-red-400">{errorMsg}</p>
<button
onClick={() => router.push("/auth")}
className="mt-4 px-6 py-2 rounded-xl bg-[#D4AF37] text-[#0a0a0f] text-sm font-medium"
>
Back to Login
</button>
</div>
)}
</div>
</div>
);
}
export default function AuthCallbackPage() {
return (
<Suspense
fallback={
<div className="min-h-dvh bg-[#0a0a0f] flex items-center justify-center">
<div className="flex flex-col items-center gap-4">
<div className="w-10 h-10 rounded-full border-2 border-[#D4AF37]/30 border-t-[#D4AF37] animate-spin" />
<p className="text-sm text-gray-400">Signing you in...</p>
</div>
</div>
}
>
<AuthCallbackContent />
</Suspense>
);
}