jayedgar commited on
Commit
e4555de
·
verified ·
1 Parent(s): 471d979

Add 2 files

Browse files
Files changed (2) hide show
  1. index.html +179 -213
  2. prompts.txt +2 -1
index.html CHANGED
@@ -3,27 +3,43 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>TaskMaster - To-Do List App</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
  <style>
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  /* Custom scrollbar */
11
- .task-list::-webkit-scrollbar {
12
  width: 8px;
13
  }
14
- .task-list::-webkit-scrollbar-track {
15
- background: #f1f1f1;
 
16
  border-radius: 10px;
17
  }
18
- .task-list::-webkit-scrollbar-thumb {
19
- background: #888;
 
20
  border-radius: 10px;
21
  }
22
- .task-list::-webkit-scrollbar-thumb:hover {
23
- background: #555;
 
24
  }
25
 
26
- /* Animation for task items */
27
  @keyframes fadeIn {
28
  from { opacity: 0; transform: translateY(10px); }
29
  to { opacity: 1; transform: translateY(0); }
@@ -33,120 +49,117 @@
33
  animation: fadeIn 0.3s ease-out forwards;
34
  }
35
 
36
- /* Checkbox styling */
37
  .custom-checkbox {
38
  appearance: none;
39
  -webkit-appearance: none;
40
  width: 22px;
41
  height: 22px;
42
- border: 2px solid #4f46e5;
43
- border-radius: 4px;
44
  cursor: pointer;
45
  position: relative;
46
  transition: all 0.2s;
47
  }
48
 
49
  .custom-checkbox:checked {
50
- background-color: #4f46e5;
 
51
  }
52
 
53
  .custom-checkbox:checked::after {
54
- content: '\2713';
55
  position: absolute;
56
  color: white;
57
  font-size: 14px;
58
  left: 4px;
59
- top: 1px;
60
- }
61
-
62
- /* Empty state styling */
63
- .empty-state {
64
- opacity: 0.6;
65
- transition: all 0.3s;
66
- }
67
-
68
- .empty-state:hover {
69
- opacity: 1;
70
- transform: scale(1.02);
71
  }
72
  </style>
73
  </head>
74
- <body class="bg-gradient-to-br from-indigo-50 to-purple-50 min-h-screen">
75
  <div class="container mx-auto px-4 py-8 max-w-3xl">
76
  <!-- Header -->
77
  <header class="mb-8 text-center">
78
- <h1 class="text-4xl font-bold text-indigo-800 mb-2">TaskMaster</h1>
79
- <p class="text-indigo-600">Organize your day, one task at a time</p>
 
 
 
80
  </header>
81
 
82
- <!-- Main Content -->
83
- <main class="bg-white rounded-xl shadow-lg overflow-hidden">
84
  <!-- Input Section -->
85
- <div class="p-6 border-b border-gray-200">
86
- <div class="flex gap-2">
87
  <input
88
  type="text"
89
  id="taskInput"
90
- placeholder="What needs to be done?"
91
- class="flex-1 px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
92
- autocomplete="off"
93
  >
94
  <button
95
  id="addTaskBtn"
96
- class="bg-indigo-600 hover:bg-indigo-700 text-white px-6 py-3 rounded-lg font-medium transition-colors duration-200 flex items-center gap-2"
97
  >
98
- <i class="fas fa-plus"></i> Add
99
  </button>
100
  </div>
101
-
102
- <div class="flex justify-between mt-4">
103
- <div class="flex items-center gap-2">
104
- <span class="text-sm text-gray-600">Filter:</span>
105
- <select id="filterSelect" class="border border-gray-300 rounded px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-indigo-500">
106
- <option value="all">All Tasks</option>
107
- <option value="active">Active</option>
108
- <option value="completed">Completed</option>
109
- </select>
110
- </div>
 
 
 
 
 
 
 
 
 
 
111
  <button
112
- id="clearCompletedBtn"
113
- class="text-sm text-indigo-600 hover:text-indigo-800 transition-colors duration-200"
114
  >
