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 | ||
