diff --git a/src/routes/verify-email.tsx b/src/routes/verify-email.tsx index fc2d782..28769b7 100644 --- a/src/routes/verify-email.tsx +++ b/src/routes/verify-email.tsx @@ -47,16 +47,14 @@ function getVerificationErrorMessage(error: string | undefined) { function getVerifyEmailPageCopy({ isHostedMode, errorMessage, - isWaiting, isPending, - isVerified, + isRedirecting, email, }: { isHostedMode: boolean; errorMessage: string | null; - isWaiting: boolean; isPending: boolean; - isVerified: boolean; + isRedirecting: boolean; email: string | undefined; }) { if (!isHostedMode) { @@ -73,12 +71,10 @@ function getVerifyEmailPageCopy({ }; } - if (isWaiting) { + if (isRedirecting) { return { - title: "Verify your email", - helperText: email - ? `Click the link we sent to ${email} to verify your email.` - : "Check your inbox for the link to verify your email.", + title: "Email confirmed", + helperText: "You're all set. Taking you to your account now.", }; } @@ -89,16 +85,15 @@ function getVerifyEmailPageCopy({ }; } - if (isVerified) { - return { - title: "Email confirmed", - helperText: "You're all set. Taking you to your account now.", - }; - } - + // Default: the user just signed up (or reloaded this page) and still needs to + // click the verification link. There is never a sign-in CTA here — an + // unverified hosted user would be bounced straight back by the verification + // gate. return { - title: "Sign in to continue", - helperText: "Sign in to continue to your account.", + title: "Verify your email", + helperText: email + ? `Click the link we sent to ${email} to verify your email.` + : "Check your inbox for the link to verify your email.", }; } @@ -115,23 +110,15 @@ function VerifyEmailPage() { const email = search.email ?? session?.user?.email; const isVerified = !!session?.user?.emailVerified; const [isResending, setIsResending] = useState(false); - // A hosted user who still needs to verify must see the resend / "check your - // inbox" state — never a sign-in CTA, which the verification gate would - // immediately block (the email-verify trap). Keying off `email` (which the - // sign-up flow always passes) covers the just-signed-up case even while the - // session is still resolving, so we never flash the sign-in fallback. - const isWaiting = - isHostedMode && - !errorMessage && - !bypassEmailVerification && - !isVerified && - (Boolean(email) || !isPending); + // Verified (or bypass) users are sent on to the app by the effect below; until + // that lands we show the redirecting state instead of the resend prompt. + const isRedirecting = + isVerified || (bypassEmailVerification && Boolean(session?.user?.id)); const pageCopy = getVerifyEmailPageCopy({ isHostedMode, errorMessage, - isWaiting, isPending, - isVerified, + isRedirecting, email, }); @@ -229,32 +216,20 @@ function VerifyEmailPage() { Back to sign in - ) : isWaiting ? ( - email ? ( -
- -
- ) : null - ) : isPending || isVerified ? ( + ) : isPending || isRedirecting ? (
- ) : ( - void handleResend()} + disabled={isResending} > - Sign in to continue - - )} + {isResending ? "Sending email..." : "Resend email"} + + ) : null} );