Compare commits

..

No commits in common. "0bf19ab6f2342e8bea165818e2bda7e29cea2f32" and "7ea6c89e8390d2b2ec54d0538bcc21a3135826cb" have entirely different histories.

24 changed files with 1036 additions and 905 deletions

View File

@ -1,27 +1,19 @@
import React, { useState, useMemo } from 'react';
import React, { useState, useMemo } from "react";
import dayjs from "dayjs";
import TabelaAgendamentoDia from '../components/AgendarConsulta/TabelaAgendamentoDia';
import TabelaAgendamentoSemana from '../components/AgendarConsulta/TabelaAgendamentoSemana';
import TabelaAgendamentoMes from '../components/AgendarConsulta/TabelaAgendamentoMes';
import FormNovaConsulta from '../components/AgendarConsulta/FormNovaConsulta';
// Importe os componentes que você está usando
import TabelaAgendamentoDia from "../components/AgendarConsulta/TabelaAgendamentoDia";
import TabelaAgendamentoSemana from "../components/AgendarConsulta/TabelaAgendamentoSemana";
import TabelaAgendamentoMes from "../components/AgendarConsulta/TabelaAgendamentoMes";
import FormNovaConsulta from "../components/AgendarConsulta/FormNovaConsulta";
// NOVO: Caminho de importação corrigido com base na sua estrutura de pastas
import AgendamentosMes from '../components/AgendarConsulta/DadosConsultasMock.js';
import dayjs from 'dayjs';
// Importe os estilos
import "./styleMedico/Agendamento.css";
import "./styleMedico/FilaEspera.css";
const Agendamento = () => {
// --- DADOS E FUNÇÕES FORA DO COMPONENTE ---
const [FiladeEspera, setFiladeEspera] = useState(false);
const [tabela, setTabela] = useState('diario');
const [PageNovaConsulta, setPageConsulta] = useState(false);
const [searchTerm, setSearchTerm] = useState('');
// Dados da fila de espera (sem alteração)
const filaEsperaData = [
const filaEsperaData = [
{ nome: 'Ricardo Pereira', email: 'ricardo.pereira@gmail.com', cpf: '444.777.666-55', telefone: '(79) 99123-4567', entrada: '25/09/2025 às 08:00' },
{ nome: 'Ana Costa', email: 'ana.costa@gmail.com', cpf: '321.654.987-00', telefone: '(79) 97777-3333', entrada: '25/09/2025 às 08:30' },
{ nome: 'Lucas Martins', email: 'lucas.martins@gmail.com', cpf: '777.666.555-33', telefone: '(79) 99654-3210', entrada: '25/09/2025 às 09:00' },
@ -30,197 +22,188 @@ const Agendamento = () => {
{ nome: 'Fernanda Lima', email: 'fernanda.lima@gmail.com', cpf: '888.999.000-22', telefone: '(79) 98877-6655', entrada: '26/09/2025 às 09:30' },
{ nome: 'Carlos Andrade', email: 'carlos.andrade@gmail.com', cpf: '222.555.888-11', telefone: '(79) 99876-5432', entrada: '26/09/2025 às 10:00' },
{ nome: 'Juliana Oliveira', email: 'juliana.o@gmail.com', cpf: '111.222.333-44', telefone: '(79) 98765-1234', entrada: '26/09/2025 às 11:30' },
];
];
// Filtro da fila de espera (sem alteração)
const filteredFila = filaEsperaData.filter(item =>
item.nome.toLowerCase().includes(searchTerm.toLowerCase()) ||
item.email.toLowerCase().includes(searchTerm.toLowerCase()) ||
item.cpf.includes(searchTerm) ||
item.telefone.includes(searchTerm)
);
const ListarDiasdoMes = (ano, mes) => {
const diasDaSemana = [[], [], [], [], [], [], []]; // 0: Domingo, 1: Segunda, ...
const base = dayjs(`${ano}-${mes}-01`);
const diasNoMes = base.daysInMonth();
// Lógica para filtrar os dados da AGENDA (AgendamentosMes)
const filteredAgendamentos = useMemo(() => {
if (!searchTerm.trim()) {
return AgendamentosMes;
for (let d = 1; d <= diasNoMes; d++) {
const data = dayjs(`${ano}-${mes}-${d}`);
const diaDaSemana = data.day(); // Retorna um número de 0 (Dom) a 6 (Sáb)
diasDaSemana[diaDaSemana].push(d);
}
const lowerCaseSearchTerm = searchTerm.toLowerCase();
const filteredData = {};
// Retornando apenas os dias úteis (Segunda a Sexta)
return [
diasDaSemana[1], // Segundas
diasDaSemana[2], // Terças
diasDaSemana[3], // Quartas
diasDaSemana[4], // Quintas
diasDaSemana[5], // Sextas
];
};
for (const semana in AgendamentosMes) {
filteredData[semana] = {};
for (const dia in AgendamentosMes[semana]) {
filteredData[semana][dia] = AgendamentosMes[semana][dia].filter(agendamento =>
agendamento.status === 'vazio' ||
(agendamento.paciente && agendamento.paciente.toLowerCase().includes(lowerCaseSearchTerm))
);
}
}
return filteredData;
}, [searchTerm]);
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]
return ListaDiasDatas
}
// --- COMPONENTE PRINCIPAL ---
const handleClickAgendamento = (agendamento) => {
if (agendamento.status !== 'vazio') return
else setPageConsulta(true)
}
const Agendamento = () => {
const [FiladeEspera, setFiladeEspera] = useState(false);
const [tabela, setTabela] = useState('diario');
const [PageNovaConsulta, setPageConsulta] = useState(false);
const [searchTerm, setSearchTerm] = useState('');
const handleClickCancel = () => setPageConsulta(false)
const filteredFila = useMemo(() =>
filaEsperaData.filter(item =>
item.nome.toLowerCase().includes(searchTerm.toLowerCase()) ||
item.email.toLowerCase().includes(searchTerm.toLowerCase()) ||
item.cpf.includes(searchTerm) ||
item.telefone.includes(searchTerm)
), [searchTerm]);
return (
<div>
<h1>Agendar nova consulta</h1>
const handleClickAgendamento = (agendamento) => {
if (agendamento.status !== 'vazio') return;
setPageConsulta(true);
};
{!PageNovaConsulta ? (
<div className='atendimento-eprocura'>
<div className='busca-atendimento'>
<div>
<i className="fa-solid fa-calendar-day"></i>
<input
type="text"
placeholder="Buscar atendimento por paciente..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
</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>
const handleClickCancel = () => setPageConsulta(false);
<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>
return (
<div>
<h1>Agendar nova consulta</h1>
<div className='container-btns-agenda-fila_esepera'>
<button
className={`btn-agenda ${FiladeEspera === false ? "opc-agenda-ativo" : ""}`}
onClick={() => {
setFiladeEspera(false);
setSearchTerm('');
}}
>
Agenda
</button>
<button
className={`btn-fila-espera ${FiladeEspera === true ? "opc-filaespera-ativo" : ""}`}
onClick={() => {
setFiladeEspera(true);
setSearchTerm('');
}}
>
Fila de espera
</button>
</div>
<section className='calendario-ou-filaespera'>
{FiladeEspera === false ?
(
<div className='calendario'>
<div>
<section className='btns-e-legenda-container'>
<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>
<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>
</section>
{!PageNovaConsulta ? (
<div className='atendimento-eprocura'>
{tabela === "diario" && <TabelaAgendamentoDia handleClickAgendamento={handleClickAgendamento} agendamentos={filteredAgendamentos} />}
{tabela === 'semanal' && <TabelaAgendamentoSemana agendamentos={filteredAgendamentos} />}
{tabela === 'mensal' && <TabelaAgendamentoMes ListarDiasdoMes={ListarDiasdoMes} aplicarCores={true} agendamentos={filteredAgendamentos} />}
</div>
{/* ✅ BARRA DE BUSCA E FILTRO FOI MOVIDA PARA DENTRO DO CALENDÁRIO */}
{/* ✅ BARRA DE UNIDADE E PROFISSIONAL REMOVIDA (COMENTADA) */}
{/*
<div className='unidade-selecionarprofissional'>
<select defaultValue="">
<option value="" disabled >Unidade</option>
<option value="central">Unidade Central</option>
<option value="norte">Unidade Zona Norte</option>
<option value="oeste">Unidade Zona Oeste</option>
</select>
<input type="text" placeholder='Selecionar profissional' />
</div>
*/}
{/* Botões para alternar Agenda / Fila de Espera */}
<div className='container-btns-agenda-fila_esepera'>
<button
className={`btn-agenda ${!FiladeEspera ? "opc-agenda-ativo" : ""}`}
onClick={() => setFiladeEspera(false)}
>
Agenda
</button>
<button
className={`btn-fila-espera ${FiladeEspera ? "opc-filaespera-ativo" : ""}`}
onClick={() => setFiladeEspera(true)}
>
Fila de espera
</button>
</div>
<section className='calendario-ou-filaespera'>
{!FiladeEspera ? (
<div className='calendario'>
<div>
<section className='btns-e-legenda-container'>
<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>
<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>
</section>
{/* ✅ BARRA DE BUSCA MOVIDA PARA CÁ */}
<div className='busca-atendimento'>
<div>
<i className="fa-solid fa-calendar-day"></i>
<input type="text" placeholder="Buscar atendimento" />
</div>
<div>
<select defaultValue="" >
<option value="" disabled>Agendar</option>
<option value="atendimento">Atendimento</option>
<option value="sessoes">Sessões</option>
<option value="urgencia">Urgência</option>
</select>
</div>
</div>
{tabela === "diario" && <TabelaAgendamentoDia handleClickAgendamento={handleClickAgendamento} />}
{tabela === 'semanal' && <TabelaAgendamentoSemana />}
{tabela === 'mensal' && <TabelaAgendamentoMes ListarDiasdoMes={ListarDiasdoMes} aplicarCores={true} />}
</div>
</div>
) : (
<div className="fila-container">
<div className="fila-header">
<input
type="text"
placeholder="Pesquisar..."
className="busca-fila-espera"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
<h2 className="fila-titulo">Fila de Espera</h2>
</div>
<table className="fila-tabela">
<thead>
<tr>
<th>Nome</th>
<th>Email</th>
<th>CPF</th>
<th>Telefone</th>
<th>Entrou na fila de espera</th>
</tr>
</thead>
<tbody>
{filteredFila.map((item, index) => (
<tr key={index}>
<td>{item.nome}</td>
<td>{item.email}</td>
<td>{item.cpf}</td>
<td>{item.telefone}</td>
<td>{item.entrada}</td>
</tr>
))}
</tbody>
</table>
</div>
)}
</section>
</div>
)
:
(
<div className="fila-container">
<div className="fila-header">
<input
type="text"
placeholder="Pesquisar na fila de espera..."
className="busca-fila-espera"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
<h2 className="fila-titulo">Fila de Espera</h2>
</div>
<table className="fila-tabela">
<thead>
<tr>
<th>Nome</th>
<th>Email</th>
<th>CPF</th>
<th>Telefone</th>
<th>Entrou na fila de espera</th>
</tr>
</thead>
<tbody>
{filteredFila.map((item, index) => (
<tr key={index}>
<td>{item.nome}</td>
<td>{item.email}</td>
<td>{item.cpf}</td>
<td>{item.telefone}</td>
<td>{item.entrada}</td>
</tr>
))}
</tbody>
</table>
</div>
)
}
</section>
) : (
<FormNovaConsulta onCancel={handleClickCancel} />
)}
</div>
) : (
<FormNovaConsulta onCancel={handleClickCancel} />
)}
</div>
)
}
);
};
export default Agendamento;

