@@ -7,33 +7,37 @@ import { InputOTP } from "@/components/ui/input-otp"
77import { Card , CardHeader , CardDescription , CardTitle , CardContent , CardFooter } from "@/components/ui/card"
88import { Button } from "@/components/ui/button"
99import { ArrowLeft } from "lucide-react"
10- import { useRouter , useSearchParams } from "next/navigation"
10+ import { useSearchParams } from "next/navigation"
1111import { useCallback , useState , Suspense } from "react"
12- import VerificationFailed from "./verificationFailed"
1312import { SourcebotLogo } from "@/app/components/sourcebotLogo"
1413import useCaptureEvent from "@/hooks/useCaptureEvent"
1514import { Footer } from "@/app/components/footer"
1615import { SOURCEBOT_SUPPORT_EMAIL } from "@/lib/constants"
16+ import { Redirect } from "@/app/components/redirect"
1717
1818function VerifyPageContent ( ) {
1919 const [ value , setValue ] = useState ( "" )
2020 const searchParams = useSearchParams ( )
2121 const email = searchParams . get ( "email" )
22- const router = useRouter ( )
2322 const captureEvent = useCaptureEvent ( ) ;
2423
2524 const handleSubmit = useCallback ( ( ) => {
2625 if ( email && value . length === 6 ) {
2726 const url = new URL ( "/api/auth/callback/nodemailer" , window . location . origin )
2827 url . searchParams . set ( "token" , value )
2928 url . searchParams . set ( "email" , email )
30- router . push ( url . toString ( ) )
29+ // Use a full-page navigation (not router.push) so the auth callback's
30+ // session cookie + 302 redirect are applied by the browser, and the
31+ // one-time token isn't consumed twice by a client-side RSC navigation.
32+ window . location . href = url . toString ( )
3133 }
32- } , [ value , email , router ] )
34+ } , [ value , email ] )
3335
3436 if ( ! email ) {
3537 captureEvent ( "wa_login_verify_page_no_email" , { } )
36- return < VerificationFailed />
38+ return < Redirect
39+ to = "/login"
40+ />
3741 }
3842
3943 const handleKeyDown = ( e : React . KeyboardEvent < HTMLInputElement > ) => {
@@ -49,9 +53,9 @@ function VerifyPageContent() {
4953 < div className = "flex justify-center mb-6" >
5054 < SourcebotLogo className = "h-16" size = "large" />
5155 </ div >
52- < Card className = "w-full shadow-lg border-muted/40 " >
56+ < Card className = "w-full" >
5357 < CardHeader className = "space-y-1" >
54- < CardTitle className = "text-2xl font-bold text-center" > Verify your email</ CardTitle >
58+ < CardTitle className = "text-2xl font-semibold text-center" > Verify your email</ CardTitle >
5559 < CardDescription className = "text-center" >
5660 Enter the 6-digit code we sent to < span className = "font-semibold text-primary" > { email } </ span >
5761 </ CardDescription >
@@ -65,15 +69,15 @@ function VerifyPageContent() {
6569 < div className = "flex justify-center py-4" >
6670 < InputOTP maxLength = { 6 } value = { value } onChange = { setValue } onKeyDown = { handleKeyDown } className = "gap-2" >
6771 < InputOTPGroup >
68- < InputOTPSlot index = { 0 } className = "rounded-md border-input" />
69- < InputOTPSlot index = { 1 } className = "rounded-md border-input" />
70- < InputOTPSlot index = { 2 } className = "rounded-md border-input" />
72+ < InputOTPSlot index = { 0 } />
73+ < InputOTPSlot index = { 1 } />
74+ < InputOTPSlot index = { 2 } />
7175 </ InputOTPGroup >
7276 < InputOTPSeparator />
7377 < InputOTPGroup >
74- < InputOTPSlot index = { 3 } className = "rounded-md border-input" />
75- < InputOTPSlot index = { 4 } className = "rounded-md border-input" />
76- < InputOTPSlot index = { 5 } className = "rounded-md border-input" />
78+ < InputOTPSlot index = { 3 } />
79+ < InputOTPSlot index = { 4 } />
80+ < InputOTPSlot index = { 5 } />
7781 </ InputOTPGroup >
7882 </ InputOTP >
7983 </ div >
0 commit comments