Online Dynamic Goal-Setting Assistant

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)}%
`; goalsList.appendChild(card); }); } function renderCharts() { if (charts.statusChart) charts.statusChart.destroy(); if (charts.categoryChart) charts.categoryChart.destroy(); const statusCounts = goals.reduce((acc, goal) => { acc[goal.status] = (acc[goal.status] || 0) + 1; return acc; }, {}); const statusCtx = document.getElementById('statusChart').getContext('2d'); charts.statusChart = new Chart(statusCtx, { type: 'doughnut', data: { labels: Object.keys(statusCounts), datasets: [{ data: Object.values(statusCounts), backgroundColor: ['#F59E0B', '#3B82F6', '#10B981'] }] }, options: { responsive: true, maintainAspectRatio: false } }); const categoryCounts = goals.reduce((acc, goal) => { acc[goal.category] = (acc[goal.category] || 0) + 1; return acc; }, {}); const categoryCtx = document.getElementById('categoryChart').getContext('2d'); charts.categoryChart = new Chart(categoryCtx, { type: 'pie', data: { labels: Object.keys(categoryCounts), datasets: [{ data: Object.values(categoryCounts), backgroundColor: ['#EF4444', '#8B5CF6', '#EC4899', '#6366F1'] }] }, options: { responsive: true, maintainAspectRatio: false } }); } function renderMilestones() { milestonesContainer.innerHTML = currentMilestones.map((milestone, index) => `
${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('')}
`; }); pdfContentEl.innerHTML = `
${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(); });
Scroll to Top