taskmail-reminders / script.js
AnySue's picture
The user is unable to set a reminder and or delete the task. Please fix.
b9cb929 verified
// 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');
});
// Reminder modal
document.getElementById('closeReminderModal').addEventListener('click', () => {
document.getElementById('reminderModal').classList.add('hidden');
this.currentReminderTaskId = null;
});
document.getElementById('cancelReminder').addEventListener('click', () => {
document.getElementById('reminderModal').classList.add('hidden');
this.currentReminderTaskId = null;
});
document.getElementById('stopExistingReminder').addEventListener('click', () => {
if (this.currentReminderTaskId) {
const task = this.tasks.find(t => t.id === this.currentReminderTaskId);
if (task) {
task.hasReminder = false;
task.reminderStopped = true;
this.saveTasks();
this.renderTasks();
this.updateStats();
this.showToast('Reminder stopped', 'info');
}
}
document.getElementById('reminderModal').classList.add('hidden');
this.currentReminderTaskId = null;
});
// Frequency buttons
document.querySelectorAll('.frequency-btn').forEach(btn => {
btn.addEventListener('click', (e) => {
const frequency = e.currentTarget.dataset.frequency;
this.setReminderFrequency(frequency);
});
});
// Close modals on outside click
document.getElementById('emailModal').addEventListener('click', (e) => {
if (e.target.id === 'emailModal') {
document.getElementById('emailModal').classList.add('hidden');
}
});
document.getElementById('reminderModal').addEventListener('click', (e) => {
if (e.target.id === 'reminderModal') {
document.getElementById('reminderModal').classList.add('hidden');
this.currentReminderTaskId = null;
}
});
}
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;
}
this.currentReminderTaskId = id;
if (task.hasReminder && !task.reminderStopped) {
// Show stop reminder option
document.getElementById('reminderModal').classList.remove('hidden');
document.getElementById('stopExistingReminder').classList.remove('hidden');
document.querySelectorAll('.frequency-btn').forEach(btn => btn.style.display = 'none');
} else {
// Show frequency selection
document.getElementById('reminderModal').classList.remove('hidden');
document.getElementById('stopExistingReminder').classList.add('hidden');
document.querySelectorAll('.frequency-btn').forEach(btn => btn.style.display = 'block');
}
}
setReminderFrequency(frequency) {
if (!this.currentReminderTaskId) return;
const task = this.tasks.find(t => t.id === this.currentReminderTaskId);
if (task) {
task.hasReminder = true;
task.reminderStopped = false;
task.reminderFrequency = frequency;
const frequencyText = frequency === 'daily' ? 'daily' : frequency === 'weekly' ? 'weekly' : 'monthly';
this.showToast(`Reminder set! You'll receive ${frequencyText} email notifications`, 'success');
this.showEmailPreview(task);
this.saveTasks();
this.renderTasks();
this.updateStats();
}
document.getElementById('reminderModal').classList.add('hidden');
this.currentReminderTaskId = null;
}
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 => `
<task-card
id="${task.id}"
text="${this.escapeHtml(task.text)}"
email="${this.escapeHtml(task.email)}"
completed="${task.completed}"
has-reminder="${task.hasReminder}"
reminder-stopped="${task.reminderStopped}"
reminder-frequency="${task.reminderFrequency || ''}"
created-at="${task.createdAt}"
></task-card>
`).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() {
// Check for reminders every minute
setInterval(() => {
this.tasks.forEach(task => {
if (task.hasReminder && !task.reminderStopped && !task.completed) {
const now = new Date();
const lastReminder = task.lastReminder ? new Date(task.lastReminder) : null;
let shouldSend = false;
if (!lastReminder) {
// First reminder
shouldSend = true;
} else {
const timeDiff = now - lastReminder;
const daysDiff = timeDiff / (1000 * 60 * 60 * 24);
switch (task.reminderFrequency) {
case 'daily':
shouldSend = daysDiff >= 1;
break;
case 'weekly':
shouldSend = daysDiff >= 7;
break;
case 'monthly':
shouldSend = daysDiff >= 30;
break;
}
}
if (shouldSend) {
// In a real app, this would send an email
console.log(`Sending ${task.reminderFrequency} reminder for task: ${task.text} to ${task.email}`);
this.showToast(`Reminder: ${task.text}`, 'info');
task.lastReminder = now.toISOString();
this.saveTasks();
}
}
});
}, 60000); // Check every minute
}
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 = `
<i data-feather="${icon}" class="w-5 h-5"></i>
<span>${message}</span>
`;
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) => {
const toggleBtn = e.target.closest('[data-action="toggle"]');
const reminderBtn = e.target.closest('[data-action="reminder"]');
const deleteBtn = e.target.closest('[data-action="delete"]');
if (toggleBtn) {
const card = e.target.closest('task-card');
if (card) {
taskManager.toggleTask(parseInt(card.getAttribute('id'))));
} else if (reminderBtn) {
const card = e.target.closest('task-card');
if (card) {
taskManager.toggleReminder(parseInt(card.getAttribute('id'))));
} else if (deleteBtn) {
const card = e.target.closest('task-card');
if (card) {
taskManager.deleteTask(parseInt(card.getAttribute('id'))));
}
}
});
// Initialize the app
const taskManager = new TaskManager();