115
- Clear Completed
116
  </button>
117
  </div>
118
  </div>
119
 
120
- <!-- Task List -->
121
- <div class="task-list max-h-96 overflow-y-auto p-4">
122
- <div id="tasksContainer">
123
- <!-- Tasks will be added here dynamically -->
124
- </div>
125
-
126
- <!-- Empty State -->
127
- <div id="emptyState" class="empty-state text-center py-12">
128
- <i class="fas fa-tasks text-6xl text-gray-300 mb-4"></i>
129
- <h3 class="text-xl text-gray-500 font-medium">No tasks yet</h3>
130
- <p class="text-gray-400 mt-1">Add your first task to get started!</p>
131
  </div>
132
  </div>
133
 
134
- <!-- Stats Footer -->
135
- <div class="bg-gray-50 px-6 py-3 border-t border-gray-200 flex justify-between items-center">
136
- <span id="taskCount" class="text-sm text-gray-600">0 tasks</span>
137
  <button
138
- id="saveTasksBtn"
139
- class="text-sm bg-green-600 hover:bg-green-700 text-white px-4 py-1 rounded transition-colors duration-200 flex items-center gap-1"
140
  >
141
- <i class="fas fa-save"></i> Save
 
 
 
 
 
 
142
  </button>
143
  </div>
144
- </main>
145
-
146
- <!-- Footer -->
147
- <footer class="mt-8 text-center text-gray-500 text-sm">
148
- <p>Tasks are saved in your browser's local storage</p>
149
- </footer>
150
  </div>
151
 
152
  <script>
@@ -156,94 +169,91 @@
156
  const addTaskBtn = document.getElementById('addTaskBtn');
157
  const tasksContainer = document.getElementById('tasksContainer');
158
  const emptyState = document.getElementById('emptyState');
159
- const filterSelect = document.getElementById('filterSelect');
160
- const clearCompletedBtn = document.getElementById('clearCompletedBtn');
161
- const saveTasksBtn = document.getElementById('saveTasksBtn');
162
  const taskCount = document.getElementById('taskCount');
 
 
 
163
 
 
164
  let tasks = [];
 
165
 
166
- // Load tasks from localStorage
167
- function loadTasks() {
168
- const savedTasks = localStorage.getItem('tasks');
169
- if (savedTasks) {
170
- tasks = JSON.parse(savedTasks);
 
 
 
 
 
 
 
 
 
 
171
  renderTasks();
172
- }
173
- updateEmptyState();
174
- updateTaskCount();
175
- }
176
 
177
- // Save tasks to localStorage
178
- function saveTasks() {
179
- localStorage.setItem('tasks', JSON.stringify(tasks));
180
- showNotification('Tasks saved successfully!', 'success');
181
- }
182
 
183
- // Add new task
184
  function addTask() {
185
- const taskText = taskInput.value.trim();
186
- if (taskText === '') {
187
- showNotification('Please enter a task', 'error');
188
- return;
189
- }
190
 
191
  const newTask = {
192
  id: Date.now(),
193
- text: taskText,
194
  completed: false,
195
- createdAt: new Date().toISOString()
196
  };
197
 
198
  tasks.unshift(newTask);
199
  taskInput.value = '';
200
  renderTasks();
201
- updateEmptyState();
202
  updateTaskCount();
 
203
  saveTasks();
204
  }
205
 
