TheFrogGod commited on
Commit
4bba950
·
verified ·
1 Parent(s): fe7cb36

Update web/profile.html

Browse files
Files changed (1) hide show
  1. web/profile.html +264 -133
web/profile.html CHANGED
@@ -6,6 +6,7 @@
6
  <title>Profile - CTRL + ALT + HEAL</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <link rel="stylesheet" href="style.css" />
 
9
  </head>
10
  <body class="bg-[#F7F8F9] min-h-screen">
11
  <!-- NAVBAR -->
@@ -224,6 +225,136 @@
224
  '#mobile-menu a[href="index.html"]'
225
  )?.parentElement;
226
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
  // ✅ Auth State Handling
228
  onAuthStateChanged(auth, async (user) => {
229
  const authNavItem = document.getElementById("authNavItem");
@@ -280,7 +411,7 @@
280
  }
281
  };
282
 
283
- document.addEventListener("DOMContentLoaded", () => {
284
  const profileView = document.getElementById("profileViewSection");
285
  const profileEdit = document.getElementById("profileEditSection");
286
  const editBtn = document.getElementById("editProfileBtn");
@@ -320,138 +451,138 @@
320
  // RANGE BARS LOGIC
321
  const tabs = document.querySelectorAll(".tab");
322
  const contents = document.querySelectorAll(".tab-content");
323
- const measurements = [
324
- {
325
- name: "Blood Sugar",
326
- min: 70,
327
- max: 110,
328
- value: 95,
329
- tab: "in-range",
330
- impacts: ["Pancreas"],
331
- },
332
- {
333
- name: "Cholesterol",
334
- min: 120,
335
- max: 200,
336
- value: 180,
337
- tab: "in-range",
338
- impacts: ["Heart", "Arteries"],
339
- },
340
- {
341
- name: "Triglycerides",
342
- min: 50,
343
- max: 150,
344
- value: 180,
345
- tab: "out-range",
346
- impacts: ["Heart"],
347
- },
348
- {
349
- name: "Blood Pressure",
350
- min: 90,
351
- max: 120,
352
- value: 130,
353
- tab: "out-range",
354
- impacts: ["Heart", "Kidneys"],
355
- },
356
- ];
357
-
358
- const counts = { "in-range": 0, "out-range": 0 };
359
-
360
- measurements.forEach((m) => {
361
- counts[m.tab]++;
362
- const container = document.getElementById(m.tab);
363
- const card = document.createElement("div");
364
- card.className = "range-card";
365
- const title = document.createElement("h3");
366
- title.textContent = m.name;
367
- card.appendChild(title);
368
- if (m.impacts) {
369
- const impactLabel = document.createElement("div");
370
- impactLabel.className = "impact-label";
371
- impactLabel.textContent = "Impacts: " + m.impacts.join(", ");
372
- card.appendChild(impactLabel);
373
- }
374
- const barContainer = document.createElement("div");
375
- barContainer.className = "range-bar-container";
376
- const bar = document.createElement("div");
377
- bar.className = "range-bar";
378
-
379
- let normalPercent = 100;
380
- let overflowPercent = 0;
381
- if (m.tab === "out-range" && m.value > m.max) {
382
- normalPercent = ((m.max - m.min) / (m.value - m.min)) * 100;
383
- overflowPercent = 100 - normalPercent;
384
- }
385
-
386
- const normalDiv = document.createElement("div");
387
- normalDiv.className = "normal-range";
388
- normalDiv.style.width = normalPercent + "%";
389
- bar.appendChild(normalDiv);
390
- if (overflowPercent > 0) {
391
- const overflowDiv = document.createElement("div");
392
- overflowDiv.className = "overflow-range";
393
- overflowDiv.style.left = normalPercent + "%";
394
- overflowDiv.style.width = overflowPercent + "%";
395
- bar.appendChild(overflowDiv);
396
- }
397
-
398
- let valuePercent = ((m.value - m.min) / (m.max - m.min)) * 100;
399
- valuePercent = Math.min(Math.max(valuePercent, 0), 100);
400
- const marker = document.createElement("div");
401
- marker.className = "marker";
402
- marker.style.left = valuePercent + "%";
403
- bar.appendChild(marker);
404
- const valueLabel = document.createElement("div");
405
- valueLabel.className = "value-label";
406
- valueLabel.style.left = valuePercent + "%";
407
- valueLabel.textContent = m.value;
408
- bar.appendChild(valueLabel);
409
-
410
- barContainer.appendChild(bar);
411
-
412
- const minMaxDiv = document.createElement("div");
413
- minMaxDiv.className = "min-max-labels relative w-full";
414
-
415
- const minLabel = document.createElement("span");
416
- minLabel.textContent = "Min: " + m.min;
417
- minLabel.style.position = "absolute";
418
- minLabel.style.left = "0";
419
-
420
- const maxLabel = document.createElement("span");
421
- maxLabel.textContent = "Max: " + m.max;
422
- maxLabel.style.position = "absolute";
423
-
424
- // put the max label at the end of the green section
425
- let maxPercent = 100;
426
- if (m.value > m.max) {
427
- maxPercent = ((m.max - m.min) / (m.value - m.min)) * 100;
428
- }
429
- maxLabel.style.left = maxPercent + "%";
430
- maxLabel.style.transform = "translateX(-100%)"; // anchor it properly
431
-
432
- minMaxDiv.appendChild(minLabel);
433
- minMaxDiv.appendChild(maxLabel);
434
- barContainer.appendChild(minMaxDiv);
435
-
436
-
437
- card.appendChild(barContainer);
438
- container.appendChild(card);
439
- });
440
-
441
- tabs.forEach((tab) => {
442
- const t = tab.dataset.tab;
443
- const badge = tab.querySelector(".count-badge");
444
- badge.textContent = counts[t];
445
- tab.addEventListener("click", () => {
446
- tabs.forEach((t) => t.classList.remove("active"));
447
- tab.classList.add("active");
448
- contents.forEach((c) =>
449
- c.id === t
450
- ? c.classList.add("active")
451
- : c.classList.remove("active")
452
- );
453
- });
454
- });
455
  });
