/** * useFormValidation — composable para validação de formulários com PrimeVue * * Retorna funções de validação prontas para usar em :invalid e mensagens de erro. * * Uso: * const { validateCPF, validatePhone, validateEmail, validateCEP } = useFormValidation() * * // No template: * * {{ validateCPF(cpf).message }} */ import { isValidCPF, isValidCNPJ, isValidPhone, isValidEmail, isValidCEP, fmtCPF, fmtCNPJ, fmtPhone, fmtCEP, sanitizeDigits, toISODate, digitsOnly, } from '@/utils/validators' export function useFormValidation() { /** CPF — campo: `cpf` ou `cpf_responsavel` */ function validateCPF(v, { required = false } = {}) { if (!v || digitsOnly(v).length === 0) { return required ? { valid: false, message: 'CPF é obrigatório.' } : { valid: true, message: '' } } if (!isValidCPF(v)) return { valid: false, message: 'CPF inválido.' } return { valid: true, message: '' } } /** CNPJ */ function validateCNPJ(v, { required = false } = {}) { if (!v || digitsOnly(v).length === 0) { return required ? { valid: false, message: 'CNPJ é obrigatório.' } : { valid: true, message: '' } } if (!isValidCNPJ(v)) return { valid: false, message: 'CNPJ inválido.' } return { valid: true, message: '' } } /** Telefone — campos: `telefone`, `telefone_alternativo`, `telefone_parente`, `telefone_responsavel` */ function validatePhone(v, { required = false } = {}) { if (!v || digitsOnly(v).length === 0) { return required ? { valid: false, message: 'Telefone é obrigatório.' } : { valid: true, message: '' } } if (!isValidPhone(v)) return { valid: false, message: 'Telefone inválido. Use (XX) XXXXX-XXXX.' } return { valid: true, message: '' } } /** Email — campos: `email_principal`, `email_alternativo` */ function validateEmail(v, { required = false } = {}) { if (!v || String(v).trim().length === 0) { return required ? { valid: false, message: 'E-mail é obrigatório.' } : { valid: true, message: '' } } if (!isValidEmail(v)) return { valid: false, message: 'E-mail inválido.' } return { valid: true, message: '' } } /** CEP — campo: `cep` */ function validateCEP(v, { required = false } = {}) { if (!v || digitsOnly(v).length === 0) { return required ? { valid: false, message: 'CEP é obrigatório.' } : { valid: true, message: '' } } if (!isValidCEP(v)) return { valid: false, message: 'CEP inválido. Use 00000-000.' } return { valid: true, message: '' } } /** Nome completo — campo: `nome_completo` */ function validateNomeCompleto(v, { required = true, minWords = 2 } = {}) { const s = String(v ?? '').trim() if (!s) { return required ? { valid: false, message: 'Nome completo é obrigatório.' } : { valid: true, message: '' } } const words = s.split(/\s+/).filter(Boolean) if (words.length < minWords) return { valid: false, message: 'Informe o nome completo (mínimo 2 palavras).' } return { valid: true, message: '' } } /** * Valida um objeto de formulário de paciente de uma só vez. * Retorna { valid: boolean, errors: { campo: mensagem } } * * Exemplo: * const { valid, errors } = validatePatientForm(form, { cpfRequired: false }) */ function validatePatientForm(form, { cpfRequired = false, emailRequired = false, phoneRequired = false } = {}) { const errors = {} const nome = validateNomeCompleto(form.nome_completo) if (!nome.valid) errors.nome_completo = nome.message if (form.cpf || cpfRequired) { const cpf = validateCPF(form.cpf, { required: cpfRequired }) if (!cpf.valid) errors.cpf = cpf.message } if (form.cpf_responsavel) { const cpfResp = validateCPF(form.cpf_responsavel) if (!cpfResp.valid) errors.cpf_responsavel = cpfResp.message } if (form.telefone || phoneRequired) { const tel = validatePhone(form.telefone, { required: phoneRequired }) if (!tel.valid) errors.telefone = tel.message } if (form.telefone_alternativo) { const telAlt = validatePhone(form.telefone_alternativo) if (!telAlt.valid) errors.telefone_alternativo = telAlt.message } if (form.telefone_parente) { const telPar = validatePhone(form.telefone_parente) if (!telPar.valid) errors.telefone_parente = telPar.message } if (form.telefone_responsavel) { const telResp = validatePhone(form.telefone_responsavel) if (!telResp.valid) errors.telefone_responsavel = telResp.message } if (form.email_principal || emailRequired) { const email = validateEmail(form.email_principal, { required: emailRequired }) if (!email.valid) errors.email_principal = email.message } if (form.email_alternativo) { const emailAlt = validateEmail(form.email_alternativo) if (!emailAlt.valid) errors.email_alternativo = emailAlt.message } if (form.cep) { const cep = validateCEP(form.cep) if (!cep.valid) errors.cep = cep.message } return { valid: Object.keys(errors).length === 0, errors } } return { // Validadores individuais validateCPF, validateCNPJ, validatePhone, validateEmail, validateCEP, validateNomeCompleto, // Validação completa do formulário de paciente validatePatientForm, // Re-exporta formatadores para usar junto fmtCPF, fmtCNPJ, fmtPhone, fmtCEP, // Re-exporta utilitários sanitizeDigits, toISODate, digitsOnly, } }