206
- // Render tasks based on filter
207
  function renderTasks() {
208
  tasksContainer.innerHTML = '';
209
 
210
- const filter = filterSelect.value;
211
- let filteredTasks = tasks;
212
-
213
- if (filter === 'active') {
214
- filteredTasks = tasks.filter(task => !task.completed);
215
- } else if (filter === 'completed') {
216
- filteredTasks = tasks.filter(task => task.completed);
217
- }
218
 
219
  if (filteredTasks.length === 0) {
220
  updateEmptyState();
221
  return;
222
  }
223
 
 
 
224
  filteredTasks.forEach(task => {
225
  const taskElement = document.createElement('div');
226
- taskElement.className = `task-item bg-white mb-2 p-3 rounded-lg border border-gray-200 hover:border-indigo-300 transition-colors duration-200 flex items-center justify-between ${task.completed ? 'opacity-70' : ''}`;
227
 
228
  taskElement.innerHTML = `
229
- <div class="flex items-center gap-3">
230
  <input
231
  type="checkbox"
232
- class="custom-checkbox"
233
  ${task.completed ? 'checked' : ''}
234
  data-id="${task.id}"
235
  >
236
- <span class="${task.completed ? 'line-through text-gray-500' : 'text-gray-800'}">${task.text}</span>
237
- </div>
238
- <div class="flex items-center gap-2">
239
- <span class="text-xs text-gray-400">${formatDate(task.createdAt)}</span>
240
- <button
241
- class="delete-btn text-red-500 hover:text-red-700 p-1 rounded-full transition-colors duration-200"
242
- data-id="${task.id}"
243
- >
244
- <i class="fas fa-trash-alt"></i>
245
- </button>
246
  </div>
 
 
 
247
  `;
248
 
249
  tasksContainer.appendChild(taskElement);
@@ -251,7 +261,7 @@
251
 
252
  // Add event listeners to new elements
253
  document.querySelectorAll('.custom-checkbox').forEach(checkbox => {
254
- checkbox.addEventListener('change', toggleTaskStatus);
255
  });
256
 
257
  document.querySelectorAll('.delete-btn').forEach(btn => {
@@ -259,10 +269,9 @@
259
  });
260
  }
261
 
262
- // Toggle task completed status
263
- function toggleTaskStatus(e) {
264
  const taskId = parseInt(e.target.dataset.id);
265
- const task = tasks.find(task => task.id === taskId);
266
 
267
  if (task) {
268
  task.completed = e.target.checked;
@@ -272,124 +281,81 @@
272
  }
273
  }
274
 
275
- // Delete task
276
  function deleteTask(e) {
277
  const taskId = parseInt(e.currentTarget.dataset.id);
278
  tasks = tasks.filter(task => task.id !== taskId);
 
279
  renderTasks();
280
- updateEmptyState();
281
  updateTaskCount();
 
282
  saveTasks();
283
  }
284
 
285
- // Clear completed tasks
286
- function clearCompleted() {
287
  tasks = tasks.filter(task => !task.completed);
 
288
  renderTasks();
289
- updateEmptyState();
290
  updateTaskCount();
 
291
  saveTasks();
292
  }
293
 
294
- // Update empty state visibility
295
- function updateEmptyState() {
296
- const filter = filterSelect.value;
297
- let hasTasks = false;
298
-
299
- if (filter === 'all') {
300
- hasTasks = tasks.length > 0;
301
- } else if (filter === 'active') {
302
- hasTasks = tasks.some(task => !task.completed);
303
- } else if (filter === 'completed') {
304
- hasTasks = tasks.some(task => task.completed);
305
- }
306
-
307
- emptyState.style.display = hasTasks ? 'none' : 'block';
308
- }
309
-
310
- // Update task count
311
  function updateTaskCount() {
 
312
  const totalTasks = tasks.length;
313
- const completedTasks = tasks.filter(task => task.completed).length;
314
- const activeTasks = totalTasks - completedTasks;
315
 
316
- let countText = '';
 
 
 
 
 
 
 
 
317
 
318
- if (filterSelect.value === 'all') {
319
- countText = `${totalTasks} ${totalTasks === 1 ? 'task' : 'tasks'} (${activeTasks} active, ${completedTasks} completed)`;
320
- } else if (filterSelect.value === 'active') {
321
- countText = `${activeTasks} ${activeTasks === 1 ? 'task' : 'tasks'} remaining`;
322
  } else {
323
- countText = `${completedTasks} ${completedTasks === 1 ? 'task' : 'tasks'} completed`;
324
  }
325
-
326
- taskCount.textContent = countText;
327
  }
328
 
329
- // Format date for display
330
- function formatDate(dateString) {
331
- const date = new Date(dateString);
332
- return date.toLocaleDateString('en-US', {
333
- month: 'short',
334
- day: 'numeric',
335
- hour: '2-digit',
336
- minute: '2-digit'
 
337
  });
338
  }
339
 
340
- // Show notification
341
- function showNotification(message, type) {
342
- const notification = document.createElement('div');
343
- notification.className = `fixed top-4 right-4 px-4 py-2 rounded-lg shadow-lg text-white ${
344
- type === 'success' ? 'bg-green-500' : 'bg-red-500'
345
- } animate-fade-in-out`;
346
- notification.textContent = message;
347
 
348
- document.body.appendChild(notification);
 
 
 
 
349
 
350
  setTimeout(() => {
351
- notification.classList.add('opacity-0', 'transition-opacity', 'duration-300');
352
- setTimeout(() => {
353
- notification.remove();
354
- }, 300);
355
- }, 3000);
356
  }
357
 
358
- // Event Listeners
359
- addTaskBtn.addEventListener('click', addTask);
360
- taskInput.addEventListener('keypress', function(e) {
361
- if (e.key === 'Enter') {
362
- addTask();
363
- }
364
- });
365
-
366
- filterSelect.addEventListener('change', function() {
367
- renderTasks();
368
- updateEmptyState();
369
- updateTaskCount();
370
- });
371
-
372
- clearCompletedBtn.addEventListener('click', clearCompleted);
373
- saveTasksBtn.addEventListener('click', saveTasks);
374
-
375
- // Initialize
376
- loadTasks();
377
-
378
- // Add animation styles dynamically
379
- const style = document.createElement('style');
380
- style.textContent = `
381
- @keyframes fade-in-out {
382
- 0% { opacity: 0; transform: translateY(-10px); }
383
- 10% { opacity: 1; transform: translateY(0); }
384
- 90% { opacity: 1; transform: translateY(0); }
385
- 100% { opacity: 0; transform: translateY(-10px); }
386
- }
387
-
388
- .animate-fade-in-out {
389
- animation: fade-in-out 3s ease forwards;
390
  }
391
- `;
392
- document.head.appendChild(style);
393
  });
