import PropTypes from 'prop-types' import React, { useEffect, useReducer, useRef, useState } from 'react' import { SFVColor } from '../../../../assets/colors' import { IconNoShow, IconShowEye } from '../../../../assets/icons' import { isCC, isEmail, isPassword, onlyLetters, rangeLength, valNit, validatePhoneNumber } from '../../../../utils' import { simpleVerifyEmail } from './helpers' import { BoxInput, InputV, LabelInput, List, Listbox, ShowPass, TextAreaInput, Tooltip } from './styled' export const InputHooks = ({ autoComplete = 'off', border = '', Cc, checked = false, autoFocus, dataForm = {}, disabled = false, display = '', email = false, error = false, labelTop = '', fontSize = '14px', height, labelColor, letters, margin = '0', maxWidth = '', minWidth = '', name = '', nit = false, numeric = false, onChange = (e) => { return e }, padding = '', paddingInput = '', pass, passConfirm, placeholder = '', radius = '', range, reference, required, title = '', messageError = '', type = 'text', typeTextarea = false, value = '', width = '100%', onFocus = () => { return }, onInvalid = () => { return }, setDataValue = () => { return }, onBlur = () => { return }, ...rest }) => { // STATE const [errors, setError] = useState(error) const [isPasswordShown, setIsPasswordShown] = useState(false) const [message, setMessage] = useState(messageError || 'El campo no debe estar vacío') const [showSuggestions, setShowSuggestions] = useState(false) const [suggestionList, setSuggestionList] = useState([]) const errorFunc = (e, v, m) => { setError(v) v && setMessage(m) onChange(e, v) } useEffect(() => { setError(error) }, [error]) const topLevelEmailDomainList = [ 'gmail.com', 'outlook.com', 'hotmail.com', 'live.com', 'yahoo.com', 'icloud.com' ] const otherLevelEmailDomainList = [ 'gmail.com', 'gmail.co.uk', 'outlook.com', 'outlook.co.uk', 'yahoo.com', 'yahoo.ca', 'hotmail.com', 'live.com', 'icloud.com' ] const provideEmailSuggestion = (email) => { const emailParts = email.split('@') const emailUsername = emailParts[0] const emailDomain = emailParts[1] let suggestionList = [] if (emailDomain !== undefined) { if (emailDomain === '') { suggestionList = topLevelEmailDomainList?.map( domain => { return emailUsername + '@' + domain } ) } else { suggestionList = otherLevelEmailDomainList.filter(domain => { return domain.startsWith(emailDomain) }).map(domain => { return emailUsername + '@' + domain }) } } return suggestionList } const autoCompleteEmail = (email) => { setShowSuggestions(false) // errorMessage: '', if (email) { const suggestionList = provideEmailSuggestion(email) if (suggestionList.length > 1) { setShowSuggestions(true) setSuggestionList(suggestionList) } else { const errorMessage = simpleVerifyEmail(email, setMessage) // eslint-disable-next-line no-empty if (errorMessage) { // mysql.services.clever-cloud.co } } } } // const arrowUpPressed = useKeyPress('ArrowUp') // const backSpace = useKeyPress('backSpace') // const arrowDownPressed = useKeyPress('ArrowDown') const arrowUpPressed = '' const backSpace = '' const arrowDownPressed = '' const initialState = { selectedIndex: 0 } function reducer(state, action) { switch (action.type) { case 'arrowUp': return { selectedIndex: state.selectedIndex !== 0 ? state.selectedIndex - 1 : topLevelEmailDomainList.length - 1 } case 'arrowDown': return { selectedIndex: state.selectedIndex !== topLevelEmailDomainList.length - 1 ? state.selectedIndex + 1 : 0 } case 'Backspace': return { selectedIndex: 0 } case 'select': return { selectedIndex: action.payload } default: return null } } const [state, dispatch] = useReducer(reducer, initialState) useEffect(() => { if (arrowUpPressed) { dispatch({ type: 'arrowUp' }) } if (arrowDownPressed) { dispatch({ type: 'arrowDown' }) } if (backSpace) { dispatch({ type: 'Backspace' }) } }, [arrowUpPressed, arrowDownPressed, backSpace]) const refInput = useRef({ focus: () => { return } }) const handleSuggestionOnClick = () => { // setEmail(suggestion) setShowSuggestions(!showSuggestions) // setValue(suggestion) setTimeout(() => { refInput.current.focus() }) } /** * @description Which function to validate the text fields by the onChange method * @version 0.0.1 * @param {object} e change method event * @return {boolean} returns true or false if validation is successful or unsuccessful * */ // eslint-disable-next-line consistent-return const validations = e => { autoCompleteEmail(e.target.value) // Valida que el campo no sea nulo if (required) { if (e.target.value.length == 0) return errorFunc(e, true, 'El campo no debe estar vacío') errorFunc(e, false, '') } // Valida que el campo sea tipo numérico if (numeric) { if (isNaN(parseFloat(e.target.value))) return errorFunc(e, true, 'El campo debe ser numérico') errorFunc(e, false, '') } // Valida que el campo sea solo letras if (letters) { if (onlyLetters(e.target.value)) return errorFunc(e, true, 'El campo debe contener solo letras') errorFunc(e, false, '') } // Valida que el campo esté en el rango correcto if (range) { if (rangeLength(e.target.value, range.min, range.max)) return errorFunc(e, true, `El rango de caracteres es de ${range.min} a ${range.max}`) errorFunc(e, false, '') } // Valida si el campo tiene un formato de email correcto if (email) { if (isEmail(e.target.value)) return errorFunc(e, true, 'El formato de email no es válido') errorFunc(e, false, '') } if (pass) { if (isPassword(e.target.value)) { return errorFunc(e, true, 'La contraseña debe tener al entre 8 y 16 caracteres, al menos un dígito, al menos una minúscula y al menos una mayúscula. Puede tener otros símbolos.') } errorFunc(e, false, '') } if (nit) { if (valNit(e.target.value)) { return errorFunc(e, true, 'El nit no es correcto') } errorFunc(e, false, '') } if (Cc) { if (isCC(e.target.value)) { return errorFunc(e, true, 'El numero de documento no es correcto') } errorFunc(e, false, '') } if (type == 'tel') { if (validatePhoneNumber(e.target.value)) { return errorFunc(e, true, 'El numero de teléfono no es correcto') } errorFunc(e, false, '') } // Valida que las contraseñas coincidan if (passConfirm?.validate) { if (validatePhoneNumber(e.target.value, passConfirm?.passValue)) { return errorFunc(e, true, 'Las contraseñas no coinciden.') } errorFunc(e, false, '') } if (e) { return errorFunc(e, false, '') } } const isAutoComplete = !autoComplete ? 'off' : autoComplete const isEmailValue = email ? 'off' : isAutoComplete const handleBlur = () => { } const handleFocus = () => { } const asType = numeric ? 'number' : type return ( {pass && { return setIsPasswordShown(!isPasswordShown) }} type='button'> {isPasswordShown ? : } } {!typeTextarea ?
{ return validations(e) }} onFocus={handleFocus} onInvalid={onInvalid} paddingInput={paddingInput} placeholder={placeholder} radius={radius} ref={email ? refInput : reference} size={fontSize} type={isPasswordShown ? 'text' : asType} value={value} /> {(!!showSuggestions) && (
{suggestionList.map((suggestion, index) => { return ( { dispatch({ type: 'select', payload: index }) handleSuggestionOnClick() setDataValue({ ...dataForm, [name]: suggestion }) }} onKeyPress={(e) => { if (e.key === 'Enter') { e.preventDefault() dispatch({ type: 'select', payload: index }) e.target.blur() } }} style={{ cursor: 'pointer', backgroundColor: index === state.selectedIndex ? `${SFVColor}2e` : 'transparent' }} tabIndex={0} > {suggestion} ) })}
)}
: } { { return refInput.current.focus() }} type={type} value={value} > {title} } {errors && {message}}
) } InputHooks.propTypes = { Cc: PropTypes.any, autoComplete: PropTypes.string, autoFocus: PropTypes.any, border: PropTypes.string, checked: PropTypes.bool, dataForm: PropTypes.object, disabled: PropTypes.bool, display: PropTypes.string, email: PropTypes.shape({ split: PropTypes.func }), error: PropTypes.string, fontSize: PropTypes.string, height: PropTypes.any, labelColor: PropTypes.any, labelTop: PropTypes.any, letters: PropTypes.any, margin: PropTypes.string, maxWidth: PropTypes.string, minWidth: PropTypes.string, name: PropTypes.string, nit: PropTypes.bool, numeric: PropTypes.bool, onBlur: PropTypes.func, onChange: PropTypes.func, onFocus: PropTypes.func, messageError: PropTypes.string, onInvalid: PropTypes.func, padding: PropTypes.string, paddingInput: PropTypes.string, pass: PropTypes.any, passConfirm: PropTypes.shape({ passValue: PropTypes.any, validate: PropTypes.any }), placeholder: PropTypes.string, radius: PropTypes.string, range: PropTypes.shape({ max: PropTypes.any, min: PropTypes.any }), reference: PropTypes.any, required: PropTypes.any, setDataValue: PropTypes.func, title: PropTypes.string, type: PropTypes.string, typeTextarea: PropTypes.bool, value: PropTypes.string, width: PropTypes.string }