AnySue commited on
Commit
8c453b0
·
verified ·
1 Parent(s): 1c52982

When the "set reminder" at the bottom of the task is clicked it should produce something that the user can say yes or no and if yes the user should be able to click daily, weekly, monthly until the task is complete or deleted.

Browse files
Files changed (3) hide show
  1. components/task-card.js +4 -6
  2. index.html +58 -2
  3. script.js +109 -20
components/task-card.js CHANGED
@@ -8,12 +8,12 @@ class TaskCard extends HTMLElement {
8
  const completed = this.getAttribute('completed') === 'true';
9
  const hasReminder = this.getAttribute('has-reminder') === 'true';
10
  const reminderStopped = this.getAttribute('reminder-stopped') === 'true';
 
11
  const createdAt = this.getAttribute('created-at');
12
 
13
  const createdDate = new Date(createdAt).toLocaleDateString();
14
  const timeAgo = this.getTimeAgo(createdAt);
15
-
16
- this.shadowRoot.innerHTML = `
17
  <style>
18
  .task-card {
19
  background: white;
@@ -156,16 +156,14 @@ class TaskCard extends HTMLElement {
156
  <span>${timeAgo}</span>
157
  </div>
158
  </div>
159
-
160
  <div class="flex items-center justify-between">
161
  <div class="flex gap-2">
162
  ${hasReminder && !reminderStopped ?
163
- '<span class="badge badge-reminder">Active Reminder</span>' : ''}
164
  ${reminderStopped ?
165
  '<span class="badge badge-stopped">Reminder Stopped</span>' : ''}
166
  </div>
167
-
168
- <div class="flex items-center gap-1">
169
  ${!completed ? `
170
  <button class="action-btn reminder-btn ${hasReminder && !reminderStopped ? 'active' : ''}"
171
  data-action="reminder"
 
8
  const completed = this.getAttribute('completed') === 'true';
9
  const hasReminder = this.getAttribute('has-reminder') === 'true';
10
  const reminderStopped = this.getAttribute('reminder-stopped') === 'true';
11
+ const reminderFrequency = this.getAttribute('reminder-frequency');
12
  const createdAt = this.getAttribute('created-at');
13
 
14
  const createdDate = new Date(createdAt).toLocaleDateString();
15
  const timeAgo = this.getTimeAgo(createdAt);
16
+ this.shadowRoot.innerHTML = `
 
17
  <style>
18
  .task-card {
19
  background: white;
 
156
  <span>${timeAgo}</span>
157
  </div>
158
  </div>
 
159
  <div class="flex items-center justify-between">
160
  <div class="flex gap-2">
161
  ${hasReminder && !reminderStopped ?
162
+ `<span class="badge badge-reminder">Active (${reminderFrequency || 'daily'})</span>` : ''}
163
  ${reminderStopped ?
164
  '<span class="badge badge-stopped">Reminder Stopped</span>' : ''}
165
  </div>
166
+ <div class="flex items-center gap-1">
 
167
  ${!completed ? `
168
  <button class="action-btn reminder-btn ${hasReminder && !reminderStopped ? 'active' : ''}"
169
  data-action="reminder"
index.html CHANGED
@@ -160,7 +160,6 @@
160
  <p class="text-gray-500">Add your first task to get started!</p>
161
  </div>
162
  </main>
163
-
164
  <!-- Email Preview Modal -->
165
  <div id="emailModal" class="fixed inset-0 bg-black bg-opacity-50 hidden z-50 flex items-center justify-center p-4">
166
  <div class="bg-white rounded-2xl max-w-2xl w-full max-h-[90vh] overflow-auto">
@@ -198,7 +197,64 @@
198
  </div>
199
  </div>
200
 
201
- <!-- Components -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
  <script src="components/navbar.js"></script>
203
  <script src="components/task-card.js"></script>
204
 
 
160
  <p class="text-gray-500">Add your first task to get started!</p>
161
  </div>
162
  </main>
 
163
  <!-- Email Preview Modal -->
164
  <div id="emailModal" class="fixed inset-0 bg-black bg-opacity-50 hidden z-50 flex items-center justify-center p-4">
165
  <div class="bg-white rounded-2xl max-w-2xl w-full max-h-[90vh] overflow-auto">
 
197
  </div>
198
  </div>
199
 
200
+ <!-- Reminder Frequency Modal -->
201
+ <div id="reminderModal" class="fixed inset-0 bg-black bg-opacity-50 hidden z-50 flex items-center justify-center p-4">
202
+ <div class="bg-white rounded-2xl max-w-md w-full">
203
+ <div class="p-6 border-b border-gray-200">
204
+ <div class="flex justify-between items-center">
205
+ <h3 class="text-xl font-bold text-gray-800">Set Reminder Frequency</h3>
206
+ <button id="closeReminderModal" class="text-gray-500 hover:text-gray-700">
207
+ <i data-feather="x" class="w-6 h-6"></i>
208
+ </button>
209
+ </div>
210
+ </div>
211
+ <div class="p-6">
212
+ <p class="text-gray-600 mb-6">How often would you like to receive email reminders for this task?</p>
213
+
214
+ <div class="space-y-3 mb-6">
215
+ <button class="frequency-btn w-full text-left px-4 py-3 border-2 border-gray-200 rounded-lg hover:border-primary-500 hover:bg-primary-50 transition-all" data-frequency="daily">
216
+ <div class="flex items-center justify-between">
217
+ <div>
218
+ <p class="font-semibold text-gray-800">📅 Daily</p>
219
+ <p class="text-sm text-gray-500">Receive reminders every day</p>
220
+ </div>
221
+ <i data-feather="chevron-right" class="w-5 h-5 text-gray-400"></i>
222
+ </div>
223
+ </button>
224
+
225
+ <button class="frequency-btn w-full text-left px-4 py-3 border-2 border-gray-200 rounded-lg hover:border-primary-500 hover:bg-primary-50 transition-all" data-frequency="weekly">
226
+ <div class="flex items-center justify-between">
227
+ <div>
228
+ <p class="font-semibold text-gray-800">📆 Weekly</p>
229
+ <p class="text-sm text-gray-500">Receive reminders every week</p>
230
+ </div>
231
+ <i data-feather="chevron-right" class="w-5 h-5 text-gray-400"></i>
232
+ </div>
233
+ </button>
234
+
235
+ <button class="frequency-btn w-full text-left px-4 py-3 border-2 border-gray-200 rounded-lg hover:border-primary-500 hover:bg-primary-50 transition-all" data-frequency="monthly">
236
+ <div class="flex items-center justify-between">
237
+ <div>
238
+ <p class="font-semibold text-gray-800">🗓️ Monthly</p>
239
+ <p class="text-sm text-gray-500">Receive reminders every month</p>
240
+ </div>
241
+ <i data-feather="chevron-right" class="w-5 h-5 text-gray-400"></i>
242
+ </div>
243
+ </button>
244
+ </div>
245
+
246
+ <div class="flex gap-3">
247
+ <button id="cancelReminder" class="flex-1 px-4 py-2 bg-gray-200 text-gray-700 rounded-lg hover:bg-gray-300 transition-colors">
248
+ Cancel
249
+ </button>
250
+ <button id="stopExistingReminder" class="flex-1 px-4 py-2 bg-red-500 text-white rounded-lg hover:bg-red-600 transition-colors hidden">
251
+ Stop Reminder
252
+ </button>
253
+ </div>
254
+ </div>
255
+ </div>
256
+ </div>
257
+ <!-- Components -->
258
  <script src="components/navbar.js"></script>
259
  <script src="components/task-card.js"></script>
260
 
script.js CHANGED
@@ -12,7 +12,6 @@ class TaskManager {
12
  this.updateStats();
13
  this.startReminderScheduler();
14
  }
15
-
16
  setupEventListeners() {
17
  // Add task
18
  document.getElementById('addTaskBtn').addEventListener('click', () => this.addTask());
@@ -32,15 +31,56 @@ class TaskManager {
32
  document.getElementById('emailModal').classList.add('hidden');
33
  });
34
 
35
- // Close modal on outside click
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  document.getElementById('emailModal').addEventListener('click', (e) => {
37
  if (e.target.id === 'emailModal') {
38
  document.getElementById('emailModal').classList.add('hidden');
39
  }
40
  });
41
- }
42
 
