import { eq } from "drizzle-orm"; import { CheckCircle2, Clock, MailX } from "lucide-react"; import { getTranslations } from "next-intl/server"; import { isValidVerificationToken } from "@/actions/email-verify"; import Link from "@/components/link"; import { SurfaceCard } from "@/components/surface-card"; import { db, User } from "@/lib/db"; type Status = "verified" | "already" | "invalid" | "unavailable"; function StatusCard({ icon, title, subtitle, children, color, }: { icon: React.ReactNode; title: string; subtitle: string; children: React.ReactNode; color: string; }) { const tintMap: Record = { green: "#16a34a", yellow: "#d97706", red: "#dc2626", blue: "#2563eb", }; const tint = tintMap[color] ?? tintMap.blue; return (
{icon}

{title}

{icon}

{subtitle}

{children}
); } export default async function VerifyPage({ searchParams, }: { searchParams: Promise<{ token?: string; email?: string; }>; }) { const t = await getTranslations("pages.verify"); const { token = "", email = "" } = await searchParams; const normalisedEmail = email.trim().toLowerCase(); let status: Status = "invalid"; if (normalisedEmail && token) { const ok = await isValidVerificationToken(normalisedEmail, token); if (ok) { try { const [user] = await db .select({ id: User.id, mailVerified: User.mailVerified }) .from(User) .where(eq(User.mail, normalisedEmail)) .limit(1); if (!user) { status = "invalid"; } else if (user.mailVerified === "1") { status = "already"; } else { await db .update(User) .set({ mailVerified: "1" }) .where(eq(User.id, user.id)); status = "verified"; } } catch { status = "unavailable"; } } } const linkClass = "btn-shine inline-flex items-center gap-2 font-extrabold text-sm px-6 py-3 rounded-xl transition-all duration-200 hover:scale-[1.02] active:scale-95 shadow-lg"; const linkStyle = { background: "var(--color-primary)", color: "var(--color-primary-foreground)", boxShadow: "0 4px 20px color-mix(in srgb, var(--color-primary) 30%, transparent)", }; return ( <> {status === "verified" && ( } title={t("verifiedTitle")} subtitle={t("verifiedSubtitle")} color="green" >

{t("verifiedBody")}

{t("goToLogin")}
)} {status === "already" && ( } title={t("alreadyTitle")} subtitle={t("alreadySubtitle")} color="yellow" >

{t("alreadyBody")}

{t("goToLogin")}
)} {status === "unavailable" && ( } title={t("unavailableTitle")} subtitle={t("unavailableSubtitle")} color="blue" >

{t("unavailableBody")}

)} {status === "invalid" && ( } title={t("invalidTitle")} subtitle={t("invalidSubtitle")} color="red" >

{t("invalidBody")}

{t("backToLogin")}
)} ); }