From e37c73e33a4aaf7fb8d25b5af03627f20bcda19f Mon Sep 17 00:00:00 2001
From: Doog <157747121+doogongithub@users.noreply.github.com>
Date: Sat, 24 Feb 2024 20:08:35 -0500
Subject: add gitignore

---
 fe/src/lib/DataView.svelte | 67 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)
 create mode 100644 fe/src/lib/DataView.svelte

(limited to 'fe/src/lib/DataView.svelte')

diff --git a/fe/src/lib/DataView.svelte b/fe/src/lib/DataView.svelte
new file mode 100644
index 0000000..cd7b042
--- /dev/null
+++ b/fe/src/lib/DataView.svelte
@@ -0,0 +1,67 @@
+<script lang='ts'>
+import { onMount } from 'svelte';
+import { token } from '../stores/auth'
+import Table from './Table.svelte';
+
+let json;
+let showAddForm: boolean = false;
+
+async function fetchData() {
+    const res = await fetch('http://localhost:8080/api/v1/stats/', {
+        method: "GET",
+        headers: {
+            'Authorization': `Bearer ${$token}`
+        }
+    });
+    if (res.ok) {
+        json = res.json();
+    } else {
+        throw new Error('There was a problem with your request');
+    }
+}
+
+async function submitStat() {
+    const response = await fetch('http://localhost:8080/api/v1/stats/', {
+        method: "POST",
+        headers: {
+            'Authorization': `Bearer ${$token}`
+        },
+        body: JSON.stringify({
+            date: new Date,
+            user_id: 1,
+            quantity: 3
+        })
+    });
+    fetchData();
+}
+
+function handleClick() {
+    showAddForm = true;
+}
+
+function handleAddDialogSubmit (e) {
+    console.log(e.keyCode)
+}
+
+onMount(() => {
+    fetchData();
+});
+
+</script>
+<div>
+    <button on:click={submitStat}>Add Stat Test</button>
+    <dialog open={showAddForm} on:submit={handleAddDialogSubmit}>
+        <form method="dialog">
+            <input name="date" type="date" />
+            <input name="quantity" type="number" min="0" autocomplete="off"/>
+            <button type="submit">Submit</button>
+        </form>
+    </dialog>
+    <button on:click={handleClick}>Add</button>
+    {#await json then data}
+        <Table {data} nofooter />
+    {:catch error}
+        <p>{error}</p>
+    {/await}
+    <!-- <Chart /> -->
+</div>
-- 
cgit v1.1


From 9f9a33cbf55d38987a66b709284d2bb4ffea0fe9 Mon Sep 17 00:00:00 2001
From: Doog <157747121+doogongithub@users.noreply.github.com>
Date: Thu, 29 Feb 2024 20:13:48 -0500
Subject: modify api, build additional FE components, add types

---
 fe/src/lib/DataView.svelte | 67 +++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 63 insertions(+), 4 deletions(-)

(limited to 'fe/src/lib/DataView.svelte')

diff --git a/fe/src/lib/DataView.svelte b/fe/src/lib/DataView.svelte
index cd7b042..dc8acae 100644
--- a/fe/src/lib/DataView.svelte
+++ b/fe/src/lib/DataView.svelte
@@ -1,11 +1,24 @@
 <script lang='ts'>
 import { onMount } from 'svelte';
-import { token } from '../stores/auth'
+import type { Preference } from '../types';
+import { token, user, preferences } from '../stores/auth'
 import Table from './Table.svelte';
+import PreferencesForm from './PreferencesForm.svelte';
+
+const formatter = new Intl.DateTimeFormat(
+    'en',
+    {
+        year: 'numeric',
+        month: '2-digit',
+        day: '2-digit'
+    }
+);
 
 let json;
 let showAddForm: boolean = false;
 
+let statistic: Statistic = newStatistic();
+
 async function fetchData() {
     const res = await fetch('http://localhost:8080/api/v1/stats/', {
         method: "GET",
@@ -40,7 +53,32 @@ function handleClick() {
 }
 
 function handleAddDialogSubmit (e) {
-    console.log(e.keyCode)
+    console.log(statistic);
+    showAddForm = false;
+}
+
+function closeDialog () {
+    showAddForm = false;
+}
+
+function newStatistic (): Statistic {
+    let now = new Date(), month, day, year;
+
+    month = `${now.getMonth() + 1}`;
+    day = `${now.getDate()}`;
+    year = now.getFullYear();
+    if (month.length < 2)
+        month = '0' + month;
+    if (day.length < 2)
+        day = '0' + day;
+
+    const date = [year, month, day].join('-');
+
+    return {
+        user_id: $user.uuid,
+        date,
+        quantity: 1
+    }
 }
 
 onMount(() => {
@@ -50,10 +88,19 @@ onMount(() => {
 </script>
 <div>
     <button on:click={submitStat}>Add Stat Test</button>
+    <PreferencesForm />
     <dialog open={showAddForm} on:submit={handleAddDialogSubmit}>
+        <h2>Add Water</h2>
         <form method="dialog">
-            <input name="date" type="date" />
-            <input name="quantity" type="number" min="0" autocomplete="off"/>
+            <div class='form input group'>
+                <label for="date">Date:</label>
+                <input bind:value={statistic.date} id="date" name="date" type="date" />
+            </div>
+            <div class='form input group'>
+                <label for="quantity">Quantity:</label>
+                <input bind:value={statistic.quantity} id="quantity" name="quantity" type="number" min="0" autocomplete="off"/>
+            </div>
+            <button on:click={closeDialog}>Cancel</button>
             <button type="submit">Submit</button>
         </form>
     </dialog>
@@ -65,3 +112,15 @@ onMount(() => {
     {/await}
     <!-- <Chart /> -->
 </div>
+
+<style>
+dialog {
+    background: red;
+    box-shadow: 0 20px 5em 10px rgba(0,0,0,0.8);
+}
+dialog::backdrop {
+    padding: 20px;
+    box-shadow: 20px 20px rgba(0,0,0,0.8);
+    background-color: red;
+}
+</style>
-- 
cgit v1.1


From afeffe31bd7d0f8333627a972e1d32e64a325b5b Mon Sep 17 00:00:00 2001
From: Zach Berwaldt <zberwaldt@tutamail.com>
Date: Fri, 1 Mar 2024 18:17:42 -0500
Subject: reformat fe

---
 fe/src/lib/DataView.svelte | 177 ++++++++++++++++++++++-----------------------
 1 file changed, 87 insertions(+), 90 deletions(-)

(limited to 'fe/src/lib/DataView.svelte')

diff --git a/fe/src/lib/DataView.svelte b/fe/src/lib/DataView.svelte
index dc8acae..1458c9a 100644
--- a/fe/src/lib/DataView.svelte
+++ b/fe/src/lib/DataView.svelte
@@ -1,126 +1,123 @@
-<script lang='ts'>
-import { onMount } from 'svelte';
-import type { Preference } from '../types';
-import { token, user, preferences } from '../stores/auth'
-import Table from './Table.svelte';
-import PreferencesForm from './PreferencesForm.svelte';
+<script lang="ts">
+  import { onMount } from "svelte";
+  import type { Statistic } from "../types";
+  import { token, user } from "../stores/auth";
+  import Table from "./Table.svelte";
 
-const formatter = new Intl.DateTimeFormat(
-    'en',
-    {
-        year: 'numeric',
-        month: '2-digit',
-        day: '2-digit'
-    }
-);
-
-let json;
-let showAddForm: boolean = false;
+  let json: Promise<any>;
+  let showAddForm: boolean = false;
 
-let statistic: Statistic = newStatistic();
+  let statistic: Statistic = newStatistic();
 
-async function fetchData() {
-    const res = await fetch('http://localhost:8080/api/v1/stats/', {
-        method: "GET",
-        headers: {
-            'Authorization': `Bearer ${$token}`
-        }
+  async function fetchData() {
+    const res = await fetch("http://localhost:8080/api/v1/stats/", {
+      method: "GET",
+      headers: {
+        Authorization: `Bearer ${$token}`,
+      },
     });
     if (res.ok) {
-        json = res.json();
+      json = res.json();
     } else {
-        throw new Error('There was a problem with your request');
+      throw new Error("There was a problem with your request");
     }
-}
+  }
 
-async function submitStat() {
-    const response = await fetch('http://localhost:8080/api/v1/stats/', {
-        method: "POST",
-        headers: {
-            'Authorization': `Bearer ${$token}`
-        },
-        body: JSON.stringify({
-            date: new Date,
-            user_id: 1,
-            quantity: 3
-        })
+  async function submitStat() {
+    const response = await fetch("http://localhost:8080/api/v1/stats/", {
+      method: "POST",
+      headers: {
+        Authorization: `Bearer ${$token}`,
+      },
+      body: JSON.stringify({
+        date: new Date(),
+        user_id: 1,
+        quantity: 3,
+      }),
     });
     fetchData();
-}
+  }
 
-function handleClick() {
+  function handleClick() {
     showAddForm = true;
-}
+  }
 
-function handleAddDialogSubmit (e) {
+  function handleAddDialogSubmit(e: Event) {
     console.log(statistic);
     showAddForm = false;
-}
+  }
 
-function closeDialog () {
+  function closeDialog() {
     showAddForm = false;
-}
+  }
 
-function newStatistic (): Statistic {
-    let now = new Date(), month, day, year;
+  function newStatistic(): Statistic {
+    let now = new Date(),
+      month,
+      day,
+      year;
 
     month = `${now.getMonth() + 1}`;
     day = `${now.getDate()}`;
     year = now.getFullYear();
-    if (month.length < 2)
-        month = '0' + month;
-    if (day.length < 2)
-        day = '0' + day;
+    if (month.length < 2) month = "0" + month;
+    if (day.length < 2) day = "0" + day;
 
-    const date = [year, month, day].join('-');
+    const date = [year, month, day].join("-");
 
     return {
-        user_id: $user.uuid,
-        date,
-        quantity: 1
-    }
-}
+      user_id: $user!.uuid,
+      date,
+      quantity: 1,
+    };
+  }
 
-onMount(() => {
+  onMount(() => {
     fetchData();
-});
-
+  });
 </script>
+
 <div>
-    <button on:click={submitStat}>Add Stat Test</button>
-    <PreferencesForm />
-    <dialog open={showAddForm} on:submit={handleAddDialogSubmit}>
-        <h2>Add Water</h2>
-        <form method="dialog">
-            <div class='form input group'>
-                <label for="date">Date:</label>
-                <input bind:value={statistic.date} id="date" name="date" type="date" />
-            </div>
-            <div class='form input group'>
-                <label for="quantity">Quantity:</label>
-                <input bind:value={statistic.quantity} id="quantity" name="quantity" type="number" min="0" autocomplete="off"/>
-            </div>
-            <button on:click={closeDialog}>Cancel</button>
-            <button type="submit">Submit</button>
-        </form>
-    </dialog>
-    <button on:click={handleClick}>Add</button>
-    {#await json then data}
-        <Table {data} nofooter />
-    {:catch error}
-        <p>{error}</p>
-    {/await}
-    <!-- <Chart /> -->
+  <button on:click={submitStat}>Add Stat Test</button>
+  <dialog open={showAddForm} on:submit={handleAddDialogSubmit}>
+    <h2>Add Water</h2>
+    <form method="dialog">
+      <div class="form input group">
+        <label for="date">Date:</label>
+        <input bind:value={statistic.date} id="date" name="date" type="date" />
+      </div>
+      <div class="form input group">
+        <label for="quantity">Quantity:</label>
+        <input
+          bind:value={statistic.quantity}
+          id="quantity"
+          name="quantity"
+          type="number"
+          min="0"
+          autocomplete="off"
+        />
+      </div>
+      <button on:click={closeDialog}>Cancel</button>
+      <button type="submit">Submit</button>
+    </form>
+  </dialog>
+  <button on:click={handleClick}>Add</button>
+  {#await json then data}
+    <Table {data} nofooter />
+  {:catch error}
+    <p>{error}</p>
+  {/await}
+  <!-- <Chart /> -->
 </div>
 
 <style>
-dialog {
+  dialog {
     background: red;
-    box-shadow: 0 20px 5em 10px rgba(0,0,0,0.8);
-}
-dialog::backdrop {
+    box-shadow: 0 20px 5em 10px rgba(0, 0, 0, 0.8);
+  }
+  dialog::backdrop {
     padding: 20px;
-    box-shadow: 20px 20px rgba(0,0,0,0.8);
+    box-shadow: 20px 20px rgba(0, 0, 0, 0.8);
     background-color: red;
-}
+  }
 </style>
-- 
cgit v1.1


From 74ec025991f6acde6383e448974738e857758ebb Mon Sep 17 00:00:00 2001
From: Zach Berwaldt <zberwaldt@tutamail.com>
Date: Fri, 1 Mar 2024 18:50:51 -0500
Subject: Add dependencies, refine dataview

---
 fe/src/lib/DataView.svelte | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

(limited to 'fe/src/lib/DataView.svelte')

diff --git a/fe/src/lib/DataView.svelte b/fe/src/lib/DataView.svelte
index 1458c9a..00ee21a 100644
--- a/fe/src/lib/DataView.svelte
+++ b/fe/src/lib/DataView.svelte
@@ -1,12 +1,16 @@
 <script lang="ts">
-  import { onMount } from "svelte";
+  import { onDestroy, onMount } from "svelte";
   import type { Statistic } from "../types";
   import { token, user } from "../stores/auth";
   import Table from "./Table.svelte";
+  import Chart from 'chart.js/auto';
 
   let json: Promise<any>;
   let showAddForm: boolean = false;
 
+  let canvasRef: HTMLCanvasElement;
+  let chart: any;
+
   let statistic: Statistic = newStatistic();
 
   async function fetchData() {
@@ -74,6 +78,26 @@
 
   onMount(() => {
     fetchData();
+    chart = new Chart(canvasRef, {
+        type: 'bar',
+        data: {
+            labels: ['one', 'two'],
+            datasets: [
+                {
+                    label: 'Water',
+                    data: [1, 2],
+                    backgroundColor: 'rgba(75, 192, 192, 0.2)',
+                    borderColor: 'rgba(75, 192, 192, 1)',
+                    borderWidth: 1
+                }
+            ]
+        }
+    });
+  });
+
+  onDestroy(() => {
+    if (chart) chart.destroy();
+    chart = null;
   });
 </script>
 
@@ -102,6 +126,7 @@
     </form>
   </dialog>
   <button on:click={handleClick}>Add</button>
+  <canvas bind:this={canvasRef} />
   {#await json then data}
     <Table {data} nofooter />
   {:catch error}
-- 
cgit v1.1


From d8b0f1335078d53d95a4212b1a4d4b0b28016702 Mon Sep 17 00:00:00 2001
From: Zach Berwaldt <zberwaldt@tutamail.com>
Date: Fri, 1 Mar 2024 20:12:21 -0500
Subject: feat(DataView): Add functionality to add water statistic

This commit adds functionality to add water statistics to the DataView component. It includes the following changes:
- Remove unused imports and variables
- Move the 'handleClick' function logic to a new 'AddForm' component
- Create the 'AddForm' component which displays a dialog with input fields for date and quantity and allows the user to add a new water statistic
- Dispatch events on form submit and dialog close in the 'AddForm' component
- Call the 'fetchData' function on successful submission of a new statistic
- Update chart data to display sample data

New component:
- AddForm.svelte: A form component to add a new water statistic

Note: This commit message exceeds the 50-character limit in the subject line, but adheres to the other specified requirements.
---
 fe/src/lib/DataView.svelte | 206 ++++++++++++++++-----------------------------
 1 file changed, 74 insertions(+), 132 deletions(-)

(limited to 'fe/src/lib/DataView.svelte')

diff --git a/fe/src/lib/DataView.svelte b/fe/src/lib/DataView.svelte
index 00ee21a..7f368c6 100644
--- a/fe/src/lib/DataView.svelte
+++ b/fe/src/lib/DataView.svelte
@@ -1,148 +1,90 @@
 <script lang="ts">
-  import { onDestroy, onMount } from "svelte";
-  import type { Statistic } from "../types";
-  import { token, user } from "../stores/auth";
-  import Table from "./Table.svelte";
-  import Chart from 'chart.js/auto';
-
-  let json: Promise<any>;
-  let showAddForm: boolean = false;
+    import { onDestroy, onMount } from "svelte";
+    import { token } from "../stores/auth";
+    import Table from "./Table.svelte";
+    import Chart from "chart.js/auto";
+    import AddForm from "./forms/AddForm.svelte";
+
+    let open: boolean = false;
+
+    let json: Promise<any>;
+
+    let canvasRef: HTMLCanvasElement;
+    let chart: any;
+
+    async function fetchData() {
+        const res = await fetch("http://localhost:8080/api/v1/stats/", {
+            method: "GET",
+            headers: {
+                Authorization: `Bearer ${$token}`
+            }
+        });
+        if (res.ok) {
+            json = res.json();
+        } else {
+            throw new Error("There was a problem with your request");
+        }
+    }
 
-  let canvasRef: HTMLCanvasElement;
-  let chart: any;
+    function handleClick() {
+        open = true;
+    }
 
-  let statistic: Statistic = newStatistic();
+    function closeDialog() {
+        open = false;
+    }
 
-  async function fetchData() {
-    const res = await fetch("http://localhost:8080/api/v1/stats/", {
-      method: "GET",
-      headers: {
-        Authorization: `Bearer ${$token}`,
-      },
-    });
-    if (res.ok) {
-      json = res.json();
-    } else {
-      throw new Error("There was a problem with your request");
+    function onStatisticAdd() {
+        open = false;
+        fetchData();
     }
-  }
 
-  async function submitStat() {
-    const response = await fetch("http://localhost:8080/api/v1/stats/", {
-      method: "POST",
-      headers: {
-        Authorization: `Bearer ${$token}`,
-      },
-      body: JSON.stringify({
-        date: new Date(),
-        user_id: 1,
-        quantity: 3,
-      }),
+    onMount(() => {
+        fetchData();
+        chart = new Chart(canvasRef, {
+            type: "bar",
+            data: {
+                labels: ["one", "two"],
+                datasets: [
+                    {
+                        label: "Water",
+                        data: [1, 2],
+                        backgroundColor: "rgba(75, 192, 192, 0.2)",
+                        borderColor: "rgba(75, 192, 192, 1)",
+                        borderWidth: 1
+                    }
+                ]
+            }
+        });
     });
-    fetchData();
-  }
-
-  function handleClick() {
-    showAddForm = true;
-  }
-
-  function handleAddDialogSubmit(e: Event) {
-    console.log(statistic);
-    showAddForm = false;
-  }
-
-  function closeDialog() {
-    showAddForm = false;
-  }
 
-  function newStatistic(): Statistic {
-    let now = new Date(),
-      month,
-      day,
-      year;
-
-    month = `${now.getMonth() + 1}`;
-    day = `${now.getDate()}`;
-    year = now.getFullYear();
-    if (month.length < 2) month = "0" + month;
-    if (day.length < 2) day = "0" + day;
-
-    const date = [year, month, day].join("-");
-
-    return {
-      user_id: $user!.uuid,
-      date,
-      quantity: 1,
-    };
-  }
-
-  onMount(() => {
-    fetchData();
-    chart = new Chart(canvasRef, {
-        type: 'bar',
-        data: {
-            labels: ['one', 'two'],
-            datasets: [
-                {
-                    label: 'Water',
-                    data: [1, 2],
-                    backgroundColor: 'rgba(75, 192, 192, 0.2)',
-                    borderColor: 'rgba(75, 192, 192, 1)',
-                    borderWidth: 1
-                }
-            ]
-        }
+    onDestroy(() => {
+        if (chart) chart.destroy();
+        chart = null;
     });
-  });
-
-  onDestroy(() => {
-    if (chart) chart.destroy();
-    chart = null;
-  });
 </script>
 
 <div>
-  <button on:click={submitStat}>Add Stat Test</button>
-  <dialog open={showAddForm} on:submit={handleAddDialogSubmit}>
-    <h2>Add Water</h2>
-    <form method="dialog">
-      <div class="form input group">
-        <label for="date">Date:</label>
-        <input bind:value={statistic.date} id="date" name="date" type="date" />
-      </div>
-      <div class="form input group">
-        <label for="quantity">Quantity:</label>
-        <input
-          bind:value={statistic.quantity}
-          id="quantity"
-          name="quantity"
-          type="number"
-          min="0"
-          autocomplete="off"
-        />
-      </div>
-      <button on:click={closeDialog}>Cancel</button>
-      <button type="submit">Submit</button>
-    </form>
-  </dialog>
-  <button on:click={handleClick}>Add</button>
-  <canvas bind:this={canvasRef} />
-  {#await json then data}
-    <Table {data} nofooter />
-  {:catch error}
-    <p>{error}</p>
-  {/await}
-  <!-- <Chart /> -->
+    <button on:click={handleClick}>Add</button>
+    <canvas bind:this={canvasRef} />
+    <AddForm {open} on:submit={onStatisticAdd} on:close={closeDialog} />
+    {#await json then data}
+        <Table {data} nofooter />
+    {:catch error}
+        <p>{error}</p>
+    {/await}
+    <!-- <Chart /> -->
 </div>
 
 <style>
-  dialog {
-    background: red;
-    box-shadow: 0 20px 5em 10px rgba(0, 0, 0, 0.8);
-  }
-  dialog::backdrop {
-    padding: 20px;
-    box-shadow: 20px 20px rgba(0, 0, 0, 0.8);
-    background-color: red;
-  }
+    dialog {
+        background: red;
+        box-shadow: 0 20px 5em 10px rgba(0, 0, 0, 0.8);
+    }
+
+    dialog::backdrop {
+        padding: 20px;
+        box-shadow: 20px 20px rgba(0, 0, 0, 0.8);
+        background-color: red;
+    }
 </style>
-- 
cgit v1.1


From 326f186d67017f87e631a1fbcdf3f184cbc42d7d Mon Sep 17 00:00:00 2001
From: Zach Berwaldt <zberwaldt@tutamail.com>
Date: Fri, 1 Mar 2024 20:26:42 -0500
Subject: feat: Add last seven days labels to chart

In the `DataView.svelte` component, the last seven days are now included as labels in the chart. This allows users to easily visualize data for the past week. The `getLastSevenDays` function generates an array of string values representing the dates in ISO format. This array is assigned to the `lastSevenDays` variable, which is then used as the labels in the chart's dataset.
---
 fe/src/lib/DataView.svelte | 27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)

(limited to 'fe/src/lib/DataView.svelte')

diff --git a/fe/src/lib/DataView.svelte b/fe/src/lib/DataView.svelte
index 7f368c6..5182a85 100644
--- a/fe/src/lib/DataView.svelte
+++ b/fe/src/lib/DataView.svelte
@@ -12,6 +12,8 @@
     let canvasRef: HTMLCanvasElement;
     let chart: any;
 
+    let lastSevenDays: string[];
+
     async function fetchData() {
         const res = await fetch("http://localhost:8080/api/v1/stats/", {
             method: "GET",
@@ -26,6 +28,16 @@
         }
     }
 
+    function getLastSevenDays() {
+        const result = [];
+        for (let i = 0; i < 7; i++) {
+            let d = new Date();
+            d.setDate(d.getDate() - i);
+            result.push(d.toISOString().substring(0, 10));
+        }
+        return result;
+    }
+
     function handleClick() {
         open = true;
     }
@@ -41,14 +53,21 @@
 
     onMount(() => {
         fetchData();
+        lastSevenDays = getLastSevenDays();
         chart = new Chart(canvasRef, {
             type: "bar",
             data: {
-                labels: ["one", "two"],
+                labels: lastSevenDays,
                 datasets: [
                     {
-                        label: "Water",
-                        data: [1, 2],
+                        label: "Zach",
+                        data: [1, 2, 8, 2, 5, 5, 1],
+                        backgroundColor: "rgba(255, 192, 192, 0.2)",
+                        borderColor: "rgba(75, 192, 192, 1)",
+                        borderWidth: 1
+                    }, {
+                        label: "Parker",
+                        data: [6, 1, 1, 4, 3, 5, 1],
                         backgroundColor: "rgba(75, 192, 192, 0.2)",
                         borderColor: "rgba(75, 192, 192, 1)",
                         borderWidth: 1
@@ -66,8 +85,8 @@
 
 <div>
     <button on:click={handleClick}>Add</button>
-    <canvas bind:this={canvasRef} />
     <AddForm {open} on:submit={onStatisticAdd} on:close={closeDialog} />
+    <canvas bind:this={canvasRef} />
     {#await json then data}
         <Table {data} nofooter />
     {:catch error}
-- 
cgit v1.1


From cf2113e77edabf8e3a632c7b76c769752039ba88 Mon Sep 17 00:00:00 2001
From: Zach Berwaldt <zberwaldt@tutamail.com>
Date: Sat, 2 Mar 2024 16:52:55 -0500
Subject: feat: Add API logging

Add logging to the API to keep track of specific requests and headers. Also added CORS middleware to handle OPTIONS requests.

---

The commit adds logging functionality to the API and includes a middleware function to handle CORS OPTIONS requests. This will allow us to track specific requests and headers received by the API.

[API/main.go](/api/main.go):
- Added import for the 'log' package
- Added logging statements to print the request headers and "_I am here_" message
- Removed unnecessary newlines and comments

[fe/src/app.css](/fe/src/app.css):
- Added a new style for button hover effects

[fe/src/lib/Card.svelte](/fe/src/lib/Card.svelte):
- Added a new `height` prop to the Card component

[fe/src/lib/Column.svelte](/fe/src/lib/Column.svelte):
- Added a new CSS class for column layout
- Set the width and gap using CSS variables

[fe/src/lib/DataView.svelte](/fe/src/lib/DataView.svelte):
- Updated the 'fetchData' function to also fetch 'totals' and 'userStats' data
- Added canvas references and chart variables for bar and line charts
- Added a new 'getLastSevenDays' function to calculate the labels for the charts
- Updated the 'onMount' function to initialize the bar and line charts using the canvas references and data
- Updated the 'onDestroy' function to destroy the bar and line charts
- Added a new 'addFormOpen' store and imported it
- Added a new 'onClick' handler for the Add button to open the AddForm modal
- Updated the layout and added Card components to display the bar and line charts and the JSON data
- Added a new 'fetchTotals' function to fetch data for the 'totals' section
- Added a new 'fetchStatsForUser' function to fetch data for the 'userStats' section

[fe/src/lib/Layout.svelte](/fe/src/lib/Layout.svelte):
- Added a new 'preferenceFormOpen' variable and initialized it to 'false'
- Added a new 'showPreferencesDialog' function to set 'preferenceFormOpen' to 'true'
- Added a new 'closePreferenceDialog' function to set 'preferenceFormOpen' to 'false'
- Added a new 'showAddDialog' function to open the AddForm modal
---
 fe/src/lib/DataView.svelte | 129 ++++++++++++++++++++++++++++++++++++---------
 1 file changed, 105 insertions(+), 24 deletions(-)

(limited to 'fe/src/lib/DataView.svelte')

diff --git a/fe/src/lib/DataView.svelte b/fe/src/lib/DataView.svelte
index 5182a85..2b1b8b9 100644
--- a/fe/src/lib/DataView.svelte
+++ b/fe/src/lib/DataView.svelte
@@ -1,16 +1,21 @@
 <script lang="ts">
     import { onDestroy, onMount } from "svelte";
     import { token } from "../stores/auth";
+    import { addFormOpen } from "../stores/forms";
     import Table from "./Table.svelte";
     import Chart from "chart.js/auto";
+    import Card from "./Card.svelte";
+    import Column from "./Column.svelte";
     import AddForm from "./forms/AddForm.svelte";
 
-    let open: boolean = false;
-
     let json: Promise<any>;
+    let totals: Promise<any>;
+    let userStats: Promise<any>;
 
-    let canvasRef: HTMLCanvasElement;
-    let chart: any;
+    let barCanvasRef: HTMLCanvasElement;
+    let lineCanvasRef: HTMLCanvasElement;
+    let barChart: any;
+    let lineChart: any;
 
     let lastSevenDays: string[];
 
@@ -28,6 +33,37 @@
         }
     }
 
+    async function fetchTotals() {
+        const res = await fetch("http://localhost:8080/api/v1/stats/totals/", {
+            method: 'GET',
+            mode: 'no-cors',
+            headers: {
+                Authorization: `Bearer ${$token}`
+            }
+        });
+
+        if (res.ok) {
+            totals = res.json();
+        } else {
+            throw new Error("There was a problem with your request");
+        }
+    }
+
+    async function fetchStatsForUser() {
+        const res = await fetch("http://localhost:8080/api/v1/stats/user/1aa668f3-7527-4a67-9c24-fdf307542eeb", {
+            method: "GET",
+            headers: {
+                Authorization: `Bearer ${$token}`
+            }
+        });
+
+        if (res.ok) {
+            userStats = res.json();
+        } else {
+            throw new Error("There was a problem with your request");
+        }
+    }
+
     function getLastSevenDays() {
         const result = [];
         for (let i = 0; i < 7; i++) {
@@ -38,23 +74,21 @@
         return result;
     }
 
-    function handleClick() {
-        open = true;
-    }
-
     function closeDialog() {
-        open = false;
+        addFormOpen.set(false);
     }
 
     function onStatisticAdd() {
-        open = false;
+        closeDialog();
         fetchData();
     }
 
     onMount(() => {
         fetchData();
+//        fetchTotals();
+        fetchStatsForUser();
         lastSevenDays = getLastSevenDays();
-        chart = new Chart(canvasRef, {
+        barChart = new Chart(barCanvasRef, {
             type: "bar",
             data: {
                 labels: lastSevenDays,
@@ -73,27 +107,74 @@
                         borderWidth: 1
                     }
                 ]
+            },
+            options: {
+                responsive: true
+            }
+        });
+        lineChart = new Chart(lineCanvasRef, {
+            type: "line",
+            data: {
+                labels: lastSevenDays,
+                datasets: [
+                    {
+                        label: "Zach",
+                        data: [1, 2, 8, 2, 5, 5, 1],
+                        backgroundColor: "rgba(255, 192, 192, 0.2)",
+                        borderColor: "rgba(75, 192, 192, 1)",
+                        borderWidth: 1
+                    }, {
+                        label: "Parker",
+                        data: [6, 1, 1, 4, 3, 5, 1],
+                        backgroundColor: "rgba(75, 192, 192, 0.2)",
+                        borderColor: "rgba(75, 192, 192, 1)",
+                        borderWidth: 1
+                    }
+                ]
+            },
+            options: {
+                responsive: true
             }
         });
     });
 
     onDestroy(() => {
-        if (chart) chart.destroy();
-        chart = null;
+        if (barChart) barChart.destroy();
+        if (lineChart) lineChart.destroy();
+        barChart = null;
+        lineChart = null;
     });
 </script>
 
-<div>
-    <button on:click={handleClick}>Add</button>
-    <AddForm {open} on:submit={onStatisticAdd} on:close={closeDialog} />
-    <canvas bind:this={canvasRef} />
-    {#await json then data}
-        <Table {data} nofooter />
-    {:catch error}
-        <p>{error}</p>
-    {/await}
-    <!-- <Chart /> -->
-</div>
+<Column --width="500px">
+    <Card>
+        <canvas bind:this={barCanvasRef} width="" />
+    </Card>
+    <Card>
+        <canvas bind:this={lineCanvasRef} />
+    </Card>
+</Column>
+
+<AddForm open={$addFormOpen} on:submit={onStatisticAdd} on:close={closeDialog} />
+<Column>
+    <Card>
+        {#await json then data}
+            <Table {data} nofooter />
+        {:catch error}
+            <p>{error}</p>
+        {/await}
+    </Card>
+    <Card>
+        <button on:click={() => fetchTotals()}>Get totals</button>
+        {#await totals then data}
+            {JSON.stringify(data)}
+        {:catch error}
+            <p>{error}</p>
+        {/await}
+    </Card>
+</Column>
+<!-- <Chart /> -->
+
 
 <style>
     dialog {
-- 
cgit v1.1


From 5fa57845052655883120ba4d19a85d8756fb8d8c Mon Sep 17 00:00:00 2001
From: Zach Berwaldt <zberwaldt@tutamail.com>
Date: Wed, 6 Mar 2024 21:53:07 -0500
Subject: [FEAT] Refactor API main file and models

This commit refactors the `main.go` file in the API directory, as well as the related models in the `models.go` file. The changes include:

- Reordering imports and removing unnecessary imports
- Fixing error messages to be more descriptive
- Handling database connections more efficiently with deferred closures
- Handling errors and returning appropriate error responses
- Adding proper JSON bindings for POST requests
- Adding new views in the database scripts for aggregated statistics and daily user statistics

No changes were made to imports and requires.
---
 fe/src/lib/DataView.svelte | 130 ++++++++++++++++++++++++---------------------
 1 file changed, 69 insertions(+), 61 deletions(-)

(limited to 'fe/src/lib/DataView.svelte')

diff --git a/fe/src/lib/DataView.svelte b/fe/src/lib/DataView.svelte
index 2b1b8b9..7d62a43 100644
--- a/fe/src/lib/DataView.svelte
+++ b/fe/src/lib/DataView.svelte
@@ -9,8 +9,6 @@
     import AddForm from "./forms/AddForm.svelte";
 
     let json: Promise<any>;
-    let totals: Promise<any>;
-    let userStats: Promise<any>;
 
     let barCanvasRef: HTMLCanvasElement;
     let lineCanvasRef: HTMLCanvasElement;
@@ -18,6 +16,10 @@
     let lineChart: any;
 
     let lastSevenDays: string[];
+    let lastSevenDaysData: number[];
+
+    let userTotalsLabels: string[];
+    let userTotalsData: number[];
 
     async function fetchData() {
         const res = await fetch("http://localhost:8080/api/v1/stats/", {
@@ -33,24 +35,27 @@
         }
     }
 
-    async function fetchTotals() {
+    async function fetchDailyUserStatistics() {
         const res = await fetch("http://localhost:8080/api/v1/stats/totals/", {
-            method: 'GET',
-            mode: 'no-cors',
+            method: "GET",
             headers: {
                 Authorization: `Bearer ${$token}`
             }
         });
 
         if (res.ok) {
-            totals = res.json();
+            const json = await res.json();
+            let labels = json.map(d => d.name);
+            let data = json.map(d => d.total);
+            return [labels, data];
         } else {
             throw new Error("There was a problem with your request");
         }
+
     }
 
-    async function fetchStatsForUser() {
-        const res = await fetch("http://localhost:8080/api/v1/stats/user/1aa668f3-7527-4a67-9c24-fdf307542eeb", {
+    async function fetchWeeklyTotals() {
+        const res = await fetch("http://localhost:8080/api/v1/stats/weekly/", {
             method: "GET",
             headers: {
                 Authorization: `Bearer ${$token}`
@@ -58,22 +63,15 @@
         });
 
         if (res.ok) {
-            userStats = res.json();
+            const json = await res.json();
+            let labels = json.map(d => d.date);
+            let data = json.map(d => d.total);
+            return [labels, data];
         } else {
             throw new Error("There was a problem with your request");
         }
     }
 
-    function getLastSevenDays() {
-        const result = [];
-        for (let i = 0; i < 7; i++) {
-            let d = new Date();
-            d.setDate(d.getDate() - i);
-            result.push(d.toISOString().substring(0, 10));
-        }
-        return result;
-    }
-
     function closeDialog() {
         addFormOpen.set(false);
     }
@@ -81,61 +79,79 @@
     function onStatisticAdd() {
         closeDialog();
         fetchData();
+        fetchWeeklyTotals().then(updateWeeklyTotalsChart).catch(err => console.error(err));
+        fetchDailyUserStatistics().then(updateDailyUserTotalsChart).catch(err => console.error(err));
     }
 
-    onMount(() => {
-        fetchData();
-//        fetchTotals();
-        fetchStatsForUser();
-        lastSevenDays = getLastSevenDays();
-        barChart = new Chart(barCanvasRef, {
-            type: "bar",
+    function setupWeeklyTotalsChart(result) {
+        [lastSevenDays, lastSevenDaysData] = result;
+        lineChart = new Chart(lineCanvasRef, {
+            type: "line",
             data: {
                 labels: lastSevenDays,
                 datasets: [
                     {
-                        label: "Zach",
-                        data: [1, 2, 8, 2, 5, 5, 1],
-                        backgroundColor: "rgba(255, 192, 192, 0.2)",
-                        borderColor: "rgba(75, 192, 192, 1)",
-                        borderWidth: 1
-                    }, {
-                        label: "Parker",
-                        data: [6, 1, 1, 4, 3, 5, 1],
-                        backgroundColor: "rgba(75, 192, 192, 0.2)",
-                        borderColor: "rgba(75, 192, 192, 1)",
-                        borderWidth: 1
+                        label: "Totals",
+                        data: lastSevenDaysData,
+                        backgroundColor: "rgba(255, 192, 192, 0.2)"
                     }
                 ]
             },
             options: {
-                responsive: true
+                responsive: true,
+                plugins: {
+                    legend: {
+                        display: false
+                    }
+                }
             }
         });
-        lineChart = new Chart(lineCanvasRef, {
-            type: "line",
+    }
+
+    function setupDailyUserTotalsChart(result) {
+        [userTotalsLabels, userTotalsData] = result;
+
+        barChart = new Chart(barCanvasRef, {
+            type: "bar",
             data: {
-                labels: lastSevenDays,
+                labels: userTotalsLabels,
                 datasets: [
                     {
-                        label: "Zach",
-                        data: [1, 2, 8, 2, 5, 5, 1],
-                        backgroundColor: "rgba(255, 192, 192, 0.2)",
-                        borderColor: "rgba(75, 192, 192, 1)",
-                        borderWidth: 1
-                    }, {
-                        label: "Parker",
-                        data: [6, 1, 1, 4, 3, 5, 1],
-                        backgroundColor: "rgba(75, 192, 192, 0.2)",
-                        borderColor: "rgba(75, 192, 192, 1)",
-                        borderWidth: 1
+                        data: userTotalsData,
+                        backgroundColor: [
+                            "#330000",
+                            "rgba(100, 200, 192, 0.2)"
+                        ]
                     }
                 ]
             },
             options: {
-                responsive: true
+                responsive: true,
+                plugins: {
+                    legend: {
+                        display: false
+                    }
+                }
             }
         });
+    }
+
+    function updateWeeklyTotalsChart(result) {
+        [,lastSevenDaysData] = result;
+        lineChart.data.datasets[0].data = lastSevenDaysData;
+        lineChart.update();
+    }
+
+    function updateDailyUserTotalsChart(result) {
+        [,userTotalsData] = result;
+        barChart.data.datasets[0].data = userTotalsData;
+        barChart.update();
+    }
+
+    onMount(() => {
+        fetchData();
+        fetchWeeklyTotals().then(setupWeeklyTotalsChart);
+        fetchDailyUserStatistics().then(setupDailyUserTotalsChart);
     });
 
     onDestroy(() => {
@@ -164,14 +180,6 @@
             <p>{error}</p>
         {/await}
     </Card>
-    <Card>
-        <button on:click={() => fetchTotals()}>Get totals</button>
-        {#await totals then data}
-            {JSON.stringify(data)}
-        {:catch error}
-            <p>{error}</p>
-        {/await}
-    </Card>
 </Column>
 <!-- <Chart /> -->
 
-- 
cgit v1.1


From 8fab2d03bce82e4dee798ebffb1e93c557f62a4b Mon Sep 17 00:00:00 2001
From: Zach Berwaldt <zberwaldt@tutamail.com>
Date: Thu, 7 Mar 2024 23:16:22 -0500
Subject: feat: Update authentication route and add comments to exported
 members

- The authentication route in the API has been updated to use a new router setup function.
- Comments have been added to all exported members of the `auth.go` module in the internal controllers package.
---
 fe/src/lib/DataView.svelte | 53 ++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 47 insertions(+), 6 deletions(-)

(limited to 'fe/src/lib/DataView.svelte')

diff --git a/fe/src/lib/DataView.svelte b/fe/src/lib/DataView.svelte
index 7d62a43..0a6b81b 100644
--- a/fe/src/lib/DataView.svelte
+++ b/fe/src/lib/DataView.svelte
@@ -1,5 +1,6 @@
 <script lang="ts">
     import { onDestroy, onMount } from "svelte";
+    import HttpClient from "../http";
     import { token } from "../stores/auth";
     import { addFormOpen } from "../stores/forms";
     import Table from "./Table.svelte";
@@ -36,7 +37,7 @@
     }
 
     async function fetchDailyUserStatistics() {
-        const res = await fetch("http://localhost:8080/api/v1/stats/totals/", {
+        const res = await fetch("http://localhost:8080/api/v1/stats/daily/", {
             method: "GET",
             headers: {
                 Authorization: `Bearer ${$token}`
@@ -99,9 +100,29 @@
             },
             options: {
                 responsive: true,
+                maintainAspectRatio: false,
+                scales: {
+                    y: {
+                        suggestedMax: 30,
+                        beginAtZero: true,
+                        ticks: {
+                            autoSkip: true,
+                            stepSize: 5
+                        }
+                    }
+                },
                 plugins: {
                     legend: {
                         display: false
+                    },
+                    title: {
+                        display: true,
+                        text: "Weekly Breakdown"
+                    },
+                    subtitle: {
+                        display: true,
+                        text: "Water consumption over the last week",
+                        padding: {bottom: 10}
                     }
                 }
             }
@@ -127,9 +148,29 @@
             },
             options: {
                 responsive: true,
+                maintainAspectRatio: false,
+                scales: {
+                    y: {
+                        beginAtZero: true,
+                        suggestedMax: 10,
+                        ticks: {
+                            autoSkip: true,
+                            stepSize: 1
+                        }
+                    }
+                },
                 plugins: {
                     legend: {
                         display: false
+                    },
+                    title: {
+                        display: true,
+                        text: "Daily Total"
+                    },
+                    subtitle: {
+                        display: true,
+                        text: "Water Drank Today",
+                        padding: {bottom: 10}
                     }
                 }
             }
@@ -137,13 +178,13 @@
     }
 
     function updateWeeklyTotalsChart(result) {
-        [,lastSevenDaysData] = result;
+        [, lastSevenDaysData] = result;
         lineChart.data.datasets[0].data = lastSevenDaysData;
         lineChart.update();
     }
 
     function updateDailyUserTotalsChart(result) {
-        [,userTotalsData] = result;
+        [, userTotalsData] = result;
         barChart.data.datasets[0].data = userTotalsData;
         barChart.update();
     }
@@ -163,10 +204,10 @@
 </script>
 
 <Column --width="500px">
-    <Card>
-        <canvas bind:this={barCanvasRef} width="" />
+    <Card --height="300px">
+        <canvas bind:this={barCanvasRef} />
     </Card>
-    <Card>
+    <Card --height="300px">
         <canvas bind:this={lineCanvasRef} />
     </Card>
 </Column>
-- 
cgit v1.1


From 9cae9c1d2a0b4f7fa72f3075541b9ffafe1a7275 Mon Sep 17 00:00:00 2001
From: Zach Berwaldt <zberwaldt@tutamail.com>
Date: Fri, 15 Mar 2024 18:49:43 -0400
Subject: Add routes for preference, clean up and add types

---
 fe/src/lib/DataView.svelte | 40 ++++++++++++++--------------------------
 1 file changed, 14 insertions(+), 26 deletions(-)

(limited to 'fe/src/lib/DataView.svelte')

diff --git a/fe/src/lib/DataView.svelte b/fe/src/lib/DataView.svelte
index 0a6b81b..5e81a5a 100644
--- a/fe/src/lib/DataView.svelte
+++ b/fe/src/lib/DataView.svelte
@@ -1,10 +1,11 @@
 <script lang="ts">
     import { onDestroy, onMount } from "svelte";
-    import HttpClient from "../http";
+    import http from "../http";
     import { token } from "../stores/auth";
     import { addFormOpen } from "../stores/forms";
     import Table from "./Table.svelte";
-    import Chart from "chart.js/auto";
+    import ChartJS from "chart.js/auto";
+    import Chart from './Chart.svelte'
     import Card from "./Card.svelte";
     import Column from "./Column.svelte";
     import AddForm from "./forms/AddForm.svelte";
@@ -46,8 +47,8 @@
 
         if (res.ok) {
             const json = await res.json();
-            let labels = json.map(d => d.name);
-            let data = json.map(d => d.total);
+            let labels = json.map((d: any) => d.name);
+            let data = json.map((d: any) => d.total);
             return [labels, data];
         } else {
             throw new Error("There was a problem with your request");
@@ -65,8 +66,8 @@
 
         if (res.ok) {
             const json = await res.json();
-            let labels = json.map(d => d.date);
-            let data = json.map(d => d.total);
+            let labels = json.map((d: any) => d.date);
+            let data = json.map((d: any) => d.total);
             return [labels, data];
         } else {
             throw new Error("There was a problem with your request");
@@ -84,9 +85,9 @@
         fetchDailyUserStatistics().then(updateDailyUserTotalsChart).catch(err => console.error(err));
     }
 
-    function setupWeeklyTotalsChart(result) {
+    function setupWeeklyTotalsChart(result: any) {
         [lastSevenDays, lastSevenDaysData] = result;
-        lineChart = new Chart(lineCanvasRef, {
+        lineChart = new ChartJS(lineCanvasRef, {
             type: "line",
             data: {
                 labels: lastSevenDays,
@@ -129,10 +130,10 @@
         });
     }
 
-    function setupDailyUserTotalsChart(result) {
+    function setupDailyUserTotalsChart(result: any) {
         [userTotalsLabels, userTotalsData] = result;
 
-        barChart = new Chart(barCanvasRef, {
+        barChart = new ChartJS(barCanvasRef, {
             type: "bar",
             data: {
                 labels: userTotalsLabels,
@@ -177,13 +178,13 @@
         });
     }
 
-    function updateWeeklyTotalsChart(result) {
+    function updateWeeklyTotalsChart(result: any) {
         [, lastSevenDaysData] = result;
         lineChart.data.datasets[0].data = lastSevenDaysData;
         lineChart.update();
     }
 
-    function updateDailyUserTotalsChart(result) {
+    function updateDailyUserTotalsChart(result: any) {
         [, userTotalsData] = result;
         barChart.data.datasets[0].data = userTotalsData;
         barChart.update();
@@ -205,6 +206,7 @@
 
 <Column --width="500px">
     <Card --height="300px">
+        <!--<Chart />-->
         <canvas bind:this={barCanvasRef} />
     </Card>
     <Card --height="300px">
@@ -223,17 +225,3 @@
     </Card>
 </Column>
 <!-- <Chart /> -->
-
-
-<style>
-    dialog {
-        background: red;
-        box-shadow: 0 20px 5em 10px rgba(0, 0, 0, 0.8);
-    }
-
-    dialog::backdrop {
-        padding: 20px;
-        box-shadow: 20px 20px rgba(0, 0, 0, 0.8);
-        background-color: red;
-    }
-</style>
-- 
cgit v1.1


From fd1332a3df191577e91c6d846a8b5db1747099fd Mon Sep 17 00:00:00 2001
From: Zach Berwaldt <zberwaldt@tutamail.com>
Date: Fri, 15 Mar 2024 22:00:10 -0400
Subject: cleanup

---
 fe/src/lib/DataView.svelte | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

(limited to 'fe/src/lib/DataView.svelte')

diff --git a/fe/src/lib/DataView.svelte b/fe/src/lib/DataView.svelte
index 5e81a5a..ffc2fe8 100644
--- a/fe/src/lib/DataView.svelte
+++ b/fe/src/lib/DataView.svelte
@@ -9,6 +9,7 @@
     import Card from "./Card.svelte";
     import Column from "./Column.svelte";
     import AddForm from "./forms/AddForm.svelte";
+    import { apiURL } from "../utils";
 
     let json: Promise<any>;
 
@@ -24,7 +25,7 @@
     let userTotalsData: number[];
 
     async function fetchData() {
-        const res = await fetch("http://localhost:8080/api/v1/stats/", {
+        const res = await fetch(apiURL("stats"), {
             method: "GET",
             headers: {
                 Authorization: `Bearer ${$token}`
@@ -38,7 +39,7 @@
     }
 
     async function fetchDailyUserStatistics() {
-        const res = await fetch("http://localhost:8080/api/v1/stats/daily/", {
+        const res = await fetch(apiURL("stats/daily"), {
             method: "GET",
             headers: {
                 Authorization: `Bearer ${$token}`
@@ -57,7 +58,7 @@
     }
 
     async function fetchWeeklyTotals() {
-        const res = await fetch("http://localhost:8080/api/v1/stats/weekly/", {
+        const res = await fetch(apiURL("stats/weekly"), {
             method: "GET",
             headers: {
                 Authorization: `Bearer ${$token}`
-- 
cgit v1.1