43
- addTask() {
 
 
 
 
 
 
 
44
  const taskInput = document.getElementById('taskInput');
45
  const emailInput = document.getElementById('emailInput');
46
  const taskText = taskInput.value.trim();
@@ -111,22 +151,42 @@ class TaskManager {
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();
127
  this.renderTasks();
128
  this.updateStats();
129
  }
 
 
 
130
  }
131
  deleteTask(id) {
132
  if (confirm('Are you sure you want to delete this task?')) {
@@ -186,9 +246,10 @@ deleteTask(id) {
186
  completed="${task.completed}"
187
  has-reminder="${task.hasReminder}"
188
  reminder-stopped="${task.reminderStopped}"
 
189
  created-at="${task.createdAt}"
190
  ></task-card>
191
- `).join('');
192
 
193
  // Re-initialize feather icons for new elements
194
  feather.replace();
@@ -213,17 +274,45 @@ deleteTask(id) {
213
  document.getElementById('emailModal').classList.remove('hidden');
214
  }
215
  startReminderScheduler() {
216
- // Simulate sending reminders every 30 seconds for demo
217
  setInterval(() => {
218
  this.tasks.forEach(task => {
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');
 
12
  this.updateStats();
13
  this.startReminderScheduler();
14
  }
 
15
  setupEventListeners() {
16
  // Add task
17
  document.getElementById('addTaskBtn').addEventListener('click', () => this.addTask());
 
31
  document.getElementById('emailModal').classList.add('hidden');
32
  });
33
 
34
+ // Reminder modal
35
+ document.getElementById('closeReminderModal').addEventListener('click', () => {
36
+ document.getElementById('reminderModal').classList.add('hidden');
37
+ this.currentReminderTaskId = null;
38
+ });
39
+
40
+ document.getElementById('cancelReminder').addEventListener('click', () => {
41
+ document.getElementById('reminderModal').classList.add('hidden');
42
+ this.currentReminderTaskId = null;
43
+ });
44
+
45
+ document.getElementById('stopExistingReminder').addEventListener('click', () => {
46
+ if (this.currentReminderTaskId) {
47
+ const task = this.tasks.find(t => t.id === this.currentReminderTaskId);
48
+ if (task) {
49
+ task.hasReminder = false;
50
+ task.reminderStopped = true;
51
+ this.saveTasks();
52
+ this.renderTasks();
53
+ this.updateStats();
54
+ this.showToast('Reminder stopped', 'info');
55
+ }
56
+ }
57
+ document.getElementById('reminderModal').classList.add('hidden');
58
+ this.currentReminderTaskId = null;
59
+ });
60
+
61
+ // Frequency buttons
62
+ document.querySelectorAll('.frequency-btn').forEach(btn => {
63
+ btn.addEventListener('click', (e) => {
64
+ const frequency = e.currentTarget.dataset.frequency;
65
+ this.setReminderFrequency(frequency);
66
+ });
67
+ });
68
+
69
+ // Close modals on outside click
70
  document.getElementById('emailModal').addEventListener('click', (e) => {
71
  if (e.target.id === 'emailModal') {
72
  document.getElementById('emailModal').classList.add('hidden');
73
  }
74
  });
 
75
 
76
+ document.getElementById('reminderModal').addEventListener('click', (e) => {
77
+ if (e.target.id === 'reminderModal') {
78
+ document.getElementById('reminderModal').classList.add('hidden');
79
+ this.currentReminderTaskId = null;
80
+ }
81
+ });
82
+ }
83
+ addTask() {
84
  const taskInput = document.getElementById('taskInput');
85
  const emailInput = document.getElementById('emailInput');
86
  const taskText = taskInput.value.trim();
 
151
  return;
152
  }
153
 
154
+ this.currentReminderTaskId = id;
155
+
156
  if (task.hasReminder && !task.reminderStopped) {
157
+ // Show stop reminder option
158
+ document.getElementById('reminderModal').classList.remove('hidden');
159
+ document.getElementById('stopExistingReminder').classList.remove('hidden');
160
+ document.querySelectorAll('.frequency-btn').forEach(btn => btn.style.display = 'none');
161
  } else {
162
+ // Show frequency selection
163
+ document.getElementById('reminderModal').classList.remove('hidden');
164
+ document.getElementById('stopExistingReminder').classList.add('hidden');
165
+ document.querySelectorAll('.frequency-btn').forEach(btn => btn.style.display = 'block');
 
166
  }
167
+ }
168
+ }
169
+
170
+ setReminderFrequency(frequency) {
171
+ if (!this.currentReminderTaskId) return;
172
+
173
+ const task = this.tasks.find(t => t.id === this.currentReminderTaskId);
174
+ if (task) {
175
+ task.hasReminder = true;
176
+ task.reminderStopped = false;
177
+ task.reminderFrequency = frequency;
178
+
179
+ const frequencyText = frequency === 'daily' ? 'daily' : frequency === 'weekly' ? 'weekly' : 'monthly';
180
+ this.showToast(`Reminder set! You'll receive ${frequencyText} email notifications`, 'success');
181
+
182
+ this.showEmailPreview(task);
183
  this.saveTasks();
184
  this.renderTasks();
185
  this.updateStats();
186
  }
187
+
188
+ document.getElementById('reminderModal').classList.add('hidden');
189
+ this.currentReminderTaskId = null;
190
  }
191
  deleteTask(id) {
192
  if (confirm('Are you sure you want to delete this task?')) {
 
246
  completed="${task.completed}"
247
  has-reminder="${task.hasReminder}"
248
  reminder-stopped="${task.reminderStopped}"
249
+ reminder-frequency="${task.reminderFrequency || ''}"
250
  created-at="${task.createdAt}"
251
  ></task-card>
252
+ `).join('');
253
 
254
  // Re-initialize feather icons for new elements
255
  feather.replace();
 
274
  document.getElementById('emailModal').classList.remove('hidden');
275
  }
276
  startReminderScheduler() {
277
+ // Check for reminders every minute
278
  setInterval(() => {
279
  this.tasks.forEach(task => {
280
  if (task.hasReminder && !task.reminderStopped && !task.completed) {
281
+ const now = new Date();
282
+ const lastReminder = task.lastReminder ? new Date(task.lastReminder) : null;
283
+
284
+ let shouldSend = false;
285
+
286
+ if (!lastReminder) {
287
+ // First reminder
288
+ shouldSend = true;
289
+ } else {
290
+ const timeDiff = now - lastReminder;
291
+ const daysDiff = timeDiff / (1000 * 60 * 60 * 24);
292
+
293
+ switch (task.reminderFrequency) {
294
+ case 'daily':
295
+ shouldSend = daysDiff >= 1;
296
+ break;
297
+ case 'weekly':
298
+ shouldSend = daysDiff >= 7;
299
+ break;
300
+ case 'monthly':
301
+ shouldSend = daysDiff >= 30;
302
+ break;
303
+ }
304
+ }
305
+
306
+ if (shouldSend) {
307
+ // In a real app, this would send an email
308
+ console.log(`Sending ${task.reminderFrequency} reminder for task: ${task.text} to ${task.email}`);
309
+ this.showToast(`Reminder: ${task.text}`, 'info');
310
+ task.lastReminder = now.toISOString();
311
+ this.saveTasks();
312
+ }
313
  }
314
  });
315
+ }, 60000); // Check every minute
316
  }
317
  showToast(message, type = 'info') {
318
  const toast = document.createElement('div');