Smart Non-Work Time Utilization Tracker

Smart Non-Work Time Utilization Tracker

Log Your Non-Work Activities

Log an Activity

Recently Logged Activities (for today):

No activities logged for this date yet.

Non-Work Time Utilization Report

No activities logged for this date to analyze. Please log activities in Tab 1.

"; reportArea.style.display = 'block'; if(pdfBtn) pdfBtn.style.display = 'none'; snwtuAnalysisResults = null; return; } let totalLoggedMinutes = 0; let categoryTimes = {}; // { "CategoryName": { time: XX, count: X, totalFulfillment: X }, ... } let highFulfillmentActivities = []; let lowFulfillmentActivities = []; let alignedActivities = []; let unalignedActivities = []; let numAligned = 0, numPartiallyAligned = 0, numNotAligned = 0; activitiesToAnalyze.forEach(act => { totalLoggedMinutes += act.durationMinutes; if (!categoryTimes[act.category]) { categoryTimes[act.category] = { time: 0, count: 0, totalFulfillment: 0 }; } categoryTimes[act.category].time += act.durationMinutes; categoryTimes[act.category].count++; categoryTimes[act.category].totalFulfillment += act.fulfillmentScore; if (act.fulfillmentScore >= 4) highFulfillmentActivities.push(`${act.name} (${act.category})`); if (act.fulfillmentScore <= 2) lowFulfillmentActivities.push(`${act.name} (${act.category})`); if (act.alignsWithIntention === "Yes") { alignedActivities.push(act.name); numAligned++; } else if (act.alignsWithIntention === "Partially") { numPartiallyAligned++; // Could also add to a 'partially aligned' list if needed } else { unalignedActivities.push(act.name); numNotAligned++; } }); // --- Populate Report Area --- document.getElementById('snwtu-report-intention').textContent = snwtuNonWorkTimeData.mainIntention + (snwtuNonWorkTimeData.intentionDetails ? ` (${snwtuNonWorkTimeData.intentionDetails})` : ''); document.getElementById('snwtu-report-total-time').textContent = `${Math.floor(totalLoggedMinutes/60)}h ${totalLoggedMinutes%60}m`; const catListEl = document.getElementById('snwtu-report-category-list'); catListEl.innerHTML = ''; const catBarsEl = document.getElementById('snwtu-report-category-bars'); catBarsEl.innerHTML = '
'; const catAllocBar = document.getElementById('snwtu-cat-alloc-bar'); const sortedCategories = Object.entries(categoryTimes).sort(([,a],[,b]) => b.time - a.time); const categoryColors = ["#FF7F50", "#FFA07A", "#FFDAB9", "#FFE4E1", "#FFC0CB", "#FA8072", "#F08080"]; // Example colors let colorIndex = 0; sortedCategories.forEach(([category, data]) => { const percentage = totalLoggedMinutes > 0 ? (data.time / totalLoggedMinutes * 100) : 0; catListEl.innerHTML += `
  • ${category}: ${Math.floor(data.time/60)}h ${data.time%60}m (${percentage.toFixed(1)}%)
  • `; if (percentage > 0 && catAllocBar) { const segment = document.createElement('div'); segment.style.width = `${percentage}%`; segment.style.backgroundColor = categoryColors[colorIndex % categoryColors.length]; segment.style.height = '100%'; segment.style.display = 'flex'; segment.style.alignItems = 'center'; segment.style.justifyContent = 'center'; segment.style.fontSize = '0.7em'; segment.style.color = '#fff'; // Assuming dark enough colors for white text segment.title = `${category}: ${percentage.toFixed(1)}%`; if (percentage > 10) segment.textContent = `${category.substring(0,3)}.${percentage.toFixed(0)}%`; // Short label catAllocBar.appendChild(segment); colorIndex++; } }); if(sortedCategories.length === 0) catListEl.innerHTML = '
  • No specific categories logged.
  • '; document.getElementById('snwtu-report-high-fulfillment').textContent = highFulfillmentActivities.join(', ') || "None rated 4-5."; document.getElementById('snwtu-report-low-fulfillment').textContent = lowFulfillmentActivities.join(', ') || "None rated 1-2."; let alignmentSummary = ""; if (activitiesToAnalyze.length > 0) { const alignedPercent = (numAligned / activitiesToAnalyze.length * 100).toFixed(0); alignmentSummary = `${alignedPercent}% of activities (${numAligned}/${activitiesToAnalyze.length}) clearly aligned with your intention.`; } else { alignmentSummary = "No activities logged to assess alignment."; } document.getElementById('snwtu-report-alignment-summary').textContent = alignmentSummary; const alignedUl = document.getElementById('snwtu-report-aligned-activities'); alignedUl.innerHTML = alignedActivities.length > 0 ? `Aligned: ${alignedActivities.map(a=>`"${a}"`).join(', ')}` : ""; const unalignedUl = document.getElementById('snwtu-report-unaligned-activities'); unalignedUl.innerHTML = unalignedActivities.length > 0 ? `
    Not Directly Aligned: ${unalignedActivities.map(a=>`"${a}"`).join(', ')}` : ""; // Smart Suggestions const suggestionsListEl = document.getElementById('snwtu-report-suggestions-list'); suggestionsListEl.innerHTML = ''; let suggestions = []; const mainIntention = snwtuNonWorkTimeData.mainIntention; if (totalLoggedMinutes < 120 && mainIntention !== "Just Go With The Flow") { // Less than 2 hours logged for non-work suggestions.push("You logged relatively little non-work time. Ensure you're allocating enough time for personal activities and rest."); } let intentionRelatedTime = 0; activitiesToAnalyze.forEach(act => { if (act.alignsWithIntention === "Yes") intentionRelatedTime += act.durationMinutes; }); const intentionTimePercent = totalLoggedMinutes > 0 ? (intentionRelatedTime / totalLoggedMinutes * 100) : 0; if (mainIntention !== "Just Go With The Flow" && mainIntention !== "Getting Things Done (Errands, Chores)" && intentionTimePercent < 30 && activitiesToAnalyze.length > 2) { suggestions.push(`Your main intention was "${mainIntention}", but less than 30% of your logged time directly supported it. Consider proactively scheduling activities that align more closely with this intention.`); } let lowFulfillmentHighTime = activitiesToAnalyze.filter(act => act.fulfillmentScore <= 2 && act.durationMinutes >= 60); if (lowFulfillmentHighTime.length > 0) { suggestions.push(`You spent significant time on "${lowFulfillmentHighTime.map(a=>a.name).join(', ')}" but didn't find it very fulfilling. Could this time be used for activities you enjoy more or that better align with your intentions?`); } if (highFulfillmentActivities.length > 0) { suggestions.push(`Activities like "${highFulfillmentActivities.slice(0,2).join('", "')}" brought you high fulfillment! Try to make more time for these or similar activities.`); } else if (activitiesToAnalyze.length > 0) { suggestions.push("Explore different types of non-work activities to discover what truly recharges and fulfills you."); } if (suggestions.length > 0) { suggestions.forEach(sug => suggestionsListEl.innerHTML += `
  • ${sug}
  • `); document.getElementById('snwtu-report-suggestions').style.display = 'block'; } else { document.getElementById('snwtu-report-suggestions').style.display = 'none'; } reportArea.style.display = 'block'; if(pdfBtn) pdfBtn.style.display = 'inline-block'; snwtuAnalysisResults = { // Store for PDF trackingDate: currentAnalysisDate, mainIntention: mainIntention + (snwtuNonWorkTimeData.intentionDetails ? ` (${snwtuNonWorkTimeData.intentionDetails})` : ''), totalLoggedMinutes, categoryTimes, highFulfillmentActivities, lowFulfillmentActivities, alignmentSummary, alignedActivities, unalignedActivities, suggestions, loggedActivitiesForDate: JSON.parse(JSON.stringify(activitiesToAnalyze)) // Deep copy }; } function snwtuGetFormattedDateForPDF_context() { return new Date(2025, 4, 18).toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' }); } function snwtuDownloadPDF() { if (!jsPDF_constructor_snwtu) { alert("PDF library error. Cannot generate PDF."); return; } if (!snwtuAnalysisResults) { alert("Please analyze your time first."); return; } const { trackingDate, mainIntention, totalLoggedMinutes, categoryTimes, highFulfillmentActivities, lowFulfillmentActivities, alignmentSummary, alignedActivities, unalignedActivities, suggestions, loggedActivitiesForDate } = snwtuAnalysisResults; const doc = new jsPDF_constructor_snwtu('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("Non-Work Time Utilization Report", pageWidth / 2, yPos, { align: "center" }); yPos += 25; doc.setFont(FONT_FAMILY, "normal"); doc.setFontSize(10); doc.setTextColor(PRIMARY_TEXT_COLOR_HEX); doc.text(`Report for Date: ${new Date(trackingDate+'T00:00:00').toLocaleDateString(undefined, { weekday:'long', year: 'numeric', month: 'long', day: 'numeric' })}`, margin, yPos); doc.text(`Generated on: ${snwtuGetFormattedDateForPDF_context()}`, pageWidth - margin, yPos, { align: 'right'}); yPos += 15; doc.setFont(FONT_FAMILY, "italic"); doc.setFontSize(9); const intentionLines = doc.splitTextToSize(`Your Stated Intention: ${mainIntention}`, usableWidth); doc.text(intentionLines, margin, yPos); yPos += intentionLines.length * 11 + 10; const addTextListToPdf = (title, items, itemPrefix = "• ") => { if (yPos > doc.internal.pageSize.getHeight() - (items.length * 12) - 30 ) { 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); if (items.length > 0) { items.forEach(item => { if (yPos > doc.internal.pageSize.getHeight() - 25) { doc.addPage(); yPos = margin; } const itemLines = doc.splitTextToSize(`${itemPrefix}${item}`, usableWidth - (itemPrefix ? 10 : 0)); doc.text(itemLines, margin + (itemPrefix ? 10 : 0), yPos); yPos += itemLines.length * 11 + 2; }); } else { doc.text("None specified for this section.", margin + 10, yPos); yPos += 12; } yPos += 8; }; // Summary doc.setFont(FONT_FAMILY, "bold"); doc.setFontSize(11); doc.setTextColor(SECTION_TITLE_COLOR_HEX); doc.text("Summary of Logged Time:", margin, yPos); yPos += 15; doc.setFont(FONT_FAMILY, "normal"); doc.setFontSize(10); doc.text(`Total Non-Work Time Logged: ${Math.floor(totalLoggedMinutes/60)}h ${totalLoggedMinutes%60}m`, margin, yPos); yPos += 14; doc.setFont(FONT_FAMILY, "bold"); doc.text("Time Allocation by Category:", margin, yPos); yPos += 12; doc.setFont(FONT_FAMILY, "normal"); doc.setFontSize(9); const sortedCategories = Object.entries(categoryTimes).sort(([,a],[,b]) => b.time - a.time); if (sortedCategories.length > 0) { sortedCategories.forEach(([category, data]) => { if (yPos > doc.internal.pageSize.getHeight() - 25) { doc.addPage(); yPos = margin; } const percentage = totalLoggedMinutes > 0 ? (data.time / totalLoggedMinutes * 100) : 0; doc.text(`• ${category}: ${Math.floor(data.time/60)}h ${data.time%60}m (${percentage.toFixed(1)}%)`, margin + 10, yPos); yPos += 12; }); } else { doc.text("No categories logged.", margin + 10, yPos); yPos += 12; } yPos += 8; // Fulfillment & Alignment addTextListToPdf("Highly Fulfilling Activities (Rated 4-5):", highFulfillmentActivities.length > 0 ? highFulfillmentActivities : ["None this period."]); addTextListToPdf("Less Fulfilling Activities (Rated 1-2):", lowFulfillmentActivities.length > 0 ? lowFulfillmentActivities : ["None this period."]); if (yPos > doc.internal.pageSize.getHeight() - 40) { doc.addPage(); yPos = margin; } doc.setFont(FONT_FAMILY, "bold"); doc.setFontSize(11); doc.setTextColor(SECTION_TITLE_COLOR_HEX); doc.text("Alignment with Intention:", margin, yPos); yPos += 15; doc.setFont(FONT_FAMILY, "normal"); doc.setFontSize(9); doc.text(alignmentSummary, margin, yPos); yPos += 12; if(alignedActivities.length > 0) { const alignedText = "Aligned Activities: " + alignedActivities.join(', '); const alignedLines = doc.splitTextToSize(alignedText, usableWidth); doc.text(alignedLines, margin, yPos); yPos += alignedLines.length * 11 + 2; } if(unalignedActivities.length > 0) { const unalignedText = "Non-Aligned Activities: " + unalignedActivities.join(', '); const unalignedLines = doc.splitTextToSize(unalignedText, usableWidth); doc.text(unalignedLines, margin, yPos); yPos += unalignedLines.length * 11 + 2; } yPos += 8; // Suggestions if(suggestions.length > 0) addTextListToPdf("Smart Suggestions & Reflections:", suggestions); // Detailed Log if (yPos > doc.internal.pageSize.getHeight() - 60 && loggedActivitiesForDate.length > 0) { doc.addPage(); yPos = margin; } doc.setFont(FONT_FAMILY, "bold"); doc.setFontSize(12); doc.setTextColor(SECTION_TITLE_COLOR_HEX); doc.text("Detailed Activity Log:", margin, yPos); yPos += 5; if (jsPDF_autoTable_plugin_snwtu && loggedActivitiesForDate.length > 0) { const activityTableBody = loggedActivitiesForDate.map(act => [ act.name, act.category, `${act.durationMinutes} min`, act.timeOfDay || "N/A", act.fulfillmentScore, act.alignsWithIntention ]); doc.autoTable({ startY: yPos, head: [['Activity', 'Category', 'Duration', 'Time of Day', 'Fulfillment (1-5)', 'Aligned?']], 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 (loggedActivitiesForDate.length === 0) { doc.setFont(FONT_FAMILY, "normal"); doc.setFontSize(9); doc.text("No detailed activities logged for this date.", margin, yPos); yPos += 15; } // 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("Non_Work_Time_Utilization_Report.pdf"); }
    Scroll to Top