Family Game Plan Generator

Family Game Plan Generator

1. Roster & Week Details

Family Members (Roster)

2. Daily Tasks & Chores

3. Reward Zone

Configure details in the Data Configuration tab and click "Update Plan" to generate the structured plan here.

${rosterHtml}

Weekly Mission/Goal

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

Daily Chore and Routine Matrix

${tableRowsHtml || ''}
Task/Chore Owner Mon Tue Wed Thu Fri Sat Sun
No tasks added.

*Check boxes can be printed and marked manually.

Reward Zone

${rewardsHtml} `; planContentDiv.innerHTML = planHtml; } // --- Event Handlers (Configuration) --- // Add Member addMemberBtn.addEventListener("click", function() { var newMemberName = newMemberInput.value.trim(); if (newMemberName && !appState.members.includes(newMemberName)) { appState.members.push(newMemberName); newMemberInput.value = ""; renderConfigLists(); } }); // Add Task addTaskBtn.addEventListener("click", function() { var taskName = taskNameInput.value.trim(); var taskOwner = taskOwnerSelect.value.trim(); var taskTime = taskTimeInput.value.trim(); if (taskName && taskOwner) { var newId = appState.tasks.length > 0 ? appState.tasks[appState.tasks.length - 1].id + 1 : 1; appState.tasks.push({ id: newId, name: taskName, owner: taskOwner, time: taskTime }); taskNameInput.value = ""; taskTimeInput.value = ""; taskOwnerSelect.value = ""; renderConfigLists(); } else { alert("Please enter both the Task Name and assign an Owner."); } }); // Add Reward addRewardBtn.addEventListener("click", function() { var rewardName = rewardNameInput.value.trim(); var rewardCost = rewardCostInput.value.trim(); if (rewardName && rewardCost) { appState.rewards.push({ name: rewardName, cost: rewardCost }); rewardNameInput.value = ""; rewardCostInput.value = ""; renderConfigLists(); } else { alert("Please enter both the Reward Name and its Cost/Condition."); } }); // Remove Items (Delegation) toolContainer.addEventListener("click", function(e) { if (e.target.classList.contains("fgp-remove-btn-sm")) { var type = e.target.dataset.type; var nameToRemove = e.target.dataset.name; var idToRemove = parseInt(e.target.dataset.id); if (type === 'member') { appState.members = appState.members.filter(function(m) { return m !== nameToRemove; }); // Unassign tasks from removed member appState.tasks.forEach(function(task) { if (task.owner === nameToRemove) { task.owner = "Unassigned"; } }); } else if (type === 'task') { appState.tasks = appState.tasks.filter(function(t) { return t.id !== idToRemove; }); } else if (type === 'reward') { appState.rewards = appState.rewards.filter(function(r) { return r.name !== nameToRemove; }); } renderConfigLists(); } }); // Update State from Inputs updateBtn.addEventListener("click", function() { appState.planName = planNameInput.value; appState.startDate = startDateInput.value; appState.endDate = endDateInput.value; appState.goal = goalInput.value; renderDashboardTab(); showTab(1); // Switch to Dashboard }); // --- PDF Download --- pdfBtn.addEventListener("click", function() { var jsPDF = window.jspdf.jsPDF; var fileName = `${planNameInput.value.replace(/[^a-zA-Z0-9\s]/g, '').replace(/\s/g, '_')}_Game_Plan.pdf` || 'Family_Game_Plan.pdf'; // 1. Temporarily hide action column from PDF view var actionCells = exportArea.querySelectorAll('.fgp-remove-btn-sm'); actionCells.forEach(function(cell) { cell.style.display = 'none'; }); html2canvas(exportArea, { scale: 2, useCORS: true, backgroundColor: '#ffffff' }).then(function(canvas) { // 2. Restore action column actionCells.forEach(function(cell) { cell.style.display = 'block'; }); var imgData = canvas.toDataURL('image/png'); var doc = new jsPDF({ orientation: 'l', // Landscape is better for chore matrix unit: 'pt', format: 'a4' }); var pdfWidth = doc.internal.pageSize.getWidth(); var pdfHeight = doc.internal.pageSize.getHeight(); var imgProps = doc.getImageProperties(imgData); var imgWidth = imgProps.width; var imgHeight = imgProps.height; var margin = 30; var usableWidth = pdfWidth - (2 * margin); var ratio = usableWidth / imgWidth; var scaledHeight = imgHeight * ratio; if (scaledHeight > pdfHeight - (2 * margin)) { var pageHeight = pdfHeight - (2 * margin); var heightLeft = scaledHeight; var position = 0; while (heightLeft > 0) { doc.addImage(imgData, 'PNG', margin, position + margin, usableWidth, scaledHeight); heightLeft -= pageHeight; position -= pageHeight; if (heightLeft > 0) { doc.addPage(); } } } else { // Single page doc.addImage(imgData, 'PNG', margin, margin, usableWidth, scaledHeight); } doc.save(fileName); }).catch(function(err) { actionCells.forEach(function(cell) { cell.style.display = 'block'; }); // Restore on error console.error("FGP PDF Error:", err); // alert("An error occurred while generating the PDF."); // Per spec }); }); // --- Initial Load --- var today = new Date(); var tomorrow = new Date(today); tomorrow.setDate(today.getDate() + 7); startDateInput.value = today.toISOString().split('T')[0]; endDateInput.value = tomorrow.toISOString().split('T')[0]; renderConfigLists(); renderDashboardTab(); showTab(0); });
Scroll to Top