Office Productivity Time Checker
Office Productivity Time Checker

Define Your Office Hours


Define Productive Activity Categories


Log Daily Activity

Check Daily Productivity

Activity Log for Selected Date

StartEndDurationActivityCategoryTypeActions

No productive time logged by category.

"; } document.getElementById('optc-daily-summary-section').style.display = 'block'; } function optc_clearAllLogs() { if (confirm("Are you sure you want to clear ALL logged activities? Office hours and categories will remain.")) { optc_loggedActivities = []; optc_logIdCounter = 0; optc_editLogId = null; optc_clearLogForm(); optc_generateDailyReport(); // Re-render empty analysis and log table } } function optc_downloadPDF() { if (!tpc_jsPDF_loaded_OPTC || !tpc_autoTable_loaded_OPTC) { alert("OPTC Error: PDF libraries not loaded."); return; } const reportDateStr = document.getElementById('optc-report-date').value; if(!reportDateStr){ alert("Please select a date to generate PDF for."); return; } // Ensure data for PDF is current from analysis display optc_generateDailyReport(); // This populates the UI which PDF can then read or use data from const entriesForDate = optc_loggedActivities.filter(e => e.date === reportDateStr); // if (entriesForDate.length === 0) { alert("No log entries for the selected date to export."); return; } const doc = new TPC_jsPDF_OPTC(); const primaryColor = getComputedStyle(document.documentElement).getPropertyValue('--primary-color').trim(); const darkColor = getComputedStyle(document.documentElement).getPropertyValue('--dark-color').trim(); let finalY = 15; const officeHoursText = `Office Hours: ${optc_officeHours.startTime} - ${optc_officeHours.endTime}`; const displayReportDate = new Date(reportDateStr+"T00:00:00Z").toLocaleDateString(undefined,{timeZone:'UTC'}); doc.setFontSize(18); doc.setTextColor(primaryColor); doc.text("Daily Productivity Report", doc.internal.pageSize.getWidth() / 2, finalY, { align: 'center' }); finalY += 8; doc.setFontSize(10); doc.setTextColor(darkColor); doc.text(`For Date: ${displayReportDate} | ${officeHoursText}`, doc.internal.pageSize.getWidth() / 2, finalY, { align: 'center'}); finalY += 10; // Summary Data from rendered UI (as it's already calculated) doc.setFontSize(12); doc.setTextColor(primaryColor); doc.text("Productivity Summary:", 14, finalY); finalY += 6; doc.setFontSize(9); doc.setTextColor(darkColor); const summaryItems = document.querySelectorAll('#optc-summary-results .optc-summary-item'); summaryItems.forEach(item => { const label = item.querySelector('.label').textContent; const value = item.querySelector('strong').textContent; doc.text(`${label} ${value}`, 14, finalY); finalY +=5; }); finalY += 5; // Category Breakdown for PDF const timeByProdCategoryForPdf = {}; let totalProductiveMinutesForPdf = 0; entriesForDate.forEach(entry => { const officeStartMinutes = optc_timeToMinutes(optc_officeHours.startTime); const officeEndMinutes = optc_timeToMinutes(optc_officeHours.endTime); const entryStartMinutes = optc_timeToMinutes(entry.startTime); const entryEndMinutes = optc_timeToMinutes(entry.endTime); const effectiveStart = Math.max(entryStartMinutes, officeStartMinutes); const effectiveEnd = Math.min(entryEndMinutes, officeEndMinutes); let durationInOfficeHours = 0; if (effectiveEnd > effectiveStart) durationInOfficeHours = effectiveEnd - effectiveStart; if (entry.isProductive && durationInOfficeHours > 0) { timeByProdCategoryForPdf[entry.categoryName] = (timeByProdCategoryForPdf[entry.categoryName] || 0) + durationInOfficeHours; totalProductiveMinutesForPdf += durationInOfficeHours; } }); if(Object.keys(timeByProdCategoryForPdf).length > 0){ doc.setFontSize(11); doc.setTextColor(primaryColor); doc.text("Time by Productive Category:", 14, finalY); finalY+=5; const catTableBody = Object.entries(timeByProdCategoryForPdf).map(([cat, mins]) => { const perc = totalProductiveMinutesForPdf > 0 ? (mins/totalProductiveMinutesForPdf * 100).toFixed(1) + "%" : "0%"; return [cat, optc_formatDurationForDisplay(mins), perc]; }); doc.autoTable({ startY: finalY, head:[['Category', 'Time Spent', '% of Productive Time']], body: catTableBody, theme: 'striped', headStyles:{fillColor:primaryColor, textColor:'#fff',fontSize:9}, styles:{fontSize:8} }); finalY = doc.lastAutoTable.finalY + 7; } doc.setFontSize(12); doc.setTextColor(primaryColor); doc.text("Detailed Activity Log:", 14, finalY); finalY += 6; const logTableBody = entriesForDate.sort((a,b)=>a.startTimeObj - b.startTimeObj).map(entry => [ // Chronological for PDF entry.startTime, entry.endTime, optc_formatDurationForDisplay(entry.durationMinutes), entry.activityName, entry.categoryName, entry.isProductive ? 'Productive' : 'Non-Prod.' ]); if(logTableBody.length > 0) { doc.autoTable({ startY: finalY, head: [['Start', 'End', 'Duration', 'Activity', 'Category', 'Type']], body: logTableBody, theme: 'grid', headStyles: { fillColor: primaryColor, textColor: '#ffffff', fontSize: 9 }, styles: { fontSize: 8, cellPadding: 1.5, overflow: 'linebreak' } }); } else { doc.setFontSize(9); doc.setTextColor(darkColor); doc.text("No activities logged for this date.", 14, finalY); } doc.save(`Office_Productivity_Report_${reportDateStr.replace(/\//g, '-')}.pdf`); }
Scroll to Top