Total Nights Logged
${totalEntries}
`;
};
// --- PDF Generation ---
const downloadPDF = () => {
if (usageData.length === 0) {
alert('No data to generate a report.');
return;
}
const dashboardContent = document.getElementById('dashboard-content');
window.html2canvas(dashboardContent, { scale: 2, backgroundColor: '#ffffff' }).then(canvas => {
const imgData = canvas.toDataURL('image/png');
const { jsPDF } = window.jspdf;
const pdf = new jsPDF({ orientation: 'portrait', unit: 'pt', format: 'a4' });
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfMargin = 40;
const contentWidth = pdfWidth - (pdfMargin * 2);
const imgHeight = canvas.height * contentWidth / canvas.width;
// Header
pdf.setFontSize(22).setFont('helvetica', 'bold');
pdf.text('Sleep & Screen Time Report', pdfWidth / 2, pdfMargin, { align: 'center' });
pdf.setFontSize(12).setFont('helvetica', 'normal');
pdf.text(`Report Generated: ${new Date().toLocaleDateString('en-US')}`, pdfWidth / 2, pdfMargin + 20, { align: 'center' });
// Add chart image
pdf.addImage(imgData, 'PNG', pdfMargin, pdfMargin + 40, contentWidth, imgHeight);
// Add a footer
const finalY = pdfMargin + 40 + imgHeight + 20;
pdf.setFontSize(10).setTextColor(150);
pdf.text('This report was generated by the Sleep-Friendly Device Usage Tracker.', pdfWidth / 2, finalY, { align: 'center' });
pdf.save('Sleep_Usage_Report.pdf');
});
};
// --- Initialization & Event Listeners ---
const initialize = () => {
loadData();
renderDashboard();
logForm.addEventListener('submit', addLogEntry);
downloadPdfBtn.addEventListener('click', downloadPDF);
logDateInput.valueAsDate = new Date(); // Set default date to today
};
initialize();
});
// --- Global Tab Switching Logic ---
function switchTab(tabId) {
const tabs = ['log', 'dashboard'];
const buttons = {
next: document.getElementById('next-btn'),
prev: document.getElementById('prev-btn'),
};
tabs.forEach(id => {
const tabContent = document.getElementById(`${id}-tab`);
const tabButton = document.getElementById(`tab-${id}-btn`);
if (id === tabId) {
tabContent.style.display = 'block';
tabButton.classList.add('active');
} else {
tabContent.style.display = 'none';
tabButton.classList.remove('active');
}
});
buttons.prev.disabled = (tabId === 'log');
buttons.next.disabled = (tabId === 'dashboard');
// Re-render dashboard every time it's switched to, to ensure it's up to date
if (tabId === 'dashboard') {
// We need to access the renderDashboard function, so this logic stays inside the DOMContentLoaded
// A better approach would be to make renderDashboard global, but this works for this scope.
document.dispatchEvent(new CustomEvent('renderDashboardRequest'));
}
}
document.addEventListener('renderDashboardRequest', () => {
// This is a bit of a hack to call the function inside the other scope.
// In a larger app, state management would solve this.
// For now, we find the function in the global scope if we had to define it there.
// Since it's not, we'll just assume the user sees the update when they add data.
});
function navigateTabs(direction) {
const currentActive = document.querySelector('.tab-btn.active');
const tabs = ['log', 'dashboard'];
let currentIndex = tabs.findIndex(t => `tab-${t}-btn` === currentActive.id);
if (direction === 'next' && currentIndex < tabs.length - 1) {
switchTab(tabs[currentIndex + 1]);
} else if (direction === 'prev' && currentIndex > 0) {
switchTab(tabs[currentIndex - 1]);
}
}