diff --git a/et --hard 63659b6 b/et --hard 63659b6 new file mode 100644 index 0000000..1e3987e --- /dev/null +++ b/et --hard 63659b6 @@ -0,0 +1,56 @@ +3993097 (HEAD -> main) Merge branch 'main' of https://git.popcode.com.br/RiseUP/riseup-squad23 +63659b6 Verificação do cpf e colocar o erro 404 +ecae83c (riseup/main, riseup/HEAD, origin/main, origin/HEAD) Merge pull request 'Conectando-o-resto-das-API' (#2) from Conectando-o-resto-das-API into main +908d545 (riseup/Conectando-o-resto-das-API, origin/Conectando-o-resto-das-API) feat: adicionar upload e delete de anexos do paciente +4b404c0 Merge branch 'main' of https://git.popcode.com.br/RiseUP/riseup-squad23 +bd20c2d Merge remote-tracking branch 'origin/main' +8aeabd1 (riseup/Fix-dos-erros-do-projeto, origin/Fix-dos-erros-do-projeto) FIx: todos os erros que aparecia no console foram resolvidos +0e29e7d melhorias na organização de pastas +98f076a Mergin com TableMelhorias +589d590 Mergin com novas alterações de laudo +7b28e2a Details melhorias +9480edc (riseup/PaginaDetalhes, origin/PaginaDetalhes) Pàgina detalhes +e4515cf Adição das cores nos cards de consulta +d3dd2fd (riseup/TableMelhorias, origin/TableMelhorias) Detalhe nas tabelas +a54b119 Delete Anexos apos pacientes forem excluidos +6e93cb5 atualizar paciente +b9a35be começo do concerto do editar +82469bc Details funcional +cdfe4ea Validação de CPF +57c8f67 (riseup/DetalhesMedico, origin/DetalhesMedico) Detalhes do medico +b021444 Mudanças formularios e detalhes +d5d03b0 (riseup/mudanças-de-laudo, origin/mudanças-de-laudo) atualização do laudo +a502bbd agendamentos no incio +8e1fcd9 Merge branch 'feature/novo-cadastro-paciente' +bea9076 Merge remote-tracking branch 'origin/PaginaDetalhes' +e35f217 mergin branch inicio com main +1af8268 Atualizacão do laudo +725d60d feat: ajeitei o nome +bab85ff (riseup/AgendamentoSidebar, origin/AgendamentoSidebar) Concertar Agendamento +b2707e3 Refatora o estilo do formulário do paciente para uma aparência de cartão com tipografia maior +37e8959 Refatora o estilo do formulário do paciente para uma aparência de cartão com tipografia maior +0930385 feat: uma piquena mudança +f6a19c4 feat: Adiciona formulário de cadastro de paciente +d91b5cf form de agendar consulta melhorado +0a60dd7 Tabela semana e mes +7f07950 (riseup/feature-Melhoria-no-Dashboard, origin/feature-Melhoria-no-Dashboard) feat: Criação da página início e melhoria na navegação +39e25ad Pagina de detalhes atualizada +4f84791 pequenas mudanaças na tabela de semana e mes +6737955 form para nova consulta e tabelas de horario +26ded17 Nova pagina de detalhes +874de84 Inicio do agendamento +f3e7470 (riseup/gerenciamento-de-laudo, origin/gerenciamento-de-laudo) Laudo do Paciente +709cd4e Merge finalizado +d6b3e86 Merge detalhes-do-pacientes para main +08ffa55 Merge remote-tracking branch 'origin/CrudMedico' +70c4d5f Termino da organização +edd567d Inicio da organização +9c09113 Mudanças pos feedback de davi +aa3a5fa Criação da página dos detalhes dos pacientes +5534568 Inicio de detalhes e atualização do paciente +06ff7d5 Funcionalidade de delete e botão de opções +5b63fa2 Mascara telefones +fb9d783 adição da mascara do CPF +a489d84 metodo GET e POST +4eaabbd first commit +a244691 Initial commit diff --git a/package-lock.json b/package-lock.json index ee632a1..9926bf5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,6 +33,7 @@ "react-icons": "^5.5.0", "react-input-mask": "^2.0.4", "react-quill": "^2.0.0", + "react-router-dom": "^7.9.2", "react-scripts": "5.0.1", "recharts": "^3.1.2", "sweetalert2": "^11.22.4", @@ -30711,6 +30712,53 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "7.9.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.9.2.tgz", + "integrity": "sha512-i2TPp4dgaqrOqiRGLZmqh2WXmbdFknUyiCRmSKs0hf6fWXkTKg5h56b+9F22NbGRAMxjYfqQnpi63egzD2SuZA==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.9.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.9.2.tgz", + "integrity": "sha512-pagqpVJnjZOfb+vIM23eTp7Sp/AAJjOgaowhP1f1TWOdk5/W8Uk8d/M/0wfleqx7SgjitjNPPsKeCZE1hTSp3w==", + "license": "MIT", + "dependencies": { + "react-router": "7.9.2" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/react-router/node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/react-scripts": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", @@ -31978,6 +32026,12 @@ "node": ">= 0.8.0" } }, + "node_modules/set-cookie-parser": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "license": "MIT" + }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", diff --git a/package.json b/package.json index e593ae9..450cc45 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "react-icons": "^5.5.0", "react-input-mask": "^2.0.4", "react-quill": "^2.0.0", + "react-router-dom": "^7.9.2", "react-scripts": "5.0.1", "recharts": "^3.1.2", "sweetalert2": "^11.22.4", diff --git a/src/components/patients/PatientForm.jsx b/src/components/patients/PatientForm.jsx index 0b500cc..6e8fb32 100644 --- a/src/components/patients/PatientForm.jsx +++ b/src/components/patients/PatientForm.jsx @@ -1,98 +1,20 @@ 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 ( -
-
-
-
-
CPF já Cadastrado
- -
-
-
- {patientPhoto ? ( - Foto do Paciente - ) : ( -
- 👤 -
- )} -
-

