Real-Time Performance Insights Tool

Real-Time Performance Insights

Live Session Tracker

Log New Activity

Live Session Overview:

Total Time Logged: 0 min

Activities Completed: 0

Time by Category: No activities logged yet.

Session Report & Insights

×

Log Activity Manually

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"); }
Scroll to Top