@@ -14,12 +14,10 @@ import { API_BASE_URL } from "@/lib/api";
1414import { useFirebaseAuth } from "@/hooks/use-firebase-auth" ;
1515import {
1616 GoogleAuthProvider ,
17- signInWithPopup ,
18- createUserWithEmailAndPassword ,
19- updateProfile ,
20- sendEmailVerification
17+ signInWithPopup
2118} from "firebase/auth" ;
2219import { useRouter } from "next/navigation" ;
20+ import Script from 'next/script' ;
2321
2422
2523const GoogleIcon = ( props : React . SVGProps < SVGSVGElement > ) => (
@@ -51,6 +49,12 @@ interface SignupModalProps {
5149 setIsOpen : ( isOpen : boolean ) => void ;
5250}
5351
52+ declare global {
53+ interface Window {
54+ grecaptcha : any ;
55+ }
56+ }
57+
5458export default function SignupModal ( { isOpen, setIsOpen } : SignupModalProps ) {
5559 const { toast } = useToast ( ) ;
5660 const router = useRouter ( ) ;
@@ -66,38 +70,48 @@ export default function SignupModal({ isOpen, setIsOpen }: SignupModalProps) {
6670
6771 const { formState : { isSubmitting } } = form ;
6872
69- const handleSignup = async ( values : SignupSchema ) => {
70- if ( ! auth ) {
71- toast ( { variant : 'destructive' , title : 'Error' , description : 'Authentication service is not available . Please try again later .' } ) ;
73+ const executeRecaptcha = ( callback : ( token : string ) => void ) => {
74+ if ( ! window . grecaptcha ) {
75+ toast ( { variant : 'destructive' , title : 'reCAPTCHA Error' , description : 'reCAPTCHA not loaded . Please try again.' } ) ;
7276 return ;
7377 }
74- try {
75- // Register user with Firebase Auth
76- const userCredential = await createUserWithEmailAndPassword ( auth , values . email , values . password ) ;
77- // Optionally update display name
78- await updateProfile ( userCredential . user , { displayName : values . name } ) ;
79- // Send email verification
80- await sendEmailVerification ( userCredential . user ) ;
78+ window . grecaptcha . enterprise . ready ( ( ) => {
79+ window . grecaptcha . enterprise . execute ( '6LfZ4H8rAAAAAA0NMVH1C-sCiE9-Vz4obaWy9eUI' , { action : 'register' } ) . then ( callback ) ;
80+ } ) ;
81+ } ;
82+
83+ const handleSignup = ( values : SignupSchema ) => {
84+ executeRecaptcha ( async ( recaptchaToken : string ) => {
85+ try {
86+ const response = await fetch ( `${ API_BASE_URL } /api/register` , {
87+ method : 'POST' ,
88+ headers : { 'Content-Type' : 'application/json' } ,
89+ body : JSON . stringify ( { ...values , recaptchaToken } ) ,
90+ } ) ;
91+
92+ const data = await response . json ( ) ;
93+
94+ if ( response . ok ) {
95+ toast ( {
96+ title : "Registration Successful" ,
97+ description : "Your account has been created. Please check your email to verify your account." ,
98+ } ) ;
99+ setIsOpen ( false ) ;
100+ } else {
101+ toast ( {
102+ variant : "destructive" ,
103+ title : "Registration Failed" ,
104+ description : data . error || 'An unexpected error occurred.' ,
105+ } ) ;
106+ }
107+ } catch ( error ) {
81108 toast ( {
82- title : "Registration Successful" ,
83- description : "Your account has been created. Please check your email to verify your account." ,
109+ variant : "destructive" ,
110+ title : "Registration Failed" ,
111+ description : "Could not connect to the server. Please try again later." ,
84112 } ) ;
85- setIsOpen ( false ) ;
86- } catch ( error : any ) {
87- let description = error . message || 'An error occurred while creating your account.' ;
88- if ( error . code === 'auth/email-already-in-use' ) {
89- description = 'This email is already in use.' ;
90- } else if ( error . code === 'auth/invalid-email' ) {
91- description = 'The email address is invalid.' ;
92- } else if ( error . code === 'auth/weak-password' ) {
93- description = 'The password is too weak.' ;
94113 }
95- toast ( {
96- variant : "destructive" ,
97- title : "Registration Failed" ,
98- description,
99- } ) ;
100- }
114+ } ) ;
101115 } ;
102116
103117 const handleSocialLogin = async ( provider : 'google' ) => {
@@ -109,7 +123,7 @@ export default function SignupModal({ isOpen, setIsOpen }: SignupModalProps) {
109123 try {
110124 const result = await signInWithPopup ( auth , authProvider ) ;
111125 toast ( { title : "Login Successful" , description : `Welcome, ${ result . user . displayName || result . user . email } !` } ) ;
112- setIsOpen ( false ) ;
126+ setIsOpen ( false ) ;
113127 // Optionally update UI or redirect
114128 } catch ( error : any ) {
115129 let description = error . message || 'An error occurred while signing in.' ;
@@ -127,8 +141,13 @@ export default function SignupModal({ isOpen, setIsOpen }: SignupModalProps) {
127141 } ;
128142
129143 return (
144+ < >
145+ < Script
146+ src = "https://www.google.com/recaptcha/enterprise.js?render=6LfZ4H8rAAAAAA0NMVH1C-sCiE9-Vz4obaWy9eUI"
147+ strategy = "lazyOnload"
148+ />
130149 < Dialog open = { isOpen } onOpenChange = { setIsOpen } >
131- < DialogContent className = "sm:max-w-lg" >
150+ < DialogContent className = "sm:max-w-lg auth-modal-glow overflow-hidden " >
132151 < DialogHeader className = "text-center" >
133152 < DialogTitle > Create an Account</ DialogTitle >
134153 < DialogDescription >
@@ -205,5 +224,6 @@ export default function SignupModal({ isOpen, setIsOpen }: SignupModalProps) {
205224 </ Form >
206225 </ DialogContent >
207226 </ Dialog >
227+ </ >
208228 ) ;
209229}
0 commit comments