fix:fix export pdf in reports

This commit is contained in:
M-Gabrielly 2025-12-03 23:12:02 -03:00
parent a0dfcd671c
commit 4cec1582ce

View File

@ -2,10 +2,11 @@
"use client"; "use client";
import React, { useEffect, useState } from "react"; import React, { useEffect, useState, useRef } from "react";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { FileDown, BarChart2, Users, CalendarCheck } from "lucide-react"; import { FileDown, BarChart2, Users, CalendarCheck } from "lucide-react";
import jsPDF from "jspdf"; import jsPDF from "jspdf";
import html2canvas from "html2canvas";
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from "recharts"; import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from "recharts";
import { import {
countAppointmentsToday, countAppointmentsToday,
@ -30,10 +31,51 @@ const FALLBACK_MEDICOS = [
// Helper Functions // Helper Functions
// ============================================================================ // ============================================================================
function exportPDF(title: string, content: string) { async function exportPDF(title: string, content: string, chartElementId?: string) {
const doc = new jsPDF(); const doc = new jsPDF();
doc.text(title, 10, 10); let yPosition = 15;
doc.text(content, 10, 20);
// Add title
doc.setFontSize(16);
doc.setFont(undefined, "bold");
doc.text(title, 15, yPosition);
yPosition += 10;
// Add description/content
doc.setFontSize(11);
doc.setFont(undefined, "normal");
const contentLines = doc.splitTextToSize(content, 180);
doc.text(contentLines, 15, yPosition);
yPosition += contentLines.length * 5 + 15;
// Capture chart if chartElementId is provided
if (chartElementId) {
try {
const chartElement = document.getElementById(chartElementId);
if (chartElement) {
// Create a canvas from the chart element
const canvas = await html2canvas(chartElement, {
backgroundColor: "#ffffff",
scale: 2,
logging: false,
});
// Convert canvas to image
const imgData = canvas.toDataURL("image/png");
const imgWidth = 180;
const imgHeight = (canvas.height * imgWidth) / canvas.width;
// Add image to PDF
doc.addImage(imgData, "PNG", 15, yPosition, imgWidth, imgHeight);
yPosition += imgHeight + 10;
}
} catch (error) {
console.error("Error capturing chart:", error);
doc.text("(Erro ao capturar gráfico)", 15, yPosition);
yPosition += 10;
}
}
doc.save(`${title.toLowerCase().replace(/ /g, "-")}.pdf`); doc.save(`${title.toLowerCase().replace(/ /g, "-")}.pdf`);
} }
@ -203,7 +245,7 @@ export default function RelatoriosPage() {
size="sm" size="sm"
variant="outline" variant="outline"
className="hover:bg-primary! hover:text-white! transition-colors w-full md:w-auto" className="hover:bg-primary! hover:text-white! transition-colors w-full md:w-auto"
onClick={() => exportPDF("Consultas por Período", "Resumo das consultas realizadas por período.")} onClick={() => exportPDF("Consultas por Período", "Resumo das consultas realizadas por período.", "chart-consultas")}
> >
<FileDown className="w-4 h-4 mr-1" /> Exportar PDF <FileDown className="w-4 h-4 mr-1" /> Exportar PDF
</Button> </Button>
@ -211,15 +253,17 @@ export default function RelatoriosPage() {
{loading ? ( {loading ? (
<div className="h-[220px] flex items-center justify-center text-muted-foreground">Carregando dados...</div> <div className="h-[220px] flex items-center justify-center text-muted-foreground">Carregando dados...</div>
) : ( ) : (
<ResponsiveContainer width="100%" height={220}> <div id="chart-consultas">
<BarChart data={consultasData}> <ResponsiveContainer width="100%" height={220}>
<CartesianGrid strokeDasharray="3 3" /> <BarChart data={consultasData}>
<XAxis dataKey="periodo" /> <CartesianGrid strokeDasharray="3 3" />
<YAxis /> <XAxis dataKey="periodo" />
<Tooltip /> <YAxis />
<Bar dataKey="consultas" fill="#6366f1" name="Consultas" /> <Tooltip />
</BarChart> <Bar dataKey="consultas" fill="#6366f1" name="Consultas" />
</ResponsiveContainer> </BarChart>
</ResponsiveContainer>
</div>
)} )}
</div> </div>
</div> </div>
@ -229,9 +273,10 @@ export default function RelatoriosPage() {
<div className="bg-card border border-border rounded-lg shadow p-6"> <div className="bg-card border border-border rounded-lg shadow p-6">
<div className="flex items-center justify-between mb-2"> <div className="flex items-center justify-between mb-2">
<h2 className="font-semibold text-lg text-foreground flex items-center gap-2"><Users className="w-5 h-5" /> Pacientes Mais Atendidos</h2> <h2 className="font-semibold text-lg text-foreground flex items-center gap-2"><Users className="w-5 h-5" /> Pacientes Mais Atendidos</h2>
<Button size="sm" variant="outline" className="hover:bg-primary! hover:text-white! transition-colors" onClick={() => exportPDF("Pacientes Mais Atendidos", "Lista dos pacientes mais atendidos.")}> <FileDown className="w-4 h-4 mr-1" /> Exportar PDF</Button> <Button size="sm" variant="outline" className="hover:bg-primary! hover:text-white! transition-colors" onClick={() => exportPDF("Pacientes Mais Atendidos", "Lista dos pacientes mais atendidos.", "table-pacientes")}> <FileDown className="w-4 h-4 mr-1" /> Exportar PDF</Button>
</div> </div>
<table className="w-full text-sm mt-4"> <div id="table-pacientes">
<table className="w-full text-sm mt-4">
<thead> <thead>
<tr className="text-muted-foreground"> <tr className="text-muted-foreground">
<th className="text-left font-medium">Paciente</th> <th className="text-left font-medium">Paciente</th>
@ -257,15 +302,17 @@ export default function RelatoriosPage() {
)} )}
</tbody> </tbody>
</table> </table>
</div>
</div> </div>
{/* Médicos mais produtivos */} {/* Médicos mais produtivos */}
<div className="bg-card border border-border rounded-lg shadow p-6"> <div className="bg-card border border-border rounded-lg shadow p-6">
<div className="flex items-center justify-between mb-2"> <div className="flex items-center justify-between mb-2">
<h2 className="font-semibold text-lg text-foreground flex items-center gap-2"><Users className="w-5 h-5" /> Médicos Mais Produtivos</h2> <h2 className="font-semibold text-lg text-foreground flex items-center gap-2"><Users className="w-5 h-5" /> Médicos Mais Produtivos</h2>
<Button size="sm" variant="outline" className="hover:bg-primary! hover:text-white! transition-colors" onClick={() => exportPDF("Médicos Mais Produtivos", "Lista dos médicos mais produtivos.")}> <FileDown className="w-4 h-4 mr-1" /> Exportar PDF</Button> <Button size="sm" variant="outline" className="hover:bg-primary! hover:text-white! transition-colors" onClick={() => exportPDF("Médicos Mais Produtivos", "Lista dos médicos mais produtivos.", "table-medicos")}> <FileDown className="w-4 h-4 mr-1" /> Exportar PDF</Button>
</div> </div>
<table className="w-full text-sm mt-4"> <div id="table-medicos">
<table className="w-full text-sm mt-4">
<thead> <thead>
<tr className="text-muted-foreground"> <tr className="text-muted-foreground">
<th className="text-left font-medium">Médico</th> <th className="text-left font-medium">Médico</th>
@ -291,6 +338,7 @@ export default function RelatoriosPage() {
)} )}
</tbody> </tbody>
</table> </table>
</div>
</div> </div>
</div> </div>
</div> </div>