394
  </script>
395
  <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=jayedgar/generative-waves" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Nebula Tasks | Modern To-Do App</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
  <style>
10
+ /* Custom gradient animation */
11
+ @keyframes gradientBG {
12
+ 0% { background-position: 0% 50%; }
13
+ 50% { background-position: 100% 50%; }
14
+ 100% { background-position: 0% 50%; }
15
+ }
16
+
17
+ .gradient-bg {
18
+ background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
19
+ background-size: 400% 400%;
20
+ animation: gradientBG 15s ease infinite;
21
+ }
22
+
23
  /* Custom scrollbar */
24
+ ::-webkit-scrollbar {
25
  width: 8px;
26
  }
27
+
28
+ ::-webkit-scrollbar-track {
29
+ background: rgba(255, 255, 255, 0.1);
30
  border-radius: 10px;
31
  }
32
+
33
+ ::-webkit-scrollbar-thumb {
34
+ background: rgba(255, 255, 255, 0.3);
35
  border-radius: 10px;
36
  }
37
+
38
+ ::-webkit-scrollbar-thumb:hover {
39
+ background: rgba(255, 255, 255, 0.5);
40
  }
41
 
42
+ /* Task item animation */
43
  @keyframes fadeIn {
44
  from { opacity: 0; transform: translateY(10px); }
45
  to { opacity: 1; transform: translateY(0); }
 
49
  animation: fadeIn 0.3s ease-out forwards;
50
  }
51
 
52
+ /* Checkbox style */
53
  .custom-checkbox {
54
  appearance: none;
55
  -webkit-appearance: none;
56
  width: 22px;
57
  height: 22px;
58
+ border: 2px solid rgba(255, 255, 255, 0.7);
59
+ border-radius: 6px;
60
  cursor: pointer;
61
  position: relative;
62
  transition: all 0.2s;
63
  }
