From 9c0911396e732eba79e98f562d737d69ba95b1f7 Mon Sep 17 00:00:00 2001 From: Caio Miguel Lima Nunes Date: Thu, 4 Sep 2025 17:32:19 -0300 Subject: [PATCH] =?UTF-8?q?Mudan=C3=A7as=20pos=20feedback=20de=20davi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 26 +- src/components/Sidebar.js | 6 +- src/components/doctors/DoctorForm.jsx | 310 ++++++++++++++++++++++++ src/components/doctors/DoctorList.jsx | 20 ++ src/components/patients/PatientForm.jsx | 26 +- src/data/sidebar-items.json | 88 +------ src/pages/DoctorEditPage.jsx | 52 ++++ src/pages/DoctorFormLayout.jsx | 69 ++++++ src/pages/DoctorTable.jsx | 157 ++++++++++++ src/pages/FormLayout.jsx | 6 +- src/pages/Table.jsx | 168 +++++++------ 11 files changed, 751 insertions(+), 177 deletions(-) create mode 100644 src/components/doctors/DoctorForm.jsx create mode 100644 src/components/doctors/DoctorList.jsx create mode 100644 src/pages/DoctorEditPage.jsx create mode 100644 src/pages/DoctorFormLayout.jsx create mode 100644 src/pages/DoctorTable.jsx diff --git a/src/App.js b/src/App.js index 931fa271..942a128b 100644 --- a/src/App.js +++ b/src/App.js @@ -11,17 +11,19 @@ import Table from "./pages/Table"; // <-- ADIÇÃO AQUI import DataTable from "./pages/DataTable"; import Files from "./pages/files"; import EmailApp from "./pages/EmailApp"; -import ChatApp from "./pages/ChatApp"; +//import ChatApp from "./pages/ChatApp"; import GalleryApp from "./pages/GalleryApp"; import FormLayout from './pages/FormLayout'; import EditPage from './pages/EditPage'; -import PatientList from './components/patients/PatientList'; +import PatientForm from "./components/patients/PatientForm"; import Details from './pages/Details'; - +//import DoctorEditPage from './components/doctors/DoctorEditPage'; +import DoctorTable from './pages/DoctorTable'; +import DoctorFormLayout from './pages/DoctorFormLayout'; function App() { const [isSidebarActive, setIsSidebarActive] = useState(true); - const [currentPage, setCurrentPage] = useState('dashboard'); + const [currentPage, setCurrentPage] = useState('table '); const [patientID, setPatientID] = useState(0) @@ -36,9 +38,15 @@ const renderPageContent = () => { if (currentPage === 'form-layout') { return ; } + else if(currentPage === 'doctor-form-layout'){ + return + } else if (currentPage === 'table') { return ; } + else if(currentPage === 'doctor-table'){ + return + } else if (currentPage === 'data-table') { return ; } @@ -48,16 +56,18 @@ const renderPageContent = () => { else if (currentPage === 'email-app') { return ; } - else if (currentPage === 'chat-app') { - return ; - } + //else if (currentPage === 'chat-app') { + // return ; + //} else if (currentPage === 'gallery-app') { return ; } else if(currentPage === 'edit-page-paciente'){ - return } + // else if(currentPage === 'doctor-form-layout'){ + // return + //} else if(currentPage === 'details-page-paciente'){ return
} diff --git a/src/components/Sidebar.js b/src/components/Sidebar.js index d5addb82..23bb80b9 100644 --- a/src/components/Sidebar.js +++ b/src/components/Sidebar.js @@ -56,11 +56,7 @@ function Sidebar(props) { props.setCurrentPage('dashboard'); }} > - Logo + MediConnect
diff --git a/src/components/doctors/DoctorForm.jsx b/src/components/doctors/DoctorForm.jsx new file mode 100644 index 00000000..94dbf689 --- /dev/null +++ b/src/components/doctors/DoctorForm.jsx @@ -0,0 +1,310 @@ +import React, { useState } from 'react'; +import InputMask from "react-input-mask"; + +function DoctorForm({ onSave, onCancel, PatientDict }) { + + const FormatTelefones = (valor) => { + + const digits = String(valor).replace(/\D/g, '').slice(0, 11); + + + return digits + .replace(/(\d)/, '($1') // 123 -> 123. + .replace(/(\d{2})(\d)/, '$1) $2' ) + .replace(/(\d)(\d{4})/, '$1 $2') + .replace(/(\d{4})(\d{4})/, '$1-$2') + } + + + const FormatCPF = (valor) => { + + const digits = String(valor).replace(/\D/g, '').slice(0, 11); + + + + return digits + .replace(/(\d{3})(\d)/, '$1.$2') // 123 -> 123. + .replace(/(\d{3})(\d)/, '$1.$2') // 123.456 -> 123.456. + .replace(/(\d{3})(\d{1,2})$/, '$1-$2'); // 123.456.789 -> 123.456.789-01 + + } + + + const [formData, setFormData] = useState({ + nome: PatientDict.nome, + nomeSocial: PatientDict.nome_social, + dataNascimento: PatientDict.data_nascimento, + genero: PatientDict.sexo, + //documento: '', + //numeroDocumento: '', + cpf: PatientDict.cpf, + profissao: PatientDict.profissao , + //nomeConjuge: '', + //outroId: '', + cep: '', + cidade: PatientDict.cidade, + estado: PatientDict.estado, + bairro: PatientDict.bairro, + rua: PatientDict.logradouro, + numero: '', + complemento: '', + email: PatientDict.email, + telefone1: PatientDict.celular, + telefone2: '', + telefone3: '', + observacoes: '' + }); + + const handleChange = (e) => { + const { name, value } = e.target; + setFormData({ + ...formData, + [name]: value + }); + + + if(name.includes('cpf')){ + + let cpfFormatado = FormatCPF(e.target.value) + + setFormData({...formData, + [name]: cpfFormatado,} + )} + + else if(name.includes('telefone')){ + let telefoneFormatado = FormatTelefones(value) + + console.log(telefoneFormatado) + + + + setFormData({...formData, + [name]: telefoneFormatado + }) + } + + + + }; + + + // Função para buscar endereço pelo CEP + const handleCepBlur = async () => { + const cep = formData.cep.replace(/\D/g, ''); + if (cep.length === 8) { + try { + const response = await fetch(`https://viacep.com.br/ws/${cep}/json/`); + const data = await response.json(); + if (!data.erro) { + setFormData((prev) => ({ + ...prev, + rua: data.logradouro || '', + bairro: data.bairro || '', + cidade: data.localidade || '', + estado: data.uf || '' + })); + } else { + alert('CEP não encontrado!'); + } + } catch (error) { + alert('Erro ao buscar o CEP.'); + } + } + }; + + const handleSubmit = () => { + if (!formData.nome || !formData.cpf || !formData.genero || !formData.dataNascimento || !formData.email){ + alert('Por favor, preencha: Nome ,CPF, Gênero, Data de nascimento e Email.'); + return; + } + onSave( + {nome: formData.nome, + nomeSocial: formData.nomeSocial, + dataNascimento: formData.dataNascimento, + genero: formData.genero, + //documento: formData.documento, + //numeroDocumento: formData.numeroDocumento, + cpf: formData.cpf, + profissao: formData.profissao, + //nomeConjuge: formData.nomeConjuge, + //outroId: formData.outroId, + endereco: { + cep: formData.cep, + cidade: formData.cidade, + estado: formData.estado, + bairro: formData.bairro, + logradouro: formData.rua, + numero: formData.numero, + complemento: formData.complemento, + }, + + contato: { + email: formData.email, + telefone1: formData.telefone1, + telefone2: formData.telefone2, + telefone3: formData.telefone3, + }, + + observacoes: formData.observacoes, +} + + + ); + }; + + return ( +
+

MediConnect

+ + {/* ------------------ DADOS PESSOAIS ------------------ */} +
Dados Pessoais
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ {/* +
+ + +
+
+ + +
+ */} +
+ + +
+
+ + + +
+ {/* +
+ + +
+
+ + +
+ */} +
+ + {/* ------------------ ENDEREÇO ------------------ */} +
Endereço
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + {/* ------------------ CONTATO ------------------ */} +
Contato
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + {/* ------------------ INFORMAÇÕES ADICIONAIS ------------------ */} +
Informações Adicionais
+
+ + +
+ + {/* Botões */} +
+ + +
+
+ ); +} + + +export default DoctorForm; diff --git a/src/components/doctors/DoctorList.jsx b/src/components/doctors/DoctorList.jsx new file mode 100644 index 00000000..570e5987 --- /dev/null +++ b/src/components/doctors/DoctorList.jsx @@ -0,0 +1,20 @@ +import React from 'react'; + +// Este componente recebe uma função 'onAddDoctor' para avisar que o botão foi clicado +function DoctorList({ onAddPatient }) { + return ( +
+
+

