From fba93e4c358def2159c969e33c738872affdfe96 Mon Sep 17 00:00:00 2001 From: AbdulmujibOladayo Date: Thu, 29 Jan 2026 05:11:28 +0100 Subject: [PATCH] email verification page --- frontend/app/email-success/page.tsx | 333 ++++++++++++++++++++++++++++ 1 file changed, 333 insertions(+) create mode 100644 frontend/app/email-success/page.tsx diff --git a/frontend/app/email-success/page.tsx b/frontend/app/email-success/page.tsx new file mode 100644 index 0000000..11de89a --- /dev/null +++ b/frontend/app/email-success/page.tsx @@ -0,0 +1,333 @@ +"use client"; + +import { useState, useEffect } from "react"; +import Link from "next/link"; +import { useRouter, useSearchParams } from "next/navigation"; + +type VerificationState = "loading" | "success" | "error" | "already-verified"; + +export default function VerifyEmailPage() { + const [state, setState] = useState("loading"); + const [errorMessage, setErrorMessage] = useState(""); + const [userEmail, setUserEmail] = useState(""); + const [countdown, setCountdown] = useState(5); + const [isResending, setIsResending] = useState(false); + const router = useRouter(); + const searchParams = useSearchParams(); + const token = searchParams.get("token"); + + useEffect(() => { + if (!token) { + setState("error"); + setErrorMessage( + "No verification token found. Please check your email link.", + ); + return; + } + + verifyEmail(token); + }, [token]); + + useEffect(() => { + if (state === "success" || state === "already-verified") { + let timeLeft = 5; + const timer = setInterval(() => { + timeLeft -= 1; + setCountdown(timeLeft); + if (timeLeft === 0) { + clearInterval(timer); + // Check if user is logged in to decide redirect + const isLoggedIn = localStorage.getItem("authToken"); // Adjust based on your auth + router.push(isLoggedIn ? "/dashboard" : "/login"); + } + }, 1000); + + return () => clearInterval(timer); + } + }, [state, router]); + + const verifyEmail = async (verificationToken: string) => { + try { + const response = await fetch("/api/v1/auth/verify-email", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ token: verificationToken }), + }); + + const data = await response.json(); + + if (!response.ok) { + if (data.message?.includes("already verified")) { + setState("already-verified"); + setUserEmail(data.email || ""); + } else if ( + data.message?.includes("expired") || + data.message?.includes("invalid") + ) { + setState("error"); + setErrorMessage( + "This verification link has expired or is invalid. Please request a new one.", + ); + } else { + setState("error"); + setErrorMessage( + data.message || "Verification failed. Please try again.", + ); + } + return; + } + + setState("success"); + setUserEmail(data.email || ""); + } catch (error) { + setState("error"); + setErrorMessage( + "Network error. Please check your connection and try again.", + ); + } + }; + + const handleResendEmail = async () => { + setIsResending(true); + try { + const response = await fetch("/api/v1/auth/resend-verification", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ email: userEmail }), + }); + + if (response.ok) { + alert("Verification email sent! Please check your inbox."); + } else { + alert("Failed to resend email. Please try again later."); + } + } catch (error) { + alert("Network error. Please try again."); + } finally { + setIsResending(false); + } + }; + + // Loading State + if (state === "loading") { + return ( +
+
+
+ + + + +
+

+ Verifying Your Email... +

+

Please wait a moment

+
+
+ ); + } + + // Success State + if (state === "success") { + const isLoggedIn = + typeof window !== "undefined" && localStorage.getItem("authToken"); + + return ( +
+
+
+
+ + + +
+

+ Email Verified! +

+

+ Your email has been successfully verified +

+ {userEmail && ( +

+ {userEmail} +

+ )} +

+ You can now access all features of AssetsUp +

+
+ +
+ + {isLoggedIn ? "Continue to Dashboard" : "Go to Login"} + +

+ Redirecting in {countdown} seconds... +

+
+
+
+ ); + } + + // Already Verified State + if (state === "already-verified") { + const isLoggedIn = + typeof window !== "undefined" && localStorage.getItem("authToken"); + + return ( +
+
+
+
+ + + +
+

+ Already Verified +

+

+ This email is already verified +

+ {userEmail && ( +

+ {userEmail} +

+ )} +

+ You can proceed to login or dashboard +

+
+ +
+ + {isLoggedIn ? "Go to Dashboard" : "Go to Login"} + +

+ Redirecting in {countdown} seconds... +

+
+
+
+ ); + } + + // Error State + return ( +
+
+
+
+ + + +
+

+ Verification Failed +

+

{errorMessage}

+
+ +
+ + + Back to Login + +
+
+
+ ); +}