64
 
65
  .custom-checkbox:checked {
66
+ background-color: rgba(255, 255, 255, 0.3);
67
+ border-color: rgba(255, 255, 255, 0.7);
68
  }
69
 
70
  .custom-checkbox:checked::after {
71
+ content: '';
72
  position: absolute;
73
  color: white;
74
  font-size: 14px;
75
  left: 4px;
76
+ top: 0;
 
 
 
 
 
 
 
 
 
 
 
77
  }
78
  </style>
79
  </head>
80
+ <body class="gradient-bg min-h-screen text-white font-sans">
81
  <div class="container mx-auto px-4 py-8 max-w-3xl">
82
  <!-- Header -->
83
  <header class="mb-8 text-center">
84
+ <h1 class="text-4xl font-bold mb-2 flex items-center justify-center">
85
+ <i class="fas fa-meteor mr-3 text-yellow-300"></i>
86
+ Nebula Tasks
87
+ </h1>
88
+ <p class="opacity-80">Organize your cosmic to-dos</p>
89
  </header>
90
 
91
+ <!-- Main Card -->
92
+ <div class="bg-white bg-opacity-10 backdrop-blur-lg rounded-xl shadow-2xl overflow-hidden">
93
  <!-- Input Section -->
94
+ <div class="p-6 border-b border-white border-opacity-20">
95
+ <div class="flex gap-3">
96
  <input
97
  type="text"
98
  id="taskInput"
99
+ placeholder="Add a new task..."
100
+ class="flex-1 bg-white bg-opacity-20 rounded-lg px-4 py-3 focus:outline-none focus:ring-2 focus:ring-white focus:ring-opacity-50 placeholder-white placeholder-opacity-70"
 
101
  >
102
  <button
103
  id="addTaskBtn"
104
+ class="bg-white bg-opacity-30 hover:bg-opacity-40 text-white px-5 rounded-lg transition-all duration-200 flex items-center justify-center"
105
  >
106
+ <i class="fas fa-plus mr-2"></i> Add
107
  </button>
108
  </div>
109
+ </div>
110
+
111
+ <!-- Filter Controls -->
112
+ <div class="px-6 py-3 flex justify-between items-center bg-white bg-opacity-5">
113
+ <div class="text-sm opacity-80">
114
+ <span id="taskCount">0</span> tasks
115
+ </div>
116
+ <div class="flex gap-2">
117
+ <button
118
+ data-filter="all"
119
+ class="filter-btn px-3 py-1 text-xs rounded-full bg-white bg-opacity-20 hover:bg-opacity-30 transition"
120
+ >
121
+ All
122
+ </button>
123
+ <button
124
+ data-filter="active"
125
+ class="filter-btn px-3 py-1 text-xs rounded-full bg-white bg-opacity-10 hover:bg-opacity-20 transition"
126
+ >
127
+ Active
128
+ </button>
129
  <button
130
+ data-filter="completed"
131
+ class="filter-btn px-3 py-1 text-xs rounded-full bg-white bg-opacity-10 hover:bg-opacity-20 transition"
132
  >
133
+ Completed
134
  </button>
135
  </div>
136
  </div>
137
 
138
+ <!-- Tasks List -->
139
+ <div id="tasksContainer" class="max-h-96 overflow-y-auto px-6">
140
+ <!-- Tasks will be added here dynamically -->
141
+ <div id="emptyState" class="py-10 text-center opacity-70">
142
+ <i class="fas fa-tasks text-4xl mb-3 opacity-50"></i>
143
+ <p>No tasks yet. Add one above!</p>
 
 
 
 
 
144
  </div>
145
  </div>
146
 
147
+ <!-- Footer Actions -->
148
+ <div class="p-4 bg-white bg-opacity-5 flex justify-between items-center text-sm">
 
149
  <button
