Implement creating food

This commit is contained in:
2024-08-09 21:20:02 +02:00
parent db34fe039e
commit d9ae2e1ab3
10 changed files with 171 additions and 84 deletions

10
app.go
View File

@@ -28,7 +28,6 @@ func (a *App) GetFood() WailsFood {
} }
return WailsFood{Data: data, Success: true} return WailsFood{Data: data, Success: true}
} }
func (a *App) CreateFood(food Food) WailsFood1 { func (a *App) CreateFood(food Food) WailsFood1 {
data, err := foodService.Create(food) data, err := foodService.Create(food)
if err != nil { if err != nil {
@@ -36,7 +35,6 @@ func (a *App) CreateFood(food Food) WailsFood1 {
} }
return WailsFood1{Data: data, Success: true} return WailsFood1{Data: data, Success: true}
} }
func (a *App) UpdateFood(food Food) WailsFood1 { func (a *App) UpdateFood(food Food) WailsFood1 {
data, err := foodService.Update(food) data, err := foodService.Update(food)
if err != nil { if err != nil {
@@ -45,6 +43,14 @@ func (a *App) UpdateFood(food Food) WailsFood1 {
return WailsFood1{Data: data, Success: true} return WailsFood1{Data: data, Success: true}
} }
func (a *App) GetLastPer100(name string) WailsPer100 {
data, err := foodService.GetLastPer100(name)
if err != nil {
return WailsPer100{Success: false, Error: err.Error()}
}
return WailsPer100{Data: data, Success: true}
}
// region settings // region settings
func (a *App) GetSettings() settings { func (a *App) GetSettings() settings {
return Settings return Settings

View File

@@ -56,6 +56,21 @@ func (s *FoodService) GetRecent() ([]Food, error) {
return res, nil return res, nil
} }
func (s *FoodService) GetLastPer100(name string) (float32, error) {
if s.db == nil || !s.db.Ready {
return 0, fmt.Errorf("cannot get last per100, db is nil or is not ready")
}
row := s.db.readConn.QueryRow("SELECT per100 FROM food WHERE food like ? ORDER BY rowid DESC LIMIT 1", name+"%")
var per100 float32
err := row.Scan(&per100)
if err != nil {
return 0, fmt.Errorf("error scanning row: %v", err)
}
return per100, nil
}
func (s *FoodService) Create(food Food) (Food, error) { func (s *FoodService) Create(food Food) (Food, error) {
if s.db == nil || !s.db.Ready { if s.db == nil || !s.db.Ready {
return food, fmt.Errorf("cannot create food, db is nil or is not ready") return food, fmt.Errorf("cannot create food, db is nil or is not ready")

View File

@@ -1,8 +1,10 @@
<script lang="ts"> <script lang="ts">
import Header from "$lib/components/Header.svelte"; import Header from "$lib/components/Header.svelte";
import Router from "$lib/router/Router.svelte"; import Router from "$lib/router/Router.svelte";
import { Toaster } from 'svelte-sonner'
</script> </script>
<Toaster />
<template> <template>
<Header /> <Header />
<main class="flex-1"> <main class="flex-1">

View File

@@ -1,8 +1,24 @@
<script lang="ts"> <script lang="ts">
import { foodStore } from "$lib/store/FoodStore"; import { foodStore } from "$lib/store/FoodStore";
import FoodTable from "./Food/FoodTable.svelte"; import FoodTable from "./Food/FoodTable.svelte";
// Fuck this hacky shit
// Svelte won't re-render FoodTable when using the store directly
// It won't do it when using a variable and subscribing to the store
// It won't do it when reassigning the store
// Not when pushing unshifting the store
// This is the only thing that works
// Hacky ass shit
let forceUpdate = false;
foodStore.subscribe(() => {
forceUpdate = !forceUpdate;
});
</script> </script>
<template> <template>
{#if forceUpdate}
<FoodTable items={$foodStore} /> <FoodTable items={$foodStore} />
{:else}
<FoodTable items={$foodStore} />
{/if}
</template> </template>

View File

@@ -1,95 +1,110 @@
<!-- <script lang="ts"> <script lang="ts">
import { type Food, FoodService } from '$lib/database/food' import { toast } from "svelte-sonner";
import { toast } from 'svelte-sonner' import { main } from "$wails/models";
import type { Err } from '$lib/types' import { CreateFood, GetLastPer100 } from "$wails/main/App";
import { foodStore } from '$lib/store/energy/foodStore' import { foodStore } from "$lib/store/FoodStore";
import { RefreshStores } from '$lib/utils'
let item: Food = { let item: main.Food = {
food: '', food: "",
amount: 0, amount: 0,
description: '' description: "",
} rowid: 0,
let name: string = '' date: "",
let amount: string = '' per100: 0,
let description: string = '' energy: 0,
let per100: string = '' };
let per100Edited: boolean = false let name: string = "";
let per100Element: HTMLTableCellElement let amount: string = "";
let description: string = "";
let per100: string = "";
let per100Edited: boolean = false;
let per100Element: HTMLTableCellElement;
async function update(event: KeyboardEvent & { currentTarget: (EventTarget & HTMLTableCellElement) }) { async function update(event: KeyboardEvent & { currentTarget: EventTarget & HTMLTableCellElement }) {
name = name.trim() name = name.trim();
amount = amount.trim() amount = amount.trim();
description = description.trim() description = description.trim();
per100 = per100.trim() per100 = per100.trim();
if (!per100Edited && event.currentTarget === per100Element) if (!per100Edited && event.currentTarget === per100Element) per100Edited = true;
per100Edited = true
if (event.key == 'Enter') { if (event.key == "Enter") {
event.preventDefault() event.preventDefault();
item.food = name item.food = name;
item.description = description item.description = description;
item.amount = parseInt(amount) item.amount = parseInt(amount);
item.per100 = parseInt(per100) item.per100 = parseInt(per100);
const [dbFood, err]: [Food, Err] = await FoodService.Create(item) const res = await CreateFood(item);
name = '' name = "";
amount = '' amount = "";
// description = '' // description = ''
per100 = '' per100 = "";
per100Edited = false per100Edited = false;
if (err) { if (!res.success) {
toast.error(err) toast.error(`failed to create item with error ${res.error}`);
return return;
} }
RefreshStores()
foodStore.update((value) => {
const updatedValue = [res.data, ...value];
console.log("Updated items:", updatedValue.length);
return updatedValue;
});
} }
if (!per100Edited) if (!per100Edited)
FoodService.GetLatestPer100(name.trim()).then((res) => { GetLastPer100(name.trim()).then((res) => {
if (res[1]) if (res.success) {
// toast.error(res[1]) per100 = res.data.toString();
return }
});
per100 = res[0].toString()
})
} }
</script> </script>
<template> <template>
<tr class="border-b border-gray-200 dark:border-gray-700 text-lg font-bold"> <tr class="border-b border-gray-200 dark:border-gray-700 text-lg font-bold">
<th class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap bg-gray-50 dark:text-white dark:bg-gray-800" <th
scope="row"> class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap bg-gray-50 dark:text-white dark:bg-gray-800"
scope="row"
>
</th> </th>
<td bind:innerText={name} <td
bind:innerText={name}
class:border-[3px]={!name} class:border-[3px]={!name}
class:border-red-600={!name} class:border-red-600={!name}
class="px-6 py-4 overflow-hidden" class="px-6 py-4 overflow-hidden"
contenteditable="true" contenteditable="true"
autofocus autofocus
on:keydown={update}> on:keydown={update}
>
</td> </td>
<td bind:innerText={description} <td
bind:innerText={description}
class="px-6 py-4 bg-gray-50 dark:bg-gray-800 overflow-hidden" class="px-6 py-4 bg-gray-50 dark:bg-gray-800 overflow-hidden"
contenteditable="true" contenteditable="true"
on:keydown={update}> on:keydown={update}
>
</td> </td>
<td bind:innerText={amount} <td
bind:innerText={amount}
class:border-[3px]={!amount} class:border-[3px]={!amount}
class:border-red-600={!amount} class:border-red-600={!amount}
class="px-6 py-4 overflow-hidden" class="px-6 py-4 overflow-hidden"
contenteditable="true" contenteditable="true"
on:keydown={update}> on:keydown={update}
>
</td> </td>
<td bind:this={per100Element} <td
bind:this={per100Element}
bind:innerText={per100} bind:innerText={per100}
class="px-6 py-4 bg-gray-50 dark:bg-gray-800 overflow-hidden" class="px-6 py-4 bg-gray-50 dark:bg-gray-800 overflow-hidden"
class:border-[3px]={!per100} class:border-[3px]={!per100}
class:border-orange-600={!per100} class:border-orange-600={!per100}
contenteditable="true" contenteditable="true"
on:keydown={update}> on:keydown={update}
>
</td> </td>
</tr> </tr>
</template> --> </template>

View File

@@ -8,11 +8,13 @@
let minCal = 1e5; let minCal = 1e5;
let maxCal = 0; let maxCal = 0;
$: {
for (let item of items) { for (let item of items) {
if (!item.energy) continue; if (!item.energy) continue;
if (item.energy > maxCal) maxCal = item.energy; if (item.energy > maxCal) maxCal = item.energy;
if (item.energy < minCal) minCal = item.energy; if (item.energy < minCal) minCal = item.energy;
} }
}
const start = "#99ff99"; const start = "#99ff99";
const end = "#ff9999"; const end = "#ff9999";
@@ -72,7 +74,12 @@
<tbody> <tbody>
<EmptyFoodComp /> <EmptyFoodComp />
{#each items as f} {#each items as f}
<FoodComp item="{f}" energyColor="{lerp(f)}" nameColor="{getNameColor(f)}" dateColor="{getDateColor(f)}" /> <FoodComp
item={f}
energyColor={lerp(f)}
nameColor={getNameColor(f)}
dateColor={getDateColor(f)}
/>
{/each} {/each}
</tbody> </tbody>
</table> </table>

View File

@@ -6,6 +6,8 @@ export function CreateFood(arg1:main.Food):Promise<main.WailsFood1>;
export function GetFood():Promise<main.WailsFood>; export function GetFood():Promise<main.WailsFood>;
export function GetLastPer100(arg1:string):Promise<main.WailsPer100>;
export function GetSettings():Promise<main.settings>; export function GetSettings():Promise<main.settings>;
export function SetSetting(arg1:string,arg2:any):Promise<main.settings>; export function SetSetting(arg1:string,arg2:any):Promise<main.settings>;

View File

@@ -10,6 +10,10 @@ export function GetFood() {
return window['go']['main']['App']['GetFood'](); return window['go']['main']['App']['GetFood']();
} }
export function GetLastPer100(arg1) {
return window['go']['main']['App']['GetLastPer100'](arg1);
}
export function GetSettings() { export function GetSettings() {
return window['go']['main']['App']['GetSettings'](); return window['go']['main']['App']['GetSettings']();
} }

View File

@@ -92,6 +92,22 @@ export namespace main {
return a; return a;
} }
} }
export class WailsPer100 {
data: number;
success: boolean;
error?: string;
static createFrom(source: any = {}) {
return new WailsPer100(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.data = source["data"];
this.success = source["success"];
this.error = source["error"];
}
}
export class settings { export class settings {
foodDaysLookback: number; foodDaysLookback: number;
foodAggregatedDaysLookback: number; foodAggregatedDaysLookback: number;

View File

@@ -20,7 +20,11 @@ type (
Success bool `json:"success"` Success bool `json:"success"`
Error string `json:"error,omitempty"` Error string `json:"error,omitempty"`
} }
WailsPer100 struct {
Data float32 `json:"data"`
Success bool `json:"success"`
Error string `json:"error,omitempty"`
}
WailsAggregateFood struct { WailsAggregateFood struct {
Data []AggregatedFood `json:"data"` Data []AggregatedFood `json:"data"`
Success bool `json:"success"` Success bool `json:"success"`