fix: setting layout pdf

This commit is contained in:
Sukma Gladys 2024-11-08 14:13:34 +07:00
parent 8788310621
commit ad775c5778

View File

@ -1,4 +1,4 @@
import { SetStateAction, useEffect, useRef, useState } from "react";
import { useEffect, useRef, useState } from "react";
import html2pdf from "html2pdf.js";
import useAuth from "@/hooks/useAuth";
import { createLazyFileRoute } from "@tanstack/react-router";
@ -10,7 +10,6 @@ import { PolarAngleAxis, PolarRadiusAxis, PolarGrid, Radar, RadarChart } from "r
import {
Card,
CardContent,
CardFooter,
CardHeader,
CardTitle,
} from "@/shadcn/components/ui/card"
@ -44,6 +43,7 @@ export default function AssessmentResultPage() {
setAssessmentId(id ?? undefined);
}, []);
//fetch data from API
const { data: aspectsData } = useQuery(aspectQueryOptions(0, 10));
const { data: assessmentResult } = useQuery(getAssessmentResultByIdQueryOptions(assessmentId));
const { data: verifiedAssessmentResult } = useQuery(getVerifiedAssessmentResultByIdQueryOptions(assessmentId));
@ -74,30 +74,38 @@ export default function AssessmentResultPage() {
return !isNaN(parsedScore) ? parsedScore.toFixed(2) : '0';
};
// Total score
const totalScore = parseFloat(formatScore(assessmentResult?.assessmentsResult));
const totalVerifiedScore = parseFloat(formatScore(verifiedAssessmentResult?.verifiedAssessmentsResult));
// Mengatur warna dan level maturitas berdasarkan skor
const getScoreStyleClass = (score: number | undefined, isBg: boolean = false) => {
if (score === undefined || score === null) return { color: 'grey' };
let colorVar = '--levelOne-color';
let textColor = 'white';
let descLevel = '1';
if (score >= 1.50 && score < 2.50) {
colorVar = '--levelTwo-color';
descLevel = '2';
} else if (score >= 2.50 && score < 3.50) {
colorVar = '--levelThree-color';
descLevel = '3';
} else if (score >= 3.50 && score < 4.49) {
colorVar = '--levelFour-color';
descLevel = '4';
} else if (score >= 4.50 && score <= 5) {
colorVar = '--levelFive-color';
descLevel = '5';
}
return isBg
? { backgroundColor: `var(${colorVar})`, color: textColor }
: { color: `var(${colorVar})` };
? { backgroundColor: `var(${colorVar})`, color: textColor, descLevel }
: { color: `var(${colorVar})`, descLevel };
};
// Warna aspek
const aspectsColors = [
"#DBED9B",
"#FF3F9F",
@ -106,6 +114,7 @@ export default function AssessmentResultPage() {
"#5FD4E7",
];
// Data diagram
const chartData = aspectsData?.data?.map((aspect, index) => ({
aspectName: aspect.name,
score: Number(formatScore(getAspectScore(aspect.id))),
@ -159,6 +168,7 @@ export default function AssessmentResultPage() {
return config;
}, {} as ChartConfig) || {};
// Mengatur tampilan label sumbu X
const customizedAxisTick = (props: any) => {
const { x, y, payload } = props;
return (
@ -178,6 +188,7 @@ export default function AssessmentResultPage() {
);
};
// Dropdown State
const [isOpen, setIsOpen] = useState(false);
const [selectedItem, setSelectedItem] = useState('Hasil Sementara');
@ -189,7 +200,7 @@ export default function AssessmentResultPage() {
setSelectedItem(prev =>
prev === 'Hasil Sementara' ? 'Hasil Terverifikasi' : 'Hasil Sementara'
);
setIsOpen(false); // Tutup dropdown setelah klik item
setIsOpen(false);
};
// Pie Chart Component
@ -274,6 +285,7 @@ export default function AssessmentResultPage() {
);
}
// Radar Chart Component
function RadarChartComponent({ chartData, chartConfig }: { chartData: { aspectName: string, score: number }[], chartConfig: ChartConfig }) {
return (
<div className="flex-1 pb-0">
@ -311,6 +323,7 @@ export default function AssessmentResultPage() {
);
}
// Bar Chart Component
function BarChartComponent({ barChartData, barChartConfig }: { barChartData: { subAspectName: string, score: number, fill: string, aspectId: string, aspectName: string }[], barChartConfig: ChartConfig }) {
return (
<div className="w-full">
@ -347,28 +360,33 @@ export default function AssessmentResultPage() {
);
}
const cardRef = useRef<HTMLDivElement | null>(null); // Create a ref for your component
const handlePrintPDF = async (isSuperAdmin: boolean) => {
const pdfContainer = document.getElementById("pdfContainer");
const targetCard = document.getElementById("target-card");
const barChart = document.getElementById("bar-chart");
const handlePrintPDF = async () => {
const element = cardRef.current;
if (element) {
if (pdfContainer && targetCard && barChart) {
// Sembunyikan elemen yang tidak ingin dicetak
const buttonPrint = document.getElementById("button-print");
const noPrint = document.getElementById("no-print");
if (buttonPrint) buttonPrint.style.visibility = 'hidden'; // Menggunakan visibility untuk tetap menjaga ruang
if (noPrint) noPrint.style.visibility = 'hidden'; // Menggunakan visibility untuk tetap menjaga ruang
if (buttonPrint) buttonPrint.style.visibility = 'hidden';
if (noPrint) noPrint.style.visibility = 'hidden';
// Pastikan elemen memiliki lebar 100%
element.style.width = '100%'; // Mengatur lebar konten
// Tentukan marginTop sesuai dengan isSuperAdmin
const originalMarginTop = targetCard.style.marginTop || "0px";
targetCard.style.marginTop = isSuperAdmin ? "190px" : "0px";
// Tentukan marginTop sesuai dengan isSuperAdmin
const originalBarChart = barChart.style.marginTop || "0px";
barChart.style.marginTop = isSuperAdmin ? "0px" : "150px";
const options = {
margin: [0.4, 0.5, 0.4, 0], // Margin kecil untuk mengurangi ruang kosong
margin: [0, 0.5, 0, 0],
image: { type: 'jpeg', quality: 0.98 },
html2canvas: {
scale: 2, // Mengatur scale agar kualitas tinggi
width: element.scrollWidth,
height: element.scrollHeight,
scale: 2,
width: pdfContainer.scrollWidth,
height: pdfContainer.scrollHeight,
},
jsPDF: {
unit: 'in',
@ -380,32 +398,34 @@ export default function AssessmentResultPage() {
try {
const pdfBlob: Blob = await html2pdf()
.set(options)
.from(element)
.from(pdfContainer)
.toPdf()
.get('pdf')
.then((pdf: any) => {
pdf.setProperties({
title: 'Hasil_Asesemen_Level_Maturitas',
});
return pdf.output('blob'); // Menghasilkan PDF sebagai blob dengan title
return pdf.output('blob');
});
// Buat URL dari Blob dan buka di tab baru untuk pratinjau
const pdfURL = URL.createObjectURL(pdfBlob);
window.open(pdfURL, '_blank'); // Pratinjau di tab baru tanpa unduh
window.open(pdfURL, '_blank');
} catch (err) {
console.error("Error generating PDF:", err);
} finally {
// Tampilkan kembali elemen yang disembunyikan
if (buttonPrint) buttonPrint.style.visibility = 'visible'; // Mengembalikan visibility
if (noPrint) noPrint.style.visibility = 'visible'; // Mengembalikan visibility
element.style.width = ""; // Reset lebar setelah selesai
if (buttonPrint) buttonPrint.style.visibility = 'visible';
if (noPrint) noPrint.style.visibility = 'visible';
// Reset marginTop ke nilai aslinya
targetCard.style.marginTop = originalMarginTop || "0px";
barChart.style.marginTop = originalBarChart || "0px";
}
}
};
return (
<Card ref={cardRef} className="flex flex-row w-full h-full border-none shadow-none">
<Card className="flex flex-row w-full h-full border-none shadow-none" id="pdfContainer">
<div className="flex flex-col w-fit h-fit border-none shadow-none -ml-1 -pr-2">
<p className="font-bold mt-2 ml-2">Tingkatan Level Maturitas</p>
<div className="flex flex-col mr-5 -ml-5 h-full">
@ -459,10 +479,10 @@ export default function AssessmentResultPage() {
<div className="flex flex-row gap-2" id="button-print">
<button
onClick={handlePrintPDF}
onClick={() => handlePrintPDF(isSuperAdmin)}
className="bg-blue-600 text-white flex w-fit p-2 rounded-sm text-sm items-start justify-between outline-none ring-offset-0"
>
Cetak ke PDF
Cetak PDF
</button>
<div className="flex">
<DropdownMenu>
@ -492,14 +512,10 @@ export default function AssessmentResultPage() {
{isSuperAdmin &&
<Card className="flex flex-col w-full h-full mb-6 justify-center items-start">
<div className="flex flex-row border-b w-full p-4 gap-4 items-center">
<div className="flex w-16 h-16 rounded-full bg-slate-300">
</div>
<div className="flex flex-col">
<div className="flex flex-col border-b w-full p-4">
<p className="text-lg font-bold">{assessmentResult?.respondentName}</p>
<p className="text-sm">{assessmentResult?.position}</p>
</div>
</div>
<div className="flex lg:flex-row flex-col text-xs h-full w-full justify-between p-4">
<div className="flex flex-col gap-4">
<div>
@ -566,7 +582,7 @@ export default function AssessmentResultPage() {
<>
{/* Score Table */}
<p className="text-lg font-bold">Tabel Level Maturitas</p>
<Card className="flex flex-col w-full h-fit my-2 mb-8 overflow-hidden text-center">
<Card className="flex flex-col w-full h-fit my-2 mb-6 overflow-hidden text-center">
<div className="flex flex-row w-full">
{aspectsData?.data?.map((aspect) => (
<div key={aspect.id} className="flex-col bg-white w-full h-full border-t border-x">
@ -587,9 +603,15 @@ export default function AssessmentResultPage() {
</div>
{/* Total score */}
<div className="flex flex-row w-full h-fit justify-center font-bold text-3xl gap-0.5">
<div className="flex flex-row w-full h-full p-3 justify-center gap-2 font-bold text-3xl bg-blue-600 text-white">
<p className="text-center">Nilai Maturitas:</p>
<span>{totalScore}</span>
</div>
<div className="flex flex-row w-full h-fit p-3 justify-center gap-2 font-bold text-3xl" style={getScoreStyleClass(Number(totalScore), true)}>
<p className="text-center">Level Maturitas:</p>
<span>{totalScore}</span>
<span className="ml-2">{getScoreStyleClass(Number(totalScore), true).descLevel}</span>
</div>
</div>
</Card>
</>
@ -618,15 +640,21 @@ export default function AssessmentResultPage() {
</div>
{/* Total verified score */}
<div className="flex flex-row w-full h-fit justify-center font-bold text-3xl gap-0.5">
<div className="flex flex-row w-full h-full p-3 justify-center gap-2 font-bold text-3xl bg-blue-600 text-white">
<p className="text-center">Nilai Maturitas:</p>
<span>{totalScore}</span>
</div>
<div className="flex flex-row w-full h-fit p-3 justify-center gap-2 font-bold text-3xl" style={getScoreStyleClass(Number(totalScore), true)}>
<p className="text-center">Level Maturitas:</p>
<span>{totalVerifiedScore}</span>
<span className="ml-2">{getScoreStyleClass(Number(totalScore), true).descLevel}</span>
</div>
</div>
</Card>
</>
)}
<Card className="flex flex-col lg:flex-row gap-8 border-none shadow-none w-full">
<Card className="flex flex-col lg:flex-row gap-4 border-none shadow-none w-full" id="target-card">
{/* Pie Chart */}
{selectedItem === 'Hasil Sementara' ? (
<Card className="flex flex-col w-full">
@ -678,7 +706,7 @@ export default function AssessmentResultPage() {
)}
</Card>
<Card className="flex w-full h-fit border mt-8">
<Card className="flex w-full h-fit border mt-4" id="bar-chart">
{/* Bar Chart */}
{selectedItem === 'Hasil Sementara' ? (
<>