diff options
author | Zach Berwaldt <zberwaldt@tutamail.com> | 2024-03-01 20:12:21 -0500 |
---|---|---|
committer | Zach Berwaldt <zberwaldt@tutamail.com> | 2024-03-01 20:12:21 -0500 |
commit | d8b0f1335078d53d95a4212b1a4d4b0b28016702 (patch) | |
tree | 691eb6ec3ffc2e3cfad0016ad3e339bdc6616184 | |
parent | 74ec025991f6acde6383e448974738e857758ebb (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.svelte | 206 | ||||
-rw-r--r-- | fe/src/lib/forms/AddForm.svelte | 74 |
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 | ||