mannadamay12 commited on
Commit
735cb23
·
verified ·
1 Parent(s): 9b2306b

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +750 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Copd Medication Tracker
3
- emoji: 👀
4
- colorFrom: indigo
5
- colorTo: gray
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: copd-medication-tracker
3
+ emoji: 🐳
4
+ colorFrom: yellow
5
+ colorTo: purple
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,750 @@
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>COPD Medication Tracker</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
+ @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
11
+
12
+ body {
13
+ font-family: 'Poppins', sans-serif;
14
+ background-color: #f0f9ff;
15
+ }
16
+
17
+ .medication-card {
18
+ transition: all 0.3s ease;
19
+ }
20
+
21
+ .medication-card:hover {
22
+ transform: translateY(-3px);
23
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
24
+ }
25
+
26
+ .progress-bar {
27
+ height: 8px;
28
+ border-radius: 4px;
29
+ background-color: #e0f2fe;
30
+ }
31
+
32
+ .progress-fill {
33
+ height: 100%;
34
+ border-radius: 4px;
35
+ background-color: #0ea5e9;
36
+ transition: width 0.5s ease;
37
+ }
38
+
39
+ .notification-badge {
40
+ position: absolute;
41
+ top: -8px;
42
+ right: -8px;
43
+ width: 20px;
44
+ height: 20px;
45
+ border-radius: 50%;
46
+ background-color: #ef4444;
47
+ color: white;
48
+ display: flex;
49
+ align-items: center;
50
+ justify-content: center;
51
+ font-size: 12px;
52
+ }
53
+
54
+ .modal {
55
+ transition: opacity 0.3s ease, transform 0.3s ease;
56
+ }
57
+
58
+ .modal-enter {
59
+ opacity: 0;
60
+ transform: translateY(-20px);
61
+ }
62
+
63
+ .modal-enter-active {
64
+ opacity: 1;
65
+ transform: translateY(0);
66
+ }
67
+ </style>
68
+ </head>
69
+ <body class="min-h-screen">
70
+ <div class="container mx-auto px-4 py-8 max-w-6xl">
71
+ <!-- Header -->
72
+ <header class="flex justify-between items-center mb-8">
73
+ <div>
74
+ <h1 class="text-3xl font-bold text-sky-900">COPD Care</h1>
75
+ <p class="text-sky-700">Medication Tracker</p>
76
+ </div>
77
+ <div class="relative">
78
+ <button id="notificationBtn" class="p-2 rounded-full bg-sky-100 text-sky-700 hover:bg-sky-200 transition">
79
+ <i class="fas fa-bell"></i>
80
+ <div id="notificationCount" class="notification-badge hidden">3</div>
81
+ </button>
82
+ </div>
83
+ </header>
84
+
85
+ <!-- Stats Overview -->
86
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-8">
87
+ <div class="bg-white rounded-xl p-6 shadow-sm">
88
+ <div class="flex items-center">
89
+ <div class="p-3 rounded-full bg-green-100 text-green-600 mr-4">
90
+ <i class="fas fa-check-circle text-xl"></i>
91
+ </div>
92
+ <div>
93
+ <p class="text-gray-500">Today's Taken</p>
94
+ <h3 class="text-2xl font-bold" id="takenToday">0</h3>
95
+ </div>
96
+ </div>
97
+ </div>
98
+ <div class="bg-white rounded-xl p-6 shadow-sm">
99
+ <div class="flex items-center">
100
+ <div class="p-3 rounded-full bg-yellow-100 text-yellow-600 mr-4">
101
+ <i class="fas fa-clock text-xl"></i>
102
+ </div>
103
+ <div>
104
+ <p class="text-gray-500">Pending</p>
105
+ <h3 class="text-2xl font-bold" id="pendingToday">0</h3>
106
+ </div>
107
+ </div>
108
+ </div>
109
+ <div class="bg-white rounded-xl p-6 shadow-sm">
110
+ <div class="flex items-center">
111
+ <div class="p-3 rounded-full bg-red-100 text-red-600 mr-4">
112
+ <i class="fas fa-times-circle text-xl"></i>
113
+ </div>
114
+ <div>
115
+ <p class="text-gray-500">Missed</p>
116
+ <h3 class="text-2xl font-bold" id="missedToday">0</h3>
117
+ </div>
118
+ </div>
119
+ </div>
120
+ </div>
121
+
122
+ <!-- Today's Medications -->
123
+ <div class="mb-8">
124
+ <div class="flex justify-between items-center mb-4">
125
+ <h2 class="text-xl font-semibold text-sky-900">Today's Medications</h2>
126
+ <div class="text-sm text-gray-500" id="currentDate"></div>
127
+ </div>
128
+
129
+ <div id="todaysMeds" class="space-y-4">
130
+ <!-- Medications will be added here by JavaScript -->
131
+ </div>
132
+ </div>
133
+
134
+ <!-- All Medications -->
135
+ <div class="mb-8">
136
+ <div class="flex justify-between items-center mb-4">
137
+ <h2 class="text-xl font-semibold text-sky-900">Your Medications</h2>
138
+ <button id="addMedBtn" class="px-4 py-2 bg-sky-600 text-white rounded-lg hover:bg-sky-700 transition flex items-center">
139
+ <i class="fas fa-plus mr-2"></i> Add Medication
140
+ </button>
141
+ </div>
142
+
143
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4" id="allMeds">
144
+ <!-- Medications will be added here by JavaScript -->
145
+ </div>
146
+ </div>
147
+
148
+ <!-- Progress -->
149
+ <div class="bg-white rounded-xl p-6 shadow-sm mb-8">
150
+ <h2 class="text-xl font-semibold text-sky-900 mb-4">This Week's Progress</h2>
151
+ <div class="progress-bar mb-2">
152
+ <div class="progress-fill" style="width: 75%"></div>
153
+ </div>
154
+ <div class="flex justify-between text-sm text-gray-600">
155
+ <span>75% adherence</span>
156
+ <span>7 of 9 doses taken</span>
157
+ </div>
158
+ </div>
159
+ </div>
160
+
161
+ <!-- Add Medication Modal -->
162
+ <div id="medModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden modal">
163
+ <div class="bg-white rounded-xl p-6 w-full max-w-md">
164
+ <div class="flex justify-between items-center mb-4">
165
+ <h3 class="text-xl font-semibold text-sky-900">Add New Medication</h3>
166
+ <button id="closeModalBtn" class="text-gray-500 hover:text-gray-700">
167
+ <i class="fas fa-times"></i>
168
+ </button>
169
+ </div>
170
+
171
+ <form id="medForm" class="space-y-4">
172
+ <div>
173
+ <label for="medName" class="block text-sm font-medium text-gray-700 mb-1">Medication Name</label>
174
+ <input type="text" id="medName" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-sky-500 focus:border-sky-500" placeholder="e.g., Spiriva, Advair">
175
+ </div>
176
+
177
+ <div>
178
+ <label for="medType" class="block text-sm font-medium text-gray-700 mb-1">Type</label>
179
+ <select id="medType" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-sky-500 focus:border-sky-500">
180
+ <option value="inhaler">Inhaler</option>
181
+ <option value="tablet">Tablet</option>
182
+ <option value="capsule">Capsule</option>
183
+ <option value="liquid">Liquid</option>
184
+ <option value="injection">Injection</option>
185
+ </select>
186
+ </div>
187
+
188
+ <div>
189
+ <label for="medDosage" class="block text-sm font-medium text-gray-700 mb-1">Dosage</label>
190
+ <input type="text" id="medDosage" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-sky-500 focus:border-sky-500" placeholder="e.g., 250mcg, 10mg">
191
+ </div>
192
+
193
+ <div>
194
+ <label for="medFrequency" class="block text-sm font-medium text-gray-700 mb-1">Frequency</label>
195
+ <select id="medFrequency" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-sky-500 focus:border-sky-500">
196
+ <option value="once">Once daily</option>
197
+ <option value="twice">Twice daily</option>
198
+ <option value="three">Three times daily</option>
199
+ <option value="four">Four times daily</option>
200
+ <option value="as_needed">As needed</option>
201
+ </select>
202
+ </div>
203
+
204
+ <div>
205
+ <label for="medTimes" class="block text-sm font-medium text-gray-700 mb-1">Times</label>
206
+ <div class="space-y-2" id="timeInputs">
207
+ <div class="flex items-center">
208
+ <input type="time" class="px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-sky-500 focus:border-sky-500" value="08:00">
209
+ <button type="button" class="ml-2 text-red-500 hover:text-red-700">
210
+ <i class="fas fa-times"></i>
211
+ </button>
212
+ </div>
213
+ </div>
214
+ <button type="button" id="addTimeBtn" class="mt-2 text-sm text-sky-600 hover:text-sky-800 flex items-center">
215
+ <i class="fas fa-plus mr-1"></i> Add another time
216
+ </button>
217
+ </div>
218
+
219
+ <div>
220
+ <label for="medNotes" class="block text-sm font-medium text-gray-700 mb-1">Notes</label>
221
+ <textarea id="medNotes" rows="3" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-sky-500 focus:border-sky-500" placeholder="Special instructions..."></textarea>
222
+ </div>
223
+
224
+ <div class="flex justify-end space-x-3 pt-4">
225
+ <button type="button" id="cancelMedBtn" class="px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-100">Cancel</button>
226
+ <button type="submit" class="px-4 py-2 bg-sky-600 text-white rounded-lg hover:bg-sky-700">Save Medication</button>
227
+ </div>
228
+ </form>
229
+ </div>
230
+ </div>
231
+
232
+ <!-- Notification Modal -->
233
+ <div id="notificationModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
234
+ <div class="bg-white rounded-xl p-6 w-full max-w-md">
235
+ <div class="flex justify-between items-center mb-4">
236
+ <h3 class="text-xl font-semibold text-sky-900">Notifications</h3>
237
+ <button id="closeNotifModalBtn" class="text-gray-500 hover:text-gray-700">
238
+ <i class="fas fa-times"></i>
239
+ </button>
240
+ </div>
241
+
242
+ <div class="space-y-3 max-h-96 overflow-y-auto" id="notificationList">
243
+ <div class="p-3 bg-blue-50 rounded-lg border border-blue-100">
244
+ <div class="flex justify-between">
245
+ <p class="font-medium text-blue-800">Medication Reminder</p>
246
+ <span class="text-xs text-blue-600">10 min ago</span>
247
+ </div>
248
+ <p class="text-sm text-blue-700">Time to take your Spiriva inhaler</p>
249
+ </div>
250
+
251
+ <div class="p-3 bg-yellow-50 rounded-lg border border-yellow-100">
252
+ <div class="flex justify-between">
253
+ <p class="font-medium text-yellow-800">Refill Reminder</p>
254
+ <span class="text-xs text-yellow-600">2 days ago</span>
255
+ </div>
256
+ <p class="text-sm text-yellow-700">Your Advair inhaler is running low</p>
257
+ </div>
258
+
259
+ <div class="p-3 bg-red-50 rounded-lg border border-red-100">
260
+ <div class="flex justify-between">
261
+ <p class="font-medium text-red-800">Missed Dose</p>
262
+ <span class="text-xs text-red-600">Yesterday</span>
263
+ </div>
264
+ <p class="text-sm text-red-700">You missed your morning dose of Prednisone</p>
265
+ </div>
266
+ </div>
267
+
268
+ <div class="flex justify-end pt-4">
269
+ <button id="clearNotifBtn" class="px-4 py-2 text-sm text-gray-600 hover:text-gray-800">Clear All</button>
270
+ </div>
271
+ </div>
272
+ </div>
273
+
274
+ <script>
275
+ // Sample medication data
276
+ const medications = [
277
+ {
278
+ id: 1,
279
+ name: "Spiriva",
280
+ type: "inhaler",
281
+ dosage: "18mcg",
282
+ frequency: "once",
283
+ times: ["08:00"],
284
+ notes: "Take before breakfast",
285
+ taken: ["2023-06-15T08:00:00"],
286
+ color: "bg-blue-100",
287
+ icon: "fa-inhaler",
288
+ todayStatus: { taken: true, time: "08:00" }
289
+ },
290
+ {
291
+ id: 2,
292
+ name: "Advair",
293
+ type: "inhaler",
294
+ dosage: "250/50mcg",
295
+ frequency: "twice",
296
+ times: ["08:00", "20:00"],
297
+ notes: "Rinse mouth after use",
298
+ taken: ["2023-06-15T08:05:00"],
299
+ color: "bg-green-100",
300
+ icon: "fa-inhaler",
301
+ todayStatus: { taken: true, time: "08:00" }
302
+ },
303
+ {
304
+ id: 3,
305
+ name: "Prednisone",
306
+ type: "tablet",
307
+ dosage: "10mg",
308
+ frequency: "once",
309
+ times: ["07:00"],
310
+ notes: "Take with food",
311
+ taken: [],
312
+ color: "bg-purple-100",
313
+ icon: "fa-pills",
314
+ todayStatus: { taken: false, time: "07:00" }
315
+ },
316
+ {
317
+ id: 4,
318
+ name: "Albuterol",
319
+ type: "inhaler",
320
+ dosage: "90mcg",
321
+ frequency: "as_needed",
322
+ times: [],
323
+ notes: "Use for shortness of breath",
324
+ taken: [],
325
+ color: "bg-red-100",
326
+ icon: "fa-inhaler",
327
+ todayStatus: null
328
+ }
329
+ ];
330
+
331
+ // DOM elements
332
+ const currentDateEl = document.getElementById('currentDate');
333
+ const todaysMedsEl = document.getElementById('todaysMeds');
334
+ const allMedsEl = document.getElementById('allMeds');
335
+ const takenTodayEl = document.getElementById('takenToday');
336
+ const pendingTodayEl = document.getElementById('pendingToday');
337
+ const missedTodayEl = document.getElementById('missedToday');
338
+ const medModal = document.getElementById('medModal');
339
+ const addMedBtn = document.getElementById('addMedBtn');
340
+ const closeModalBtn = document.getElementById('closeModalBtn');
341
+ const cancelMedBtn = document.getElementById('cancelMedBtn');
342
+ const medForm = document.getElementById('medForm');
343
+ const timeInputs = document.getElementById('timeInputs');
344
+ const addTimeBtn = document.getElementById('addTimeBtn');
345
+ const notificationBtn = document.getElementById('notificationBtn');
346
+ const notificationModal = document.getElementById('notificationModal');
347
+ const closeNotifModalBtn = document.getElementById('closeNotifModalBtn');
348
+ const clearNotifBtn = document.getElementById('clearNotifBtn');
349
+ const notificationCount = document.getElementById('notificationCount');
350
+
351
+ // Set current date
352
+ const today = new Date();
353
+ currentDateEl.textContent = today.toLocaleDateString('en-US', {
354
+ weekday: 'long',
355
+ month: 'long',
356
+ day: 'numeric'
357
+ });
358
+
359
+ // Render today's medications
360
+ function renderTodaysMeds() {
361
+ todaysMedsEl.innerHTML = '';
362
+
363
+ const todaysMeds = medications.filter(med => med.todayStatus !== null);
364
+ let takenCount = 0;
365
+ let pendingCount = 0;
366
+ let missedCount = 0;
367
+
368
+ if (todaysMeds.length === 0) {
369
+ todaysMedsEl.innerHTML = `
370
+ <div class="bg-white rounded-xl p-6 shadow-sm text-center text-gray-500">
371
+ <i class="fas fa-calendar-check text-3xl mb-2 text-sky-300"></i>
372
+ <p>No medications scheduled for today</p>
373
+ </div>
374
+ `;
375
+ return;
376
+ }
377
+
378
+ todaysMeds.forEach(med => {
379
+ const isTaken = med.todayStatus.taken;
380
+ const time = med.todayStatus.time;
381
+
382
+ if (isTaken) takenCount++;
383
+ else {
384
+ const medTime = new Date();
385
+ const [hours, minutes] = time.split(':');
386
+ medTime.setHours(hours, minutes, 0, 0);
387
+
388
+ if (today > medTime) missedCount++;
389
+ else pendingCount++;
390
+ }
391
+
392
+ const card = document.createElement('div');
393
+ card.className = `bg-white rounded-xl p-4 shadow-sm medication-card border-l-4 ${isTaken ? 'border-green-500' : today > new Date(`${today.toDateString()} ${time}`) ? 'border-red-500' : 'border-yellow-500'}`;
394
+
395
+ card.innerHTML = `
396
+ <div class="flex justify-between items-start">
397
+ <div class="flex items-center">
398
+ <div class="p-3 rounded-full ${med.color} text-${med.color.replace('bg-', 'text-').replace('-100', '-600')} mr-4">
399
+ <i class="fas ${med.icon} text-xl"></i>
400
+ </div>
401
+ <div>
402
+ <h3 class="font-semibold">${med.name}</h3>
403
+ <p class="text-sm text-gray-600">${med.dosage} • ${getFrequencyText(med.frequency)}</p>
404
+ </div>
405
+ </div>
406
+ <div class="text-right">
407
+ <p class="text-sm font-medium ${isTaken ? 'text-green-600' : today > new Date(`${today.toDateString()} ${time}`) ? 'text-red-600' : 'text-yellow-600'}">
408
+ ${isTaken ? 'Taken' : today > new Date(`${today.toDateString()} ${time}`) ? 'Missed' : 'Pending'} at ${time}
409
+ </p>
410
+ ${!isTaken && today <= new Date(`${today.toDateString()} ${time}`) ? `
411
+ <button class="mt-2 px-3 py-1 bg-sky-600 text-white text-sm rounded-lg hover:bg-sky-700 transition"
412
+ onclick="markAsTaken(${med.id})">
413
+ Mark as Taken
414
+ </button>
415
+ ` : ''}
416
+ </div>
417
+ </div>
418
+ ${med.notes ? `<div class="mt-3 p-3 bg-gray-50 rounded-lg text-sm text-gray-700">${med.notes}</div>` : ''}
419
+ `;
420
+
421
+ todaysMedsEl.appendChild(card);
422
+ });
423
+
424
+ takenTodayEl.textContent = takenCount;
425
+ pendingTodayEl.textContent = pendingCount;
426
+ missedTodayEl.textContent = missedCount;
427
+
428
+ // Show notification badge if there are missed medications
429
+ if (missedCount > 0) {
430
+ notificationCount.textContent = missedCount;
431
+ notificationCount.classList.remove('hidden');
432
+ } else {
433
+ notificationCount.classList.add('hidden');
434
+ }
435
+ }
436
+
437
+ // Render all medications
438
+ function renderAllMeds() {
439
+ allMedsEl.innerHTML = '';
440
+
441
+ if (medications.length === 0) {
442
+ allMedsEl.innerHTML = `
443
+ <div class="col-span-3 bg-white rounded-xl p-8 shadow-sm text-center">
444
+ <i class="fas fa-prescription-bottle-alt text-4xl mb-4 text-sky-300"></i>
445
+ <h3 class="text-lg font-medium text-gray-700 mb-2">No medications added yet</h3>
446
+ <p class="text-gray-500 mb-4">Add your first medication to start tracking</p>
447
+ <button id="addFirstMedBtn" class="px-4 py-2 bg-sky-600 text-white rounded-lg hover:bg-sky-700 transition">
448
+ <i class="fas fa-plus mr-2"></i> Add Medication
449
+ </button>
450
+ </div>
451
+ `;
452
+
453
+ document.getElementById('addFirstMedBtn').addEventListener('click', () => {
454
+ medModal.classList.remove('hidden');
455
+ medModal.classList.add('modal-enter-active');
456
+ });
457
+
458
+ return;
459
+ }
460
+
461
+ medications.forEach(med => {
462
+ const card = document.createElement('div');
463
+ card.className = `bg-white rounded-xl p-5 shadow-sm medication-card hover:shadow-md transition`;
464
+
465
+ // Calculate adherence percentage (for demo purposes)
466
+ const adherence = Math.min(100, Math.floor(Math.random() * 30) + 70);
467
+
468
+ card.innerHTML = `
469
+ <div class="flex justify-between items-start mb-4">
470
+ <div class="flex items-center">
471
+ <div class="p-3 rounded-full ${med.color} text-${med.color.replace('bg-', 'text-').replace('-100', '-600')} mr-3">
472
+ <i class="fas ${med.icon} text-xl"></i>
473
+ </div>
474
+ <div>
475
+ <h3 class="font-semibold">${med.name}</h3>
476
+ <p class="text-sm text-gray-600">${med.dosage}</p>
477
+ </div>
478
+ </div>
479
+ <span class="text-xs px-2 py-1 bg-gray-100 text-gray-700 rounded-full">${med.type}</span>
480
+ </div>
481
+
482
+ <div class="mb-3">
483
+ <p class="text-sm text-gray-700 mb-1"><i class="fas fa-clock mr-2 text-gray-400"></i> ${getFrequencyText(med.frequency)}</p>
484
+ ${med.times.length > 0 ? `
485
+ <p class="text-sm text-gray-700"><i class="fas fa-bell mr-2 text-gray-400"></i> ${med.times.join(', ')}</p>
486
+ ` : ''}
487
+ </div>
488
+
489
+ ${med.notes ? `<div class="mb-4 p-3 bg-gray-50 rounded-lg text-sm text-gray-700">${med.notes}</div>` : ''}
490
+
491
+ <div class="flex justify-between items-center">
492
+ <div class="w-full mr-2">
493
+ <div class="text-xs text-gray-500 mb-1">Adherence</div>
494
+ <div class="progress-bar">
495
+ <div class="progress-fill" style="width: ${adherence}%"></div>
496
+ </div>
497
+ </div>
498
+ <span class="text-sm font-medium text-gray-700">${adherence}%</span>
499
+ </div>
500
+
501
+ <div class="flex justify-between mt-4 pt-3 border-t border-gray-100">
502
+ <button class="text-sm text-gray-500 hover:text-gray-700" onclick="editMedication(${med.id})">
503
+ <i class="fas fa-edit mr-1"></i> Edit
504
+ </button>
505
+ <button class="text-sm text-red-500 hover:text-red-700" onclick="deleteMedication(${med.id})">
506
+ <i class="fas fa-trash-alt mr-1"></i> Delete
507
+ </button>
508
+ </div>
509
+ `;
510
+
511
+ allMedsEl.appendChild(card);
512
+ });
513
+ }
514
+
515
+ // Helper function to get frequency text
516
+ function getFrequencyText(frequency) {
517
+ const freqMap = {
518
+ once: "Once daily",
519
+ twice: "Twice daily",
520
+ three: "Three times daily",
521
+ four: "Four times daily",
522
+ as_needed: "As needed"
523
+ };
524
+ return freqMap[frequency] || frequency;
525
+ }
526
+
527
+ // Mark medication as taken
528
+ window.markAsTaken = function(id) {
529
+ const medIndex = medications.findIndex(m => m.id === id);
530
+ if (medIndex !== -1) {
531
+ medications[medIndex].todayStatus.taken = true;
532
+ medications[medIndex].taken.push(new Date().toISOString());
533
+ renderTodaysMeds();
534
+
535
+ // Show success notification
536
+ const notification = document.createElement('div');
537
+ notification.className = 'fixed top-4 right-4 px-4 py-2 bg-green-500 text-white rounded-lg shadow-lg flex items-center animate-fade-in';
538
+ notification.innerHTML = `
539
+ <i class="fas fa-check-circle mr-2"></i>
540
+ <span>${medications[medIndex].name} marked as taken</span>
541
+ `;
542
+ document.body.appendChild(notification);
543
+
544
+ setTimeout(() => {
545
+ notification.classList.add('animate-fade-out');
546
+ setTimeout(() => notification.remove(), 300);
547
+ }, 3000);
548
+ }
549
+ }
550
+
551
+ // Edit medication
552
+ window.editMedication = function(id) {
553
+ // In a real app, this would populate the modal with the medication data
554
+ alert(`Editing medication with ID ${id}. This would open the edit form in a real application.`);
555
+ }
556
+
557
+ // Delete medication
558
+ window.deleteMedication = function(id) {
559
+ if (confirm('Are you sure you want to delete this medication?')) {
560
+ const medIndex = medications.findIndex(m => m.id === id);
561
+ if (medIndex !== -1) {
562
+ medications.splice(medIndex, 1);
563
+ renderAllMeds();
564
+ renderTodaysMeds();
565
+
566
+ // Show success notification
567
+ const notification = document.createElement('div');
568
+ notification.className = 'fixed top-4 right-4 px-4 py-2 bg-red-500 text-white rounded-lg shadow-lg flex items-center animate-fade-in';
569
+ notification.innerHTML = `
570
+ <i class="fas fa-trash-alt mr-2"></i>
571
+ <span>Medication deleted</span>
572
+ `;
573
+ document.body.appendChild(notification);
574
+
575
+ setTimeout(() => {
576
+ notification.classList.add('animate-fade-out');
577
+ setTimeout(() => notification.remove(), 300);
578
+ }, 3000);
579
+ }
580
+ }
581
+ }
582
+
583
+ // Add time input
584
+ addTimeBtn.addEventListener('click', () => {
585
+ const timeInput = document.createElement('div');
586
+ timeInput.className = 'flex items-center';
587
+ timeInput.innerHTML = `
588
+ <input type="time" class="px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-sky-500 focus:border-sky-500" value="12:00">
589
+ <button type="button" class="ml-2 text-red-500 hover:text-red-700 remove-time">
590
+ <i class="fas fa-times"></i>
591
+ </button>
592
+ `;
593
+ timeInputs.appendChild(timeInput);
594
+
595
+ // Add event listener to remove button
596
+ timeInput.querySelector('.remove-time').addEventListener('click', () => {
597
+ timeInput.remove();
598
+ });
599
+ });
600
+
601
+ // Modal controls
602
+ addMedBtn.addEventListener('click', () => {
603
+ medModal.classList.remove('hidden');
604
+ medModal.classList.add('modal-enter-active');
605
+ });
606
+
607
+ closeModalBtn.addEventListener('click', () => {
608
+ medModal.classList.add('hidden');
609
+ });
610
+
611
+ cancelMedBtn.addEventListener('click', () => {
612
+ medModal.classList.add('hidden');
613
+ });
614
+
615
+ // Notification controls
616
+ notificationBtn.addEventListener('click', () => {
617
+ notificationModal.classList.remove('hidden');
618
+ });
619
+
620
+ closeNotifModalBtn.addEventListener('click', () => {
621
+ notificationModal.classList.add('hidden');
622
+ });
623
+
624
+ clearNotifBtn.addEventListener('click', () => {
625
+ document.getElementById('notificationList').innerHTML = `
626
+ <div class="text-center py-8 text-gray-500">
627
+ <i class="fas fa-bell-slash text-3xl mb-2"></i>
628
+ <p>No notifications</p>
629
+ </div>
630
+ `;
631
+ notificationCount.classList.add('hidden');
632
+ });
633
+
634
+ // Form submission
635
+ medForm.addEventListener('submit', (e) => {
636
+ e.preventDefault();
637
+
638
+ // Get form values
639
+ const name = document.getElementById('medName').value;
640
+ const type = document.getElementById('medType').value;
641
+ const dosage = document.getElementById('medDosage').value;
642
+ const frequency = document.getElementById('medFrequency').value;
643
+ const notes = document.getElementById('medNotes').value;
644
+
645
+ // Get times
646
+ const timeElements = timeInputs.querySelectorAll('input[type="time"]');
647
+ const times = Array.from(timeElements).map(el => el.value);
648
+
649
+ // Create new medication
650
+ const newMed = {
651
+ id: medications.length > 0 ? Math.max(...medications.map(m => m.id)) + 1 : 1,
652
+ name,
653
+ type,
654
+ dosage,
655
+ frequency,
656
+ times,
657
+ notes,
658
+ taken: [],
659
+ color: getRandomColor(),
660
+ icon: getIconForType(type),
661
+ todayStatus: frequency !== 'as_needed' && times.length > 0 ?
662
+ { taken: false, time: times[0] } : null
663
+ };
664
+
665
+ medications.push(newMed);
666
+
667
+ // Reset form
668
+ medForm.reset();
669
+ timeInputs.innerHTML = `
670
+ <div class="flex items-center">
671
+ <input type="time" class="px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-sky-500 focus:border-sky-500" value="08:00">
672
+ <button type="button" class="ml-2 text-red-500 hover:text-red-700">
673
+ <i class="fas fa-times"></i>
674
+ </button>
675
+ </div>
676
+ `;
677
+
678
+ // Close modal
679
+ medModal.classList.add('hidden');
680
+
681
+ // Update UI
682
+ renderAllMeds();
683
+ renderTodaysMeds();
684
+
685
+ // Show success notification
686
+ const notification = document.createElement('div');
687
+ notification.className = 'fixed top-4 right-4 px-4 py-2 bg-green-500 text-white rounded-lg shadow-lg flex items-center animate-fade-in';
688
+ notification.innerHTML = `
689
+ <i class="fas fa-check-circle mr-2"></i>
690
+ <span>${name} added successfully</span>
691
+ `;
692
+ document.body.appendChild(notification);
693
+
694
+ setTimeout(() => {
695
+ notification.classList.add('animate-fade-out');
696
+ setTimeout(() => notification.remove(), 300);
697
+ }, 3000);
698
+ });
699
+
700
+ // Helper function to get random color for medication card
701
+ function getRandomColor() {
702
+ const colors = [
703
+ 'bg-blue-100', 'bg-green-100', 'bg-yellow-100',
704
+ 'bg-red-100', 'bg-purple-100', 'bg-pink-100',
705
+ 'bg-indigo-100', 'bg-teal-100', 'bg-orange-100'
706
+ ];
707
+ return colors[Math.floor(Math.random() * colors.length)];
708
+ }
709
+
710
+ // Helper function to get icon based on medication type
711
+ function getIconForType(type) {
712
+ const icons = {
713
+ inhaler: 'fa-inhaler',
714
+ tablet: 'fa-pills',
715
+ capsule: 'fa-capsules',
716
+ liquid: 'fa-flask',
717
+ injection: 'fa-syringe'
718
+ };
719
+ return icons[type] || 'fa-prescription-bottle-alt';
720
+ }
721
+
722
+ // Initial render
723
+ renderTodaysMeds();
724
+ renderAllMeds();
725
+
726
+ // Add animation classes
727
+ const style = document.createElement('style');
728
+ style.textContent = `
729
+ @keyframes fadeIn {
730
+ from { opacity: 0; transform: translateY(10px); }
731
+ to { opacity: 1; transform: translateY(0); }
732
+ }
733
+
734
+ @keyframes fadeOut {
735
+ from { opacity: 1; transform: translateY(0); }
736
+ to { opacity: 0; transform: translateY(10px); }
737
+ }
738
+
739
+ .animate-fade-in {
740
+ animation: fadeIn 0.3s ease-out forwards;
741
+ }
742
+
743
+ .animate-fade-out {
744
+ animation: fadeOut 0.3s ease-out forwards;
745
+ }
746
+ `;
747
+ document.head.appendChild(style);
748
+ </script>
749
+ <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=mannadamay12/copd-medication-tracker" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
750
+ </html>