/** * @ai-summary Signup form component with password validation and show/hide toggle */ import React, { useState } from 'react'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { z } from 'zod'; import { Button } from '../../../shared-minimal/components/Button'; import { SignupRequest } from '../types/auth.types'; const signupSchema = z .object({ email: z.string().email('Please enter a valid email address'), password: z .string() .min(8, 'Password must be at least 8 characters') .regex(/[A-Z]/, 'Password must contain at least one uppercase letter') .regex(/[0-9]/, 'Password must contain at least one number'), confirmPassword: z.string(), termsAccepted: z.literal(true, { errorMap: () => ({ message: 'You must agree to the Terms & Conditions to create an account' }), }), }) .refine((data) => data.password === data.confirmPassword, { message: 'Passwords do not match', path: ['confirmPassword'], }); interface SignupFormProps { onSubmit: (data: SignupRequest) => void; loading?: boolean; } export const SignupForm: React.FC = ({ onSubmit, loading }) => { const [showPassword, setShowPassword] = useState(false); const [showConfirmPassword, setShowConfirmPassword] = useState(false); const { register, handleSubmit, formState: { errors }, } = useForm({ resolver: zodResolver(signupSchema), }); const handleFormSubmit = (data: SignupRequest & { confirmPassword: string }) => { const { email, password, termsAccepted } = data; onSubmit({ email, password, termsAccepted }); }; return (
{errors.email && (

{errors.email.message}

)}
{errors.password && (

{errors.password.message}

)}

Must be at least 8 characters with one uppercase letter and one number

{errors.confirmPassword && (

{errors.confirmPassword.message}

)}
{errors.termsAccepted && (

{errors.termsAccepted.message}

)}
); };