83 lines
2.2 KiB
TypeScript
83 lines
2.2 KiB
TypeScript
"use client";
|
|
|
|
import { Suspense, useEffect, useState } from "react";
|
|
import Link from "next/link";
|
|
import { useSearchParams } from "next/navigation";
|
|
import { auth, AuthError } from "@/lib/auth";
|
|
import { useAuth } from "@/components/auth/auth-provider";
|
|
import {
|
|
Card,
|
|
CardContent,
|
|
CardDescription,
|
|
CardHeader,
|
|
CardTitle,
|
|
} from "@/components/ui/card";
|
|
|
|
function VerifyEmailContent() {
|
|
const params = useSearchParams();
|
|
const token = params.get("token") ?? "";
|
|
const { refresh } = useAuth();
|
|
const [status, setStatus] = useState<"pending" | "ok" | "error">("pending");
|
|
const [message, setMessage] = useState<string>("");
|
|
|
|
useEffect(() => {
|
|
if (!token) {
|
|
setStatus("error");
|
|
setMessage("Verification link is missing a token.");
|
|
return;
|
|
}
|
|
void (async () => {
|
|
try {
|
|
await auth.verifyEmail(token);
|
|
// Pull the freshly-verified user so the banner disappears immediately.
|
|
await refresh();
|
|
setStatus("ok");
|
|
} catch (err) {
|
|
setStatus("error");
|
|
setMessage(err instanceof AuthError ? err.message : "Verification failed.");
|
|
}
|
|
})();
|
|
}, [token, refresh]);
|
|
|
|
return (
|
|
<main className="flex-1 flex items-center justify-center px-4 py-12">
|
|
<div className="w-full max-w-md">
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle className="text-2xl">
|
|
{status === "pending"
|
|
? "Verifying your email…"
|
|
: status === "ok"
|
|
? "Email verified ✓"
|
|
: "Verification failed"}
|
|
</CardTitle>
|
|
<CardDescription>
|
|
{status === "pending"
|
|
? "One moment."
|
|
: status === "ok"
|
|
? "Thanks — your email is confirmed."
|
|
: message}
|
|
</CardDescription>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<Link
|
|
href="/"
|
|
className="text-primary underline-offset-4 hover:underline"
|
|
>
|
|
Back to home
|
|
</Link>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
</main>
|
|
);
|
|
}
|
|
|
|
export default function VerifyEmailPage() {
|
|
return (
|
|
<Suspense fallback={null}>
|
|
<VerifyEmailContent />
|
|
</Suspense>
|
|
);
|
|
}
|