Challenges/Distractions:
${rtpiSessionData.reflections.challenges.replace(/\n/g, '
') || "Not specified."}
Energy/Focus Observations:
${rtpiSessionData.reflections.energyFocus.replace(/\n/g, '
') || "Not specified."}
Adjustment for Next Session:
${rtpiSessionData.reflections.nextAdjustment.replace(/\n/g, '
') || "Not specified."}
`;
reportDisplay.style.display = 'block';
reflectionSection.style.display = 'block'; // Ensure reflections are visible
const pdfBtn = document.getElementById('rtpi-pdf-download');
if(pdfBtn) pdfBtn.style.display = 'inline-block';
}
function rtpiDownloadPDF() {
if (!jsPDF_constructor_rtpi) { alert("PDF library error."); return; }
if (rtpiSessionData.activities.length === 0 && !rtpiSessionData.sessionGoal && !rtpiSessionData.reflections.accomplishments) {
alert("No data to generate PDF. Please track activities or fill reflections."); return;
}
const doc = new jsPDF_constructor_rtpi('p', 'pt', 'a4');
const FONT_FAMILY = "helvetica";
const ACCENT_COLOR_HEX = getComputedStyle(document.documentElement).getPropertyValue('--accent-color').trim();
const PRIMARY_TEXT_COLOR_HEX = getComputedStyle(document.documentElement).getPropertyValue('--primary-text').trim();
const SECTION_TITLE_COLOR_HEX = getComputedStyle(document.documentElement).getPropertyValue('--section-title-color').trim();
const BUTTON_TEXT_COLOR_HEX = getComputedStyle(document.documentElement).getPropertyValue('--button-text-color').trim();
let yPos = 40;
const pageWidth = doc.internal.pageSize.getWidth();
const margin = 40;
const usableWidth = pageWidth - (2 * margin);
doc.setFillColor(ACCENT_COLOR_HEX);
doc.rect(0, 0, pageWidth, yPos + 10, 'F');
doc.setFont(FONT_FAMILY, "bold"); doc.setFontSize(16); doc.setTextColor(BUTTON_TEXT_COLOR_HEX);
doc.text("Performance Insights Session Report", pageWidth / 2, yPos, { align: "center" });
yPos += 25;
doc.setFont(FONT_FAMILY, "normal"); doc.setFontSize(10); doc.setTextColor(PRIMARY_TEXT_COLOR_HEX);
doc.text(`Session Date: ${document.getElementById('rtpi-session-date').value}`, margin, yPos);
const genDate = new Date(2025, 4, 18).toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' }); // Context date
doc.text(`Generated on: ${genDate}`, pageWidth - margin, yPos, { align: 'right'});
yPos += 15;
doc.setFont(FONT_FAMILY, "bold");
doc.text(`Session Goal: ${rtpiSessionData.sessionGoal || "Not specified."}`, margin, yPos); yPos += 20;
const addTextSectionPDF = (title, content, isList = false) => {
if (yPos > doc.internal.pageSize.getHeight() - 60 ) { doc.addPage(); yPos = margin; }
doc.setFont(FONT_FAMILY, "bold"); doc.setFontSize(11); doc.setTextColor(SECTION_TITLE_COLOR_HEX);
doc.text(title, margin, yPos); yPos += 15;
doc.setFont(FONT_FAMILY, "normal"); doc.setFontSize(9); doc.setTextColor(PRIMARY_TEXT_COLOR_HEX);
if (typeof content === 'string') {
const lines = doc.splitTextToSize(content || "N/A", usableWidth);
doc.text(lines, margin, yPos);
yPos += lines.length * 11 + 8;
} else if (Array.isArray(content)) { // For lists of strings
content.forEach(item => {
if (yPos > doc.internal.pageSize.getHeight() - 25) { doc.addPage(); yPos = margin; }
const itemLines = doc.splitTextToSize((isList ? "• " : "") + item, usableWidth - (isList ? 10 : 0) );
doc.text(itemLines, margin + (isList ? 10 : 0), yPos);
yPos += itemLines.length * 11 + 2;
});
yPos += 8;
}
};
let totalDuration = rtpiSessionData.liveTotalMinutes;
let avgFocus = 0; let focusRatedCount = 0;
rtpiSessionData.activities.forEach(act => { if (act.focusLevel !== null) { avgFocus += act.focusLevel; focusRatedCount++; } });
avgFocus = focusRatedCount > 0 ? (avgFocus / focusRatedCount).toFixed(1) : "N/A";
addTextSectionPDF("Session Summary:", [
`Total Logged Time: ${totalDuration} minutes`,
`Total Activities Completed: ${rtpiSessionData.activities.length}`,
`Average Focus Level: ${avgFocus} / 5 (from ${focusRatedCount} rated activities)`
]);
// Time Allocation
if (yPos > doc.internal.pageSize.getHeight() - 80 ) { doc.addPage(); yPos = margin; }
doc.setFont(FONT_FAMILY, "bold"); doc.setFontSize(11); doc.setTextColor(SECTION_TITLE_COLOR_HEX);
doc.text("Time Allocation by Category:", margin, yPos); yPos += 15;
doc.setFont(FONT_FAMILY, "normal"); doc.setFontSize(9);
const categoryContent = [];
for (const category in rtpiSessionData.liveCategoryTimes) {
const minutes = rtpiSessionData.liveCategoryTimes[category];
const percentage = totalDuration > 0 ? (minutes / totalDuration * 100).toFixed(1) : 0;
categoryContent.push(`${category}: ${minutes} min (${percentage}%)`);
}
if (categoryContent.length === 0) categoryContent.push("No activities logged to categorize time.");
addTextSectionPDF(null, categoryContent, true); // No title, just list
// Detailed Activity Log
if (yPos > doc.internal.pageSize.getHeight() - 60 ) { doc.addPage(); yPos = margin; }
doc.setFont(FONT_FAMILY, "bold"); doc.setFontSize(11); doc.setTextColor(SECTION_TITLE_COLOR_HEX);
doc.text("Detailed Activity Log:", margin, yPos); yPos += 5;
if (jsPDF_autoTable_plugin_rtpi && rtpiSessionData.activities.length > 0) {
const activityTableBody = rtpiSessionData.activities.map(act => [
act.name, act.category,
new Date(act.startTime).toLocaleTimeString([],{hour:'2-digit',minute:'2-digit'}),
new Date(act.endTime).toLocaleTimeString([],{hour:'2-digit',minute:'2-digit'}),
act.durationMinutes,
act.focusLevel || "N/A"
]);
doc.autoTable({
startY: yPos,
head: [['Activity', 'Category', 'Start', 'End', 'Duration (min)', 'Focus (1-5)']],
body: activityTableBody, theme: 'grid', margin: {left: margin, right: margin},
headStyles: { fillColor: ACCENT_COLOR_HEX, textColor: BUTTON_TEXT_COLOR_HEX, fontSize: 8, fontStyle:'bold'},
styles: { fontSize: 8, cellPadding: 2, overflow: 'linebreak' }
});
yPos = doc.lastAutoTable.finalY + 15;
} else if (rtpiSessionData.activities.length > 0) {
rtpiSessionData.activities.forEach(act => {
if (yPos > doc.internal.pageSize.getHeight() - 30) { doc.addPage(); yPos = margin; }
let logEntry = `• ${act.name} (${act.category}): ${act.durationMinutes} min. Focus: ${act.focusLevel || "N/A"}`;
doc.text(logEntry, margin, yPos); yPos += 12;
});
yPos += 5;
} else {
doc.text("No activities logged in detail.", margin, yPos); yPos += 15;
}
// Reflections
addTextSectionPDF("Session Reflections:", []);
addTextSectionPDF("Key accomplishments or progress:", [rtpiSessionData.reflections.accomplishments || "Not specified."], true);
addTextSectionPDF("Main distractions or challenges faced:", [rtpiSessionData.reflections.challenges || "Not specified."], true);
addTextSectionPDF("Energy and focus level fluctuations:", [rtpiSessionData.reflections.energyFocus || "Not specified."], true);
addTextSectionPDF("Key takeaway or adjustment for next session:", [rtpiSessionData.reflections.nextAdjustment || "Not specified."], true);
// Footer
const pageCount = doc.internal.getNumberOfPages();
for (let i = 1; i <= pageCount; i++) {
doc.setPage(i);
const pageHeight = doc.internal.pageSize.getHeight();
doc.setLineWidth(0.5); doc.setDrawColor(ACCENT_COLOR_HEX);
doc.line(margin, pageHeight - 30, pageWidth - margin, pageHeight - 30);
doc.setFont(FONT_FAMILY, "normal"); doc.setFontSize(8); doc.setTextColor(PRIMARY_TEXT_COLOR_HEX);
doc.text(`Page ${i} of ${pageCount}`, pageWidth / 2, pageHeight - 20, { align: "center" });
}
doc.save("Real_Time_Performance_Report.pdf");
}