akhaliq HF Staff commited on
Commit
3f36611
·
verified ·
1 Parent(s): 39f777a

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +612 -19
index.html CHANGED
@@ -1,19 +1,612 @@
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
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Modern Todo App</title>
7
+ <!-- Font Awesome for Icons -->
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ :root {
11
+ --primary-color: #6366f1;
12
+ --primary-hover: #4f46e5;
13
+ --bg-color: #f3f4f6;
14
+ --card-bg: #ffffff;
15
+ --text-color: #1f2937;
16
+ --text-secondary: #6b7280;
17
+ --danger-color: #ef4444;
18
+ --success-color: #10b981;
19
+ --border-radius: 16px;
20
+ --shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
21
+ --transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
22
+ }
23
+
24
+ * {
25
+ margin: 0;
26
+ padding: 0;
27
+ box-sizing: border-box;
28
+ font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
29
+ }
30
+
31
+ body {
32
+ background-color: var(--bg-color);
33
+ background-image:
34
+ radial-gradient(at 0% 0%, hsla(253,16%,7%,1) 0, transparent 50%),
35
+ radial-gradient(at 50% 0%, hsla(225,39%,30%,1) 0, transparent 50%),
36
+ radial-gradient(at 100% 0%, hsla(339,49%,30%,1) 0, transparent 50%);
37
+ background-size: cover;
38
+ background-attachment: fixed;
39
+ min-height: 100vh;
40
+ display: flex;
41
+ justify-content: center;
42
+ align-items: center;
43
+ padding: 20px;
44
+ color: var(--text-color);
45
+ }
46
+
47
+ /* Mobile Adjustment for background to be dark mode style usually looks better with gradients,
48
+ but let's stick to a clean glassmorphism look */
49
+ body {
50
+ background: linear-gradient(135deg, #e0c3fc 0%, #8ec5fc 100%);
51
+ }
52
+
53
+ .app-container {
54
+ width: 100%;
55
+ max-width: 500px;
56
+ background: rgba(255, 255, 255, 0.85);
57
+ backdrop-filter: blur(12px);
58
+ -webkit-backdrop-filter: blur(12px);
59
+ border-radius: var(--border-radius);
60
+ box-shadow: var(--shadow);
61
+ padding: 2rem;
62
+ display: flex;
63
+ flex-direction: column;
64
+ gap: 1.5rem;
65
+ border: 1px solid rgba(255, 255, 255, 0.5);
66
+ }
67
+
68
+ /* Header Section */
69
+ header {
70
+ text-align: center;
71
+ position: relative;
72
+ }
73
+
74
+ h1 {
75
+ font-size: 2rem;
76
+ font-weight: 800;
77
+ background: linear-gradient(135deg, var(--primary-color), #a855f7);
78
+ -webkit-background-clip: text;
79
+ -webkit-text-fill-color: transparent;
80
+ margin-bottom: 0.5rem;
81
+ letter-spacing: -0.5px;
82
+ }
83
+
84
+ .built-with {
85
+ font-size: 0.85rem;
86
+ color: var(--text-secondary);
87
+ text-decoration: none;
88
+ display: inline-flex;
89
+ align-items: center;
90
+ gap: 5px;
91
+ transition: var(--transition);
92
+ padding: 5px 12px;
93
+ background: rgba(255,255,255,0.5);
94
+ border-radius: 20px;
95
+ }
96
+
97
+ .built-with:hover {
98
+ background: rgba(255,255,255,0.9);
99
+ transform: translateY(-2px);
100
+ box-shadow: 0 4px 6px rgba(0,0,0,0.05);
101
+ color: var(--primary-color);
102
+ }
103
+
104
+ /* Input Section */
105
+ .input-wrapper {
106
+ position: relative;
107
+ display: flex;
108
+ gap: 10px;
109
+ }
110
+
111
+ input[type="text"] {
112
+ width: 100%;
113
+ padding: 1rem 1.5rem;
114
+ border: 2px solid transparent;
115
+ background: rgba(255, 255, 255, 0.9);
116
+ border-radius: 12px;
117
+ font-size: 1rem;
118
+ outline: none;
119
+ transition: var(--transition);
120
+ box-shadow: inset 0 2px 4px rgba(0,0,0,0.02);
121
+ }
122
+
123
+ input[type="text"]:focus {
124
+ border-color: var(--primary-color);
125
+ box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.2);
126
+ }
127
+
128
+ .add-btn {
129
+ padding: 0 1.5rem;
130
+ background: var(--primary-color);
131
+ color: white;
132
+ border: none;
133
+ border-radius: 12px;
134
+ cursor: pointer;
135
+ font-weight: 600;
136
+ transition: var(--transition);
137
+ display: flex;
138
+ align-items: center;
139
+ justify-content: center;
140
+ }
141
+
142
+ .add-btn:hover {
143
+ background: var(--primary-hover);
144
+ transform: scale(1.05);
145
+ box-shadow: 0 4px 12px rgba(99, 102, 241, 0.4);
146
+ }
147
+
148
+ /* Filters */
149
+ .filters {
150
+ display: flex;
151
+ justify-content: center;
152
+ gap: 0.5rem;
153
+ background: rgba(255, 255, 255, 0.5);
154
+ padding: 0.3rem;
155
+ border-radius: 12px;
156
+ }
157
+
158
+ .filter-btn {
159
+ flex: 1;
160
+ padding: 0.5rem;
161
+ border: none;
162
+ background: transparent;
163
+ color: var(--text-secondary);
164
+ cursor: pointer;
165
+ border-radius: 8px;
166
+ font-weight: 600;
167
+ font-size: 0.9rem;
168
+ transition: var(--transition);
169
+ }
170
+
171
+ .filter-btn.active {
172
+ background: white;
173
+ color: var(--primary-color);
174
+ box-shadow: 0 2px 4px rgba(0,0,0,0.05);
175
+ }
176
+
177
+ .filter-btn:hover:not(.active) {
178
+ color: var(--text-color);
179
+ }
180
+
181
+ /* Todo List */
182
+ .todo-list {
183
+ list-style: none;
184
+ display: flex;
185
+ flex-direction: column;
186
+ gap: 0.8rem;
187
+ max-height: 400px;
188
+ overflow-y: auto;
189
+ padding-right: 5px;
190
+ }
191
+
192
+ /* Custom Scrollbar */
193
+ .todo-list::-webkit-scrollbar {
194
+ width: 6px;
195
+ }
196
+ .todo-list::-webkit-scrollbar-track {
197
+ background: transparent;
198
+ }
199
+ .todo-list::-webkit-scrollbar-thumb {
200
+ background-color: rgba(0,0,0,0.1);
201
+ border-radius: 20px;
202
+ }
203
+
204
+ .todo-item {
205
+ background: white;
206
+ padding: 1rem;
207
+ border-radius: 12px;
208
+ display: flex;
209
+ align-items: center;
210
+ gap: 1rem;
211
+ box-shadow: 0 2px 5px rgba(0,0,0,0.02);
212
+ transition: var(--transition);
213
+ animation: slideIn 0.3s ease-out;
214
+ position: relative;
215
+ overflow: hidden;
216
+ }
217
+
218
+ .todo-item:hover {
219
+ transform: translateY(-2px);
220
+ box-shadow: 0 5px 15px rgba(0,0,0,0.05);
221
+ }
222
+
223
+ .todo-item.completed .todo-text {
224
+ text-decoration: line-through;
225
+ color: #9ca3af;
226
+ }
227
+
228
+ /* Custom Checkbox */
229
+ .checkbox-wrapper {
230
+ position: relative;
231
+ width: 24px;
232
+ height: 24px;
233
+ flex-shrink: 0;
234
+ }
235
+
236
+ .checkbox-wrapper input {
237
+ opacity: 0;
238
+ width: 100%;
239
+ height: 100%;
240
+ cursor: pointer;
241
+ position: absolute;
242
+ z-index: 2;
243
+ }
244
+
245
+ .custom-checkbox {
246
+ position: absolute;
247
+ top: 0;
248
+ left: 0;
249
+ width: 100%;
250
+ height: 100%;
251
+ background-color: #e5e7eb;
252
+ border-radius: 6px;
253
+ transition: var(--transition);
254
+ display: flex;
255
+ align-items: center;
256
+ justify-content: center;
257
+ }
258
+
259
+ .checkbox-wrapper input:checked ~ .custom-checkbox {
260
+ background-color: var(--success-color);
261
+ }
262
+
263
+ .custom-checkbox::after {
264
+ content: '\f00c';
265
+ font-family: 'Font Awesome 6 Free';
266
+ font-weight: 900;
267
+ color: white;
268
+ font-size: 0.8rem;
269
+ opacity: 0;
270
+ transform: scale(0);
271
+ transition: var(--transition);
272
+ }
273
+
274
+ .checkbox-wrapper input:checked ~ .custom-checkbox::after {
275
+ opacity: 1;
276
+ transform: scale(1);
277
+ }
278
+
279
+ .todo-text {
280
+ flex: 1;
281
+ font-size: 1rem;
282
+ word-break: break-word;
283
+ transition: var(--transition);
284
+ }
285
+
286
+ .delete-btn {
287
+ background: transparent;
288
+ border: none;
289
+ color: #ef4444;
290
+ cursor: pointer;
291
+ opacity: 0;
292
+ transform: scale(0.8);
293
+ transition: var(--transition);
294
+ padding: 5px;
295
+ font-size: 1.1rem;
296
+ }
297
+
298
+ .todo-item:hover .delete-btn {
299
+ opacity: 1;
300
+ transform: scale(1);
301
+ }
302
+
303
+ .delete-btn:hover {
304
+ transform: scale(1.2);
305
+ color: #b91c1c;
306
+ }
307
+
308
+ /* Empty State */
309
+ .empty-state {
310
+ text-align: center;
311
+ padding: 2rem 0;
312
+ color: var(--text-secondary);
313
+ display: none;
314
+ }
315
+
316
+ .empty-state i {
317
+ font-size: 3rem;
318
+ margin-bottom: 1rem;
319
+ opacity: 0.3;
320
+ }
321
+
322
+ /* Animations */
323
+ @keyframes slideIn {
324
+ from {
325
+ opacity: 0;
326
+ transform: translateY(10px);
327
+ }
328
+ to {
329
+ opacity: 1;
330
+ transform: translateY(0);
331
+ }
332
+ }
333
+
334
+ @keyframes fall {
335
+ to {
336
+ transform: translateY(13px) rotate(5deg);
337
+ opacity: 0;
338
+ }
339
+ }
340
+
341
+ .fall {
342
+ animation: fall 0.3s ease-out forwards;
343
+ }
344
+
345
+ /* Footer Stats */
346
+ .footer-info {
347
+ display: flex;
348
+ justify-content: space-between;
349
+ align-items: center;
350
+ font-size: 0.85rem;
351
+ color: var(--text-secondary);
352
+ padding-top: 0.5rem;
353
+ }
354
+
355
+ .clear-btn {
356
+ background: transparent;
357
+ border: none;
358
+ color: var(--text-secondary);
359
+ cursor: pointer;
360
+ font-size: 0.85rem;
361
+ transition: var(--transition);
362
+ }
363
+
364
+ .clear-btn:hover {
365
+ color: var(--danger-color);
366
+ text-decoration: underline;
367
+ }
368
+
369
+ /* Mobile Responsiveness */
370
+ @media (max-width: 480px) {
371
+ .app-container {
372
+ padding: 1.5rem;
373
+ max-height: 90vh;
374
+ }
375
+
376
+ h1 {
377
+ font-size: 1.75rem;
378
+ }
379
+
380
+ .delete-btn {
381
+ opacity: 1; /* Always show delete on mobile */
382
+ transform: scale(1);
383
+ }
384
+ }
385
+ </style>
386
+ </head>
387
+ <body>
388
+
389
+ <div class="app-container">
390
+ <header>
391
+ <h1>Task Master</h1>
392
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="built-with">
393
+ <i class="fas fa-code"></i> Built with anycoder
394
+ </a>
395
+ </header>
396
+
397
+ <div class="input-wrapper">
398
+ <input type="text" id="todo-input" placeholder="What needs to be done?" autocomplete="off">
399
+ <button class="add-btn" id="add-btn">
400
+ <i class="fas fa-plus"></i>
401
+ </button>
402
+ </div>
403
+
404
+ <div class="filters">
405
+ <button class="filter-btn active" data-filter="all">All</button>
406
+ <button class="filter-btn" data-filter="active">Active</button>
407
+ <button class="filter-btn" data-filter="completed">Completed</button>
408
+ </div>
409
+
410
+ <ul class="todo-list" id="todo-list">
411
+ <!-- Tasks will be injected here -->
412
+ </ul>
413
+
414
+ <div class="empty-state" id="empty-state">
415
+ <i class="fas fa-clipboard-check"></i>
416
+ <p>No tasks found. Add one above!</p>
417
+ </div>
418
+
419
+ <div class="footer-info">
420
+ <span id="items-left">0 items left</span>
421
+ <button class="clear-btn" id="clear-completed">Clear Completed</button>
422
+ </div>
423
+ </div>
424
+
425
+ <script>
426
+ // Selectors
427
+ const todoInput = document.getElementById('todo-input');
428
+ const addBtn = document.getElementById('add-btn');
429
+ const todoList = document.getElementById('todo-list');
430
+ const filterBtns = document.querySelectorAll('.filter-btn');
431
+ const itemsLeftSpan = document.getElementById('items-left');
432
+ const clearCompletedBtn = document.getElementById('clear-completed');
433
+ const emptyState = document.getElementById('empty-state');
434
+
435
+ // State
436
+ let todos = JSON.parse(localStorage.getItem('todos')) || [];
437
+ let currentFilter = 'all';
438
+
439
+ // Event Listeners
440
+ addBtn.addEventListener('click', addTodo);
441
+ todoInput.addEventListener('keypress', (e) => {
442
+ if (e.key === 'Enter') addTodo();
443
+ });
444
+
445
+ filterBtns.forEach(btn => {
446
+ btn.addEventListener('click', () => {
447
+ // Remove active class from all
448
+ filterBtns.forEach(b => b.classList.remove('active'));
449
+ // Add active to clicked
450
+ btn.classList.add('active');
451
+ currentFilter = btn.dataset.filter;
452
+ renderTodos();
453
+ });
454
+ });
455
+
456
+ clearCompletedBtn.addEventListener('click', clearCompleted);
457
+ todoList.addEventListener('click', deleteCheck);
458
+
459
+ // Initial Render
460
+ renderTodos();
461
+
462
+ // Functions
463
+ function addTodo() {
464
+ const todoText = todoInput.value.trim();
465
+
466
+ if (todoText === '') {
467
+ shakeInput();
468
+ return;
469
+ }
470
+
471
+ const newTodo = {
472
+ id: Date.now(),
473
+ text: todoText,
474
+ completed: false
475
+ };
476
+
477
+ todos.push(newTodo);
478
+ saveAndRender();
479
+ todoInput.value = '';
480
+ todoInput.focus();
481
+ }
482
+
483
+ function deleteCheck(e) {
484
+ const item = e.target;
485
+ const todoItem = item.closest('.todo-item');
486
+
487
+ // Delete
488
+ if (item.classList.contains('delete-btn') || item.parentElement.classList.contains('delete-btn')) {
489
+ const id = parseInt(todoItem.dataset.id);
490
+
491
+ // Add animation class before removing
492
+ todoItem.classList.add('fall');
493
+
494
+ // Remove from array after animation starts
495
+ setTimeout(() => {
496
+ todos = todos.filter(todo => todo.id !== id);
497
+ saveAndRender();
498
+ }, 300);
499
+ }
500
+
501
+ // Check Mark
502
+ if (item.classList.contains('checkbox-wrapper') || item.closest('.checkbox-wrapper')) {
503
+ const id = parseInt(todoItem.dataset.id);
504
+ const todo = todos.find(t => t.id === id);
505
+ if (todo) {
506
+ todo.completed = !todo.completed;
507
+ saveAndRender();
508
+ }
509
+ }
510
+ }
511
+
512
+ function setStatus(e) {
513
+ if (e.target.classList.contains('filter-btn')) {
514
+ currentFilter = e.target.dataset.filter;
515
+ renderTodos();
516
+ }
517
+ }
518
+
519
+ function clearCompleted() {
520
+ todos = todos.filter(todo => !todo.completed);
521
+ saveAndRender();
522
+ }
523
+
524
+ function saveAndRender() {
525
+ localStorage.setItem('todos', JSON.stringify(todos));
526
+ renderTodos();
527
+ }
528
+
529
+ function renderTodos() {
530
+ todoList.innerHTML = '';
531
+
532
+ // Filter logic
533
+ let filteredTodos = [];
534
+ if (currentFilter === 'all') {
535
+ filteredTodos = todos;
536
+ } else if (currentFilter === 'active') {
537
+ filteredTodos = todos.filter(todo => !todo.completed);
538
+ } else if (currentFilter === 'completed') {
539
+ filteredTodos = todos.filter(todo => todo.completed);
540
+ }
541
+
542
+ // Check empty state
543
+ if (filteredTodos.length === 0) {
544
+ emptyState.style.display = 'block';
545
+ } else {
546
+ emptyState.style.display = 'none';
547
+ }
548
+
549
+ // Update items left
550
+ const activeCount = todos.filter(t => !t.completed).length;
551
+ itemsLeftSpan.innerText = `${activeCount} item${activeCount !== 1 ? 's' : ''} left`;
552
+
553
+ // Generate HTML
554
+ filteredTodos.forEach(todo => {
555
+ const li = document.createElement('li');
556
+ li.classList.add('todo-item');
557
+ if (todo.completed) li.classList.add('completed');
558
+ li.dataset.id = todo.id;
559
+
560
+ li.innerHTML = `
561
+ <div class="checkbox-wrapper">
562
+ <input type="checkbox" ${todo.completed ? 'checked' : ''}>
563
+ <div class="custom-checkbox"></div>
564
+ </div>
565
+ <span class="todo-text">${escapeHtml(todo.text)}</span>
566
+ <button class="delete-btn"><i class="fas fa-trash"></i></button>
567
+ `;
568
+
569
+ todoList.appendChild(li);
570
+ });
571
+ }
572
+
573
+ // Utility: Prevent XSS
574
+ function escapeHtml(text) {
575
+ const map = {
576
+ '&': '&amp;',
577
+ '<': '&lt;',
578
+ '>': '&gt;',
579
+ '"': '&quot;',
580
+ "'": '&#039;'
581
+ };
582
+ return text.replace(/[&<>"']/g, (m) => map[m]);
583
+ }
584
+
585
+ // Utility: Shake animation for empty input
586
+ function shakeInput() {
587
+ todoInput.style.animation = 'none';
588
+ todoInput.offsetHeight; /* trigger reflow */
589
+ todoInput.style.animation = 'shake 0.5s';
590
+ todoInput.style.borderColor = 'var(--danger-color)';
591
+
592
+ setTimeout(() => {
593
+ todoInput.style.borderColor = 'transparent';
594
+ }, 2000);
595
+ }
596
+
597
+ // Inject keyframes dynamically
598
+ const styleSheet = document.createElement("style");
599
+ styleSheet.innerText = `
600
+ @keyframes shake {
601
+ 0% { transform: translateX(0); }
602
+ 25% { transform: translateX(-10px); }
603
+ 50% { transform: translateX(10px); }
604
+ 75% { transform: translateX(-10px); }
605
+ 100% { transform: translateX(0); }
606
+ }
607
+ `;
608
+ document.head.appendChild(styleSheet);
609
+
610
+ </script>
611
+ </body>
612
+ </html>