Verificação do cpf e colocar o erro 404
This commit is contained in:
parent
bd20c2d811
commit
63659b69cc
6151
package-lock.json
generated
6151
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import InputMask from "react-input-mask";
|
|
||||||
|
|
||||||
function DoctorForm({ onSave, onCancel, PatientDict }) {
|
function DoctorForm({ onSave, onCancel, PatientDict }) {
|
||||||
|
|
||||||
|
|||||||
@ -1,18 +1,98 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
|
// componente de Modal para CPF duplicado
|
||||||
|
const DuplicatePatientModal = ({ show, onClose, onGoToDetails, patient }) => {
|
||||||
|
if (!show || !patient) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const patientName = patient.nome || patient.nome_completo || 'Paciente sem nome';
|
||||||
|
const patientCpf = patient.cpf || 'Não informado';
|
||||||
|
const patientId = patient.id || 'Não informado';
|
||||||
|
const patientDob = patient.data_nascimento || 'Não informada';
|
||||||
|
const patientPhone = patient.contato?.telefone1 || 'Não informado';
|
||||||
|
const patientPhoto = patient.foto || null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="modal show d-block" style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}>
|
||||||
|
<div className="modal-dialog modal-dialog-centered">
|
||||||
|
<div className="modal-content">
|
||||||
|
<div className="modal-header bg-danger text-white">
|
||||||
|
<h5 className="modal-title">CPF já Cadastrado</h5>
|
||||||
|
<button type="button" className="btn-close" onClick={onClose} style={{ filter: 'invert(1)' }}></button>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body">
|
||||||
|
<div className="d-flex align-items-center mb-3">
|
||||||
|
{patientPhoto ? (
|
||||||
|
<img src={patientPhoto} alt="Foto do Paciente" className="rounded-circle me-3" style={{ width: '80px', height: '80px', objectFit: 'cover' }} />
|
||||||
|
) : (
|
||||||
|
<div className="rounded-circle me-3 d-flex align-items-center justify-content-center" style={{ width: '80px', height: '80px', backgroundColor: '#e9ecef', fontSize: '2rem' }}>
|
||||||
|
👤
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div>
|
||||||
|
<p className="mb-1"><strong>Nome:</strong> {patientName}</p>
|
||||||
|
<p className="mb-1"><strong>CPF:</strong> {patientCpf}</p>
|
||||||
|
<p className="mb-1"><strong>ID:</strong> {patientId}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className="mb-1"><strong>Data de Nascimento:</strong> {patientDob}</p>
|
||||||
|
<p className="mb-1"><strong>Telefone:</strong> {patientPhone}</p>
|
||||||
|
</div>
|
||||||
|
<div className="modal-footer">
|
||||||
|
<button type="button" className="btn btn-primary" onClick={onClose}>
|
||||||
|
Continuar Cadastro
|
||||||
|
</button>
|
||||||
|
<button type="button" className="btn btn-primary" onClick={() => onGoToDetails(patientId)}>
|
||||||
|
Visualizar Paciente
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
// Modal para Erro 404
|
||||||
|
const Error404Modal = ({ show, onClose }) => {
|
||||||
|
if (!show) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div className="modal show d-block" style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}>
|
||||||
|
<div className="modal-dialog modal-dialog-centered">
|
||||||
|
<div className="modal-content">
|
||||||
|
<div className="modal-header bg-danger text-white">
|
||||||
|
<h5 className="modal-title">Erro de Validação</h5>
|
||||||
|
<button type="button" className="btn-close" onClick={onClose} style={{ filter: 'invert(1)' }}></button>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body">
|
||||||
|
<p className="text-danger" style={{ fontSize: '1.4rem' }}>(Erro 404). Por favor, tente novamente mais tarde.</p>
|
||||||
|
</div>
|
||||||
|
<div className="modal-footer">
|
||||||
|
<button type="button" className="btn btn-primary" onClick={onClose}>
|
||||||
|
Fechar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
function PatientForm({ onSave, onCancel,formData, setFormData }) {
|
function PatientForm({ onSave, onCancel, formData, setFormData }) {
|
||||||
|
const [showDuplicateModal, setShowDuplicateModal] = useState(false);
|
||||||
|
const [duplicatePatientData, setDuplicatePatientData] = useState(null);
|
||||||
|
|
||||||
|
const [show404Modal, setShow404Modal] = useState(false);
|
||||||
|
|
||||||
const FormatTelefones = (valor) => {
|
const FormatTelefones = (valor) => {
|
||||||
const digits = String(valor).replace(/\D/g, '').slice(0, 11);
|
const digits = String(valor).replace(/\D/g, '').slice(0, 11);
|
||||||
return digits
|
return digits
|
||||||
.replace(/(\d)/, '($1')
|
.replace(/(\d)/, '($1')
|
||||||
.replace(/(\d{2})(\d)/, '$1) $2' )
|
.replace(/(\d{2})(\d)/, '$1) $2')
|
||||||
.replace(/(\d)(\d{4})/, '$1 $2')
|
.replace(/(\d)(\d{4})/, '$1 $2')
|
||||||
.replace(/(\d{4})(\d{4})/, '$1-$2')
|
.replace(/(\d{4})(\d{4})/, '$1-$2');
|
||||||
}
|
};
|
||||||
|
const ReceberRespostaAPIdoCPF = async (cpf) => {
|
||||||
const ReceberRespostaAPIdoCPF = async (cpf) =>{
|
|
||||||
var myHeaders = new Headers();
|
var myHeaders = new Headers();
|
||||||
myHeaders.append("Authorization", "Bearer <token>");
|
myHeaders.append("Authorization", "Bearer <token>");
|
||||||
myHeaders.append("Content-Type", "application/json");
|
myHeaders.append("Content-Type", "application/json");
|
||||||
@ -28,56 +108,83 @@ function PatientForm({ onSave, onCancel,formData, setFormData }) {
|
|||||||
redirect: 'follow'
|
redirect: 'follow'
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await fetch("https://mock.apidog.com/m1/1053378-0-default/pacientes/validar-cpf", requestOptions)
|
const response = await fetch("https://mock.apidog.com/m1/1053378-0-default/pacientes/validar-cpf", requestOptions);
|
||||||
const result = await response.json()
|
|
||||||
|
|
||||||
return result.data
|
|
||||||
|
|
||||||
|
|
||||||
|
if (response.status === 404) {
|
||||||
|
|
||||||
|
throw new Error("404 Not Found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
return result.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchPatientById = async (id) => {
|
||||||
|
var myHeaders = new Headers();
|
||||||
|
myHeaders.append("Authorization", "Bearer <token>");
|
||||||
|
|
||||||
|
var requestOptions = {
|
||||||
|
method: 'GET',
|
||||||
|
headers: myHeaders,
|
||||||
|
redirect: 'follow'
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}`, requestOptions);
|
||||||
|
const result = await response.json();
|
||||||
|
return result.data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erro ao buscar paciente por ID:", error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const ValidarCPF = async (cpf) => {
|
const ValidarCPF = async (cpf) => {
|
||||||
let aviso
|
let aviso = '';
|
||||||
let Erro = false
|
let Erro = false;
|
||||||
|
let patientData = null;
|
||||||
|
|
||||||
const resutadoAPI = await ReceberRespostaAPIdoCPF(cpf)
|
try {
|
||||||
|
const resultadoAPI = await ReceberRespostaAPIdoCPF(cpf);
|
||||||
|
const { valido, existe, id } = resultadoAPI;
|
||||||
|
|
||||||
const valido = resutadoAPI.valido
|
if (!valido) {
|
||||||
const ExisteNoBancoDeDados = resutadoAPI.existe
|
aviso = 'CPF inválido';
|
||||||
|
Erro = true;
|
||||||
if(valido === false){
|
} else if (existe) {
|
||||||
aviso = 'CPF inválido'
|
aviso = 'O CPF informado já está presente no sistema.';
|
||||||
Erro = true
|
Erro = true;
|
||||||
|
patientData = await fetchPatientById(id);
|
||||||
}
|
}
|
||||||
else if(ExisteNoBancoDeDados === true){
|
} catch (e) {
|
||||||
aviso = 'O CPF informado já está presente no sistema'
|
if (e.message === "404 Not Found") {
|
||||||
Erro = true
|
setShow404Modal(true);
|
||||||
|
Erro = true;
|
||||||
|
} else {
|
||||||
|
aviso = 'Erro ao validar o CPF. Tente novamente.';
|
||||||
|
Erro = true;
|
||||||
}
|
}
|
||||||
return [Erro,aviso]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return { Erro, aviso, patientData };
|
||||||
|
};
|
||||||
const FormatCPF = (valor) => {
|
const FormatCPF = (valor) => {
|
||||||
const digits = String(valor).replace(/\D/g, '').slice(0, 11);
|
const digits = String(valor).replace(/\D/g, '').slice(0, 11);
|
||||||
return digits
|
return digits
|
||||||
.replace(/(\d{3})(\d)/, '$1.$2')
|
.replace(/(\d{3})(\d)/, '$1.$2')
|
||||||
.replace(/(\d{3})(\d)/, '$1.$2')
|
.replace(/(\d{3})(\d)/, '$1.$2')
|
||||||
.replace(/(\d{3})(\d{1,2})$/, '$1-$2');
|
.replace(/(\d{3})(\d{1,2})$/, '$1-$2');
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
// Estado para armazenar a URL da foto do avatar
|
|
||||||
const [avatarUrl, setAvatarUrl] = useState(null);
|
const [avatarUrl, setAvatarUrl] = useState(null);
|
||||||
|
|
||||||
// Estado para controlar quais seções estão colapsadas
|
|
||||||
const [collapsedSections, setCollapsedSections] = useState({
|
const [collapsedSections, setCollapsedSections] = useState({
|
||||||
dadosPessoais: true, // Alterado para true para a seção ficar aberta por padrão
|
dadosPessoais: true,
|
||||||
infoMedicas: false,
|
infoMedicas: false,
|
||||||
infoConvenio: false,
|
infoConvenio: false,
|
||||||
endereco: false,
|
endereco: false,
|
||||||
contato: false,
|
contato: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Função para alternar o estado de colapso de uma seção
|
|
||||||
const handleToggleCollapse = (section) => {
|
const handleToggleCollapse = (section) => {
|
||||||
setCollapsedSections(prevState => ({
|
setCollapsedSections(prevState => ({
|
||||||
...prevState,
|
...prevState,
|
||||||
@ -95,28 +202,20 @@ function PatientForm({ onSave, onCancel,formData, setFormData }) {
|
|||||||
} else {
|
} else {
|
||||||
setFormData(prev => ({ ...prev, imc: '' }));
|
setFormData(prev => ({ ...prev, imc: '' }));
|
||||||
}
|
}
|
||||||
}, [formData.peso, formData.altura]);
|
}, [formData.peso, formData.altura, setFormData]);
|
||||||
|
|
||||||
|
const [enderecoData, setEnderecoData] = useState({});
|
||||||
|
useEffect(() => { setEnderecoData(formData.endereco || {}); }, [formData.endereco]);
|
||||||
|
|
||||||
const [enderecoData, setEnderecoData] = useState({})
|
const [contato, setContato] = useState({});
|
||||||
useEffect(() => {setEnderecoData(formData.endereco || {}); console.log(enderecoData)}, [formData.endereco])
|
useEffect(() => { setContato(formData.contato || {}); }, [formData.contato]);
|
||||||
|
|
||||||
const [contato, setContato] = useState({})
|
|
||||||
|
|
||||||
useEffect(() => {setContato(formData.contato || {})}, [formData.contato])
|
|
||||||
|
|
||||||
|
|
||||||
const handleChange = (e) => {
|
const handleChange = (e) => {
|
||||||
const { name, value, type, checked, files } = e.target;
|
const { name, value, type, checked, files } = e.target;
|
||||||
|
|
||||||
console.log(formData, name)
|
|
||||||
|
|
||||||
if (type === 'checkbox') {
|
if (type === 'checkbox') {
|
||||||
setFormData({ ...formData, [name]: checked });
|
setFormData({ ...formData, [name]: checked });
|
||||||
} else if (type === 'file') {
|
} else if (type === 'file') {
|
||||||
setFormData({ ...formData, [name]: files[0] });
|
setFormData({ ...formData, [name]: files[0] });
|
||||||
|
|
||||||
// Lógica para pré-visualizar a imagem no avatar
|
|
||||||
if (name === 'foto' && files[0]) {
|
if (name === 'foto' && files[0]) {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.onloadend = () => {
|
reader.onloadend = () => {
|
||||||
@ -124,26 +223,22 @@ function PatientForm({ onSave, onCancel,formData, setFormData }) {
|
|||||||
};
|
};
|
||||||
reader.readAsDataURL(files[0]);
|
reader.readAsDataURL(files[0]);
|
||||||
} else if (name === 'foto' && !files[0]) {
|
} else if (name === 'foto' && !files[0]) {
|
||||||
setAvatarUrl(null); // Limpa o avatar se nenhum arquivo for selecionado
|
setAvatarUrl(null);
|
||||||
}}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (name.includes('cpf')) {
|
if (name.includes('cpf')) {
|
||||||
|
setFormData({ ...formData, cpf: FormatCPF(value) });
|
||||||
setFormData({...formData, cpf:FormatCPF(value) });
|
|
||||||
|
|
||||||
} else if (name.includes('telefone')) {
|
} else if (name.includes('telefone')) {
|
||||||
let telefoneFormatado = FormatTelefones(value);
|
let telefoneFormatado = FormatTelefones(value);
|
||||||
setContato(prev => ({ ...prev, [name]: telefoneFormatado }));
|
setContato(prev => ({ ...prev, [name]: telefoneFormatado }));
|
||||||
}else if (name === 'email') {
|
} else if (name === 'email') {
|
||||||
setContato(prev => ({ ...prev, email: value }));
|
setContato(prev => ({ ...prev, email: value }));
|
||||||
}else if(name.includes('endereco')) {
|
} else if (name.includes('endereco')) {
|
||||||
setEnderecoData(prev => ({ ...prev, [name.split('.')[1]]: value }));
|
setEnderecoData(prev => ({ ...prev, [name.split('.')[1]]: value }));
|
||||||
}else{
|
} else {
|
||||||
setFormData({ ...formData, [name]: value });
|
setFormData({ ...formData, [name]: value });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCepBlur = async () => {
|
const handleCepBlur = async () => {
|
||||||
const cep = formData.cep.replace(/\D/g, '');
|
const cep = formData.cep.replace(/\D/g, '');
|
||||||
if (cep.length === 8) {
|
if (cep.length === 8) {
|
||||||
@ -166,20 +261,25 @@ function PatientForm({ onSave, onCancel,formData, setFormData }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
if (!formData.nome || !formData.cpf || !formData.sexo || !formData.data_nascimento){
|
if (!formData.nome || !formData.cpf || !formData.sexo || !formData.data_nascimento) {
|
||||||
alert('Por favor, preencha Nome ,CPF, Gênero e data de nascimento.');
|
alert('Por favor, preencha Nome, CPF, Gênero e data de nascimento.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CPFinvalido = await ValidarCPF(formData.cpf)
|
const { Erro, aviso, patientData } = await ValidarCPF(formData.cpf);
|
||||||
console.log(CPFinvalido)
|
|
||||||
if(CPFinvalido[0] === true){
|
|
||||||
alert(CPFinvalido[1])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (Erro) {
|
||||||
|
if (patientData) {
|
||||||
|
setDuplicatePatientData(patientData);
|
||||||
|
setShowDuplicateModal(true);
|
||||||
|
} else {
|
||||||
|
if (aviso) {
|
||||||
|
alert(aviso);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
onSave({
|
onSave({
|
||||||
...formData,
|
...formData,
|
||||||
@ -230,9 +330,9 @@ function PatientForm({ onSave, onCancel,formData, setFormData }) {
|
|||||||
</h4>
|
</h4>
|
||||||
<div className={`collapse${collapsedSections.dadosPessoais ? ' show' : ''}`}>
|
<div className={`collapse${collapsedSections.dadosPessoais ? ' show' : ''}`}>
|
||||||
<div className="row mt-3">
|
<div className="row mt-3">
|
||||||
{/* AVATAR E INPUT DE FOTO */}
|
|
||||||
<div className="col-md-6 mb-3 d-flex align-items-center">
|
<div className="col-md-6 mb-3 d-flex align-items-center">
|
||||||
<div className="me-3">
|
<div className="me-3">
|
||||||
|
{/* AVATAR E INPUT DE FOTO */}
|
||||||
{avatarUrl ? (
|
{avatarUrl ? (
|
||||||
<img
|
<img
|
||||||
src={avatarUrl}
|
src={avatarUrl}
|
||||||
@ -294,7 +394,7 @@ function PatientForm({ onSave, onCancel,formData, setFormData }) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label style={{ fontSize: '1.1rem' }}>CPF: *</label>
|
<label style={{ fontSize: '1.1rem' }}>CPF: *</label>
|
||||||
<input type="text" className="form-control" name="cpf" value={formData.cpf} onChange={ handleChange} style={{ fontSize: '1.1rem' }} />
|
<input type="text" className="form-control" name="cpf" value={formData.cpf} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label style={{ fontSize: '1.1rem' }}>RG:</label>
|
<label style={{ fontSize: '1.1rem' }}>RG:</label>
|
||||||
@ -386,7 +486,6 @@ function PatientForm({ onSave, onCancel,formData, setFormData }) {
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* CAMPOS MOVIDOS */}
|
{/* CAMPOS MOVIDOS */}
|
||||||
<div className="col-md-12 mb-3 mt-3">
|
<div className="col-md-12 mb-3 mt-3">
|
||||||
<label style={{ fontSize: '1.1rem' }}>Observações:</label>
|
<label style={{ fontSize: '1.1rem' }}>Observações:</label>
|
||||||
@ -395,16 +494,14 @@ function PatientForm({ onSave, onCancel,formData, setFormData }) {
|
|||||||
<div className="col-md-12 mb-3">
|
<div className="col-md-12 mb-3">
|
||||||
<label style={{ fontSize: '1.1rem' }}>Anexos do Paciente:</label>
|
<label style={{ fontSize: '1.1rem' }}>Anexos do Paciente:</label>
|
||||||
<div>
|
<div>
|
||||||
<label htmlFor="anexos-input" className="btn btn-secondary" style={{ fontSize: '1.1rem' }}>Escolher arquivo</label>
|
<label htmlFor="anexos-input" className="btn btn-secondary" style={{ fontSize: '1.1rem', background: '#9ca3af' }}>Escolher arquivo</label>
|
||||||
<input type="file" className="form-control d-none" name="anexos" id="anexos-input" onChange={handleChange} />
|
<input type="file" className="form-control d-none" name="anexos" id="anexos-input" onChange={handleChange} />
|
||||||
<span className="ms-2" style={{ fontSize: '1.1rem' }}>{formData.anexos ? formData.anexos.name : 'Nenhum arquivo escolhido'}</span>
|
<span className="ms-2" style={{ fontSize: '1.1rem' }}>{formData.anexos ? formData.anexos.name : 'Nenhum arquivo escolhido'}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* INFORMAÇÕES MÉDICAS */}
|
{/* INFORMAÇÕES MÉDICAS */}
|
||||||
<div className="mb-5 p-4 border rounded shadow-sm">
|
<div className="mb-5 p-4 border rounded shadow-sm">
|
||||||
<h4 className="mb-4 cursor-pointer d-flex justify-content-between align-items-center" onClick={() => handleToggleCollapse('infoMedicas')} style={{ fontSize: '1.8rem' }}>
|
<h4 className="mb-4 cursor-pointer d-flex justify-content-between align-items-center" onClick={() => handleToggleCollapse('infoMedicas')} style={{ fontSize: '1.8rem' }}>
|
||||||
@ -448,7 +545,6 @@ function PatientForm({ onSave, onCancel,formData, setFormData }) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* INFORMAÇÕES DE CONVÊNIO */}
|
{/* INFORMAÇÕES DE CONVÊNIO */}
|
||||||
<div className="mb-5 p-4 border rounded shadow-sm">
|
<div className="mb-5 p-4 border rounded shadow-sm">
|
||||||
<h4 className="mb-4 cursor-pointer d-flex justify-content-between align-items-center" onClick={() => handleToggleCollapse('infoConvenio')} style={{ fontSize: '1.8rem' }}>
|
<h4 className="mb-4 cursor-pointer d-flex justify-content-between align-items-center" onClick={() => handleToggleCollapse('infoConvenio')} style={{ fontSize: '1.8rem' }}>
|
||||||
@ -501,7 +597,6 @@ function PatientForm({ onSave, onCancel,formData, setFormData }) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ENDEREÇO */}
|
{/* ENDEREÇO */}
|
||||||
<div className="mb-5 p-4 border rounded shadow-sm">
|
<div className="mb-5 p-4 border rounded shadow-sm">
|
||||||
<h4 className="mb-4 cursor-pointer d-flex justify-content-between align-items-center" onClick={() => handleToggleCollapse('endereco')} style={{ fontSize: '1.8rem' }}>
|
<h4 className="mb-4 cursor-pointer d-flex justify-content-between align-items-center" onClick={() => handleToggleCollapse('endereco')} style={{ fontSize: '1.8rem' }}>
|
||||||
@ -543,7 +638,6 @@ function PatientForm({ onSave, onCancel,formData, setFormData }) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* CONTATO */}
|
{/* CONTATO */}
|
||||||
<div className="mb-5 p-4 border rounded shadow-sm">
|
<div className="mb-5 p-4 border rounded shadow-sm">
|
||||||
<h4 className="mb-4 cursor-pointer d-flex justify-content-between align-items-center" onClick={() => handleToggleCollapse('contato')} style={{ fontSize: '1.8rem' }}>
|
<h4 className="mb-4 cursor-pointer d-flex justify-content-between align-items-center" onClick={() => handleToggleCollapse('contato')} style={{ fontSize: '1.8rem' }}>
|
||||||
@ -574,6 +668,23 @@ function PatientForm({ onSave, onCancel,formData, setFormData }) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Modal para CPF duplicado */}
|
||||||
|
<DuplicatePatientModal
|
||||||
|
show={showDuplicateModal}
|
||||||
|
onClose={() => setShowDuplicateModal(false)}
|
||||||
|
onGoToDetails={(id) => {
|
||||||
|
console.log(`Navegando para a página de detalhes do paciente com ID: ${id}`);
|
||||||
|
setShowDuplicateModal(false);
|
||||||
|
}}
|
||||||
|
patient={duplicatePatientData}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/*404 Error Modal */}
|
||||||
|
<Error404Modal
|
||||||
|
show={show404Modal}
|
||||||
|
onClose={() => setShow404Modal(false)}
|
||||||
|
/>
|
||||||
|
|
||||||
{/* Botões */}
|
{/* Botões */}
|
||||||
<div className="mt-3 text-center">
|
<div className="mt-3 text-center">
|
||||||
<button className="btn btn-success me-3" onClick={handleSubmit} style={{ fontSize: '1.2rem', padding: '0.75rem 1.5rem' }}>
|
<button className="btn btn-success me-3" onClick={handleSubmit} style={{ fontSize: '1.2rem', padding: '0.75rem 1.5rem' }}>
|
||||||
|
|||||||
@ -7,6 +7,8 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
|
|||||||
const [filtroVIP, setFiltroVIP] = useState(false);
|
const [filtroVIP, setFiltroVIP] = useState(false);
|
||||||
const [filtroAniversariante, setFiltroAniversariante] = useState(false);
|
const [filtroAniversariante, setFiltroAniversariante] = useState(false);
|
||||||
|
|
||||||
|
// Estado para controlar a exibição do erro 404
|
||||||
|
const [showError404, setShowError404] = useState(false);
|
||||||
|
|
||||||
const GetAnexos = async (id) => {
|
const GetAnexos = async (id) => {
|
||||||
var myHeaders = new Headers();
|
var myHeaders = new Headers();
|
||||||
@ -19,30 +21,24 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
|
|||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}/anexos`, requestOptions);
|
const response = await fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}/anexos`, requestOptions);
|
||||||
|
if (!response.ok) {
|
||||||
|
setShowError404(true);
|
||||||
|
setTimeout(() => setShowError404(false), 5000); // Esconde a mensagem após 5 segundos
|
||||||
|
throw new Error('Erro 404');
|
||||||
|
}
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
|
return result.data;
|
||||||
return result.data; // agora retorna corretamente
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('error', error);
|
console.log('error', error);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const DeleteAnexo = async (patientID) => {
|
const DeleteAnexo = async (patientID) => {
|
||||||
|
const RespostaGetAnexos = await GetAnexos(patientID);
|
||||||
|
for (let i = 0; i < RespostaGetAnexos.length; i++) {
|
||||||
const RespostaGetAnexos = await GetAnexos(patientID)
|
|
||||||
|
|
||||||
for(let i = 0; i < RespostaGetAnexos.length; i++){
|
|
||||||
|
|
||||||
const idAnexo = RespostaGetAnexos[i].id;
|
const idAnexo = RespostaGetAnexos[i].id;
|
||||||
|
|
||||||
console.log('anexos',RespostaGetAnexos)
|
|
||||||
|
|
||||||
|
|
||||||
var myHeaders = new Headers();
|
var myHeaders = new Headers();
|
||||||
myHeaders.append("Authorization", "Bearer <token>");
|
myHeaders.append("Authorization", "Bearer <token>");
|
||||||
|
|
||||||
@ -53,42 +49,41 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientID}/anexos/${idAnexo}`, requestOptions)
|
fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientID}/anexos/${idAnexo}`, requestOptions)
|
||||||
.then(response => response.text())
|
.then(response => {
|
||||||
.then(result => console.log('anexo excluido com sucesso',result))
|
if (!response.ok) {
|
||||||
|
setShowError404(true);
|
||||||
|
setTimeout(() => setShowError404(false), 5000); // Esconde a mensagem após 5 segundos
|
||||||
|
throw new Error('Erro 404');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then(result => console.log('anexo excluido com sucesso', result))
|
||||||
.catch(error => console.log('error', error));
|
.catch(error => console.log('error', error));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Função para excluir paciente
|
|
||||||
const deletePatient = async (id) => {
|
const deletePatient = async (id) => {
|
||||||
|
DeleteAnexo(id);
|
||||||
DeleteAnexo(id)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const requestOptionsDelete = { method: "DELETE", redirect: "follow" };
|
const requestOptionsDelete = { method: "DELETE", redirect: "follow" };
|
||||||
|
|
||||||
if (!window.confirm("Tem certeza que deseja excluir este paciente?")) return;
|
if (!window.confirm("Tem certeza que deseja excluir este paciente?")) return;
|
||||||
|
|
||||||
await fetch(
|
await fetch(
|
||||||
`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}`,
|
`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}`,
|
||||||
requestOptionsDelete
|
requestOptionsDelete
|
||||||
)
|
)
|
||||||
.then((response) => response.text())
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
setShowError404(true);
|
||||||
|
setTimeout(() => setShowError404(false), 5000); // Esconde a mensagem após 5 segundos
|
||||||
|
throw new Error('Erro 404');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
.then((mensage) => console.log(mensage))
|
.then((mensage) => console.log(mensage))
|
||||||
.catch((error) => console.log("Deu problema", error));
|
.catch((error) => console.log("Deu problema", error));
|
||||||
};
|
};
|
||||||
|
|
||||||
// Função para marcar/desmarcar VIP
|
|
||||||
const toggleVIP = async (id, atual) => {
|
const toggleVIP = async (id, atual) => {
|
||||||
const novoStatus = atual === true ? false : true;
|
const novoStatus = atual === true ? false : true;
|
||||||
|
|
||||||
await fetch(
|
await fetch(
|
||||||
`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}`,
|
`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}`,
|
||||||
{
|
{
|
||||||
@ -97,7 +92,14 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
|
|||||||
body: JSON.stringify({ vip: novoStatus }),
|
body: JSON.stringify({ vip: novoStatus }),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.then((response) => response.json())
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
setShowError404(true);
|
||||||
|
setTimeout(() => setShowError404(false), 5000);
|
||||||
|
throw new Error('Erro 404');
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
setPacientes((prev) =>
|
setPacientes((prev) =>
|
||||||
prev.map((p) => (p.id === id ? { ...p, vip: novoStatus } : p))
|
prev.map((p) => (p.id === id ? { ...p, vip: novoStatus } : p))
|
||||||
@ -106,7 +108,6 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
|
|||||||
.catch((error) => console.log("Erro ao atualizar VIP:", error));
|
.catch((error) => console.log("Erro ao atualizar VIP:", error));
|
||||||
};
|
};
|
||||||
|
|
||||||
// Função para atualizar convênio/particular
|
|
||||||
const updateConvenio = async (id, convenio) => {
|
const updateConvenio = async (id, convenio) => {
|
||||||
await fetch(
|
await fetch(
|
||||||
`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}`,
|
`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}`,
|
||||||
@ -116,7 +117,14 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
|
|||||||
body: JSON.stringify({ convenio }),
|
body: JSON.stringify({ convenio }),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.then((response) => response.json())
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
setShowError404(true);
|
||||||
|
setTimeout(() => setShowError404(false), 5000);
|
||||||
|
throw new Error('Erro 404');
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
setPacientes((prev) =>
|
setPacientes((prev) =>
|
||||||
prev.map((p) => (p.id === id ? { ...p, convenio } : p))
|
prev.map((p) => (p.id === id ? { ...p, convenio } : p))
|
||||||
@ -125,32 +133,34 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
|
|||||||
.catch((error) => console.log("Erro ao atualizar convênio:", error));
|
.catch((error) => console.log("Erro ao atualizar convênio:", error));
|
||||||
};
|
};
|
||||||
|
|
||||||
// Requisição inicial para buscar pacientes
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetch("https://mock.apidog.com/m1/1053378-0-default/pacientes")
|
fetch("https://mock.apidog.com/m1/1053378-0-default/pacientes")
|
||||||
.then((response) => response.json())
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
setShowError404(true);
|
||||||
|
setTimeout(() => setShowError404(false), 5000);
|
||||||
|
throw new Error('Erro 404');
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
.then((result) => setPacientes(result["data"]))
|
.then((result) => setPacientes(result["data"]))
|
||||||
.catch((error) =>
|
.catch((error) =>
|
||||||
console.log("Erro para encontrar pacientes no banco de dados", error)
|
console.log("Erro para encontrar pacientes no banco de dados", error)
|
||||||
);
|
);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Função para verificar se hoje é aniversário do paciente
|
|
||||||
const ehAniversariante = (dataNascimento) => {
|
const ehAniversariante = (dataNascimento) => {
|
||||||
if (!dataNascimento) return false;
|
if (!dataNascimento) return false;
|
||||||
const hoje = new Date();
|
const hoje = new Date();
|
||||||
const nascimento = new Date(dataNascimento);
|
const nascimento = new Date(dataNascimento);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
hoje.getDate() === nascimento.getDate() &&
|
hoje.getDate() === nascimento.getDate() &&
|
||||||
hoje.getMonth() === nascimento.getMonth()
|
hoje.getMonth() === nascimento.getMonth()
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const pacientesFiltrados = pacientes.filter((paciente) => {
|
const pacientesFiltrados = pacientes.filter((paciente) => {
|
||||||
const texto = `${paciente.nome}`.toLowerCase();
|
const texto = `${paciente.nome}`.toLowerCase();
|
||||||
|
|
||||||
const passaBusca = texto.includes(search.toLowerCase());
|
const passaBusca = texto.includes(search.toLowerCase());
|
||||||
const passaVIP = filtroVIP ? paciente.vip === true : true;
|
const passaVIP = filtroVIP ? paciente.vip === true : true;
|
||||||
const passaConvenio =
|
const passaConvenio =
|
||||||
@ -158,7 +168,6 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
|
|||||||
const passaAniversario = filtroAniversariante
|
const passaAniversario = filtroAniversariante
|
||||||
? ehAniversariante(paciente.data_nascimento)
|
? ehAniversariante(paciente.data_nascimento)
|
||||||
: true;
|
: true;
|
||||||
|
|
||||||
return passaBusca && passaVIP && passaConvenio && passaAniversario;
|
return passaBusca && passaVIP && passaConvenio && passaAniversario;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -182,11 +191,15 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
|
{showError404 && (
|
||||||
|
<div className="alert alert-danger" role="alert">
|
||||||
|
(Erro 404). Por favor, tente novamente mais tarde.
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div className="card p-3 mb-3">
|
<div className="card p-3 mb-3">
|
||||||
<h5 className="mb-3">
|
<h5 className="mb-3">
|
||||||
<i className="bi bi-funnel-fill me-2 text-primary"></i> Filtros
|
<i className="bi bi-funnel-fill me-2 text-primary"></i> Filtros
|
||||||
</h5>
|
</h5>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className="d-flex flex-nowrap align-items-center gap-2"
|
className="d-flex flex-nowrap align-items-center gap-2"
|
||||||
style={{ overflowX: "auto", paddingBottom: "6px" }}
|
style={{ overflowX: "auto", paddingBottom: "6px" }}
|
||||||
@ -204,7 +217,6 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
|
|||||||
flex: "0 0 auto",
|
flex: "0 0 auto",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<select
|
<select
|
||||||
className="form-select"
|
className="form-select"
|
||||||
value={filtroConvenio}
|
value={filtroConvenio}
|
||||||
@ -220,16 +232,13 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
|
|||||||
<option>Hapvida</option>
|
<option>Hapvida</option>
|
||||||
<option>Unimed</option>
|
<option>Unimed</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
className={`btn ${filtroVIP ? "btn-primary" : "btn-outline-primary"
|
className={`btn ${filtroVIP ? "btn-primary" : "btn-outline-primary"}`}
|
||||||
}`}
|
|
||||||
onClick={() => setFiltroVIP(!filtroVIP)}
|
onClick={() => setFiltroVIP(!filtroVIP)}
|
||||||
style={{ flex: "0 0 auto", whiteSpace: "nowrap" }}
|
style={{ flex: "0 0 auto", whiteSpace: "nowrap" }}
|
||||||
>
|
>
|
||||||
<i className="bi bi-award me-1"></i> VIP
|
<i className="bi bi-award me-1"></i> VIP
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
className={`btn ${filtroAniversariante
|
className={`btn ${filtroAniversariante
|
||||||
? "btn-primary"
|
? "btn-primary"
|
||||||
@ -244,8 +253,6 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div className="table-responsive">
|
<div className="table-responsive">
|
||||||
<table className="table table-striped table-hover">
|
<table className="table table-striped table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
@ -254,6 +261,8 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
|
|||||||
<th>CPF</th>
|
<th>CPF</th>
|
||||||
<th>Email</th>
|
<th>Email</th>
|
||||||
<th>Telefone</th>
|
<th>Telefone</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Ações</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@ -276,7 +285,6 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div className="d-flex gap-2">
|
<div className="d-flex gap-2">
|
||||||
|
|
||||||
<button
|
<button
|
||||||
className="btn btn-sm"
|
className="btn btn-sm"
|
||||||
style={{
|
style={{
|
||||||
@ -290,8 +298,6 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
|
|||||||
>
|
>
|
||||||
<i className="bi bi-eye me-1"></i> Ver Detalhes
|
<i className="bi bi-eye me-1"></i> Ver Detalhes
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
|
||||||
<button
|
<button
|
||||||
className="btn btn-sm"
|
className="btn btn-sm"
|
||||||
style={{
|
style={{
|
||||||
@ -305,7 +311,6 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
|
|||||||
>
|
>
|
||||||
<i className="bi bi-pencil me-1"></i> Editar
|
<i className="bi bi-pencil me-1"></i> Editar
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
className="btn btn-sm"
|
className="btn btn-sm"
|
||||||
style={{
|
style={{
|
||||||
@ -322,7 +327,7 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
|
|||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<tr>
|
<tr>
|
||||||
<td colSpan="8" className="text-center">
|
<td colSpan="6" className="text-center">
|
||||||
Nenhum paciente encontrado.
|
Nenhum paciente encontrado.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user