150
+ id="clearCompletedBtn"
151
+ class="opacity-70 hover:opacity-100 transition"
152
  >
153
+ Clear completed
154
+ </button>
155
+ <button
156
+ id="saveAllBtn"
157
+ class="bg-blue-500 bg-opacity-80 hover:bg-opacity-100 px-3 py-1 rounded-lg flex items-center transition"
158
+ >
159
+ <i class="fas fa-save mr-2"></i> Save All
160
  </button>
161
  </div>
162
+ </div>
 
 
 
 
 
163
  </div>
164
 
165
  <script>
 
169
  const addTaskBtn = document.getElementById('addTaskBtn');
170
  const tasksContainer = document.getElementById('tasksContainer');
171
  const emptyState = document.getElementById('emptyState');
 
 
 
172
  const taskCount = document.getElementById('taskCount');
173
+ const filterButtons = document.querySelectorAll('.filter-btn');
174
+ const clearCompletedBtn = document.getElementById('clearCompletedBtn');
175
+ const saveAllBtn = document.getElementById('saveAllBtn');
176
 
177
+ // State
178
  let tasks = [];
179
+ let currentFilter = 'all';
180
 
181
+ // Initialize the app
182
+ loadTasks();
183
+ updateTaskCount();
184
+ updateEmptyState();
185
+ updateActiveFilterButton();
186
+
187
+ // Event Listeners
188
+ addTaskBtn.addEventListener('click', addTask);
189
+ taskInput.addEventListener('keypress', function(e) {
190
+ if (e.key === 'Enter') addTask();
191
+ });
192
+
193
+ filterButtons.forEach(btn => {
194
+ btn.addEventListener('click', function() {
195
+ currentFilter = this.dataset.filter;
196
  renderTasks();
197
+ updateActiveFilterButton();
198
+ });
199
+ });
 
200
 
201
+ clearCompletedBtn.addEventListener('click', clearCompletedTasks);
202
+ saveAllBtn.addEventListener('click', saveTasks);
 
 
 
203
 
204
+ // Functions
205
  function addTask() {
206
+ const text = taskInput.value.trim();
207
+ if (text === '') return;
 
 
 
208
 
209
  const newTask = {
210
  id: Date.now(),
211
+ text: text,
212
  completed: false,
213
+ createdAt: new Date()
214
  };
215
 
216
  tasks.unshift(newTask);
217
  taskInput.value = '';
218
  renderTasks();
 
219
  updateTaskCount();
220
+ updateEmptyState();
221
  saveTasks();
222
  }