456
  </script>
457
  </body>
 
6
  <title>Profile - CTRL + ALT + HEAL</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <link rel="stylesheet" href="style.css" />
9
+ <script src="script.js"></script>
10
  </head>
11
  <body class="bg-[#F7F8F9] min-h-screen">
12
  <!-- NAVBAR -->
 
225
  '#mobile-menu a[href="index.html"]'
226
  )?.parentElement;
227
 
228
+ // Fetch measurements from backend API
229
+ async function getUserMeasurements(userId) {
230
+ try {
231
+ const url = api("user_measurements/", { user_id: userId });
232
+ const res = await fetch(url);
233
+ if (!res.ok) throw new Error("Failed to fetch measurements");
234
+
235
+ const data = await res.json();
236
+
237
+ return (data.measurements || []).map((m) => ({
238
+ name: m.type,
239
+ value: Number(m.value),
240
+ min: Number(m.min),
241
+ max: Number(m.max),
242
+ tab: m.status === "HIGH" || m.status === "LOW" ? "out-range" : "in-range",
243
+ impacts: m.impacts || [],
244
+ }));
245
+ } catch (e) {
246
+ console.error("Error fetching user measurements:", e);
247
+ return [];
248
+ }
249
+ }
250
+
251
+ // Render bars in the UI based on measurement array
252
+ function renderBars(measurements) {
253
+ const counts = { "in-range": 0, "out-range": 0 };
254
+ const tabs = document.querySelectorAll(".tab");
255
+ const contents = document.querySelectorAll(".tab-content");
256
+
257
+ // Clear existing content
258
+ contents.forEach((c) => (c.innerHTML = ""));
259
+
260
+ measurements.forEach((m) => {
261
+ counts[m.tab]++;
262
+ const container = document.getElementById(m.tab);
263
+ const card = document.createElement("div");
264
+ card.className = "range-card";
265
+
266
+ const title = document.createElement("h3");
267
+ title.textContent = m.name;
268
+ card.appendChild(title);
269
+
270
+ if (m.impacts?.length) {
271
+ const impactLabel = document.createElement("div");
272
+ impactLabel.className = "impact-label";
273
+ impactLabel.textContent = "Impacts: " + m.impacts.join(", ");
274
+ card.appendChild(impactLabel);
275
+ }
276
+
277
+ const barContainer = document.createElement("div");
278
+ barContainer.className = "range-bar-container";
279
+ const bar = document.createElement("div");
280
+ bar.className = "range-bar";
281
+
282
+ let normalPercent = 100;
283
+ let overflowPercent = 0;
284
+ if (m.tab === "out-range" && m.value > m.max) {
285
+ normalPercent = ((m.max - m.min) / (m.value - m.min)) * 100;
286
+ overflowPercent = 100 - normalPercent;
287
+ }
288
+
289
+ const normalDiv = document.createElement("div");
290
+ normalDiv.className = "normal-range";
291
+ normalDiv.style.width = normalPercent + "%";
292
+ bar.appendChild(normalDiv);
293
+
294
+ if (overflowPercent > 0) {
295
+ const overflowDiv = document.createElement("div");
296
+ overflowDiv.className = "overflow-range";
297
+ overflowDiv.style.left = normalPercent + "%";
298
+ overflowDiv.style.width = overflowPercent + "%";
299
+ bar.appendChild(overflowDiv);
300
+ }
301
+
302
+ let valuePercent = ((m.value - m.min) / (m.max - m.min)) * 100;
303
+ valuePercent = Math.min(Math.max(valuePercent, 0), 100);
304
+
305
+ const marker = document.createElement("div");
306
+ marker.className = "marker";
307
+ marker.style.left = valuePercent + "%";
308
+ bar.appendChild(marker);
309
+
310
+ const valueLabel = document.createElement("div");
311
+ valueLabel.className = "value-label";
312
+ valueLabel.style.left = valuePercent + "%";
313
+ valueLabel.textContent = m.value;
314
+ bar.appendChild(valueLabel);
315
+
316
+ barContainer.appendChild(bar);
317
+
318
+ const minMaxDiv = document.createElement("div");
319
+ minMaxDiv.className = "min-max-labels relative w-full";
320
+
321
+ const minLabel = document.createElement("span");
322
+ minLabel.textContent = "Min: " + m.min;
323
+ minLabel.style.position = "absolute";
324
+ minLabel.style.left = "0";
325
+
326
+ const maxLabel = document.createElement("span");
327
+ maxLabel.textContent = "Max: " + m.max;
328
+ maxLabel.style.position = "absolute";
329
+
330
+ let maxPercent = 100;
331
+ if (m.value > m.max) maxPercent = ((m.max - m.min) / (m.value - m.min)) * 100;
332
+ maxLabel.style.left = maxPercent + "%";
333
+ maxLabel.style.transform = "translateX(-100%)";
334
+
335
+ minMaxDiv.appendChild(minLabel);
336
+ minMaxDiv.appendChild(maxLabel);
337
+ barContainer.appendChild(minMaxDiv);
338
+
339
+ card.appendChild(barContainer);
340
+ container.appendChild(card);
341
+ });
342
+
343
+ // Update tab badges
344
+ tabs.forEach((tab) => {
345
+ const t = tab.dataset.tab;
346
+ const badge = tab.querySelector(".count-badge");
347
+ badge.textContent = counts[t];
348
+ tab.addEventListener("click", () => {
349
+ tabs.forEach((t) => t.classList.remove("active"));
350
+ tab.classList.add("active");
351
+ contents.forEach((c) =>
352
+ c.id === t ? c.classList.add("active") : c.classList.remove("active")
353
+ );
354
+ });
355
+ });
356
+ }
357
+
358
  // ✅ Auth State Handling
