diff --git a/src/pages/Signup/Signup.tsx b/src/pages/Signup/Signup.tsx index b55df05..71699f8 100644 --- a/src/pages/Signup/Signup.tsx +++ b/src/pages/Signup/Signup.tsx @@ -21,9 +21,13 @@ const SignUp: React.FC = () => { password: "", }); const [message, setMessage] = useState(""); - const [isLoading, setIsLoading] = useState(false); - const [showPassword, setShowPassword] = useState(false); - + const [errors, setErrors] = useState({ + username: "", + email: "", + password: "", + }); + const [showPassword, setShowPassword] = useState(false); + const [isLoading, setIsLoading] = useState(false); const navigate = useNavigate(); const themeContext = useContext(ThemeContext) as ThemeContextType; const { mode } = themeContext; @@ -31,16 +35,56 @@ const SignUp: React.FC = () => { 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"; + } 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.trim())) { + 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(); + 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) + ? "Password must be 8+ characters with letters and numbers" + : ""; + if (usernameError || emailError || passwordError) { + setErrors({ username: usernameError, email: emailError, password: passwordError }); + return; + } setIsLoading(true); - try { const response = await axios.post(`${backendUrl}/api/auth/signup`, formData); setMessage(response.data.message); - if (response.data.message === "User created successfully") { navigate("/login"); } @@ -52,184 +96,76 @@ const SignUp: React.FC = () => { }; return ( -
-
-
-
-
-
-
- +
- +
Logo
-

- GitHubTracker -

-

- Join your GitHub journey -

+

GitHubTracker

+

Join your GitHub journey

- -

- Create Account -

+ +

Create Account

-
-
- +
+
+ +
+
- + {errors.username &&

{errors.username}

}
-
-
- +
+
+ +
+
- + {errors.email &&

{errors.email}

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

{errors.password}

}
- {message && ( -
+
{message}
)} -
-

- Already have an account? - +

+

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

@@ -246,4 +182,4 @@ const SignUp: React.FC = () => { ); }; -export default SignUp; \ No newline at end of file +export default SignUp;