Pull Request branch dev-clone to main #1
|
|
@ -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,13 +512,9 @@ 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">
|
||||
|
|
@ -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 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>
|
||||
<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 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 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>
|
||||
<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 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' ? (
|
||||
<>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user