Assess Current State & Get Recovery Suggestions
Suggested Recovery Activities
Based on your input, consider these activities. Select ones you'd like to plan:
Plan Your Recovery Activities
Add Activity to Plan for
Planned Activities for
Track Recovery & Reflect
Log Completion & Effectiveness for
Select a date to see planned activities.
Weekly Reflection (Optional)
Activity Log & Effectiveness Trends
Recovery Activity Library & Settings
Manage Recovery Activities
Activity Library:
Select a date to log completion.
No activities planned for this date to track.
'; return; } activitiesToTrack.forEach(pAct => { const activityDetails = wrp_recoveryActivities.find(a => a.id === pAct.activityId); const div = document.createElement('div'); div.className = 'wrp-activity-card'; div.style.borderLeft = `5px solid ${pAct.isDone ? '#10B981' : (activityDetails ? activityDetails.color || '#ccc' : '#ccc')}`; div.innerHTML = ` ${activityDetails ? activityDetails.name : 'Unknown'} Scheduled: ${pAct.scheduledTime || 'Any time'} | Planned: ${wrp_formatDurationFromMinutes(pAct.plannedDurationMins)}Effectiveness: ${pAct.effectiveness ? '⭐'.repeat(pAct.effectiveness) : 'Not rated'} | Notes: ${pAct.completionNotes || 'None'}`; listEl.appendChild(li); }); } function wrp_saveWeeklyReflection() { const weekKey = wrp_getWeekNumberString(document.getElementById('wrp-trackDate').value || WRP_TODAY_CONTEXT.toISOString().split('T')[0]); wrp_weeklyReflections[weekKey] = document.getElementById('wrp-weeklyReflectionText').value; wrp_saveData(); alert("Weekly reflection saved for week " + weekKey.split('-W')[1]); } function wrp_renderEffectivenessChart() { const chartContainer = document.getElementById('wrp-effectivenessChartContainer'); const chartCanvas = document.getElementById('wrp-effectivenessTrendChart'); const completedWithRating = wrp_plannedActivities.filter(p => p.isDone && p.effectiveness); if (completedWithRating.length < 3) { chartContainer.style.display = 'none'; return; } chartContainer.style.display = 'block'; // Aggregate effectiveness by activity type for a simple bar chart const effectivenessByActivityType = {}; // { activityName: { totalRating: X, count: Y, color: Z } } completedWithRating.forEach(pAct => { const activity = wrp_recoveryActivities.find(a => a.id === pAct.activityId); if (activity) { if (!effectivenessByActivityType[activity.name]) { effectivenessByActivityType[activity.name] = { totalRating: 0, count: 0, color: activity.color || '#ccc' }; } effectivenessByActivityType[activity.name].totalRating += pAct.effectiveness; effectivenessByActivityType[activity.name].count++; } }); const labels = Object.keys(effectivenessByActivityType); const data = labels.map(name => (effectivenessByActivityType[name].totalRating / effectivenessByActivityType[name].count).toFixed(1) ); const colors = labels.map(name => effectivenessByActivityType[name].color); if (wrp_effectivenessChartInstance) wrp_effectivenessChartInstance.destroy(); wrp_effectivenessChartInstance = new Chart(chartCanvas.getContext('2d'), { type: 'bar', data: { labels: labels, datasets: [{ label: 'Avg. Effectiveness (1-5)', data: data, backgroundColor: colors }] }, options: { responsive: true, maintainAspectRatio: false, scales: { y: { beginAtZero: true, max: 5, title:{display:true, text:'Avg. Rating'} } }, plugins: {legend:{display:false}} } }); } // --- Activity Library Tab --- document.getElementById('wrp-recoveryActivityForm').onsubmit = (e) => { /* Standard CRUD for activity types */ e.preventDefault(); const id = document.getElementById('wrp-activityId').value; const name = document.getElementById('wrp-activityName').value.trim(); const category = document.getElementById('wrp-activityCategory').value; const duration = parseInt(document.getElementById('wrp-activityDefaultDuration').value); if(!name || !category || isNaN(duration) || duration <=0) { alert("Valid name, category and duration required."); return; } const activityData = { id: id || wrp_generateId(), name, category, defaultDurationMins: duration, isDefault: id ? wrp_recoveryActivities.find(a=>a.id===id).isDefault : false }; // Find default color for category if new, or keep existing color const catColors = {'Physical':'#A0D2DB', 'Mental':'#FFE08C', 'SocialEmotional':'#D1C4E9', 'Restorative':'#FFCCBC'}; activityData.color = id ? (wrp_recoveryActivities.find(a=>a.id===id).color || catColors[category]) : catColors[category]; if (id) wrp_recoveryActivities = wrp_recoveryActivities.map(a => a.id === id ? activityData : a); else wrp_recoveryActivities.push(activityData); wrp_saveData(); wrp_renderActivityLibraryList(); wrp_resetRecoveryActivityForm(); wrp_populateActivitySelectForPlan(); // Update planner dropdown }; function wrp_resetRecoveryActivityForm() {document.getElementById('wrp-recoveryActivityForm').reset(); document.getElementById('wrp-activityId').value=''; document.getElementById('wrp-cancelActivityEditBtn').style.display='none';} function wrp_renderActivityLibraryList() { const listEl = document.getElementById('wrp-activityLibraryList'); listEl.innerHTML = ''; if(wrp_recoveryActivities.length === 0) { listEl.innerHTML = '
${act.name} (${act.category}, ${act.defaultDurationMins}min) ${act.isDefault ? '(Default)':''}
${!act.isDefault ? ``:''}
`;
listEl.appendChild(li);
});
}
function wrp_editRecoveryActivity(id) {
const act = wrp_recoveryActivities.find(a=>a.id===id); if(!act) return;
document.getElementById('wrp-activityId').value = act.id;
document.getElementById('wrp-activityName').value = act.name;
document.getElementById('wrp-activityCategory').value = act.category;
document.getElementById('wrp-activityDefaultDuration').value = act.defaultDurationMins;
document.getElementById('wrp-cancelActivityEditBtn').style.display='inline-block';
}
function wrp_deleteRecoveryActivity(id) {
if(wrp_plannedActivities.some(p => p.activityId === id)) { alert("Cannot delete: This activity is used in your recovery plans."); return; }
if(confirm('Delete this activity from the library?')){ wrp_recoveryActivities = wrp_recoveryActivities.filter(a=>a.id!==id); wrp_saveData(); wrp_renderActivityLibraryList(); wrp_populateActivitySelectForPlan();}
}
// --- PDF Download ---
document.getElementById('wrp-downloadPdfBtn').onclick = async () => {
const { jsPDF } = window.jspdf; const pdf = new jsPDF('p', 'mm', 'a4');
let currentY = 15; const margin = 15; const contentWidth = pdf.internal.pageSize.getWidth() - 2*margin;
const accentColor = '#81C784'; const textColor = '#388E3C';
const planDateForReport = document.getElementById('wrp-planDate').value || WRP_TODAY_CONTEXT.toISOString().split('T')[0];
pdf.setFontSize(18); pdf.setTextColor(accentColor);
pdf.text("Work Recovery Plan & Reflection", pdf.internal.pageSize.getWidth() / 2, currentY, { align: 'center' });
currentY += 8;
pdf.setFontSize(10); pdf.setTextColor(textColor);
pdf.text(`Report Date: ${new Date().toLocaleDateString()} | Plan Focus Date: ${new Date(planDateForReport+"T00:00:00").toLocaleDateString()}`, pdf.internal.pageSize.getWidth() / 2, currentY, { align: 'center'});
currentY += 10;
// Planned Activities for a specific date (e.g. wrp-planDate value)
pdf.setFontSize(12); pdf.setTextColor(accentColor);
pdf.text(`Planned Recovery Activities for ${new Date(planDateForReport+"T00:00:00").toLocaleDateString()}:`, margin, currentY); currentY += 6;
const plannedForDate = wrp_plannedActivities.filter(p => p.date === planDateForReport);
if (plannedForDate.length > 0) {
const planBody = plannedForDate.map(pAct => {
const activity = wrp_recoveryActivities.find(a => a.id === pAct.activityId);
return [
pAct.scheduledTime || 'Any time',
activity ? activity.name : 'Unknown',
`${pAct.plannedDurationMins} min`,
pAct.isDone ? 'Done' : 'Pending',
pAct.isDone && pAct.effectiveness ? `${pAct.effectiveness}★` : '-'
];
});
pdf.autoTable({
head: [["Time", "Activity", "Duration", "Status", "Effectiveness"]], body: planBody, startY: currentY,
theme: 'grid', headStyles: { fillColor: accentColor, textColor: '#FFFFFF' }, styles: { fontSize: 9, cellPadding: 1.5 }
});
currentY = pdf.lastAutoTable.finalY + 7;
} else { pdf.setFontSize(9); pdf.text("No activities planned for this specific date.", margin, currentY); currentY += 6; }
// Recent Completed Activity Log & Effectiveness
const completedForLog = wrp_plannedActivities.filter(p => p.isDone).sort((a,b) => new Date(b.date) - new Date(a.date)).slice(0,10); // Last 10 completed
if(completedForLog.length > 0) {
if (currentY > pdf.internal.pageSize.getHeight() - 40) { pdf.addPage(); currentY = margin; }
pdf.setFontSize(12); pdf.setTextColor(accentColor);
pdf.text("Recent Completed Recovery Activities & Effectiveness:", margin, currentY); currentY +=6;
const completedBody = completedForLog.map(pAct => {
const activity = wrp_recoveryActivities.find(a => a.id === pAct.activityId);
return [
new Date(pAct.date+"T00:00:00").toLocaleDateString(),
activity ? activity.name : 'Unknown',
pAct.effectiveness ? `${pAct.effectiveness}★` : 'Not Rated',
(pAct.completionNotes || '-').substring(0,50)
];
});
pdf.autoTable({
head: [["Date", "Activity", "Effectiveness", "Notes"]], body: completedBody, startY: currentY,
theme: 'striped', headStyles: { fillColor: '#E6F4EA' }, styles: { fontSize: 8, cellPadding: 1.5 },
columnStyles: { 3: { cellWidth: 'auto'} }
});
currentY = pdf.lastAutoTable.finalY + 7;
}
// Weekly Reflection
const weekKeyForReflection = wrp_getWeekNumberString(planDateForReport);
const reflectionText = wrp_weeklyReflections[weekKeyForReflection];
if(reflectionText) {
if (currentY > pdf.internal.pageSize.getHeight() - 30) { pdf.addPage(); currentY = margin; }
pdf.setFontSize(12); pdf.setTextColor(accentColor);
pdf.text(`Reflection for Week ${weekKeyForReflection.split('-W')[1]}:`, margin, currentY); currentY +=6;
pdf.setFontSize(10); pdf.setTextColor(textColor);
const lines = pdf.splitTextToSize(reflectionText, contentWidth);
pdf.text(lines, margin, currentY);
}
pdf.save(`Work_Recovery_Plan_${planDateForReport}.pdf`);
};
// --- Initial Load ---
document.addEventListener('DOMContentLoaded', () => {
wrp_openTab(null, wrp_tabs[0]);
const firstTabButton = document.querySelector(`.wrp-tab-button[onclick*="'${wrp_tabs[0]}'"]`);
if (firstTabButton) firstTabButton.classList.add('active');
else console.error("First tab button not found for initial activation.");
wrp_updateNavButtons();
});
