From 8539d1e97ff9aac22e81881b37215bc148223157 Mon Sep 17 00:00:00 2001 From: DeepakGhenyar Date: Fri, 15 May 2026 23:30:07 +0530 Subject: [PATCH 1/3] Enhance signup form validation and user feedback handling --- src/pages/Signup/Signup.tsx | 137 +++++++++++++++++++++++++----------- 1 file changed, 95 insertions(+), 42 deletions(-) diff --git a/src/pages/Signup/Signup.tsx b/src/pages/Signup/Signup.tsx index d03a921..c2583de 100644 --- a/src/pages/Signup/Signup.tsx +++ b/src/pages/Signup/Signup.tsx @@ -1,7 +1,7 @@ import React, { useState } from "react"; import axios from "axios"; import { useNavigate ,Link } from "react-router-dom"; -import { User, Mail, Lock } from "lucide-react"; +import { User, Mail, Lock,Eye,EyeOff } from "lucide-react"; const backendUrl = import.meta.env.VITE_BACKEND_URL; interface SignUpFormData { username: string; @@ -16,47 +16,74 @@ const SignUp: React.FC = () => { password: "" }); const [message, setMessage] = useState(""); + const [errors, setErrors] = useState({ + username: "", + email: "", + password: "", +}); +const [showPassword, setShowPassword] = useState(false); const navigate = useNavigate(); const handleChange = (e: React.ChangeEvent) => { - const { name, value } = e.target; - setFormData({ ...formData, [name]: value }); - }; - - const handleSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - try { - const response = await axios.post(`${backendUrl}/api/auth/signup`, - formData // Include cookies for session - ); - setMessage(response.data.message); // Show success message from backend - - // Navigate to login page after successful signup - if (response.data.message === 'User created successfully') { - navigate("/login");} - - - // // Simulate API call (replace with your actual backend integration) - // try { - // // Mock successful signup - // setMessage("Account created successfully! Redirecting to login..."); - - // // In your actual implementation, integrate with your backend here: - // // const response = await fetch(`${backendUrl}/api/auth/signup`, { - // // method: 'POST', - // // headers: { 'Content-Type': 'application/json' }, - // // body: JSON.stringify(formData) - // // }); - - // setTimeout(() => { - // // Navigate to login page in your actual implementation - // console.log("Redirecting to login page..."); - // }, 2000); - - } catch (error) { - setMessage("Something went wrong. Please try again."); + const { name, value } = e.target; + + setFormData({ ...formData, [name]: value }); + + let errorMessage = ""; + + if (name === "username") { + if (!value.trim()) { + errorMessage = "Username is required"; + } else if (!/^[A-Za-z\s]+$/.test(value)) { + errorMessage = "Only letters are allowed"; + } + } + + if (name === "email") { + if (!value.trim()) { + errorMessage = "Email is required"; + } else if (!/\S+@\S+\.\S+/.test(value)) { + errorMessage = "Enter a valid email"; } - }; + } + + if (name === "password") { + if (!value.trim()) { + errorMessage = "Password is required"; + } else if ( + !/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*#?&]{8,}$/.test(value) + ) { + errorMessage = + "Password must be 8+ characters with letters and numbers"; + } + } + + setErrors((prev) => ({ + ...prev, + [name]: errorMessage, + })); +}; + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + + if (errors.username || errors.email || errors.password) { + return; + } + try { + const response = await axios.post( + `${backendUrl}/api/auth/signup`, + formData + ); + + setMessage(response.data.message); + + if (response.data.message === "User created successfully") { + navigate("/login"); + } + } catch (error) { + setMessage("Something went wrong. Please try again."); + } +}; return (
{/* Background decorative elements */} @@ -78,8 +105,8 @@ const navigate = useNavigate(); {/* Sign Up Form */}

Create Account

-
+
@@ -93,8 +120,14 @@ const navigate = useNavigate(); required className="w-full pl-12 pr-4 py-4 bg-white/10 border border-white/20 rounded-2xl text-white placeholder-purple-300 focus:outline-none focus:ring-2 focus:ring-purple-400 focus:border-transparent backdrop-blur-sm transition-all duration-300" /> +
+ {errors.username && ( +

+ {errors.username} +

+ )}
- +
@@ -108,14 +141,21 @@ const navigate = useNavigate(); required className="w-full pl-12 pr-4 py-4 bg-white/10 border border-white/20 rounded-2xl text-white placeholder-purple-300 focus:outline-none focus:ring-2 focus:ring-purple-400 focus:border-transparent backdrop-blur-sm transition-all duration-300" /> +
+ {errors.email && ( +

+ {errors.email} +

+ )}
- + +
+ +
+ {errors.password && ( +

+ {errors.password} +

+ )}
+
+
+ +
+ +
{errors.password && ( -

- {errors.password} -

+

{errors.password}

)}
+ {/* Submit Button */}
{message && ( -
+
{message}
)}
-

- Already have an account?{' '} +

+ Already have an account?{" "} - @@ -212,4 +241,4 @@ const navigate = useNavigate(); ); }; -export default SignUp; \ No newline at end of file +export default SignUp; From cdfd4adee0b2caba7c3865fdb15cc0bc4806aff7 Mon Sep 17 00:00:00 2001 From: DeepakGhenyar Date: Sun, 17 May 2026 22:21:45 +0530 Subject: [PATCH 3/3] fix: resolve conflicts, add ThemeContext, fix validation and accessibility --- src/pages/Signup/Signup.tsx | 159 +++++++++++------------------------- 1 file changed, 47 insertions(+), 112 deletions(-) diff --git a/src/pages/Signup/Signup.tsx b/src/pages/Signup/Signup.tsx index 8e83d09..41745db 100644 --- a/src/pages/Signup/Signup.tsx +++ b/src/pages/Signup/Signup.tsx @@ -1,7 +1,10 @@ -import React, { useState } from "react"; +import React, { useState, useContext } from "react"; import axios from "axios"; import { useNavigate, Link } from "react-router-dom"; +import { motion } from "framer-motion"; import { User, Mail, Lock, Eye, EyeOff } from "lucide-react"; +import { ThemeContext } from "../../context/ThemeContext"; +import type { ThemeContextType } from "../../context/ThemeContext"; const backendUrl = import.meta.env.VITE_BACKEND_URL; @@ -24,15 +27,15 @@ const SignUp: React.FC = () => { password: "", }); const [showPassword, setShowPassword] = useState(false); + const [isLoading, setIsLoading] = useState(false); const navigate = useNavigate(); + const themeContext = useContext(ThemeContext) as ThemeContextType; + const { mode } = themeContext; const handleChange = (e: React.ChangeEvent) => { const { name, value } = e.target; - setFormData({ ...formData, [name]: value }); - let errorMessage = ""; - if (name === "username") { if (!value.trim()) { errorMessage = "Username is required"; @@ -40,7 +43,6 @@ const SignUp: React.FC = () => { errorMessage = "Only letters are allowed"; } } - if (name === "email") { if (!value.trim()) { errorMessage = "Email is required"; @@ -48,194 +50,127 @@ const SignUp: React.FC = () => { errorMessage = "Enter a valid email"; } } - if (name === "password") { if (!value.trim()) { errorMessage = "Password is required"; - } else if ( - !/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*#?&]{8,}$/.test(value) - ) { + } else if (!/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*#?&]{8,}$/.test(value)) { errorMessage = "Password must be 8+ characters with letters and numbers"; } } - - setErrors((prev) => ({ - ...prev, - [name]: errorMessage, - })); + setErrors((prev) => ({ ...prev, [name]: errorMessage })); }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); - const usernameError = !formData.username.trim() ? "Username is required" : !/^[A-Za-z\s]+$/.test(formData.username) ? "Only letters are allowed" : ""; - const emailError = !formData.email.trim() ? "Email is required" : !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.email.trim()) ? "Enter a valid email" : ""; - const passwordError = !formData.password.trim() ? "Password is required" - : !/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*#?&]{8,}$/.test( - formData.password - ) + : !/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*#?&]{8,}$/.test(formData.password) ? "Password must be 8+ characters with letters and numbers" : ""; - if (usernameError || emailError || passwordError) { - setErrors({ - username: usernameError, - email: emailError, - password: passwordError, - }); + setErrors({ username: usernameError, email: emailError, password: passwordError }); return; } - + setIsLoading(true); try { - const response = await axios.post( - `${backendUrl}/api/auth/signup`, - formData - ); - + const response = await axios.post(`${backendUrl}/api/auth/signup`, formData); setMessage(response.data.message); - if (response.data.message === "User created successfully") { navigate("/login"); } - } catch (error) { - setMessage("Something went wrong. Please try again."); + } catch (error: any) { + setMessage(error.response?.data?.message || "Something went wrong. Please try again."); + } finally { + setIsLoading(false); } }; return ( -

-
- {/* Logo and Title */} -
+
+
+
Logo
-

GitHubTracker

-

Join your GitHub journey

-
+

GitHubTracker

+

Join your GitHub journey

+ - {/* Sign Up Form */} -
-

- Create Account -

-
+ +

Create Account

- {/* Username */} +
-
- {errors.username && ( -

{errors.username}

- )} + {errors.username &&

{errors.username}

}
- {/* Email */}
-
- {errors.email && ( -

{errors.email}

- )} + {errors.email &&

{errors.email}

}
- {/* Password */}
- -
- {errors.password && ( -

{errors.password}

- )} + {errors.password &&

{errors.password}

}
- {/* Submit Button */} - -
+ {message && ( -
+
{message}
)}
-

+

Already have an account?{" "} - - + + Sign in here

-
+
);