223
 
 
224
  function renderTasks() {
225
  tasksContainer.innerHTML = '';
226
 
227
+ const filteredTasks = tasks.filter(task => {
228
+ if (currentFilter === 'active') return !task.completed;
229
+ if (currentFilter === 'completed') return task.completed;
230
+ return true;
231
+ });
 
 
 
232
 
233
  if (filteredTasks.length === 0) {
234
  updateEmptyState();
235
  return;
236
  }
237
 
238
+ emptyState.style.display = 'none';
239
+
240
  filteredTasks.forEach(task => {
241
  const taskElement = document.createElement('div');
242
+ taskElement.className = `task-item py-3 px-2 flex items-center border-b border-white border-opacity-10 hover:bg-white hover:bg-opacity-5 transition ${task.completed ? 'opacity-70' : ''}`;
243
 
244
  taskElement.innerHTML = `
245
+ <div class="flex items-center flex-1">
246
  <input
247
  type="checkbox"
248
+ class="custom-checkbox mr-3"
249
  ${task.completed ? 'checked' : ''}
250
  data-id="${task.id}"
251
  >
252
+ <span class="${task.completed ? 'line-through opacity-80' : ''}">${task.text}</span>
 
 
 
 
 
 
 
 
 
253
  </div>
254
+ <button class="delete-btn p-2 rounded-full hover:bg-white hover:bg-opacity-20 transition" data-id="${task.id}">
255
+ <i class="fas fa-trash-alt opacity-70 hover:opacity-100"></i>
256
+ </button>
257
  `;
258
 
259
  tasksContainer.appendChild(taskElement);
 
261
 
262
  // Add event listeners to new elements
263
  document.querySelectorAll('.custom-checkbox').forEach(checkbox => {
264
+ checkbox.addEventListener('change', toggleTaskComplete);
265
  });
266
 
267
  document.querySelectorAll('.delete-btn').forEach(btn => {
 
269
  });
270
  }
271
 
272
+ function toggleTaskComplete(e) {
 
273
  const taskId = parseInt(e.target.dataset.id);
274
+ const task = tasks.find(t => t.id === taskId);
275
 
276
  if (task) {
277
  task.completed = e.target.checked;
 
281
  }
282
  }
283
 
 
284
  function deleteTask(e) {
285
  const taskId = parseInt(e.currentTarget.dataset.id);
286
  tasks = tasks.filter(task => task.id !== taskId);
287
+
288
  renderTasks();
 
289
  updateTaskCount();
290
+ updateEmptyState();
291
  saveTasks();
292
  }
293
 
294
+ function clearCompletedTasks() {
 
295
  tasks = tasks.filter(task => !task.completed);
296
+
297
  renderTasks();
 
298
  updateTaskCount();
299
+ updateEmptyState();
300
  saveTasks();
301
  }
302
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
303
  function updateTaskCount() {
304
+ const activeTasks = tasks.filter(task => !task.completed).length;
305
  const totalTasks = tasks.length;
 
 
306
 
307
+ taskCount.textContent = `${activeTasks} active of ${totalTasks}`;
308
+ }
309
+
310
+ function updateEmptyState() {
311
+ const filteredTasks = tasks.filter(task => {
312
+ if (currentFilter === 'active') return !task.completed;
313
+ if (currentFilter === 'completed') return task.completed;
314
+ return true;
315
+ });
316
 
317
+ if (filteredTasks.length === 0) {
318
+ emptyState.style.display = 'block';
 
 
319
  } else {
320
+ emptyState.style.display = 'none';
321
  }
 
 
322
  }
323
 
324
+ function updateActiveFilterButton() {
325
+ filterButtons.forEach(btn => {
326
+ if (btn.dataset.filter === currentFilter) {
327
+ btn.classList.remove('bg-opacity-10');
328
+ btn.classList.add('bg-opacity-20');
329
+ } else {
330
+ btn.classList.remove('bg-opacity-20');
331
+ btn.classList.add('bg-opacity-10');
332
+ }
333
  });
334
  }
335
 
336
+ function saveTasks() {
337
+ localStorage.setItem('nebula-tasks', JSON.stringify(tasks));
 
 
 
 
 
338
 
339
+ // Show save confirmation
340
+ const originalText = saveAllBtn.innerHTML;
341
+ saveAllBtn.innerHTML = '<i class="fas fa-check mr-2"></i> Saved!';
342
+ saveAllBtn.classList.remove('bg-blue-500');
343
+ saveAllBtn.classList.add('bg-green-500');
344
 
345
  setTimeout(() => {
346
+ saveAllBtn.innerHTML = originalText;
347
+ saveAllBtn.classList.remove('bg-green-500');
348
+ saveAllBtn.classList.add('bg-blue-500');
349
+ }, 1500);
 
350
  }
351
 
352
+ function loadTasks() {
353
+ const savedTasks = localStorage.getItem('nebula-tasks');
354
+ if (savedTasks) {
355
+ tasks = JSON.parse(savedTasks);
356
+ renderTasks();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
357
  }
358
+ }
 
359
  });
360
  </script>
361
  <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=jayedgar/generative-waves" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
prompts.txt CHANGED
@@ -1 +1,2 @@
1
- Create a responsive to-do list web app with save/delete features
 
 
1
+ Create a responsive to-do list web app with save/delete features
2
+ Create a responsive to-do list web app with save/delete features , with a cool background