@@ -53,8 +53,11 @@ const SignUp: React.FC = () => {
5353 if ( name === "password" ) {
5454 if ( ! value . trim ( ) ) {
5555 errorMessage = "Password is required" ;
56- } else if ( ! / ^ (? = .* [ A - Z a - z ] ) (? = .* \d ) [ A - Z a - z \d @ $ ! % * # ? & ] { 8 , } $ / . test ( value ) ) {
57- errorMessage = "Password must be 8+ characters with letters and numbers" ;
56+ } else if (
57+ ! / ^ (? = .* [ A - Z a - z ] ) (? = .* \d ) [ A - Z a - z \d @ $ ! % * # ? & ] { 8 , } $ / . test ( value )
58+ ) {
59+ errorMessage =
60+ "Password must be 8+ characters with letters and numbers" ;
5861 }
5962 }
6063 setErrors ( ( prev ) => ( { ...prev , [ name ] : errorMessage } ) ) ;
@@ -65,35 +68,49 @@ const SignUp: React.FC = () => {
6568 const usernameError = ! formData . username . trim ( )
6669 ? "Username is required"
6770 : ! / ^ [ A - Z a - z \s ] + $ / . test ( formData . username )
68- ? "Only letters are allowed"
69- : "" ;
71+ ? "Only letters are allowed"
72+ : "" ;
7073 const emailError = ! formData . email . trim ( )
7174 ? "Email is required"
7275 : ! / ^ [ ^ \s @ ] + @ [ ^ \s @ ] + \. [ ^ \s @ ] + $ / . test ( formData . email . trim ( ) )
73- ? "Enter a valid email"
74- : "" ;
76+ ? "Enter a valid email"
77+ : "" ;
7578 const passwordError = ! formData . password . trim ( )
7679 ? "Password is required"
77- : ! / ^ (? = .* [ A - Z a - z ] ) (? = .* \d ) [ A - Z a - z \d @ $ ! % * # ? & ] { 8 , } $ / . test ( formData . password )
78- ? "Password must be 8+ characters with letters and numbers"
79- : "" ;
80+ : ! / ^ (? = .* [ A - Z a - z ] ) (? = .* \d ) [ A - Z a - z \d @ $ ! % * # ? & ] { 8 , } $ / . test (
81+ formData . password ,
82+ )
83+ ? "Password must be 8+ characters with letters and numbers"
84+ : "" ;
8085 if ( usernameError || emailError || passwordError ) {
81- setErrors ( { username : usernameError , email : emailError , password : passwordError } ) ;
86+ setErrors ( {
87+ username : usernameError ,
88+ email : emailError ,
89+ password : passwordError ,
90+ } ) ;
8291 return ;
8392 }
8493 setIsLoading ( true ) ;
8594 try {
86- const response = await axios . post ( `${ backendUrl } /api/auth/signup` ,
87- formData // Include cookies for session
95+ const response = await axios . post (
96+ `${ backendUrl } /api/auth/signup` ,
97+ formData , // Include cookies for session
8898 ) ;
8999 setMessage ( response . data . message ) ; // Show success message from backend
90100
91101 // Navigate to login page after successful signup
92- if ( response . data . message === ' User created successfully' ) {
102+ if ( response . data . message === " User created successfully" ) {
93103 navigate ( "/login" ) ;
94104 }
95- } catch ( error : any ) {
96- setMessage ( error . response ?. data ?. message || "Something went wrong. Please try again." ) ;
105+ } catch ( error : unknown ) {
106+ if ( axios . isAxiosError ( error ) ) {
107+ setMessage (
108+ error . response ?. data ?. message ||
109+ "Something went wrong. Please try again." ,
110+ ) ;
111+ } else {
112+ setMessage ( "Something went wrong. Please try again." ) ;
113+ }
97114 } finally {
98115 setIsLoading ( false ) ;
99116 }
@@ -138,10 +155,22 @@ const SignUp: React.FC = () => {
138155 className = "text-center mb-10"
139156 >
140157 < div className = "inline-flex items-center justify-center w-20 h-20 bg-white rounded-3xl mb-6 shadow-2xl transform hover:scale-105 transition-transform duration-300 overflow-hidden" >
141- < img src = "/crl-icon.png" alt = "Logo" className = "w-14 h-14 object-contain" />
158+ < img
159+ src = "/crl-icon.png"
160+ alt = "Logo"
161+ className = "w-14 h-14 object-contain"
162+ />
142163 </ div >
143- < h1 className = { `text-4xl font-bold mb-2 ${ mode === "dark" ? "text-white" : "text-black" } ` } > GitHubTracker</ h1 >
144- < p className = { `text-lg font-medium ${ mode === "dark" ? "text-slate-300" : "text-gray-700" } ` } > Join your GitHub journey</ p >
164+ < h1
165+ className = { `text-4xl font-bold mb-2 ${ mode === "dark" ? "text-white" : "text-black" } ` }
166+ >
167+ GitHubTracker
168+ </ h1 >
169+ < p
170+ className = { `text-lg font-medium ${ mode === "dark" ? "text-slate-300" : "text-gray-700" } ` }
171+ >
172+ Join your GitHub journey
173+ </ p >
145174 </ motion . div >
146175
147176 < motion . div
@@ -154,7 +183,6 @@ const SignUp: React.FC = () => {
154183 : "bg-white border-gray-200 text-black"
155184 } `}
156185 >
157-
158186 < h2
159187 className = { `text-2xl font-bold text-center mb-8 ${
160188 mode === "dark" ? "text-white" : "text-gray-800"
@@ -169,39 +197,72 @@ const SignUp: React.FC = () => {
169197 < div className = "absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none" >
170198 < User className = "h-5 w-5 text-gray-400" />
171199 </ div >
172- < input type = "text" name = "username" placeholder = "Enter your username" value = { formData . username } onChange = { handleChange } required
200+ < input
201+ type = "text"
202+ name = "username"
203+ placeholder = "Enter your username"
204+ value = { formData . username }
205+ onChange = { handleChange }
206+ required
173207 className = { `w-full pl-12 pr-4 py-4 rounded-2xl border focus:outline-none focus:ring-2 focus:ring-gray-400 focus:border-transparent transition-all duration-300 ${ mode === "dark" ? "bg-white/10 border-white/20 text-white placeholder-gray-400" : "bg-gray-100 border-gray-300 text-black placeholder-gray-400" } ` }
174208 />
175209 </ div >
176- { errors . username && < p className = "text-red-500 text-sm mt-2" > { errors . username } </ p > }
210+ { errors . username && (
211+ < p className = "text-red-500 text-sm mt-2" > { errors . username } </ p >
212+ ) }
177213 </ div >
178214
179215 < div >
180216 < div className = "relative" >
181217 < div className = "absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none" >
182218 < Mail className = "h-5 w-5 text-gray-400" />
183219 </ div >
184- < input type = "email" name = "email" placeholder = "Enter your email" value = { formData . email } onChange = { handleChange } required
220+ < input
221+ type = "email"
222+ name = "email"
223+ placeholder = "Enter your email"
224+ value = { formData . email }
225+ onChange = { handleChange }
226+ required
185227 className = { `w-full pl-12 pr-4 py-4 rounded-2xl border focus:outline-none focus:ring-2 focus:ring-gray-400 focus:border-transparent transition-all duration-300 ${ mode === "dark" ? "bg-white/10 border-white/20 text-white placeholder-gray-400" : "bg-gray-100 border-gray-300 text-black placeholder-gray-400" } ` }
186228 />
187229 </ div >
188- { errors . email && < p className = "text-red-500 text-sm mt-2" > { errors . email } </ p > }
230+ { errors . email && (
231+ < p className = "text-red-500 text-sm mt-2" > { errors . email } </ p >
232+ ) }
189233 </ div >
190234
191235 < div >
192236 < div className = "relative" >
193237 < div className = "absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none" >
194238 < Lock className = "h-5 w-5 text-gray-400" />
195239 </ div >
196- < input type = { showPassword ? "text" : "password" } name = "password" placeholder = "Enter your password" value = { formData . password } onChange = { handleChange } required
240+ < input
241+ type = { showPassword ? "text" : "password" }
242+ name = "password"
243+ placeholder = "Enter your password"
244+ value = { formData . password }
245+ onChange = { handleChange }
246+ required
197247 className = { `w-full pl-12 pr-12 py-4 rounded-2xl border focus:outline-none focus:ring-2 focus:ring-gray-400 focus:border-transparent transition-all duration-300 ${ mode === "dark" ? "bg-white/10 border-white/20 text-white placeholder-gray-400" : "bg-gray-100 border-gray-300 text-black placeholder-gray-400" } ` }
198248 />
199- < button type = "button" onClick = { ( ) => setShowPassword ( ! showPassword ) } aria-label = { showPassword ? "Hide password" : "Show password" } aria-pressed = { showPassword }
200- className = { `absolute inset-y-0 right-0 pr-4 flex items-center transition-colors duration-200 ${ mode === "dark" ? "text-slate-400 hover:text-white" : "text-gray-500 hover:text-gray-800" } ` } >
201- { showPassword ? < EyeOff className = "h-5 w-5" /> : < Eye className = "h-5 w-5" /> }
249+ < button
250+ type = "button"
251+ onClick = { ( ) => setShowPassword ( ! showPassword ) }
252+ aria-label = { showPassword ? "Hide password" : "Show password" }
253+ aria-pressed = { showPassword }
254+ className = { `absolute inset-y-0 right-0 pr-4 flex items-center transition-colors duration-200 ${ mode === "dark" ? "text-slate-400 hover:text-white" : "text-gray-500 hover:text-gray-800" } ` }
255+ >
256+ { showPassword ? (
257+ < EyeOff className = "h-5 w-5" />
258+ ) : (
259+ < Eye className = "h-5 w-5" />
260+ ) }
202261 </ button >
203262 </ div >
204- { errors . password && < p className = "text-red-500 text-sm mt-2" > { errors . password } </ p > }
263+ { errors . password && (
264+ < p className = "text-red-500 text-sm mt-2" > { errors . password } </ p >
265+ ) }
205266 </ div >
206267
207268 < button
@@ -214,15 +275,20 @@ const SignUp: React.FC = () => {
214275 </ form >
215276
216277 { message && (
217- < div className = { `text-center mt-6 p-3 rounded-xl ${ message . includes ( "successfully" ) ? "text-green-600 bg-green-100" : "text-red-600 bg-red-100" } ` } >
278+ < div
279+ className = { `text-center mt-6 p-3 rounded-xl ${ message . includes ( "successfully" ) ? "text-green-600 bg-green-100" : "text-red-600 bg-red-100" } ` }
280+ >
218281 { message }
219282 </ div >
220283 ) }
221284
222285 < div className = "text-center mt-8" >
223286 < p className = { mode === "dark" ? "text-gray-300" : "text-gray-600" } >
224287 Already have an account?{ " " }
225- < Link to = "/login" className = { `font-medium hover:underline transition-colors duration-300 ${ mode === "dark" ? "text-white" : "text-black" } ` } >
288+ < Link
289+ to = "/login"
290+ className = { `font-medium hover:underline transition-colors duration-300 ${ mode === "dark" ? "text-white" : "text-black" } ` }
291+ >
226292 Sign in here
227293 </ Link >
228294 </ p >
0 commit comments