akhaliq HF Staff commited on
Commit
df725dd
·
verified ·
1 Parent(s): e0a3d59

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +819 -19
index.html CHANGED
@@ -1,19 +1,819 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Todo App</title>
8
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
9
+ <style>
10
+ * {
11
+ margin: 0;
12
+ padding: 0;
13
+ box-sizing: border-box;
14
+ }
15
+
16
+ :root {
17
+ --primary: #6366f1;
18
+ --primary-dark: #4f46e5;
19
+ --secondary: #f1f5f9;
20
+ --accent: #10b981;
21
+ --danger: #ef4444;
22
+ --text: #1e293b;
23
+ --text-light: #64748b;
24
+ --white: #ffffff;
25
+ --shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
26
+ --shadow-sm: 0 4px 12px rgba(0, 0, 0, 0.08);
27
+ }
28
+
29
+ body {
30
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
31
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
32
+ min-height: 100vh;
33
+ padding: 20px;
34
+ display: flex;
35
+ flex-direction: column;
36
+ align-items: center;
37
+ }
38
+
39
+ .built-with {
40
+ text-align: center;
41
+ margin-bottom: 20px;
42
+ }
43
+
44
+ .built-with a {
45
+ color: var(--white);
46
+ text-decoration: none;
47
+ font-size: 0.9rem;
48
+ opacity: 0.9;
49
+ transition: opacity 0.3s ease;
50
+ }
51
+
52
+ .built-with a:hover {
53
+ opacity: 1;
54
+ text-decoration: underline;
55
+ }
56
+
57
+ .container {
58
+ width: 100%;
59
+ max-width: 600px;
60
+ background: var(--white);
61
+ border-radius: 24px;
62
+ box-shadow: var(--shadow);
63
+ overflow: hidden;
64
+ animation: slideUp 0.6s ease;
65
+ }
66
+
67
+ @keyframes slideUp {
68
+ from {
69
+ opacity: 0;
70
+ transform: translateY(30px);
71
+ }
72
+
73
+ to {
74
+ opacity: 1;
75
+ transform: translateY(0);
76
+ }
77
+ }
78
+
79
+ .header {
80
+ background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
81
+ padding: 30px;
82
+ color: var(--white);
83
+ text-align: center;
84
+ }
85
+
86
+ .header h1 {
87
+ font-size: 2rem;
88
+ font-weight: 700;
89
+ margin-bottom: 8px;
90
+ display: flex;
91
+ align-items: center;
92
+ justify-content: center;
93
+ gap: 12px;
94
+ }
95
+
96
+ .header p {
97
+ opacity: 0.9;
98
+ font-size: 0.95rem;
99
+ }
100
+
101
+ .stats {
102
+ display: flex;
103
+ justify-content: center;
104
+ gap: 30px;
105
+ margin-top: 20px;
106
+ }
107
+
108
+ .stat {
109
+ text-align: center;
110
+ }
111
+
112
+ .stat-number {
113
+ font-size: 1.8rem;
114
+ font-weight: 700;
115
+ }
116
+
117
+ .stat-label {
118
+ font-size: 0.8rem;
119
+ opacity: 0.8;
120
+ text-transform: uppercase;
121
+ letter-spacing: 1px;
122
+ }
123
+
124
+ .input-section {
125
+ padding: 25px;
126
+ background: var(--secondary);
127
+ border-bottom: 1px solid #e2e8f0;
128
+ }
129
+
130
+ .input-wrapper {
131
+ display: flex;
132
+ gap: 12px;
133
+ }
134
+
135
+ .input-wrapper input {
136
+ flex: 1;
137
+ padding: 16px 20px;
138
+ border: 2px solid transparent;
139
+ border-radius: 14px;
140
+ font-size: 1rem;
141
+ background: var(--white);
142
+ color: var(--text);
143
+ transition: all 0.3s ease;
144
+ box-shadow: var(--shadow-sm);
145
+ }
146
+
147
+ .input-wrapper input:focus {
148
+ outline: none;
149
+ border-color: var(--primary);
150
+ box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.1);
151
+ }
152
+
153
+ .input-wrapper input::placeholder {
154
+ color: var(--text-light);
155
+ }
156
+
157
+ .add-btn {
158
+ padding: 16px 24px;
159
+ background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
160
+ color: var(--white);
161
+ border: none;
162
+ border-radius: 14px;
163
+ font-size: 1rem;
164
+ font-weight: 600;
165
+ cursor: pointer;
166
+ transition: all 0.3s ease;
167
+ display: flex;
168
+ align-items: center;
169
+ gap: 8px;
170
+ box-shadow: var(--shadow-sm);
171
+ }
172
+
173
+ .add-btn:hover {
174
+ transform: translateY(-2px);
175
+ box-shadow: 0 8px 20px rgba(99, 102, 241, 0.4);
176
+ }
177
+
178
+ .add-btn:active {
179
+ transform: translateY(0);
180
+ }
181
+
182
+ .filters {
183
+ display: flex;
184
+ gap: 10px;
185
+ padding: 20px 25px;
186
+ background: var(--white);
187
+ border-bottom: 1px solid #e2e8f0;
188
+ flex-wrap: wrap;
189
+ }
190
+
191
+ .filter-btn {
192
+ padding: 10px 20px;
193
+ border: 2px solid #e2e8f0;
194
+ border-radius: 10px;
195
+ background: var(--white);
196
+ color: var(--text-light);
197
+ font-size: 0.9rem;
198
+ font-weight: 500;
199
+ cursor: pointer;
200
+ transition: all 0.3s ease;
201
+ }
202
+
203
+ .filter-btn:hover {
204
+ border-color: var(--primary);
205
+ color: var(--primary);
206
+ }
207
+
208
+ .filter-btn.active {
209
+ background: var(--primary);
210
+ border-color: var(--primary);
211
+ color: var(--white);
212
+ }
213
+
214
+ .todo-list {
215
+ padding: 20px 25px;
216
+ max-height: 400px;
217
+ overflow-y: auto;
218
+ }
219
+
220
+ .todo-list::-webkit-scrollbar {
221
+ width: 6px;
222
+ }
223
+
224
+ .todo-list::-webkit-scrollbar-track {
225
+ background: #f1f5f9;
226
+ border-radius: 3px;
227
+ }
228
+
229
+ .todo-list::-webkit-scrollbar-thumb {
230
+ background: #cbd5e1;
231
+ border-radius: 3px;
232
+ }
233
+
234
+ .todo-item {
235
+ display: flex;
236
+ align-items: center;
237
+ gap: 15px;
238
+ padding: 18px;
239
+ background: var(--secondary);
240
+ border-radius: 14px;
241
+ margin-bottom: 12px;
242
+ transition: all 0.3s ease;
243
+ animation: fadeIn 0.4s ease;
244
+ }
245
+
246
+ @keyframes fadeIn {
247
+ from {
248
+ opacity: 0;
249
+ transform: translateX(-20px);
250
+ }
251
+
252
+ to {
253
+ opacity: 1;
254
+ transform: translateX(0);
255
+ }
256
+ }
257
+
258
+ .todo-item:hover {
259
+ transform: translateX(5px);
260
+ box-shadow: var(--shadow-sm);
261
+ }
262
+
263
+ .todo-item.completed {
264
+ opacity: 0.7;
265
+ }
266
+
267
+ .todo-item.completed .todo-text {
268
+ text-decoration: line-through;
269
+ color: var(--text-light);
270
+ }
271
+
272
+ .checkbox {
273
+ width: 24px;
274
+ height: 24px;
275
+ border: 2px solid #cbd5e1;
276
+ border-radius: 8px;
277
+ cursor: pointer;
278
+ display: flex;
279
+ align-items: center;
280
+ justify-content: center;
281
+ transition: all 0.3s ease;
282
+ flex-shrink: 0;
283
+ }
284
+
285
+ .checkbox:hover {
286
+ border-color: var(--primary);
287
+ }
288
+
289
+ .checkbox.checked {
290
+ background: var(--accent);
291
+ border-color: var(--accent);
292
+ }
293
+
294
+ .checkbox.checked i {
295
+ color: var(--white);
296
+ font-size: 0.8rem;
297
+ }
298
+
299
+ .todo-text {
300
+ flex: 1;
301
+ font-size: 1rem;
302
+ color: var(--text);
303
+ word-break: break-word;
304
+ }
305
+
306
+ .todo-date {
307
+ font-size: 0.75rem;
308
+ color: var(--text-light);
309
+ white-space: nowrap;
310
+ }
311
+
312
+ .todo-actions {
313
+ display: flex;
314
+ gap: 8px;
315
+ }
316
+
317
+ .action-btn {
318
+ width: 36px;
319
+ height: 36px;
320
+ border: none;
321
+ border-radius: 10px;
322
+ cursor: pointer;
323
+ display: flex;
324
+ align-items: center;
325
+ justify-content: center;
326
+ transition: all 0.3s ease;
327
+ }
328
+
329
+ .edit-btn {
330
+ background: #fef3c7;
331
+ color: #f59e0b;
332
+ }
333
+
334
+ .edit-btn:hover {
335
+ background: #fde68a;
336
+ transform: scale(1.1);
337
+ }
338
+
339
+ .delete-btn {
340
+ background: #fee2e2;
341
+ color: var(--danger);
342
+ }
343
+
344
+ .delete-btn:hover {
345
+ background: #fecaca;
346
+ transform: scale(1.1);
347
+ }
348
+
349
+ .empty-state {
350
+ text-align: center;
351
+ padding: 50px 20px;
352
+ color: var(--text-light);
353
+ }
354
+
355
+ .empty-state i {
356
+ font-size: 4rem;
357
+ margin-bottom: 20px;
358
+ opacity: 0.3;
359
+ }
360
+
361
+ .empty-state h3 {
362
+ font-size: 1.2rem;
363
+ margin-bottom: 8px;
364
+ color: var(--text);
365
+ }
366
+
367
+ .empty-state p {
368
+ font-size: 0.95rem;
369
+ }
370
+
371
+ .footer {
372
+ padding: 20px 25px;
373
+ background: var(--secondary);
374
+ display: flex;
375
+ justify-content: space-between;
376
+ align-items: center;
377
+ flex-wrap: wrap;
378
+ gap: 10px;
379
+ }
380
+
381
+ .footer-text {
382
+ color: var(--text-light);
383
+ font-size: 0.9rem;
384
+ }
385
+
386
+ .clear-btn {
387
+ padding: 10px 20px;
388
+ background: transparent;
389
+ border: 2px solid var(--danger);
390
+ color: var(--danger);
391
+ border-radius: 10px;
392
+ font-size: 0.9rem;
393
+ font-weight: 500;
394
+ cursor: pointer;
395
+ transition: all 0.3s ease;
396
+ }
397
+
398
+ .clear-btn:hover {
399
+ background: var(--danger);
400
+ color: var(--white);
401
+ }
402
+
403
+ /* Edit Modal */
404
+ .modal-overlay {
405
+ position: fixed;
406
+ top: 0;
407
+ left: 0;
408
+ width: 100%;
409
+ height: 100%;
410
+ background: rgba(0, 0, 0, 0.5);
411
+ display: none;
412
+ align-items: center;
413
+ justify-content: center;
414
+ z-index: 1000;
415
+ padding: 20px;
416
+ }
417
+
418
+ .modal-overlay.active {
419
+ display: flex;
420
+ }
421
+
422
+ .modal {
423
+ background: var(--white);
424
+ border-radius: 20px;
425
+ padding: 30px;
426
+ width: 100%;
427
+ max-width: 400px;
428
+ animation: modalSlide 0.3s ease;
429
+ }
430
+
431
+ @keyframes modalSlide {
432
+ from {
433
+ opacity: 0;
434
+ transform: scale(0.9);
435
+ }
436
+
437
+ to {
438
+ opacity: 1;
439
+ transform: scale(1);
440
+ }
441
+ }
442
+
443
+ .modal h3 {
444
+ font-size: 1.3rem;
445
+ color: var(--text);
446
+ margin-bottom: 20px;
447
+ }
448
+
449
+ .modal input {
450
+ width: 100%;
451
+ padding: 14px 18px;
452
+ border: 2px solid #e2e8f0;
453
+ border-radius: 12px;
454
+ font-size: 1rem;
455
+ margin-bottom: 20px;
456
+ transition: all 0.3s ease;
457
+ }
458
+
459
+ .modal input:focus {
460
+ outline: none;
461
+ border-color: var(--primary);
462
+ }
463
+
464
+ .modal-actions {
465
+ display: flex;
466
+ gap: 12px;
467
+ justify-content: flex-end;
468
+ }
469
+
470
+ .modal-btn {
471
+ padding: 12px 24px;
472
+ border-radius: 10px;
473
+ font-size: 0.95rem;
474
+ font-weight: 500;
475
+ cursor: pointer;
476
+ transition: all 0.3s ease;
477
+ }
478
+
479
+ .cancel-btn {
480
+ background: var(--secondary);
481
+ border: none;
482
+ color: var(--text);
483
+ }
484
+
485
+ .cancel-btn:hover {
486
+ background: #e2e8f0;
487
+ }
488
+
489
+ .save-btn {
490
+ background: var(--primary);
491
+ border: none;
492
+ color: var(--white);
493
+ }
494
+
495
+ .save-btn:hover {
496
+ background: var(--primary-dark);
497
+ }
498
+
499
+ /* Responsive Design */
500
+ @media (max-width: 480px) {
501
+ .header h1 {
502
+ font-size: 1.5rem;
503
+ }
504
+
505
+ .stats {
506
+ gap: 20px;
507
+ }
508
+
509
+ .stat-number {
510
+ font-size: 1.4rem;
511
+ }
512
+
513
+ .input-wrapper {
514
+ flex-direction: column;
515
+ }
516
+
517
+ .add-btn {
518
+ justify-content: center;
519
+ }
520
+
521
+ .filters {
522
+ justify-content: center;
523
+ }
524
+
525
+ .todo-item {
526
+ flex-wrap: wrap;
527
+ }
528
+
529
+ .todo-actions {
530
+ width: 100%;
531
+ justify-content: flex-end;
532
+ margin-top: 10px;
533
+ }
534
+
535
+ .footer {
536
+ flex-direction: column;
537
+ text-align: center;
538
+ }
539
+ }
540
+ </style>
541
+ </head>
542
+
543
+ <body>
544
+ <div class="built-with">
545
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank">Built with anycoder</a>
546
+ </div>
547
+
548
+ <div class="container">
549
+ <header class="header">
550
+ <h1><i class="fas fa-check-circle"></i> Todo App</h1>
551
+ <p>Organize your tasks efficiently</p>
552
+ <div class="stats">
553
+ <div class="stat">
554
+ <div class="stat-number" id="totalTasks">0</div>
555
+ <div class="stat-label">Total</div>
556
+ </div>
557
+ <div class="stat">
558
+ <div class="stat-number" id="completedTasks">0</div>
559
+ <div class="stat-label">Completed</div>
560
+ </div>
561
+ <div class="stat">
562
+ <div class="stat-number" id="pendingTasks">0</div>
563
+ <div class="stat-label">Pending</div>
564
+ </div>
565
+ </div>
566
+ </header>
567
+
568
+ <div class="input-section">
569
+ <div class="input-wrapper">
570
+ <input type="text" id="todoInput" placeholder="What needs to be done?" maxlength="100">
571
+ <button class="add-btn" onclick="addTodo()">
572
+ <i class="fas fa-plus"></i>
573
+ <span>Add</span>
574
+ </button>
575
+ </div>
576
+ </div>
577
+
578
+ <div class="filters">
579
+ <button class="filter-btn active" data-filter="all" onclick="filterTodos('all')">All</button>
580
+ <button class="filter-btn" data-filter="pending" onclick="filterTodos('pending')">Pending</button>
581
+ <button class="filter-btn" data-filter="completed" onclick="filterTodos('completed')">Completed</button>
582
+ </div>
583
+
584
+ <div class="todo-list" id="todoList">
585
+ <!-- Todos will be rendered here -->
586
+ </div>
587
+
588
+ <div class="footer">
589
+ <span class="footer-text" id="footerText">No tasks yet</span>
590
+ <button class="clear-btn" onclick="clearCompleted()">
591
+ <i class="fas fa-trash-alt"></i> Clear Completed
592
+ </button>
593
+ </div>
594
+ </div>
595
+
596
+ <!-- Edit Modal -->
597
+ <div class="modal-overlay" id="editModal">
598
+ <div class="modal">
599
+ <h3><i class="fas fa-edit"></i> Edit Task</h3>
600
+ <input type="text" id="editInput" placeholder="Update your task..." maxlength="100">
601
+ <div class="modal-actions">
602
+ <button class="modal-btn cancel-btn" onclick="closeModal()">Cancel</button>
603
+ <button class="modal-btn save-btn" onclick="saveEdit()">Save</button>
604
+ </div>
605
+ </div>
606
+ </div>
607
+
608
+ <script>
609
+ let todos = JSON.parse(localStorage.getItem('todos')) || [];
610
+ let currentFilter = 'all';
611
+ let editingId = null;
612
+
613
+ function saveTodos() {
614
+ localStorage.setItem('todos', JSON.stringify(todos));
615
+ }
616
+
617
+ function formatDate(date) {
618
+ const options = { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' };
619
+ return new Date(date).toLocaleDateString('en-US', options);
620
+ }
621
+
622
+ function updateStats() {
623
+ const total = todos.length;
624
+ const completed = todos.filter(t => t.completed).length;
625
+ const pending = total - completed;
626
+
627
+ document.getElementById('totalTasks').textContent = total;
628
+ document.getElementById('completedTasks').textContent = completed;
629
+ document.getElementById('pendingTasks').textContent = pending;
630
+
631
+ const footerText = document.getElementById('footerText');
632
+ if (total === 0) {
633
+ footerText.textContent = 'No tasks yet';
634
+ } else if (pending === 0) {
635
+ footerText.textContent = 'All tasks completed! 🎉';
636
+ } else {
637
+ footerText.textContent = `${pending} task${pending !== 1 ? 's' : ''} remaining`;
638
+ }
639
+ }
640
+
641
+ function renderTodos() {
642
+ const todoList = document.getElementById('todoList');
643
+ let filteredTodos = todos;
644
+
645
+ if (currentFilter === 'pending') {
646
+ filteredTodos = todos.filter(t => !t.completed);
647
+ } else if (currentFilter === 'completed') {
648
+ filteredTodos = todos.filter(t => t.completed);
649
+ }
650
+
651
+ if (filteredTodos.length === 0) {
652
+ let message = 'No tasks yet';
653
+ let subMessage = 'Add a new task to get started!';
654
+
655
+ if (currentFilter === 'pending') {
656
+ message = 'No pending tasks';
657
+ subMessage = 'All caught up! 🎉';
658
+ } else if (currentFilter === 'completed') {
659
+ message = 'No completed tasks';
660
+ subMessage = 'Complete some tasks to see them here';
661
+ }
662
+
663
+ todoList.innerHTML = `
664
+ <div class="empty-state">
665
+ <i class="fas fa-clipboard-list"></i>
666
+ <h3>${message}</h3>
667
+ <p>${subMessage}</p>
668
+ </div>
669
+ `;
670
+ } else {
671
+ todoList.innerHTML = filteredTodos.map(todo => `
672
+ <div class="todo-item ${todo.completed ? 'completed' : ''}" data-id="${todo.id}">
673
+ <div class="checkbox ${todo.completed ? 'checked' : ''}" onclick="toggleTodo(${todo.id})">
674
+ ${todo.completed ? '<i class="fas fa-check"></i>' : ''}
675
+ </div>
676
+ <span class="todo-text">${escapeHtml(todo.text)}</span>
677
+ <span class="todo-date">${formatDate(todo.createdAt)}</span>
678
+ <div class="todo-actions">
679
+ <button class="action-btn edit-btn" onclick="openEditModal(${todo.id})" title="Edit">
680
+ <i class="fas fa-pen"></i>
681
+ </button>
682
+ <button class="action-btn delete-btn" onclick="deleteTodo(${todo.id})" title="Delete">
683
+ <i class="fas fa-trash"></i>
684
+ </button>
685
+ </div>
686
+ </div>
687
+ `).join('');
688
+ }
689
+
690
+ updateStats();
691
+ }
692
+
693
+ function escapeHtml(text) {
694
+ const div = document.createElement('div');
695
+ div.textContent = text;
696
+ return div.innerHTML;
697
+ }
698
+
699
+ function addTodo() {
700
+ const input = document.getElementById('todoInput');
701
+ const text = input.value.trim();
702
+
703
+ if (text === '') {
704
+ input.focus();
705
+ return;
706
+ }
707
+
708
+ const todo = {
709
+ id: Date.now(),
710
+ text: text,
711
+ completed: false,
712
+ createdAt: new Date().toISOString()
713
+ };
714
+
715
+ todos.unshift(todo);
716
+ saveTodos();
717
+ renderTodos();
718
+ input.value = '';
719
+ input.focus();
720
+ }
721
+
722
+ function toggleTodo(id) {
723
+ const todo = todos.find(t => t.id === id);
724
+ if (todo) {
725
+ todo.completed = !todo.completed;
726
+ saveTodos();
727
+ renderTodos();
728
+ }
729
+ }
730
+
731
+ function deleteTodo(id) {
732
+ todos = todos.filter(t => t.id !== id);
733
+ saveTodos();
734
+ renderTodos();
735
+ }
736
+
737
+ function openEditModal(id) {
738
+ const todo = todos.find(t => t.id === id);
739
+ if (todo) {
740
+ editingId = id;
741
+ document.getElementById('editInput').value = todo.text;
742
+ document.getElementById('editModal').classList.add('active');
743
+ document.getElementById('editInput').focus();
744
+ }
745
+ }
746
+
747
+ function closeModal() {
748
+ document.getElementById('editModal').classList.remove('active');
749
+ editingId = null;
750
+ }
751
+
752
+ function saveEdit() {
753
+ const input = document.getElementById('editInput');
754
+ const text = input.value.trim();
755
+
756
+ if (text === '' || editingId === null) {
757
+ return;
758
+ }
759
+
760
+ const todo = todos.find(t => t.id === editingId);
761
+ if (todo) {
762
+ todo.text = text;
763
+ saveTodos();
764
+ renderTodos();
765
+ }
766
+
767
+ closeModal();
768
+ }
769
+
770
+ function filterTodos(filter) {
771
+ currentFilter = filter;
772
+
773
+ document.querySelectorAll('.filter-btn').forEach(btn => {
774
+ btn.classList.remove('active');
775
+ if (btn.dataset.filter === filter) {
776
+ btn.classList.add('active');
777
+ }
778
+ });
779
+
780
+ renderTodos();
781
+ }
782
+
783
+ function clearCompleted() {
784
+ todos = todos.filter(t => !t.completed);
785
+ saveTodos();
786
+ renderTodos();
787
+ }
788
+
789
+ // Event Listeners
790
+ document.getElementById('todoInput').addEventListener('keypress', function(e) {
791
+ if (e.key === 'Enter') {
792
+ addTodo();
793
+ }
794
+ });
795
+
796
+ document.getElementById('editInput').addEventListener('keypress', function(e) {
797
+ if (e.key === 'Enter') {
798
+ saveEdit();
799
+ }
800
+ });
801
+
802
+ document.getElementById('editModal').addEventListener('click', function(e) {
803
+ if (e.target === this) {
804
+ closeModal();
805
+ }
806
+ });
807
+
808
+ document.addEventListener('keydown', function(e) {
809
+ if (e.key === 'Escape') {
810
+ closeModal();
811
+ }
812
+ });
813
+
814
+ // Initial render
815
+ renderTodos();
816
+ </script>
817
+ </body>
818
+
819
+ </html>