`;
scheduleContentEl.innerHTML = `
`).join('');
container.addEventListener('change', handleConfigChange);
}
function handleConfigChange(e) {
if (e.target.dataset.configKey) {
const keys = e.target.dataset.configKey.split('.');
state.config[keys[0]][keys[1]] = parseInt(e.target.value);
}
}
// --- PDF GENERATION ---
window.downloadPDF = async () => {
const { jsPDF } = window.jspdf;
if (!state.scheduleData) return;
const { age, schedule, totalDaySleep } = state.scheduleData;
const reportContainer = document.createElement('div');
reportContainer.id = 'pdf-report';
reportContainer.className = 'w-[800px] bg-white p-10 text-gray-800';
reportContainer.style.position = 'absolute';
reportContainer.style.left = '-9999px';
reportContainer.style.fontFamily = 'Inter, sans-serif';
const scheduleHtml = schedule.map(item => `
${item.icon}
${item.type}
${item.time}
`).join('');
reportContainer.innerHTML = `
${scheduleHtml}
`;
document.body.appendChild(reportContainer);
try {
const canvas = await html2canvas(reportContainer, { scale: 2, useCORS: true, logging: false });
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'a4' });
const pageHeight = pdf.internal.pageSize.getHeight();
const pageWidth = pdf.internal.pageSize.getWidth();
const margin = 15;
const contentWidth = pageWidth - (margin * 2);
const imgProps = pdf.getImageProperties(imgData);
const contentHeight = (imgProps.height * contentWidth) / imgProps.width;
let heightLeft = contentHeight;
let position = 0;
pdf.addImage(imgData, 'PNG', margin, margin, contentWidth, contentHeight);
heightLeft -= (pageHeight - (margin * 2));
while (heightLeft > 0) {
position -= (pageHeight - (margin * 2));
pdf.addPage();
pdf.addImage(imgData, 'PNG', margin, position + margin, contentWidth, contentHeight);
heightLeft -= (pageHeight - (margin * 2));
}
pdf.save('Infant-Sleep-Schedule.pdf');
} catch (error) {
console.error("Error generating PDF:", error);
alert("Sorry, there was an error creating the PDF report.");
} finally {
document.body.removeChild(reportContainer);
}
};
// --- INITIALIZATION ---
switchTab(1);
populateConfig();
});
${scheduleHtml}
${summaryHtml}`;
schedulePlaceholderEl.classList.add('hidden');
scheduleContentEl.classList.remove('hidden');
}
// --- CONFIGURATION TAB ---
function populateConfig() {
const container = document.getElementById('config-inputs');
container.innerHTML = Object.entries(state.config).map(([age, params]) => `
${age} Months
Infant Sleep Schedule
For Age: ${age} Months
Summary & Notes
Total Naps: ${state.config[age].naps}
Total Daytime Sleep: ${Math.floor(totalDaySleep / 60)} hours, ${totalDaySleep % 60} minutes
Important: This is a sample schedule based on averages. The most important thing is to watch your baby for sleepy cues (yawning, rubbing eyes, fussiness) and adapt the schedule to their individual needs. Wake windows are a guide, not a strict rule.
This tool provides general guidance and is not a substitute for professional medical advice. Consult a pediatrician for any health concerns.
