// Task Manager Class class TaskManager { constructor() { this.tasks = this.loadTasks(); this.currentFilter = 'all'; this.init(); } init() { this.setupEventListeners(); this.renderTasks(); this.updateStats(); this.startReminderScheduler(); } setupEventListeners() { // Add task document.getElementById('addTaskBtn').addEventListener('click', () => this.addTask()); document.getElementById('taskInput').addEventListener('keypress', (e) => { if (e.key === 'Enter') this.addTask(); }); // Filter buttons document.querySelectorAll('.filter-btn').forEach(btn => { btn.addEventListener('click', (e) => { this.setFilter(e.target.dataset.filter); }); }); // Email modal document.getElementById('closeEmailModal').addEventListener('click', () => { document.getElementById('emailModal').classList.add('hidden'); }); // Close modal on outside click document.getElementById('emailModal').addEventListener('click', (e) => { if (e.target.id === 'emailModal') { document.getElementById('emailModal').classList.add('hidden'); } }); } addTask() { const taskInput = document.getElementById('taskInput'); const emailInput = document.getElementById('emailInput'); const taskText = taskInput.value.trim(); const email = emailInput.value.trim(); if (!taskText) { this.showToast('Please enter a task', 'error'); return; } if (!email || !this.isValidEmail(email)) { this.showToast('Please enter a valid email address', 'error'); return; } const task = { id: Date.now(), text: taskText, email: email, completed: false, hasReminder: false, reminderStopped: false, createdAt: new Date().toISOString(), completedAt: null }; this.tasks.push(task); this.saveTasks(); this.renderTasks(); this.updateStats(); // Clear inputs taskInput.value = ''; emailInput.value = ''; this.showToast('Task added successfully!', 'success'); } toggleTask(id) { const task = this.tasks.find(t => t.id === id); if (task) { task.completed = !task.completed; task.completedAt = task.completed ? new Date().toISOString() : null; // When task is completed, automatically stop reminders if (task.completed) { task.hasReminder = false; task.reminderStopped = true; } this.saveTasks(); this.renderTasks(); this.updateStats(); if (task.completed) { this.showToast('Task completed! Great job! 🎉', 'success'); } else { // If unchecking a completed task, reset reminder status task.reminderStopped = false; this.showToast('Task marked as incomplete', 'info'); } } } toggleReminder(id) { const task = this.tasks.find(t => t.id === id); if (task) { if (task.completed) { this.showToast('Cannot set reminder for completed task', 'error'); return; } if (task.hasReminder && !task.reminderStopped) { // Stop reminder task.hasReminder = false; task.reminderStopped = true; this.showToast('Reminder stopped', 'info'); } else { // Start reminder task.hasReminder = true; task.reminderStopped = false; this.showToast('Reminder started! You\'ll receive email notifications every 30 seconds', 'success'); this.showEmailPreview(task); } this.saveTasks(); this.renderTasks(); this.updateStats(); } } deleteTask(id) { if (confirm('Are you sure you want to delete this task?')) { this.tasks = this.tasks.filter(t => t.id !== id); this.saveTasks(); this.renderTasks(); this.updateStats(); this.showToast('Task deleted', 'info'); } } setFilter(filter) { this.currentFilter = filter; // Update button styles document.querySelectorAll('.filter-btn').forEach(btn => { if (btn.dataset.filter === filter) { btn.className = 'filter-btn px-4 py-2 bg-primary-500 text-white rounded-lg transition-colors'; } else { btn.className = 'filter-btn px-4 py-2 bg-gray-200 text-gray-700 rounded-lg hover:bg-gray-300 transition-colors'; } }); this.renderTasks(); } getFilteredTasks() { switch (this.currentFilter) { case 'pending': return this.tasks.filter(t => !t.completed); case 'completed': return this.tasks.filter(t => t.completed); case 'reminders': return this.tasks.filter(t => t.hasReminder && !t.reminderStopped && !t.completed); default: return this.tasks; } } renderTasks() { const container = document.getElementById('tasksContainer'); const emptyState = document.getElementById('emptyState'); const filteredTasks = this.getFilteredTasks(); if (filteredTasks.length === 0) { container.innerHTML = ''; emptyState.style.display = 'block'; return; } emptyState.style.display = 'none'; container.innerHTML = filteredTasks.map(task => ` `).join(''); // Re-initialize feather icons for new elements feather.replace(); } updateStats() { const total = this.tasks.length; const completed = this.tasks.filter(t => t.completed).length; const pending = total - completed; const reminders = this.tasks.filter(t => t.hasReminder && !t.reminderStopped && !t.completed).length; document.getElementById('totalTasks').textContent = total; document.getElementById('completedTasks').textContent = completed; document.getElementById('pendingTasks').textContent = pending; document.getElementById('activeReminders').textContent = reminders; } showEmailPreview(task) { document.getElementById('emailTo').textContent = task.email; document.getElementById('emailSubject').textContent = task.text; document.getElementById('emailTask').textContent = task.text; document.getElementById('emailModal').classList.remove('hidden'); } startReminderScheduler() { // Simulate sending reminders every 30 seconds for demo setInterval(() => { this.tasks.forEach(task => { if (task.hasReminder && !task.reminderStopped && !task.completed) { // In a real app, this would send an email console.log(`Sending reminder for task: ${task.text} to ${task.email}`); // Show a notification in the browser for demo purposes this.showToast(`Reminder: ${task.text}`, 'info'); } }); }, 30000); // 30 seconds } showToast(message, type = 'info') { const toast = document.createElement('div'); const bgColor = type === 'success' ? 'bg-green-500' : type === 'error' ? 'bg-red-500' : 'bg-blue-500'; toast.className = `fixed bottom-4 right-4 ${bgColor} text-white px-6 py-3 rounded-lg shadow-lg z-50 flex items-center gap-2 task-card-enter`; const icon = type === 'success' ? 'check-circle' : type === 'error' ? 'alert-circle' : 'info'; toast.innerHTML = ` ${message} `; document.body.appendChild(toast); feather.replace(); setTimeout(() => { toast.style.opacity = '0'; setTimeout(() => toast.remove(), 300); }, 3000); } isValidEmail(email) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); } escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } saveTasks() { localStorage.setItem('tasks', JSON.stringify(this.tasks)); } loadTasks() { const saved = localStorage.getItem('tasks'); return saved ? JSON.parse(saved) : []; } } // Custom event delegation for dynamic task cards document.addEventListener('click', (e) => { if (e.target.closest('[data-action="toggle"]')) { const card = e.target.closest('task-card'); taskManager.toggleTask(parseInt(card.id)); } else if (e.target.closest('[data-action="reminder"]')) { const card = e.target.closest('task-card'); taskManager.toggleReminder(parseInt(card.id)); } else if (e.target.closest('[data-action="delete"]')) { const card = e.target.closest('task-card'); taskManager.deleteTask(parseInt(card.id)); } }); // Initialize the app const taskManager = new TaskManager();