359
  onAuthStateChanged(auth, async (user) => {
360
  const authNavItem = document.getElementById("authNavItem");
 
411
  }
412
  };
413
 
414
+ document.addEventListener("DOMContentLoaded", async () => {
415
  const profileView = document.getElementById("profileViewSection");
416
  const profileEdit = document.getElementById("profileEditSection");
417
  const editBtn = document.getElementById("editProfileBtn");
 
451
  // RANGE BARS LOGIC
452
  const tabs = document.querySelectorAll(".tab");
453
  const contents = document.querySelectorAll(".tab-content");
454
+ // const measurements = [
455
+ // {
456
+ // name: "Blood Sugar",
457
+ // min: 70,
458
+ // max: 110,
459
+ // value: 95,
460
+ // tab: "in-range",
461
+ // impacts: ["Pancreas"],
462
+ // },
463
+ // {
464
+ // name: "Cholesterol",
465
+ // min: 120,
466
+ // max: 200,
467
+ // value: 180,
468
+ // tab: "in-range",
469
+ // impacts: ["Heart", "Arteries"],
470
+ // },
471
+ // {
472
+ // name: "Triglycerides",
473
+ // min: 50,
474
+ // max: 150,
475
+ // value: 180,
476
+ // tab: "out-range",
477
+ // impacts: ["Heart"],
478
+ // },
479
+ // {
480
+ // name: "Blood Pressure",
481
+ // min: 90,
482
+ // max: 120,
483
+ // value: 130,
484
+ // tab: "out-range",
485
+ // impacts: ["Heart", "Kidneys"],
486
+ // },
487
+ // ];
488
+
489
+ // const counts = { "in-range": 0, "out-range": 0 };
490
+
491
+ // measurements.forEach((m) => {
492
+ // counts[m.tab]++;
493
+ // const container = document.getElementById(m.tab);
494
+ // const card = document.createElement("div");
495
+ // card.className = "range-card";
496
+ // const title = document.createElement("h3");
497
+ // title.textContent = m.name;
498
+ // card.appendChild(title);
499
+ // if (m.impacts) {
500
+ // const impactLabel = document.createElement("div");
501
+ // impactLabel.className = "impact-label";
502
+ // impactLabel.textContent = "Impacts: " + m.impacts.join(", ");
503
+ // card.appendChild(impactLabel);
504
+ // }
505
+ // const barContainer = document.createElement("div");
506
+ // barContainer.className = "range-bar-container";
507
+ // const bar = document.createElement("div");
508
+ // bar.className = "range-bar";
509
+
510
+ // let normalPercent = 100;
511
+ // let overflowPercent = 0;
512
+ // if (m.tab === "out-range" && m.value > m.max) {
513
+ // normalPercent = ((m.max - m.min) / (m.value - m.min)) * 100;
514
+ // overflowPercent = 100 - normalPercent;
515
+ // }
516
+
517
+ // const normalDiv = document.createElement("div");
518
+ // normalDiv.className = "normal-range";
519
+ // normalDiv.style.width = normalPercent + "%";
520
+ // bar.appendChild(normalDiv);
521
+ // if (overflowPercent > 0) {
522
+ // const overflowDiv = document.createElement("div");
523
+ // overflowDiv.className = "overflow-range";
524
+ // overflowDiv.style.left = normalPercent + "%";
525
+ // overflowDiv.style.width = overflowPercent + "%";
526
+ // bar.appendChild(overflowDiv);
527
+ // }
528
+
529
+ // let valuePercent = ((m.value - m.min) / (m.max - m.min)) * 100;
530
+ // valuePercent = Math.min(Math.max(valuePercent, 0), 100);
531
+ // const marker = document.createElement("div");
532
+ // marker.className = "marker";
533
+ // marker.style.left = valuePercent + "%";
534
+ // bar.appendChild(marker);
535
+ // const valueLabel = document.createElement("div");
536
+ // valueLabel.className = "value-label";
537
+ // valueLabel.style.left = valuePercent + "%";
538
+ // valueLabel.textContent = m.value;
539
+ // bar.appendChild(valueLabel);
540
+
541
+ // barContainer.appendChild(bar);
542
+
543
+ // const minMaxDiv = document.createElement("div");
544
+ // minMaxDiv.className = "min-max-labels relative w-full";
545
+
546
+ // const minLabel = document.createElement("span");
547
+ // minLabel.textContent = "Min: " + m.min;
548
+ // minLabel.style.position = "absolute";
549
+ // minLabel.style.left = "0";
550
+
551
+ // const maxLabel = document.createElement("span");
552
+ // maxLabel.textContent = "Max: " + m.max;
553
+ // maxLabel.style.position = "absolute";
554
+
555
+ // // put the max label at the end of the green section
556
+ // let maxPercent = 100;
557
+ // if (m.value > m.max) {
558
+ // maxPercent = ((m.max - m.min) / (m.value - m.min)) * 100;
559
+ // }
560
+ // maxLabel.style.left = maxPercent + "%";
561
+ // maxLabel.style.transform = "translateX(-100%)"; // anchor it properly
562
+
563
+ // minMaxDiv.appendChild(minLabel);
564
+ // minMaxDiv.appendChild(maxLabel);
565
+ // barContainer.appendChild(minMaxDiv);
566
+
567
+
568
+ // card.appendChild(barContainer);
569
+ // container.appendChild(card);
570
+ // });
571
+
572
+ // tabs.forEach((tab) => {
573
+ // const t = tab.dataset.tab;
574
+ // const badge = tab.querySelector(".count-badge");
575
+ // badge.textContent = counts[t];
576
+ // tab.addEventListener("click", () => {
577
+ // tabs.forEach((t) => t.classList.remove("active"));
578
+ // tab.classList.add("active");
579
+ // contents.forEach((c) =>
580
+ // c.id === t
581
+ // ? c.classList.add("active")
582
+ // : c.classList.remove("active")
583
+ // );
584
+ // });
585
+ // });
586
  });
587
  </script>
588
  </body>