import React, { useState, useEffect } from 'react';
import { TextField, FormHelperText, Box, Chip } from '@mui/material';
import { CheckCircle, Error as ErrorIcon, Warning } from '@mui/icons-material';
import { useTranslation } from 'react-i18next';
import {
validateUsername,
validateEmail,
validateUrl,
validateTextField,
validateInteger
} from '../utils/inputValidator';
/**
* ValidatedTextField Component
* Provides client-side validation with visual feedback
*/
const ValidatedTextField = ({
type = 'text',
value,
onChange,
validationType,
minLength,
maxLength,
min,
max,
required = false,
showValidation = true,
relatedValues = {},
...textFieldProps
}) => {
const { t } = useTranslation();
const [errors, setErrors] = useState([]);
const [touched, setTouched] = useState(false);
const [isValid, setIsValid] = useState(null);
useEffect(() => {
if (!touched || !value) {
setErrors([]);
setIsValid(null);
return;
}
let validationResult;
switch (validationType) {
case 'username':
validationResult = validateUsername(value);
break;
case 'email':
validationResult = validateEmail(value);
break;
case 'url':
validationResult = validateUrl(value);
break;
case 'integer':
validationResult = validateInteger(value, min, max);
break;
case 'text':
default:
validationResult = validateTextField(value, minLength, maxLength, required);
break;
}
setErrors(validationResult.errors);
setIsValid(validationResult.valid);
// If valid and sanitized value is different, update parent
if (validationResult.valid && validationResult.sanitized !== value) {
onChange({ target: { value: validationResult.sanitized } });
}
}, [value, touched, validationType, minLength, maxLength, min, max, required]);
const handleBlur = (e) => {
setTouched(true);
if (textFieldProps.onBlur) {
textFieldProps.onBlur(e);
}
};
const handleChange = (e) => {
onChange(e);
};
const getValidationColor = () => {
if (!showValidation || !touched || !value) return undefined;
return isValid ? 'success' : 'error';
};
const getEndAdornment = () => {
if (!showValidation || !touched || !value) return textFieldProps.InputProps?.endAdornment;
const adornment = (
{isValid ? (
) : (
)}
{textFieldProps.InputProps?.endAdornment}
);
return adornment;
};
return (
0}
color={getValidationColor()}
InputProps={{
...textFieldProps.InputProps,
endAdornment: getEndAdornment()
}}
/>
{showValidation && touched && errors.length > 0 && (
{errors.map((error, index) => (
{error}
))}
)}
{showValidation && touched && isValid && (
{t('security.inputSanitized')}
)}
);
};
export default ValidatedTextField;