Online Study Motivation & Habit Tracker

Study Motivation & Habit Tracker

Build productive habits and stay motivated on your learning journey.

"The secret to getting ahead is getting started."

- Mark Twain

Weekly Habit Tracker

No habits added yet. Add one below to get started!

'; } habits.forEach((habit, habitIndex) => { const habitEl = document.createElement('div'); habitEl.className = 'habit-item'; let daysHTML = ''; daysOfWeek.forEach((day, dayIndex) => { daysHTML += `
${day}
`; }); const streak = calculateStreak(habit.completedDays); habitEl.innerHTML = `

${habit.name}

🔥 ${streak} Day Streak
${daysHTML}
`; habitList.appendChild(habitEl); }); addEventListenersToHabits(); }; const addEventListenersToHabits = () => { document.querySelectorAll('.day-check').forEach(el => { el.addEventListener('click', toggleDayCompletion); }); document.querySelectorAll('.remove-habit-btn').forEach(el => { el.addEventListener('click', removeHabit); }); }; const addNewHabit = () => { const habitName = newHabitInput.value.trim(); if (!habitName) { showMessage('Please enter a habit name.', 'error'); return; } const today = new Date(); habits.push({ name: habitName, completedDays: [false, false, false, false, false, false, false], weekStartDate: getStartOfWeek(today).toISOString().split('T')[0] }); newHabitInput.value = ''; saveData(); renderHabits(); }; const removeHabit = (event) => { const habitIndex = parseInt(event.target.dataset.habitIndex, 10); habits.splice(habitIndex, 1); saveData(); renderHabits(); }; const toggleDayCompletion = (event) => { const habitIndex = parseInt(event.target.dataset.habitIndex, 10); const dayIndex = parseInt(event.target.dataset.dayIndex, 10); habits[habitIndex].completedDays[dayIndex] = !habits[habitIndex].completedDays[dayIndex]; saveData(); renderHabits(); }; const calculateStreak = (completedDays) => { let currentStreak = 0; let todayIndex = new Date().getDay(); // Sunday is 0 // Check today if (completedDays[todayIndex]) { currentStreak = 1; // Check backwards from yesterday for (let i = 1; i < 7; i++) { let checkIndex = (todayIndex - i + 7) % 7; if (completedDays[checkIndex]) { currentStreak++; } else { break; // Streak is broken } } } return currentStreak; }; // --- PDF Export --- pdfBtn.addEventListener('click', () => { if (habits.length === 0) { showMessage('No habits to report.', 'error'); return; } const { jsPDF } = window.jspdf; const doc = new jsPDF(); doc.setFontSize(18); doc.text('Weekly Habit Progress Report', 105, 20, { align: 'center' }); doc.setFontSize(12); doc.text(`Week of: ${getStartOfWeek(new Date()).toLocaleDateString()}`, 105, 30, { align: 'center' }); const tableData = habits.map(habit => { const completionCount = habit.completedDays.filter(Boolean).length; const streak = calculateStreak(habit.completedDays); return [ habit.name, `${completionCount} / 7`, `${streak} days` ]; }); doc.autoTable({ startY: 40, head: [['Habit', 'Weekly Completion', 'Current Streak']], body: tableData, headStyles: { fillColor: [79, 70, 229] } }); doc.save('habit-progress-report.pdf'); }); // --- Utility Functions --- const getStartOfWeek = (date) => { const d = new Date(date); const day = d.getDay(); // 0 for Sunday const diff = d.getDate() - day; return new Date(d.setDate(diff)); }; const showMessage = (message, type = 'success') => { messageBox.textContent = message; messageBox.className = `message-box ${type} show`; setTimeout(() => { messageBox.classList.remove('show'); }, 3000); }; // --- Initial Load --- addHabitBtn.addEventListener('click', addNewHabit); newHabitInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') addNewHabit(); }); loadData(); renderHabits(); showNewQuote(); });
Scroll to Top