Spaces:
Running
Running
I don't know what the "Tasks Calendar Analytics" with the "Profile" buttons do. You can delete those. The "set reminder" circle at the bottom of the task doesn't do anything. I'm not sure what the square check box at the top of the task does.
Browse files- components/navbar.js +1 -18
- components/task-card.js +14 -12
- script.js +23 -10
components/navbar.js
CHANGED
|
@@ -57,24 +57,7 @@ class NavHeader extends HTMLElement {
|
|
| 57 |
<i data-feather="check-square" class="w-8 h-8 text-primary-500"></i>
|
| 58 |
<span class="logo">TaskMail</span>
|
| 59 |
</div>
|
| 60 |
-
|
| 61 |
-
<div class="hidden md:flex items-center gap-6">
|
| 62 |
-
<a href="#" class="nav-link text-gray-700 hover:text-primary-500 font-medium">
|
| 63 |
-
Tasks
|
| 64 |
-
</a>
|
| 65 |
-
<a href="#" class="nav-link text-gray-700 hover:text-primary-500 font-medium">
|
| 66 |
-
Calendar
|
| 67 |
-
</a>
|
| 68 |
-
<a href="#" class="nav-link text-gray-700 hover:text-primary-500 font-medium">
|
| 69 |
-
Analytics
|
| 70 |
-
</a>
|
| 71 |
-
<button class="bg-primary-500 text-white px-4 py-2 rounded-lg hover:bg-primary-600 transition-colors flex items-center gap-2">
|
| 72 |
-
<i data-feather="user" class="w-4 h-4"></i>
|
| 73 |
-
Profile
|
| 74 |
-
</button>
|
| 75 |
-
</div>
|
| 76 |
-
|
| 77 |
-
<button class="md:hidden" id="mobileMenuBtn">
|
| 78 |
<i data-feather="menu" class="w-6 h-6 text-gray-700"></i>
|
| 79 |
</button>
|
| 80 |
</div>
|
|
|
|
| 57 |
<i data-feather="check-square" class="w-8 h-8 text-primary-500"></i>
|
| 58 |
<span class="logo">TaskMail</span>
|
| 59 |
</div>
|
| 60 |
+
<button class="md:hidden" id="mobileMenuBtn">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
<i data-feather="menu" class="w-6 h-6 text-gray-700"></i>
|
| 62 |
</button>
|
| 63 |
</div>
|
components/task-card.js
CHANGED
|
@@ -43,7 +43,6 @@ class TaskCard extends HTMLElement {
|
|
| 43 |
text-decoration: line-through;
|
| 44 |
color: #9ca3af;
|
| 45 |
}
|
| 46 |
-
|
| 47 |
.task-checkbox {
|
| 48 |
width: 24px;
|
| 49 |
height: 24px;
|
|
@@ -52,6 +51,11 @@ class TaskCard extends HTMLElement {
|
|
| 52 |
border-radius: 6px;
|
| 53 |
position: relative;
|
| 54 |
transition: all 0.2s ease;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 55 |
}
|
| 56 |
|
| 57 |
.task-checkbox.checked {
|
|
@@ -60,18 +64,16 @@ class TaskCard extends HTMLElement {
|
|
| 60 |
}
|
| 61 |
|
| 62 |
.task-checkbox.checked::after {
|
| 63 |
-
content: '';
|
| 64 |
position: absolute;
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
.action-btn {
|
| 75 |
padding: 8px;
|
| 76 |
border-radius: 8px;
|
| 77 |
transition: all 0.2s ease;
|
|
|
|
| 43 |
text-decoration: line-through;
|
| 44 |
color: #9ca3af;
|
| 45 |
}
|
|
|
|
| 46 |
.task-checkbox {
|
| 47 |
width: 24px;
|
| 48 |
height: 24px;
|
|
|
|
| 51 |
border-radius: 6px;
|
| 52 |
position: relative;
|
| 53 |
transition: all 0.2s ease;
|
| 54 |
+
background-color: white;
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
.task-checkbox:hover {
|
| 58 |
+
border-color: #3b82f6;
|
| 59 |
}
|
| 60 |
|
| 61 |
.task-checkbox.checked {
|
|
|
|
| 64 |
}
|
| 65 |
|
| 66 |
.task-checkbox.checked::after {
|
| 67 |
+
content: 'β';
|
| 68 |
position: absolute;
|
| 69 |
+
top: 50%;
|
| 70 |
+
left: 50%;
|
| 71 |
+
transform: translate(-50%, -50%);
|
| 72 |
+
color: white;
|
| 73 |
+
font-weight: bold;
|
| 74 |
+
font-size: 14px;
|
| 75 |
+
}
|
| 76 |
+
.action-btn {
|
|
|
|
|
|
|
| 77 |
padding: 8px;
|
| 78 |
border-radius: 8px;
|
| 79 |
transition: all 0.2s ease;
|
script.js
CHANGED
|
@@ -78,35 +78,49 @@ class TaskManager {
|
|
| 78 |
|
| 79 |
this.showToast('Task added successfully!', 'success');
|
| 80 |
}
|
| 81 |
-
|
| 82 |
toggleTask(id) {
|
| 83 |
const task = this.tasks.find(t => t.id === id);
|
| 84 |
if (task) {
|
| 85 |
task.completed = !task.completed;
|
| 86 |
task.completedAt = task.completed ? new Date().toISOString() : null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
this.saveTasks();
|
| 88 |
this.renderTasks();
|
| 89 |
this.updateStats();
|
| 90 |
|
| 91 |
if (task.completed) {
|
| 92 |
this.showToast('Task completed! Great job! π', 'success');
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
}
|
| 94 |
}
|
| 95 |
}
|
| 96 |
-
|
| 97 |
toggleReminder(id) {
|
| 98 |
const task = this.tasks.find(t => t.id === id);
|
| 99 |
if (task) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 100 |
if (task.hasReminder && !task.reminderStopped) {
|
| 101 |
// Stop reminder
|
| 102 |
task.hasReminder = false;
|
| 103 |
task.reminderStopped = true;
|
| 104 |
this.showToast('Reminder stopped', 'info');
|
| 105 |
-
} else
|
| 106 |
// Start reminder
|
| 107 |
task.hasReminder = true;
|
| 108 |
task.reminderStopped = false;
|
| 109 |
-
this.showToast('Reminder started! You\'ll receive email notifications', 'success');
|
| 110 |
this.showEmailPreview(task);
|
| 111 |
}
|
| 112 |
this.saveTasks();
|
|
@@ -114,8 +128,7 @@ class TaskManager {
|
|
| 114 |
this.updateStats();
|
| 115 |
}
|
| 116 |
}
|
| 117 |
-
|
| 118 |
-
deleteTask(id) {
|
| 119 |
if (confirm('Are you sure you want to delete this task?')) {
|
| 120 |
this.tasks = this.tasks.filter(t => t.id !== id);
|
| 121 |
this.saveTasks();
|
|
@@ -199,7 +212,6 @@ class TaskManager {
|
|
| 199 |
document.getElementById('emailTask').textContent = task.text;
|
| 200 |
document.getElementById('emailModal').classList.remove('hidden');
|
| 201 |
}
|
| 202 |
-
|
| 203 |
startReminderScheduler() {
|
| 204 |
// Simulate sending reminders every 30 seconds for demo
|
| 205 |
setInterval(() => {
|
|
@@ -207,12 +219,13 @@ class TaskManager {
|
|
| 207 |
if (task.hasReminder && !task.reminderStopped && !task.completed) {
|
| 208 |
// In a real app, this would send an email
|
| 209 |
console.log(`Sending reminder for task: ${task.text} to ${task.email}`);
|
|
|
|
|
|
|
| 210 |
}
|
| 211 |
});
|
| 212 |
-
}, 30000);
|
| 213 |
}
|
| 214 |
-
|
| 215 |
-
showToast(message, type = 'info') {
|
| 216 |
const toast = document.createElement('div');
|
| 217 |
const bgColor = type === 'success' ? 'bg-green-500' : type === 'error' ? 'bg-red-500' : 'bg-blue-500';
|
| 218 |
|
|
|
|
| 78 |
|
| 79 |
this.showToast('Task added successfully!', 'success');
|
| 80 |
}
|
|
|
|
| 81 |
toggleTask(id) {
|
| 82 |
const task = this.tasks.find(t => t.id === id);
|
| 83 |
if (task) {
|
| 84 |
task.completed = !task.completed;
|
| 85 |
task.completedAt = task.completed ? new Date().toISOString() : null;
|
| 86 |
+
|
| 87 |
+
// When task is completed, automatically stop reminders
|
| 88 |
+
if (task.completed) {
|
| 89 |
+
task.hasReminder = false;
|
| 90 |
+
task.reminderStopped = true;
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
this.saveTasks();
|
| 94 |
this.renderTasks();
|
| 95 |
this.updateStats();
|
| 96 |
|
| 97 |
if (task.completed) {
|
| 98 |
this.showToast('Task completed! Great job! π', 'success');
|
| 99 |
+
} else {
|
| 100 |
+
// If unchecking a completed task, reset reminder status
|
| 101 |
+
task.reminderStopped = false;
|
| 102 |
+
this.showToast('Task marked as incomplete', 'info');
|
| 103 |
}
|
| 104 |
}
|
| 105 |
}
|
|
|
|
| 106 |
toggleReminder(id) {
|
| 107 |
const task = this.tasks.find(t => t.id === id);
|
| 108 |
if (task) {
|
| 109 |
+
if (task.completed) {
|
| 110 |
+
this.showToast('Cannot set reminder for completed task', 'error');
|
| 111 |
+
return;
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
if (task.hasReminder && !task.reminderStopped) {
|
| 115 |
// Stop reminder
|
| 116 |
task.hasReminder = false;
|
| 117 |
task.reminderStopped = true;
|
| 118 |
this.showToast('Reminder stopped', 'info');
|
| 119 |
+
} else {
|
| 120 |
// Start reminder
|
| 121 |
task.hasReminder = true;
|
| 122 |
task.reminderStopped = false;
|
| 123 |
+
this.showToast('Reminder started! You\'ll receive email notifications every 30 seconds', 'success');
|
| 124 |
this.showEmailPreview(task);
|
| 125 |
}
|
| 126 |
this.saveTasks();
|
|
|
|
| 128 |
this.updateStats();
|
| 129 |
}
|
| 130 |
}
|
| 131 |
+
deleteTask(id) {
|
|
|
|
| 132 |
if (confirm('Are you sure you want to delete this task?')) {
|
| 133 |
this.tasks = this.tasks.filter(t => t.id !== id);
|
| 134 |
this.saveTasks();
|
|
|
|
| 212 |
document.getElementById('emailTask').textContent = task.text;
|
| 213 |
document.getElementById('emailModal').classList.remove('hidden');
|
| 214 |
}
|
|
|
|
| 215 |
startReminderScheduler() {
|
| 216 |
// Simulate sending reminders every 30 seconds for demo
|
| 217 |
setInterval(() => {
|
|
|
|
| 219 |
if (task.hasReminder && !task.reminderStopped && !task.completed) {
|
| 220 |
// In a real app, this would send an email
|
| 221 |
console.log(`Sending reminder for task: ${task.text} to ${task.email}`);
|
| 222 |
+
// Show a notification in the browser for demo purposes
|
| 223 |
+
this.showToast(`Reminder: ${task.text}`, 'info');
|
| 224 |
}
|
| 225 |
});
|
| 226 |
+
}, 30000); // 30 seconds
|
| 227 |
}
|
| 228 |
+
showToast(message, type = 'info') {
|
|
|
|
| 229 |
const toast = document.createElement('div');
|
| 230 |
const bgColor = type === 'success' ? 'bg-green-500' : type === 'error' ? 'bg-red-500' : 'bg-blue-500';
|
| 231 |
|