Médicos

+
+
+

Gerencie os médicos cadastrados no sistema.

+ +
+
+ ); +} + +export default DoctorList; \ No newline at end of file diff --git a/src/components/patients/PatientForm.jsx b/src/components/patients/PatientForm.jsx index e0af33ff..f4eb4484 100644 --- a/src/components/patients/PatientForm.jsx +++ b/src/components/patients/PatientForm.jsx @@ -90,6 +90,13 @@ function PatientForm({ onSave, onCancel, PatientDict }) { }) } + else if(name.includes('cep')){ + const digitsCep = String(value).replace(/\D/g, '').slice(0, 8); + setFormData({...formData, + [name]: digitsCep + }) + } + }; @@ -120,10 +127,11 @@ function PatientForm({ onSave, onCancel, PatientDict }) { }; const handleSubmit = () => { - if (!formData.nome || !formData.cpf || !formData.genero || !formData.dataNascimento){ - alert('Por favor, preencha Nome ,CPF, Gênero e data de nascimento.'); + if (!formData.nome || !formData.cpf || !formData.genero || !formData.dataNascimento || !formData.email||!formData.telefone1){ + alert('Por favor, preencha: Nome ,CPF, Gênero, Data de nascimento, telefone e Email.'); return; } + onSave( {nome: formData.nome, nomeSocial: formData.nomeSocial, @@ -167,13 +175,13 @@ function PatientForm({ onSave, onCancel, PatientDict }) { return (
-

MedicoConnect

+

MediConnect

{/* ------------------ DADOS PESSOAIS ------------------ */}
Dados Pessoais
- +
@@ -181,11 +189,11 @@ function PatientForm({ onSave, onCancel, PatientDict }) {
- +
- +
- +
@@ -280,11 +288,11 @@ function PatientForm({ onSave, onCancel, PatientDict }) {
Contato
- +
- +
diff --git a/src/data/sidebar-items.json b/src/data/sidebar-items.json index 8a79aa05..9d395841 100644 --- a/src/data/sidebar-items.json +++ b/src/data/sidebar-items.json @@ -3,93 +3,29 @@ "name": "Menu", "isTitle": true }, - { - "name": "Dashboard", - "url": "dashboard", - "icon": "grid-fill" - }, { - "name": "Form Layout", + "name": "Cadastro de Pacientes", "url": "form-layout", "icon": "file-earmark-medical-fill" }, { - "name": "Table", + "name": "Cadastro do Médico", + "url": "doctor-form-layout", + "icon": "file-earmark-medical-fill" + }, + + { + "name": "Lista de Pacientes", "icon": "table", "url": "table" }, - { - "name": "Data Table", - "icon": "table", - "url": "data-table" - }, { - "name": "Files", - "icon": "folder", - "url": "files" - }, + "name": "Lista de Médico", + "icon": "table", + "url": "doctor-table" + } - -{ - "name": "comunicação", - "isTitle": true - }, - - { - "name": "Email App", - "icon": "envelope", - "url": "email-app" - }, - - { - "name": "Chat App", - "icon": "chat-dots", - "url": "chat-app" - }, - - - { - "name": "GalleryApp", - "icon": "gallery-fill", - "url": "gallery-app" - }, - - { - "name": "Account", - "key": "account", - "icon": "person-circle", - "submenu": [ - { - "name": "Profile", - "url": "account-profile.html" - }, - { - "name": "Security", - "url": "account-security.html" - } - ] - }, - { - "name": "Authentication", - "key": "auth", - "icon": "person-badge-fill", - "submenu": [ - { - "name": "Login", - "url": "auth-login.html" - }, - { - "name": "Register", - "url": "auth-register.html" - }, - { - "name": "Forgot Password", - "url": "auth-forgot-password.html" - } - ] - } - ] \ No newline at end of file diff --git a/src/pages/DoctorEditPage.jsx b/src/pages/DoctorEditPage.jsx new file mode 100644 index 00000000..1a445e3a --- /dev/null +++ b/src/pages/DoctorEditPage.jsx @@ -0,0 +1,52 @@ +// import React from 'react' + +// import DoctorForm from '../components/doctors/DoctorForm' + +// import {useEffect, useState} from 'react' + +// const EditPage = ( {id}) => { + +// const [PatientToPUT, setPatientPUT] = useState({}) + +// var requestOptions = { +// method: 'GET', +// redirect: 'follow' +// }; + +// useEffect(() => { + + +// fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}`, requestOptions) +// .then(response => response.json()) +// .then(result => result.data) +// .then(data => console.log(data)) +// .catch(error => console.log('error', error)); + +// }, []) +// const HandlePutPatient = () => { + +// console.log('médico atualizado') + +// } + + +// return ( + +//
+ +// + + + +// + +//
+// ) +// } + +// export default EditPage \ No newline at end of file diff --git a/src/pages/DoctorFormLayout.jsx b/src/pages/DoctorFormLayout.jsx new file mode 100644 index 00000000..02a9bed2 --- /dev/null +++ b/src/pages/DoctorFormLayout.jsx @@ -0,0 +1,69 @@ +import React, { useState } from 'react'; + +// Importamos os dois novos componentes que criamos +import DoctorList from '../components/doctors/DoctorList'; +import DoctorForm from '../components/doctors/DoctorForm'; + +function FormLayout( ) { + // Este estado vai controlar qual "tela" mostrar: 'list' (lista) ou 'form' (formulário) + const [view, setView] = useState('form'); + + + var myHeaders = new Headers(); + myHeaders.append("Content-Type", "application/json"); + + // Função que será chamada para "salvar" o paciente + const handleSavePatient = (patientData) => { + console.log('Salvando médico:', patientData); + + var raw = JSON.stringify(patientData) + + var requestOptions = { + method:'POST', + header: myHeaders, + body:raw, + redirect:'follow' + + } + + + fetch("https://mock.apidog.com/m1/1053378-0-default/pacientes", requestOptions) + .then(response => response.text()) + .then(result => console.log(result)) + .catch(error => console.log('error', error)); + + alert(`Médico "${patientData.nome}" salvo com sucesso!`); //altere isso para integração com backend + // Após salvar, voltamos para a tela de lista + setView('list'); + }; + + return ( + <> +
+

Cadastro de Médicos

+
+
+
+
+ {/* Aqui está a lógica principal: */} + {/* Se a view for 'list', mostramos a lista com o botão. */} + {/* Se for 'form', mostramos o formulário de cadastro. */} + + {view === 'list' ? ( + setView('form')} /> + ) : ( + setView('list')} + PatientDict={{}} + + /> + )} +
+
+
+ + ); +} + +export default FormLayout; \ No newline at end of file diff --git a/src/pages/DoctorTable.jsx b/src/pages/DoctorTable.jsx new file mode 100644 index 00000000..9f032b53 --- /dev/null +++ b/src/pages/DoctorTable.jsx @@ -0,0 +1,157 @@ +import React, { useState, useEffect } from 'react'; +import DoctorList from '../components/doctors/DoctorList'; +import DoctorForm from '../components/doctors/DoctorForm'; + +function TableDoctor({ setCurrentPage, setPatientID }) { + const [pacientes, setPacientes] = useState([]); + const [search, setSearch] = useState(""); + + // Função para excluir médicos + const deletePatient = async (id) => { + const requestOptionsDelete = { method: "DELETE", redirect: "follow" }; + + if (!window.confirm("Tem certeza que deseja excluir este médico?")) return; + + await fetch( + `https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}`, + requestOptionsDelete + ) + .then((response) => response.text()) + .then((mensage) => console.log(mensage)) + .catch((error) => console.log("Deu problema", error)); + }; + + const onChange = (e, id) => { + let value = e.target.value; + + if (value === "verdetalhes") { + setCurrentPage("details-page-paciente"); + } + + if (value === "editar") { + setCurrentPage("edit-page-paciente"); + setPatientID(id); + } + + if (value === "excluir") { + console.log(`Excluir ${id}`); + deletePatient(id); + } + }; + + var requestOptions = { + method: "GET", + redirect: "follow", + }; + + useEffect(() => { + fetch( + "https://mock.apidog.com/m1/1053378-0-default/pacientes", + requestOptions + ) + .then((response) => response.json()) + .then((result) => setPacientes(result["data"])) + .catch((error) => + console.log("Erro para encontrar médicos no banco de dados", error) + ); + }, []); + + // Filtrar médicos pelo campo de pesquisa (nome, cpf, email, telefone) + const pacientesFiltrados = pacientes.filter((paciente) => + `${paciente.nome} ${paciente.cpf} ${paciente.email} ${paciente.telefone}` + .toLowerCase() + .includes(search.toLowerCase()) + ); + + return ( + <> +
+

Lista de Médicos

+
+
+
+
+
+ {/* Header com título e botão alinhados */} +
+

Médicos Cadastrados

+ +
+ +
+ {/* Barra de pesquisa abaixo do título */} +
+ setSearch(e.target.value)} + className="form-control" + /> +
+ +
+
+ + + + + + + + + + + {pacientesFiltrados.length > 0 ? ( + pacientesFiltrados.map((paciente) => ( + + + + + + + + + + )) + ) : ( + + + + )} + +
NomeCPFEmailTelefoneOpções
{paciente.nome}{paciente.cpf}{paciente.email}{paciente.telefone} + + {paciente.ativo} + + + +
+ Nenhum paciente encontrado. +
+ + + + + + + + ); +} +export default TableDoctor; \ No newline at end of file diff --git a/src/pages/FormLayout.jsx b/src/pages/FormLayout.jsx index 18d4801e..14e05a7f 100644 --- a/src/pages/FormLayout.jsx +++ b/src/pages/FormLayout.jsx @@ -6,8 +6,8 @@ import PatientForm from '../components/patients/PatientForm'; function FormLayout( ) { // Este estado vai controlar qual "tela" mostrar: 'list' (lista) ou 'form' (formulário) - const [view, setView] = useState('list'); - + const [view, setView] = useState('form'); + var myHeaders = new Headers(); myHeaders.append("Content-Type", "application/json"); @@ -40,7 +40,7 @@ function FormLayout( ) { return ( <>
-

Gerenciamento de Pacientes

+

Cadastro de Pacientes

diff --git a/src/pages/Table.jsx b/src/pages/Table.jsx index 62b42790..63d13c79 100644 --- a/src/pages/Table.jsx +++ b/src/pages/Table.jsx @@ -1,89 +1,100 @@ import React, { useState, useEffect } from 'react'; +import PatientList from '../components/patients/PatientList'; +import PatientForm from '../components/patients/PatientForm'; +function TablePaciente({ setCurrentPage, setPatientID }) { + const [pacientes, setPacientes] = useState([]); + const [search, setSearch] = useState(""); -function Table( {setCurrentPage, setPatientID}) { + // Função para excluir paciente + const deletePatient = async (id) => { + const requestOptionsDelete = { method: "DELETE", redirect: "follow" }; + if (!window.confirm("Tem certeza que deseja excluir este paciente?")) return; - - // Função para excluir paciente - const deletePatient = async (id) => { - - const requestOptionsDelete = {method: 'DELETE',redirect:'follow' }; - - - - if (!window.confirm('Tem certeza que deseja excluir este paciente?')) return; - - const response = await fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}`, requestOptionsDelete) - .then(response => response.text()) - .then(mensage => console.log(mensage)) - .catch(error => console.log('Deu problema', error)) - - - - } + await fetch( + `https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}`, + requestOptionsDelete + ) + .then((response) => response.text()) + .then((mensage) => console.log(mensage)) + .catch((error) => console.log("Deu problema", error)); + }; const onChange = (e, id) => { - let value = e.target.value - - console.log(e.target.value) + let value = e.target.value; - if(value === 'verdetalhes'){ - setCurrentPage('details-page-paciente') + if (value === "verdetalhes") { + setCurrentPage("details-page-paciente"); } - if(value === 'editar') - {setCurrentPage('edit-page-paciente') - setPatientID(id) - - - } - - if(value === 'excluir'){ - console.log(`Excluir ${id}`) - deletePatient(id) + if (value === "editar") { + setCurrentPage("edit-page-paciente"); + setPatientID(id); } - } - - - - - - - //const [resposta, setResposta] = useState(dadosEstáticos); - - //const { data: pacientes, pagination } = resposta; - - let [pacientes, setPacientes] = useState([]) + if (value === "excluir") { + console.log(`Excluir ${id}`); + deletePatient(id); + } + }; var requestOptions = { - method:'GET', - redirect:'follow' - } + method: "GET", + redirect: "follow", + }; -useEffect(() => { - console.log('hsjduhdeu') - fetch('https://mock.apidog.com/m1/1053378-0-default/pacientes', requestOptions) - .then(response => response.json()) - .then(result => setPacientes(result['data'])) - - .catch(error => console.log('Erro para encontrar pacientes no banco de dados', error))}, []) + useEffect(() => { + fetch( + "https://mock.apidog.com/m1/1053378-0-default/pacientes", + requestOptions + ) + .then((response) => response.json()) + .then((result) => setPacientes(result["data"])) + .catch((error) => + console.log("Erro para encontrar pacientes no banco de dados", error) + ); + }, []); + // Filtrar pacientes pelo campo de pesquisa (nome, cpf, email, telefone) + const pacientesFiltrados = pacientes.filter((paciente) => + `${paciente.nome} ${paciente.cpf} ${paciente.email} ${paciente.telefone}` + .toLowerCase() + .includes(search.toLowerCase()) + ); return ( <>
-

Tabela de Pacientes

+

Lista de Pacientes

-
-

Pacientes Cadastrados

+ {/* Header com título e botão alinhados */} +
+

Pacientes Cadastrados

+
+
+ {/* Barra de pesquisa abaixo do título */} +
+ setSearch(e.target.value)} + className="form-control" + /> +
+
@@ -92,37 +103,44 @@ useEffect(() => { - - {pacientes.length > 0 ? ( - pacientes.map(paciente => ( + {pacientesFiltrados.length > 0 ? ( + pacientesFiltrados.map((paciente) => ( - - + )) ) : ( - + )} @@ -136,6 +154,4 @@ useEffect(() => { ); } - - -export default Table; \ No newline at end of file +export default TablePaciente; \ No newline at end of file
CPF Email TelefoneStatus Opções
{paciente.nome} {paciente.cpf} {paciente.email} {paciente.telefone} - - {paciente.status} + + {paciente.ativo} - + +
Nenhum paciente encontrado. + Nenhum paciente encontrado. +