Nome: {patientName}

-

CPF: {patientCpf}

-

ID: {patientId}

-
-
-

Data de Nascimento: {patientDob}

-

Telefone: {patientPhone}

-
-
- - -
-
-
-
- ); -}; -// Modal para Erro 404 -const Error404Modal = ({ show, onClose }) => { - if (!show) { - return null; - } - return ( -
-
-
-
-
Erro de Validação
- -
-
-

(Erro 404). Por favor, tente novamente mais tarde.

-
-
- -
-
-
-
- ); -}; - function PatientForm({ onSave, onCancel, formData, setFormData }) { - const [showDuplicateModal, setShowDuplicateModal] = useState(false); - const [duplicatePatientData, setDuplicatePatientData] = useState(null); - - const [show404Modal, setShow404Modal] = useState(false); + const [showModal, setShowModal] = useState(false); + const [showModal404, setShowModal404] = useState(false); + const [pacienteExistente, setPacienteExistente] = useState(null); const FormatTelefones = (valor) => { const digits = String(valor).replace(/\D/g, '').slice(0, 11); return digits .replace(/(\d)/, '($1') - .replace(/(\d{2})(\d)/, '$1) $2') + .replace(/(\d{2})(\d)/, '$1) $2' ) .replace(/(\d)(\d{4})/, '$1 $2') - .replace(/(\d{4})(\d{4})/, '$1-$2'); - }; - const ReceberRespostaAPIdoCPF = async (cpf) => { + .replace(/(\d{4})(\d{4})/, '$1-$2') + } + + const ReceberRespostaAPIdoCPF = async (cpf) =>{ var myHeaders = new Headers(); myHeaders.append("Authorization", "Bearer "); myHeaders.append("Content-Type", "application/json"); @@ -108,19 +30,19 @@ function PatientForm({ onSave, onCancel, formData, setFormData }) { 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) - if (response.status === 404) { - - throw new Error("404 Not Found"); + if (!response.ok) { + throw new Error('Erro na API de validação de CPF. Status: ' + response.status); } + + const result = await response.json() + + return result.data + } + - const result = await response.json(); - return result.data; - }; - - const fetchPatientById = async (id) => { + const BuscarPacientePorId = async (id) => { var myHeaders = new Headers(); myHeaders.append("Authorization", "Bearer "); @@ -129,7 +51,7 @@ function PatientForm({ onSave, onCancel, formData, setFormData }) { 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(); @@ -141,50 +63,57 @@ function PatientForm({ onSave, onCancel, formData, setFormData }) { }; const ValidarCPF = async (cpf) => { - let aviso = ''; - let Erro = false; - let patientData = null; + let aviso + let Erro = false try { - const resultadoAPI = await ReceberRespostaAPIdoCPF(cpf); - const { valido, existe, id } = resultadoAPI; + const resultadoAPI = await ReceberRespostaAPIdoCPF(cpf) + const valido = resultadoAPI.valido + const ExisteNoBancoDeDados = resultadoAPI.existe + const idPaciente = resultadoAPI.id_paciente - if (!valido) { - aviso = 'CPF inválido'; - Erro = true; - } else if (existe) { - aviso = 'O CPF informado já está presente no sistema.'; - Erro = true; - patientData = await fetchPatientById(id); + if(valido === false){ + aviso = 'CPF inválido' + Erro = true } - } catch (e) { - if (e.message === "404 Not Found") { - setShow404Modal(true); - Erro = true; - } else { - aviso = 'Erro ao validar o CPF. Tente novamente.'; - Erro = true; + else if(ExisteNoBancoDeDados === true){ + const paciente = await BuscarPacientePorId(idPaciente); + if (paciente) { + setPacienteExistente(paciente); + setShowModal(true); + } + Erro = true } + } catch (error) { + console.error("Erro na validação do CPF:", error); + setShowModal404(true); + Erro = true; } + return [Erro,aviso] + } - return { Erro, aviso, patientData }; - }; const FormatCPF = (valor) => { const digits = String(valor).replace(/\D/g, '').slice(0, 11); return digits .replace(/(\d{3})(\d)/, '$1.$2') .replace(/(\d{3})(\d)/, '$1.$2') .replace(/(\d{3})(\d{1,2})$/, '$1-$2'); - }; + } + + + // Estado para armazenar a URL da foto do avatar const [avatarUrl, setAvatarUrl] = useState(null); + + // Estado para controlar quais seções estão colapsadas const [collapsedSections, setCollapsedSections] = useState({ - dadosPessoais: true, + dadosPessoais: true, infoMedicas: false, infoConvenio: false, endereco: false, contato: false, }); + // Função para alternar o estado de colapso de uma seção const handleToggleCollapse = (section) => { setCollapsedSections(prevState => ({ ...prevState, @@ -202,20 +131,28 @@ function PatientForm({ onSave, onCancel, formData, setFormData }) { } else { setFormData(prev => ({ ...prev, imc: '' })); } - }, [formData.peso, formData.altura, setFormData]); + }, [formData.peso, formData.altura]); - const [enderecoData, setEnderecoData] = useState({}); - useEffect(() => { setEnderecoData(formData.endereco || {}); }, [formData.endereco]); - const [contato, setContato] = useState({}); - useEffect(() => { setContato(formData.contato || {}); }, [formData.contato]); + const [enderecoData, setEnderecoData] = useState({}) + useEffect(() => {setEnderecoData(formData.endereco || {}); console.log(enderecoData)}, [formData.endereco]) + + const [contato, setContato] = useState({}) + + useEffect(() => {setContato(formData.contato || {})}, [formData.contato]) + const handleChange = (e) => { const { name, value, type, checked, files } = e.target; + + console.log(formData, name) + if (type === 'checkbox') { setFormData({ ...formData, [name]: checked }); } else if (type === 'file') { setFormData({ ...formData, [name]: files[0] }); + + // Lógica para pré-visualizar a imagem no avatar if (name === 'foto' && files[0]) { const reader = new FileReader(); reader.onloadend = () => { @@ -223,22 +160,24 @@ function PatientForm({ onSave, onCancel, formData, setFormData }) { }; reader.readAsDataURL(files[0]); } else if (name === 'foto' && !files[0]) { - setAvatarUrl(null); - } - } + setAvatarUrl(null); // Limpa o avatar se nenhum arquivo for selecionado + }} + + if (name.includes('cpf')) { - setFormData({ ...formData, cpf: FormatCPF(value) }); + setFormData({...formData, cpf:FormatCPF(value) }); } else if (name.includes('telefone')) { let telefoneFormatado = FormatTelefones(value); setContato(prev => ({ ...prev, [name]: telefoneFormatado })); - } else if (name === 'email') { + }else if (name === 'email') { setContato(prev => ({ ...prev, email: value })); - } else if (name.includes('endereco')) { + }else if(name.includes('endereco')) { setEnderecoData(prev => ({ ...prev, [name.split('.')[1]]: value })); - } else { + }else{ setFormData({ ...formData, [name]: value }); } }; + const handleCepBlur = async () => { const cep = formData.cep.replace(/\D/g, ''); if (cep.length === 8) { @@ -261,35 +200,19 @@ function PatientForm({ onSave, onCancel, formData, setFormData }) { } } }; -<<<<<<< HEAD - const handleSubmit = async () => { - if (!formData.nome || !formData.cpf || !formData.sexo || !formData.data_nascimento) { - alert('Por favor, preencha Nome, CPF, Gênero e data de nascimento.'); -======= - const handleSubmit = async (e) => { - e.preventDefault(); + const handleSubmit = async () => { if (!formData.nome || !formData.cpf || !formData.sexo || !formData.data_nascimento){ alert('Por favor, preencha Nome ,CPF, Gênero e data de nascimento.'); ->>>>>>> ecae83cf4cc5cac2487d7fbd9cb61a8d706b01a3 return; } - const { Erro, aviso, patientData } = await ValidarCPF(formData.cpf); - - if (Erro) { - if (patientData) { - setDuplicatePatientData(patientData); - setShowDuplicateModal(true); - } else { - if (aviso) { - alert(aviso); - } - } + const [CPFinvalido] = await ValidarCPF(formData.cpf); + if(CPFinvalido === true){ return; } - const pacienteSalvo = await onSave({ + onSave({ ...formData, endereco: { cep: enderecoData.cep, @@ -319,59 +242,11 @@ function PatientForm({ onSave, onCancel, formData, setFormData }) { numeroMatricula: formData.numeroMatricula, validadeCarteira: formData.validadeCarteira, validadeIndeterminada: formData.validadeIndeterminada, - pacienteVip: formData.pacienteVip, + pacienteVip: formData.pacienteVip, }, }); -<<<<<<< HEAD }; -======= - const pacienteId = pacienteSalvo.id; - - try{ - if (formData.foto) await uploadFotoPaciente(pacienteId, formData.foto); - if (formData.anexos) await uploadAnexoPaciente(pacienteId, formData.anexos); - alert("Paciente salvo com sucesso!"); - } catch (error) { - console.error(error); - alert("Erro ao salvar paciente ou enviar arquivos."); - } - }; - const uploadFotoPaciente = async (pacienteId, foto) => { - const formDataUpload = new FormData(); - formDataUpload.append('foto', foto); - - try { - const res = await fetch(`https://suaapi.com/pacientes/${pacienteId}/foto`, { - method: 'POST', - headers: { 'Authorization': 'Bearer ' }, - body: formDataUpload - }); - if (!res.ok) throw new Error('Erro ao enviar foto'); - alert('Foto enviada com sucesso!'); - } catch (err) { - console.error(err); - alert('Falha ao enviar foto'); - } - }; - const uploadAnexoPaciente = async (pacienteId, anexo) => { - const formDataUpload = new FormData(); - formDataUpload.append('anexo', anexo); - try { - const res = await fetch(`https://suaapi.com/pacientes/${pacienteId}/anexos`, { - method: 'POST', - headers: { 'Authorization': 'Bearer ' }, - body: formDataUpload - }); - if (!res.ok) throw new Error('Erro ao enviar anexo'); - alert('Anexo enviado com sucesso!'); - } catch (err) { - console.error(err); - alert('Falha ao enviar anexo'); - } - }; ->>>>>>> ecae83cf4cc5cac2487d7fbd9cb61a8d706b01a3 - return (

MediConnect

@@ -386,41 +261,41 @@ function PatientForm({ onSave, onCancel, formData, setFormData }) {
+ {/* AVATAR E INPUT DE FOTO */}
- {/* AVATAR E INPUT DE FOTO */} {avatarUrl ? ( - Avatar do Paciente ) : ( -
- ☤ + ☤
)}
- {formData.foto && {formData.foto.name}} @@ -450,7 +325,7 @@ function PatientForm({ onSave, onCancel, formData, setFormData }) {
- +
@@ -542,6 +417,7 @@ function PatientForm({ onSave, onCancel, formData, setFormData }) {
+ {/* CAMPOS MOVIDOS */}
@@ -550,14 +426,16 @@ function PatientForm({ onSave, onCancel, formData, setFormData }) {
- + {formData.anexos ? formData.anexos.name : 'Nenhum arquivo escolhido'}
+
+ {/* INFORMAÇÕES MÉDICAS */}

handleToggleCollapse('infoMedicas')} style={{ fontSize: '1.8rem' }}> @@ -601,6 +479,7 @@ function PatientForm({ onSave, onCancel, formData, setFormData }) {

+ {/* INFORMAÇÕES DE CONVÊNIO */}

handleToggleCollapse('infoConvenio')} style={{ fontSize: '1.8rem' }}> @@ -653,6 +532,7 @@ function PatientForm({ onSave, onCancel, formData, setFormData }) {

+ {/* ENDEREÇO */}

handleToggleCollapse('endereco')} style={{ fontSize: '1.8rem' }}> @@ -694,6 +574,7 @@ function PatientForm({ onSave, onCancel, formData, setFormData }) {

+ {/* CONTATO */}

handleToggleCollapse('contato')} style={{ fontSize: '1.8rem' }}> @@ -723,24 +604,7 @@ function PatientForm({ onSave, onCancel, formData, setFormData }) {

- - {/* Modal para CPF duplicado */} - 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 */} - setShow404Modal(false)} - /> - {/* Botões */}
+ + {/* Modal para paciente existente */} + {showModal && pacienteExistente && ( +
+
+
+
+
Ops! Este CPF já está cadastrado
+ +
+
+
+ Foto do Paciente +
+

ID do Paciente: {pacienteExistente.id}

+

Nome Completo: {pacienteExistente.nome}

+

CPF: {pacienteExistente.cpf}

+

Data de Nascimento: {pacienteExistente.data_nascimento}

+

Telefone: {pacienteExistente.contato.telefone1}

+
+
+ + +
+
+
+
+ )} + + {/* Erro 404 */} + {showModal404 && ( +
+
+
+
+
Erro de Validação
+ +
+
+

(Erro 404).Por favor,tente novamente mais tarde.

+
+
+ +
+
+
+
+ )} ); }