Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
bd20c2d811
6334
package-lock.json
generated
6334
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -13,8 +13,11 @@
|
|||||||
"apexcharts": "^5.3.4",
|
"apexcharts": "^5.3.4",
|
||||||
"bootstrap": "^5.3.8",
|
"bootstrap": "^5.3.8",
|
||||||
"bootstrap-icons": "^1.13.1",
|
"bootstrap-icons": "^1.13.1",
|
||||||
|
"dayjs": "^1.11.18",
|
||||||
"flatpickr": "^4.6.13",
|
"flatpickr": "^4.6.13",
|
||||||
|
"lucide-react": "^0.543.0",
|
||||||
"perfect-scrollbar": "^1.5.6",
|
"perfect-scrollbar": "^1.5.6",
|
||||||
|
"powershell": "^2.3.3",
|
||||||
"quill": "^2.0.3",
|
"quill": "^2.0.3",
|
||||||
"rater-js": "^1.0.1",
|
"rater-js": "^1.0.1",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
@ -22,6 +25,7 @@
|
|||||||
"react-bootstrap": "^2.10.10",
|
"react-bootstrap": "^2.10.10",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-flatpickr": "^4.0.11",
|
"react-flatpickr": "^4.0.11",
|
||||||
|
"react-icons": "^5.5.0",
|
||||||
"react-input-mask": "^2.0.4",
|
"react-input-mask": "^2.0.4",
|
||||||
"react-quill": "^2.0.0",
|
"react-quill": "^2.0.0",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
@ -55,7 +59,10 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"autoprefixer": "^10.4.21",
|
||||||
|
"postcss": "^8.5.6",
|
||||||
"sass": "^1.91.0",
|
"sass": "^1.91.0",
|
||||||
"sass-loader": "^16.0.5"
|
"sass-loader": "^16.0.5",
|
||||||
|
"tailwindcss": "^4.1.13"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
121
src/App.js
121
src/App.js
@ -1,101 +1,62 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState } from 'react';
|
||||||
import Sidebar from './components/Sidebar';
|
import Sidebar from './components/Sidebar';
|
||||||
import Header from './components/Header';
|
//import Header from './components/Header';
|
||||||
import Table from "./pages/Table"; // <-- ADIÇÃO AQUI
|
import Table from "./pages/Table";
|
||||||
import DataTable from "./pages/DataTable";
|
|
||||||
import Files from "./pages/files";
|
import Inicio from './pages/Inicio';
|
||||||
import EmailApp from "./pages/EmailApp";
|
import PatientCadastroManager from './pages/PatientCadastroManager';
|
||||||
//import ChatApp from "./pages/ChatApp";
|
|
||||||
import GalleryApp from "./pages/GalleryApp";
|
|
||||||
import FormLayout from './pages/FormLayout';
|
|
||||||
import EditPage from './pages/EditPage';
|
import EditPage from './pages/EditPage';
|
||||||
import PatientForm from "./components/patients/PatientForm";
|
import DoctorEditPage from './pages/DoctorEditPage';
|
||||||
|
|
||||||
import Details from './pages/Details';
|
import Details from './pages/Details';
|
||||||
//import DoctorEditPage from './components/doctors/DoctorEditPage';
|
import DoctorDetails from './pages/DoctorDetails';
|
||||||
|
|
||||||
import DoctorTable from './pages/DoctorTable';
|
import DoctorTable from './pages/DoctorTable';
|
||||||
import DoctorFormLayout from './pages/DoctorFormLayout';
|
import DoctorCadastroManager from './pages/DoctorCadastroManager';
|
||||||
|
import Agendamento from './pages/Agendamento'
|
||||||
|
|
||||||
|
import LaudoManager from "./pages/LaudoManager";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [isSidebarActive, setIsSidebarActive] = useState(true);
|
const [isSidebarActive] = useState(true);
|
||||||
const [currentPage, setCurrentPage] = useState('table ');
|
const [currentPage, setCurrentPage] = useState('Inicio');
|
||||||
|
const [patientID, setPatientID] = useState(null);
|
||||||
|
|
||||||
const [patientID, setPatientID] = useState(null)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const toggleSidebar = () => {
|
|
||||||
setIsSidebarActive(!isSidebarActive);
|
|
||||||
};
|
|
||||||
|
|
||||||
const renderPageContent = () => {
|
const renderPageContent = () => {
|
||||||
if (currentPage === 'form-layout') {
|
switch (currentPage) {
|
||||||
return <FormLayout/>;
|
case 'Inicio':
|
||||||
}
|
return <Inicio setCurrentPage={setCurrentPage} />;
|
||||||
else if(currentPage === 'doctor-form-layout'){
|
case 'agendamento':
|
||||||
return <DoctorFormLayout/>
|
return <Agendamento/>;
|
||||||
}
|
case 'form-layout':
|
||||||
else if (currentPage === 'table') {
|
return <PatientCadastroManager setCurrentPage={setCurrentPage}/>;
|
||||||
|
case 'doctor-form-layout':
|
||||||
|
return <DoctorCadastroManager />;
|
||||||
|
case 'table':
|
||||||
return <Table setCurrentPage={setCurrentPage} setPatientID={setPatientID} />;
|
return <Table setCurrentPage={setCurrentPage} setPatientID={setPatientID} />;
|
||||||
}
|
case 'doctor-table':
|
||||||
else if(currentPage === 'doctor-table'){
|
return <DoctorTable setCurrentPage={setCurrentPage} setPatientID={setPatientID} />;
|
||||||
return <DoctorTable setCurrentPage={setCurrentPage} setPatientID={setPatientID}/>
|
case 'details-page-paciente':
|
||||||
}
|
|
||||||
else if (currentPage === 'data-table') {
|
|
||||||
return <DataTable />;
|
|
||||||
}
|
|
||||||
else if (currentPage === 'files') {
|
|
||||||
return <Files />;
|
|
||||||
}
|
|
||||||
else if (currentPage === 'email-app') {
|
|
||||||
return <EmailApp />;
|
|
||||||
}
|
|
||||||
//else if (currentPage === 'chat-app') {
|
|
||||||
// return <ChatApp />;
|
|
||||||
//}
|
|
||||||
else if (currentPage === 'gallery-app') {
|
|
||||||
return <GalleryApp />;
|
|
||||||
}
|
|
||||||
else if(currentPage === 'edit-page-paciente'){
|
|
||||||
return <EditPage id={patientID} />
|
|
||||||
}
|
|
||||||
// else if(currentPage === 'doctor-form-layout'){
|
|
||||||
// return <DoctorEditPage id={patientID} />
|
|
||||||
//}
|
|
||||||
else if(currentPage === 'details-page-paciente'){
|
|
||||||
return <Details patientID={patientID} setCurrentPage={setCurrentPage} />;
|
return <Details patientID={patientID} setCurrentPage={setCurrentPage} />;
|
||||||
|
case 'details-page-doctor':
|
||||||
|
return <DoctorDetails patientID={patientID} setCurrentPage={setCurrentPage} />;
|
||||||
|
case 'edit-page-paciente':
|
||||||
|
return <EditPage id={patientID} />;
|
||||||
|
case 'edit-page-doctor':
|
||||||
|
return <DoctorEditPage id={patientID} />;
|
||||||
|
case 'laudo-manager':
|
||||||
|
return <LaudoManager />;
|
||||||
|
default:
|
||||||
|
return <Inicio setCurrentPage={setCurrentPage} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Dashboard por padrão
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className="page-heading">
|
|
||||||
<h3>Profile Statistics</h3>
|
|
||||||
</div>
|
|
||||||
<div className="page-content">
|
|
||||||
<section className="row">
|
|
||||||
<div className="col-12 col-lg-9">
|
|
||||||
<div className="row">
|
|
||||||
|
|
||||||
<div className="col-12 col-md-6 col-lg-8">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="col-12 col-lg-3">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id="app" className={isSidebarActive ? 'active' : ''}>
|
<div id="app" className={isSidebarActive ? 'active' : ''}>
|
||||||
<Sidebar isSidebarActive={isSidebarActive} setCurrentPage={setCurrentPage} />
|
<Sidebar isSidebarActive={isSidebarActive} setCurrentPage={setCurrentPage} />
|
||||||
<div id="main">
|
<div id="main">
|
||||||
<Header toggleSidebar={toggleSidebar} />
|
|
||||||
{renderPageContent()}
|
{renderPageContent()}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
BIN
src/assets/images/avatar_placeholder.png
Normal file
BIN
src/assets/images/avatar_placeholder.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
32
src/components/AgendarConsulta/CardConsulta.jsx
Normal file
32
src/components/AgendarConsulta/CardConsulta.jsx
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
const CardConsulta = ( {DadosConsulta, TabelaAgendamento} ) => {
|
||||||
|
|
||||||
|
|
||||||
|
// Status (agendado, confirmado, realizado, cancelado)
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={`container-cardconsulta-${TabelaAgendamento}`}>
|
||||||
|
|
||||||
|
{DadosConsulta.status !== 'vazio'?
|
||||||
|
<div className='cardconsulta' id={`status-card-consulta-${DadosConsulta.status}`}>
|
||||||
|
<section className='cardconsulta-infosecundaria'>
|
||||||
|
<p>{DadosConsulta.horario}|GEAP| {DadosConsulta.medico}</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className='cardconsulta-infoprimaria'>
|
||||||
|
<p>{DadosConsulta.paciente} - {DadosConsulta.motivo} - 23 anos</p>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
:
|
||||||
|
null
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CardConsulta
|
||||||
105
src/components/AgendarConsulta/DadosConsultasMock.js
Normal file
105
src/components/AgendarConsulta/DadosConsultasMock.js
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
|
||||||
|
// Status (agendado, confirmado, realizado, cancelado)
|
||||||
|
|
||||||
|
|
||||||
|
let AgendamentosMes = {semana1:{
|
||||||
|
segunda:[ { horario: '07:00', medico: 'Rogerio Cena', paciente: 'Caio Miguel', status: 'realizado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '07:10', status:'vazio' },
|
||||||
|
{ horario: '07:20', medico: 'Rogerio Cena', paciente: 'Ana Paula', status: 'realizado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '07:30', medico: 'Rogerio Cena', paciente: 'Bruno Lima', status: 'realizado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '07:40', status:'vazio' },
|
||||||
|
{ horario: '07:50', medico: 'Rogerio Cena', paciente: 'Felipe Duarte', status: 'realizado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '08:00', medico: 'Rogerio Cena', paciente: 'Carolina Alves', status: 'confirmado', motivo:'2 Exames' },
|
||||||
|
{ horario: '08:10', medico: 'Rogerio Cena', paciente: 'Ricardo Gomes', status: 'agendado', motivo:'retorno' },
|
||||||
|
{ horario: '08:20', medico: 'Rogerio Cena', paciente: 'Tatiane Ramos', status: 'confirmado', motivo: '' },
|
||||||
|
{ horario: '08:30', medico: 'Rogerio Cena', paciente: 'Daniel Oliveira', status: 'realizado', motivo: '' }],
|
||||||
|
|
||||||
|
terca:[ { horario: '07:00', medico: 'Rogerio Cena', paciente: 'Caio Miguel', status: 'confirmado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '07:10', status:'vazio' },
|
||||||
|
{ horario: '07:20', medico: 'Rogerio Cena', paciente: 'Ana Paula', status: 'cancelado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '07:30', medico: 'Rogerio Cena', paciente: 'Bruno Lima', status: 'realizado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '07:40', status:'vazio' },
|
||||||
|
{ horario: '07:50', medico: 'Rogerio Cena', paciente: 'Felipe Duarte', status: 'cancelado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '08:00', medico: 'Rogerio Cena', paciente: 'Carolina Alves', status: 'confirmado', motivo:'2 Exames' },
|
||||||
|
{ horario: '08:10', medico: 'Rogerio Cena', paciente: 'Ricardo Gomes', status: 'agendado', motivo:'retorno' },
|
||||||
|
{ horario: '08:20', medico: 'Rogerio Cena', paciente: 'Tatiane Ramos', status: 'confirmado', motivo: '' },
|
||||||
|
{ horario: '08:30', medico: 'Rogerio Cena', paciente: 'Daniel Oliveira', status: 'realizado', motivo: '' }],
|
||||||
|
|
||||||
|
quarta:[ { horario: '07:00', medico: 'Rogerio Cena', paciente: 'Caio Miguel', status: 'confirmado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '07:10', status:'vazio' },
|
||||||
|
{ horario: '07:20', medico: 'Rogerio Cena', paciente: 'Ana Paula', status: 'cancelado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '07:30', medico: 'Rogerio Cena', paciente: 'Bruno Lima', status: 'realizado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '07:40', status:'vazio' },
|
||||||
|
{ horario: '07:50', medico: 'Rogerio Cena', paciente: 'Felipe Duarte', status: 'cancelado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '08:00', medico: 'Rogerio Cena', paciente: 'Carolina Alves', status: 'confirmado', motivo:'2 Exames' },
|
||||||
|
{ horario: '08:10', medico: 'Rogerio Cena', paciente: 'Ricardo Gomes', status: 'agendado', motivo:'retorno' },
|
||||||
|
{ horario: '08:20', medico: 'Rogerio Cena', paciente: 'Tatiane Ramos', status: 'confirmado', motivo: '' },
|
||||||
|
{ horario: '08:30', medico: 'Rogerio Cena', paciente: 'Daniel Oliveira', status: 'realizado', motivo: '' }],
|
||||||
|
|
||||||
|
quinta:[ { horario: '07:00', medico: 'Rogerio Cena', paciente: 'Caio Miguel', status: 'confirmado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '07:10', status:'vazio' },
|
||||||
|
{ horario: '07:20', medico: 'Rogerio Cena', paciente: 'Ana Paula', status: 'cancelado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '07:30', medico: 'Rogerio Cena', paciente: 'Bruno Lima', status: 'realizado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '07:40', status:'vazio' },
|
||||||
|
{ horario: '07:50', medico: 'Rogerio Cena', paciente: 'Felipe Duarte', status: 'cancelado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '08:00', medico: 'Rogerio Cena', paciente: 'Carolina Alves', status: 'confirmado', motivo:'2 Exames' },
|
||||||
|
{ horario: '08:10', medico: 'Rogerio Cena', paciente: 'Ricardo Gomes', status: 'agendado', motivo:'retorno' },
|
||||||
|
{ horario: '08:20', medico: 'Rogerio Cena', paciente: 'Tatiane Ramos', status: 'confirmado', motivo: '' },
|
||||||
|
{ horario: '08:30', medico: 'Rogerio Cena', paciente: 'Daniel Oliveira', status: 'realizado', motivo: '' }],
|
||||||
|
|
||||||
|
sexta:[ { horario: '07:00', medico: 'Rogerio Cena', paciente: 'Caio Miguel', status: 'confirmado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '07:10', status:'vazio' },
|
||||||
|
{ horario: '07:20', medico: 'Rogerio Cena', paciente: 'Ana Paula', status: 'cancelado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '07:30', medico: 'Rogerio Cena', paciente: 'Bruno Lima', status: 'realizado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '07:40', status:'vazio' },
|
||||||
|
{ horario: '07:50', medico: 'Rogerio Cena', paciente: 'Felipe Duarte', status: 'cancelado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '08:00', medico: 'Rogerio Cena', paciente: 'Carolina Alves', status: 'confirmado', motivo:'2 Exames' },
|
||||||
|
{ horario: '08:10', medico: 'Rogerio Cena', paciente: 'Ricardo Gomes', status: 'agendado', motivo:'retorno' },
|
||||||
|
{ horario: '08:20', medico: 'Rogerio Cena', paciente: 'Tatiane Ramos', status: 'confirmado', motivo: '' },
|
||||||
|
{ horario: '08:30', medico: 'Rogerio Cena', paciente: 'Daniel Oliveira', status: 'realizado', motivo: '' }]
|
||||||
|
|
||||||
|
|
||||||
|
}, semana2:{segunda:[ { horario: '07:00', medico: 'Rogerio Cena', paciente: 'Caio Miguel', status: 'confirmado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '07:10', status:'vazio' },
|
||||||
|
{ horario: '07:20', medico: 'Rogerio Cena', paciente: 'Ana Paula', status: 'cancelado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '07:30', medico: 'Rogerio Cena', paciente: 'Bruno Lima', status: 'realizado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '07:40', status:'vazio' },
|
||||||
|
{ horario: '07:50', medico: 'Rogerio Cena', paciente: 'Felipe Duarte', status: 'cancelado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '08:00', medico: 'Rogerio Cena', paciente: 'Carolina Alves', status: 'confirmado', motivo:'2 Exames' },
|
||||||
|
{ horario: '08:10', medico: 'Rogerio Cena', paciente: 'Ricardo Gomes', status: 'agendado', motivo:'retorno' },
|
||||||
|
{ horario: '08:20', medico: 'Rogerio Cena', paciente: 'Tatiane Ramos', status: 'confirmado', motivo: '' },
|
||||||
|
{ horario: '08:30', medico: 'Rogerio Cena', paciente: 'Daniel Oliveira', status: 'realizado', motivo: '' },
|
||||||
|
{ horario: '07:10', status:'vazio' },
|
||||||
|
{ horario: '07:20', medico: 'Rogerio Cena', paciente: 'Ana Paula', status: 'cancelado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '07:30', medico: 'Rogerio Cena', paciente: 'Bruno Lima', status: 'realizado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '07:40', status:'vazio' },
|
||||||
|
{ horario: '07:50', medico: 'Rogerio Cena', paciente: 'Felipe Duarte', status: 'cancelado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '08:00', medico: 'Rogerio Cena', paciente: 'Carolina Alves', status: 'confirmado', motivo:'2 Exames' },
|
||||||
|
{ horario: '08:10', medico: 'Rogerio Cena', paciente: 'Ricardo Gomes', status: 'agendado', motivo:'retorno' },
|
||||||
|
{ horario: '08:20', medico: 'Rogerio Cena', paciente: 'Tatiane Ramos', status: 'confirmado', motivo: '' },
|
||||||
|
{ horario: '08:30', medico: 'Rogerio Cena', paciente: 'Daniel Oliveira', status: 'realizado', motivo: '' }],
|
||||||
|
|
||||||
|
terca:[ { horario: '07:00', medico: 'Rogerio Cena', paciente: 'Caio Miguel', status: 'confirmado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '07:10', status:'vazio' },
|
||||||
|
{ horario: '07:20', medico: 'Rogerio Cena', paciente: 'Ana Paula', status: 'cancelado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '07:30', medico: 'Rogerio Cena', paciente: 'Bruno Lima', status: 'realizado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '07:40', status:'vazio' },
|
||||||
|
{ horario: '07:50', medico: 'Rogerio Cena', paciente: 'Felipe Duarte', status: 'cancelado', motivo:'Consulta de Rotina' },
|
||||||
|
{ horario: '08:00', medico: 'Rogerio Cena', paciente: 'Carolina Alves', status: 'confirmado', motivo:'2 Exames' },
|
||||||
|
{ horario: '08:10', medico: 'Rogerio Cena', paciente: 'Ricardo Gomes', status: 'agendado', motivo:'retorno' },
|
||||||
|
{ horario: '08:20', medico: 'Rogerio Cena', paciente: 'Tatiane Ramos', status: 'confirmado', motivo: '' },
|
||||||
|
{ horario: '08:30', medico: 'Rogerio Cena', paciente: 'Daniel Oliveira', status: 'realizado', motivo: '' }],
|
||||||
|
|
||||||
|
quarta:[{ horario: '07:10', status:'vazio' }],
|
||||||
|
|
||||||
|
quinta:[{ horario: '07:00', medico: 'Rogerio Cena', paciente: 'Caio Miguel', status: 'confirmado', motivo:'Consulta de Rotina' }],
|
||||||
|
|
||||||
|
sexta:[{ horario: '07:00', medico: 'Rogerio Cena', paciente: 'Caio Miguel', status: 'confirmado', motivo:'Consulta de Rotina' }]}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default AgendamentosMes
|
||||||
117
src/components/AgendarConsulta/FormNovaConsulta.jsx
Normal file
117
src/components/AgendarConsulta/FormNovaConsulta.jsx
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
import React from "react";
|
||||||
|
import InputMask from "react-input-mask";
|
||||||
|
import "./style/styleagendamentos.css";
|
||||||
|
|
||||||
|
const FormNovaConsulta = ({ onCancel }) => {
|
||||||
|
const handleSubmit = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
alert("Agendamento salvo!");
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="form-container">
|
||||||
|
|
||||||
|
|
||||||
|
<form className="form-agendamento" onSubmit={handleSubmit}>
|
||||||
|
<h2 className="section-title">Informações do paciente</h2>
|
||||||
|
|
||||||
|
<div id="informacoes-paciente-primeiralinha">
|
||||||
|
<label>Nome *</label>
|
||||||
|
<input type="text" name="nome" placeholder="Insira o nome do paciente" required />
|
||||||
|
|
||||||
|
<label>CPF do paciente</label>
|
||||||
|
<InputMask mask="999.999.999-99" placeholder="000.000.000-00">
|
||||||
|
{(inputProps) => <input {...inputProps} type="text" name="cpf" />}
|
||||||
|
</InputMask>
|
||||||
|
|
||||||
|
<label>RG</label>
|
||||||
|
<input type="text" name="rg" placeholder="Insira o nº do RG" maxLength={9} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<label>Data de nascimento *</label>
|
||||||
|
<input type="date" name="data_nascimento" required />
|
||||||
|
|
||||||
|
<label>Telefone</label>
|
||||||
|
<InputMask mask="(99) 99999-9999" placeholder="(99) 99999-9999">
|
||||||
|
{(inputProps) => <input {...inputProps} type="tel" name="telefone" />}
|
||||||
|
</InputMask>
|
||||||
|
|
||||||
|
<label>E-mail</label>
|
||||||
|
<input type="email" name="email" placeholder="Email" />
|
||||||
|
|
||||||
|
<label>Convênio</label>
|
||||||
|
<select name="convenio">
|
||||||
|
<option value="particular">Particular</option>
|
||||||
|
<option value="publico">Público</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label>Matrícula</label>
|
||||||
|
<input type="text" name="matricula" placeholder="000000000" />
|
||||||
|
|
||||||
|
<label>Validade</label>
|
||||||
|
<InputMask mask="99/99/9999" placeholder="00/00/0000">
|
||||||
|
{(inputProps) => <input {...inputProps} type="text" name="validade" />}
|
||||||
|
</InputMask>
|
||||||
|
|
||||||
|
<h3 className="section-subtitle">Informações adicionais</h3>
|
||||||
|
<button type="button" className="btn-secondary">Documentos e anexos</button>
|
||||||
|
|
||||||
|
<h2 className="section-title">Informações do atendimento</h2>
|
||||||
|
|
||||||
|
<label>Nome do profissional *</label>
|
||||||
|
<input type="text" name="profissional" required />
|
||||||
|
|
||||||
|
<label>Tipo de atendimento *</label>
|
||||||
|
<input type="text" name="tipoAtendimento" required />
|
||||||
|
|
||||||
|
<label>Unidade *</label>
|
||||||
|
<select name="unidade">
|
||||||
|
<option value="centro">Núcleo de Especialidades Integradas</option>
|
||||||
|
<option value="leste">Unidade Leste</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label>Data *</label>
|
||||||
|
<input type="date" name="dataAtendimento" required />
|
||||||
|
|
||||||
|
<label>Início *</label>
|
||||||
|
<input type="time" name="inicio" required />
|
||||||
|
|
||||||
|
<label>Término *</label>
|
||||||
|
<input type="time" name="termino" required />
|
||||||
|
|
||||||
|
<label>Profissional solicitante</label>
|
||||||
|
<select name="solicitante">
|
||||||
|
<option value="">Selecione o solicitante</option>
|
||||||
|
<option value="secretaria">Secretária</option>
|
||||||
|
<option value="medico">Médico</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label>Observações</label>
|
||||||
|
<textarea name="observacoes"></textarea>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" name="reembolso" /> Pagamento via Reembolso
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" name="imprimirEtiqueta" /> Imprimir na Etiqueta / Pulseira
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<h3 className="section-subtitle">Acessibilidade</h3>
|
||||||
|
<div className="btn-group">
|
||||||
|
<button type="button"></button>
|
||||||
|
<button type="button"></button>
|
||||||
|
<button type="button"></button>
|
||||||
|
<button type="button"></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="form-actions">
|
||||||
|
<button type="submit" className="btn-primary">Salvar agendamento</button>
|
||||||
|
<button type="button" className="btn-cancel" onClick={onCancel}>Cancelar</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FormNovaConsulta;
|
||||||
48
src/components/AgendarConsulta/TabelaAgendamentoDia.jsx
Normal file
48
src/components/AgendarConsulta/TabelaAgendamentoDia.jsx
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import CardConsulta from './CardConsulta'
|
||||||
|
import AgendamentosMes from './DadosConsultasMock'
|
||||||
|
import "./style/styleTabelas/tabeladia.css";
|
||||||
|
|
||||||
|
const TabelaAgendamentoDia = ({handleClickAgendamento}) => {
|
||||||
|
|
||||||
|
let agendamentosDessaSemana = AgendamentosMes.semana1
|
||||||
|
|
||||||
|
let agendamentos = agendamentosDessaSemana.segunda
|
||||||
|
|
||||||
|
console.log(agendamentos)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<table className='tabeladiaria'>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<th>{agendamentos.medico}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
{agendamentos.map((agendamento) => (
|
||||||
|
<tr key={agendamento.id} border='2' >
|
||||||
|
<td ><p>{agendamento.horario}</p></td>
|
||||||
|
<td className='mostrar-horario'>
|
||||||
|
|
||||||
|
<div onClick={() => handleClickAgendamento(agendamento)} >
|
||||||
|
<CardConsulta DadosConsulta={agendamento} TabelaAgendamento={'dia'} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
))}
|
||||||
|
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TabelaAgendamentoDia
|
||||||
133
src/components/AgendarConsulta/TabelaAgendamentoMes.jsx
Normal file
133
src/components/AgendarConsulta/TabelaAgendamentoMes.jsx
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import AgendamentosMes from './DadosConsultasMock'
|
||||||
|
import dayjs from "dayjs"
|
||||||
|
import CardConsulta from './CardConsulta'
|
||||||
|
import "./style/styleTabelas/tabelames.css";
|
||||||
|
|
||||||
|
const TabelaAgendamentoMes = ({ListarDiasdoMes}) => {
|
||||||
|
|
||||||
|
|
||||||
|
const dataHoje = dayjs()
|
||||||
|
const AnoAtual = dataHoje.year()
|
||||||
|
const mes = dataHoje.month() + 1
|
||||||
|
|
||||||
|
let ListaDiasDatas = ListarDiasdoMes(AnoAtual, mes)
|
||||||
|
|
||||||
|
let segundas = ListaDiasDatas[0];
|
||||||
|
let tercas = ListaDiasDatas[1];
|
||||||
|
let quartas = ListaDiasDatas[2];
|
||||||
|
let quintas = ListaDiasDatas[3];
|
||||||
|
let sextas = ListaDiasDatas[4]
|
||||||
|
|
||||||
|
console.log(AnoAtual, 'ano', mes, 'mes')
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<table className='tabelamensal'>
|
||||||
|
<tr>
|
||||||
|
<th>Seg</th>
|
||||||
|
<th>Ter</th>
|
||||||
|
<th>Qua</th>
|
||||||
|
<th>Qui</th>
|
||||||
|
<th>Sex</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{Object.entries(AgendamentosMes).map(([semanas, dias], index) => (
|
||||||
|
<tr key={index}>
|
||||||
|
<td>
|
||||||
|
<div>
|
||||||
|
<p>{segundas[index]}</p>
|
||||||
|
<div>
|
||||||
|
{dias.segunda.slice(0,4).map((consulta, idx) => (
|
||||||
|
<CardConsulta
|
||||||
|
key={idx}
|
||||||
|
DadosConsulta={consulta}
|
||||||
|
className={`usuario-${consulta.cor || "default"}`}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
{dias.segunda.length > 3 ?
|
||||||
|
<div><p>+ {dias.segunda.length - 3}</p></div>
|
||||||
|
: null}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<div>
|
||||||
|
{tercas[index]}
|
||||||
|
<div>
|
||||||
|
{dias.terca.slice(0,4).map((consulta, idx) => (
|
||||||
|
<CardConsulta
|
||||||
|
key={idx}
|
||||||
|
DadosConsulta={consulta}
|
||||||
|
className={`usuario-${consulta.cor || "default"}`}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
{dias.terca.length > 3 ?
|
||||||
|
<div><p>+ {dias.terca.length - 3}</p></div>
|
||||||
|
: null}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<div>
|
||||||
|
{quartas[index]}
|
||||||
|
<div>
|
||||||
|
{dias.quarta.slice(0,4).map((consulta, idx) => (
|
||||||
|
<CardConsulta
|
||||||
|
key={idx}
|
||||||
|
DadosConsulta={consulta}
|
||||||
|
className={`usuario-${consulta.cor || "default"}`}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
{dias.quarta.length > 3 ?
|
||||||
|
<div><p>+ {dias.quarta.length - 3}</p></div>
|
||||||
|
: null}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<div>
|
||||||
|
{quintas[index]}
|
||||||
|
<div>
|
||||||
|
{dias.quinta.slice(0,4).map((consulta, idx) => (
|
||||||
|
<CardConsulta
|
||||||
|
key={idx}
|
||||||
|
DadosConsulta={consulta}
|
||||||
|
className={`usuario-${consulta.cor || "default"}`}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
{dias.quinta.length > 3 ?
|
||||||
|
<div><p>+ {dias.quinta.length - 3}</p></div>
|
||||||
|
: null}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<div>
|
||||||
|
{sextas[index]}
|
||||||
|
<div>
|
||||||
|
{dias.sexta.slice(0,4).map((consulta, idx) => (
|
||||||
|
<CardConsulta
|
||||||
|
key={idx}
|
||||||
|
DadosConsulta={consulta}
|
||||||
|
className={`usuario-${consulta.cor || "default"}`}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
{dias.sexta.length > 3 ?
|
||||||
|
<div><p>+ {dias.sexta.length - 3}</p></div>
|
||||||
|
: null}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TabelaAgendamentoMes
|
||||||
54
src/components/AgendarConsulta/TabelaAgendamentoSemana.jsx
Normal file
54
src/components/AgendarConsulta/TabelaAgendamentoSemana.jsx
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import AgendamentosMes from './DadosConsultasMock'
|
||||||
|
import CardConsulta from './CardConsulta'
|
||||||
|
import "./style/styleTabelas/tabelasemana.css";
|
||||||
|
|
||||||
|
const TabelaAgendamentoSemana = () => {
|
||||||
|
|
||||||
|
let AgendamentosDesseMes = AgendamentosMes
|
||||||
|
|
||||||
|
let AgendamentoSemana = AgendamentosDesseMes.semana1
|
||||||
|
|
||||||
|
|
||||||
|
let AgendamentosdeSegunda = AgendamentoSemana.segunda
|
||||||
|
let AgendamentosdeTerca = AgendamentoSemana.terca
|
||||||
|
let AgendamentosdeQuarta = AgendamentoSemana.quarta
|
||||||
|
let AgendamentosdeQuinta = AgendamentoSemana.quinta
|
||||||
|
let AgendamentosdeSexta = AgendamentoSemana.sexta
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div >
|
||||||
|
|
||||||
|
<table className='tabelasemanal'>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<th>Segunda</th>
|
||||||
|
<th>Terça</th>
|
||||||
|
<th>Quarta</th>
|
||||||
|
<th>Quinta</th>
|
||||||
|
<th>Sexta</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
|
{AgendamentosdeSegunda.map((consulta, index) => (
|
||||||
|
|
||||||
|
<tr key={index}>
|
||||||
|
<td>{consulta.horario}</td>
|
||||||
|
<td className='coluna-tipo1'> <CardConsulta DadosConsulta={AgendamentosdeSegunda[index]} /> </td>
|
||||||
|
<td> <CardConsulta DadosConsulta={AgendamentosdeTerca[index]} /> </td>
|
||||||
|
<td> <CardConsulta DadosConsulta={AgendamentosdeQuarta[index]} /> </td>
|
||||||
|
<td><CardConsulta DadosConsulta={AgendamentosdeQuinta[index]} /></td>
|
||||||
|
<td><CardConsulta DadosConsulta={AgendamentosdeSexta[index]} /></td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
|
||||||
|
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TabelaAgendamentoSemana
|
||||||
@ -0,0 +1,80 @@
|
|||||||
|
.tabeladiaria {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin: 2rem 0;
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: hidden; /* mantém o arredondado */
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||||
|
border: 4px solid #4a90e2; /* borda azul, altere para a cor desejada */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Células da tabela */
|
||||||
|
.tabeladiaria th, .tabeladiaria td {
|
||||||
|
padding: 9px;
|
||||||
|
text-align: left;
|
||||||
|
border: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cabeçalho */
|
||||||
|
.tabeladiaria thead th {
|
||||||
|
background-color: #0078d7;
|
||||||
|
color: #ffffff;
|
||||||
|
font-weight: 600;
|
||||||
|
border-bottom: 2px solid #005a9e; /* borda inferior mais forte no cabeçalho */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remover bordas laterais do cabeçalho (se quiser) */
|
||||||
|
.tabeladiaria thead th:first-child {
|
||||||
|
border-left: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabeladiaria thead th:last-child {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Linhas pares do corpo */
|
||||||
|
.tabeladiaria tbody tr:nth-child(even) {
|
||||||
|
background-color: #e7e7e7a6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hover nas linhas */
|
||||||
|
.tabeladiaria tbody tr:hover {
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Card dentro da tabela */
|
||||||
|
.tabeladiaria .cardconsulta {
|
||||||
|
border-radius: 10px;
|
||||||
|
color: black;
|
||||||
|
height: 80px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ajuste para a classe .diadia, se for usada */
|
||||||
|
.diadia {
|
||||||
|
margin-top: 20px;
|
||||||
|
border-collapse: collapse;
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 4px 12px rgb(255, 255, 255);
|
||||||
|
border: 10px solid #ffffffc5;
|
||||||
|
background-color: rgb(253, 253, 253);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.mostrar-horario td, .mostrar-horario th {
|
||||||
|
padding: 4px 6px;
|
||||||
|
height: 30px;
|
||||||
|
border: 1px solid #e0e0e0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container-cardconsulta-dia {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: flex-start;
|
||||||
|
height: 70px;
|
||||||
|
}
|
||||||
150
src/components/AgendarConsulta/style/styleTabelas/tabelames.css
Normal file
150
src/components/AgendarConsulta/style/styleTabelas/tabelames.css
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
.tabelamensal {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin: 2rem 0;
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: hidden; /* mantém o arredondado */
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||||
|
border: 4px solid #4a90e2; /* borda azul, altere para a cor desejada */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Células da tabela */
|
||||||
|
.tabelamensal th, .tabelamensal td {
|
||||||
|
padding: 9px;
|
||||||
|
text-align: left;
|
||||||
|
border: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cabeçalho */
|
||||||
|
.tabelamensal thead th {
|
||||||
|
background-color: #0078d7;
|
||||||
|
color: #0078d7;
|
||||||
|
font-weight: 600;
|
||||||
|
border-bottom: 2px solid #0078d7; /* borda inferior mais forte no cabeçalho */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remover bordas laterais do cabeçalho (se quiser) */
|
||||||
|
.tabelamensal thead th:first-child {
|
||||||
|
border-left: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabelamensal thead th:last-child {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Linhas pares do corpo */
|
||||||
|
.tabelamensal tbody tr:nth-child(even) {
|
||||||
|
background-color: #e7e7e7a6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hover nas linhas */
|
||||||
|
.tabelamensal tbody tr:hover {
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Card dentro da tabela */
|
||||||
|
.tabelamensal .cardconsulta {
|
||||||
|
border-radius: 10px;
|
||||||
|
color: black;
|
||||||
|
height: 80px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ajuste para a classe .diadia, se for usada */
|
||||||
|
.diadia {
|
||||||
|
margin-top: 20px;
|
||||||
|
border-collapse: collapse;
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 4px 12px rgb(255, 255, 255);
|
||||||
|
border: 10px solid #ffffffc5;
|
||||||
|
background-color: rgb(253, 253, 253);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabelamensal {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin: 2rem 0;
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: hidden; /* mantém o arredondado */
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||||
|
border: 4px solid #4a90e2; /* borda azul, altere para a cor desejada */
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabelamensal th, .tabelamensal td {
|
||||||
|
padding: 9px;
|
||||||
|
text-align: left;
|
||||||
|
border: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabelamensal th {
|
||||||
|
background-color: #0078d7;
|
||||||
|
color: #ffffff;
|
||||||
|
font-weight: 600;
|
||||||
|
border-bottom: 2px solid #005a9e; /* borda inferior mais forte no cabeçalho */
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabelamensal td {
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabelamensal td:hover {
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Estilo geral do card de consulta */
|
||||||
|
.tabelamensal .cardconsulta {
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 6px;
|
||||||
|
margin: 4px 0;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-weight: 500;
|
||||||
|
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
||||||
|
border-left: 5px solid transparent; /* espaço da borda colorida */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.usuario-azul {
|
||||||
|
background-color: #E3F2FD;
|
||||||
|
border-left: 4px solid #2196F3;
|
||||||
|
padding: 4px 8px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.usuario-verde {
|
||||||
|
background-color: #E8F5E9;
|
||||||
|
border-left: 4px solid #4CAF50;
|
||||||
|
padding: 4px 8px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.usuario-roxo {
|
||||||
|
background-color: #F3E5F5;
|
||||||
|
border-left: 4px solid #9C27B0;
|
||||||
|
padding: 4px 8px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.usuario-laranja {
|
||||||
|
background-color: #FFF3E0;
|
||||||
|
border-left: 4px solid #FF9800;
|
||||||
|
padding: 4px 8px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.usuario-default {
|
||||||
|
background-color: #FAFAFA;
|
||||||
|
border-left: 4px solid #BDBDBD;
|
||||||
|
padding: 4px 8px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
@ -0,0 +1,82 @@
|
|||||||
|
.tabelasemanal {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin: 2rem 0;
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: hidden; /* mantém o arredondado */
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||||
|
border: 4px solid #4a90e2; /* borda azul, altere para a cor desejada */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Células da tabela */
|
||||||
|
.tabelasemanal th, .tabelasemanal td {
|
||||||
|
padding: 9px;
|
||||||
|
text-align: left;
|
||||||
|
border: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cabeçalho da semanal */
|
||||||
|
.tabelasemanal thead th,
|
||||||
|
.tabelasemanal thead td,
|
||||||
|
.tabelasemanal tr:first-child th,
|
||||||
|
.tabelasemanal tr:first-child td {
|
||||||
|
background-color: #0078d7 !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
font-weight: 600;
|
||||||
|
text-align: center;
|
||||||
|
border-bottom: 2px solid #005a9e;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Remover bordas laterais do cabeçalho (se quiser) */
|
||||||
|
.tabelasemanal thead th:first-child {
|
||||||
|
border-left: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabelasemanal thead th:last-child {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Linhas pares do corpo */
|
||||||
|
.tabelasemanal tbody tr:nth-child(even) {
|
||||||
|
background-color: #e7e7e7a6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hover nas linhas */
|
||||||
|
.tabelasemanal tbody tr:hover {
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Card dentro da tabela */
|
||||||
|
.tabelasemanal .cardconsulta {
|
||||||
|
border-radius: 10px;
|
||||||
|
color: black;
|
||||||
|
height: 80px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ajuste para a classe .diadia, se for usada */
|
||||||
|
.diadia {
|
||||||
|
margin-top: 20px;
|
||||||
|
border-collapse: collapse;
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 4px 12px rgb(255, 255, 255);
|
||||||
|
border: 10px solid #ffffffc5;
|
||||||
|
background-color: rgb(253, 253, 253);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabelasemanal tr:nth-child(even) {
|
||||||
|
background-color: #e7e7e7a6 !important;
|
||||||
|
margin-left: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabelasemanal tr:nth-child(odd) {
|
||||||
|
background-color: #ffffff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabelasemanal tr:hover {
|
||||||
|
background-color: #f1f1f1 !important;
|
||||||
|
}
|
||||||
108
src/components/AgendarConsulta/style/styleagendamentos.css
Normal file
108
src/components/AgendarConsulta/style/styleagendamentos.css
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
.form-container {
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 20px auto;
|
||||||
|
padding: 25px;
|
||||||
|
background: #f5f8ff;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-title {
|
||||||
|
font-size: 26px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #1e3a8a;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-agendamento label {
|
||||||
|
display: block;
|
||||||
|
margin-top: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-agendamento input,
|
||||||
|
.form-agendamento select,
|
||||||
|
.form-agendamento textarea {
|
||||||
|
width: 100%;
|
||||||
|
padding: 8px;
|
||||||
|
margin-top: 6px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 20px;
|
||||||
|
margin-top: 25px;
|
||||||
|
color: #1e40af;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-subtitle {
|
||||||
|
font-size: 16px;
|
||||||
|
margin-top: 20px;
|
||||||
|
color: #374151;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group button {
|
||||||
|
margin-right: 8px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
border: 1px solid #1e3a8a;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group button:hover {
|
||||||
|
background: #e0e7ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-actions {
|
||||||
|
margin-top: 25px;
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background: #1e3a8a;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 18px;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
background: #172554;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-cancel {
|
||||||
|
background: #e5e7eb;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 18px;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-cancel:hover {
|
||||||
|
background: #d1d5db;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary {
|
||||||
|
margin: 10px 0;
|
||||||
|
background: #f3f4f6;
|
||||||
|
padding: 8px 14px;
|
||||||
|
border: 1px solid #9ca3af;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary:hover {
|
||||||
|
background: #e5e7eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.cardconsulta-infosecundaria{
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
// O componente agora recebe a função `toggleSidebar` como uma prop.
|
|
||||||
function Header({ toggleSidebar }) {
|
|
||||||
return (
|
|
||||||
<header className="mb-3">
|
|
||||||
<a href="#" className="burger-btn d-block d-xl-none" onClick={toggleSidebar}>
|
|
||||||
<i className="bi bi-justify fs-3"></i>
|
|
||||||
</a>
|
|
||||||
</header>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Header;
|
|
||||||
@ -31,16 +31,15 @@ function DoctorForm({ onSave, onCancel, PatientDict }) {
|
|||||||
|
|
||||||
|
|
||||||
const [formData, setFormData] = useState({
|
const [formData, setFormData] = useState({
|
||||||
|
foto: null,
|
||||||
nome: PatientDict.nome,
|
nome: PatientDict.nome,
|
||||||
nomeSocial: PatientDict.nome_social,
|
nomeSocial: PatientDict.nome_social,
|
||||||
dataNascimento: PatientDict.data_nascimento,
|
dataNascimento: PatientDict.data_nascimento,
|
||||||
genero: PatientDict.sexo,
|
genero: PatientDict.sexo,
|
||||||
//documento: '',
|
|
||||||
//numeroDocumento: '',
|
|
||||||
cpf: PatientDict.cpf,
|
cpf: PatientDict.cpf,
|
||||||
profissao: PatientDict.profissao ,
|
profissao: PatientDict.profissao ,
|
||||||
//nomeConjuge: '',
|
nomeConjuge: '',
|
||||||
//outroId: '',
|
outroId: '',
|
||||||
cep: '',
|
cep: '',
|
||||||
cidade: PatientDict.cidade,
|
cidade: PatientDict.cidade,
|
||||||
estado: PatientDict.estado,
|
estado: PatientDict.estado,
|
||||||
@ -52,41 +51,77 @@ function DoctorForm({ onSave, onCancel, PatientDict }) {
|
|||||||
telefone1: PatientDict.celular,
|
telefone1: PatientDict.celular,
|
||||||
telefone2: '',
|
telefone2: '',
|
||||||
telefone3: '',
|
telefone3: '',
|
||||||
observacoes: ''
|
observacoes: '',
|
||||||
|
rg: '',
|
||||||
|
documentoTipo: '',
|
||||||
|
numeroDocumento: '',
|
||||||
|
etniaRaca: '',
|
||||||
|
naturalidade: '',
|
||||||
|
nacionalidade: '',
|
||||||
|
estadoCivil: '',
|
||||||
|
|
||||||
|
// INFORMAÇÕES MÉDICAS
|
||||||
|
tipoSanguineo: '',
|
||||||
|
peso: '',
|
||||||
|
altura: '',
|
||||||
|
imc: '',
|
||||||
|
alergias: '',
|
||||||
|
|
||||||
|
// ANEXO
|
||||||
|
anexos: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleChange = (e) => {
|
// Estado para armazenar a URL da foto do avatar
|
||||||
const { name, value } = e.target;
|
const [avatarUrl, setAvatarUrl] = useState(null);
|
||||||
setFormData({
|
|
||||||
...formData,
|
// Estado para controlar quais seções estão colapsadas
|
||||||
[name]: value
|
const [collapsedSections, setCollapsedSections] = useState({
|
||||||
|
dadosPessoais: true, // Alterado para true para a seção ficar aberta por padrão
|
||||||
|
infoMedicas: false,
|
||||||
|
infoConvenio: false,
|
||||||
|
endereco: false,
|
||||||
|
contato: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Função para alternar o estado de colapso de uma seção
|
||||||
if(name.includes('cpf')){
|
const handleToggleCollapse = (section) => {
|
||||||
|
setCollapsedSections(prevState => ({
|
||||||
let cpfFormatado = FormatCPF(e.target.value)
|
...prevState,
|
||||||
|
[section]: !prevState[section]
|
||||||
setFormData({...formData,
|
}));
|
||||||
[name]: cpfFormatado,}
|
|
||||||
)}
|
|
||||||
|
|
||||||
else if(name.includes('telefone')){
|
|
||||||
let telefoneFormatado = FormatTelefones(value)
|
|
||||||
|
|
||||||
console.log(telefoneFormatado)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
setFormData({...formData,
|
|
||||||
[name]: telefoneFormatado
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleChange = (e) => {
|
||||||
|
const { name, value, type, checked, files } = e.target;
|
||||||
|
|
||||||
|
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 = () => {
|
||||||
|
setAvatarUrl(reader.result);
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(files[0]);
|
||||||
|
} else if (name === 'foto' && !files[0]) {
|
||||||
|
setAvatarUrl(null); // Limpa o avatar se nenhum arquivo for selecionado
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
setFormData({ ...formData, [name]: value });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name.includes('cpf')) {
|
||||||
|
let cpfFormatado = FormatCPF(value);
|
||||||
|
setFormData(prev => ({ ...prev, [name]: cpfFormatado }));
|
||||||
|
} else if (name.includes('telefone')) {
|
||||||
|
let telefoneFormatado = FormatTelefones(value);
|
||||||
|
setFormData(prev => ({ ...prev, [name]: telefoneFormatado }));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Função para buscar endereço pelo CEP
|
// Função para buscar endereço pelo CEP
|
||||||
const handleCepBlur = async () => {
|
const handleCepBlur = async () => {
|
||||||
@ -114,20 +149,13 @@ function DoctorForm({ onSave, onCancel, PatientDict }) {
|
|||||||
|
|
||||||
const handleSubmit = () => {
|
const handleSubmit = () => {
|
||||||
if (!formData.nome || !formData.cpf || !formData.genero || !formData.dataNascimento || !formData.email) {
|
if (!formData.nome || !formData.cpf || !formData.genero || !formData.dataNascimento || !formData.email) {
|
||||||
alert('Por favor, preencha: Nome ,CPF, Gênero, Data de nascimento e Email.');
|
alert('Por favor, preencha: Nome ,CPF, Gênero, Data de Nascimento e Email.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
onSave(
|
onSave(
|
||||||
{nome: formData.nome,
|
{
|
||||||
nomeSocial: formData.nomeSocial,
|
...formData,
|
||||||
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: {
|
endereco: {
|
||||||
cep: formData.cep,
|
cep: formData.cep,
|
||||||
cidade: formData.cidade,
|
cidade: formData.cidade,
|
||||||
@ -137,72 +165,146 @@ function DoctorForm({ onSave, onCancel, PatientDict }) {
|
|||||||
numero: formData.numero,
|
numero: formData.numero,
|
||||||
complemento: formData.complemento,
|
complemento: formData.complemento,
|
||||||
},
|
},
|
||||||
|
|
||||||
contato: {
|
contato: {
|
||||||
email: formData.email,
|
email: formData.email,
|
||||||
telefone1: formData.telefone1,
|
telefone1: formData.telefone1,
|
||||||
telefone2: formData.telefone2,
|
telefone2: formData.telefone2,
|
||||||
telefone3: formData.telefone3,
|
telefone3: formData.telefone3,
|
||||||
},
|
},
|
||||||
|
infoMedicas: {
|
||||||
observacoes: formData.observacoes,
|
tipoSanguineo: formData.tipoSanguineo,
|
||||||
|
peso: formData.peso,
|
||||||
|
altura: formData.altura,
|
||||||
|
imc: formData.imc,
|
||||||
|
alergias: formData.alergias,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="card p-3">
|
<div className="card p-3 shadow-sm">
|
||||||
<h3 className="mb-3 text-center">MediConnect</h3>
|
<h3 className="mb-4 text-center" style={{ fontSize: '2.5rem' }}>MediConnect</h3>
|
||||||
|
|
||||||
{/* ------------------ DADOS PESSOAIS ------------------ */}
|
{/* DADOS PESSOAIS */}
|
||||||
<h5 className="mb-3">Dados Pessoais</h5>
|
<div className="mb-5 p-4 border rounded shadow-sm">
|
||||||
<div className="row">
|
<h4 className="mb-4 cursor-pointer d-flex justify-content-between align-items-center" onClick={() => handleToggleCollapse('dadosPessoais')} style={{ fontSize: '1.8rem' }}>
|
||||||
|
Dados Pessoais
|
||||||
|
<span className="fs-5">
|
||||||
|
{collapsedSections.dadosPessoais ? '▲' : '▼'}
|
||||||
|
</span>
|
||||||
|
</h4>
|
||||||
|
<div className={`collapse${collapsedSections.dadosPessoais ? ' show' : ''}`}>
|
||||||
|
<div className="row mt-3">
|
||||||
|
{/* AVATAR E INPUT DE FOTO */}
|
||||||
|
<div className="col-md-6 mb-3 d-flex align-items-center">
|
||||||
|
<div className="me-3">
|
||||||
|
{avatarUrl ? (
|
||||||
|
<img
|
||||||
|
src={avatarUrl}
|
||||||
|
alt="Avatar do Médico"
|
||||||
|
style={{ width: '100px', height: '100px', borderRadius: '50%', objectFit: 'cover' }}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
width: '100px',
|
||||||
|
height: '100px',
|
||||||
|
borderRadius: '50%',
|
||||||
|
backgroundColor: '#e0e0e0',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
fontSize: '3.5rem',
|
||||||
|
color: '#9e9e9e'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
☤
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label htmlFor="foto-input" className="btn btn-primary" style={{ fontSize: '1rem' }}>Carregar Foto</label>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
className="form-control d-none"
|
||||||
|
name="foto"
|
||||||
|
id="foto-input"
|
||||||
|
onChange={handleChange}
|
||||||
|
accept="image/*"
|
||||||
|
/>
|
||||||
|
{formData.foto && <span className="ms-2" style={{ fontSize: '1rem' }}>{formData.foto.name}</span>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* CADASTRO */}
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Nome: *</label>
|
<label style={{ fontSize: '1.1rem' }}>Nome: *</label>
|
||||||
<input type="text" className="form-control" name="nome" value={formData.nome} onChange={handleChange} />
|
<input type="text" className="form-control" name="nome" value={formData.nome} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Nome social:</label>
|
<label style={{ fontSize: '1.1rem' }}>Nome social:</label>
|
||||||
<input type="text" className="form-control" name="nomeSocial" value={formData.nomeSocial} onChange={handleChange} />
|
<input type="text" className="form-control" name="nomeSocial" value={formData.nomeSocial} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Data de nascimento:</label>
|
<label style={{ fontSize: '1.1rem' }}>Data de nascimento: *</label>
|
||||||
<input type="date" className="form-control" name="dataNascimento" value={formData.dataNascimento} onChange={handleChange} />
|
<input type="date" className="form-control" name="dataNascimento" value={formData.dataNascimento} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Gênero: *</label>
|
<label style={{ fontSize: '1.1rem' }}>Gênero: *</label>
|
||||||
<select className="form-control" name="genero" value={formData.genero} onChange={handleChange}>
|
<select className="form-control" name="genero" value={formData.genero} onChange={handleChange} style={{ fontSize: '1.1rem' }}>
|
||||||
<option value="">Selecione</option>
|
<option value="">Selecione</option>
|
||||||
<option value="Masculino">Masculino</option>
|
<option value="Masculino">Masculino</option>
|
||||||
<option value="Feminino">Feminino</option>
|
<option value="Feminino">Feminino</option>
|
||||||
<option value="Outro">Outro</option>
|
<option value="Outro">Outro</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
{/*
|
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Outro documento:</label>
|
<label style={{ fontSize: '1.1rem' }}>Identificador de outro sistema:</label>
|
||||||
<input type="text" className="form-control" name="documento" value={formData.documento} onChange={handleChange} />
|
<input type="text" className="form-control" name="outroId" value={formData.outroId} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Número do documento:</label>
|
<label style={{ fontSize: '1.1rem' }}>CPF: *</label>
|
||||||
<input type="text" className="form-control" name="numeroDocumento" value={formData.numeroDocumento} onChange={handleChange} />
|
<input type="text" className="form-control" name="cpf" value={formData.cpf} onChange={ handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
|
||||||
*/}
|
|
||||||
<div className="col-md-6 mb-3">
|
|
||||||
<label>CPF: *</label>
|
|
||||||
<input type="text" className="form-control" name="cpf" value={formData.cpf} onChange={ handleChange} />
|
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Especialização:</label>
|
<label style={{ fontSize: '1.1rem' }}>RG:</label>
|
||||||
<select
|
<input type="text" className="form-control" name="rg" value={formData.rg} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
className="form-control"
|
</div>
|
||||||
name="profissao"
|
<div className="col-md-6 mb-3">
|
||||||
value={formData.profissao}
|
<label style={{ fontSize: '1.1rem' }}>Outros documentos:</label>
|
||||||
onChange={handleChange}
|
<select className="form-control" name="documentoTipo" value={formData.documentoTipo} onChange={handleChange} style={{ fontSize: '1.1rem' }}>
|
||||||
>
|
<option value="">Selecione</option>
|
||||||
<option value="">Selecione uma especialização</option>
|
<option value="CNH">CNH</option>
|
||||||
|
<option value="Passaporte">Passaporte</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label style={{ fontSize: '1.1rem' }}>Número do documento:</label>
|
||||||
|
<input type="text" className="form-control" name="numeroDocumento" value={formData.numeroDocumento} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label style={{ fontSize: '1.1rem' }}>Etnia e Raça:</label>
|
||||||
|
<select className="form-control" name="etniaRaca" value={formData.etniaRaca} onChange={handleChange} style={{ fontSize: '1.1rem' }}>
|
||||||
|
<option value="">Selecione</option>
|
||||||
|
<option value="Branca">Branca</option>
|
||||||
|
<option value="Preta">Preta</option>
|
||||||
|
<option value="Parda">Parda</option>
|
||||||
|
<option value="Amarela">Amarela</option>
|
||||||
|
<option value="Indígena">Indígena</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label style={{ fontSize: '1.1rem' }}>Naturalidade:</label>
|
||||||
|
<input type="text" className="form-control" name="naturalidade" value={formData.naturalidade} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label style={{ fontSize: '1.1rem' }}>Nacionalidade:</label>
|
||||||
|
<input type="text" className="form-control" name="nacionalidade" value={formData.nacionalidade} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label style={{ fontSize: '1.1rem' }}>Especialização:</label>
|
||||||
|
<select className="form-control" name="profissao" value={formData.profissao} onChange={handleChange} style={{ fontSize: '1.1rem' }}>
|
||||||
|
<option value="">Selecione</option>
|
||||||
<option value="Cardiologia">Clínica médica (clínico geral)</option>
|
<option value="Cardiologia">Clínica médica (clínico geral)</option>
|
||||||
<option value="Dermatologia">Pediatria</option>
|
<option value="Dermatologia">Pediatria</option>
|
||||||
<option value="Ginecologia">Ginecologia e obstetrícia</option>
|
<option value="Ginecologia">Ginecologia e obstetrícia</option>
|
||||||
@ -216,93 +318,251 @@ function DoctorForm({ onSave, onCancel, PatientDict }) {
|
|||||||
<option value="Oncologia">Endocrinologia</option>
|
<option value="Oncologia">Endocrinologia</option>
|
||||||
<option value="Oncologia">Gastroenterologia</option>
|
<option value="Oncologia">Gastroenterologia</option>
|
||||||
<option value="Oncologia">Urologia</option>
|
<option value="Oncologia">Urologia</option>
|
||||||
|
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
</div>
|
|
||||||
{/*
|
|
||||||
<div className="col-md-6 mb-3">
|
|
||||||
<label>Nome do esposo(a):</label>
|
|
||||||
<input type="text" className="form-control" name="nomeConjuge" value={formData.nomeConjuge} onChange={handleChange} />
|
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Identificador de outro sistema:</label>
|
<label style={{ fontSize: '1.1rem' }}>Estado civil:</label>
|
||||||
<input type="text" className="form-control" name="outroId" value={formData.outroId} onChange={handleChange} />
|
<select className="form-control" name="estadoCivil" value={formData.estadoCivil} onChange={handleChange} style={{ fontSize: '1.1rem' }}>
|
||||||
|
<option value="">Selecione</option>
|
||||||
|
<option value="Solteiro">Solteiro(a)</option>
|
||||||
|
<option value="Casado">Casado(a)</option>
|
||||||
|
<option value="Divorciado">Divorciado(a)</option>
|
||||||
|
<option value="Viuvo">Viúvo(a)</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
*/}
|
<div className="col-md-6 mb-3">
|
||||||
|
<label style={{ fontSize: '1.1rem' }}>Nome do esposo(a):</label>
|
||||||
|
<input type="text" className="form-control" name="nomeConjuge" value={formData.nomeConjuge} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ------------------ ENDEREÇO ------------------ */}
|
{/* CAMPOS MOVIDOS */}
|
||||||
<h5>Endereço</h5>
|
<div className="col-md-12 mb-3 mt-3">
|
||||||
<div className="row">
|
<label style={{ fontSize: '1.1rem' }}>Observações:</label>
|
||||||
|
<textarea className="form-control" name="observacoes" value={formData.observacoes} onChange={handleChange} style={{ fontSize: '1.1rem' }}></textarea>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-12 mb-3">
|
||||||
|
<label style={{ fontSize: '1.1rem' }}>Anexos do Médico:</label>
|
||||||
|
<div>
|
||||||
|
<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} />
|
||||||
|
<span className="ms-2" style={{ fontSize: '1.1rem' }}>{formData.anexos ? formData.anexos.name : 'Nenhum arquivo escolhido'}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* ENDEREÇO */}
|
||||||
|
<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' }}>
|
||||||
|
Endereço
|
||||||
|
<span className="fs-5">
|
||||||
|
{collapsedSections.endereco ? '▲' : '▼'}
|
||||||
|
</span>
|
||||||
|
</h4>
|
||||||
|
<div className={`collapse${collapsedSections.endereco ? ' show' : ''}`}>
|
||||||
|
<div className="row mt-3">
|
||||||
<div className="col-md-4 mb-3">
|
<div className="col-md-4 mb-3">
|
||||||
<label>CEP:</label>
|
<label style={{ fontSize: '1.1rem' }}>CEP:</label>
|
||||||
<input type="text" className="form-control" name="cep" value={formData.cep} onChange={handleChange} onBlur={handleCepBlur} />
|
<input type="text" className="form-control" name="cep" value={formData.cep} onChange={handleChange} onBlur={handleCepBlur} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-8 mb-3">
|
<div className="col-md-8 mb-3">
|
||||||
<label>Rua:</label>
|
<label style={{ fontSize: '1.1rem' }}>Rua:</label>
|
||||||
<input type="text" className="form-control" name="rua" value={formData.rua} onChange={handleChange} />
|
<input type="text" className="form-control" name="rua" value={formData.rua} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Bairro:</label>
|
<label style={{ fontSize: '1.1rem' }}>Bairro:</label>
|
||||||
<input type="text" className="form-control" name="bairro" value={formData.bairro} onChange={handleChange} />
|
<input type="text" className="form-control" name="bairro" value={formData.bairro} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-4 mb-3">
|
<div className="col-md-4 mb-3">
|
||||||
<label>Cidade:</label>
|
<label style={{ fontSize: '1.1rem' }}>Cidade:</label>
|
||||||
<input type="text" className="form-control" name="cidade" value={formData.cidade} onChange={handleChange} />
|
<input type="text" className="form-control" name="cidade" value={formData.cidade} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-2 mb-3">
|
<div className="col-md-2 mb-3">
|
||||||
<label>Estado:</label>
|
<label style={{ fontSize: '1.1rem' }}>Estado:</label>
|
||||||
<input type="text" className="form-control" name="estado" value={formData.estado} onChange={handleChange} />
|
<input type="text" className="form-control" name="estado" value={formData.estado} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-4 mb-3">
|
<div className="col-md-4 mb-3">
|
||||||
<label>Número:</label>
|
<label style={{ fontSize: '1.1rem' }}>Número:</label>
|
||||||
<input type="text" className="form-control" name="numero" value={formData.numero} onChange={handleChange} />
|
<input type="text" className="form-control" name="numero" value={formData.numero} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-8 mb-3">
|
<div className="col-md-8 mb-3">
|
||||||
<label>Complemento:</label>
|
<label style={{ fontSize: '1.1rem' }}>Complemento:</label>
|
||||||
<input type="text" className="form-control" name="complemento" value={formData.complemento} onChange={handleChange} />
|
<input type="text" className="form-control" name="complemento" value={formData.complemento} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ------------------ CONTATO ------------------ */}
|
{/* CONTATO */}
|
||||||
<h5>Contato</h5>
|
<div className="mb-5 p-4 border rounded shadow-sm">
|
||||||
<div className="row">
|
<h4 className="mb-4 cursor-pointer d-flex justify-content-between align-items-center" onClick={() => handleToggleCollapse('contato')} style={{ fontSize: '1.8rem' }}>
|
||||||
|
Contato
|
||||||
|
<span className="fs-5">
|
||||||
|
{collapsedSections.contato ? '▲' : '▼'}
|
||||||
|
</span>
|
||||||
|
</h4>
|
||||||
|
<div className={`collapse${collapsedSections.contato ? ' show' : ''}`}>
|
||||||
|
<div className="row mt-3">
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>E-mail: *</label>
|
<label style={{ fontSize: '1.1rem' }}>Email: *</label>
|
||||||
<input type="email" className="form-control" name="email" value={formData.email} onChange={handleChange} />
|
<input type="email" className="form-control" name="email" value={formData.email} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Telefone: *</label>
|
<label style={{ fontSize: '1.1rem' }}>Telefone: *</label>
|
||||||
<input type="text" className="form-control" name="telefone1" value={formData.telefone1} onChange={handleChange} />
|
<input type="text" className="form-control" name="telefone1" value={formData.telefone1} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Telefone 2:</label>
|
<label style={{ fontSize: '1.1rem' }}>Telefone 2:</label>
|
||||||
<input type="text" className="form-control" name="telefone2" value={formData.telefone2} onChange={handleChange} />
|
<input type="text" className="form-control" name="telefone2" value={formData.telefone2} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Telefone 3:</label>
|
<label style={{ fontSize: '1.1rem' }}>Celular:</label>
|
||||||
<input type="text" className="form-control" name="telefone3" value={formData.telefone3} onChange={handleChange} />
|
<input type="text" className="form-control" name="telefone3" value={formData.telefone3} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ------------------ INFORMAÇÕES ADICIONAIS ------------------ */}
|
|
||||||
<h5>Informações Adicionais</h5>
|
|
||||||
<div className="mb-3">
|
|
||||||
<label>Observações:</label>
|
|
||||||
<textarea className="form-control" name="observacoes" value={formData.observacoes} onChange={handleChange}></textarea>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Botões */}
|
{/* Botões */}
|
||||||
<div className="mt-3">
|
<div className="mt-3 text-center">
|
||||||
<button className="btn btn-success me-2" onClick={handleSubmit}>
|
<button className="btn btn-success me-3" onClick={handleSubmit} style={{ fontSize: '1.2rem', padding: '0.75rem 1.5rem' }}>
|
||||||
Salvar Paciente
|
Salvar Paciente
|
||||||
</button>
|
</button>
|
||||||
<button className="btn btn-light" onClick={onCancel}>
|
<button className="btn btn-light" onClick={onCancel} style={{ fontSize: '1.2rem', padding: '0.75rem 1.5rem' }}>
|
||||||
Cancelar
|
Cancelar
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
// <div className="card p-3">
|
||||||
|
// <h3 className="mb-4 text-center" style={{ fontSize: '2.5rem' }}>MediConnect</h3>
|
||||||
|
|
||||||
|
// {/* ------------------ DADOS PESSOAIS ------------------ */}
|
||||||
|
// <h5 className="mb-3">Dados Pessoais</h5>
|
||||||
|
// <div className="row">
|
||||||
|
// <div className="col-md-6 mb-3">
|
||||||
|
// <label>Nome: *</label>
|
||||||
|
// <input type="text" className="form-control" name="nome" value={formData.nome} onChange={handleChange} />
|
||||||
|
// </div>
|
||||||
|
// <div className="col-md-6 mb-3">
|
||||||
|
// <label>Nome social:</label>
|
||||||
|
// <input type="text" className="form-control" name="nomeSocial" value={formData.nomeSocial} onChange={handleChange} />
|
||||||
|
// </div>
|
||||||
|
// <div className="col-md-6 mb-3">
|
||||||
|
// <label>Data de nascimento:</label>
|
||||||
|
// <input type="date" className="form-control" name="dataNascimento" value={formData.dataNascimento} onChange={handleChange} />
|
||||||
|
// </div>
|
||||||
|
// <div className="col-md-6 mb-3">
|
||||||
|
// <label>Gênero: *</label>
|
||||||
|
// <select className="form-control" name="genero" value={formData.genero} onChange={handleChange}>
|
||||||
|
// <option value="">Selecione</option>
|
||||||
|
// <option value="Masculino">Masculino</option>
|
||||||
|
// <option value="Feminino">Feminino</option>
|
||||||
|
// <option value="Outro">Outro</option>
|
||||||
|
// </select>
|
||||||
|
// </div>
|
||||||
|
// <div className="col-md-6 mb-3">
|
||||||
|
// <label>CPF: *</label>
|
||||||
|
// <input type="text" className="form-control" name="cpf" value={formData.cpf} onChange={ handleChange} />
|
||||||
|
// </div>
|
||||||
|
// <div className="col-md-6 mb-3">
|
||||||
|
// <label>Especialização:</label>
|
||||||
|
// <select
|
||||||
|
// className="form-control"
|
||||||
|
// name="profissao"
|
||||||
|
// value={formData.profissao}
|
||||||
|
// onChange={handleChange}
|
||||||
|
// >
|
||||||
|
// <option value="">Selecione uma especialização</option>
|
||||||
|
// <option value="Cardiologia">Clínica médica (clínico geral)</option>
|
||||||
|
// <option value="Dermatologia">Pediatria</option>
|
||||||
|
// <option value="Ginecologia">Ginecologia e obstetrícia</option>
|
||||||
|
// <option value="Pediatria">Cardiologia</option>
|
||||||
|
// <option value="Ortopedia">Ortopedia e traumatologia</option>
|
||||||
|
// <option value="Oftalmologia">Oftalmologia</option>
|
||||||
|
// <option value="Neurologia">Otorrinolaringologia</option>
|
||||||
|
// <option value="Psiquiatria">Dermatologia</option>
|
||||||
|
// <option value="Endocrinologia">Neurologia</option>
|
||||||
|
// <option value="Oncologia">Psiquiatria</option>
|
||||||
|
// <option value="Oncologia">Endocrinologia</option>
|
||||||
|
// <option value="Oncologia">Gastroenterologia</option>
|
||||||
|
// <option value="Oncologia">Urologia</option>
|
||||||
|
// </select>
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// {/* ------------------ ENDEREÇO ------------------ */}
|
||||||
|
// <h5>Endereço</h5>
|
||||||
|
// <div className="row">
|
||||||
|
// <div className="col-md-4 mb-3">
|
||||||
|
// <label>CEP:</label>
|
||||||
|
// <input type="text" className="form-control" name="cep" value={formData.cep} onChange={handleChange} onBlur={handleCepBlur} />
|
||||||
|
// </div>
|
||||||
|
// <div className="col-md-8 mb-3">
|
||||||
|
// <label>Rua:</label>
|
||||||
|
// <input type="text" className="form-control" name="rua" value={formData.rua} onChange={handleChange} />
|
||||||
|
// </div>
|
||||||
|
// <div className="col-md-6 mb-3">
|
||||||
|
// <label>Bairro:</label>
|
||||||
|
// <input type="text" className="form-control" name="bairro" value={formData.bairro} onChange={handleChange} />
|
||||||
|
// </div>
|
||||||
|
// <div className="col-md-4 mb-3">
|
||||||
|
// <label>Cidade:</label>
|
||||||
|
// <input type="text" className="form-control" name="cidade" value={formData.cidade} onChange={handleChange} />
|
||||||
|
// </div>
|
||||||
|
// <div className="col-md-2 mb-3">
|
||||||
|
// <label>Estado:</label>
|
||||||
|
// <input type="text" className="form-control" name="estado" value={formData.estado} onChange={handleChange} />
|
||||||
|
// </div>
|
||||||
|
// <div className="col-md-4 mb-3">
|
||||||
|
// <label>Número:</label>
|
||||||
|
// <input type="text" className="form-control" name="numero" value={formData.numero} onChange={handleChange} />
|
||||||
|
// </div>
|
||||||
|
// <div className="col-md-8 mb-3">
|
||||||
|
// <label>Complemento:</label>
|
||||||
|
// <input type="text" className="form-control" name="complemento" value={formData.complemento} onChange={handleChange} />
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// {/* ------------------ CONTATO ------------------ */}
|
||||||
|
// <h5>Contato</h5>
|
||||||
|
// <div className="row">
|
||||||
|
// <div className="col-md-6 mb-3">
|
||||||
|
// <label>E-mail: *</label>
|
||||||
|
// <input type="email" className="form-control" name="email" value={formData.email} onChange={handleChange} />
|
||||||
|
// </div>
|
||||||
|
// <div className="col-md-6 mb-3">
|
||||||
|
// <label>Telefone: *</label>
|
||||||
|
// <input type="text" className="form-control" name="telefone1" value={formData.telefone1} onChange={handleChange} />
|
||||||
|
// </div>
|
||||||
|
// <div className="col-md-6 mb-3">
|
||||||
|
// <label>Telefone 2:</label>
|
||||||
|
// <input type="text" className="form-control" name="telefone2" value={formData.telefone2} onChange={handleChange} />
|
||||||
|
// </div>
|
||||||
|
// <div className="col-md-6 mb-3">
|
||||||
|
// <label>Telefone 3:</label>
|
||||||
|
// <input type="text" className="form-control" name="telefone3" value={formData.telefone3} onChange={handleChange} />
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// {/* ------------------ INFORMAÇÕES ADICIONAIS ------------------ */}
|
||||||
|
// <h5>Informações Adicionais</h5>
|
||||||
|
// <div className="mb-3">
|
||||||
|
// <label>Observações:</label>
|
||||||
|
// <textarea className="form-control" name="observacoes" value={formData.observacoes} onChange={handleChange}></textarea>
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// {/* Botões */}
|
||||||
|
// <div className="mt-3">
|
||||||
|
// <button className="btn btn-success me-2" onClick={handleSubmit}>
|
||||||
|
// Salvar Paciente
|
||||||
|
// </button>
|
||||||
|
// <button className="btn btn-light" onClick={onCancel}>
|
||||||
|
// Cancelar
|
||||||
|
// </button>
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,108 +1,149 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import InputMask from "react-input-mask";
|
|
||||||
|
|
||||||
function PatientForm({ onSave, onCancel, PatientDict }) {
|
|
||||||
|
|
||||||
|
function PatientForm({ onSave, onCancel,formData, setFormData }) {
|
||||||
|
|
||||||
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') // 123 -> 123.
|
.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) =>{
|
||||||
|
var myHeaders = new Headers();
|
||||||
|
myHeaders.append("Authorization", "Bearer <token>");
|
||||||
|
myHeaders.append("Content-Type", "application/json");
|
||||||
|
|
||||||
const FormatCPF = (valor) => {
|
var raw = JSON.stringify({
|
||||||
|
"cpf": cpf
|
||||||
|
});
|
||||||
|
|
||||||
const digits = String(valor).replace(/\D/g, '').slice(0, 11);
|
var requestOptions = {
|
||||||
|
method: 'POST',
|
||||||
|
headers: myHeaders,
|
||||||
|
body: raw,
|
||||||
|
redirect: 'follow'
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await fetch("https://mock.apidog.com/m1/1053378-0-default/pacientes/validar-cpf", requestOptions)
|
||||||
|
const result = await response.json()
|
||||||
|
|
||||||
|
return result.data
|
||||||
|
|
||||||
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 ValidarCPF = async (cpf) => {
|
||||||
|
let aviso
|
||||||
|
let Erro = false
|
||||||
|
|
||||||
const [formData, setFormData] = useState({
|
const resutadoAPI = await ReceberRespostaAPIdoCPF(cpf)
|
||||||
nome: PatientDict.nome,
|
|
||||||
nomeSocial: PatientDict.nome_social,
|
const valido = resutadoAPI.valido
|
||||||
dataNascimento: PatientDict.data_nascimento,
|
const ExisteNoBancoDeDados = resutadoAPI.existe
|
||||||
genero: PatientDict.sexo,
|
|
||||||
documento: '',
|
if(valido === false){
|
||||||
numeroDocumento: '',
|
aviso = 'CPF inválido'
|
||||||
cpf: PatientDict.cpf,
|
Erro = true
|
||||||
profissao: PatientDict.profissao ,
|
}
|
||||||
nomeMae: PatientDict.nome_mae,
|
else if(ExisteNoBancoDeDados === true){
|
||||||
profissaoMae: PatientDict.profissao_mae,
|
aviso = 'O CPF informado já está presente no sistema'
|
||||||
nomePai: PatientDict.nome_pai,
|
Erro = true
|
||||||
profissaoPai: PatientDict.profissao_pai,
|
}
|
||||||
nomeResponsavel: '',
|
return [Erro,aviso]
|
||||||
cpfResponsavel: '',
|
}
|
||||||
nomeConjuge: '',
|
|
||||||
outroId: '',
|
const FormatCPF = (valor) => {
|
||||||
cep: '',
|
const digits = String(valor).replace(/\D/g, '').slice(0, 11);
|
||||||
cidade: PatientDict.cidade,
|
return digits
|
||||||
estado: PatientDict.estado,
|
.replace(/(\d{3})(\d)/, '$1.$2')
|
||||||
bairro: PatientDict.bairro,
|
.replace(/(\d{3})(\d)/, '$1.$2')
|
||||||
rua: PatientDict.logradouro,
|
.replace(/(\d{3})(\d{1,2})$/, '$1-$2');
|
||||||
numero: '',
|
}
|
||||||
complemento: '',
|
|
||||||
email: PatientDict.email,
|
|
||||||
telefone1: PatientDict.celular,
|
// Estado para armazenar a URL da foto do avatar
|
||||||
telefone2: '',
|
const [avatarUrl, setAvatarUrl] = useState(null);
|
||||||
telefone3: '',
|
|
||||||
observacoes: ''
|
// Estado para controlar quais seções estão colapsadas
|
||||||
|
const [collapsedSections, setCollapsedSections] = useState({
|
||||||
|
dadosPessoais: true, // Alterado para true para a seção ficar aberta por padrão
|
||||||
|
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,
|
||||||
|
[section]: !prevState[section]
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Lógica para calcular o IMC
|
||||||
|
useEffect(() => {
|
||||||
|
const peso = parseFloat(formData.peso);
|
||||||
|
const altura = parseFloat(formData.altura);
|
||||||
|
if (peso > 0 && altura > 0) {
|
||||||
|
const imcCalculado = peso / (altura * altura);
|
||||||
|
setFormData(prev => ({ ...prev, imc: imcCalculado.toFixed(2) }));
|
||||||
|
} else {
|
||||||
|
setFormData(prev => ({ ...prev, imc: '' }));
|
||||||
|
}
|
||||||
|
}, [formData.peso, formData.altura]);
|
||||||
|
|
||||||
|
|
||||||
|
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 handleChange = (e) => {
|
||||||
const { name, value } = e.target;
|
const { name, value, type, checked, files } = e.target;
|
||||||
setFormData({
|
|
||||||
...formData,
|
console.log(formData, name)
|
||||||
[name]: value
|
|
||||||
});
|
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 = () => {
|
||||||
|
setAvatarUrl(reader.result);
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(files[0]);
|
||||||
|
} else if (name === 'foto' && !files[0]) {
|
||||||
|
setAvatarUrl(null); // Limpa o avatar se nenhum arquivo for selecionado
|
||||||
|
}}
|
||||||
|
|
||||||
|
|
||||||
if (name.includes('cpf')) {
|
if (name.includes('cpf')) {
|
||||||
|
|
||||||
let cpfFormatado = FormatCPF(e.target.value)
|
setFormData({...formData, cpf:FormatCPF(value) });
|
||||||
|
|
||||||
setFormData({...formData,
|
} else if (name.includes('telefone')) {
|
||||||
[name]: cpfFormatado,}
|
let telefoneFormatado = FormatTelefones(value);
|
||||||
)}
|
setContato(prev => ({ ...prev, [name]: telefoneFormatado }));
|
||||||
|
}else if (name === 'email') {
|
||||||
else if(name.includes('telefone')){
|
setContato(prev => ({ ...prev, email: value }));
|
||||||
let telefoneFormatado = FormatTelefones(value)
|
}else if(name.includes('endereco')) {
|
||||||
|
setEnderecoData(prev => ({ ...prev, [name.split('.')[1]]: value }));
|
||||||
console.log(telefoneFormatado)
|
}else{
|
||||||
|
setFormData({ ...formData, [name]: value });
|
||||||
|
|
||||||
|
|
||||||
setFormData({...formData,
|
|
||||||
[name]: telefoneFormatado
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(name.includes('cep')){
|
|
||||||
const digitsCep = String(value).replace(/\D/g, '').slice(0, 8);
|
|
||||||
setFormData({...formData,
|
|
||||||
[name]: digitsCep
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Função para buscar endereço pelo CEP
|
|
||||||
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) {
|
||||||
@ -126,75 +167,125 @@ function PatientForm({ onSave, onCancel, PatientDict }) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = () => {
|
const handleSubmit = async () => {
|
||||||
if (!formData.nome || !formData.cpf || !formData.genero || !formData.dataNascimento || !formData.email||!formData.telefone1){
|
if (!formData.nome || !formData.cpf || !formData.sexo || !formData.data_nascimento){
|
||||||
alert('Por favor, preencha: Nome ,CPF, Gênero, Data de nascimento, telefone e Email.');
|
alert('Por favor, preencha Nome ,CPF, Gênero e data de nascimento.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
onSave(
|
const CPFinvalido = await ValidarCPF(formData.cpf)
|
||||||
{nome: formData.nome,
|
console.log(CPFinvalido)
|
||||||
nomeSocial: formData.nomeSocial,
|
if(CPFinvalido[0] === true){
|
||||||
dataNascimento: formData.dataNascimento,
|
alert(CPFinvalido[1])
|
||||||
genero: formData.genero,
|
return
|
||||||
documento: formData.documento,
|
|
||||||
numeroDocumento: formData.numeroDocumento,
|
|
||||||
cpf: formData.cpf,
|
|
||||||
profissao: formData.profissao,
|
|
||||||
nomeMae: formData.nomeMae,
|
|
||||||
profissaoMae: formData.profissaoMae,
|
|
||||||
nomePai: formData.nomePai,
|
|
||||||
profissaoPai: formData.profissaoPai,
|
|
||||||
nomeResponsavel: formData.nomeResponsavel,
|
|
||||||
cpfResponsavel: formData.cpfResponsavel,
|
|
||||||
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,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
);
|
onSave({
|
||||||
|
...formData,
|
||||||
|
endereco: {
|
||||||
|
cep: enderecoData.cep,
|
||||||
|
cidade: enderecoData.cidade,
|
||||||
|
estado: enderecoData.estado,
|
||||||
|
bairro: enderecoData.bairro,
|
||||||
|
logradouro: enderecoData.logradouro,
|
||||||
|
numero: enderecoData.numero,
|
||||||
|
complemento: enderecoData.complemento,
|
||||||
|
},
|
||||||
|
contato: {
|
||||||
|
email: contato.email,
|
||||||
|
telefone1: contato.telefone1,
|
||||||
|
telefone2: contato.telefone2,
|
||||||
|
telefone3: contato.telefone3,
|
||||||
|
},
|
||||||
|
infoMedicas: {
|
||||||
|
tipoSanguineo: formData.tipoSanguineo,
|
||||||
|
peso: formData.peso,
|
||||||
|
altura: formData.altura,
|
||||||
|
imc: formData.imc,
|
||||||
|
alergias: formData.alergias,
|
||||||
|
},
|
||||||
|
infoConvenio: {
|
||||||
|
convenio: formData.convenio,
|
||||||
|
plano: formData.plano,
|
||||||
|
numeroMatricula: formData.numeroMatricula,
|
||||||
|
validadeCarteira: formData.validadeCarteira,
|
||||||
|
validadeIndeterminada: formData.validadeIndeterminada,
|
||||||
|
pacienteVip: formData.pacienteVip,
|
||||||
|
},
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="card p-3">
|
<div className="card p-3">
|
||||||
<h3 className="mb-3 text-center">MediConnect</h3>
|
<h3 className="mb-4 text-center" style={{ fontSize: '2.5rem' }}>MediConnect</h3>
|
||||||
|
|
||||||
{/* ------------------ DADOS PESSOAIS ------------------ */}
|
{/* DADOS PESSOAIS */}
|
||||||
<h5 className="mb-3">Dados Pessoais</h5>
|
<div className="mb-5 p-4 border rounded shadow-sm">
|
||||||
<div className="row">
|
<h4 className="mb-4 cursor-pointer d-flex justify-content-between align-items-center" onClick={() => handleToggleCollapse('dadosPessoais')} style={{ fontSize: '1.8rem' }}>
|
||||||
|
Dados Pessoais
|
||||||
|
<span className="fs-5">
|
||||||
|
{collapsedSections.dadosPessoais ? '▲' : '▼'}
|
||||||
|
</span>
|
||||||
|
</h4>
|
||||||
|
<div className={`collapse${collapsedSections.dadosPessoais ? ' show' : ''}`}>
|
||||||
|
<div className="row mt-3">
|
||||||
|
{/* AVATAR E INPUT DE FOTO */}
|
||||||
|
<div className="col-md-6 mb-3 d-flex align-items-center">
|
||||||
|
<div className="me-3">
|
||||||
|
{avatarUrl ? (
|
||||||
|
<img
|
||||||
|
src={avatarUrl}
|
||||||
|
alt="Avatar do Paciente"
|
||||||
|
style={{ width: '100px', height: '100px', borderRadius: '50%', objectFit: 'cover' }}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
width: '100px',
|
||||||
|
height: '100px',
|
||||||
|
borderRadius: '50%',
|
||||||
|
backgroundColor: '#e0e0e0',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
fontSize: '3.5rem',
|
||||||
|
color: '#9e9e9e'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
☤
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label htmlFor="foto-input" className="btn btn-primary" style={{ fontSize: '1rem' }}>Carregar Foto</label>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
className="form-control d-none"
|
||||||
|
name="foto"
|
||||||
|
id="foto-input"
|
||||||
|
onChange={handleChange}
|
||||||
|
accept="image/*"
|
||||||
|
/>
|
||||||
|
{formData.foto && <span className="ms-2" style={{ fontSize: '1rem' }}>{formData.foto.name}</span>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* CADASTRO */}
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Nome: *</label>
|
<label style={{ fontSize: '1.1rem' }}>Nome: *</label>
|
||||||
<input type="text" className="form-control" name="nome" value={formData.nome} onChange={handleChange} />
|
<input type="text" className="form-control" name="nome" value={formData.nome} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Nome social:</label>
|
<label style={{ fontSize: '1.1rem' }}>Nome social:</label>
|
||||||
<input type="text" className="form-control" name="nomeSocial" value={formData.nomeSocial} onChange={handleChange} />
|
<input type="text" className="form-control" name="nome_social" value={formData.nome_social} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Data de nascimento: *</label>
|
<label style={{ fontSize: '1.1rem' }}>Data de nascimento: *</label>
|
||||||
<input type="date" className="form-control" name="dataNascimento" value={formData.dataNascimento} onChange={handleChange} />
|
<input type="date" className="form-control" name="data_nascimento" value={formData.data_nascimento} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Gênero: *</label>
|
<label style={{ fontSize: '1.1rem' }}>Gênero: *</label>
|
||||||
<select className="form-control" name="genero" value={formData.genero} onChange={handleChange}>
|
<select className="form-control" name="sexo" value={formData.sexo} onChange={handleChange} style={{ fontSize: '1.1rem' }}>
|
||||||
<option value="">Selecione</option>
|
<option value="">Selecione</option>
|
||||||
<option value="Masculino">Masculino</option>
|
<option value="Masculino">Masculino</option>
|
||||||
<option value="Feminino">Feminino</option>
|
<option value="Feminino">Feminino</option>
|
||||||
@ -202,122 +293,293 @@ function PatientForm({ onSave, onCancel, PatientDict }) {
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Outro documento:</label>
|
<label style={{ fontSize: '1.1rem' }}>CPF: *</label>
|
||||||
<input type="text" className="form-control" name="documento" value={formData.documento} onChange={handleChange} />
|
<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>Número do documento:</label>
|
<label style={{ fontSize: '1.1rem' }}>RG:</label>
|
||||||
<input type="text" className="form-control" name="numeroDocumento" value={formData.numeroDocumento} onChange={handleChange} />
|
<input type="text" className="form-control" name="rg" value={formData.rg} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>CPF: *</label>
|
<label style={{ fontSize: '1.1rem' }}>Outros documentos:</label>
|
||||||
<input type="text" className="form-control" name="cpf" value={formData.cpf} onChange={ handleChange} />
|
<select className="form-control" name="documentoTipo" value={formData.documentoTipo} onChange={handleChange} style={{ fontSize: '1.1rem' }}>
|
||||||
|
<option value="">Selecione</option>
|
||||||
|
<option value="CNH">CNH</option>
|
||||||
|
<option value="Passaporte">Passaporte</option>
|
||||||
|
<option value="carteira de trabalho">Carteira de Trabalho</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Profissão:</label>
|
<label style={{ fontSize: '1.1rem' }}>Número do documento:</label>
|
||||||
<input type="text" className="form-control" name="profissao" value={formData.profissao} onChange={handleChange} />
|
<input type="text" className="form-control" name="numero_documento" value={formData.numero_documento} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Nome da Mãe:</label>
|
<label style={{ fontSize: '1.1rem' }}>Etnia e Raça:</label>
|
||||||
<input type="text" className="form-control" name="nomeMae" value={formData.nomeMae} onChange={handleChange} />
|
<select className="form-control" name="etniaRaca" value={formData.etniaRaca} onChange={handleChange} style={{ fontSize: '1.1rem' }}>
|
||||||
|
<option value="">Selecione</option>
|
||||||
|
<option value="Branca">Branca</option>
|
||||||
|
<option value="Preta">Preta</option>
|
||||||
|
<option value="Parda">Parda</option>
|
||||||
|
<option value="Amarela">Amarela</option>
|
||||||
|
<option value="Indígena">Indígena</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Profissão da mãe:</label>
|
<label style={{ fontSize: '1.1rem' }}>Naturalidade:</label>
|
||||||
<input type="text" className="form-control" name="profissaoMae" value={formData.profissaoMae} onChange={handleChange} />
|
<input type="text" className="form-control" name="naturalidade" value={formData.naturalidade} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Nome do Pai:</label>
|
<label style={{ fontSize: '1.1rem' }}>Nacionalidade:</label>
|
||||||
<input type="text" className="form-control" name="nomePai" value={formData.nomePai} onChange={handleChange} />
|
<input type="text" className="form-control" name="nacionalidade" value={formData.nacionalidade} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Profissão do pai:</label>
|
<label style={{ fontSize: '1.1rem' }}>Profissão:</label>
|
||||||
<input type="text" className="form-control" name="profissaoPai" value={formData.profissaoPai} onChange={handleChange} />
|
<input type="text" className="form-control" name="profissao" value={formData.profissao} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Nome do responsável:</label>
|
<label style={{ fontSize: '1.1rem' }}>Estado civil:</label>
|
||||||
<input type="text" className="form-control" name="nomeResponsavel" value={formData.nomeResponsavel} onChange={handleChange} />
|
<select className="form-control" name="estado_civil" value={formData.estado_civil} onChange={handleChange} style={{ fontSize: '1.1rem' }}>
|
||||||
|
<option value="">Selecione</option>
|
||||||
|
<option value="Solteiro">Solteiro(a)</option>
|
||||||
|
<option value="Casado">Casado(a)</option>
|
||||||
|
<option value="Divorciado">Divorciado(a)</option>
|
||||||
|
<option value="Viuvo">Viúvo(a)</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>CPF do responsável:</label>
|
<label style={{ fontSize: '1.1rem' }}>Nome da Mãe:</label>
|
||||||
<input type="text" className="form-control" name="cpfResponsavel" value={formData.cpfResponsavel} onChange={handleChange} />
|
<input type="text" className="form-control" name="nomeMae" value={formData.nome_mae} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Nome do esposo(a):</label>
|
<label style={{ fontSize: '1.1rem' }}>Profissão da mãe:</label>
|
||||||
<input type="text" className="form-control" name="nomeConjuge" value={formData.nomeConjuge} onChange={handleChange} />
|
<input type="text" className="form-control" name="profissaoMae" value={formData.profissao_mae} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Identificador de outro sistema:</label>
|
<label style={{ fontSize: '1.1rem' }}>Nome do Pai:</label>
|
||||||
<input type="text" className="form-control" name="outroId" value={formData.outroId} onChange={handleChange} />
|
<input type="text" className="form-control" name="nomePai" value={formData.nome_pai} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label style={{ fontSize: '1.1rem' }}>Profissão do pai:</label>
|
||||||
|
<input type="text" className="form-control" name="profissaoPai" value={formData.profissao_pai} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label style={{ fontSize: '1.1rem' }}>Nome do responsável:</label>
|
||||||
|
<input type="text" className="form-control" name="nomeResponsavel" value={formData.nome_responsavel} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label style={{ fontSize: '1.1rem' }}>CPF do responsável:</label>
|
||||||
|
<input type="text" className="form-control" name="cpfResponsavel" value={formData.cpf_responsavel} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label style={{ fontSize: '1.1rem' }}>Nome do esposo(a):</label>
|
||||||
|
<input type="text" className="form-control" name="nomeConjuge" value={formData.nome_conjuge} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label style={{ fontSize: '1.1rem' }}>Identificador de outro sistema:</label>
|
||||||
|
<input type="text" className="form-control" name="outroId" value={formData.outroId} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
|
</div>
|
||||||
|
<div className="col-md-12 mb-3">
|
||||||
|
<div className="form-check">
|
||||||
|
<input className="form-check-input" type="checkbox" name="rnConvenio" checked={formData.rnConvenio} onChange={handleChange} id="rnConvenio" style={{ transform: 'scale(1.2)' }} />
|
||||||
|
<label className="form-check-label ms-2" htmlFor="rnConvenio" style={{ fontSize: '1.1rem' }}>
|
||||||
|
RN na Guia do convênio
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ------------------ ENDEREÇO ------------------ */}
|
{/* CAMPOS MOVIDOS */}
|
||||||
<h5>Endereço</h5>
|
<div className="col-md-12 mb-3 mt-3">
|
||||||
<div className="row">
|
<label style={{ fontSize: '1.1rem' }}>Observações:</label>
|
||||||
<div className="col-md-4 mb-3">
|
<textarea className="form-control" name="observacoes" value={formData.observacoes} onChange={handleChange} style={{ fontSize: '1.1rem' }}></textarea>
|
||||||
<label>CEP:</label>
|
|
||||||
<input type="text" className="form-control" name="cep" value={formData.cep} onChange={handleChange} onBlur={handleCepBlur} />
|
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-8 mb-3">
|
<div className="col-md-12 mb-3">
|
||||||
<label>Rua:</label>
|
<label style={{ fontSize: '1.1rem' }}>Anexos do Paciente:</label>
|
||||||
<input type="text" className="form-control" name="rua" value={formData.rua} onChange={handleChange} />
|
<div>
|
||||||
|
<label htmlFor="anexos-input" className="btn btn-secondary" style={{ fontSize: '1.1rem' }}>Escolher arquivo</label>
|
||||||
|
<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>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* INFORMAÇÕES MÉDICAS */}
|
||||||
|
<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' }}>
|
||||||
|
Informações Médicas
|
||||||
|
<span className="fs-5">
|
||||||
|
{collapsedSections.infoMedicas ? '▲' : '▼'}
|
||||||
|
</span>
|
||||||
|
</h4>
|
||||||
|
<div className={`collapse${collapsedSections.infoMedicas ? ' show' : ''}`}>
|
||||||
|
<div className="row mt-3">
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Bairro:</label>
|
<label style={{ fontSize: '1.1rem' }}>Tipo Sanguíneo:</label>
|
||||||
<input type="text" className="form-control" name="bairro" value={formData.bairro} onChange={handleChange} />
|
<select className="form-control" name="tipoSanguineo" value={formData.tipoSanguineo} onChange={handleChange} style={{ fontSize: '1.1rem' }}>
|
||||||
</div>
|
<option value="">Selecione</option>
|
||||||
<div className="col-md-4 mb-3">
|
<option value="A+">A+</option>
|
||||||
<label>Cidade:</label>
|
<option value="A-">A-</option>
|
||||||
<input type="text" className="form-control" name="cidade" value={formData.cidade} onChange={handleChange} />
|
<option value="B+">B+</option>
|
||||||
|
<option value="B-">B-</option>
|
||||||
|
<option value="AB+">AB+</option>
|
||||||
|
<option value="AB-">AB-</option>
|
||||||
|
<option value="O+">O+</option>
|
||||||
|
<option value="O-">O-</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-2 mb-3">
|
<div className="col-md-2 mb-3">
|
||||||
<label>Estado:</label>
|
<label style={{ fontSize: '1.1rem' }}>Peso (kg):</label>
|
||||||
<input type="text" className="form-control" name="estado" value={formData.estado} onChange={handleChange} />
|
<input type="number" step="0.1" className="form-control" name="peso" value={formData.peso} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
|
</div>
|
||||||
|
<div className="col-md-2 mb-3">
|
||||||
|
<label style={{ fontSize: '1.1rem' }}>Altura (m):</label>
|
||||||
|
<input type="number" step="0.01" className="form-control" name="altura" value={formData.altura} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
|
</div>
|
||||||
|
<div className="col-md-2 mb-3">
|
||||||
|
<label style={{ fontSize: '1.1rem' }}>IMC (kg/m²):</label>
|
||||||
|
<input type="text" className="form-control" name="imc" value={formData.imc} readOnly disabled style={{ fontSize: '1.1rem' }} />
|
||||||
|
</div>
|
||||||
|
<div className="col-md-12 mb-3">
|
||||||
|
<label style={{ fontSize: '1.1rem' }}>Alergias:</label>
|
||||||
|
<textarea className="form-control" name="alergias" value={formData.alergias} onChange={handleChange} placeholder="Ex: AAS, Dipirona, etc" style={{ fontSize: '1.1rem' }}></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* INFORMAÇÕES DE CONVÊNIO */}
|
||||||
|
<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' }}>
|
||||||
|
Informações de convênio
|
||||||
|
<span className="fs-5">
|
||||||
|
{collapsedSections.infoConvenio ? '▲' : '▼'}
|
||||||
|
</span>
|
||||||
|
</h4>
|
||||||
|
<div className={`collapse${collapsedSections.infoConvenio ? ' show' : ''}`}>
|
||||||
|
<div className="row mt-3">
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label style={{ fontSize: '1.1rem' }}>Convênio:</label>
|
||||||
|
<select className="form-control" name="convenio" value={formData.convenio} onChange={handleChange} style={{ fontSize: '1.1rem' }}>
|
||||||
|
<option value="">Selecione</option>
|
||||||
|
<option value="Amil">Amil</option>
|
||||||
|
<option value="Bradesco Saúde">Bradesco Saúde</option>
|
||||||
|
<option value="SulAmérica">SulAmérica</option>
|
||||||
|
<option value="Unimed">Unimed</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label style={{ fontSize: '1.1rem' }}>Plano:</label>
|
||||||
|
<input type="text" className="form-control" name="plano" value={formData.plano} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label style={{ fontSize: '1.1rem' }}>Nº de matrícula:</label>
|
||||||
|
<input type="text" className="form-control" name="numeroMatricula" value={formData.numeroMatricula} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-4 mb-3">
|
<div className="col-md-4 mb-3">
|
||||||
<label>Número:</label>
|
<label style={{ fontSize: '1.1rem' }}>Validade da Carteira:</label>
|
||||||
<input type="text" className="form-control" name="numero" value={formData.numero} onChange={handleChange} />
|
<input type="date" className="form-control" name="validadeCarteira" value={formData.validadeCarteira} onChange={handleChange} disabled={formData.validadeIndeterminada} style={{ fontSize: '1.1rem' }} />
|
||||||
|
</div>
|
||||||
|
<div className="col-md-2 d-flex align-items-end mb-3">
|
||||||
|
<div className="form-check">
|
||||||
|
<input className="form-check-input" type="checkbox" name="validadeIndeterminada" checked={formData.validadeIndeterminada} onChange={handleChange} id="validadeIndeterminada" style={{ transform: 'scale(1.2)' }} />
|
||||||
|
<label className="form-check-label ms-2" htmlFor="validadeIndeterminada" style={{ fontSize: '1.1rem' }}>
|
||||||
|
Validade indeterminada
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* PACIENTE VIP */}
|
||||||
|
<div className="col-md-12 mb-3 mt-3">
|
||||||
|
<div className="form-check">
|
||||||
|
<input className="form-check-input" type="checkbox" name="pacienteVip" checked={formData.pacienteVip} onChange={handleChange} id="pacienteVip" style={{ transform: 'scale(1.2)' }} />
|
||||||
|
<label className="form-check-label ms-2" htmlFor="pacienteVip" style={{ fontSize: '1.1rem' }}>
|
||||||
|
Paciente VIP
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* ENDEREÇO */}
|
||||||
|
<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' }}>
|
||||||
|
Endereço
|
||||||
|
<span className="fs-5">
|
||||||
|
{collapsedSections.endereco ? '▲' : '▼'}
|
||||||
|
</span>
|
||||||
|
</h4>
|
||||||
|
<div className={`collapse${collapsedSections.endereco ? ' show' : ''}`}>
|
||||||
|
<div className="row mt-3">
|
||||||
|
<div className="col-md-4 mb-3">
|
||||||
|
<label style={{ fontSize: '1.1rem' }}>CEP:</label>
|
||||||
|
<input type="text" className="form-control" name="endereco.cep" value={enderecoData.cep} onChange={handleChange} onBlur={handleCepBlur} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-8 mb-3">
|
<div className="col-md-8 mb-3">
|
||||||
<label>Complemento:</label>
|
<label style={{ fontSize: '1.1rem' }}>Rua:</label>
|
||||||
<input type="text" className="form-control" name="complemento" value={formData.complemento} onChange={handleChange} />
|
<input type="text" className="form-control" name="endereco.logradouro" value={enderecoData.logradouro} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label style={{ fontSize: '1.1rem' }}>Bairro:</label>
|
||||||
|
<input type="text" className="form-control" name="endereco.bairro" value={enderecoData.bairro} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
|
</div>
|
||||||
|
<div className="col-md-4 mb-3">
|
||||||
|
<label style={{ fontSize: '1.1rem' }}>Cidade:</label>
|
||||||
|
<input type="text" className="form-control" name="endereco.cidade" value={enderecoData.cidade} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
|
</div>
|
||||||
|
<div className="col-md-2 mb-3">
|
||||||
|
<label style={{ fontSize: '1.1rem' }}>Estado:</label>
|
||||||
|
<input type="text" className="form-control" name="endereco.estado" value={enderecoData.estado} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
|
</div>
|
||||||
|
<div className="col-md-4 mb-3">
|
||||||
|
<label style={{ fontSize: '1.1rem' }}>Número:</label>
|
||||||
|
<input type="text" className="form-control" name="endereco.numero" value={enderecoData.numero} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
|
</div>
|
||||||
|
<div className="col-md-8 mb-3">
|
||||||
|
<label style={{ fontSize: '1.1rem' }}>Complemento:</label>
|
||||||
|
<input type="text" className="form-control" name="endereco.complemento" value={enderecoData.complemento} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ------------------ CONTATO ------------------ */}
|
{/* CONTATO */}
|
||||||
<h5>Contato</h5>
|
<div className="mb-5 p-4 border rounded shadow-sm">
|
||||||
<div className="row">
|
<h4 className="mb-4 cursor-pointer d-flex justify-content-between align-items-center" onClick={() => handleToggleCollapse('contato')} style={{ fontSize: '1.8rem' }}>
|
||||||
|
Contato
|
||||||
|
<span className="fs-5">
|
||||||
|
{collapsedSections.contato ? '▲' : '▼'}
|
||||||
|
</span>
|
||||||
|
</h4>
|
||||||
|
<div className={`collapse${collapsedSections.contato ? ' show' : ''}`}>
|
||||||
|
<div className="row mt-3">
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Email: *</label>
|
<label style={{ fontSize: '1.1rem' }}>Email:</label>
|
||||||
<input type="email" className="form-control" name="email" value={formData.email} onChange={handleChange} />
|
<input type="email" className="form-control" name="email" value={contato.email || ''} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Telefone: *</label>
|
<label style={{ fontSize: '1.1rem' }}>Telefone:</label>
|
||||||
<input type="text" className="form-control" name="telefone1" value={formData.telefone1} onChange={handleChange} />
|
<input type="text" className="form-control" name="telefone1" value={contato.telefone1 || ''} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Telefone 2:</label>
|
<label style={{ fontSize: '1.1rem' }}>Telefone 2:</label>
|
||||||
<input type="text" className="form-control" name="telefone2" value={formData.telefone2} onChange={handleChange} />
|
<input type="text" className="form-control" name="telefone2" value={contato.telefone2 || ''} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
<label>Telefone 3:</label>
|
<label style={{ fontSize: '1.1rem' }}>Telefone 3:</label>
|
||||||
<input type="text" className="form-control" name="telefone3" value={formData.telefone3} onChange={handleChange} />
|
<input type="text" className="form-control" name="telefone3" value={contato.telefone3 || ''} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ------------------ INFORMAÇÕES ADICIONAIS ------------------ */}
|
|
||||||
<h5>Informações Adicionais</h5>
|
|
||||||
<div className="mb-3">
|
|
||||||
<label>Observações:</label>
|
|
||||||
<textarea className="form-control" name="observacoes" value={formData.observacoes} onChange={handleChange}></textarea>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Botões */}
|
{/* Botões */}
|
||||||
<div className="mt-3">
|
<div className="mt-3 text-center">
|
||||||
<button className="btn btn-success me-2" onClick={handleSubmit}>
|
<button className="btn btn-success me-3" onClick={handleSubmit} style={{ fontSize: '1.2rem', padding: '0.75rem 1.5rem' }}>
|
||||||
Salvar Paciente
|
Salvar Paciente
|
||||||
</button>
|
</button>
|
||||||
<button className="btn btn-light" onClick={onCancel}>
|
<button className="btn btn-light" onClick={onCancel} style={{ fontSize: '1.2rem', padding: '0.75rem 1.5rem' }}>
|
||||||
Cancelar
|
Cancelar
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -4,28 +4,45 @@
|
|||||||
"isTitle": true
|
"isTitle": true
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"name":"Início",
|
||||||
|
"url": "Inicio",
|
||||||
|
"icon": "house"
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"name": "Cadastro de Pacientes",
|
"name": "Cadastro de Pacientes",
|
||||||
"url": "form-layout",
|
"url": "form-layout",
|
||||||
"icon": "file-earmark-medical-fill"
|
"icon": "heart-pulse-fill"
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"name": "Cadastro do Médico",
|
"name": "Cadastro do Médico",
|
||||||
"url": "doctor-form-layout",
|
"url": "doctor-form-layout",
|
||||||
"icon": "file-earmark-medical-fill"
|
"icon": "capsule"
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"name": "Lista de Pacientes",
|
"name": "Lista de Pacientes",
|
||||||
"icon": "table",
|
"icon": "clipboard-heart-fill",
|
||||||
"url": "table"
|
"url": "table"
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"name": "Lista de Médico",
|
"name": "Lista de Médico",
|
||||||
"icon": "table",
|
"icon": "hospital-fill",
|
||||||
"url": "doctor-table"
|
"url": "doctor-table"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Agendar consulta",
|
||||||
|
"icon": "calendar-plus-fill",
|
||||||
|
"url": "agendamento"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "Laudo do Paciente",
|
||||||
|
"icon": "table",
|
||||||
|
"url": "laudo-manager"
|
||||||
}
|
}
|
||||||
|
|
||||||
]
|
]
|
||||||
@ -1,409 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"name": "Dashboard",
|
|
||||||
"url": "dashboard",
|
|
||||||
"icon": "grid-fill"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Components",
|
|
||||||
"key": "component",
|
|
||||||
"icon": "stack",
|
|
||||||
"submenu": [
|
|
||||||
{
|
|
||||||
"name": "Alert",
|
|
||||||
"url": "component-alert.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Badge",
|
|
||||||
"url": "component-badge.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Breadcrumb",
|
|
||||||
"url": "component-breadcrumb.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Button",
|
|
||||||
"url": "component-button.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Card",
|
|
||||||
"url": "component-card.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Carousel",
|
|
||||||
"url": "component-carousel.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Collapse",
|
|
||||||
"url": "component-collapse.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Dropdown",
|
|
||||||
"url": "component-dropdown.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "List Group",
|
|
||||||
"url": "component-list-group.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Modal",
|
|
||||||
"url": "component-modal.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Navs",
|
|
||||||
"url": "component-navs.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Pagination",
|
|
||||||
"url": "component-pagination.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Progress",
|
|
||||||
"url": "component-progress.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Spinner",
|
|
||||||
"url": "component-spinner.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Tooltip",
|
|
||||||
"url": "component-tooltip.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Extra Components",
|
|
||||||
"key": "extra-component",
|
|
||||||
"icon": "collection-fill",
|
|
||||||
"submenu": [
|
|
||||||
{
|
|
||||||
"name": "Avatar",
|
|
||||||
"url": "extra-component-avatar.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Comment",
|
|
||||||
"url": "extra-component-comment.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Sweet Alert",
|
|
||||||
"url": "extra-component-sweetalert.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Toastify",
|
|
||||||
"url": "extra-component-toastify.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Rating",
|
|
||||||
"url": "extra-component-rating.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Divider",
|
|
||||||
"url": "extra-component-divider.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "GLightbox",
|
|
||||||
"url": "extra-component-glightbox.html"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Layouts",
|
|
||||||
"key": "layout",
|
|
||||||
"icon": "grid-1x2-fill",
|
|
||||||
"submenu": [
|
|
||||||
{
|
|
||||||
"name": "Default Layout",
|
|
||||||
"url": "layout-default.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "1 Column",
|
|
||||||
"url": "layout-vertical-1-column.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Vertical Navbar",
|
|
||||||
"url": "layout-vertical-navbar.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "RTL Layout",
|
|
||||||
"url": "layout-rtl.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Horizontal Menu",
|
|
||||||
"url": "layout-horizontal.html"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Forms",
|
|
||||||
"key": "form",
|
|
||||||
"icon": "file-earmark-medical-fill",
|
|
||||||
"submenu": [
|
|
||||||
{
|
|
||||||
"name": "Form Elements",
|
|
||||||
"key": "form-element",
|
|
||||||
"icon": "hexagon-fill",
|
|
||||||
"submenu": [
|
|
||||||
{
|
|
||||||
"name": "Input",
|
|
||||||
"url": "form-element-input.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Input Group",
|
|
||||||
"url": "form-element-input-group.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Select",
|
|
||||||
"url": "form-element-select.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Radio",
|
|
||||||
"url": "form-element-radio.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Checkbox",
|
|
||||||
"url": "form-element-checkbox.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Textarea",
|
|
||||||
"url": "form-element-textarea.html"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Form Layout",
|
|
||||||
"url": "form-layout",
|
|
||||||
"icon": "file-earmark-medical-fill"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Form Validation",
|
|
||||||
"icon": "journal-check",
|
|
||||||
"key": "form-validation",
|
|
||||||
"submenu": [
|
|
||||||
{
|
|
||||||
"name": "Parsley",
|
|
||||||
"url": "form-validation-parsley.html"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Form Editor",
|
|
||||||
"icon": "pen-fill",
|
|
||||||
"key": "form-editor",
|
|
||||||
"submenu": [
|
|
||||||
{
|
|
||||||
"name": "Quill",
|
|
||||||
"url": "form-editor-quill.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "CKEditor",
|
|
||||||
"url": "form-editor-ckeditor.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Summernote",
|
|
||||||
"url": "form-editor-summernote.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "TinyMCE",
|
|
||||||
"url": "form-editor-tinymce.html"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Table",
|
|
||||||
"icon": "table",
|
|
||||||
"submenu": [
|
|
||||||
{
|
|
||||||
"name": "Table",
|
|
||||||
"url": "table",
|
|
||||||
"icon": "file-earmark-spreadsheet-fill"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Datatable",
|
|
||||||
"url": "table-datatable.html",
|
|
||||||
"icon": "file-earmark-spreadsheet-fill"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Datatable (jQuery)",
|
|
||||||
"url": "table-datatable-jquery.html",
|
|
||||||
"icon": "file-earmark-spreadsheet-fill"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Extras",
|
|
||||||
"key": "extras",
|
|
||||||
"icon": "plus-square-fill",
|
|
||||||
"submenu": [
|
|
||||||
{
|
|
||||||
"name": "Widgets",
|
|
||||||
"key": "ui-widgets",
|
|
||||||
"icon": "pentagon-fill",
|
|
||||||
"submenu": [
|
|
||||||
{
|
|
||||||
"name": "Chatbox",
|
|
||||||
"url": "ui-widgets-chatbox.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Pricing",
|
|
||||||
"url": "ui-widgets-pricing.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "To-do List",
|
|
||||||
"url": "ui-widgets-todolist.html"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Icons",
|
|
||||||
"key": "ui-icons",
|
|
||||||
"icon": "egg-fill",
|
|
||||||
"submenu": [
|
|
||||||
{
|
|
||||||
"name": "Bootstrap Icons ",
|
|
||||||
"url": "ui-icons-bootstrap-icons.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Fontawesome",
|
|
||||||
"url": "ui-icons-fontawesome.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Dripicons",
|
|
||||||
"url": "ui-icons-dripicons.html"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Charts",
|
|
||||||
"key": "ui-chart",
|
|
||||||
"icon": "bar-chart-fill",
|
|
||||||
"submenu": [
|
|
||||||
{
|
|
||||||
"name": "ChartJS",
|
|
||||||
"url": "ui-chart-chartjs.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Apexcharts",
|
|
||||||
"url": "ui-chart-apexcharts.html"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Pages",
|
|
||||||
"key": "pages",
|
|
||||||
"icon": "file-earmark-fill",
|
|
||||||
"submenu": [
|
|
||||||
{
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Errors",
|
|
||||||
"key": "error",
|
|
||||||
"icon": "x-octagon-fill",
|
|
||||||
"submenu": [
|
|
||||||
{
|
|
||||||
"name": "403",
|
|
||||||
"url": "error-403.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "404",
|
|
||||||
"url": "error-404.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "500",
|
|
||||||
"url": "error-500.html"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "File Uploader",
|
|
||||||
"key": "ui-file",
|
|
||||||
"icon": "cloud-arrow-up-fill",
|
|
||||||
"url": "ui-file-uploader.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Maps",
|
|
||||||
"key": "ui-map",
|
|
||||||
"icon": "map-fill",
|
|
||||||
"submenu": [
|
|
||||||
{
|
|
||||||
"name": "Google Map",
|
|
||||||
"url": "ui-map-google-map.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "JS Vector Map",
|
|
||||||
"url": "ui-map-jsvectormap.html"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Email Application",
|
|
||||||
"key": "application-email",
|
|
||||||
"icon": "envelope-fill",
|
|
||||||
"url": "application-email.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Chat Application",
|
|
||||||
"key": "application-chat",
|
|
||||||
"icon": "chat-dots-fill",
|
|
||||||
"url": "application-chat.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Photo Gallery",
|
|
||||||
"key": "application-gallery",
|
|
||||||
"icon": "image-fill",
|
|
||||||
"url": "application-gallery.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Checkout Page",
|
|
||||||
"key": "application-checkout",
|
|
||||||
"icon": "basket-fill",
|
|
||||||
"url": "application-checkout.html"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Support",
|
|
||||||
"key": "error",
|
|
||||||
"icon": "life-preserver",
|
|
||||||
"submenu": [
|
|
||||||
{
|
|
||||||
"name": "Documentation",
|
|
||||||
"key": "error",
|
|
||||||
"icon": "life-preserver",
|
|
||||||
"url": "https://zuramai.github.io/mazer/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Contribute",
|
|
||||||
"key": "error",
|
|
||||||
"url": "https://github.com/zuramai/mazer/blob/main/CONTRIBUTING.md",
|
|
||||||
"icon": "puzzle"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Donate",
|
|
||||||
"key": "error",
|
|
||||||
"url": "https://github.com/zuramai/mazer#donation",
|
|
||||||
"icon": "cash"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
183
src/pages/Agendamento.jsx
Normal file
183
src/pages/Agendamento.jsx
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import TabelaAgendamentoDia from '../components/AgendarConsulta/TabelaAgendamentoDia';
|
||||||
|
import TabelaAgendamentoSemana from '../components/AgendarConsulta/TabelaAgendamentoSemana';
|
||||||
|
import TabelaAgendamentoMes from '../components/AgendarConsulta/TabelaAgendamentoMes';
|
||||||
|
import FormNovaConsulta from '../components/AgendarConsulta/FormNovaConsulta';
|
||||||
|
import { useState} from 'react';
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
import "./style/Agendamento.css";
|
||||||
|
|
||||||
|
const Agendamento = () => {
|
||||||
|
|
||||||
|
|
||||||
|
const ListarDiasdoMes = (ano, mes) => {
|
||||||
|
let segundas = []; let tercas = []; let quartas = []; let quintas = []; let sextas = []
|
||||||
|
|
||||||
|
|
||||||
|
const base = dayjs(`${ano}-${mes}-01`)
|
||||||
|
|
||||||
|
const DiasnoMes= base.daysInMonth()
|
||||||
|
for(let d = 1; d <= DiasnoMes; d++){
|
||||||
|
|
||||||
|
const data = dayjs(`${ano}-${mes}-${d}`)
|
||||||
|
|
||||||
|
const dia = data.format('dddd')
|
||||||
|
|
||||||
|
switch(dia){
|
||||||
|
case'Monday':
|
||||||
|
segundas.push(d)
|
||||||
|
break
|
||||||
|
|
||||||
|
case'Tuesday':
|
||||||
|
tercas.push(d)
|
||||||
|
break
|
||||||
|
|
||||||
|
case'Wednesday':
|
||||||
|
quartas.push(d)
|
||||||
|
break
|
||||||
|
|
||||||
|
case'Thursday':
|
||||||
|
quintas.push(d)
|
||||||
|
break
|
||||||
|
|
||||||
|
case'Friday':
|
||||||
|
sextas.push(d)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}}
|
||||||
|
|
||||||
|
let ListaDiasDatas = [segundas,tercas, quartas, quintas,sextas]
|
||||||
|
console.log('dentro da função', ListaDiasDatas)
|
||||||
|
|
||||||
|
return ListaDiasDatas
|
||||||
|
}
|
||||||
|
|
||||||
|
const [tabela, setTabela] = useState('diario')
|
||||||
|
const [PageNovaConsulta, setPageConsulta] = useState(false)
|
||||||
|
|
||||||
|
const handleClickAgendamento = (agendamento) => {
|
||||||
|
|
||||||
|
if(agendamento.status !== 'vazio')return
|
||||||
|
|
||||||
|
else{
|
||||||
|
setPageConsulta(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleClickCancel = () => {
|
||||||
|
setPageConsulta(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return(
|
||||||
|
<div>
|
||||||
|
<h1>Agendar nova consulta</h1>
|
||||||
|
|
||||||
|
{!PageNovaConsulta? (
|
||||||
|
|
||||||
|
<div className='atendimento-eprocura'>
|
||||||
|
|
||||||
|
<div className='busca-atendimento'>
|
||||||
|
<div className="">
|
||||||
|
<i className="fa-solid fa-calendar-day"></i>
|
||||||
|
<input type="text" placeholder="Buscar atendimento" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<select>
|
||||||
|
<option value="" disabled selected>Agendar</option>
|
||||||
|
<option value="">Atendimento</option>
|
||||||
|
<option value="">Sessões</option>
|
||||||
|
<option value="">Urgência</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div className='unidade-selecionarprofissional'>
|
||||||
|
<select>
|
||||||
|
<option value="" disabled selected >Unidade</option>
|
||||||
|
<option value="">Unidade Central</option>
|
||||||
|
<option value="">Unidade Zona Norte</option>
|
||||||
|
<option value="">Unidade Zona Oeste</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<input type="text" placeholder='Selecionar profissional' />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='diadia'>
|
||||||
|
<div>
|
||||||
|
<button className={`btn-selecionar-tabeladia ${tabela === "diario" ? "ativo" : ""}`}
|
||||||
|
|
||||||
|
onClick={() => setTabela("diario")}>
|
||||||
|
<i className="fa-solid fa-calendar-day"></i>
|
||||||
|
Dia
|
||||||
|
</button>
|
||||||
|
<button className={`btn-selecionar-tabelasemana ${tabela === 'semanal' ? 'ativo': ""}`} onClick={() => setTabela("semanal")}>
|
||||||
|
<i className="fa-solid fa-calendar-day"></i>
|
||||||
|
Semana
|
||||||
|
</button>
|
||||||
|
<button className={`btn-selecionar-tabelames ${tabela === 'mensal' ? 'ativo':''}`} onClick={() => setTabela("mensal")}>
|
||||||
|
<i className="fa-solid fa-calendar-day"></i>
|
||||||
|
Mês
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div className='legenda-tabela'>
|
||||||
|
<div className='legenda-item-realizado'>
|
||||||
|
|
||||||
|
<span>Realizado</span>
|
||||||
|
</div>
|
||||||
|
<div className='legenda-item-confirmado'>
|
||||||
|
<span>Confirmado</span>
|
||||||
|
</div>
|
||||||
|
<div className='legenda-item-agendado'>
|
||||||
|
|
||||||
|
<span>Agendado</span>
|
||||||
|
</div>
|
||||||
|
<div className='legenda-item-cancelado'>
|
||||||
|
<span>Cancelado</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{tabela === "diario" && (
|
||||||
|
<TabelaAgendamentoDia
|
||||||
|
handleClickAgendamento={handleClickAgendamento}
|
||||||
|
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{tabela === 'semanal' &&
|
||||||
|
<TabelaAgendamentoSemana/>
|
||||||
|
}
|
||||||
|
|
||||||
|
{tabela === 'mensal' && (
|
||||||
|
<TabelaAgendamentoMes
|
||||||
|
ListarDiasdoMes={ListarDiasdoMes}
|
||||||
|
aplicarCores={true} // 🔹 Ativa a lógica de cores só no mensal
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
|
||||||
|
<FormNovaConsulta onCancel={handleClickCancel} />
|
||||||
|
|
||||||
|
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default Agendamento
|
||||||
@ -1,110 +0,0 @@
|
|||||||
import React, { useState } from "react";
|
|
||||||
|
|
||||||
function ChatApp() {
|
|
||||||
const [selectedUser, setSelectedUser] = useState(1);
|
|
||||||
|
|
||||||
const users = [
|
|
||||||
{ id: 1, name: "Alice", avatar: "https://i.pravatar.cc/40?img=1" },
|
|
||||||
{ id: 2, name: "Bob", avatar: "https://i.pravatar.cc/40?img=2" },
|
|
||||||
{ id: 3, name: "Charlie", avatar: "https://i.pravatar.cc/40?img=3" }
|
|
||||||
];
|
|
||||||
|
|
||||||
const messages = {
|
|
||||||
1: [
|
|
||||||
{ from: "Alice", text: "Oi Rafael 👋", time: "10:15" },
|
|
||||||
{ from: "Você", text: "E aí Alice, tudo bem?", time: "10:16" },
|
|
||||||
{ from: "Alice", text: "Tudo ótimo! 😄", time: "10:17" }
|
|
||||||
],
|
|
||||||
2: [
|
|
||||||
{ from: "Bob", text: "Fala mano!", time: "09:30" },
|
|
||||||
{ from: "Você", text: "Tranquilo Bob?", time: "09:32" },
|
|
||||||
{ from: "Bob", text: "Sempre ✌️", time: "09:33" }
|
|
||||||
],
|
|
||||||
3: [
|
|
||||||
{ from: "Charlie", text: "Já viu a novidade?", time: "Ontem" },
|
|
||||||
{ from: "Você", text: "Qual novidade?", time: "Ontem" },
|
|
||||||
{ from: "Charlie", text: "Te conto depois kkk 🤐", time: "Ontem" }
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
const currentMessages = messages[selectedUser] || [];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className="page-heading">
|
|
||||||
<h3>Chat Application</h3>
|
|
||||||
<p className="text-muted">Converse em tempo real com seus contatos</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="page-content">
|
|
||||||
<div className="row">
|
|
||||||
{/* Sidebar - Contatos */}
|
|
||||||
<div className="col-3 border-end">
|
|
||||||
<h6 className="mb-3">Contatos</h6>
|
|
||||||
<ul className="list-group">
|
|
||||||
{users.map((user) => (
|
|
||||||
<li
|
|
||||||
key={user.id}
|
|
||||||
className={`list-group-item d-flex align-items-center ${
|
|
||||||
selectedUser === user.id ? "active" : ""
|
|
||||||
}`}
|
|
||||||
style={{ cursor: "pointer" }}
|
|
||||||
onClick={() => setSelectedUser(user.id)}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
src={user.avatar}
|
|
||||||
alt={user.name}
|
|
||||||
className="rounded-circle me-2"
|
|
||||||
width={40}
|
|
||||||
height={40}
|
|
||||||
/>
|
|
||||||
<span>{user.name}</span>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Chat */}
|
|
||||||
<div className="col-9 d-flex flex-column" style={{ height: "70vh" }}>
|
|
||||||
<div
|
|
||||||
className="flex-grow-1 border rounded p-3 mb-2 overflow-auto"
|
|
||||||
style={{ background: "#f9f9f9" }}
|
|
||||||
>
|
|
||||||
{currentMessages.map((msg, index) => (
|
|
||||||
<div
|
|
||||||
key={index}
|
|
||||||
className={`mb-2 ${
|
|
||||||
msg.from === "Você" ? "text-end" : "text-start"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className={`d-inline-block p-2 rounded ${
|
|
||||||
msg.from === "Você"
|
|
||||||
? "bg-primary text-white"
|
|
||||||
: "bg-light"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<strong>{msg.from}:</strong> {msg.text}
|
|
||||||
</div>
|
|
||||||
<div className="small text-muted">{msg.time}</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Caixa de mensagem */}
|
|
||||||
<div className="d-flex">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
className="form-control me-2"
|
|
||||||
placeholder="Digite sua mensagem..."
|
|
||||||
/>
|
|
||||||
<button className="btn btn-primary">Enviar</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ChatApp;
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
|
|
||||||
function DataTable() {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className="page-heading">
|
|
||||||
<h3>Data Table</h3>
|
|
||||||
</div>
|
|
||||||
<div className="page-content">
|
|
||||||
<section className="row">
|
|
||||||
<div className="col-12">
|
|
||||||
<div className="card">
|
|
||||||
<div className="card-header">
|
|
||||||
<h4 className="card-title">Minha Data Table</h4>
|
|
||||||
</div>
|
|
||||||
<div className="card-body">
|
|
||||||
<p>Aqui você vai construir sua DataTable futuramente 🚀</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default DataTable;
|
|
||||||
@ -1,148 +1,272 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
|
import avatarPlaceholder from '../assets/images/avatar_placeholder.png';
|
||||||
|
|
||||||
const Details = ({ patientID, setCurrentPage }) => {
|
const Details = ({ patientID, setCurrentPage }) => {
|
||||||
const [paciente, setPaciente] = useState(null);
|
const [paciente, setPaciente] = useState({});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!patientID) return;
|
if (!patientID) return;
|
||||||
|
|
||||||
fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientID}`)
|
fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientID}`)
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(data => setPaciente(data))
|
|
||||||
|
.then(result => {setPaciente(result.data)})
|
||||||
.catch(err => console.error("Erro ao buscar paciente:", err));
|
.catch(err => console.error("Erro ao buscar paciente:", err));
|
||||||
}, [patientID]);
|
}, [patientID]);
|
||||||
|
|
||||||
if (!paciente) return <p style={{ textAlign: "center" }}>Carregando...</p>;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={styles.container}>
|
<>
|
||||||
{/* Botão voltar */}
|
<div className="card p-3 shadow-sm">
|
||||||
<button style={styles.backBtn} onClick={() => setCurrentPage("tabela")}>
|
<h3 className="mb-3 text-center">MediConnect</h3>
|
||||||
⬅ Voltar
|
<hr />
|
||||||
</button>
|
<div className="d-flex justify-content-between align-items-center mb-3">
|
||||||
|
|
||||||
{/* Cabeçalho */}
|
<div className="d-flex mb-3">
|
||||||
<div style={styles.header}>
|
<div className="avatar avatar-xl">
|
||||||
<img
|
<img src={avatarPlaceholder} alt="" />
|
||||||
src="https://via.placeholder.com/80"
|
|
||||||
alt="Foto do paciente"
|
|
||||||
style={styles.avatar}
|
|
||||||
/>
|
|
||||||
<h2 style={styles.nome}>
|
|
||||||
{paciente.nomeCompleto}
|
|
||||||
</h2>
|
|
||||||
<p style={styles.cpf}>CPF: {paciente.cpf}</p>
|
|
||||||
<button style={styles.editBtn}>Editar</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div className="media-body ms-3 font-extrabold">
|
||||||
{/* Dados pessoais */}
|
<span>{paciente.nome || "Nome Completo"}</span>
|
||||||
<div style={styles.section}>
|
<p>{paciente.cpf || "CPF"}</p>
|
||||||
<h3 style={styles.sectionTitle}>Dados Pessoais</h3>
|
|
||||||
<div style={styles.grid}>
|
|
||||||
<div style={styles.item}><strong>Nome Completo:</strong> {paciente.nomeCompleto}</div>
|
|
||||||
<div style={styles.item}><strong>CPF:</strong> {paciente.cpf}</div>
|
|
||||||
<div style={styles.item}><strong>Idade:</strong> {paciente.idade}</div>
|
|
||||||
<div style={styles.item}><strong>Data de Nascimento:</strong> {paciente.dataNascimento}</div>
|
|
||||||
<div style={styles.item}><strong>Sexo:</strong> {paciente.sexo}</div>
|
|
||||||
<div style={styles.item}><strong>Estado Civil:</strong> {paciente.estadoCivil}</div>
|
|
||||||
<div style={styles.item}><strong>Profissão:</strong> {paciente.profissao}</div>
|
|
||||||
<div style={styles.item}><strong>Nacionalidade:</strong> {paciente.nacionalidade}</div>
|
|
||||||
<div style={styles.item}><strong>Naturalidade:</strong> {paciente.naturalidade}</div>
|
|
||||||
<div style={styles.item}><strong>Etnia:</strong> {paciente.etnia}</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Contato */}
|
</div>
|
||||||
<div style={styles.section}>
|
</div>
|
||||||
<h3 style={styles.sectionTitle}>Informações de Contato</h3>
|
|
||||||
<div style={styles.grid}>
|
{/* ------------------ DADOS PESSOAIS ------------------ */}
|
||||||
<div style={styles.item}><strong>E-mail:</strong> {paciente.email}</div>
|
<div className="card p-3 shadow-sm">
|
||||||
<div style={styles.item}><strong>Celular:</strong> {paciente.celular}</div>
|
<h5 className="mb-3">Dados Pessoais</h5>
|
||||||
<div style={styles.item}><strong>Telefone 1:</strong> {paciente.telefone1 || "-"}</div>
|
<hr />
|
||||||
<div style={styles.item}><strong>Telefone 2:</strong> {paciente.telefone2 || "-"}</div>
|
<div className="row">
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Nome:</label>
|
||||||
|
<p>{paciente.nome || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Nome social:</label>
|
||||||
|
<p>{paciente.nome_social || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Data de nascimento:</label>
|
||||||
|
<p>{paciente.data_nascimento || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Gênero:</label>
|
||||||
|
<p>{paciente.sexo || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">CPF:</label>
|
||||||
|
<p>{paciente.cpf || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">RG:</label>
|
||||||
|
<p>{paciente.rg || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Outro documento:</label>
|
||||||
|
<p>{paciente.outros_documentos?.tipo || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Número do documento:</label>
|
||||||
|
<p>{paciente.outros_documentos?.numero || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Etnia:</label>
|
||||||
|
<p>{paciente.etnia || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Raça:</label>
|
||||||
|
<p>{paciente.raca || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Naturalidade:</label>
|
||||||
|
<p>{paciente.etniaRaca || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Profissão:</label>
|
||||||
|
<p>{paciente.profissao || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Nome da Mãe:</label>
|
||||||
|
<p>{paciente.nome_mae || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Profissão da mãe:</label>
|
||||||
|
<p>{paciente.profissao_mae || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Nome do Pai:</label>
|
||||||
|
<p>{paciente.nome_pai || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Profissão do pai:</label>
|
||||||
|
<p>{paciente.profissao_pai || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Nome do responsável:</label>
|
||||||
|
<p>{paciente.nome_responsavel || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">CPF do responsável:</label>
|
||||||
|
<p>{paciente.cpf_responsavel || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Estado civil:</label>
|
||||||
|
<p>{paciente.estado_civil || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Nome do esposo(a):</label>
|
||||||
|
<p>{paciente.nome_conjuge || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Identificador de outro sistema:</label>
|
||||||
|
<p>{paciente.outro_id || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<div className="form-check">
|
||||||
|
<input className="form-check-input" type="checkbox" checked={paciente.rnConvenio} disabled/>
|
||||||
|
<label className="font-extrabold">RN na Guia do convênio:</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Observações:</label>
|
||||||
|
<p>{paciente.observacoes || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Anexos do Paciente:</label>
|
||||||
|
<p>{ "-"}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* ------------------ INFORMAÇÕES MÉDICAS ------------------ */}
|
||||||
|
<div className="card p-3 shadow-sm">
|
||||||
|
<h5>Informações Médicas</h5>
|
||||||
|
<hr />
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-3 mb-3">
|
||||||
|
<label className="font-extrabold">Tipo Sanguíneo:</label>
|
||||||
|
<p>{paciente.tipoSanguineo || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-3 mb-3">
|
||||||
|
<label className="font-extrabold">Peso (kg):</label>
|
||||||
|
<p>{paciente.peso || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-3 mb-3">
|
||||||
|
<label className="font-extrabold">Altura (m):</label>
|
||||||
|
<p>{paciente.altura || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-3 mb-3">
|
||||||
|
<label className="font-extrabold">IMC (kg/m²):</label>
|
||||||
|
<p>{paciente.imc || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Alergias:</label>
|
||||||
|
<p>{paciente.alergias || "-"}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* ------------------ INFORMAÇÕES DE CONVÊNIO ------------------ */}
|
||||||
|
<div className="card p-3 shadow-sm">
|
||||||
|
<h5>Informações de Convênio</h5>
|
||||||
|
<hr />
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Convênio:</label>
|
||||||
|
<p>{paciente.convenio || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Plano:</label>
|
||||||
|
<p>{paciente.plano || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Nº de matrícula:</label>
|
||||||
|
<p>{paciente.numeroMatricula || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-3 mb-3">
|
||||||
|
<label className="font-extrabold">Validade da Carteira:</label>
|
||||||
|
<p>{paciente.validadeCarteira || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-2 d-flex align-items-end mb-3">
|
||||||
|
<div className="form-check">
|
||||||
|
<input className="form-check-input" type="checkbox" checked={paciente.validadeIndeterminada} disabled/>
|
||||||
|
<label className="font-extrabold">Validade indeterminada:</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-2 d-flex align-items-end mb-3">
|
||||||
|
<div className="form-check">
|
||||||
|
<input className="form-check-input" type="checkbox" checked={paciente.pacienteVip} disabled/>
|
||||||
|
<label className="font-extrabold">Paciente VIP: </label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* ------------------ ENDEREÇO ------------------ */}
|
||||||
|
<div className="card p-3 shadow-sm">
|
||||||
|
<h5>Endereço</h5>
|
||||||
|
<hr />
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-4 mb-3">
|
||||||
|
<label className="font-extrabold">CEP:</label>
|
||||||
|
<p>{paciente.endereco?.cep || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-8 mb-3">
|
||||||
|
<label className="font-extrabold">Rua:</label>
|
||||||
|
<p>{paciente.endereco?.logradouro || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-4 mb-3">
|
||||||
|
<label className="font-extrabold">Bairro:</label>
|
||||||
|
<p>{paciente.endereco?.bairro || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-4 mb-3">
|
||||||
|
<label className="font-extrabold">Cidade:</label>
|
||||||
|
<p>{paciente.endereco?.cidade || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-2 mb-3">
|
||||||
|
<label className="font-extrabold">Estado:</label>
|
||||||
|
<p>{paciente.endereco?.estado || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-4 mb-3">
|
||||||
|
<label className="font-extrabold">Número:</label>
|
||||||
|
<p>{paciente.endereco?.numero || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-8 mb-3">
|
||||||
|
<label className="font-extrabold">Complemento:</label>
|
||||||
|
<p>{paciente.endereco?.complemento || "-"}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* ------------------ CONTATO ------------------ */}
|
||||||
|
<div className="card p-3 shadow-sm">
|
||||||
|
<h5>Contato</h5>
|
||||||
|
<hr />
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Email:</label>
|
||||||
|
<p>{paciente.contato?.email || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Telefone:</label>
|
||||||
|
<p>{paciente.contato?.celular || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Telefone 2:</label>
|
||||||
|
<p>{paciente.contato?.telefone2 || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Telefone 3:</label>
|
||||||
|
<p>{paciente.contato?.telefone3 || "-"}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const styles = {
|
|
||||||
container: {
|
|
||||||
width: "80%",
|
|
||||||
maxWidth: "800px",
|
|
||||||
margin: "30px auto",
|
|
||||||
background: "#fff",
|
|
||||||
borderRadius: "10px",
|
|
||||||
padding: "20px",
|
|
||||||
boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
|
|
||||||
fontFamily: "Arial, sans-serif",
|
|
||||||
position: "relative"
|
|
||||||
},
|
|
||||||
backBtn: {
|
|
||||||
background: "#ddd",
|
|
||||||
border: "none",
|
|
||||||
borderRadius: "6px",
|
|
||||||
padding: "8px 14px",
|
|
||||||
cursor: "pointer",
|
|
||||||
marginBottom: "15px"
|
|
||||||
},
|
|
||||||
header: {
|
|
||||||
textAlign: "center",
|
|
||||||
marginBottom: "20px",
|
|
||||||
position: "relative"
|
|
||||||
},
|
|
||||||
avatar: {
|
|
||||||
width: "80px",
|
|
||||||
height: "80px",
|
|
||||||
borderRadius: "50%",
|
|
||||||
background: "#ddd",
|
|
||||||
display: "block",
|
|
||||||
margin: "0 auto"
|
|
||||||
},
|
|
||||||
nome: {
|
|
||||||
margin: "10px 0 5px"
|
|
||||||
},
|
|
||||||
vip: {
|
|
||||||
color: "#f7b500",
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginLeft: "5px"
|
|
||||||
},
|
|
||||||
cpf: {
|
|
||||||
margin: "5px 0",
|
|
||||||
color: "#555"
|
|
||||||
},
|
|
||||||
editBtn: {
|
|
||||||
background: "#0d6efd",
|
|
||||||
color: "white",
|
|
||||||
padding: "8px 14px",
|
|
||||||
border: "none",
|
|
||||||
borderRadius: "6px",
|
|
||||||
cursor: "pointer",
|
|
||||||
position: "absolute",
|
|
||||||
right: "20px",
|
|
||||||
top: "20px"
|
|
||||||
},
|
|
||||||
section: {
|
|
||||||
marginBottom: "20px",
|
|
||||||
border: "1px solid #e0e0e0",
|
|
||||||
borderRadius: "8px",
|
|
||||||
padding: "15px"
|
|
||||||
},
|
|
||||||
sectionTitle: {
|
|
||||||
marginTop: 0,
|
|
||||||
borderBottom: "1px solid #ddd",
|
|
||||||
paddingBottom: "8px",
|
|
||||||
fontSize: "18px"
|
|
||||||
},
|
|
||||||
grid: {
|
|
||||||
display: "grid",
|
|
||||||
gridTemplateColumns: "1fr 1fr",
|
|
||||||
gap: "10px 20px",
|
|
||||||
marginTop: "10px"
|
|
||||||
},
|
|
||||||
item: {
|
|
||||||
fontSize: "14px"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Details;
|
export default Details;
|
||||||
@ -4,7 +4,7 @@ import React, { useState } from 'react';
|
|||||||
import DoctorList from '../components/doctors/DoctorList';
|
import DoctorList from '../components/doctors/DoctorList';
|
||||||
import DoctorForm from '../components/doctors/DoctorForm';
|
import DoctorForm from '../components/doctors/DoctorForm';
|
||||||
|
|
||||||
function FormLayout( ) {
|
function DoctorCadastroManager( ) {
|
||||||
// Este estado vai controlar qual "tela" mostrar: 'list' (lista) ou 'form' (formulário)
|
// Este estado vai controlar qual "tela" mostrar: 'list' (lista) ou 'form' (formulário)
|
||||||
const [view, setView] = useState('form');
|
const [view, setView] = useState('form');
|
||||||
|
|
||||||
@ -66,4 +66,4 @@ function FormLayout( ) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default FormLayout;
|
export default DoctorCadastroManager;
|
||||||
@ -0,0 +1,182 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import avatarPlaceholder from '../assets/images/avatar_placeholder.png';
|
||||||
|
|
||||||
|
const Details = ({ patientID, setCurrentPage }) => {
|
||||||
|
const [paciente, setPaciente] = useState({});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!patientID) return;
|
||||||
|
|
||||||
|
fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientID}`)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => setPaciente(data))
|
||||||
|
.catch(err => console.error("Erro ao buscar médico:", err));
|
||||||
|
}, [patientID]);
|
||||||
|
|
||||||
|
//if (!paciente) return <p style={{ textAlign: "center" }}>Carregando...</p>;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="card p-3 shadow-sm">
|
||||||
|
<h3 className="mb-3 text-center">MediConnect</h3>
|
||||||
|
<hr />
|
||||||
|
<div className="d-flex justify-content-between align-items-center mb-3">
|
||||||
|
<button className="btn btn-success me-2" onClick={() => setCurrentPage("table")}>
|
||||||
|
<i className="bi bi-chevron-left"></i> Voltar
|
||||||
|
</button>
|
||||||
|
<div className="d-flex mb-3">
|
||||||
|
<div className="avatar avatar-xl">
|
||||||
|
<img src={avatarPlaceholder} alt="" />
|
||||||
|
</div>
|
||||||
|
<div className="media-body ms-3 font-extrabold">
|
||||||
|
<span>{paciente.nome || "Nome Completo"}</span>
|
||||||
|
<p>{paciente.cpf || "CPF"}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button className="btn btn-light" onClick={() => setCurrentPage("edit-page-doctor")}>
|
||||||
|
<i className="bi bi-pencil-square"></i> Editar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* ------------------ DADOS PESSOAIS ------------------ */}
|
||||||
|
<div className="card p-3 shadow-sm">
|
||||||
|
<h5 className="mb-3">Dados Pessoais</h5>
|
||||||
|
<hr />
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Nome:</label>
|
||||||
|
<p>{paciente.nome || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Nome social:</label>
|
||||||
|
<p>{paciente.nomeSocial || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Data de nascimento:</label>
|
||||||
|
<p>{paciente.dataNascimento || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Gênero:</label>
|
||||||
|
<p>{paciente.sexo || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">CPF:</label>
|
||||||
|
<p>{paciente.cpf || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">CRM:</label>
|
||||||
|
<p>{paciente.rg || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Outro documento:</label>
|
||||||
|
<p>{paciente.documento || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Número do documento:</label>
|
||||||
|
<p>{paciente.numeroDocumento || "-"}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Etnia e Raça:</label>
|
||||||
|
<p>{paciente.etniaRaca || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Nacionalidade:</label>
|
||||||
|
<p>{paciente.etniaRaca || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Naturalidade:</label>
|
||||||
|
<p>{paciente.etniaRaca || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Especialização:</label>
|
||||||
|
<p>{paciente.profissao || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Estado civil:</label>
|
||||||
|
<p>{paciente.estadoCivil || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Nome do esposo(a):</label>
|
||||||
|
<p>{paciente.nomeConjuge || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Identificador de outro sistema:</label>
|
||||||
|
<p>{paciente.outroId || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Observações:</label>
|
||||||
|
<p>{paciente.observacoes || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Anexos do Médico:</label>
|
||||||
|
<p>{paciente.anexos || "-"}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* ------------------ ENDEREÇO ------------------ */}
|
||||||
|
<div className="card p-3 shadow-sm">
|
||||||
|
<h5>Endereço</h5>
|
||||||
|
<hr />
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-4 mb-3">
|
||||||
|
<label className="font-extrabold">CEP:</label>
|
||||||
|
<p>{paciente.cep || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-8 mb-3">
|
||||||
|
<label className="font-extrabold">Rua:</label>
|
||||||
|
<p>{paciente.rua || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-4 mb-3">
|
||||||
|
<label className="font-extrabold">Bairro:</label>
|
||||||
|
<p>{paciente.bairro || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-4 mb-3">
|
||||||
|
<label className="font-extrabold">Cidade:</label>
|
||||||
|
<p>{paciente.cidade || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-2 mb-3">
|
||||||
|
<label className="font-extrabold">Estado:</label>
|
||||||
|
<p>{paciente.estado || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-4 mb-3">
|
||||||
|
<label className="font-extrabold">Número:</label>
|
||||||
|
<p>{paciente.numero || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-8 mb-3">
|
||||||
|
<label className="font-extrabold">Complemento:</label>
|
||||||
|
<p>{paciente.complemento || "-"}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* ------------------ CONTATO ------------------ */}
|
||||||
|
<div className="card p-3 shadow-sm">
|
||||||
|
<h5>Contato</h5>
|
||||||
|
<hr />
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Email:</label>
|
||||||
|
<p>{paciente.email || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Telefone:</label>
|
||||||
|
<p>{paciente.telefone1 || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Telefone 2:</label>
|
||||||
|
<p>{paciente.telefone2 || "-"}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 mb-3">
|
||||||
|
<label className="font-extrabold">Celular:</label>
|
||||||
|
<p>{paciente.telefone3 || "-"}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Details;
|
||||||
@ -1,52 +1,51 @@
|
|||||||
// import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
// import DoctorForm from '../components/doctors/DoctorForm'
|
import DoctorForm from '../components/doctors/DoctorForm'
|
||||||
|
|
||||||
// import {useEffect, useState} from 'react'
|
import {useEffect, useState} from 'react'
|
||||||
|
|
||||||
// const EditPage = ( {id}) => {
|
const DoctorEditPage = ( {id}) => {
|
||||||
|
|
||||||
// const [PatientToPUT, setPatientPUT] = useState({})
|
const [PatientToPUT, setPatientPUT] = useState({})
|
||||||
|
|
||||||
// var requestOptions = {
|
var requestOptions = {
|
||||||
// method: 'GET',
|
method: 'GET',
|
||||||
// redirect: 'follow'
|
redirect: 'follow'
|
||||||
// };
|
};
|
||||||
|
|
||||||
// useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
||||||
|
|
||||||
// fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}`, requestOptions)
|
fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}`, requestOptions)
|
||||||
// .then(response => response.json())
|
.then(response => response.json())
|
||||||
// .then(result => result.data)
|
.then(result => result.data)
|
||||||
// .then(data => console.log(data))
|
.then(data => console.log(data))
|
||||||
// .catch(error => console.log('error', error));
|
.catch(error => console.log('error', error));
|
||||||
|
|
||||||
// }, [])
|
}, [])
|
||||||
// const HandlePutPatient = () => {
|
const HandlePutPatient = () => {
|
||||||
|
|
||||||
// console.log('médico atualizado')
|
console.log('médico atualizado')
|
||||||
|
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
|
||||||
// return (
|
return (
|
||||||
|
|
||||||
// <div>
|
<div>
|
||||||
|
|
||||||
// <button>Voltar para lista sem salvar</button>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// <PatientForm
|
|
||||||
// onSave={HandlePutPatient}
|
|
||||||
// onCancel={console.log('Não atualizar')}
|
|
||||||
// PatientDict={PatientToPUT}
|
|
||||||
|
|
||||||
// />
|
<DoctorForm
|
||||||
|
onSave={HandlePutPatient}
|
||||||
|
onCancel={console.log('Não atualizar')}
|
||||||
|
PatientDict={PatientToPUT}
|
||||||
|
|
||||||
// </div>
|
/>
|
||||||
// )
|
|
||||||
// }
|
|
||||||
|
|
||||||
// export default EditPage
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DoctorEditPage
|
||||||
@ -1,13 +1,12 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from "react";
|
||||||
import DoctorList from '../components/doctors/DoctorList';
|
|
||||||
import DoctorForm from '../components/doctors/DoctorForm';
|
|
||||||
|
|
||||||
function TableDoctor({ setCurrentPage, setPatientID }) {
|
function TableDoctor({ setCurrentPage, setPatientID }) {
|
||||||
const [pacientes, setPacientes] = useState([]);
|
const [medicos, setMedicos] = useState([]);
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
|
const [filtroAniversariante, setFiltroAniversariante] = useState(false);
|
||||||
|
|
||||||
// Função para excluir médicos
|
// Função para excluir médicos
|
||||||
const deletePatient = async (id) => {
|
const deleteDoctor = async (id) => {
|
||||||
const requestOptionsDelete = { method: "DELETE", redirect: "follow" };
|
const requestOptionsDelete = { method: "DELETE", redirect: "follow" };
|
||||||
|
|
||||||
if (!window.confirm("Tem certeza que deseja excluir este médico?")) return;
|
if (!window.confirm("Tem certeza que deseja excluir este médico?")) return;
|
||||||
@ -21,46 +20,35 @@ function TableDoctor({ setCurrentPage, setPatientID }) {
|
|||||||
.catch((error) => console.log("Deu problema", error));
|
.catch((error) => console.log("Deu problema", error));
|
||||||
};
|
};
|
||||||
|
|
||||||
const onChange = (e, id) => {
|
// Função para verificar se hoje é aniversário
|
||||||
let value = e.target.value;
|
const ehAniversariante = (dataNascimento) => {
|
||||||
|
if (!dataNascimento) return false;
|
||||||
|
const hoje = new Date();
|
||||||
|
const nascimento = new Date(dataNascimento);
|
||||||
|
|
||||||
if (value === "verdetalhes") {
|
return (
|
||||||
setCurrentPage("details-page-paciente");
|
hoje.getDate() === nascimento.getDate() &&
|
||||||
}
|
hoje.getMonth() === nascimento.getMonth()
|
||||||
|
);
|
||||||
if (value === "editar") {
|
|
||||||
setCurrentPage("edit-page-paciente");
|
|
||||||
setPatientID(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value === "excluir") {
|
|
||||||
console.log(`Excluir ${id}`);
|
|
||||||
deletePatient(id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var requestOptions = {
|
|
||||||
method: "GET",
|
|
||||||
redirect: "follow",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Buscar médicos da API
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetch(
|
fetch("https://mock.apidog.com/m1/1053378-0-default/pacientes")
|
||||||
"https://mock.apidog.com/m1/1053378-0-default/pacientes",
|
|
||||||
requestOptions
|
|
||||||
)
|
|
||||||
.then((response) => response.json())
|
.then((response) => response.json())
|
||||||
.then((result) => setPacientes(result["data"]))
|
.then((result) => setMedicos(result["data"]))
|
||||||
.catch((error) =>
|
.catch((error) =>
|
||||||
console.log("Erro para encontrar médicos no banco de dados", error)
|
console.log("Erro para encontrar médicos no banco de dados", error)
|
||||||
);
|
);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Filtrar médicos pelo campo de pesquisa (nome, cpf, email, telefone)
|
// Filtrar médicos pelo campo de pesquisa e aniversariantes
|
||||||
const pacientesFiltrados = pacientes.filter((paciente) =>
|
const medicosFiltrados = medicos.filter(
|
||||||
`${paciente.nome} ${paciente.cpf} ${paciente.email} ${paciente.telefone}`
|
(medico) =>
|
||||||
|
`${medico.nome} ${medico.cpf} ${medico.email} ${medico.telefone}`
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
.includes(search.toLowerCase())
|
.includes(search.toLowerCase()) &&
|
||||||
|
(filtroAniversariante ? ehAniversariante(medico.data_nascimento) : true)
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -72,7 +60,7 @@ function TableDoctor({ setCurrentPage, setPatientID }) {
|
|||||||
<section className="row">
|
<section className="row">
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
<div className="card">
|
<div className="card">
|
||||||
{/* Header com título e botão alinhados */}
|
|
||||||
<div className="card-header d-flex justify-content-between align-items-center">
|
<div className="card-header d-flex justify-content-between align-items-center">
|
||||||
<h4 className="card-title mb-0">Médicos Cadastrados</h4>
|
<h4 className="card-title mb-0">Médicos Cadastrados</h4>
|
||||||
<button
|
<button
|
||||||
@ -84,17 +72,30 @@ function TableDoctor({ setCurrentPage, setPatientID }) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
{/* Barra de pesquisa abaixo do título */}
|
|
||||||
<div className="mb-3">
|
<div className="d-flex gap-2 mb-3">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Pesquisar médico..."
|
placeholder="Pesquisar médico..."
|
||||||
value={search}
|
value={search}
|
||||||
onChange={(e) => setSearch(e.target.value)}
|
onChange={(e) => setSearch(e.target.value)}
|
||||||
className="form-control"
|
className="form-control"
|
||||||
|
style={{ maxWidth: "300px" }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<button
|
||||||
|
className={`btn ${
|
||||||
|
filtroAniversariante
|
||||||
|
? "btn-primary"
|
||||||
|
: "btn-outline-primary"
|
||||||
|
}`}
|
||||||
|
onClick={() => setFiltroAniversariante(!filtroAniversariante)}
|
||||||
|
>
|
||||||
|
<i className="bi bi-calendar me-1"></i> Aniversariantes
|
||||||
|
</button>
|
||||||
</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>
|
||||||
@ -103,43 +104,80 @@ function TableDoctor({ setCurrentPage, setPatientID }) {
|
|||||||
<th>CPF</th>
|
<th>CPF</th>
|
||||||
<th>Email</th>
|
<th>Email</th>
|
||||||
<th>Telefone</th>
|
<th>Telefone</th>
|
||||||
<th>Opções</th>
|
<th></th>
|
||||||
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{pacientesFiltrados.length > 0 ? (
|
{medicosFiltrados.length > 0 ? (
|
||||||
pacientesFiltrados.map((paciente) => (
|
medicosFiltrados.map((medico) => (
|
||||||
<tr key={paciente.id}>
|
<tr key={medico.id}>
|
||||||
<td>{paciente.nome}</td>
|
<td>{medico.nome}</td>
|
||||||
<td>{paciente.cpf}</td>
|
<td>{medico.cpf}</td>
|
||||||
<td>{paciente.email}</td>
|
<td>{medico.email}</td>
|
||||||
<td>{paciente.telefone}</td>
|
<td>{medico.telefone}</td>
|
||||||
<td>
|
<td>
|
||||||
<span
|
<span
|
||||||
className={`badge ${
|
className={`badge ${
|
||||||
paciente.ativo === "ativo"
|
medico.ativo === "ativo"
|
||||||
? "bg-success"
|
? "bg-success"
|
||||||
: "bg-danger"
|
: "bg-danger"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{paciente.ativo}
|
{medico.ativo}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<select onChange={(e) => onChange(e, paciente.id)}>
|
<div className="d-flex gap-2">
|
||||||
<option value="">:</option>
|
|
||||||
<option value="verdetalhes">Ver detalhes</option>
|
<button
|
||||||
<option value="editar">Editar</option>
|
className="btn btn-sm"
|
||||||
<option value="excluir">Excluir</option>
|
style={{
|
||||||
</select>
|
backgroundColor: "#E6F2FF",
|
||||||
|
color: "#004085",
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
setCurrentPage("details-page-paciente");
|
||||||
|
setPatientID(medico.id);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<i className="bi bi-eye me-1"></i> Ver
|
||||||
|
Detalhes
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
className="btn btn-sm"
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#FFF3CD",
|
||||||
|
color: "#856404",
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
setCurrentPage("edit-page-paciente");
|
||||||
|
setPatientID(medico.id);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<i className="bi bi-pencil me-1"></i> Editar
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
className="btn btn-sm"
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#F8D7DA",
|
||||||
|
color: "#721C24",
|
||||||
|
}}
|
||||||
|
onClick={() => deleteDoctor(medico.id)}
|
||||||
|
>
|
||||||
|
<i className="bi bi-trash me-1"></i> Excluir
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<tr>
|
<tr>
|
||||||
<td colSpan="6" className="text-center">
|
<td colSpan="6" className="text-center">
|
||||||
Nenhum paciente encontrado.
|
Nenhum médico encontrado.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
)}
|
)}
|
||||||
@ -154,4 +192,5 @@ function TableDoctor({ setCurrentPage, setPatientID }) {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TableDoctor;
|
export default TableDoctor;
|
||||||
@ -19,13 +19,32 @@ useEffect(() => {
|
|||||||
fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}`, requestOptions)
|
fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}`, requestOptions)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(result => result.data)
|
.then(result => result.data)
|
||||||
.then(data => console.log(data))
|
.then(data => setPatientPUT(data))
|
||||||
.catch(error => console.log('error', error));
|
.catch(error => console.log('error', error));
|
||||||
|
|
||||||
}, [])
|
}, [])
|
||||||
const HandlePutPatient = () => {
|
|
||||||
|
|
||||||
console.log('paciente atualizado')
|
const HandlePutPatient = () => {
|
||||||
|
alert(`Atualizando paciente "${PatientToPUT.nome}" com sucesso`)
|
||||||
|
var myHeaders = new Headers();
|
||||||
|
myHeaders.append("Authorization", "Bearer <token>");
|
||||||
|
myHeaders.append("Content-Type", "application/json");
|
||||||
|
|
||||||
|
var raw = JSON.stringify(PatientToPUT)
|
||||||
|
|
||||||
|
console.log(PatientToPUT)
|
||||||
|
|
||||||
|
var requestOptions = {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: myHeaders,
|
||||||
|
body: raw,
|
||||||
|
redirect: 'follow'
|
||||||
|
};
|
||||||
|
|
||||||
|
fetch("https://mock.apidog.com/m1/1053378-0-default/pacientes/", requestOptions)
|
||||||
|
.then(response => response.text())
|
||||||
|
.then(result => console.log('ATUALIZADO COM SUCESSO',result))
|
||||||
|
.catch(error => console.log('error', error));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,15 +53,14 @@ fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}`, requestOpt
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
<button>Voltar para lista sem salvar</button>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<PatientForm
|
<PatientForm
|
||||||
onSave={HandlePutPatient}
|
onSave={HandlePutPatient}
|
||||||
onCancel={console.log('Não atualizar')}
|
onCancel={console.log('Não atualizar')}
|
||||||
PatientDict={PatientToPUT}
|
|
||||||
|
|
||||||
|
formData={PatientToPUT}
|
||||||
|
setFormData={setPatientPUT}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,113 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
|
|
||||||
function EmailApp() {
|
|
||||||
// Lista fake de emails para exibir
|
|
||||||
const emails = [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
from: "Open source project public release",
|
|
||||||
preview: "Hey John, bah kivu decrete epanorthotic unnotched...",
|
|
||||||
time: "4:14 AM",
|
|
||||||
starred: true,
|
|
||||||
avatar: "https://i.pravatar.cc/40?img=1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
from: "Ecommerce website Paypal integration",
|
|
||||||
preview: "We will start the new application development soon...",
|
|
||||||
time: "2:15 AM",
|
|
||||||
starred: false,
|
|
||||||
avatar: "https://i.pravatar.cc/40?img=2"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
from: "How To Set Intentions That Energize You",
|
|
||||||
preview: "I will provide you more details after this Saturday...",
|
|
||||||
time: "Yesterday",
|
|
||||||
starred: false,
|
|
||||||
avatar: "https://i.pravatar.cc/40?img=3"
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className="page-heading">
|
|
||||||
<h3>Email Application</h3>
|
|
||||||
<p className="text-muted">An application for user to check email inbox</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="page-content">
|
|
||||||
<div className="row">
|
|
||||||
{/* Sidebar */}
|
|
||||||
<div className="col-3">
|
|
||||||
<button className="btn btn-primary w-100 mb-3">Compose</button>
|
|
||||||
<ul className="list-group">
|
|
||||||
<li className="list-group-item">📥 Inbox</li>
|
|
||||||
<li className="list-group-item">📤 Sent</li>
|
|
||||||
<li className="list-group-item">📝 Draft</li>
|
|
||||||
<li className="list-group-item">⭐ Starred</li>
|
|
||||||
<li className="list-group-item">🚫 Spam</li>
|
|
||||||
<li className="list-group-item">🗑 Trash</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h6 className="mt-4">Labels</h6>
|
|
||||||
<ul className="list-group">
|
|
||||||
<li className="list-group-item">🏷 Product</li>
|
|
||||||
<li className="list-group-item">💼 Work</li>
|
|
||||||
<li className="list-group-item">📌 Misc</li>
|
|
||||||
<li className="list-group-item">👨👩👧 Family</li>
|
|
||||||
<li className="list-group-item">🎨 Design</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Emails */}
|
|
||||||
<div className="col-9">
|
|
||||||
<div className="d-flex justify-content-between mb-2">
|
|
||||||
<div>
|
|
||||||
<button className="btn btn-light me-2">🗑</button>
|
|
||||||
<button className="btn btn-light me-2">✉</button>
|
|
||||||
<button className="btn btn-light me-2">📌</button>
|
|
||||||
<button className="btn btn-light me-2">🏷</button>
|
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
className="form-control w-50"
|
|
||||||
placeholder="Search email.."
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="list-group">
|
|
||||||
{emails.map((mail) => (
|
|
||||||
<div
|
|
||||||
key={mail.id}
|
|
||||||
className="list-group-item d-flex align-items-center justify-content-between"
|
|
||||||
>
|
|
||||||
<div className="d-flex align-items-center">
|
|
||||||
<input type="checkbox" className="me-2" />
|
|
||||||
<img
|
|
||||||
src={mail.avatar}
|
|
||||||
alt="avatar"
|
|
||||||
className="rounded-circle me-2"
|
|
||||||
width={40}
|
|
||||||
height={40}
|
|
||||||
/>
|
|
||||||
<div>
|
|
||||||
<strong>{mail.from}</strong>
|
|
||||||
<p className="mb-0 text-muted small">{mail.preview}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
{mail.starred ? "⭐" : "☆"} <br />
|
|
||||||
<small className="text-muted">{mail.time}</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default EmailApp;
|
|
||||||
@ -1,82 +0,0 @@
|
|||||||
import React, { useState } from "react";
|
|
||||||
|
|
||||||
function GalleryApp() {
|
|
||||||
const [photos, setPhotos] = useState([
|
|
||||||
{ id: 1, url: "https://picsum.photos/400/300?random=7", title: "Paisagem 1" },
|
|
||||||
/*{url da fotos },*/
|
|
||||||
/*{url da fotos },*/
|
|
||||||
/*{url da fotos },*/
|
|
||||||
/*{url da fotos },*/
|
|
||||||
/*{url da fotos },*/
|
|
||||||
]);
|
|
||||||
|
|
||||||
const [selectedPhoto, setSelectedPhoto] = useState(null);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="page-content">
|
|
||||||
<div className="page-heading">
|
|
||||||
<h3>Galeria de Fotos</h3>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Grade de fotos */}
|
|
||||||
<div className="row">
|
|
||||||
{photos.map((photo) => (
|
|
||||||
<div key={photo.id} className="col-12 col-md-4 mb-4">
|
|
||||||
<div className="card shadow-sm" onClick={() => setSelectedPhoto(photo)}>
|
|
||||||
<img
|
|
||||||
src={photo.url}
|
|
||||||
alt={photo.title}
|
|
||||||
className="card-img-top"
|
|
||||||
style={{ borderRadius: "10px", cursor: "pointer" }}
|
|
||||||
/>
|
|
||||||
<div className="card-body text-center">
|
|
||||||
<h6>{photo.title}</h6>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Modal de visualização */}
|
|
||||||
{selectedPhoto && (
|
|
||||||
<div
|
|
||||||
className="modal d-block"
|
|
||||||
style={{
|
|
||||||
background: "rgba(0,0,0,0.7)",
|
|
||||||
position: "fixed",
|
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
width: "100%",
|
|
||||||
height: "100%",
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
}}
|
|
||||||
onClick={() => setSelectedPhoto(null)}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="modal-content p-3 bg-white"
|
|
||||||
style={{ maxWidth: "800px", borderRadius: "12px" }}
|
|
||||||
onClick={(e) => e.stopPropagation()}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
src={selectedPhoto.url}
|
|
||||||
alt={selectedPhoto.title}
|
|
||||||
className="img-fluid"
|
|
||||||
style={{ borderRadius: "12px" }}
|
|
||||||
/>
|
|
||||||
<h5 className="mt-2">{selectedPhoto.title}</h5>
|
|
||||||
<button
|
|
||||||
className="btn btn-danger mt-2"
|
|
||||||
onClick={() => setSelectedPhoto(null)}
|
|
||||||
>
|
|
||||||
Fechar
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default GalleryApp;
|
|
||||||
137
src/pages/Inicio.jsx
Normal file
137
src/pages/Inicio.jsx
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import { FaUser, FaUserPlus, FaCalendarAlt, FaCalendarCheck } from 'react-icons/fa';
|
||||||
|
import './style/Inicio.css';
|
||||||
|
|
||||||
|
function Inicio({ setCurrentPage }) {
|
||||||
|
const [pacientes, setPacientes] = useState([]);
|
||||||
|
const [agendamentos, setAgendamentos] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchPacientes = async () => {
|
||||||
|
try {
|
||||||
|
const res = await fetch("https://mock.apidog.com/m1/1053378-0-default/pacientes");
|
||||||
|
const data = await res.json();
|
||||||
|
setPacientes(data.data);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erro ao buscar pacientes:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchAgendamentos = async () => {
|
||||||
|
try {
|
||||||
|
const res = await fetch();
|
||||||
|
const data = await res.json();
|
||||||
|
setAgendamentos(data.data);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erro ao buscar agendamentos:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchPacientes();
|
||||||
|
fetchAgendamentos();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const totalPacientes = pacientes.length;
|
||||||
|
const novosEsseMes = pacientes.filter(p => p.createdAt && new Date(p.createdAt).getMonth() === new Date().getMonth()).length;
|
||||||
|
|
||||||
|
const hoje = new Date();
|
||||||
|
const agendamentosDoDia = agendamentos.filter(
|
||||||
|
a => a.data && new Date(a.data).getDate() === hoje.getDate()
|
||||||
|
);
|
||||||
|
const agendamentosHoje = agendamentosDoDia.length;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="dashboard-container">
|
||||||
|
<div className="dashboard-header">
|
||||||
|
|
||||||
|
<h1>Bem-vindo ao MediConnect</h1><br></br>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="stats-grid">
|
||||||
|
<div className="stat-card">
|
||||||
|
<div className="stat-info">
|
||||||
|
<span className="stat-label">TOTAL DE PACIENTES</span>
|
||||||
|
<span className="stat-value">{totalPacientes}</span>
|
||||||
|
</div>
|
||||||
|
<div className="stat-icon-wrapper blue"><FaUser className="stat-icon" /></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="stat-card">
|
||||||
|
<div className="stat-info">
|
||||||
|
<span className="stat-label">NOVOS ESTE MÊS</span>
|
||||||
|
<span className="stat-value">{novosEsseMes}</span>
|
||||||
|
</div>
|
||||||
|
<div className="stat-icon-wrapper green"><FaUserPlus className="stat-icon" /></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="stat-card">
|
||||||
|
<div className="stat-info">
|
||||||
|
<span className="stat-label">AGENDAMENTOS HOJE</span>
|
||||||
|
<span className="stat-value">{agendamentosHoje}</span>
|
||||||
|
</div>
|
||||||
|
<div className="stat-icon-wrapper purple"><FaCalendarCheck className="stat-icon" /></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="stat-card">
|
||||||
|
<div className="stat-info">
|
||||||
|
<span className="stat-label">PENDÊNCIAS</span>
|
||||||
|
<span className="stat-value">0</span>
|
||||||
|
</div>
|
||||||
|
<div className="stat-icon-wrapper orange"><FaCalendarAlt className="stat-icon" /></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="quick-actions">
|
||||||
|
<h2>Ações Rápidas</h2>
|
||||||
|
<div className="actions-grid">
|
||||||
|
<div className="action-button" onClick={() => setCurrentPage('form-layout')}>
|
||||||
|
<FaUserPlus className="action-icon" />
|
||||||
|
<div className="action-info">
|
||||||
|
<span className="action-title">Novo Paciente</span>
|
||||||
|
<span className="action-desc">Cadastrar um novo paciente</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="action-button" onClick={() => setCurrentPage('table')}>
|
||||||
|
<FaUser className="action-icon" />
|
||||||
|
<div className="action-info">
|
||||||
|
<span className="action-title">Lista de Pacientes</span>
|
||||||
|
<span className="action-desc">Ver todos os pacientes</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="action-button" onClick={() => setCurrentPage('agendamento')}>
|
||||||
|
<FaCalendarCheck className="action-icon" />
|
||||||
|
<div className="action-info">
|
||||||
|
<span className="action-title">Agendamentos</span>
|
||||||
|
<span className="action-desc">Gerenciar consultas</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appointments-section">
|
||||||
|
<h2>Próximos Agendamentos</h2>
|
||||||
|
{agendamentosHoje > 0 ? (
|
||||||
|
<div>
|
||||||
|
{agendamentosDoDia.map(agendamento => (
|
||||||
|
<div key={agendamento.id} className="agendamento-item">
|
||||||
|
<p>{agendamento.nomePaciente}</p>
|
||||||
|
<p>{new Date(agendamento.data).toLocaleTimeString()}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="no-appointments-content">
|
||||||
|
<FaCalendarCheck className="no-appointments-icon" />
|
||||||
|
<p>Nenhum agendamento para hoje</p>
|
||||||
|
<button className="manage-button" onClick={() => setCurrentPage('agendamento')}>
|
||||||
|
Gerenciar Agendamentos
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Inicio;
|
||||||
374
src/pages/LaudoManager.jsx
Normal file
374
src/pages/LaudoManager.jsx
Normal file
@ -0,0 +1,374 @@
|
|||||||
|
// src/pages/LaudoManager.jsx
|
||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
|
||||||
|
/* ===== Estilos embutidos ===== */
|
||||||
|
/* Eu coloquei os estilos aqui para simplificar a edição. */
|
||||||
|
const styles = `
|
||||||
|
.laudo-wrap { display:flex; gap:24px; padding:18px; font-family: Inter, Roboto, Arial, sans-serif; }
|
||||||
|
.left-col { width: 100%; max-width: 1160px; background:#ffffff; border-radius:8px; padding:18px; box-shadow: 0 1px 0 rgba(0,0,0,0.03); } /* <-- fundo branco */
|
||||||
|
.title-row { display:flex; justify-content:space-between; align-items:center; margin-bottom:12px; }
|
||||||
|
.page-title { font-size:20px; color:#2b4a78; font-weight:700; }
|
||||||
|
.laudo-row { display:flex; padding:14px 12px; align-items:center; border-bottom:1px solid #eef3f8; position:relative; overflow:visible; background: transparent; }
|
||||||
|
.col { flex:1; padding:0 8px; font-size:14px; color:#2e3a4b; }
|
||||||
|
.col.small { flex:0 0 90px; text-align:right; }
|
||||||
|
.row-actions { position:relative; flex: 0 0 88px; display:flex; justify-content:flex-end; }
|
||||||
|
.action-btn { background:transparent; border:1px solid #d7e6fb; border-radius:8px; height:40px; width:40px; display:flex; align-items:center; justify-content:center; cursor:pointer; }
|
||||||
|
.dropdown { position:absolute; right:0; top:48px; background:white; border-radius:8px; box-shadow: 0 10px 30px rgba(20,30,50,0.12); min-width:220px; padding:8px 0; z-index:9999; }
|
||||||
|
.dropdown .item { padding:12px 18px; cursor:pointer; font-size:15px; color:#244056; }
|
||||||
|
.dropdown .item:hover { background:#f6fbff; }
|
||||||
|
.viewer-modal, .preview-modal, .confirm-modal { position:fixed; inset:0; display:flex; align-items:center; justify-content:center; z-index:12000; pointer-events:none; } /* deixar pointer-events none para que não bloqueie por padrão */
|
||||||
|
.modal-backdrop { position:absolute; inset:0; background: rgba(9,20,40,0.45); pointer-events:auto; } /* usado apenas quando necessário */
|
||||||
|
.modal-card { position:relative; width:92%; max-width:1100px; background:white; border-radius:10px; padding:18px; box-shadow: 0 10px 60px rgba(10,20,40,0.25); max-height:88vh; overflow:auto; pointer-events:auto; }
|
||||||
|
.viewer-header { display:flex; justify-content:space-between; align-items:flex-start; gap:10px; margin-bottom:12px; }
|
||||||
|
.patient-info { font-size:13px; color:#3a556b; }
|
||||||
|
.toolbar { display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin-bottom:12px; }
|
||||||
|
.tool-btn { padding:8px 10px; border-radius:6px; border:1px solid #e6eef8; cursor:pointer; background:#fff; font-size:13px; }
|
||||||
|
.editor-area { border:1px solid #e6eef8; border-radius:8px; padding:14px; min-height:360px; background: #fff; color:#1f2d3d; font-size:15px; line-height:1.5; }
|
||||||
|
.footer-controls { display:flex; justify-content:space-between; align-items:center; margin-top:12px; }
|
||||||
|
.toggle { display:flex; align-items:center; gap:8px; }
|
||||||
|
.btn { padding:8px 12px; border-radius:8px; border:none; cursor:pointer; font-weight:600; }
|
||||||
|
.btn.secondary { background:#eef6ff; color:#2f63a6; border:1px solid #d6e9ff; }
|
||||||
|
.btn.primary { background:#2f63a6; color:white; }
|
||||||
|
.small-muted { color:#7f95a8; font-size:13px; }
|
||||||
|
.empty { padding:40px; text-align:center; color:#7d97b4; }
|
||||||
|
|
||||||
|
/* notificação simples (centralizada) */
|
||||||
|
.notice-card { position:fixed; top:50%; left:50%; transform:translate(-50%,-50%); background:#fff; border-radius:8px; padding:14px 18px; box-shadow:0 8px 30px rgba(10,20,40,0.12); z-index:13000; pointer-events:auto; max-width:720px; }
|
||||||
|
`;
|
||||||
|
|
||||||
|
/* ===== Mock data (simula APIDOG) ===== */
|
||||||
|
function mockFetchLaudos() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
id: "LAU-300551296",
|
||||||
|
pedido: 300551296,
|
||||||
|
data: "29/07/2025",
|
||||||
|
paciente: { nome: "Sarah Mariana Oliveira", cpf: "616.869.070-**", nascimento: "1990-03-25", convenio: "Unimed" },
|
||||||
|
solicitante: "Sandro Rangel Santos",
|
||||||
|
exame: "US - Abdome Total",
|
||||||
|
conteudo: "RELATÓRIO MÉDICO\n\nAchados: Imagens compatíveis com ...\nConclusão: Órgãos sem alterações significativas.",
|
||||||
|
status: "rascunho"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "LAU-300659170",
|
||||||
|
pedido: 300659170,
|
||||||
|
data: "29/07/2025",
|
||||||
|
paciente: { nome: "Laissa Helena Marquetti", cpf: "950.684.57-**", nascimento: "1986-09-12", convenio: "Bradesco" },
|
||||||
|
solicitante: "Sandro Rangel Santos",
|
||||||
|
exame: "US - Mamária Bilateral",
|
||||||
|
conteudo: "RELATÓRIO MÉDICO\n\nAchados: text...",
|
||||||
|
status: "liberado"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "LAU-300658301",
|
||||||
|
pedido: 300658301,
|
||||||
|
data: "28/07/2025",
|
||||||
|
paciente: { nome: "Vera Lúcia Oliveira Santos", cpf: "928.005.**", nascimento: "1979-02-02", convenio: "Particular" },
|
||||||
|
solicitante: "Dr. Fulano",
|
||||||
|
exame: "US - Transvaginal",
|
||||||
|
conteudo: "RELATÓRIO MÉDICO\n\nAchados: ...",
|
||||||
|
status: "entregue"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function mockDeleteLaudo(id) {
|
||||||
|
return new Promise((res) => setTimeout(() => res({ ok: true }), 500));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Componente ===== */
|
||||||
|
export default function LaudoManager() {
|
||||||
|
const [laudos, setLaudos] = useState([]);
|
||||||
|
const [openDropdownId, setOpenDropdownId] = useState(null);
|
||||||
|
|
||||||
|
/* viewerLaudo é usado para mostrar o editor/leitura;
|
||||||
|
previewLaudo é usado para a pré-visualização (sem bloquear) */
|
||||||
|
const [viewerLaudo, setViewerLaudo] = useState(null);
|
||||||
|
const [previewLaudo, setPreviewLaudo] = useState(null);
|
||||||
|
const [showPreview, setShowPreview] = useState(false);
|
||||||
|
|
||||||
|
const [showConfirmDelete, setShowConfirmDelete] = useState(false);
|
||||||
|
const [toDelete, setToDelete] = useState(null);
|
||||||
|
const [loadingDelete, setLoadingDelete] = useState(false);
|
||||||
|
|
||||||
|
/* notificação simples (sem backdrop) para 'sem permissão' */
|
||||||
|
const [showNoPermission, setShowNoPermission] = useState(false);
|
||||||
|
|
||||||
|
/* pesquisa */
|
||||||
|
const [query, setQuery] = useState("");
|
||||||
|
|
||||||
|
/* Para simplificar: eu assumo aqui que estamos na visão da secretaria */
|
||||||
|
const isSecretary = true; // permanece true (somente leitura)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const el = document.createElement("style");
|
||||||
|
el.innerHTML = styles;
|
||||||
|
document.head.appendChild(el);
|
||||||
|
const data = mockFetchLaudos();
|
||||||
|
setLaudos(data);
|
||||||
|
return () => document.head.removeChild(el);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Fecha dropdown ao clicar fora
|
||||||
|
useEffect(() => {
|
||||||
|
function onDocClick(e) {
|
||||||
|
if (e.target.closest && e.target.closest('.action-btn')) return;
|
||||||
|
if (e.target.closest && e.target.closest('.dropdown')) return;
|
||||||
|
setOpenDropdownId(null);
|
||||||
|
}
|
||||||
|
document.addEventListener('click', onDocClick);
|
||||||
|
return () => document.removeEventListener('click', onDocClick);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
function toggleDropdown(id, e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
setOpenDropdownId(prev => (prev === id ? null : id));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (botao editar) */
|
||||||
|
function handleOpenViewer(laudo) {
|
||||||
|
setOpenDropdownId(null);
|
||||||
|
if (isSecretary) {
|
||||||
|
// (notificação sem bloquear)
|
||||||
|
setShowNoPermission(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setViewerLaudo(laudo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (botao imprimir) */
|
||||||
|
function handlePrint(laudo) {
|
||||||
|
// evitar bug: fechar viewer antes de abrir preview
|
||||||
|
setViewerLaudo(null);
|
||||||
|
setPreviewLaudo(laudo);
|
||||||
|
setShowPreview(true);
|
||||||
|
setOpenDropdownId(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (botao excluir) */
|
||||||
|
function handleRequestDelete(laudo) {
|
||||||
|
setToDelete(laudo);
|
||||||
|
setOpenDropdownId(null);
|
||||||
|
setShowConfirmDelete(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (funcionalidade do botao de excluir) */
|
||||||
|
async function doConfirmDelete(confirm) {
|
||||||
|
if (!toDelete) return;
|
||||||
|
if (!confirm) {
|
||||||
|
setShowConfirmDelete(false);
|
||||||
|
setToDelete(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setLoadingDelete(true);
|
||||||
|
try {
|
||||||
|
const resp = await mockDeleteLaudo(toDelete.id);
|
||||||
|
if (resp.ok || resp === true) {
|
||||||
|
// removo o laudo da lista local
|
||||||
|
setLaudos(curr => curr.filter(l => l.id !== toDelete.id));
|
||||||
|
setShowConfirmDelete(false);
|
||||||
|
setToDelete(null);
|
||||||
|
alert("Laudo excluído com sucesso.");
|
||||||
|
} else {
|
||||||
|
alert("Erro ao excluir. Tente novamente.");
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
alert("Erro de rede ao excluir.");
|
||||||
|
} finally {
|
||||||
|
setLoadingDelete(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* filtro de pesquisa (por pedido ou nome do paciente) */
|
||||||
|
const normalized = (s = "") => String(s).toLowerCase();
|
||||||
|
const filteredLaudos = laudos.filter(l => {
|
||||||
|
const q = normalized(query).trim();
|
||||||
|
if (!q) return true;
|
||||||
|
if (normalized(l.pedido).includes(q)) return true;
|
||||||
|
if (normalized(l.paciente?.nome).includes(q)) return true;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="laudo-wrap">
|
||||||
|
<div className="left-col">
|
||||||
|
<div className="title-row">
|
||||||
|
<div>
|
||||||
|
<div className="page-title">Gerenciamento de Laudo</div>
|
||||||
|
{/* removi a linha "Visualização: Secretaria" conforme pedido */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ marginBottom:12 }}>
|
||||||
|
<input
|
||||||
|
placeholder="Pesquisar paciente ou pedido..."
|
||||||
|
value={query}
|
||||||
|
onChange={e => setQuery(e.target.value)}
|
||||||
|
style={{ width:"100%", padding:12, borderRadius:8, border:"1px solid #e6eef8" }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{filteredLaudos.length === 0 ? (
|
||||||
|
<div className="empty">Nenhum laudo encontrado.</div>
|
||||||
|
) : (
|
||||||
|
<div style={{ borderRadius:8, overflow:"visible", boxShadow:"0 0 0 1px #eef6ff" }}>
|
||||||
|
{filteredLaudos.map((l) => (
|
||||||
|
<div className="laudo-row" key={l.id}>
|
||||||
|
<div className="col" style={{ flex: "0 0 160px" }}>
|
||||||
|
<div style={{ fontWeight:700 }}>{l.pedido}</div>
|
||||||
|
<div className="small-muted">{l.data}</div>
|
||||||
|
</div>
|
||||||
|
<div className="col" style={{ flex:2 }}>
|
||||||
|
<div style={{ fontWeight:600 }}>{l.paciente.nome}</div>
|
||||||
|
<div className="small-muted">{l.paciente.cpf} • {l.paciente.convenio}</div>
|
||||||
|
</div>
|
||||||
|
<div className="col" style={{ flex:1 }}>{l.exame}</div>
|
||||||
|
<div className="col small">{l.solicitante}</div>
|
||||||
|
<div className="col small" style={{ flex: "0 0 80px", textAlign:"left" }}>{l.status}</div>
|
||||||
|
|
||||||
|
<div className="row-actions">
|
||||||
|
<div className="action-btn" onClick={(e)=> toggleDropdown(l.id, e)} title="Ações">
|
||||||
|
<svg width="16" height="16" viewBox="0 0 24 24"><circle cx="12" cy="5" r="1.6"/><circle cx="12" cy="12" r="1.6"/><circle cx="12" cy="19" r="1.6"/></svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{openDropdownId === l.id && (
|
||||||
|
<div className="dropdown" data-laudo-dropdown={l.id}>
|
||||||
|
<div className="item" onClick={() => handleOpenViewer(l)}>Editar</div>
|
||||||
|
<div className="item" onClick={() => handlePrint(l)}>Imprimir</div>
|
||||||
|
<div className="item" onClick={() => { alert("Protocolo de entrega: formulário (não implementado)."); setOpenDropdownId(null); }}>Protocolo de entrega</div>
|
||||||
|
<div className="item" onClick={() => { alert("Liberar laudo: requer permissão de médico. (não implementado)"); setOpenDropdownId(null); }}>Liberar laudo</div>
|
||||||
|
<div className="item" onClick={() => handleRequestDelete(l)} style={{ color:"#c23b3b" }}>Excluir laudo</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Viewer modal (modo leitura) — só abre para quem tem permissão */}
|
||||||
|
{viewerLaudo && !showPreview && !isSecretary && (
|
||||||
|
<div className="viewer-modal" style={{ pointerEvents:"auto" }}>
|
||||||
|
<div className="modal-backdrop" onClick={() => setViewerLaudo(null)} />
|
||||||
|
<div className="modal-card" role="dialog" aria-modal="true">
|
||||||
|
<div className="viewer-header">
|
||||||
|
<div>
|
||||||
|
<div style={{ fontSize:18, fontWeight:700 }}>{viewerLaudo.paciente.nome}</div>
|
||||||
|
<div className="patient-info">
|
||||||
|
Nasc.: {viewerLaudo.paciente.nascimento} • {computeAge(viewerLaudo.paciente.nascimento)} anos • {viewerLaudo.paciente.cpf} • {viewerLaudo.paciente.convenio}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ display:"flex", gap:8 }}>
|
||||||
|
<button className="tool-btn" onClick={() => { setPreviewLaudo(viewerLaudo); setShowPreview(true); setViewerLaudo(null); }}>Pré-visualizar / Imprimir</button>
|
||||||
|
<button className="tool-btn" onClick={() => setViewerLaudo(null)}>Fechar</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="toolbar">
|
||||||
|
<div className="tool-btn">B</div>
|
||||||
|
<div className="tool-btn"><i>I</i></div>
|
||||||
|
<div className="tool-btn"><u>U</u></div>
|
||||||
|
<div className="tool-btn">Fonte</div>
|
||||||
|
<div className="tool-btn">Tamanho</div>
|
||||||
|
<div className="tool-btn">Lista</div>
|
||||||
|
<div className="tool-btn">Campos</div>
|
||||||
|
<div className="tool-btn">Modelos</div>
|
||||||
|
<div className="tool-btn">Imagens</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="editor-area" aria-readonly>
|
||||||
|
{viewerLaudo.conteudo.split("\n").map((line, i) => (
|
||||||
|
<p key={i} style={{ margin: line.trim()==="" ? "8px 0" : "6px 0" }}>{line}</p>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="footer-controls">
|
||||||
|
<div className="toggle small-muted">
|
||||||
|
<label><input type="checkbox" disabled /> Pré-visualização</label>
|
||||||
|
<label style={{ marginLeft:12 }}><input type="checkbox" disabled /> Ocultar data</label>
|
||||||
|
<label style={{ marginLeft:12 }}><input type="checkbox" disabled /> Ocultar assinatura</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ display:"flex", gap:8 }}>
|
||||||
|
<button className="btn secondary" onClick={() => { if(window.confirm("Cancelar e voltar à lista? Todas alterações não salvas serão perdidas.")) setViewerLaudo(null); }}>Cancelar</button>
|
||||||
|
<button className="btn primary" onClick={() => alert("Salvar (não implementado para secretaria).")}>Salvar laudo</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Preview modal — agora não bloqueia a tela (sem backdrop escuro), botão imprimir é interativo */}
|
||||||
|
{showPreview && previewLaudo && (
|
||||||
|
<div className="preview-modal" style={{ pointerEvents:"none" /* container não bloqueia */ }}>
|
||||||
|
<div /* sem backdrop, assim não deixa a tela escura/blocked */ />
|
||||||
|
<div className="modal-card" style={{ maxWidth:900, pointerEvents:"auto" }}>
|
||||||
|
<div style={{ display:"flex", justifyContent:"space-between", alignItems:"center", marginBottom:12 }}>
|
||||||
|
<div style={{ fontWeight:700 }}>Pré-visualização - {previewLaudo.paciente.nome}</div>
|
||||||
|
<div style={{ display:"flex", gap:8 }}>
|
||||||
|
<button className="tool-btn" onClick={() => alert("Imprimir (simulado).")}>Imprimir / Download</button>
|
||||||
|
<button className="tool-btn" onClick={() => { setShowPreview(false); setPreviewLaudo(null); }}>Fechar</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ border: "1px solid #e6eef8", borderRadius:6, padding:18, background:"#fff" }}>
|
||||||
|
<div style={{ marginBottom:8, fontSize:14, color:"#33475b" }}>
|
||||||
|
<strong>RELATÓRIO MÉDICO</strong>
|
||||||
|
</div>
|
||||||
|
<div style={{ marginBottom:14, fontSize:13, color:"#546b7f" }}>
|
||||||
|
{previewLaudo.paciente.nome} • Nasc.: {previewLaudo.paciente.nascimento} • CPF: {previewLaudo.paciente.cpf}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ whiteSpace:"pre-wrap", fontSize:15, color:"#1f2d3d", lineHeight:1.5 }}>
|
||||||
|
{previewLaudo.conteudo}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Notificação simples: Sem permissão (exibe sem backdrop escuro) - centralizada */}
|
||||||
|
{showNoPermission && (
|
||||||
|
<div className="notice-card" role="alert" aria-live="polite">
|
||||||
|
<div style={{ fontWeight:700, marginBottom:6 }}>Sem permissão para editar</div>
|
||||||
|
<div style={{ marginBottom:10, color:"#5a6f80" }}>Você está na visualização da secretaria. Edição disponível somente para médicos autorizados.</div>
|
||||||
|
<div style={{ textAlign:"right" }}>
|
||||||
|
<button className="tool-btn" onClick={() => setShowNoPermission(false)}>Fechar</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Confirm delete modal (simples: Sim / Não) */}
|
||||||
|
{showConfirmDelete && toDelete && (
|
||||||
|
<div className="confirm-modal" style={{ pointerEvents:"auto" }}>
|
||||||
|
<div className="modal-card" style={{ maxWidth:480 }}>
|
||||||
|
<div style={{ fontWeight:700, marginBottom:8 }}>Confirmar exclusão</div>
|
||||||
|
<div style={{ marginBottom:12 }}>Você tem certeza que quer excluir o laudo <strong>{toDelete.pedido} - {toDelete.paciente.nome}</strong> ? Esta ação é irreversível.</div>
|
||||||
|
|
||||||
|
<div style={{ display:"flex", justifyContent:"flex-end", gap:8 }}>
|
||||||
|
<button className="tool-btn" onClick={() => doConfirmDelete(false)} disabled={loadingDelete}>Não</button>
|
||||||
|
<button className="tool-btn" onClick={() => doConfirmDelete(true)} disabled={loadingDelete} style={{ background: loadingDelete ? "#d7e8ff" : "#ffecec", border: "1px solid #ffd7d7" }}>
|
||||||
|
{loadingDelete ? "Excluindo..." : "Sim, excluir"}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Helpers ===== */
|
||||||
|
function computeAge(birth) {
|
||||||
|
if (!birth) return "-";
|
||||||
|
const [y,m,d] = birth.split("-").map(x => parseInt(x,10));
|
||||||
|
if (!y) return "-";
|
||||||
|
const today = new Date();
|
||||||
|
let age = today.getFullYear() - y;
|
||||||
|
const mm = today.getMonth() + 1;
|
||||||
|
const dd = today.getDate();
|
||||||
|
if (mm < m || (mm === m && dd < d)) age--;
|
||||||
|
return age;
|
||||||
|
}
|
||||||
@ -1,14 +1,14 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
// Importamos os dois novos componentes que criamos
|
// Importamos os dois novos componentes que criamos
|
||||||
import PatientList from '../components/patients/PatientList';
|
|
||||||
import PatientForm from '../components/patients/PatientForm';
|
import PatientForm from '../components/patients/PatientForm';
|
||||||
|
|
||||||
function FormLayout( ) {
|
function PatientCadastroManager( {setCurrentPage} ) {
|
||||||
// Este estado vai controlar qual "tela" mostrar: 'list' (lista) ou 'form' (formulário)
|
// Este estado vai controlar qual "tela" mostrar: 'list' (lista) ou 'form' (formulário)
|
||||||
const [view, setView] = useState('form');
|
|
||||||
|
|
||||||
|
|
||||||
|
const [formData, setFormData] = useState({})
|
||||||
var myHeaders = new Headers();
|
var myHeaders = new Headers();
|
||||||
myHeaders.append("Content-Type", "application/json");
|
myHeaders.append("Content-Type", "application/json");
|
||||||
|
|
||||||
@ -23,7 +23,6 @@ function FormLayout( ) {
|
|||||||
header: myHeaders,
|
header: myHeaders,
|
||||||
body:raw,
|
body:raw,
|
||||||
redirect:'follow'
|
redirect:'follow'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -34,7 +33,7 @@ function FormLayout( ) {
|
|||||||
|
|
||||||
alert(`Paciente "${patientData.nome}" salvo com sucesso!`); //altere isso para integração com backend
|
alert(`Paciente "${patientData.nome}" salvo com sucesso!`); //altere isso para integração com backend
|
||||||
// Após salvar, voltamos para a tela de lista
|
// Após salvar, voltamos para a tela de lista
|
||||||
setView('list');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -49,16 +48,13 @@ function FormLayout( ) {
|
|||||||
{/* Se a view for 'list', mostramos a lista com o botão. */}
|
{/* Se a view for 'list', mostramos a lista com o botão. */}
|
||||||
{/* Se for 'form', mostramos o formulário de cadastro. */}
|
{/* Se for 'form', mostramos o formulário de cadastro. */}
|
||||||
|
|
||||||
{view === 'list' ? (
|
|
||||||
<PatientList onAddPatient={() => setView('form')} />
|
|
||||||
) : (
|
|
||||||
<PatientForm
|
<PatientForm
|
||||||
onSave={handleSavePatient}
|
onSave={handleSavePatient}
|
||||||
onCancel={() => setView('list')}
|
onCancel={() => {setCurrentPage('table')}}
|
||||||
PatientDict={{}}
|
formData={formData}
|
||||||
|
setFormData={setFormData}
|
||||||
/>
|
/>
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
@ -66,4 +62,4 @@ function FormLayout( ) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default FormLayout;
|
export default PatientCadastroManager;
|
||||||
@ -1,13 +1,77 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from "react";
|
||||||
import PatientList from '../components/patients/PatientList';
|
|
||||||
import PatientForm from '../components/patients/PatientForm';
|
|
||||||
|
|
||||||
function TablePaciente({ setCurrentPage, setPatientID }) {
|
function TablePaciente({ setCurrentPage, setPatientID }) {
|
||||||
const [pacientes, setPacientes] = useState([]);
|
const [pacientes, setPacientes] = useState([]);
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
|
const [filtroConvenio, setFiltroConvenio] = useState("Todos");
|
||||||
|
const [filtroVIP, setFiltroVIP] = useState(false);
|
||||||
|
const [filtroAniversariante, setFiltroAniversariante] = useState(false);
|
||||||
|
|
||||||
|
|
||||||
|
const GetAnexos = 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}/anexos`, requestOptions);
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
return result.data; // agora retorna corretamente
|
||||||
|
} catch (error) {
|
||||||
|
console.log('error', error);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const DeleteAnexo = async (patientID) => {
|
||||||
|
|
||||||
|
|
||||||
|
const RespostaGetAnexos = await GetAnexos(patientID)
|
||||||
|
|
||||||
|
for(let i = 0; i < RespostaGetAnexos.length; i++){
|
||||||
|
|
||||||
|
const idAnexo = RespostaGetAnexos[i].id;
|
||||||
|
|
||||||
|
console.log('anexos',RespostaGetAnexos)
|
||||||
|
|
||||||
|
|
||||||
|
var myHeaders = new Headers();
|
||||||
|
myHeaders.append("Authorization", "Bearer <token>");
|
||||||
|
|
||||||
|
var requestOptions = {
|
||||||
|
method: 'DELETE',
|
||||||
|
headers: myHeaders,
|
||||||
|
redirect: 'follow'
|
||||||
|
};
|
||||||
|
|
||||||
|
fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientID}/anexos/${idAnexo}`, requestOptions)
|
||||||
|
.then(response => response.text())
|
||||||
|
.then(result => console.log('anexo excluido com sucesso',result))
|
||||||
|
.catch(error => console.log('error', error));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Função para excluir paciente
|
// Função para excluir paciente
|
||||||
const deletePatient = async (id) => {
|
const deletePatient = async (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;
|
||||||
@ -21,39 +85,49 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
|
|||||||
.catch((error) => console.log("Deu problema", error));
|
.catch((error) => console.log("Deu problema", error));
|
||||||
};
|
};
|
||||||
|
|
||||||
const onChange = (e, id) => {
|
// Função para marcar/desmarcar VIP
|
||||||
let value = e.target.value;
|
const toggleVIP = async (id, atual) => {
|
||||||
|
const novoStatus = atual === true ? false : true;
|
||||||
|
|
||||||
if(value === 'verdetalhes'){
|
await fetch(
|
||||||
setCurrentPage('details-page-paciente')
|
`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}`,
|
||||||
setPatientID(id);
|
{
|
||||||
|
method: "PUT",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({ vip: novoStatus }),
|
||||||
}
|
}
|
||||||
if(value === 'editar'){
|
|
||||||
setCurrentPage('edit-page-paciente')
|
|
||||||
setPatientID(id);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (value === "excluir") {
|
|
||||||
deletePatient(id);
|
|
||||||
console.log(`Excluir ${id}`);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var requestOptions = {
|
|
||||||
method: "GET",
|
|
||||||
redirect: "follow",
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
fetch(
|
|
||||||
"https://mock.apidog.com/m1/1053378-0-default/pacientes",
|
|
||||||
requestOptions
|
|
||||||
)
|
)
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then(() => {
|
||||||
|
setPacientes((prev) =>
|
||||||
|
prev.map((p) => (p.id === id ? { ...p, vip: novoStatus } : p))
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch((error) => console.log("Erro ao atualizar VIP:", error));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Função para atualizar convênio/particular
|
||||||
|
const updateConvenio = async (id, convenio) => {
|
||||||
|
await fetch(
|
||||||
|
`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}`,
|
||||||
|
{
|
||||||
|
method: "PUT",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({ convenio }),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then(() => {
|
||||||
|
setPacientes((prev) =>
|
||||||
|
prev.map((p) => (p.id === id ? { ...p, convenio } : p))
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch((error) => console.log("Erro ao atualizar convênio:", error));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Requisição inicial para buscar pacientes
|
||||||
|
useEffect(() => {
|
||||||
|
fetch("https://mock.apidog.com/m1/1053378-0-default/pacientes")
|
||||||
.then((response) => response.json())
|
.then((response) => response.json())
|
||||||
.then((result) => setPacientes(result["data"]))
|
.then((result) => setPacientes(result["data"]))
|
||||||
.catch((error) =>
|
.catch((error) =>
|
||||||
@ -61,12 +135,32 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
|
|||||||
);
|
);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Filtrar pacientes pelo campo de pesquisa (nome, cpf, email, telefone)
|
// Função para verificar se hoje é aniversário do paciente
|
||||||
const pacientesFiltrados = pacientes.filter((paciente) =>
|
const ehAniversariante = (dataNascimento) => {
|
||||||
`${paciente.nome} ${paciente.cpf} ${paciente.email} ${paciente.telefone}`
|
if (!dataNascimento) return false;
|
||||||
.toLowerCase()
|
const hoje = new Date();
|
||||||
.includes(search.toLowerCase())
|
const nascimento = new Date(dataNascimento);
|
||||||
|
|
||||||
|
return (
|
||||||
|
hoje.getDate() === nascimento.getDate() &&
|
||||||
|
hoje.getMonth() === nascimento.getMonth()
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const pacientesFiltrados = pacientes.filter((paciente) => {
|
||||||
|
const texto = `${paciente.nome}`.toLowerCase();
|
||||||
|
|
||||||
|
const passaBusca = texto.includes(search.toLowerCase());
|
||||||
|
const passaVIP = filtroVIP ? paciente.vip === true : true;
|
||||||
|
const passaConvenio =
|
||||||
|
filtroConvenio === "Todos" || paciente.convenio === filtroConvenio;
|
||||||
|
const passaAniversario = filtroAniversariante
|
||||||
|
? ehAniversariante(paciente.data_nascimento)
|
||||||
|
: true;
|
||||||
|
|
||||||
|
return passaBusca && passaVIP && passaConvenio && passaAniversario;
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -77,7 +171,6 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
|
|||||||
<section className="row">
|
<section className="row">
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
<div className="card">
|
<div className="card">
|
||||||
{/* Header com título e botão alinhados */}
|
|
||||||
<div className="card-header d-flex justify-content-between align-items-center">
|
<div className="card-header d-flex justify-content-between align-items-center">
|
||||||
<h4 className="card-title mb-0">Pacientes Cadastrados</h4>
|
<h4 className="card-title mb-0">Pacientes Cadastrados</h4>
|
||||||
<button
|
<button
|
||||||
@ -89,16 +182,69 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
{/* Barra de pesquisa abaixo do título */}
|
<div className="card p-3 mb-3">
|
||||||
<div className="mb-3">
|
<h5 className="mb-3">
|
||||||
|
<i className="bi bi-funnel-fill me-2 text-primary"></i> Filtros
|
||||||
|
</h5>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className="d-flex flex-nowrap align-items-center gap-2"
|
||||||
|
style={{ overflowX: "auto", paddingBottom: "6px" }}
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Pesquisar paciente..."
|
className="form-control"
|
||||||
|
placeholder="Buscar por nome..."
|
||||||
value={search}
|
value={search}
|
||||||
onChange={(e) => setSearch(e.target.value)}
|
onChange={(e) => setSearch(e.target.value)}
|
||||||
className="form-control"
|
style={{
|
||||||
|
minWidth: 250,
|
||||||
|
maxWidth: 300,
|
||||||
|
width: 260,
|
||||||
|
flex: "0 0 auto",
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<select
|
||||||
|
className="form-select"
|
||||||
|
value={filtroConvenio}
|
||||||
|
onChange={(e) => setFiltroConvenio(e.target.value)}
|
||||||
|
style={{
|
||||||
|
minWidth: 200,
|
||||||
|
width: 180,
|
||||||
|
flex: "0 0 auto",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<option>Todos os Convênios</option>
|
||||||
|
<option>Bradesco Saúde</option>
|
||||||
|
<option>Hapvida</option>
|
||||||
|
<option>Unimed</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<button
|
||||||
|
className={`btn ${filtroVIP ? "btn-primary" : "btn-outline-primary"
|
||||||
|
}`}
|
||||||
|
onClick={() => setFiltroVIP(!filtroVIP)}
|
||||||
|
style={{ flex: "0 0 auto", whiteSpace: "nowrap" }}
|
||||||
|
>
|
||||||
|
<i className="bi bi-award me-1"></i> VIP
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
className={`btn ${filtroAniversariante
|
||||||
|
? "btn-primary"
|
||||||
|
: "btn-outline-primary"
|
||||||
|
}`}
|
||||||
|
onClick={() =>
|
||||||
|
setFiltroAniversariante(!filtroAniversariante)
|
||||||
|
}
|
||||||
|
style={{ flex: "0 0 auto", whiteSpace: "nowrap" }}
|
||||||
|
>
|
||||||
|
<i className="bi bi-calendar me-1"></i> Aniversariantes
|
||||||
|
</button>
|
||||||
</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">
|
||||||
@ -108,7 +254,6 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
|
|||||||
<th>CPF</th>
|
<th>CPF</th>
|
||||||
<th>Email</th>
|
<th>Email</th>
|
||||||
<th>Telefone</th>
|
<th>Telefone</th>
|
||||||
<th>Opções</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@ -121,8 +266,7 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
|
|||||||
<td>{paciente.telefone}</td>
|
<td>{paciente.telefone}</td>
|
||||||
<td>
|
<td>
|
||||||
<span
|
<span
|
||||||
className={`badge ${
|
className={`badge ${paciente.ativo === "ativo"
|
||||||
paciente.ativo === "ativo"
|
|
||||||
? "bg-success"
|
? "bg-success"
|
||||||
: "bg-danger"
|
: "bg-danger"
|
||||||
}`}
|
}`}
|
||||||
@ -130,20 +274,55 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
|
|||||||
{paciente.ativo}
|
{paciente.ativo}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<select onChange={(e) => onChange(e, paciente.id)}>
|
<div className="d-flex gap-2">
|
||||||
<option value=""> </option>
|
|
||||||
<option value="verdetalhes">Ver detalhes</option>
|
<button
|
||||||
<option value="editar">Editar</option>
|
className="btn btn-sm"
|
||||||
<option value="excluir">Excluir</option>
|
style={{
|
||||||
</select>
|
backgroundColor: "#E6F2FF",
|
||||||
|
color: "#004085",
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
setCurrentPage("details-page-paciente");
|
||||||
|
setPatientID(paciente.id);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<i className="bi bi-eye me-1"></i> Ver Detalhes
|
||||||
|
</button>
|
||||||
|
|
||||||
|
|
||||||
|
<button
|
||||||
|
className="btn btn-sm"
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#FFF3CD",
|
||||||
|
color: "#856404",
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
setCurrentPage("edit-page-paciente");
|
||||||
|
setPatientID(paciente.id);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<i className="bi bi-pencil me-1"></i> Editar
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
className="btn btn-sm"
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#F8D7DA",
|
||||||
|
color: "#721C24",
|
||||||
|
}}
|
||||||
|
onClick={() => deletePatient(paciente.id)}
|
||||||
|
>
|
||||||
|
<i className="bi bi-trash me-1"></i> Excluir
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<tr>
|
<tr>
|
||||||
<td colSpan="6" className="text-center">
|
<td colSpan="8" className="text-center">
|
||||||
Nenhum paciente encontrado.
|
Nenhum paciente encontrado.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -159,4 +338,5 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TablePaciente;
|
export default TablePaciente;
|
||||||
@ -1,84 +0,0 @@
|
|||||||
import React, { useState } from "react";
|
|
||||||
|
|
||||||
function Files() {
|
|
||||||
// 1. Criamos um estado para armazenar o arquivo selecionado pelo usuário
|
|
||||||
const [selectedFile, setSelectedFile] = useState(null);
|
|
||||||
|
|
||||||
// 2. Esta função é chamada quando o usuário seleciona um arquivo no input
|
|
||||||
const handleFileChange = (event) => {
|
|
||||||
// Pegamos o primeiro arquivo da lista (mesmo que só possa selecionar um)
|
|
||||||
const file = event.target.files[0];
|
|
||||||
if (file) {
|
|
||||||
setSelectedFile(file);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 3. Esta função é chamada quando o botão "Enviar Arquivo" é clicado
|
|
||||||
const handleUpload = () => {
|
|
||||||
if (!selectedFile) {
|
|
||||||
alert("Por favor, selecione um arquivo antes de enviar.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Lógica de Envio (Simulação) ---
|
|
||||||
// Em um projeto real, aqui você enviaria o 'selectedFile' para um servidor.
|
|
||||||
// Por enquanto, vamos apenas mostrar um alerta de sucesso.
|
|
||||||
console.log("Enviando o arquivo:", selectedFile.name);
|
|
||||||
alert(`Arquivo "${selectedFile.name}" enviado com sucesso! (Isso é uma simulação)`);
|
|
||||||
|
|
||||||
// Limpa o estado após o envio
|
|
||||||
setSelectedFile(null);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className="page-heading">
|
|
||||||
<h3>Files</h3>
|
|
||||||
</div>
|
|
||||||
<div className="page-content">
|
|
||||||
<section className="row">
|
|
||||||
<div className="col-12">
|
|
||||||
<div className="card">
|
|
||||||
<div className="card-header">
|
|
||||||
<h4 className="card-title">Gerenciamento de Arquivos</h4>
|
|
||||||
</div>
|
|
||||||
<div className="card-body">
|
|
||||||
{/* 4. Adicionamos o input de arquivo e o botão */}
|
|
||||||
<div className="mb-3">
|
|
||||||
<label htmlFor="formFile" className="form-label">
|
|
||||||
Selecione um arquivo para enviar
|
|
||||||
</label>
|
|
||||||
{/* O 'key' ajuda o React a resetar o input quando o arquivo é "enviado" */}
|
|
||||||
<input
|
|
||||||
className="form-control"
|
|
||||||
type="file"
|
|
||||||
id="formFile"
|
|
||||||
onChange={handleFileChange}
|
|
||||||
key={selectedFile ? selectedFile.name : 'no-file'}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Mostra o nome do arquivo selecionado */}
|
|
||||||
{selectedFile && (
|
|
||||||
<p className="text-muted">
|
|
||||||
Arquivo selecionado: <strong>{selectedFile.name}</strong>
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<button
|
|
||||||
className="btn btn-primary"
|
|
||||||
onClick={handleUpload}
|
|
||||||
disabled={!selectedFile} // O botão fica desabilitado se nenhum arquivo for selecionado
|
|
||||||
>
|
|
||||||
<i className="bi bi-upload"></i> Enviar Arquivo
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Files;
|
|
||||||
144
src/pages/style/Agendamento.css
Normal file
144
src/pages/style/Agendamento.css
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
.filtros-container select,
|
||||||
|
.filtros-container input {
|
||||||
|
padding: 0.5rem;
|
||||||
|
border-radius: 5px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
.btn-buscar {
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.unidade-selecionarprofissional{
|
||||||
|
background-color: #fdfdfdde;
|
||||||
|
padding: 20px 10px;
|
||||||
|
display: flex;
|
||||||
|
border-radius:10px ;
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.unidade-selecionarprofissional input, .unidade-selecionarprofissional select {
|
||||||
|
margin-left: 8px;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 5px;
|
||||||
|
width: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unidade-selecionarprofissional select{
|
||||||
|
width: 7%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.busca-atendimento{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
margin:10px;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.busca-atendimento select{
|
||||||
|
padding:5px;
|
||||||
|
border-radius:8px ;
|
||||||
|
margin-left: 15px;
|
||||||
|
background-color: #0078d7;
|
||||||
|
color: white;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.busca-atendimento input{
|
||||||
|
margin-left: 8px;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 5px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-selecionar-tabeladia, .btn-selecionar-tabelasemana, .btn-selecionar-tabelames {
|
||||||
|
background-color: rgba(231, 231, 231, 0.808);
|
||||||
|
padding:8px 10px;
|
||||||
|
font-size: larger;
|
||||||
|
font-weight: bold;
|
||||||
|
border-style: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-selecionar-tabeladia{
|
||||||
|
border-radius: 10px 0px 0px 10px;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-selecionar-tabelames{
|
||||||
|
border-radius: 0px 10px 10px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.btn-selecionar-tabeladia.ativo, .btn-selecionar-tabelasemana.ativo, .btn-selecionar-tabelames.ativo{
|
||||||
|
background-color: lightcyan;
|
||||||
|
border-color: darkcyan;
|
||||||
|
font-weight: bolder;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.legenda-tabela{
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legenda-item-realizado{
|
||||||
|
background-color: #2c5e37;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legenda-item-confirmado{
|
||||||
|
background-color: #1e90ff;
|
||||||
|
}
|
||||||
|
.legenda-item-cancelado{
|
||||||
|
background-color: #d9534f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legenda-item-agendado{
|
||||||
|
background-color: #f0ad4e;
|
||||||
|
}
|
||||||
|
|
||||||
|
#status-card-consulta-realizado, .legenda-item-realizado {
|
||||||
|
background-color: #b7ffbd;
|
||||||
|
border:3px solid #91d392;
|
||||||
|
padding: 5px;
|
||||||
|
font-weight: bold;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#status-card-consulta-cancelado, .legenda-item-cancelado {
|
||||||
|
background-color: #ffb7cc;
|
||||||
|
border:3px solid #ff6c84;
|
||||||
|
padding: 5px;
|
||||||
|
font-weight: bold;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#status-card-consulta-confirmado, .legenda-item-confirmado {
|
||||||
|
background-color: #eef8fb;
|
||||||
|
border:3px solid #d8dfe7;
|
||||||
|
padding: 5px;
|
||||||
|
font-weight: bold;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#status-card-consulta-agendado, .legenda-item-agendado {
|
||||||
|
background-color: #f7f7c4;
|
||||||
|
border:3px solid #f3ce67;
|
||||||
|
padding: 5px;
|
||||||
|
font-weight: bold;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
182
src/pages/style/Inicio.css
Normal file
182
src/pages/style/Inicio.css
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
/* Container Principal */
|
||||||
|
.dashboard-container {
|
||||||
|
padding: 2rem;
|
||||||
|
background-color: #f7f9fc;
|
||||||
|
flex-grow: 1; /* Permite que o container ocupe o espaço restante */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Header */
|
||||||
|
.dashboard-header h1 {
|
||||||
|
font-size: 1.8rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-header p {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Seção de Estatísticas (Cartões) */
|
||||||
|
.stats-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||||
|
gap: 1.5rem;
|
||||||
|
margin-bottom: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 1.5rem;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #888;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-value {
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #444;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-icon-wrapper {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-icon {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cores dos ícones */
|
||||||
|
.stat-icon-wrapper.blue { background-color: #5d5dff; }
|
||||||
|
.stat-icon-wrapper.green { background-color: #30d158; }
|
||||||
|
.stat-icon-wrapper.purple { background-color: #a272ff; }
|
||||||
|
.stat-icon-wrapper.orange { background-color: #f1952e; }
|
||||||
|
|
||||||
|
/* Seção de Ações Rápidas */
|
||||||
|
.quick-actions h2 {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||||
|
gap: 1.5rem;
|
||||||
|
margin-bottom: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-button {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 1.5rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-button:hover {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
box-shadow: 0 6px 15px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-icon {
|
||||||
|
font-size: 2.25rem;
|
||||||
|
margin-right: 1rem;
|
||||||
|
color: #a272ff; /* Cor padrão para os ícones das ações */
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-title {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #444;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-desc {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Seção de Próximos Agendamentos */
|
||||||
|
.appointments-section {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 2rem;
|
||||||
|
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.appointments-section h2 {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-appointments-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
height: 100%;
|
||||||
|
padding: 2rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-appointments-icon {
|
||||||
|
font-size: 3rem;
|
||||||
|
color: #bbb;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-appointments-content p {
|
||||||
|
font-size: 1rem;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manage-button {
|
||||||
|
background-color: #5d5dff;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 0.75rem 1.5rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manage-button:hover {
|
||||||
|
background-color: #4444ff;
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user