aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZach Berwaldt <zberwaldt@tutamail.com>2024-03-01 20:12:21 -0500
committerZach Berwaldt <zberwaldt@tutamail.com>2024-03-01 20:12:21 -0500
commitd8b0f1335078d53d95a4212b1a4d4b0b28016702 (patch)
tree691eb6ec3ffc2e3cfad0016ad3e339bdc6616184
parent74ec025991f6acde6383e448974738e857758ebb (diff)
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.
-rw-r--r--fe/src/lib/DataView.svelte206
-rw-r--r--fe/src/lib/forms/AddForm.svelte74
2 files changed, 148 insertions, 132 deletions
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 @@
1<script lang="ts"> 1<script lang="ts">
2 import { onDestroy, onMount } from "svelte"; 2 import { onDestroy, onMount } from "svelte";
3 import type { Statistic } from "../types"; 3 import { token } from "../stores/auth";
4 import { token, user } from "../stores/auth"; 4 import Table from "./Table.svelte";
5 import Table from "./Table.svelte"; 5 import Chart from "chart.js/auto";
6 import Chart from 'chart.js/auto'; 6 import AddForm from "./forms/AddForm.svelte";
7 7
8 let json: Promise<any>; 8 let open: boolean = false;
9 let showAddForm: boolean = false; 9
10 let json: Promise<any>;
11
12 let canvasRef: HTMLCanvasElement;
13 let chart: any;
14
15 async function fetchData() {
16 const res = await fetch("http://localhost:8080/api/v1/stats/", {
17 method: "GET",
18 headers: {
19 Authorization: `Bearer ${$token}`
20 }
21 });
22 if (res.ok) {
23 json = res.json();
24 } else {
25 throw new Error("There was a problem with your request");
26 }
27 }
10 28
11 let canvasRef: HTMLCanvasElement; 29 function handleClick() {
12 let chart: any; 30 open = true;
31 }
13 32
14 let statistic: Statistic = newStatistic(); 33 function closeDialog() {
34 open = false;
35 }
15 36
16 async function fetchData() { 37 function onStatisticAdd() {
17 const res = await fetch("http://localhost:8080/api/v1/stats/", { 38 open = false;
18 method: "GET", 39 fetchData();
19 headers: {
20 Authorization: `Bearer ${$token}`,
21 },
22 });
23 if (res.ok) {
24 json = res.json();
25 } else {
26 throw new Error("There was a problem with your request");
27 } 40 }
28 }
29 41
30 async function submitStat() { 42 onMount(() => {
31 const response = await fetch("http://localhost:8080/api/v1/stats/", { 43 fetchData();
32 method: "POST", 44 chart = new Chart(canvasRef, {
33 headers: { 45 type: "bar",
34 Authorization: `Bearer ${$token}`, 46 data: {
35 }, 47 labels: ["one", "two"],
36 body: JSON.stringify({ 48 datasets: [
37 date: new Date(), 49 {
38 user_id: 1, 50 label: "Water",
39 quantity: 3, 51 data: [1, 2],
40 }), 52 backgroundColor: "rgba(75, 192, 192, 0.2)",
53 borderColor: "rgba(75, 192, 192, 1)",
54 borderWidth: 1
55 }
56 ]
57 }
58 });
41 }); 59 });
42 fetchData();
43 }
44
45 function handleClick() {
46 showAddForm = true;
47 }
48
49 function handleAddDialogSubmit(e: Event) {
50 console.log(statistic);
51 showAddForm = false;
52 }
53
54 function closeDialog() {
55 showAddForm = false;
56 }
57 60
58 function newStatistic(): Statistic { 61 onDestroy(() => {
59 let now = new Date(), 62 if (chart) chart.destroy();
60 month, 63 chart = null;
61 day,
62 year;
63
64 month = `${now.getMonth() + 1}`;
65 day = `${now.getDate()}`;
66 year = now.getFullYear();
67 if (month.length < 2) month = "0" + month;
68 if (day.length < 2) day = "0" + day;
69
70 const date = [year, month, day].join("-");
71
72 return {
73 user_id: $user!.uuid,
74 date,
75 quantity: 1,
76 };
77 }
78
79 onMount(() => {
80 fetchData();
81 chart = new Chart(canvasRef, {
82 type: 'bar',
83 data: {
84 labels: ['one', 'two'],
85 datasets: [
86 {
87 label: 'Water',
88 data: [1, 2],
89 backgroundColor: 'rgba(75, 192, 192, 0.2)',
90 borderColor: 'rgba(75, 192, 192, 1)',
91 borderWidth: 1
92 }
93 ]
94 }
95 }); 64 });
96 });
97
98 onDestroy(() => {
99 if (chart) chart.destroy();
100 chart = null;
101 });
102</script> 65</script>
103 66
104<div> 67<div>
105 <button on:click={submitStat}>Add Stat Test</button> 68 <button on:click={handleClick}>Add</button>
106 <dialog open={showAddForm} on:submit={handleAddDialogSubmit}> 69 <canvas bind:this={canvasRef} />
107 <h2>Add Water</h2> 70 <AddForm {open} on:submit={onStatisticAdd} on:close={closeDialog} />
108 <form method="dialog"> 71 {#await json then data}
109 <div class="form input group"> 72 <Table {data} nofooter />
110 <label for="date">Date:</label> 73 {:catch error}
111 <input bind:value={statistic.date} id="date" name="date" type="date" /> 74 <p>{error}</p>
112 </div> 75 {/await}
113 <div class="form input group"> 76 <!-- <Chart /> -->
114 <label for="quantity">Quantity:</label>
115 <input
116 bind:value={statistic.quantity}
117 id="quantity"
118 name="quantity"
119 type="number"
120 min="0"
121 autocomplete="off"
122 />
123 </div>
124 <button on:click={closeDialog}>Cancel</button>
125 <button type="submit">Submit</button>
126 </form>
127 </dialog>
128 <button on:click={handleClick}>Add</button>
129 <canvas bind:this={canvasRef} />
130 {#await json then data}
131 <Table {data} nofooter />
132 {:catch error}
133 <p>{error}</p>
134 {/await}
135 <!-- <Chart /> -->
136</div> 77</div>
137 78
138<style> 79<style>
139 dialog { 80 dialog {
140 background: red; 81 background: red;
141 box-shadow: 0 20px 5em 10px rgba(0, 0, 0, 0.8); 82 box-shadow: 0 20px 5em 10px rgba(0, 0, 0, 0.8);
142 } 83 }
143 dialog::backdrop { 84
144 padding: 20px; 85 dialog::backdrop {
145 box-shadow: 20px 20px rgba(0, 0, 0, 0.8); 86 padding: 20px;
146 background-color: red; 87 box-shadow: 20px 20px rgba(0, 0, 0, 0.8);
147 } 88 background-color: red;
89 }
148</style> 90</style>
diff --git a/fe/src/lib/forms/AddForm.svelte b/fe/src/lib/forms/AddForm.svelte
new file mode 100644
index 0000000..f22e5f4
--- /dev/null
+++ b/fe/src/lib/forms/AddForm.svelte
@@ -0,0 +1,74 @@
1<script lang='ts'>
2 import { createEventDispatcher } from "svelte";
3 import { token, user } from "../../stores/auth";
4 import type { Statistic } from "../../types";
5
6 export let open: boolean;
7
8 const dispatch = createEventDispatcher();
9
10 const statistic: Statistic = newStatistic();
11
12 function newStatistic(): Statistic {
13 let now = new Date(),
14 month,
15 day,
16 year;
17
18 month = `${now.getMonth() + 1}`;
19 day = `${now.getDate()}`;
20 year = now.getFullYear();
21 if (month.length < 2) month = "0" + month;
22 if (day.length < 2) day = "0" + day;
23
24 const date = [year, month, day].join("-");
25
26 return {
27 user_id: $user!.uuid,
28 date,
29 quantity: 1
30 };
31 }
32
33 function closeDialog() {
34 dispatch("close");
35 }
36
37 async function handleSubmitStat() {
38 const response = await fetch("http://localhost:8080/api/v1/stats/", {
39 method: "POST",
40 headers: {
41 Authorization: `Bearer ${$token}`
42 },
43 body: JSON.stringify({
44 date: new Date(),
45 user_id: 1,
46 quantity: 3
47 })
48 });
49 dispatch("submit");
50 }
51</script>
52
53<dialog {open} on:submit={handleSubmitStat}>
54 <h2>Add Water</h2>
55 <form method="dialog">
56 <div class="form input group">
57 <label for="date">Date:</label>
58 <input bind:value={statistic.date} id="date" name="date" type="date" />
59 </div>
60 <div class="form input group">
61 <label for="quantity">Quantity:</label>
62 <input
63 bind:value={statistic.quantity}
64 id="quantity"
65 name="quantity"
66 type="number"
67 min="0"
68 autocomplete="off"
69 />
70 </div>
71 <button on:click={closeDialog}>Cancel</button>
72 <button type="submit">Submit</button>
73 </form>
74</dialog> \ No newline at end of file