/**
* 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,
}
}