Im new to programming and having a very simple difficulty i believe. Im not managing how to validate or style my '-masked input component-' i spent a few hours searching and haven't found anything that can help-me. Im using bootstrap, yup and some other libs to help me. I hope you can help me! My code is like this:
main component:
import { useForm } from 'react-hook-form'
import { yupResolver } from '@hookform/resolvers/yup'
import { Link, useNavigate } from 'react-router-dom'
import { parse, isDate } from "date-fns";
import { useState } from 'react'
import * as yup from 'yup'
// Validador dos campos
function parseDateString(value: string, originalValue: string) {
const parsedDate = isDate(originalValue) ? originalValue : parse(originalValue, "dd/MM/yyyy", new Date());
return parsedDate;
}
const schema = yup.object().shape({
email: yup.string().email().required(),
password: yup.string().min(6, 'A senha deve ter no mínimo 6 caracteres').max(20, 'A senha deve ter no máximo 20 caracteres').required(),
cpf: yup.number().typeError('Apenas números serão aceitos!').test('len', 'O CPF deve ter 11 números!', val => val?.toString().length == 11),
date: yup.date().max(new Date()).required("Campo obrigatório").transform(parseDateString),
termos: yup.boolean().oneOf([true])
})
interface FormDataFis {
email: string
password: string
cpf: number
date: string
termos: boolean
exibirCliente?: boolean
}
export default function SingUpFisica() {
const [cpf, setCpf] = useState()
const { register, handleSubmit, formState: { errors } } = useForm<FormDataFis>({
resolver: yupResolver(schema),
mode: 'onChange'
});
const navigate = useNavigate()
// Verificador dos dados passados pelo usuário, garantindo que estejam no formato correto e que estejam alocados corretamente
const formSubmitHandler = (data: FormDataFis) => {
if (!errors.cpf || !errors.email || errors.password || !errors.termos) {
console.log(data)
navigate('/tokenizr-main-page')
}
}
return (
<div>
<div className="min-h-screen flex flex-col justify-center">
<div className="max-w-md w-full mx-auto">
<div className="text-center font-medium text-xl"> CADASTRO
<div className="text-3xl font-bold text-gray-900 mt-2 text-center">TOKENIZR</div>
</div>
</div>
<div className="max-w-md w-full mx-auto mt-4 bg-white p-8 border border-gray-300">
<form onSubmit={handleSubmit(formSubmitHandler)} action="" className="space-y-6">
<div>
<label htmlFor="" style={{ color: errors.email ? "red" : 'black' }} className="text-sm-font-bold text-gray-600 block">Email</label>
<input {...register('email', {})} style={{ color: errors.email ? 'red' : 'black' }} type="text" className="w-full p-2 border border-gray-300 rounded mt-1" />
</div>
{errors.email && "Campo inválido!"}
<div>
<label htmlFor="" style={{ color: errors.password ? "red" : 'black' }} className="text-sm-font-bold text-gray-600 block">Senha (6 a 20 dígitos)</label>
<input {...register('password')} style={{ color: errors.password ? 'red' : 'black' }} type="password" className="w-full p-2 border border-gray-300 rounded mt-1" />
{errors.password && errors.password.message && <span>{errors.password.message}</span>}
</div>
<div>
<label htmlFor="" style={{ color: errors.cpf ? 'red' : 'black' }} className="text-sm-font-bold text-gray-600 block">CPF</label>
<input {...register('cpf')} style={{ color: errors.cpf ? 'red' : 'black' }} type="text" className="w-full p-2 border border-gray-300 rounded mt-1" />
</div>
<div className='mt-2'>
{errors.cpf && errors.cpf.message && <span>{errors.cpf.message}</span>}
</div>
<div>
<label htmlFor="" style={{ color: errors.date ? 'red' : 'black' }} className="text-sm-font-bold text-gray-600 block">Data de nascimento (MM/DD/YYYY)</label>
<input {...register('date')} type="text" style={{ color: errors.date ? 'red' : 'black' }} className="w-full p-2 border border-gray-300 rounded mt-1" />
</div>
{errors.date && "Campo inválido!"}
<div>
<div className="flex items-center justify-between">
<div className="flex items-center">
<input {...register('termos', { required: true })} style={{ color: errors.termos ? 'red' : 'black' }} type="checkbox" className="h-4 w-4 text-blue-300 rounded mt-1" />
<label htmlFor="" style={{ color: errors.termos ? 'red' : 'black' }} className="ml-2 pt-3 text-sm text-gray-600">Li e aceito os <a href="">Termos de Uso</a> e <a href="">Política de privacidade</a> da plataforma Tokenizr</label>
</div>
</div>
<div className="flex items-center justify-between">
<div className="flex items-center">
<input {...register('exibirCliente')} type="checkbox" className="h-4 w-4 text-blue-300 rounded mt-1" />
<label htmlFor="" className="ml-2 pt-3 text-sm text-gray-600">Aceito exibir minha imagem e valores investidos em feeds de investimentos do site (não obrigatório)</label>
</div>
</div>
</div>
<div>
<button className="w-full text-center py-3 bg-gray-600 hover:bg-gray-800 rounded-md text-white text-sm">Registrar</button>
</div>
</form>
<div>
<Link to='/SignUp'>
<button className="w-full text-center py-2 bg-gray-400 hover:bg-gray-800 rounded-md mt-2 text-white text-sm">Voltar</button>
</Link>
</div>
</div>
</div>
</div>
)
}
And my react-mask-component be like this:
import InputMask from 'react-input-mask'
export default function MaskedInput({ value, onChange }) {
return (
<InputMask
mask="999.999.999-99"
value={value}
onChange={onChange}
>
</InputMask>
)
}
I tried to add a parameter in my function to record what the user types and another to be the "className" for the boostrap recognize, but i could not, believe that's not the way, but i may have done something wrong too.