riseup-squad23/src/PagesMedico/DoctorRelatorioManager.jsx

366 lines
15 KiB
JavaScript

import API_KEY from '../components/utils/apiKeys';
import { Link } from 'react-router-dom';
import { useState, useEffect } from 'react';
import { useAuth } from '../components/utils/AuthProvider';
import { GetPatientByID } from '../components/utils/Functions-Endpoints/Patient';
import { useNavigate } from 'react-router-dom';
import html2pdf from 'html2pdf.js';
import TiptapViewer from './TiptapViewer';
import './styleMedico/DoctorRelatorioManager.css';
const DoctorRelatorioManager = () => {
const navigate = useNavigate();
const { getAuthorizationHeader } = useAuth();
let authHeader = getAuthorizationHeader();
const [relatoriosOriginais, setRelatoriosOriginais] = useState([]);
const [pacientesData, setPacientesData] = useState({});
const [showModal, setShowModal] = useState(false);
const [relatorioModal, setRelatorioModal] = useState(null);
const [termoPesquisa, setTermoPesquisa] = useState('');
const [filtroExame, setFiltroExame] = useState('');
const [examesDisponiveis, setExamesDisponiveis] = useState([]);
const [relatoriosFinais, setRelatoriosFinais] = useState([]);
const [paginaAtual, setPaginaAtual] = useState(1);
const [itensPorPagina, setItensPorPagina] = useState(10);
useEffect(() => {
const buscarPacientes = async () => {
const pacientesMap = {};
for (const relatorio of relatoriosOriginais) {
if (!pacientesMap[relatorio.patient_id]) {
try {
const paciente = await GetPatientByID(relatorio.patient_id, authHeader);
if (paciente && paciente.length > 0) {
pacientesMap[relatorio.patient_id] = paciente[0];
}
} catch (error) {
console.error('Erro ao buscar paciente:', error);
}
}
}
setPacientesData(pacientesMap);
};
if (relatoriosOriginais.length > 0) {
buscarPacientes();
}
}, [relatoriosOriginais, authHeader]);
useEffect(() => {
let resultados = relatoriosOriginais;
if (termoPesquisa.trim()) {
const termo = termoPesquisa.toLowerCase().trim();
resultados = resultados.filter(relatorio => {
const paciente = pacientesData[relatorio.patient_id];
if (!paciente) return false;
const nomeMatch = paciente.full_name?.toLowerCase().includes(termo);
const cpfMatch = paciente.cpf?.includes(termoPesquisa);
return nomeMatch || cpfMatch;
});
}
if (filtroExame.trim()) {
const termoExame = filtroExame.toLowerCase().trim();
resultados = resultados.filter(relatorio =>
relatorio.exam?.toLowerCase().includes(termoExame)
);
}
setRelatoriosFinais(resultados);
setPaginaAtual(1);
}, [termoPesquisa, filtroExame, relatoriosOriginais, pacientesData]);
useEffect(() => {
var myHeaders = new Headers();
myHeaders.append("apikey", API_KEY);
myHeaders.append("Authorization", authHeader);
var requestOptions = {
method: 'GET',
headers: myHeaders,
redirect: 'follow'
};
fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/reports?patient_id&status", requestOptions)
.then(response => response.json())
.then(data => {
setRelatoriosOriginais(data);
setRelatoriosFinais(data);
const examesUnicos = [...new Set(data.map(relatorio => relatorio.exam).filter(exam => exam))];
setExamesDisponiveis(examesUnicos);
})
.catch(error => console.log('error', error));
}, [authHeader]);
const totalPaginas = Math.ceil(relatoriosFinais.length / itensPorPagina);
const indiceInicial = (paginaAtual - 1) * itensPorPagina;
const indiceFinal = indiceInicial + itensPorPagina;
const relatoriosPaginados = relatoriosFinais.slice(indiceInicial, indiceFinal);
const limparFiltros = () => {
setTermoPesquisa('');
setFiltroExame('');
setPaginaAtual(1);
};
const abrirModal = (relatorio) => {
setRelatorioModal(relatorio);
setShowModal(true);
};
const BaixarPDFdoRelatorio = (nome_paciente) => {
const elemento = document.getElementById("folhaA4");
const opt = {
margin: 0,
filename: `relatorio_${nome_paciente || "paciente"}.pdf`,
html2canvas: { scale: 2 },
jsPDF: { unit: "mm", format: "a4", orientation: "portrait" },
};
html2pdf().set(opt).from(elemento).save();
};
const irParaPagina = (pagina) => {
setPaginaAtual(pagina);
};
const avancarPagina = () => {
if (paginaAtual < totalPaginas) {
setPaginaAtual(paginaAtual + 1);
}
};
const voltarPagina = () => {
if (paginaAtual > 1) {
setPaginaAtual(paginaAtual - 1);
}
};
const gerarNumerosPaginas = () => {
const paginas = [];
const paginasParaMostrar = 5;
let inicio = Math.max(1, paginaAtual - Math.floor(paginasParaMostrar / 2));
let fim = Math.min(totalPaginas, inicio + paginasParaMostrar - 1);
inicio = Math.max(1, fim - paginasParaMostrar + 1);
for (let i = inicio; i <= fim; i++) {
paginas.push(i);
}
return paginas;
};
return (
<div>
{showModal && relatorioModal && (
<div className="modal" style={{ display: 'block', backgroundColor: 'rgba(0,0,0,0.5)' }}>
<div className="modal-dialog modal-tabela-relatorio">
<div className="modal-content">
<div className="modal-header text-white">
<h5 className="modal-title">Relatório de {pacientesData[relatorioModal.patient_id]?.full_name} </h5>
<button type="button" className="btn-close" onClick={() => setShowModal(false)}></button>
</div>
<div className="modal-body">
<div id="folhaA4">
<div id='header-relatorio'>
<p>Clinica Rise up</p>
<p>Dr - CRM/SP 123456</p>
<p>Avenida - (79) 9 4444-4444</p>
</div>
<div id='infoPaciente'>
<p>Paciente: {pacientesData[relatorioModal.patient_id]?.full_name}</p>
<p>Data de nascimento: {pacientesData[relatorioModal.patient_id]?.birth_date} </p>
<p>Data do exame: { }</p>
<p>Exame: {relatorioModal.exam}</p>
<p style={{ marginTop: '15px', fontWeight: 'bold' }}>Conteúdo do Relatório:</p>
<TiptapViewer htmlContent={relatorioModal.content || relatorioModal.diagnosis || relatorioModal.conclusion || 'Relatório não preenchido.'} />
</div>
<div>
<p>Dr {relatorioModal.required_by}</p>
<p>Emitido em: 0</p>
</div>
</div>
</div>
<div className="modal-footer">
<button className="btn btn-primary" onClick={() => BaixarPDFdoRelatorio(pacientesData[relatorioModal.patient_id]?.full_name)}>
<i className='bi bi-file-pdf-fill'></i> baixar em pdf
</button>
<button type="button" className="btn btn-primary" onClick={() => setShowModal(false)}>Fechar</button>
</div>
</div>
</div>
</div>
)}
<div className="page-heading">
<h3>Lista de Relatórios</h3>
</div>
<div className="page-content">
<section className="row">
<div className="col-12">
<div className="card">
<div className="card-header d-flex justify-content-between align-items-center">
<h4 className="card-title mb-0">Relatórios Cadastrados</h4>
<Link to={'criar'}>
<button className="btn btn-primary">
<i className="bi bi-plus-circle"></i> Adicionar Relatório
</button>
</Link>
</div>
<div className="card-body">
<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="row">
<div className="col-md-5">
<div className="mb-3">
<label className="form-label">Buscar por nome ou CPF do paciente</label>
<input
type="text"
className="form-control"
placeholder="Digite nome ou CPF do paciente..."
value={termoPesquisa}
onChange={(e) => setTermoPesquisa(e.target.value)}
/>
</div>
</div>
<div className="col-md-5">
<div className="mb-3">
<label className="form-label">Filtrar por tipo de exame</label>
<input
type="text"
className="form-control"
placeholder="Digite o tipo de exame..."
value={filtroExame}
onChange={(e) => setFiltroExame(e.target.value)}
/>
</div>
</div>
<div className="col-md-2 d-flex align-items-end">
<button className="btn btn-outline-secondary w-100" onClick={limparFiltros}>
<i className="bi bi-arrow-clockwise"></i> Limpar
</button>
</div>
</div>
<div className="mt-2">
<div className="contador-relatorios">
{relatoriosFinais.length} DE {relatoriosOriginais.length} RELATÓRIOS ENCONTRADOS
</div>
</div>
</div>
<div className="table-responsive">
<table className="table table-striped table-hover">
<thead>
<tr>
<th>Paciente</th>
<th>CPF</th>
<th>Exame</th>
<th></th>
</tr>
</thead>
<tbody>
{relatoriosPaginados.length > 0 ? (
relatoriosPaginados.map((relatorio) => {
const paciente = pacientesData[relatorio.patient_id];
return (
<tr key={relatorio.id}>
<td>{paciente?.full_name || 'Carregando...'}</td>
<td>{paciente?.cpf || 'Carregando...'}</td>
<td>{relatorio.exam}</td>
<td>
<div className="d-flex gap-2">
<button className="btn btn-sm btn-ver-detalhes" onClick={() => abrirModal(relatorio)}>
<i className="bi bi-eye me-1"></i> Ver Detalhes
</button>
<button className="btn btn-sm btn-editar" onClick={() => navigate(`/medico/relatorios/${relatorio.id}/edit`)}>
<i className="bi bi-pencil me-1"></i> Editar
</button>
</div>
</td>
</tr>
);
})
) : (
<tr>
<td colSpan="4" className="text-center py-4">
<div className="text-muted">
<i className="bi bi-search display-4"></i>
<p className="mt-2">Nenhum relatório encontrado com os filtros aplicados.</p>
{(termoPesquisa || filtroExame) && (
<button className="btn btn-outline-primary btn-sm mt-2" onClick={limparFiltros}>
Limpar filtros
</button>
)}
</div>
</td>
</tr>
)}
</tbody>
</table>
{relatoriosFinais.length > 0 && (
<div className="d-flex justify-content-between align-items-center mt-3">
<div className="d-flex align-items-center">
<span className="me-2 text-muted">Itens por página:</span>
<select
className="form-select form-select-sm w-auto"
value={itensPorPagina}
onChange={(e) => {
setItensPorPagina(Number(e.target.value));
setPaginaAtual(1);
}}
>
<option value={5}>5</option>
<option value={10}>10</option>
<option value={25}>25</option>
<option value={50}>50</option>
</select>
</div>
<div className="d-flex align-items-center">
<span className="me-3 text-muted">
Página {paginaAtual} de {totalPaginas}
Mostrando {indiceInicial + 1}-{Math.min(indiceFinal, relatoriosFinais.length)} de {relatoriosFinais.length} itens
</span>
<nav>
<ul className="pagination pagination-sm mb-0">
<li className={`page-item ${paginaAtual === 1 ? 'disabled' : ''}`}>
<button className="page-link" onClick={voltarPagina}>
<i className="bi bi-chevron-left"></i>
</button>
</li>
{gerarNumerosPaginas().map(pagina => (
<li key={pagina} className={`page-item ${pagina === paginaAtual ? 'active' : ''}`}>
<button className="page-link" onClick={() => irParaPagina(pagina)}>
{pagina}
</button>
</li>
))}
<li className={`page-item ${paginaAtual === totalPaginas ? 'disabled' : ''}`}>
<button className="page-link" onClick={avancarPagina}>
<i className="bi bi-chevron-right"></i>
</button>
</li>
</ul>
</nav>
</div>
</div>
)}
</div>
</div>
</div>
</div>
</section>
</div>
</div>
);
};
export default DoctorRelatorioManager;