File "use-form-validation.js"
Full Path: /home/fresvfqn/waterdamagerestorationandrepairsmithtown.com/wp-content/plugins/surerank/src/global/hooks/use-form-validation.js
File size: 3.31 KB
MIME-type: text/x-java
Charset: utf-8
import { z } from 'zod';
import { useState, useCallback } from '@wordpress/element';
/**
* Custom hook for form validation using Zod
* @param {Object} formState - Current form state
* @param {Array} inputFields - Array of input field configurations
* @return {Object} - Returns validation function and error states
*/
const useFormValidation = ( formState, inputFields ) => {
const [ errors, setErrors ] = useState( {} );
// Create dynamic schema based on input fields
const createValidationSchema = useCallback( () => {
const schema = {};
inputFields.forEach( ( field ) => {
let fieldSchema;
// Add validation based on field type
switch ( field.type ) {
case 'text':
case 'textarea':
fieldSchema = z.string( {
required_error: `${ field.label } is required`,
} );
break;
case 'email':
fieldSchema = z
.string( {
required_error: `${ field.label } is required`,
} )
.email( 'Please enter a valid email address' );
break;
case 'number':
fieldSchema = z.number( {
invalid_type_error: `${ field.label } must be a number`,
required_error: `${ field.label } is required`,
} );
break;
case 'url':
fieldSchema = z
.string( {
required_error: `${ field.label } is required`,
} )
.url( 'Please enter a valid URL' );
break;
case 'file':
fieldSchema = z.instanceof( File );
break;
case 'checkbox':
fieldSchema = z.boolean();
break;
default:
fieldSchema = z.string( {
required_error: `${ field.label } is required`,
} );
break;
}
// Add required validation
if ( field.required ) {
if ( field.type === 'checkbox' ) {
fieldSchema = fieldSchema.refine(
( value ) => value === true,
'This field is required'
);
} else {
fieldSchema = fieldSchema.min(
1,
`${ field.label } is required`
);
}
}
schema[ field.name ] = field.required
? fieldSchema
: fieldSchema.optional();
} );
return z.object( schema );
}, [ inputFields ] );
const validate = useCallback( () => {
const schema = createValidationSchema();
try {
schema.parse( formState );
setErrors( {} );
return true;
} catch ( validationErrors ) {
const formattedErrors = {};
validationErrors.errors.forEach( ( error ) => {
const [ fieldName ] = error.path;
formattedErrors[ fieldName ] = error.message;
} );
setErrors( formattedErrors );
// Focus on the first field with error
const firstErrorField = validationErrors.errors[ 0 ]?.path[ 0 ];
if ( firstErrorField ) {
const element = document.querySelector(
`[name="${ firstErrorField }"]`
);
if ( element ) {
element.focus();
}
}
return false;
}
}, [ formState, createValidationSchema ] );
/**
* Clear error for a specific field
* @param {string} fieldName - Name of the field to clear error for
*
* @return {void}
*/
const clearFieldError = ( fieldName ) => {
setErrors( ( prevErrors ) => {
if ( ! prevErrors[ fieldName ] ) {
return prevErrors;
}
const newErrors = { ...prevErrors };
newErrors[ fieldName ] = '';
return newErrors;
} );
};
return {
errors,
validate,
clearFieldError,
isValid: Object.keys( errors ).length === 0,
};
};
export default useFormValidation;