feat(auth): enhance registration form validation and autocomplete accessibility
All checks were successful
Deploy Flowstate to VPS / deploy (push) Successful in 1m31s

This commit is contained in:
Chneemann 2026-10-11 19:33:10 +02:00
parent 5b749bb0ee
commit c1e2dd4407
No known key found for this signature in database

View file

@ -1,6 +1,6 @@
/**
* @file app/(auth)/register/page.tsx
* @description Client component providing a user registration interface utilizing the auth service.
* @description Client component providing a user registration interface with client-side validation, autocomplete, and ActionButton integration.
*/
"use client";
@ -14,8 +14,8 @@ import { Loader2, UserPlus } from "lucide-react";
import { JSX } from "react/jsx-runtime";
/**
* Renders the registration page featuring a sign-up form, error feedback,
* and routing logic to the summary view upon successful account creation.
* Renders the registration page featuring a sign-up form, client-side validation,
* error feedback, and routing logic to the summary view upon successful account creation.
*
* @returns {JSX.Element} The rendered registration page component.
*/
@ -24,6 +24,15 @@ export default function RegisterPage(): JSX.Element {
const [loading, setLoading] = useState(false);
const router = useRouter();
/**
* Clears active error state when user modifies input fields.
*/
const handleInputChange = () => {
if (error) {
setError(null);
}
};
/**
* Handles user registration form submission, validates form data via auth service,
* and navigates to summary page on successful registration.
@ -38,11 +47,18 @@ export default function RegisterPage(): JSX.Element {
): Promise<void> {
event.preventDefault();
setError(null);
setLoading(true);
const formData = new FormData(event.currentTarget);
const payload = Object.fromEntries(formData.entries());
// Client-side password matching check
if (payload.password !== payload.confirmPassword) {
setError("Passwords do not match.");
return;
}
setLoading(true);
const result = await registerUser(payload);
if (result.error) {
@ -93,7 +109,11 @@ export default function RegisterPage(): JSX.Element {
</div>
)}
<form onSubmit={handleSubmit} className="space-y-4">
<form
onSubmit={handleSubmit}
onChange={handleInputChange}
className="space-y-4"
>
<div className="grid grid-cols-2 gap-2.5">
<div className="space-y-1">
<label
@ -108,6 +128,7 @@ export default function RegisterPage(): JSX.Element {
type="text"
placeholder="John"
maxLength={50}
autoComplete="given-name"
required
className="w-full px-3.5 py-2.5 text-sm rounded-lg border border-border bg-background/50 text-foreground placeholder:text-foreground-muted/50 focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-colors"
/>
@ -126,6 +147,7 @@ export default function RegisterPage(): JSX.Element {
type="text"
placeholder="Doe"
maxLength={50}
autoComplete="family-name"
required
className="w-full px-3.5 py-2.5 text-sm rounded-lg border border-border bg-background/50 text-foreground placeholder:text-foreground-muted/50 focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-colors"
/>
@ -145,6 +167,7 @@ export default function RegisterPage(): JSX.Element {
type="email"
placeholder="name@example.com"
maxLength={255}
autoComplete="email"
required
className="w-full px-3.5 py-2.5 text-sm rounded-lg border border-border bg-background/50 text-foreground placeholder:text-foreground-muted/50 focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-colors"
/>
@ -163,6 +186,7 @@ export default function RegisterPage(): JSX.Element {
type="password"
placeholder="••••••••••••"
maxLength={72}
autoComplete="new-password"
required
className="w-full px-3.5 py-2.5 text-sm rounded-lg border border-border bg-background/50 text-foreground placeholder:text-foreground-muted/50 focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-colors"
/>
@ -181,6 +205,7 @@ export default function RegisterPage(): JSX.Element {
type="password"
placeholder="••••••••••••"
maxLength={72}
autoComplete="new-password"
required
className="w-full px-3.5 py-2.5 text-sm rounded-lg border border-border bg-background/50 text-foreground placeholder:text-foreground-muted/50 focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-colors"
/>