Enhance signup form validation and user feedback handling#265
Enhance signup form validation and user feedback handling#265DeepakGhenyar wants to merge 1 commit into
Conversation
✅ Deploy Preview for github-spy ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
📝 WalkthroughWalkthroughThe signup form now validates username, email, and password fields on input with inline error messages. Password visibility is toggled via eye/eye-off icons. Form submission is blocked if validation errors exist; otherwise, a POST to the backend signup endpoint is attempted with proper navigation or error feedback. ChangesForm validation and password visibility
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🎉 Thank you @DeepakGhenyar for your contribution. Please make sure your PR follows https://github.com/GitMetricsLab/github_tracker/blob/main/CONTRIBUTING.md#-pull-request-guidelines
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/pages/Signup/Signup.tsx`:
- Around line 41-45: The email validation in the Signup component uses an
unanchored regex against untrimmed input which permits malformed emails; update
the logic in the block where name === "email" to first use const trimmed =
value.trim() and validate trimmed (not raw value), and replace the regex
/\S+@\S+\.\S+/ with an anchored, stricter pattern (e.g. start/end anchors and
better local/domain checks) when setting errorMessage so malformed values are
rejected; ensure errorMessage is set based on trimmed input and the
function/handler (the code that references name, value, and errorMessage) uses
the trimmed, validated value thereafter.
- Around line 166-172: The password visibility toggle button is icon-only and
lacks an accessible name; update the button (the element using setShowPassword
and showPassword that renders Eye/EyeOff) to provide an accessible label and
state, e.g., add an aria-label that changes with showPassword (e.g., "Show
password" vs "Hide password") and consider adding aria-pressed or title for
additional context so screen readers announce its purpose and current state.
- Around line 65-70: The submit handler handleSubmit currently only checks the
existing errors object, so untouched invalid fields let bad payloads through;
update handleSubmit to re-run validation against current formData on submit
(e.g., call your validate/validateAll function or validateField for each field
with formData.username, formData.email, formData.password), update/set the
errors state with any returned issues, and abort submission if any validation
errors are present before posting the payload; ensure this revalidation handles
async validators by awaiting the validator if needed and then returning early
when errors exist.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d7c43668-cf1c-4f48-9185-77390d004381
📒 Files selected for processing (1)
src/pages/Signup/Signup.tsx
| if (name === "email") { | ||
| if (!value.trim()) { | ||
| errorMessage = "Email is required"; | ||
| } else if (!/\S+@\S+\.\S+/.test(value)) { | ||
| errorMessage = "Enter a valid email"; |
There was a problem hiding this comment.
Tighten email validation to avoid false positives.
At Line 44, /\S+@\S+\.\S+/ is unanchored and used against untrimmed input, so malformed values can still pass validation.
Proposed fix
if (name === "email") {
- if (!value.trim()) {
+ const email = value.trim();
+ if (!email) {
errorMessage = "Email is required";
- } else if (!/\S+@\S+\.\S+/.test(value)) {
+ } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
errorMessage = "Enter a valid email";
}
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (name === "email") { | |
| if (!value.trim()) { | |
| errorMessage = "Email is required"; | |
| } else if (!/\S+@\S+\.\S+/.test(value)) { | |
| errorMessage = "Enter a valid email"; | |
| if (name === "email") { | |
| const email = value.trim(); | |
| if (!email) { | |
| errorMessage = "Email is required"; | |
| } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) { | |
| errorMessage = "Enter a valid email"; | |
| } | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/pages/Signup/Signup.tsx` around lines 41 - 45, The email validation in
the Signup component uses an unanchored regex against untrimmed input which
permits malformed emails; update the logic in the block where name === "email"
to first use const trimmed = value.trim() and validate trimmed (not raw value),
and replace the regex /\S+@\S+\.\S+/ with an anchored, stricter pattern (e.g.
start/end anchors and better local/domain checks) when setting errorMessage so
malformed values are rejected; ensure errorMessage is set based on trimmed input
and the function/handler (the code that references name, value, and
errorMessage) uses the trimmed, validated value thereafter.
| const handleSubmit = async (e: React.FormEvent) => { | ||
| e.preventDefault(); | ||
|
|
||
| if (errors.username || errors.email || errors.password) { | ||
| return; | ||
| } |
There was a problem hiding this comment.
Revalidate from formData on submit; current gate misses untouched invalid fields.
At Line 68, submission is blocked only when existing errors entries are set. If a user clicks submit without typing, errors remains empty and invalid payload can still be posted.
Proposed fix
+const validateField = (name: keyof SignUpFormData, rawValue: string): string => {
+ const value = rawValue.trim();
+ if (name === "username") {
+ if (!value) return "Username is required";
+ if (!/^[A-Za-z\s]+$/.test(value)) return "Only letters are allowed";
+ }
+ if (name === "email") {
+ if (!value) return "Email is required";
+ if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) return "Enter a valid email";
+ }
+ if (name === "password") {
+ if (!value) return "Password is required";
+ if (!/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*#?&]{8,}$/.test(rawValue)) {
+ return "Password must be 8+ characters with letters and numbers";
+ }
+ }
+ return "";
+};
+
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
-
- if (errors.username || errors.email || errors.password) {
+ const nextErrors = {
+ username: validateField("username", formData.username),
+ email: validateField("email", formData.email),
+ password: validateField("password", formData.password),
+ };
+ setErrors(nextErrors);
+ if (Object.values(nextErrors).some(Boolean)) {
return;
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const handleSubmit = async (e: React.FormEvent) => { | |
| e.preventDefault(); | |
| if (errors.username || errors.email || errors.password) { | |
| return; | |
| } | |
| const validateField = (name: keyof SignUpFormData, rawValue: string): string => { | |
| const value = rawValue.trim(); | |
| if (name === "username") { | |
| if (!value) return "Username is required"; | |
| if (!/^[A-Za-z\s]+$/.test(value)) return "Only letters are allowed"; | |
| } | |
| if (name === "email") { | |
| if (!value) return "Email is required"; | |
| if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) return "Enter a valid email"; | |
| } | |
| if (name === "password") { | |
| if (!value) return "Password is required"; | |
| if (!/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*#?&]{8,}$/.test(rawValue)) { | |
| return "Password must be 8+ characters with letters and numbers"; | |
| } | |
| } | |
| return ""; | |
| }; | |
| const handleSubmit = async (e: React.FormEvent) => { | |
| e.preventDefault(); | |
| const nextErrors = { | |
| username: validateField("username", formData.username), | |
| email: validateField("email", formData.email), | |
| password: validateField("password", formData.password), | |
| }; | |
| setErrors(nextErrors); | |
| if (Object.values(nextErrors).some(Boolean)) { | |
| return; | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/pages/Signup/Signup.tsx` around lines 65 - 70, The submit handler
handleSubmit currently only checks the existing errors object, so untouched
invalid fields let bad payloads through; update handleSubmit to re-run
validation against current formData on submit (e.g., call your
validate/validateAll function or validateField for each field with
formData.username, formData.email, formData.password), update/set the errors
state with any returned issues, and abort submission if any validation errors
are present before posting the payload; ensure this revalidation handles async
validators by awaiting the validator if needed and then returning early when
errors exist.
| <button | ||
| type="button" | ||
| onClick={() => setShowPassword(!showPassword)} | ||
| className="absolute inset-y-0 right-0 pr-4 flex items-center text-purple-300" | ||
| > | ||
| {showPassword ? <EyeOff size={20} /> : <Eye size={20} />} | ||
| </button> |
There was a problem hiding this comment.
Add accessible label/state to password visibility toggle.
The icon-only button at Line 166 has no accessible name, which makes the control unclear for screen-reader users.
Proposed fix
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
+ aria-label={showPassword ? "Hide password" : "Show password"}
+ aria-pressed={showPassword}
className="absolute inset-y-0 right-0 pr-4 flex items-center text-purple-300"
>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <button | |
| type="button" | |
| onClick={() => setShowPassword(!showPassword)} | |
| className="absolute inset-y-0 right-0 pr-4 flex items-center text-purple-300" | |
| > | |
| {showPassword ? <EyeOff size={20} /> : <Eye size={20} />} | |
| </button> | |
| <button | |
| type="button" | |
| onClick={() => setShowPassword(!showPassword)} | |
| aria-label={showPassword ? "Hide password" : "Show password"} | |
| aria-pressed={showPassword} | |
| className="absolute inset-y-0 right-0 pr-4 flex items-center text-purple-300" | |
| > | |
| {showPassword ? <EyeOff size={20} /> : <Eye size={20} />} | |
| </button> |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/pages/Signup/Signup.tsx` around lines 166 - 172, The password visibility
toggle button is icon-only and lacks an accessible name; update the button (the
element using setShowPassword and showPassword that renders Eye/EyeOff) to
provide an accessible label and state, e.g., add an aria-label that changes with
showPassword (e.g., "Show password" vs "Hide password") and consider adding
aria-pressed or title for additional context so screen readers announce its
purpose and current state.
Related Issue
Description
Enhanced the signup form validation and improved the overall user experience by adding real-time validation and better feedback handling.
Changes Made
How Has This Been Tested?
Screenshots (if applicable)
Type of Change
Summary by CodeRabbit
New Features