Sebbe33 commited on
Commit
3a7f3c4
·
verified ·
1 Parent(s): 031dfef

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +769 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Zenhabit
3
- emoji: 🐨
4
- colorFrom: gray
5
- colorTo: indigo
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: zenhabit
3
+ emoji: 🐳
4
+ colorFrom: blue
5
+ colorTo: blue
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,769 @@
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>ZenHabit | Minimal Habit Tracker</title>
7
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
8
+ <style>
9
+ :root {
10
+ --primary: #6366f1;
11
+ --primary-light: #818cf8;
12
+ --text: #1e293b;
13
+ --text-light: #64748b;
14
+ --bg: #f8fafc;
15
+ --card: #ffffff;
16
+ --border: #e2e8f0;
17
+ --shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
18
+ --success: #10b981;
19
+ --warning: #f59e0b;
20
+ --danger: #ef4444;
21
+ }
22
+
23
+ .dark-mode {
24
+ --primary: #818cf8;
25
+ --primary-light: #a5b4fc;
26
+ --text: #e2e8f0;
27
+ --text-light: #94a3b8;
28
+ --bg: #0f172a;
29
+ --card: #1e293b;
30
+ --border: #334155;
31
+ --shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
32
+ }
33
+
34
+ * {
35
+ margin: 0;
36
+ padding: 0;
37
+ box-sizing: border-box;
38
+ transition: background-color 0.3s, color 0.3s;
39
+ }
40
+
41
+ body {
42
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
43
+ background-color: var(--bg);
44
+ color: var(--text);
45
+ line-height: 1.6;
46
+ }
47
+
48
+ .container {
49
+ max-width: 800px;
50
+ margin: 0 auto;
51
+ padding: 2rem;
52
+ }
53
+
54
+ header {
55
+ display: flex;
56
+ justify-content: space-between;
57
+ align-items: center;
58
+ margin-bottom: 2rem;
59
+ }
60
+
61
+ h1 {
62
+ font-size: 1.8rem;
63
+ font-weight: 700;
64
+ color: var(--primary);
65
+ display: flex;
66
+ align-items: center;
67
+ gap: 0.5rem;
68
+ }
69
+
70
+ .theme-toggle {
71
+ background: none;
72
+ border: none;
73
+ color: var(--text-light);
74
+ font-size: 1.2rem;
75
+ cursor: pointer;
76
+ transition: transform 0.3s;
77
+ }
78
+
79
+ .theme-toggle:hover {
80
+ transform: rotate(30deg);
81
+ color: var(--primary);
82
+ }
83
+
84
+ .stats {
85
+ display: grid;
86
+ grid-template-columns: repeat(3, 1fr);
87
+ gap: 1rem;
88
+ margin-bottom: 2rem;
89
+ }
90
+
91
+ .stat-card {
92
+ background-color: var(--card);
93
+ border-radius: 0.5rem;
94
+ padding: 1rem;
95
+ box-shadow: var(--shadow);
96
+ text-align: center;
97
+ }
98
+
99
+ .stat-card h3 {
100
+ font-size: 0.9rem;
101
+ color: var(--text-light);
102
+ margin-bottom: 0.5rem;
103
+ }
104
+
105
+ .stat-card p {
106
+ font-size: 1.5rem;
107
+ font-weight: 700;
108
+ color: var(--primary);
109
+ }
110
+
111
+ .habits {
112
+ margin-bottom: 2rem;
113
+ }
114
+
115
+ .habits-header {
116
+ display: flex;
117
+ justify-content: space-between;
118
+ align-items: center;
119
+ margin-bottom: 1rem;
120
+ }
121
+
122
+ .habits-header h2 {
123
+ font-size: 1.3rem;
124
+ }
125
+
126
+ .add-habit {
127
+ background-color: var(--primary);
128
+ color: white;
129
+ border: none;
130
+ border-radius: 0.3rem;
131
+ padding: 0.5rem 1rem;
132
+ font-size: 0.9rem;
133
+ cursor: pointer;
134
+ display: flex;
135
+ align-items: center;
136
+ gap: 0.5rem;
137
+ transition: background-color 0.3s;
138
+ }
139
+
140
+ .add-habit:hover {
141
+ background-color: var(--primary-light);
142
+ }
143
+
144
+ .habit-list {
145
+ display: flex;
146
+ flex-direction: column;
147
+ gap: 0.5rem;
148
+ }
149
+
150
+ .habit-item {
151
+ background-color: var(--card);
152
+ border-radius: 0.5rem;
153
+ padding: 1rem;
154
+ box-shadow: var(--shadow);
155
+ display: flex;
156
+ align-items: center;
157
+ gap: 1rem;
158
+ position: relative;
159
+ overflow: hidden;
160
+ }
161
+
162
+ .habit-item::before {
163
+ content: '';
164
+ position: absolute;
165
+ top: 0;
166
+ left: 0;
167
+ height: 100%;
168
+ width: 0.3rem;
169
+ background-color: var(--primary);
170
+ }
171
+
172
+ .habit-check {
173
+ width: 1.5rem;
174
+ height: 1.5rem;
175
+ border: 2px solid var(--border);
176
+ border-radius: 0.3rem;
177
+ cursor: pointer;
178
+ display: flex;
179
+ align-items: center;
180
+ justify-content: center;
181
+ transition: all 0.3s;
182
+ }
183
+
184
+ .habit-check.checked {
185
+ background-color: var(--primary);
186
+ border-color: var(--primary);
187
+ color: white;
188
+ }
189
+
190
+ .habit-info {
191
+ flex: 1;
192
+ }
193
+
194
+ .habit-name {
195
+ font-weight: 600;
196
+ margin-bottom: 0.2rem;
197
+ }
198
+
199
+ .habit-streak {
200
+ font-size: 0.8rem;
201
+ color: var(--text-light);
202
+ display: flex;
203
+ align-items: center;
204
+ gap: 0.3rem;
205
+ }
206
+
207
+ .habit-streak i {
208
+ color: var(--warning);
209
+ }
210
+
211
+ .habit-progress {
212
+ width: 100px;
213
+ height: 0.3rem;
214
+ background-color: var(--border);
215
+ border-radius: 1rem;
216
+ overflow: hidden;
217
+ }
218
+
219
+ .progress-bar {
220
+ height: 100%;
221
+ background-color: var(--primary);
222
+ border-radius: 1rem;
223
+ transition: width 0.5s ease;
224
+ }
225
+
226
+ .calendar {
227
+ background-color: var(--card);
228
+ border-radius: 0.5rem;
229
+ padding: 1rem;
230
+ box-shadow: var(--shadow);
231
+ }
232
+
233
+ .calendar-header {
234
+ display: flex;
235
+ justify-content: space-between;
236
+ align-items: center;
237
+ margin-bottom: 1rem;
238
+ }
239
+
240
+ .calendar-nav {
241
+ display: flex;
242
+ gap: 1rem;
243
+ }
244
+
245
+ .calendar-nav button {
246
+ background: none;
247
+ border: none;
248
+ color: var(--text-light);
249
+ cursor: pointer;
250
+ font-size: 1rem;
251
+ }
252
+
253
+ .calendar-nav button:hover {
254
+ color: var(--primary);
255
+ }
256
+
257
+ .calendar-grid {
258
+ display: grid;
259
+ grid-template-columns: repeat(7, 1fr);
260
+ gap: 0.5rem;
261
+ }
262
+
263
+ .calendar-day-header {
264
+ text-align: center;
265
+ font-size: 0.8rem;
266
+ color: var(--text-light);
267
+ padding: 0.5rem 0;
268
+ }
269
+
270
+ .calendar-day {
271
+ aspect-ratio: 1;
272
+ display: flex;
273
+ flex-direction: column;
274
+ align-items: center;
275
+ justify-content: center;
276
+ border-radius: 0.3rem;
277
+ cursor: pointer;
278
+ position: relative;
279
+ }
280
+
281
+ .calendar-day:hover {
282
+ background-color: var(--border);
283
+ }
284
+
285
+ .calendar-day.today {
286
+ background-color: var(--primary);
287
+ color: white;
288
+ }
289
+
290
+ .day-number {
291
+ font-size: 0.9rem;
292
+ font-weight: 500;
293
+ }
294
+
295
+ .day-habits {
296
+ position: absolute;
297
+ bottom: 0.2rem;
298
+ display: flex;
299
+ gap: 0.2rem;
300
+ }
301
+
302
+ .day-habit-dot {
303
+ width: 0.3rem;
304
+ height: 0.3rem;
305
+ border-radius: 50%;
306
+ background-color: var(--success);
307
+ }
308
+
309
+ .modal {
310
+ position: fixed;
311
+ top: 0;
312
+ left: 0;
313
+ width: 100%;
314
+ height: 100%;
315
+ background-color: rgba(0, 0, 0, 0.5);
316
+ display: flex;
317
+ align-items: center;
318
+ justify-content: center;
319
+ z-index: 1000;
320
+ opacity: 0;
321
+ pointer-events: none;
322
+ transition: opacity 0.3s;
323
+ }
324
+
325
+ .modal.active {
326
+ opacity: 1;
327
+ pointer-events: all;
328
+ }
329
+
330
+ .modal-content {
331
+ background-color: var(--card);
332
+ border-radius: 0.5rem;
333
+ padding: 1.5rem;
334
+ width: 90%;
335
+ max-width: 400px;
336
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
337
+ transform: translateY(-20px);
338
+ transition: transform 0.3s;
339
+ }
340
+
341
+ .modal.active .modal-content {
342
+ transform: translateY(0);
343
+ }
344
+
345
+ .modal-header {
346
+ display: flex;
347
+ justify-content: space-between;
348
+ align-items: center;
349
+ margin-bottom: 1rem;
350
+ }
351
+
352
+ .modal-header h3 {
353
+ font-size: 1.2rem;
354
+ }
355
+
356
+ .close-modal {
357
+ background: none;
358
+ border: none;
359
+ font-size: 1.2rem;
360
+ color: var(--text-light);
361
+ cursor: pointer;
362
+ }
363
+
364
+ .form-group {
365
+ margin-bottom: 1rem;
366
+ }
367
+
368
+ .form-group label {
369
+ display: block;
370
+ margin-bottom: 0.5rem;
371
+ font-size: 0.9rem;
372
+ color: var(--text-light);
373
+ }
374
+
375
+ .form-group input,
376
+ .form-group select {
377
+ width: 100%;
378
+ padding: 0.5rem;
379
+ border: 1px solid var(--border);
380
+ border-radius: 0.3rem;
381
+ background-color: var(--bg);
382
+ color: var(--text);
383
+ }
384
+
385
+ .modal-actions {
386
+ display: flex;
387
+ justify-content: flex-end;
388
+ gap: 0.5rem;
389
+ margin-top: 1rem;
390
+ }
391
+
392
+ .btn {
393
+ padding: 0.5rem 1rem;
394
+ border-radius: 0.3rem;
395
+ cursor: pointer;
396
+ font-size: 0.9rem;
397
+ border: none;
398
+ transition: background-color 0.3s;
399
+ }
400
+
401
+ .btn-primary {
402
+ background-color: var(--primary);
403
+ color: white;
404
+ }
405
+
406
+ .btn-primary:hover {
407
+ background-color: var(--primary-light);
408
+ }
409
+
410
+ .btn-secondary {
411
+ background-color: var(--border);
412
+ color: var(--text);
413
+ }
414
+
415
+ .btn-secondary:hover {
416
+ background-color: #d1d5db;
417
+ }
418
+
419
+ @media (max-width: 600px) {
420
+ .stats {
421
+ grid-template-columns: 1fr;
422
+ }
423
+
424
+ .container {
425
+ padding: 1rem;
426
+ }
427
+ }
428
+
429
+ /* Animation for habit completion */
430
+ @keyframes pulse {
431
+ 0% { transform: scale(1); }
432
+ 50% { transform: scale(1.1); }
433
+ 100% { transform: scale(1); }
434
+ }
435
+
436
+ .habit-check.checked {
437
+ animation: pulse 0.3s ease;
438
+ }
439
+ </style>
440
+ </head>
441
+ <body>
442
+ <div class="container">
443
+ <header>
444
+ <h1><i class="fas fa-leaf"></i> ZenHabit</h1>
445
+ <button class="theme-toggle" id="themeToggle">
446
+ <i class="fas fa-moon"></i>
447
+ </button>
448
+ </header>
449
+
450
+ <div class="stats">
451
+ <div class="stat-card">
452
+ <h3>Current Streak</h3>
453
+ <p id="currentStreak">5</p>
454
+ </div>
455
+ <div class="stat-card">
456
+ <h3>Habits Tracked</h3>
457
+ <p id="habitsTracked">8</p>
458
+ </div>
459
+ <div class="stat-card">
460
+ <h3>Completion Rate</h3>
461
+ <p id="completionRate">72%</p>
462
+ </div>
463
+ </div>
464
+
465
+ <div class="habits">
466
+ <div class="habits-header">
467
+ <h2>Today's Habits</h2>
468
+ <button class="add-habit" id="addHabitBtn">
469
+ <i class="fas fa-plus"></i> Add Habit
470
+ </button>
471
+ </div>
472
+ <div class="habit-list" id="habitList">
473
+ <!-- Habit items will be added here by JavaScript -->
474
+ </div>
475
+ </div>
476
+
477
+ <div class="calendar">
478
+ <div class="calendar-header">
479
+ <h3 id="currentMonth">June 2023</h3>
480
+ <div class="calendar-nav">
481
+ <button id="prevMonth"><i class="fas fa-chevron-left"></i></button>
482
+ <button id="nextMonth"><i class="fas fa-chevron-right"></i></button>
483
+ </div>
484
+ </div>
485
+ <div class="calendar-grid" id="calendarGrid">
486
+ <!-- Calendar days will be added here by JavaScript -->
487
+ </div>
488
+ </div>
489
+ </div>
490
+
491
+ <!-- Add Habit Modal -->
492
+ <div class="modal" id="addHabitModal">
493
+ <div class="modal-content">
494
+ <div class="modal-header">
495
+ <h3>Add New Habit</h3>
496
+ <button class="close-modal" id="closeModal">&times;</button>
497
+ </div>
498
+ <form id="habitForm">
499
+ <div class="form-group">
500
+ <label for="habitName">Habit Name</label>
501
+ <input type="text" id="habitName" placeholder="e.g. Drink water" required>
502
+ </div>
503
+ <div class="form-group">
504
+ <label for="habitFrequency">Frequency</label>
505
+ <select id="habitFrequency" required>
506
+ <option value="daily">Daily</option>
507
+ <option value="weekly">Weekly</option>
508
+ <option value="monthly">Monthly</option>
509
+ </select>
510
+ </div>
511
+ <div class="modal-actions">
512
+ <button type="button" class="btn btn-secondary" id="cancelHabit">Cancel</button>
513
+ <button type="submit" class="btn btn-primary">Add Habit</button>
514
+ </div>
515
+ </form>
516
+ </div>
517
+ </div>
518
+
519
+ <script>
520
+ // Sample data
521
+ let habits = [
522
+ { id: 1, name: "Morning Meditation", streak: 7, frequency: "daily", progress: 85, checked: false },
523
+ { id: 2, name: "Drink 2L water", streak: 14, frequency: "daily", progress: 60, checked: true },
524
+ { id: 3, name: "Read 30 minutes", streak: 21, frequency: "daily", progress: 90, checked: false },
525
+ { id: 4, name: "Workout", streak: 5, frequency: "weekly", progress: 75, checked: false },
526
+ { id: 5, name: "Journaling", streak: 10, frequency: "daily", progress: 50, checked: true }
527
+ ];
528
+
529
+ // DOM elements
530
+ const themeToggle = document.getElementById('themeToggle');
531
+ const addHabitBtn = document.getElementById('addHabitBtn');
532
+ const addHabitModal = document.getElementById('addHabitModal');
533
+ const closeModal = document.getElementById('closeModal');
534
+ const cancelHabit = document.getElementById('cancelHabit');
535
+ const habitForm = document.getElementById('habitForm');
536
+ const habitList = document.getElementById('habitList');
537
+ const currentStreak = document.getElementById('currentStreak');
538
+ const habitsTracked = document.getElementById('habitsTracked');
539
+ const completionRate = document.getElementById('completionRate');
540
+ const currentMonth = document.getElementById('currentMonth');
541
+ const calendarGrid = document.getElementById('calendarGrid');
542
+ const prevMonthBtn = document.getElementById('prevMonth');
543
+ const nextMonthBtn = document.getElementById('nextMonth');
544
+
545
+ // Current date
546
+ let currentDate = new Date();
547
+ let currentYear = currentDate.getFullYear();
548
+ let currentMonthIndex = currentDate.getMonth();
549
+
550
+ // Initialize
551
+ document.addEventListener('DOMContentLoaded', () => {
552
+ renderHabits();
553
+ renderCalendar();
554
+ updateStats();
555
+
556
+ // Check for saved theme preference
557
+ if (localStorage.getItem('theme') === 'dark') {
558
+ document.body.classList.add('dark-mode');
559
+ themeToggle.innerHTML = '<i class="fas fa-sun"></i>';
560
+ }
561
+ });
562
+
563
+ // Theme toggle
564
+ themeToggle.addEventListener('click', () => {
565
+ document.body.classList.toggle('dark-mode');
566
+ if (document.body.classList.contains('dark-mode')) {
567
+ localStorage.setItem('theme', 'dark');
568
+ themeToggle.innerHTML = '<i class="fas fa-sun"></i>';
569
+ } else {
570
+ localStorage.setItem('theme', 'light');
571
+ themeToggle.innerHTML = '<i class="fas fa-moon"></i>';
572
+ }
573
+ });
574
+
575
+ // Modal controls
576
+ addHabitBtn.addEventListener('click', () => {
577
+ addHabitModal.classList.add('active');
578
+ });
579
+
580
+ closeModal.addEventListener('click', () => {
581
+ addHabitModal.classList.remove('active');
582
+ });
583
+
584
+ cancelHabit.addEventListener('click', () => {
585
+ addHabitModal.classList.remove('active');
586
+ });
587
+
588
+ // Add new habit
589
+ habitForm.addEventListener('submit', (e) => {
590
+ e.preventDefault();
591
+
592
+ const name = document.getElementById('habitName').value;
593
+ const frequency = document.getElementById('habitFrequency').value;
594
+
595
+ const newHabit = {
596
+ id: habits.length + 1,
597
+ name: name,
598
+ streak: 0,
599
+ frequency: frequency,
600
+ progress: 0,
601
+ checked: false
602
+ };
603
+
604
+ habits.push(newHabit);
605
+ renderHabits();
606
+ updateStats();
607
+ renderCalendar();
608
+
609
+ // Reset form and close modal
610
+ habitForm.reset();
611
+ addHabitModal.classList.remove('active');
612
+ });
613
+
614
+ // Render habits list
615
+ function renderHabits() {
616
+ habitList.innerHTML = '';
617
+
618
+ habits.forEach(habit => {
619
+ const habitItem = document.createElement('div');
620
+ habitItem.className = 'habit-item';
621
+
622
+ habitItem.innerHTML = `
623
+ <div class="habit-check ${habit.checked ? 'checked' : ''}" data-id="${habit.id}">
624
+ ${habit.checked ? '<i class="fas fa-check"></i>' : ''}
625
+ </div>
626
+ <div class="habit-info">
627
+ <div class="habit-name">${habit.name}</div>
628
+ <div class="habit-streak">
629
+ <i class="fas fa-fire"></i> ${habit.streak} day streak
630
+ </div>
631
+ </div>
632
+ <div class="habit-progress">
633
+ <div class="progress-bar" style="width: ${habit.progress}%"></div>
634
+ </div>
635
+ `;
636
+
637
+ habitList.appendChild(habitItem);
638
+ });
639
+
640
+ // Add event listeners to checkboxes
641
+ document.querySelectorAll('.habit-check').forEach(checkbox => {
642
+ checkbox.addEventListener('click', function() {
643
+ const habitId = parseInt(this.getAttribute('data-id'));
644
+ const habit = habits.find(h => h.id === habitId);
645
+
646
+ habit.checked = !habit.checked;
647
+
648
+ if (habit.checked) {
649
+ habit.streak += 1;
650
+ habit.progress = Math.min(habit.progress + 20, 100);
651
+ } else {
652
+ habit.streak = Math.max(habit.streak - 1, 0);
653
+ habit.progress = Math.max(habit.progress - 20, 0);
654
+ }
655
+
656
+ renderHabits();
657
+ updateStats();
658
+ });
659
+ });
660
+ }
661
+
662
+ // Update stats
663
+ function updateStats() {
664
+ const totalHabits = habits.length;
665
+ const completedHabits = habits.filter(h => h.checked).length;
666
+ const completionPercentage = Math.round((completedHabits / totalHabits) * 100);
667
+
668
+ // Find the longest streak
669
+ const longestStreak = habits.reduce((max, habit) => Math.max(max, habit.streak), 0);
670
+
671
+ currentStreak.textContent = longestStreak;
672
+ habitsTracked.textContent = totalHabits;
673
+ completionRate.textContent = `${completionPercentage}%`;
674
+ }
675
+
676
+ // Calendar functions
677
+ function renderCalendar() {
678
+ // Clear previous calendar
679
+ calendarGrid.innerHTML = '';
680
+
681
+ // Set month and year display
682
+ const monthNames = ["January", "February", "March", "April", "May", "June",
683
+ "July", "August", "September", "October", "November", "December"];
684
+ currentMonth.textContent = `${monthNames[currentMonthIndex]} ${currentYear}`;
685
+
686
+ // Get first day of month and total days in month
687
+ const firstDay = new Date(currentYear, currentMonthIndex, 1).getDay();
688
+ const daysInMonth = new Date(currentYear, currentMonthIndex + 1, 0).getDate();
689
+
690
+ // Add day headers
691
+ const dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
692
+ dayNames.forEach(day => {
693
+ const dayHeader = document.createElement('div');
694
+ dayHeader.className = 'calendar-day-header';
695
+ dayHeader.textContent = day;
696
+ calendarGrid.appendChild(dayHeader);
697
+ });
698
+
699
+ // Add empty cells for days before the first day of the month
700
+ for (let i = 0; i < firstDay; i++) {
701
+ const emptyDay = document.createElement('div');
702
+ emptyDay.className = 'calendar-day';
703
+ calendarGrid.appendChild(emptyDay);
704
+ }
705
+
706
+ // Add days of the month
707
+ for (let i = 1; i <= daysInMonth; i++) {
708
+ const dayElement = document.createElement('div');
709
+ dayElement.className = 'calendar-day';
710
+
711
+ // Check if this is today
712
+ const today = new Date();
713
+ if (i === today.getDate() && currentMonthIndex === today.getMonth() && currentYear === today.getFullYear()) {
714
+ dayElement.classList.add('today');
715
+ }
716
+
717
+ // Add day number
718
+ const dayNumber = document.createElement('div');
719
+ dayNumber.className = 'day-number';
720
+ dayNumber.textContent = i;
721
+ dayElement.appendChild(dayNumber);
722
+
723
+ // Add habit dots (sample - in a real app, this would come from your data)
724
+ const habitsCompleted = Math.floor(Math.random() * 3); // Random for demo
725
+ if (habitsCompleted > 0) {
726
+ const dayHabits = document.createElement('div');
727
+ dayHabits.className = 'day-habits';
728
+
729
+ for (let j = 0; j < habitsCompleted; j++) {
730
+ const habitDot = document.createElement('div');
731
+ habitDot.className = 'day-habit-dot';
732
+ dayHabits.appendChild(habitDot);
733
+ }
734
+
735
+ dayElement.appendChild(dayHabits);
736
+ }
737
+
738
+ calendarGrid.appendChild(dayElement);
739
+ }
740
+ }
741
+
742
+ // Month navigation
743
+ prevMonthBtn.addEventListener('click', () => {
744
+ currentMonthIndex--;
745
+ if (currentMonthIndex < 0) {
746
+ currentMonthIndex = 11;
747
+ currentYear--;
748
+ }
749
+ renderCalendar();
750
+ });
751
+
752
+ nextMonthBtn.addEventListener('click', () => {
753
+ currentMonthIndex++;
754
+ if (currentMonthIndex > 11) {
755
+ currentMonthIndex = 0;
756
+ currentYear++;
757
+ }
758
+ renderCalendar();
759
+ });
760
+
761
+ // Close modal when clicking outside
762
+ window.addEventListener('click', (e) => {
763
+ if (e.target === addHabitModal) {
764
+ addHabitModal.classList.remove('active');
765
+ }
766
+ });
767
+ </script>
768
+ <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 <a href="https://enzostvs-deepsite.hf.space" style="color: #fff;" target="_blank" >DeepSite</a> <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;"></p></body>
769
+ </html>