View File

@ -91,7 +91,6 @@ const App = () => {
const [conversations, setConversations] = useState(conversationsData);
const [activeConversationId, setActiveConversationId] = useState(1);
const [newMessage, setNewMessage] = useState('');
const [searchTerm, setSearchTerm] = useState(''); // 1. Estado para a busca
const chatEndRef = useRef(null);
const activeConversation = conversations.find(c => c.id === activeConversationId);
@ -135,11 +134,6 @@ const App = () => {
setConversations(updatedConversations);
};
// 2. Lógica para filtrar as conversas
const filteredConversations = conversations.filter(conversation =>
conversation.patientName.toLowerCase().includes(searchTerm.toLowerCase())
);
return (
<div className="chat-app-container">
{/* Barra Lateral de Conversas */}
@ -147,20 +141,12 @@ const App = () => {
<header className="sidebar-header">
<h1>Mensagens</h1>
<div className="search-container">
{/* ✅ 3. Conecta o input ao estado e à função de atualização */}
<input
type="text"
placeholder="Pesquisar paciente..."
className="search-input"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
<input type="text" placeholder="Pesquisar paciente..." className="search-input" />
<svg className="search-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path></svg>
</div>
</header>
<div className="conversation-list">
{/* ✅ 4. Usa a lista filtrada para renderizar os itens */}
{filteredConversations.map(convo => (
{conversations.map(convo => (
<ConversationListItem
key={convo.id}
conversation={convo}
@ -206,12 +192,7 @@ const App = () => {
</>
) : (
<div className="no-conversation-selected">
{/* Adicionado uma verificação para quando a busca não encontra resultados */}
{searchTerm && filteredConversations.length === 0 ? (
<p>Nenhum paciente encontrado com o nome "{searchTerm}".</p>
) : (
<p>Selecione uma conversa para começar.</p>
)}
<p>Selecione uma conversa para começar.</p>
</div>
)}
</main>
@ -219,4 +200,5 @@ const App = () => {
);
};
export default App;
export default App;

View File

@ -1,11 +1,37 @@
import React, { useState } from 'react';
import React, { useState, useEffect } from 'react';
import { FaUser, FaUserPlus, FaCalendarAlt, FaCalendarCheck } from 'react-icons/fa';
import './style/Inicio.css';
import { useNavigate } from 'react-router-dom';
function Inicio() {
function Inicio({ setCurrentPage }) {
const [pacientes, setPacientes] = useState([]);
const [agendamentos, setAgendamentos] = useState([]);
const navigate = useNavigate();
useEffect(() => {
const fetchPacientes = async () => {
try {
const res = await fetch("https://mock.apidog.com/m1/1053378-0-default/pacientes");
const data = await res.json();
console.log(data)
//setPacientes(data.data);
} catch (error) {
console.error("Erro ao buscar pacientes:", error);
}
};
const fetchAgendamentos = async () => {
return; // <===serve para que nao cause erro
// 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;
@ -61,21 +87,21 @@ function Inicio() {
<div className="quick-actions">
<h2>Ações Rápidas</h2>
<div className="actions-grid">
<div className="action-button" onClick={() => navigate('/form-layout')}>
<div className="action-button" onClick={() => setCurrentPage('form-layout')}>
<FaUserPlus className="action-icon" />
<div className="action-info">
<span className="action-title">Novo Pacient</span>
<span className="action-title">Novo Paciente</span>
<span className="action-desc">Cadastrar um novo paciente</span>
</div>
</div>
<div className="action-button" onClick={() => navigate('/table')}>
<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={() => navigate('agendamento')}>
<div className="action-button" onClick={() => setCurrentPage('agendamento')}>
<FaCalendarCheck className="action-icon" />
<div className="action-info">
<span className="action-title">Agendamentos</span>
@ -100,7 +126,7 @@ function Inicio() {
<div className="no-appointments-content">
<FaCalendarCheck className="no-appointments-icon" />
<p>Nenhum agendamento para hoje</p>
<button className="manage-button" onClick={() => navigate('/medico/agendamento')}>
<button className="manage-button" onClick={() => setCurrentPage('agendamento')}>
Gerenciar Agendamentos
</button>
</div>

View File

@ -1,37 +1,48 @@
import React from 'react';
import CardConsulta from './CardConsulta';
import React from 'react'
import CardConsulta from './CardConsulta'
import AgendamentosMes from './DadosConsultasMock'
import "./style/styleTabelas/tabeladia.css";
const TabelaAgendamentoDia = ({handleClickAgendamento}) => {
const TabelaAgendamentoDia = ({ handleClickAgendamento, agendamentos }) => {
const agendamentosDoDia = agendamentos?.semana1?.segunda || [];
const nomeMedico = agendamentosDoDia.find(item => item.medico)?.medico || 'Profissional';
let agendamentosDessaSemana = AgendamentosMes.semana1
let agendamentos = agendamentosDessaSemana.segunda
console.log(agendamentos)
return (
<div>
<table className='tabeladiaria'>
<thead>
<tr>
<th>Horário</th>
<th>{}</th>
</tr>
</thead>
<div>
<table className='tabeladiaria'>
<thead>
<tr>
<th></th>
<th>{agendamentos.medico}</th>
</tr>
</thead>
<tbody>
{agendamentosDoDia.map((agendamento, index) => (
<tr key={index}>
<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>
);
<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;
export default TabelaAgendamentoDia

View File

@ -1,139 +1,133 @@
import React from 'react';
import dayjs from "dayjs";
import CardConsulta from './CardConsulta';
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 TabelaAgendamentoMes = ({ ListarDiasdoMes, agendamentos }) => {
const dataHoje = dayjs();
const AnoAtual = dataHoje.year();
const mes = dataHoje.month() + 1;
const dataHoje = dayjs()
const AnoAtual = dataHoje.year()
const mes = dataHoje.month() + 1
let ListaDiasDatas = ListarDiasdoMes(AnoAtual, mes);
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];
let sextas = ListaDiasDatas[4]
console.log(AnoAtual, 'ano', mes, 'mes')
return (
<div>
<table className='tabelamensal'>
<thead>
<tr>
<th>Seg</th>
<th>Ter</th>
<th>Qua</th>
<th>Qui</th>
<th>Sex</th>
<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 className='cards-que-faltam'>+ {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 className='cards-que-faltam'>+ {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 className='cards-que-faltam'>+ {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 className='cards-que-faltam'>+ {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 className='cards-que-faltam'>+ {dias.sexta.length - 3}</p></div>
: null}
</div>
</td>
</tr>
</thead>
<tbody>
{agendamentos && Object.entries(agendamentos).map(([semana, dias], index) => (
<tr key={index}>
{/* Coluna de Segunda-feira */}
<td>
<div>
<p>{segundas[index]}</p>
<div>
{(dias.segunda || []).slice(0, 3).map((consulta, idx) => (
<CardConsulta
key={idx}
DadosConsulta={consulta}
className={`usuario-${consulta.cor || "default"}`}
/>
))}
</div>
{(dias.segunda || []).length > 3 ?
<div><p className='cards-que-faltam'>+ {(dias.segunda || []).length - 3}</p></div>
: null}
</div>
</td>
{/* Coluna de Terça-feira */}
<td>
<div>
<p>{tercas[index]}</p>
<div>
{(dias.terca || []).slice(0, 3).map((consulta, idx) => (
<CardConsulta
key={idx}
DadosConsulta={consulta}
className={`usuario-${consulta.cor || "default"}`}
/>
))}
</div>
{(dias.terca || []).length > 3 ?
<div><p className='cards-que-faltam'>+ {(dias.terca || []).length - 3}</p></div>
: null}
</div>
</td>
{/* Coluna de Quarta-feira */}
<td>
<div>
<p>{quartas[index]}</p>
<div>
{(dias.quarta || []).slice(0, 3).map((consulta, idx) => (
<CardConsulta
key={idx}
DadosConsulta={consulta}
className={`usuario-${consulta.cor || "default"}`}
/>
))}
</div>
{(dias.quarta || []).length > 3 ?
<div><p className='cards-que-faltam'>+ {(dias.quarta || []).length - 3}</p></div>
: null}
</div>
</td>
{/* Coluna de Quinta-feira */}
<td>
<div>
<p>{quintas[index]}</p>
<div>
{(dias.quinta || []).slice(0, 3).map((consulta, idx) => (
<CardConsulta
key={idx}
DadosConsulta={consulta}
className={`usuario-${consulta.cor || "default"}`}
/>
))}
</div>
{(dias.quinta || []).length > 3 ?
<div><p className='cards-que-faltam'>+ {(dias.quinta || []).length - 3}</p></div>
: null}
</div>
</td>
{/* Coluna de Sexta-feira */}
<td>
<div>
<p>{sextas[index]}</p>
<div>
{(dias.sexta || []).slice(0, 3).map((consulta, idx) => (
<CardConsulta
key={idx}
DadosConsulta={consulta}
className={`usuario-${consulta.cor || "default"}`}
/>
))}
</div>
{(dias.sexta || []).length > 3 ?
<div><p className='cards-que-faltam'>+ {(dias.sexta || []).length - 3}</p></div>
: null}
</div>
</td>
</tr>
))}
</tbody>
))}
</table>
</div>
)
}
export default TabelaAgendamentoMes;
export default TabelaAgendamentoMes

View File

@ -1,69 +1,54 @@
import React from 'react';
import CardConsulta from './CardConsulta';
import React from 'react'
import AgendamentosMes from './DadosConsultasMock'
import CardConsulta from './CardConsulta'
import "./style/styleTabelas/tabelasemana.css";
const TabelaAgendamentoSemana = () => {
const TabelaAgendamentoSemana = ({ agendamentos }) => {
let AgendamentosDesseMes = AgendamentosMes
const agendamentoSemana = agendamentos?.semana1 || {};
let AgendamentoSemana = AgendamentosDesseMes.semana1
const agendamentosDeSegunda = agendamentoSemana.segunda || [];
const agendamentosDeTerca = agendamentoSemana.terca || [];
const agendamentosDeQuarta = agendamentoSemana.quarta || [];
const agendamentosDeQuinta = agendamentoSemana.quinta || [];
const agendamentosDeSexta = agendamentoSemana.sexta || [];
const numLinhas = Math.max(
agendamentosDeSegunda.length,
agendamentosDeTerca.length,
agendamentosDeQuarta.length,
agendamentosDeQuinta.length,
agendamentosDeSexta.length
);
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'>
<thead>
<tr>
<th>Horário</th>
<th>Segunda</th>
<th>Terça</th>
<th>Quarta</th>
<th>Quinta</th>
<th>Sexta</th>
</tr>
</thead>
<tbody>
{Array.from({ length: numLinhas }).map((_, index) => {
const consultaSeg = agendamentosDeSegunda[index];
const consultaTer = agendamentosDeTerca[index];
const consultaQua = agendamentosDeQuarta[index];
const consultaQui = agendamentosDeQuinta[index];
const consultaSex = agendamentosDeSexta[index];
<div >
const horarioDaLinha = consultaSeg?.horario || consultaTer?.horario || consultaQua?.horario || consultaQui?.horario || consultaSex?.horario;
<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>
return (
<tr key={index}>
<td>{horarioDaLinha}</td>
<td>{consultaSeg && <CardConsulta DadosConsulta={consultaSeg} />}</td>
<td>{consultaTer && <CardConsulta DadosConsulta={consultaTer} />}</td>
<td>{consultaQua && <CardConsulta DadosConsulta={consultaQua} />}</td>
<td>{consultaQui && <CardConsulta DadosConsulta={consultaQui} />}</td>
<td>{consultaSex && <CardConsulta DadosConsulta={consultaSex} />}</td>
</tr>
);
})}
</tbody>
</table>
</div>
);
)
}
export default TabelaAgendamentoSemana;
export default TabelaAgendamentoSemana

View File

@ -15,11 +15,13 @@
border: 1px solid #e0e0e0;
}
/* Estilo aplicado APENAS às células do cabeçalho da tabela */
/* Cabeçalho da semanal */
.tabelasemanal thead th,
.tabelasemanal thead td {
background-color: #0078d7;
color: #ffffff;
.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;

View File

@ -1,37 +1,49 @@
import React, { useState } from 'react';
import { Link } from 'react-router-dom';
import {Link} from 'react-router-dom'
function DoctorForm({ onSave, onCancel, formData, setFormData }) {
const FormatTelefones = (valor) => {
const digits = String(valor).replace(/\D/g, '').slice(0, 11);
return digits
.replace(/(\d)/, '($1')
.replace(/(\d{2})(\d)/, '$1) $2')
.replace(/(\d)(\d{4})/, '$1 $2')
.replace(/(\d{4})(\d{4})/, '$1-$2');
};
const digits = String(valor).replace(/\D/g, '').slice(0, 11);
return digits
.replace(/(\d)/, '($1') // 123 -> 123.
.replace(/(\d{2})(\d)/, '$1) $2' )
.replace(/(\d)(\d{4})/, '$1 $2')
.replace(/(\d{4})(\d{4})/, '$1-$2')
}
const FormatCPF = (valor) => {
const digits = String(valor).replace(/\D/g, '').slice(0, 11);
return digits
.replace(/(\d{3})(\d)/, '$1.$2')
.replace(/(\d{3})(\d)/, '$1.$2')
.replace(/(\d{3})(\d{1,2})$/, '$1-$2');
};
const digits = String(valor).replace(/\D/g, '').slice(0, 11);
return digits
.replace(/(\d{3})(\d)/, '$1.$2') // 123 -> 123.
.replace(/(\d{3})(\d)/, '$1.$2') // 123.456 -> 123.456.
.replace(/(\d{3})(\d{1,2})$/, '$1-$2'); // 123.456.789 -> 123.456.789-01
}
// Estado para armazenar a URL da foto do avatar
const [avatarUrl, setAvatarUrl] = useState(null);
// Estado para controlar seções abertas/fechadas
// Estado para controlar quais seções estão colapsadas
const [collapsedSections, setCollapsedSections] = useState({
dadosPessoais: true,
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,
@ -41,12 +53,15 @@ function DoctorForm({ onSave, onCancel, formData, setFormData }) {
const handleChange = (e) => {
const { name, value, type, checked, files } = e.target;
console.log(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 = () => {
@ -54,25 +69,26 @@ function DoctorForm({ onSave, onCancel, formData, setFormData }) {
};
reader.readAsDataURL(files[0]);
} else if (name === 'foto' && !files[0]) {
setAvatarUrl(null);
setAvatarUrl(null); // Limpa o avatar se nenhum arquivo for selecionado
}
} else if (name.includes('cpf')) {
}
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 }));
} else {
}else {
setFormData({ ...formData, [name]: value });
}
};
// Modal
// Função para buscar endereço pelo CEP
const [showModal, setShowModal] = useState(false);
const [modalMsg, setModalMsg] = useState('');
// Buscar endereço via CEP
const handleCepBlur = async () => {
const cep = formData.cep.replace(/\D/g, '');
if (cep.length === 8) {
@ -98,334 +114,256 @@ function DoctorForm({ onSave, onCancel, formData, setFormData }) {
}
};
// Salvar médico
const handleSubmit = () => {
if (!formData.full_name || !formData.cpf || !formData.birth_date) {
setModalMsg("Por favor, preencha:\n- Nome\n- CPF\n- Data de Nascimento");
if (!formData.full_name || !formData.cpf || !formData.birth_date ) {
setModalMsg('Por favor, preencha: Nome, CPF, Data de Nascimento.');
setShowModal(true);
return; // impede que continue
}
onSave({ ...formData });
setModalMsg("Médico salvo com sucesso!");
onSave(
{
...formData
}
);
setModalMsg('Médico salvo com sucesso!');
setShowModal(true);
};
return (
<>
{/* Modal */}
{/* Modal de feedback */}
{showModal && (
<div
style={{
position: "fixed",
top: 0,
left: 0,
width: "100%",
height: "100%",
backgroundColor: "rgba(0,0,0,0.5)",
display: "flex",
alignItems: "center",
justifyContent: "center",
zIndex: 9999
}}
>
<div
style={{
background: "#fff",
borderRadius: "10px",
width: "400px",
maxWidth: "90%",
boxShadow: "0 6px 20px rgba(0,0,0,0.2)",
overflow: "hidden"
}}
>
{/* Header */}
<div
style={{
background: "#1e3a8a",
padding: "12px 16px",
borderBottom: "1px solid #dee2e6",
display: "flex",
alignItems: "center",
justifyContent: "space-between"
}}
>
<h5 style={{ margin: 0, fontSize: "1.2rem", fontWeight: 600, color: "#ffffffff" }}>Atenção</h5>
<button
onClick={() => setShowModal(false)}
style={{
background: "transparent",
border: "none",
fontSize: "1.2rem",
cursor: "pointer"
}}
>
×
</button>
</div>
{/* Body */}
<div style={{ padding: "16px", color: "#000" }}>
<p
style={{
fontSize: "1.1rem",
fontWeight: 500,
whiteSpace: "pre-line" // <-- garante quebra de linha no texto
}}
>
{modalMsg}
</p>
</div>
{/* Footer */}
<div
style={{
padding: "12px 16px",
borderTop: "1px solid #dee2e6",
display: "flex",
justifyContent: "flex-end"
}}
>
<button
onClick={() => setShowModal(false)}
style={{
background: "#0d6efd",
border: "none",
padding: "8px 16px",
borderRadius: "6px",
color: "#fff",
fontSize: "1rem",
cursor: "pointer"
}}
>
Fechar
</button>
</div>
</div>
</div>
)}
<div className="modal fade show" style={{ display: 'block', alignItems: 'flex-start', justifyContent: 'center' }} tabIndex="-1">
<div className="modal-dialog" style={{ marginTop: '32px' }}>
<div className="modal-content">
<div className="modal-header" style={{ backgroundColor: '# ' }}>
<h5 className="modal-title text-black">Atenção</h5>
<button type="button" className="btn-close" style={{ filter: 'invert(0)' }} onClick={() => setShowModal(false)}></button>
</div>
<div className="modal-body text-black">
<p style={{ fontSize: '1.3rem', fontWeight: 500 }}>{modalMsg}</p>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-primary" onClick={() => setShowModal(false)}>Fechar</button>
</div>
</div>
</div>
</div>
)}
<div className="card p-3 shadow-sm">
<h3 className="mb-4 text-center" style={{ fontSize: '2.5rem' }}>MediConnect</h3>
<h3 className="mb-4 text-center" style={{ fontSize: '2.5rem' }}>MediConnect</h3>
{/* DADOS PESSOAIS */}
<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('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 */}
<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'
}}
>
&#x2624;
</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/*"
{/* DADOS PESSOAIS */}
<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('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' }}
/>
{formData.foto && <span className="ms-2" style={{ fontSize: '1rem' }}>{formData.foto.name}</span>}
</div>
) : (
<div
style={{
width: '100px',
height: '100px',
borderRadius: '50%',
backgroundColor: '#e0e0e0',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: '3.5rem',
color: '#9e9e9e'
}}
>
&#x2624;
</div>
)}
</div>
{/* Inputs */}
<div className="col-md-6 mb-3">
<label style={{ fontSize: '1.1rem' }}>Nome: *</label>
<input type="text" className="form-control" name="full_name" value={formData.full_name} onChange={handleChange} />
</div>
<div className="col-md-6 mb-3">
<label style={{ fontSize: '1.1rem' }}>Data de nascimento: *</label>
<input type="date" className="form-control" name="birth_date" value={formData.birth_date} onChange={handleChange} min="1900-01-01" max="2025-09-24" />
</div>
<div className="col-md-6 mb-3">
<label style={{ fontSize: '1.1rem' }}>CPF: *</label>
<input type="text" className="form-control" name="cpf" value={formData.cpf} onChange={handleChange} />
</div>
<div className="col-md-6 mb-3">
<label style={{ fontSize: '1.1rem' }}>Estado do CRM:</label>
<select className="form-control" name="crm_uf" value={formData.crm_uf} onChange={handleChange}>
<option value="">Selecione</option>
<option value="AP">AP</option>
<option value="AL">AL</option>
<option value="AM">AM</option>
<option value="BA">BA</option>
<option value="CE">CE</option>
<option value="DF">DF</option>
<option value="ES">ES</option>
<option value="GO">GO</option>
<option value="MA">MA</option>
<option value="MT">MT</option>
<option value="MS">MS</option>
<option value="MG">MG</option>
<option value="PA">PA</option>
<option value="PB">PB</option>
<option value="PR">PR</option>
<option value="PE">PE</option>
<option value="PI">PI</option>
<option value="RJ">RJ</option>
<option value="RN">RN</option>
<option value="RS">RS</option>
<option value="RO">RO</option>
<option value="RR">RR</option>
<option value="SC">SC</option>
<option value="SP">SP</option>
<option value="SE">SE</option>
<option value="TO">TO</option>
</select>
</div>
<div className="col-md-6 mb-3">
<label style={{ fontSize: '1.1rem' }}>CRM:</label>
<input type="text" className="form-control" name="crm" value={formData.crm} onChange={handleChange} />
</div>
<div className="col-md-6 mb-3">
<label style={{ fontSize: '1.1rem' }}>Especialização:</label>
<select className="form-control" name="specialty" value={formData.specialty} onChange={handleChange}>
<option value="">Selecione</option>
<option value="Clínica Geral">Clínica médica (clínico geral)</option>
<option value="Pediatria">Pediatria</option>
<option value="Ginecologia">Ginecologia e obstetrícia</option>
<option value="Cardiologia">Cardiologia</option>
<option value="Ortopedia">Ortopedia e traumatologia</option>
<option value="Oftalmologia">Oftalmologia</option>
<option value="Otorrinolaringologia">Otorrinolaringologia</option>
<option value="Dermatologia">Dermatologia</option>
<option value="Neurologia">Neurologia</option>
<option value="Psiquiatria">Psiquiatria</option>
<option value="Endocrinologia">Endocrinologia</option>
<option value="Gastroenterologia">Gastroenterologia</option>
<option value="Urologia">Urologia</option>
</select>
<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>
</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>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="street" value={formData.street} onChange={handleChange} />
</div>
<div className="col-md-6 mb-3">
<label>Bairro:</label>
<input type="text" className="form-control" name="neighborhood" value={formData.neighborhood} onChange={handleChange} />
</div>
<div className="col-md-4 mb-3">
<label>Cidade:</label>
<input type="text" className="form-control" name="city" value={formData.city} onChange={handleChange} />
</div>
<div className="col-md-2 mb-3">
<label>Estado:</label>
<input type="text" className="form-control" name="state" value={formData.state} onChange={handleChange} />
</div>
<div className="col-md-4 mb-3">
<label>Número:</label>
<input type="text" className="form-control" name="number" value={formData.number} onChange={handleChange} />
</div>
<div className="col-md-8 mb-3">
<label>Complemento:</label>
<input type="text" className="form-control" name="complement" value={formData.complement} onChange={handleChange} />
</div>
{/* CADASTRO */}
<div className="col-md-6 mb-3">
<label style={{ fontSize: '1.1rem' }}>Nome: *</label>
<input type="text" className="form-control" name="full_name" value={formData.full_name} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
</div>
</div>
</div>
{/* CONTATO */}
<div className="mb-5 p-4 border rounded shadow-sm">
<h4 className="mb-4 cursor-pointer d-flex justify-content-between align-items-center"
onClick={() => handleToggleCollapse('contato')}
style={{ fontSize: '1.8rem' }}>
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">
<label>Email:</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="phone_mobile" value={formData.phone_mobile} onChange={handleChange} />
</div>
<div className="col-md-6 mb-3">
<label>Telefone 2:</label>
<input type="text" className="form-control" name="phone2" value={formData.phone2} onChange={handleChange} />
</div>
<div className="col-md-6 mb-3">
<label style={{ fontSize: '1.1rem' }}>Data de nascimento: *</label>
<input type="date" className="form-control" name="birth_date" value={formData.birth_date} onChange={handleChange} style={{ fontSize: '1.1rem' }} min="1900-01-01" max="2025-09-24" />
</div>
</div>
</div>
<div className="col-md-6 mb-3">
<label style={{ fontSize: '1.1rem' }}>CPF: *</label>
<input type="text" className="form-control" name="cpf" value={formData.cpf} onChange={ handleChange} style={{ fontSize: '1.1rem' }} />
</div>
{/* BOTÕES */}
<div className="mt-3 text-center">
<button
className="btn btn-success me-3"
onClick={handleSubmit}
style={{ fontSize: '1.2rem', padding: '0.75rem 1.5rem' }}
>
Salvar Médico
</button>
<Link to={'/medicos'}>
<button className="btn btn-light" onClick={onCancel} style={{ fontSize: '1.2rem', padding: '0.75rem 1.5rem' }}>
Cancelar
</button>
</Link>
<div className="col-md-6 mb-3">
<label style={{ fontSize: '1.1rem' }}>Estado do CRM:</label>
<select className="form-control" name="crm_uf" value={formData.crm_uf} onChange={handleChange} style={{ fontSize: '1.1rem' }}>
<option value="" disabled selected>Selecione</option>
<option value="AP">AP</option>
<option value="AL">AL</option>
<option value="AM">AM</option>
<option value="BA">BA</option>
<option value="CE">CE</option>
<option value="DF">DF</option>
<option value="ES">ES</option>
<option value="GO">GO</option>
<option value="MA">MA</option>
<option value="MT">MT</option>
<option value="MS">MS</option>
<option value="MG">MG</option>
<option value="PA">PA</option>
<option value="PB">PB</option>
<option value="PR">PR</option>
<option value="PE">PE</option>
<option value="PI">PI</option>
<option value="RJ">RJ</option>
<option value="RN">RN</option>
<option value="RS">RS</option>
<option value="RO">RO</option>
<option value="RR">RR</option>
<option value="SC">SC</option>
<option value="SP">SP</option>
<option value="SE">SE</option>
<option value="TO">TO</option>
</select>
</div>
<div className="col-md-6 mb-3">
<label style={{ fontSize: '1.1rem' }}>CRM:</label>
<input type="text" className="form-control" name="crm" value={formData.crm} 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="specialty" value={formData.specialty} onChange={handleChange} style={{ fontSize: '1.1rem' }}>
<option value="">Selecione</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>
</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="cep" value={formData.cep} onChange={handleChange} onBlur={handleCepBlur} style={{ fontSize: '1.1rem' }} />
</div>
<div className="col-md-8 mb-3">
<label style={{ fontSize: '1.1rem' }}>Rua:</label>
<input type="text" className="form-control" name="street" value={formData.street} 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="neighborhood" value={formData.neighborhood} 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="city" value={formData.city} 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="state" value={formData.state} 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="number" value={formData.number} 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="complement" value={formData.complement} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
</div>
</div>
</div>
</div>
{/* CONTATO */}
<div className="mb-5 p-4 border rounded shadow-sm">
<h4 className="mb-4 cursor-pointer d-flex justify-content-between align-items-center" onClick={() => handleToggleCollapse('contato')} style={{ fontSize: '1.8rem' }}>
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">
<label style={{ fontSize: '1.1rem' }}>Email: </label>
<input type="email" className="form-control" name="email" value={formData.email} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
</div>
<div className="col-md-6 mb-3">
<label style={{ fontSize: '1.1rem' }}>Telefone: </label>
<input type="text" className="form-control" name="phone_mobile" value={formData.phone_mobile} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
</div>
<div className="col-md-6 mb-3">
<label style={{ fontSize: '1.1rem' }}>Telefone 2:</label>
<input type="text" className="form-control" name="phone2" value={formData.phone2} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
</div>
</div>
</div>
</div>
{/* Botões */}
<div className="mt-3 text-center">
<button className="btn btn-success me-3" onClick={handleSubmit} style={{ fontSize: '1.2rem', padding: '0.75rem 1.5rem' }}>
Salvar Paciente
</button>
<Link to={'/medicos'}>
<button className="btn btn-light" onClick={onCancel} style={{ fontSize: '1.2rem', padding: '0.75rem 1.5rem' }}>
Cancelar
</button>
</Link>
</div>
</div>
</>
);
}

View File

@ -281,20 +281,21 @@ function PatientForm({ onSave, onCancel, formData, setFormData }) {
</label>
</div>
</div>
<div className="col-md-12 mb-3 mt-3">
<div className="form-check">
<input className="form-check-input" type="checkbox" name="vip" checked={formData.vip} onChange={handleChange} id="vip" style={{ transform: 'scale(1.2)' }} />
<label className="form-check-label ms-2" htmlFor="vip" style={{ fontSize: '1.1rem' }}>
Paciente VIP
</label>
</div>
</div>
<div className="col-md-12 mb-3 mt-3">
{/* CAMPOS MOVIDOS */}
<div className="col-md-12 mb-3 mt-3">
<label style={{ fontSize: '1.1rem' }}>Observações:</label>
<textarea className="form-control" name="notes" value={formData.notes} onChange={handleChange} style={{ fontSize: '1.1rem' }} placeholder='alergias, doenças crônicas, informações sobre porteses ou marca-passo, etc'></textarea>
</div>
<div className="col-md-12 mb-3">
<label style={{ fontSize: '1.1rem' }}>Anexos do Paciente:</label>
<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>
@ -331,12 +332,68 @@ function PatientForm({ onSave, onCancel, formData, setFormData }) {
<label style={{ fontSize: '1.1rem' }}>Altura (m):</label>
<input type="text" step="0.01" className="form-control" name="height_m" value={formData.height_m} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
</div>
<div className="col-md-2 mb-3">
<label style={{ fontSize: '1.1rem' }}>IMC (kg/):</label>
<input type="text" className="form-control" name="bmi" value={formData.bmi} readOnly disabled style={{ fontSize: '1.1rem' }} />
</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' }}> de matrícula:</label>
<input type="text" className="form-control" name="numeroMatricula" value={formData.numeroMatricula} onChange={handleChange} style={{ fontSize: '1.1rem' }} />
</div>
<div className="col-md-4 mb-3">
<label style={{ fontSize: '1.1rem' }}>Validade da Carteira:</label>
<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="vip" checked={formData.vip} onChange={handleChange} id="vip" style={{ transform: 'scale(1.2)' }} />
<label className="form-check-label ms-2" htmlFor="vip" 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' }}>
@ -450,7 +507,28 @@ function PatientForm({ onSave, onCancel, formData, setFormData }) {
</div>
)}
{showModal404 && (
<div className="modal" style={{ display: 'block', backgroundColor: 'rgba(0,0,0,0.5)' }}>
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header" style={{ backgroundColor: '#f2fa0dff' }}>
<h5 className="modal-title"><span className="text-dark">Atenção</span></h5>
<button type="button" className="btn-close btn-close-black" onClick={() => setShowModal404(false)}></button>
</div>
<div className="modal-body">
<p style={{ color: '#111', fontSize: '1.4rem' }}>{errorModalMsg || '(Erro 404).Por favor, tente novamente mais tarde'}</p>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-primary" onClick={() => setShowModal404(false)}>
Fechar
</button>
</div>
</div>
</div>
</div>
)}
</div>
);
}

View File

@ -3,6 +3,12 @@
"name": "Menu",
"isTitle": true
},
{
"name":"Início",
"url": "/admin/",
"icon": "house"
},
{
"name": "Lista de Pacientes",
"icon": "clipboard-heart-fill",
@ -14,7 +20,12 @@
"icon": "hospital-fill",
"url": "/admin/medicos"
},
{
"name": "Agendar consulta",
"icon": "calendar-plus-fill",
"url": "/admin/agendamento"
},
{
"name": "Gestão de Usuários",
"icon": "person-badge-fill",

View File

@ -3,6 +3,25 @@
"name": "Menu-Financeiro",
"isTitle": true
},
{
"name":"Início",
"url": "/financeiro/inicio",
"icon": "house"
},
{
"name": "Lista de Pacientes",
"icon": "clipboard-heart-fill",
"url": "/financeiro/pacientes"
},
{
"name": "Lista de Médico",
"icon": "hospital-fill",
"url": "/financeiro/medicos"
},
{
"name": "Controle Financeiro",
"icon": "cash-coin",

View File

@ -3,6 +3,12 @@
"name": "Menu",
"isTitle": true
},
{
"name":"Início",
"url": "/medico/",
"icon": "house"
},
{
"name": "Prontuário",

View File

@ -1,25 +1,22 @@
import React, { useState, useMemo } from 'react';
import React, { useState } 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';
// NOVO: Caminho de importação corrigido com base na sua estrutura de pastas
import AgendamentosMes from '../components/AgendarConsulta/DadosConsultasMock.js';
import dayjs from 'dayjs';
import dayjs from 'dayjs'
import "./style/Agendamento.css";
import './style/FilaEspera.css';
const Agendamento = () => {
const [FiladeEspera, setFiladeEspera] = useState(false);
const [tabela, setTabela] = useState('diario');
const [PageNovaConsulta, setPageConsulta] = useState(false);
const [searchTerm, setSearchTerm] = useState('');
const [FiladeEspera, setFiladeEspera] = useState(false)
const [tabela, setTabela] = useState('diario')
const [PageNovaConsulta, setPageConsulta] = useState(false)
const [searchTerm, setSearchTerm] = useState('') // 🔹 Estado da busca
// Dados da fila de espera (sem alteração)
// 🔹 Dados da fila de espera
const filaEsperaData = [
{ nome: 'Ricardo Pereira', email: 'ricardo.pereira@gmail.com', cpf: '444.777.666-55', telefone: '(79) 99123-4567', entrada: '25/09/2025 às 08:00' },
{ nome: 'Ana Costa', email: 'ana.costa@gmail.com', cpf: '321.654.987-00', telefone: '(79) 97777-3333', entrada: '25/09/2025 às 08:30' },
@ -31,7 +28,7 @@ const Agendamento = () => {
{ nome: 'Juliana Oliveira', email: 'juliana.o@gmail.com', cpf: '111.222.333-44', telefone: '(79) 98765-1234', entrada: '26/09/2025 às 11:30' },
];
// Filtro da fila de espera (sem alteração)
// 🔹 Filtra a fila de espera com base no searchTerm
const filteredFila = filaEsperaData.filter(item =>
item.nome.toLowerCase().includes(searchTerm.toLowerCase()) ||
item.email.toLowerCase().includes(searchTerm.toLowerCase()) ||
@ -39,34 +36,16 @@ const Agendamento = () => {
item.telefone.includes(searchTerm)
);
// Lógica para filtrar os dados da AGENDA (AgendamentosMes)
const filteredAgendamentos = useMemo(() => {
if (!searchTerm.trim()) {
return AgendamentosMes;
}
const lowerCaseSearchTerm = searchTerm.toLowerCase();
const filteredData = {};
for (const semana in AgendamentosMes) {
filteredData[semana] = {};
for (const dia in AgendamentosMes[semana]) {
filteredData[semana][dia] = AgendamentosMes[semana][dia].filter(agendamento =>
agendamento.status === 'vazio' ||
(agendamento.paciente && agendamento.paciente.toLowerCase().includes(lowerCaseSearchTerm))
);
}
}
return filteredData;
}, [searchTerm]);
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
@ -76,6 +55,7 @@ const Agendamento = () => {
default: break
}
}
let ListaDiasDatas = [segundas, tercas, quartas, quintas, sextas]
return ListaDiasDatas
}
@ -92,17 +72,16 @@ const Agendamento = () => {
<h1>Agendar nova consulta</h1>
{!PageNovaConsulta ? (
<div className='atendimento-eprocura'>
{/* 🔍 Busca e filtro */}
<div className='busca-atendimento'>
<div>
<i className="fa-solid fa-calendar-day"></i>
<input
type="text"
placeholder="Buscar atendimento por paciente..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
<input type="text" placeholder="Buscar atendimento" />
</div>
<div>
<select>
<option value="" disabled selected>Agendar</option>
@ -113,6 +92,7 @@ const Agendamento = () => {
</div>
</div>
{/* 🏥 Unidade e profissional */}
<div className='unidade-selecionarprofissional'>
<select>
<option value="" disabled selected >Unidade</option>
@ -120,25 +100,22 @@ const Agendamento = () => {
<option value="">Unidade Zona Norte</option>
<option value="">Unidade Zona Oeste</option>
</select>
<input type="text" placeholder='Selecionar profissional' />
</div>
{/* Botões para alternar Agenda / Fila de Espera */}
<div className='container-btns-agenda-fila_esepera'>
<button
className={`btn-agenda ${FiladeEspera === false ? "opc-agenda-ativo" : ""}`}
onClick={() => {
setFiladeEspera(false);
setSearchTerm('');
}}
onClick={() => setFiladeEspera(false)}
>
Agenda
</button>
<button
className={`btn-fila-espera ${FiladeEspera === true ? "opc-filaespera-ativo" : ""}`}
onClick={() => {
setFiladeEspera(true);
setSearchTerm('');
}}
onClick={() => setFiladeEspera(true)}
>
Fila de espera
</button>
@ -151,43 +128,63 @@ const Agendamento = () => {
<div>
<section className='btns-e-legenda-container'>
<div>
<button className={`btn-selecionar-tabeladia ${tabela === "diario" ? "ativo" : ""}`} onClick={() => setTabela("diario")}>
<i className="fa-solid fa-calendar-day"></i> Dia
<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
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
className={`btn-selecionar-tabelames ${tabela === 'mensal' ? 'ativo' : ''}`}
onClick={() => setTabela("mensal")}
>
<i className="fa-solid fa-calendar-day"></i>
Mês
</button>
</div>
<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>
</section>
{tabela === "diario" && <TabelaAgendamentoDia handleClickAgendamento={handleClickAgendamento} agendamentos={filteredAgendamentos} />}
{tabela === 'semanal' && <TabelaAgendamentoSemana agendamentos={filteredAgendamentos} />}
{tabela === 'mensal' && <TabelaAgendamentoMes ListarDiasdoMes={ListarDiasdoMes} aplicarCores={true} agendamentos={filteredAgendamentos} />}
{tabela === "diario" && <TabelaAgendamentoDia handleClickAgendamento={handleClickAgendamento} />}
{tabela === 'semanal' && <TabelaAgendamentoSemana />}
{tabela === 'mensal' && <TabelaAgendamentoMes ListarDiasdoMes={ListarDiasdoMes} aplicarCores={true} />}
</div>
</div>
)
:
(
<div className="fila-container">
<div className="fila-header">
<input
type="text"
placeholder="Pesquisar na fila de espera..."
className="busca-fila-espera"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
<h2 className="fila-titulo">Fila de Espera</h2>
</div>
<div className="fila-header">
<input
type="text"
placeholder="Pesquisar..."
className="busca-fila-espera"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
<h2 className="fila-titulo">Fila de Espera</h2>
</div>
<table className="fila-tabela">
<thead>
<tr>
@ -215,6 +212,7 @@ const Agendamento = () => {
}
</section>
</div>
) : (
<FormNovaConsulta onCancel={handleClickCancel} />
)}
@ -222,4 +220,4 @@ const Agendamento = () => {
)
}
export default Agendamento;
export default Agendamento

View File

@ -1,26 +1,22 @@
import React, { useEffect, useState } from "react";
import avatarPlaceholder from '../assets/images/avatar_placeholder.png';
import { useParams, useNavigate, useLocation, Navigate } from "react-router-dom";
import { useParams } from "react-router-dom";
import API_KEY from "../components/utils/apiKeys";
import {GetByID} from "../components/utils/Functions-Endpoints/Patient"
import { Link } from "react-router-dom";
import { useAuth } from "../components/utils/AuthProvider";
const Details = () => {
const parametros = useParams();
const {getAuthorizationHeader, isAuthenticated} = useAuth();
const [paciente, setPaciente] = useState({});
const [anexos, setAnexos] = useState([]);
const [selectedFile, setSelectedFile] = useState(null);
const location = useLocation();
const navigate = useNavigate();
const patientID = parametros.id
const Voltar = () => {
const prefixo = location.pathname.split("/")[1];
navigate(`/${prefixo}/pacientes`);
}
useEffect(() => {
if (!patientID) return;
@ -34,8 +30,36 @@ const Details = () => {
})
.catch((err) => console.error("Erro ao buscar paciente:", err));
}, [patientID]);
/*fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientID}/anexos`)
.then(res => res.json())
.then(data => setAnexos(data.data || []))
.catch(err => console.error("Erro ao buscar anexos:", err));
*/
}, [patientID]);
const handleUpload = async () => {
if (!selectedFile) return;
const formData = new FormData();
formData.append('file', selectedFile);
try {
const response = await fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientID}/anexos`, {
method: 'POST',
body: formData,
});
if (response.ok) {
const newAnexo = await response.json();
setAnexos(prev => [...prev, newAnexo]);
setSelectedFile(null);
} else {
console.error('Erro ao enviar anexo');
}
} catch (err) {
console.error('Erro ao enviar anexo:', err);
}
};
const handleDelete = async (anexoId) => {
try {
@ -65,10 +89,11 @@ const Details = () => {
<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={() => Voltar()}>
<Link to={'pacientes'}>
<button className="btn btn-success me-2" >
<i className="bi bi-chevron-left"></i> Voltar
</button>
</Link>
<div className="d-flex mb-3">
<div className="avatar avatar-xl">
@ -172,7 +197,10 @@ const Details = () => {
<label className="font-extrabold">Estado civil:</label>
<p>{paciente.marital_status || "-"}</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.legacy_code || "-"}</p>
@ -182,18 +210,28 @@ const Details = () => {
<input className="form-check-input" type="checkbox" checked={paciente.rn_in_insurance} disabled/>
<label className="font-extrabold">RN na Guia do convênio:</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.vip} disabled/>
<label className="font-extrabold">Paciente VIP: </label>
</div>
</div>
<div className="col-md-6 mb-3">
<label className="font-extrabold">Observações:</label>
<p>{paciente.notes || "-"}</p>
</div>
<div className="col-md-6 mb-3">
<label className="font-extrabold">Anexos do Paciente:</label>
{anexos.length > 0 ?(
<ul>
{anexos.map((anexo) => (
<li key={anexo.id} className="d-flex aling-items-center">
<a href={anexo.url} target="-blank" rel="noopener noreferrer">
{anexo.nome}
</a>
<button className="btn btn-danger btn-sm" onclick={() => handleDelete(anexo.id)} >Remover</button>
</li>
))}
</ul>
) : (
<p>-</p>
)}
</div>
</div>
</div>
@ -222,6 +260,42 @@ const Details = () => {
</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"> 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.vip} 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>

View File

@ -55,7 +55,24 @@ function DoctorCadastroManager( ) {
return (
<>
{/* Modal de feedback */}
{showModal && (
<div className="modal fade show" style={{ display: 'block' }} tabIndex="-1">
<div className="modal-dialog modal-dialog-centered">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title">Sucesso</h5>
<button type="button" className="btn-close" onClick={() => setShowModal(false)}></button>
</div>
<div className="modal-body">
<p>{modalMsg}</p>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-primary" onClick={() => setShowModal(false)}>Fechar</button>
</div>
</div>
</div>
</div>
)}
<div className="page-heading">
<h3>Cadastro de Médicos</h3>
</div>

View File

@ -1,20 +1,13 @@
import React, { useEffect, useState } from "react";
import avatarPlaceholder from '../assets/images/avatar_placeholder.png';
import { useParams,Link, useNavigate, useLocation } from "react-router-dom";
import { useParams,Link } from "react-router-dom";
import { GetDoctorByID } from "../components/utils/Functions-Endpoints/Doctor";
import { useAuth } from "../components/utils/AuthProvider";
const Details = () => {
const {getAuthorizationHeader} = useAuth();
const Details = ({setCurrentPage }) => {
const {getAuthorizationHeader, isAuthenticated} = useAuth();
const [doctor, setDoctor] = useState({});
const Parametros = useParams()
const navigate = useNavigate();
const location = useLocation();
const Voltar = () => {
const prefixo = location.pathname.split("/")[1];
navigate(`/${prefixo}/medicos`);
}
const doctorID = Parametros.id
useEffect(() => {
@ -41,10 +34,11 @@ const Details = () => {
<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={() => Voltar()}>
<i className="bi bi-chevron-left"></i> Voltar
</button>
<Link to={'/medicos'}>
<button className="btn btn-success me-2" >
<i className="bi bi-chevron-left"></i> Voltar
</button>
</Link>
<div className="d-flex mb-3">
<div className="avatar avatar-xl">
<img src={avatarPlaceholder} alt="" />
@ -54,7 +48,7 @@ const Details = () => {
<p>{doctor.cpf || "CPF"}</p>
</div>
</div>
<Link to={`edit`}>
<Link to={`/medicos/${doctor.id}/edit`}>
<button className="btn btn-light" onClick={() => {console.log(doctor.id)}} >
<i className="bi bi-pencil-square"></i> Editar
</button>

View File

@ -48,8 +48,13 @@ const authHeader = getAuthorizationHeader()
};
try {
const response = await fetch(`https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/doctors?id=eq.${DoctorID}`,requestOptions);
const response = await fetch(`https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/doctors?id=eq.${DoctorID}`,requestOptions);
// se o backend retorna JSON
const result = await response.json();
console.log("ATUALIZADO COM SUCESSO", result);
return result;
} catch (error) {
console.error("Erro ao atualizar paciente:", error);
throw error;

View File

@ -75,8 +75,6 @@ function TableDoctor({ setCurrentPage, setPatientID }) {
.catch(error => console.log('error', error));
}, []);
// Filtrar médicos pelo campo de pesquisa e aniversariantes
const medicosFiltrados = medicos.filter(
(medico) =>

View File

@ -53,11 +53,11 @@ const HandlePutPatient = async () => {
try {
const response = await fetch(`https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/patients?id=eq.${PatientID}`,requestOptions);
// se o backend retorna JSON
console.log("Resposta do servidor:", response.ok);
if(response.ok === false){
console.error("Erro ao atualizar paciente:");
const errorText = await response.text();
console.error("Erro ao atualizar paciente:", errorText);
}
else{

View File

@ -37,6 +37,8 @@ function PatientCadastroManager( {} ) {
};
// 23505 - cpf duplicadoo
// 23514 - cpf invalido
try {
const response = await fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/patients", requestOptions);
console.log(response.ok, 'aqui')
@ -53,7 +55,7 @@ function PatientCadastroManager( {} ) {
}
}
else{
console.log("Salvo com sucesso");
console.log("ATUALIZADO COM SUCESSO");
navigate('/pacientes')
}
} catch (error) {

View File

@ -131,19 +131,20 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
);
};
const pacientesFiltrados = pacientes.filter((paciente) => {
const textoCompletoPaciente = `${paciente.nome} ${paciente.cpf} ${paciente.email} ${paciente.telefone}`.toLowerCase();
const passaBusca = textoCompletoPaciente.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;
const pacientesFiltrados = pacientes.filter((paciente) => {
const texto = `${paciente.nome}`.toLowerCase();
return passaBusca && passaVIP && passaConvenio && passaAniversario;
});
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 (
<>
<div className="page-heading">

View File

@ -22,7 +22,7 @@ function Perfiladm() {
<Sidebar menuItems={admItems} />
<div id="main">
<Routes>
<Route path="/" element={<UserDashboard />} />
<Route path="/" element={<Inicio />} />
<Route path="/pacientes/cadastro" element={<PatientCadastroManager />} />
<Route path="/medicos/cadastro" element={<DoctorCadastroManager />} />
<Route path="/pacientes" element={<TablePaciente />} />
@ -33,7 +33,7 @@ function Perfiladm() {
<Route path="/medicos/:id/edit" element={<DoctorEditPage />} />
<Route path="/agendamento" element={<Agendamento />} />
<Route path="/laudo" element={<LaudoManager />} />
<Route path="/laudo" element={<LaudoManager />} />
<Route path="/gestao" element={<UserDashboard />} />
<Route path="/painel" element={<PainelAdministrativo />} />
<Route path="*" element={<h2>Página não encontrada</h2>} />

View File

@ -1,6 +1,7 @@
import { Routes, Route } from "react-router-dom";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Sidebar from "../../components/Sidebar";
import Inicio from "../../pages/Inicio";
import LaudoManager from "../../pages/LaudoManager";
import Prontuario from "../../PagesMedico/prontuario";
import Relatorio from "../../PagesMedico/relatorio";
@ -16,7 +17,7 @@ function PerfilMedico() {
<Sidebar menuItems={DoctorItems} />
<div id="main">
<Routes>
<Route path="/" element={<LaudoManager />} />
<Route path="/" element={<Inicio />} />
<Route path="/laudo" element={<LaudoManager />} />
<Route path="/prontuario" element={<Prontuario />} />
<Route path="/relatorios" element={<Relatorio />} />

View File

@ -2,8 +2,11 @@ import { Routes, Route } from "react-router-dom";
import Sidebar from "../../components/Sidebar";
import FinanceiroItems from "../../data/sidebar-items-financeiro.json";
import Inicio from "../../pages/Inicio";
import TablePaciente from "../../pages/TablePaciente";
import FinanceiroDashboard from "../../pages/FinanceiroDashboard";
import DoctorTable from "../../pages/DoctorTable";
import Details from "../../pages/Details";
import DoctorDetails from "../../pages/DoctorDetails";
function PerfilFinanceiro({ onLogout }) {
return (
@ -12,9 +15,12 @@ function PerfilFinanceiro({ onLogout }) {
<div id="main">
<Routes>
<Route path="/" element={<FinanceiroDashboard/>}/>
<Route path="inicio" element={<Inicio />} />
<Route path="controlefinanceiro" element={<FinanceiroDashboard/>}/>
<Route path="pacientes" element={<TablePaciente />} />
<Route path="medicos" element={<DoctorTable />} />
<Route path="pacientes/:id" element={<Details />} />
<Route path="medicos/:id" element={<DoctorDetails />} />
<Route path="*" element={<h2>Página não encontrada</h2>} />
</Routes>
</div>