import React, { useState, useEffect, useRef } from 'react'; import { Link } from 'react-router-dom'; import { FormatTelefones, FormatPeso, FormatCPF } from '../utils/Formatar/Format'; function PatientForm({ onSave, onCancel, formData, setFormData, isLoading }) { const [avatarUrl, setAvatarUrl] = useState(null); const [showRequiredModal, setShowRequiredModal] = useState(false); const [emptyFields, setEmptyFields] = useState([]); const [cpfError, setCpfError] = useState(''); const [collapsedSections, setCollapsedSections] = useState({ dadosPessoais: true, infoMedicas: false, infoConvenio: false, endereco: false, contato: false, }); const nomeRef = useRef(null); const cpfRef = useRef(null); const emailRef = useRef(null); const telefoneRef = useRef(null); const validarCPF = (cpf) => { const cpfLimpo = cpf.replace(/\D/g, ''); if (cpfLimpo.length !== 11) return false; if (/^(\d)\1+$/.test(cpfLimpo)) return false; let soma = 0; for (let i = 0; i < 9; i++) { soma += parseInt(cpfLimpo.charAt(i)) * (10 - i); } let resto = 11 - (soma % 11); let digito1 = resto === 10 || resto === 11 ? 0 : resto; soma = 0; for (let i = 0; i < 10; i++) { soma += parseInt(cpfLimpo.charAt(i)) * (11 - i); } resto = 11 - (soma % 11); let digito2 = resto === 10 || resto === 11 ? 0 : resto; return digito1 === parseInt(cpfLimpo.charAt(9)) && digito2 === parseInt(cpfLimpo.charAt(10)); }; const handleToggleCollapse = (section) => { setCollapsedSections(prev => ({ ...prev, [section]: !prev[section], })); }; useEffect(() => { const peso = parseFloat(formData.weight_kg); const altura = parseFloat(formData.height_m); if (peso > 0 && altura > 0) { const imcCalculado = peso / (altura * altura); setFormData(prev => ({ ...prev, bmi: imcCalculado.toFixed(2) })); } else { setFormData(prev => ({ ...prev, bmi: '' })); } }, [formData.weight_kg, formData.height_m, setFormData]); const handleChange = (e) => { const { name, value, type, checked, files } = e.target; if (value && emptyFields.includes(name)) { setEmptyFields(prev => prev.filter(field => field !== name)); } if (name === 'cpf' && cpfError) { setCpfError(''); } if (type === 'file') { setFormData(prev => ({ ...prev, [name]: files[0] })); if (name === 'foto' && files[0]) { const reader = new FileReader(); reader.onloadend = () => setAvatarUrl(reader.result); reader.readAsDataURL(files[0]); } else if (name === 'foto' && !files[0]) { setAvatarUrl(null); } } else if (name === 'cpf') { const cpfFormatado = FormatCPF(value); setFormData(prev => ({ ...prev, cpf: cpfFormatado })); const cpfLimpo = cpfFormatado.replace(/\D/g, ''); if (cpfLimpo.length === 11) { if (!validarCPF(cpfFormatado)) { setCpfError('CPF inválido'); } else { setCpfError(''); } } } else if (name.includes('phone')) { setFormData(prev => ({ ...prev, [name]: FormatTelefones(value) })); } else if (name.includes('weight_kg') || name.includes('height_m')) { setFormData(prev => ({ ...prev, [name]: FormatPeso(value) })); } else if (name === 'rn_in_insurance' || name === 'vip' || name === 'validadeIndeterminada') { setFormData(prev => ({ ...prev, [name]: checked })); } else { setFormData(prev => ({ ...prev, [name]: value })); } }; const scrollToEmptyField = (fieldName) => { let fieldRef = null; switch (fieldName) { case 'full_name': fieldRef = nomeRef; setCollapsedSections(prev => ({ ...prev, dadosPessoais: true })); break; case 'cpf': fieldRef = cpfRef; setCollapsedSections(prev => ({ ...prev, dadosPessoais: true })); break; case 'email': fieldRef = emailRef; setCollapsedSections(prev => ({ ...prev, contato: true })); break; case 'phone_mobile': fieldRef = telefoneRef; setCollapsedSections(prev => ({ ...prev, contato: true })); break; default: return; } setTimeout(() => { if (fieldRef.current) { fieldRef.current.scrollIntoView({ behavior: 'smooth', block: 'center' }); fieldRef.current.focus(); fieldRef.current.style.border = '2px solid #dc3545'; fieldRef.current.style.boxShadow = '0 0 0 0.2rem rgba(220, 53, 69, 0.25)'; setTimeout(() => { if (fieldRef.current) { fieldRef.current.style.border = ''; fieldRef.current.style.boxShadow = ''; } }, 3000); } }, 300); }; const handleSubmit = async () => { const missingFields = []; if (!formData.full_name) missingFields.push('full_name'); if (!formData.cpf) missingFields.push('cpf'); if (!formData.email) missingFields.push('email'); if (!formData.phone_mobile) missingFields.push('phone_mobile'); if (missingFields.length > 0) { setEmptyFields(missingFields); setShowRequiredModal(true); setTimeout(() => { if (missingFields.length > 0) { scrollToEmptyField(missingFields[0]); } }, 500); return; } const cpfLimpo = formData.cpf.replace(/\D/g, ''); if (cpfLimpo.length !== 11) { setShowRequiredModal(true); setEmptyFields(['cpf']); setCpfError('CPF deve ter 11 dígitos'); setTimeout(() => scrollToEmptyField('cpf'), 500); return; } if (!validarCPF(formData.cpf)) { setShowRequiredModal(true); setEmptyFields(['cpf']); setCpfError('CPF inválido'); setTimeout(() => scrollToEmptyField('cpf'), 500); return; } const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailRegex.test(formData.email)) { throw new Error('Email inválido. Por favor, verifique o email digitado.'); } await onSave({ ...formData, bmi: parseFloat(formData.bmi) || null }); }; const handleModalClose = () => { setShowRequiredModal(false); }; return (
{cpfError ? 'Problema com o CPF:' : 'Por favor, preencha:'}
{cpfError}
) : ( <> {!formData.full_name &&- Nome
} {!formData.cpf &&- CPF
} {!formData.email &&- Telefone
} > )}