Postpartum Recovery Planner

Postpartum Recovery Planner

Your personal guide to a healthy and mindful recovery.

Recovery Dashboard

Baby's Birth Date

Set this to track your postpartum weeks.

Latest Mood Entry

No mood logged yet.

Last Feeding Logged

No feeding logged yet.

Next Appointment

No upcoming appointments.

Daily Log

Feeding Log

Logged Entries

Your daily logs will appear here.

Appointments Tracker

Add New Appointment

Upcoming Appointments

Your appointments will appear here.

My Support Team

Add a Contact

Contact List

Your support contacts will appear here.

My Postpartum Recovery Plan

Review your consolidated plan above. When you're ready, you can download it as a PDF.

Feeding: ${log.feedTime}, ${log.feedType}, ${log.feedAmount}

` : ''}
`).join(''); }; // Appointments Logic addApptBtn.addEventListener('click', () => { if (!apptDateInput.value || !apptProviderInput.value) return; const appointment = { id: Date.now(), for: apptForInput.value, date: apptDateInput.value, time: apptTimeInput.value, provider: apptProviderInput.value, notes: apptNotesInput.value, }; plannerData.appointments.push(appointment); renderAppointments(); updateDashboard(); apptDateInput.value = ''; apptTimeInput.value = ''; apptProviderInput.value = ''; apptNotesInput.value = ''; }); renderAppointments = () => { if (plannerData.appointments.length === 0) { appointmentListContainer.innerHTML = `

Your appointments will appear here.

`; return; } appointmentListContainer.innerHTML = plannerData.appointments .sort((a, b) => new Date(a.date) - new Date(b.date)) .map(appt => `

${formatDate(appt.date)} at ${appt.time || 'N/A'}

${appt.provider} (For: ${appt.for})

${appt.notes ? `

Notes: ${appt.notes}

` : ''}
`).join(''); }; // Resources Logic addResourceBtn.addEventListener('click', () => { if (!contactNameInput.value || !contactRoleInput.value) return; const resource = { id: Date.now(), name: contactNameInput.value, role: contactRoleInput.value, phone: contactPhoneInput.value, email: contactEmailInput.value, }; plannerData.resources.push(resource); renderResources(); contactNameInput.value = ''; contactRoleInput.value = ''; contactPhoneInput.value = ''; contactEmailInput.value = ''; }); renderResources = () => { if (plannerData.resources.length === 0) { resourceListContainer.innerHTML = `

Your support contacts will appear here.

`; return; } resourceListContainer.innerHTML = plannerData.resources.map(res => `

${res.name} - ${res.role}

${res.phone ? `

Phone: ${res.phone}

` : ''} ${res.email ? `

Email: ${res.email}

` : ''}
`).join(''); }; // --- AI FEATURE HANDLERS --- getInsightsBtn.addEventListener('click', async () => { const mood = moodInput.value; const symptoms = physicalSymptomsInput.value; const journal = journalEntryInput.value; if (!mood && !symptoms && !journal) { insightsResult.innerHTML = "Please enter how you're feeling or your symptoms to get an insight."; insightsResult.classList.remove('hidden'); return; } const prompt = `As a friendly and supportive AI assistant for a new mother, provide a short, gentle, and encouraging insight based on her daily log. Do not provide medical advice. Be warm and empathetic. Her log today: - Mood: ${mood} - Physical Symptoms: ${symptoms || 'Not specified'} - Private thoughts: ${journal || 'Not specified'} Respond with 2-3 sentences of encouragement or a simple mindfulness tip.`; const response = await callGeminiApi(prompt, insightsLoader, insightsResult, getInsightsBtn); insightsResult.innerHTML = `

${response.replace(/\n/g, '
')}

Disclaimer: This is an AI-generated insight and not medical advice. Always consult a healthcare professional.

`; insightsResult.classList.remove('hidden'); }); getQuestionsBtn.addEventListener('click', async () => { const apptFor = apptForInput.value; const reason = apptProviderInput.value; if (!reason) { apptNotesInput.value = "Please enter a reason for the appointment to get suggested questions."; return; } const prompt = `Generate a helpful list of 5-7 questions a new parent should ask a healthcare provider during an appointment. The appointment is for the "${apptFor}" and the reason is "${reason}". Format the output as a numbered list. Do not include a preamble or conclusion, just the list of questions.`; const response = await callGeminiApi(prompt, questionsLoader, null, getQuestionsBtn); const currentNotes = apptNotesInput.value; const separator = currentNotes.trim() === '' ? '' : '\n\n--- Suggested Questions ---\n'; apptNotesInput.value = currentNotes + separator + response; }); // --- SUMMARY & PDF GENERATION --- renderSummary = () => { summaryDateEl.textContent = `Report generated on ${new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })}`; summaryAppointmentsContainer.innerHTML = plannerData.appointments.length > 0 ? `

Appointments

${plannerData.appointments.map(a => `

${formatDate(a.date)}: ${a.provider} (For: ${a.for})

${a.notes ? `

Notes: ${a.notes}

` : ''}
`).join('')}
` : `

No Appointments Logged

`; summaryLogsContainer.innerHTML = plannerData.logs.length > 0 ? `

Daily Log Summary

${plannerData.logs.map(l => `

${formatDate(l.date)}: Mood: ${l.mood}

${l.symptoms ? `

Symptoms: ${l.symptoms}

` : ''}${l.journal ? `

Journal: ${l.journal}

` : ''}${l.feedType ? `

Feeding: ${l.feedTime}, ${l.feedType}, ${l.feedAmount}

` : ''}
`).join('')}
` : `

No Daily Logs Recorded

`; summaryResourcesContainer.innerHTML = plannerData.resources.length > 0 ? `

My Support Team

${plannerData.resources.map(r => `

${r.name} - ${r.role}

${r.phone || ''} ${r.email ? `| ${r.email}` : ''}

`).join('')}
` : `

No Support Contacts Added

`; }; downloadPdfBtn.addEventListener('click', () => { const content = document.getElementById('pdf-content'); if (!content) return; pdfLoader.classList.remove('hidden'); downloadPdfBtn.disabled = true; html2canvas(content, { scale: 2, useCORS: true, backgroundColor: '#ffffff' }) .then(canvas => { const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const ratio = canvas.width / canvas.height; const imgWidth = pdfWidth - 20; const imgHeight = imgWidth / ratio; let heightLeft = imgHeight; let position = 10; pdf.addImage(imgData, 'PNG', 10, position, imgWidth, imgHeight); heightLeft -= (pdfHeight - 20); while (heightLeft > 0) { position = -heightLeft - 10; pdf.addPage(); pdf.addImage(imgData, 'PNG', 10, position, imgWidth, imgHeight); heightLeft -= (pdfHeight - 20); } pdf.save('Postpartum-Recovery-Plan.pdf'); }) .catch(err => console.error("PDF Generation Error:", err)) .finally(() => { pdfLoader.classList.add('hidden'); downloadPdfBtn.disabled = false; }); }); // --- UTILITY FUNCTIONS --- const formatDate = (dateString) => { if (!dateString) return 'N/A'; const date = new Date(dateString + 'T00:00:00'); return date.toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' }); }; // --- RUN INITIALIZATION --- initialize(); });
Scroll to Top