Dynamic Goal-Setting Assistant
Goal Overview
Goals by Status
Goals by Category
Set a New Goal
My Goals List
Export Goal Plan
Download a summary of all your goals and their progress as a PDF document.
No goals set yet. Go to the "Set/Edit Goal" tab to add one!
'; return; } goals.forEach(goal => { const progress = goal.milestones.length > 0 ? (goal.milestones.filter(m => m.done).length / goal.milestones.length) * 100 : (goal.status === 'Completed' ? 100 : 0); const card = document.createElement('div'); card.className = 'bg-white border rounded-lg p-4 shadow-sm'; card.innerHTML = `${goal.name}
${goal.category} - Deadline: ${goal.deadline}
Progress
${Math.round(progress)}%
${milestone.text}
`).join('');
}
// --- LOGIC & EVENT HANDLERS ---
function clearForm() {
goalForm.reset();
goalIdInput.value = '';
currentMilestones = [];
renderMilestones();
formTitle.textContent = 'Set a New Goal';
saveGoalBtn.textContent = 'Set Goal';
}
addMilestoneBtn.addEventListener('click', () => {
const text = newMilestoneInput.value.trim();
if (text) {
currentMilestones.push({ text, done: false });
newMilestoneInput.value = '';
renderMilestones();
}
});
window.toggleMilestone = (index) => {
currentMilestones[index].done = !currentMilestones[index].done;
renderMilestones();
};
window.removeMilestone = (index) => {
currentMilestones.splice(index, 1);
renderMilestones();
};
goalForm.addEventListener('submit', (e) => {
e.preventDefault();
const id = goalIdInput.value ? parseInt(goalIdInput.value) : null;
const goalData = {
name: goalNameInput.value,
category: goalCategoryInput.value,
deadline: goalDeadlineInput.value,
status: 'Not Started',
milestones: [...currentMilestones]
};
if (id) {
const index = goals.findIndex(g => g.id === id);
goalData.status = goals[index].status; // Preserve status on edit
goals[index] = { ...goals[index], ...goalData };
} else {
const newId = goals.length > 0 ? Math.max(...goals.map(g => g.id)) + 1 : 1;
goals.push({ id: newId, ...goalData });
}
clearForm();
renderAll();
changeTab(null, 'my-goals');
});
window.editGoal = (id) => {
const goal = goals.find(g => g.id === id);
if (goal) {
goalIdInput.value = goal.id;
goalNameInput.value = goal.name;
goalCategoryInput.value = goal.category;
goalDeadlineInput.value = goal.deadline;
currentMilestones = JSON.parse(JSON.stringify(goal.milestones)); // Deep copy
renderMilestones();
formTitle.textContent = 'Edit Goal';
saveGoalBtn.textContent = 'Save Changes';
changeTab(null, 'set-goal');
}
};
window.deleteGoal = (id) => {
if(confirm('Are you sure you want to delete this goal?')) {
goals = goals.filter(g => g.id !== id);
renderAll();
}
};
window.updateGoalStatus = (id, newStatus) => {
const goal = goals.find(g => g.id === id);
if (goal) {
goal.status = newStatus;
renderAll();
}
};
function downloadPDF() {
const { jsPDF } = window.jspdf;
const pdfContentEl = document.getElementById('pdf-content');
let reportHTML = `My Goal Plan
`; goals.forEach(goal => { const progress = goal.milestones.length > 0 ? Math.round((goal.milestones.filter(m => m.done).length / goal.milestones.length) * 100) : (goal.status === 'Completed' ? 100 : 0); reportHTML += `${goal.name} (${goal.category})
Deadline: ${goal.deadline} | Status: ${goal.status} | Progress: ${progress}%
Milestones:
- ${goal.milestones.map(m => `
- ${m.done ? '☑' : '☐'} ${m.text} `).join('')}
${reportHTML}
`;
html2canvas(pdfContentEl, { scale: 2 }).then(canvas => {
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF({ orientation: 'portrait', unit: 'pt', format: 'a4' });
const pdfWidth = pdf.internal.pageSize.getWidth();
const imgProps = pdf.getImageProperties(imgData);
const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
pdf.addImage(imgData, 'PNG', 20, 20, pdfWidth - 40, pdfHeight - 40);
pdf.save('My_Goal_Plan.pdf');
});
}
function renderAll() {
renderGoalsList();
renderCharts();
}
// --- TAB NAVIGATION ---
window.changeTab = function(evt, tabName) {
document.querySelectorAll(".tab-content").forEach(tc => tc.classList.remove('active'));
document.querySelectorAll(".tab-button").forEach(tb => tb.classList.remove('active'));
document.getElementById(tabName).classList.add('active');
const button = evt ? evt.currentTarget : document.querySelector(`.tab-button[onclick*="'${tabName}'"]`);
if(button) button.classList.add('active');
currentTab = tabName;
updateNavButtons();
if (tabName === 'dashboard') renderCharts();
}
function updateNavButtons() {
const currentIndex = tabs.indexOf(currentTab);
prevBtn.disabled = currentIndex === 0;
nextBtn.disabled = currentIndex === tabs.length - 1;
prevBtn.classList.toggle('opacity-50', prevBtn.disabled);
nextBtn.classList.toggle('opacity-50', nextBtn.disabled);
}
prevBtn.addEventListener('click', () => {
const currentIndex = tabs.indexOf(currentTab);
if (currentIndex > 0) changeTab(null, tabs[currentIndex - 1]);
});
nextBtn.addEventListener('click', () => {
const currentIndex = tabs.indexOf(currentTab);
if (currentIndex < tabs.length - 1) changeTab(null, tabs[currentIndex + 1]);
});
// --- INITIALIZATION ---
clearFormBtn.addEventListener('click', clearForm);
downloadPdfBtn.addEventListener('click', downloadPDF);
renderAll();
updateNavButtons();
});
