Detalhe nas tabelas

This commit is contained in:
Caio Miguel Lima Nunes 2025-09-18 09:45:09 -03:00
parent a502bbdffe
commit d3dd2fdbce
3 changed files with 282 additions and 6280 deletions

6162
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,12 @@
import React, { useState, useEffect } from 'react';
import DoctorList from '../components/doctors/DoctorList';
import DoctorForm from '../components/doctors/DoctorForm';
import React, { useState, useEffect } from "react";
function TableDoctor({ setCurrentPage, setPatientID }) {
const [pacientes, setPacientes] = useState([]);
const [medicos, setMedicos] = useState([]);
const [search, setSearch] = useState("");
const [filtroAniversariante, setFiltroAniversariante] = useState(false);
// Função para excluir médicos
const deletePatient = async (id) => {
const deleteDoctor = async (id) => {
const requestOptionsDelete = { method: "DELETE", redirect: "follow" };
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));
};
const onChange = (e, id) => {
let value = e.target.value;
// Função para verificar se hoje é aniversário
const ehAniversariante = (dataNascimento) => {
if (!dataNascimento) return false;
const hoje = new Date();
const nascimento = new Date(dataNascimento);
if (value === "verdetalhes") {
setCurrentPage("details-page-paciente");
}
if (value === "editar") {
setCurrentPage("edit-page-paciente");
setPatientID(id);
}
if (value === "excluir") {
console.log(`Excluir ${id}`);
deletePatient(id);
}
};
var requestOptions = {
method: "GET",
redirect: "follow",
return (
hoje.getDate() === nascimento.getDate() &&
hoje.getMonth() === nascimento.getMonth()
);
};
// Buscar médicos da API
useEffect(() => {
fetch(
"https://mock.apidog.com/m1/1053378-0-default/pacientes",
requestOptions
)
fetch("https://mock.apidog.com/m1/1053378-0-default/pacientes")
.then((response) => response.json())
.then((result) => setPacientes(result["data"]))
.then((result) => setMedicos(result["data"]))
.catch((error) =>
console.log("Erro para encontrar médicos no banco de dados", error)
);
}, []);
// Filtrar médicos pelo campo de pesquisa (nome, cpf, email, telefone)
const pacientesFiltrados = pacientes.filter((paciente) =>
`${paciente.nome} ${paciente.cpf} ${paciente.email} ${paciente.telefone}`
// Filtrar médicos pelo campo de pesquisa e aniversariantes
const medicosFiltrados = medicos.filter(
(medico) =>
`${medico.nome} ${medico.cpf} ${medico.email} ${medico.telefone}`
.toLowerCase()
.includes(search.toLowerCase())
.includes(search.toLowerCase()) &&
(filtroAniversariante ? ehAniversariante(medico.data_nascimento) : true)
);
return (
@ -72,7 +60,7 @@ function TableDoctor({ setCurrentPage, setPatientID }) {
<section className="row">
<div className="col-12">
<div className="card">
{/* Header com título e botão alinhados */}
<div className="card-header d-flex justify-content-between align-items-center">
<h4 className="card-title mb-0">Médicos Cadastrados</h4>
<button
@ -84,17 +72,30 @@ function TableDoctor({ setCurrentPage, setPatientID }) {
</div>
<div className="card-body">
{/* Barra de pesquisa abaixo do título */}
<div className="mb-3">
<div className="d-flex gap-2 mb-3">
<input
type="text"
placeholder="Pesquisar médico..."
value={search}
onChange={(e) => setSearch(e.target.value)}
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 className="table-responsive">
<table className="table table-striped table-hover">
<thead>
@ -103,43 +104,80 @@ function TableDoctor({ setCurrentPage, setPatientID }) {
<th>CPF</th>
<th>Email</th>
<th>Telefone</th>
<th>Opções</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{pacientesFiltrados.length > 0 ? (
pacientesFiltrados.map((paciente) => (
<tr key={paciente.id}>
<td>{paciente.nome}</td>
<td>{paciente.cpf}</td>
<td>{paciente.email}</td>
<td>{paciente.telefone}</td>
{medicosFiltrados.length > 0 ? (
medicosFiltrados.map((medico) => (
<tr key={medico.id}>
<td>{medico.nome}</td>
<td>{medico.cpf}</td>
<td>{medico.email}</td>
<td>{medico.telefone}</td>
<td>
<span
className={`badge ${
paciente.ativo === "ativo"
medico.ativo === "ativo"
? "bg-success"
: "bg-danger"
}`}
>
{paciente.ativo}
{medico.ativo}
</span>
</td>
<td>
<select onChange={(e) => onChange(e, paciente.id)}>
<option value="">:</option>
<option value="verdetalhes">Ver detalhes</option>
<option value="editar">Editar</option>
<option value="excluir">Excluir</option>
</select>
<div className="d-flex gap-2">
<button
className="btn btn-sm"
style={{
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>
</tr>
))
) : (
<tr>
<td colSpan="6" className="text-center">
Nenhum paciente encontrado.
Nenhum médico encontrado.
</td>
</tr>
)}
@ -154,4 +192,5 @@ function TableDoctor({ setCurrentPage, setPatientID }) {
</>
);
}
export default TableDoctor;

View File

@ -1,10 +1,11 @@
import React, { useState, useEffect } from 'react';
import PatientList from '../components/patients/PatientList';
import PatientForm from '../components/patients/PatientForm';
import React, { useState, useEffect } from "react";
function TablePaciente({ setCurrentPage, setPatientID }) {
const [pacientes, setPacientes] = useState([]);
const [search, setSearch] = useState("");
const [filtroConvenio, setFiltroConvenio] = useState("Todos");
const [filtroVIP, setFiltroVIP] = useState(false);
const [filtroAniversariante, setFiltroAniversariante] = useState(false);
// Função para excluir paciente
const deletePatient = async (id) => {
@ -21,39 +22,49 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
.catch((error) => console.log("Deu problema", error));
};
const onChange = (e, id) => {
let value = e.target.value;
// Função para marcar/desmarcar VIP
const toggleVIP = async (id, atual) => {
const novoStatus = atual === true ? false : true;
if(value === 'verdetalhes'){
setCurrentPage('details-page-paciente')
setPatientID(id);
await fetch(
`https://mock.apidog.com/m1/1053378-0-default/pacientes/${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((result) => setPacientes(result["data"]))
.catch((error) =>
@ -61,12 +72,32 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
);
}, []);
// Filtrar pacientes pelo campo de pesquisa (nome, cpf, email, telefone)
const pacientesFiltrados = pacientes.filter((paciente) =>
`${paciente.nome} ${paciente.cpf} ${paciente.email} ${paciente.telefone}`
.toLowerCase()
.includes(search.toLowerCase())
// Função para verificar se hoje é aniversário do paciente
const ehAniversariante = (dataNascimento) => {
if (!dataNascimento) return false;
const hoje = new Date();
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 (
<>
@ -77,7 +108,6 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
<section className="row">
<div className="col-12">
<div className="card">
{/* Header com título e botão alinhados */}
<div className="card-header d-flex justify-content-between align-items-center">
<h4 className="card-title mb-0">Pacientes Cadastrados</h4>
<button
@ -89,16 +119,69 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
</div>
<div className="card-body">
{/* Barra de pesquisa abaixo do título */}
<div className="mb-3">
<div className="card p-3 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
type="text"
placeholder="Pesquisar paciente..."
className="form-control"
placeholder="Buscar por nome..."
value={search}
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 className="table-responsive">
<table className="table table-striped table-hover">
@ -108,7 +191,6 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
<th>CPF</th>
<th>Email</th>
<th>Telefone</th>
<th>Opções</th>
</tr>
</thead>
<tbody>
@ -121,8 +203,7 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
<td>{paciente.telefone}</td>
<td>
<span
className={`badge ${
paciente.ativo === "ativo"
className={`badge ${paciente.ativo === "ativo"
? "bg-success"
: "bg-danger"
}`}
@ -130,20 +211,55 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
{paciente.ativo}
</span>
</td>
<td>
<select onChange={(e) => onChange(e, paciente.id)}>
<option value=""> </option>
<option value="verdetalhes">Ver detalhes</option>
<option value="editar">Editar</option>
<option value="excluir">Excluir</option>
</select>
<div className="d-flex gap-2">
<button
className="btn btn-sm"
style={{
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>
</tr>
))
) : (
<tr>
<td colSpan="6" className="text-center">
<td colSpan="8" className="text-center">
Nenhum paciente encontrado.
</td>
</tr>
@ -159,4 +275,5 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
</>
);
}
export default TablePaciente;