Test out Item table

Add to real API
Update air config
Fix bug in MenuItem
This commit is contained in:
Michał 2024-05-13 12:10:55 +01:00
parent 899867e72d
commit 1fdb6ed2f4
7 changed files with 87 additions and 58 deletions

View file

@ -3,7 +3,7 @@ testdata_dir = "testdata"
tmp_dir = "tmp" tmp_dir = "tmp"
[build] [build]
args_bin = ["run", "-host=127.0.0.1:3000"] args_bin = ["run", "-host=127.0.0.1:3000", "-log"]
bin = "./tmp/main" bin = "./tmp/main"
cmd = "go build -o ./tmp/main ." cmd = "go build -o ./tmp/main ."
delay = 1000 delay = 1000

View file

@ -15,6 +15,11 @@ type Config struct {
Logging bool Logging bool
} }
type JSONResponse struct {
Data interface{} `json:"data,omitempty"`
Error string `json:"error,omitempty"`
}
func Serve(c Config) { func Serve(c Config) {
r := echo.New() r := echo.New()
@ -28,6 +33,11 @@ func Serve(c Config) {
apiGroup := r.Group("/api") apiGroup := r.Group("/api")
apiGroup.GET("/items", func(e echo.Context) error { apiGroup.GET("/items", func(e echo.Context) error {
var response JSONResponse
type ItemResponse struct {
Item []db.Item `json:"item"`
}
builder := db.ItemStruct.SelectFrom("Item").Select("*") builder := db.ItemStruct.SelectFrom("Item").Select("*")
query, args := builder.BuildWithFlavor(sb.SQLite) query, args := builder.BuildWithFlavor(sb.SQLite)
@ -35,7 +45,8 @@ func Serve(c Config) {
defer rows.Close() defer rows.Close()
if err != nil { if err != nil {
r.Logger.Fatal(err) r.Logger.Fatal(err)
return e.String(http.StatusInternalServerError, "Could not query for data") response.Error = "Could not query for data"
return e.JSON(http.StatusInternalServerError, response)
} }
var items []db.Item var items []db.Item
@ -44,12 +55,16 @@ func Serve(c Config) {
err := rows.Scan(db.ItemStruct.Addr(&item)...) err := rows.Scan(db.ItemStruct.Addr(&item)...)
if err != nil { if err != nil {
r.Logger.Fatal(err) r.Logger.Fatal(err)
return e.String(http.StatusInternalServerError, "Could not scan row") response.Error = "Failed to map response"
return e.JSON(http.StatusInternalServerError, response)
} }
items = append(items, item) items = append(items, item)
} }
response.Data = ItemResponse{
Item: items,
}
return e.JSON(http.StatusOK, items) return e.JSON(http.StatusOK, response)
}) })
r.HideBanner = true r.HideBanner = true

View file

@ -5,12 +5,12 @@ import (
) )
type Item struct { type Item struct {
UUID string `json:"uuid" db:"uuid"` UUID string `json:"uuid" db:"uuid"`
Name string `json:"name" db:"name"` Name string `json:"name" db:"name"`
Price int64 `json:"price" db:"price"` Price int64 `json:"price" db:"price"`
Description string `json:"description,omitempty" db:"description"` Description string `json:"description" db:"description"`
//Labels []string `json:"labels,omitempty" db:"labels"` Labels []string `json:"labels,omitempty" db:"-"`
//Images []string `json:"images,omitempty" db:"images"` Images []string `json:"images,omitempty" db:"-"`
} }
var ItemStruct = sb.NewStruct(new(Item)) var ItemStruct = sb.NewStruct(new(Item))

View file

@ -23,26 +23,28 @@
<svelte:window on:resize={keepSquare}></svelte:window> <svelte:window on:resize={keepSquare}></svelte:window>
<div class="menu-item" bind:this={element}> <div class="menu-item" bind:this={element}>
{#if item.images} {#if item.images && item.images[0]}
<img src={item.images[0]} alt="" class="menu-item-image"> <img src={item.images[0]} alt="" class="menu-item-image">
{:else} {:else}
<img src={LoadingImage} alt="" class="menu-item-image"> <img src={LoadingImage} alt="" class="menu-item-image">
{/if} {/if}
<ul class="menu-item-labels"> <ul class="menu-item-labels">
{#each item.labels as label} {#if item.labels}
{#if label === Labels.vegan} {#each item.labels as label}
<li class="vegan"><Leaf weight="fill" /></li> {#if label === Labels.vegan}
{:else if label === Labels.fish} <li class="vegan"><Leaf weight="fill" /></li>
<li class="fish"><Fish weight="fill" /></li> {:else if label === Labels.fish}
{:else if label === Labels.nut} <li class="fish"><Fish weight="fill" /></li>
<li class="nut"><Acorn weight="fill" /></li> {:else if label === Labels.nut}
{:else if label === Labels.gluten} <li class="nut"><Acorn weight="fill" /></li>
<li class="gluten"><GrainsSlash weight="fill" /></li> {:else if label === Labels.gluten}
{:else if label === Labels.spicy} <li class="gluten"><GrainsSlash weight="fill" /></li>
<li class="spicy"><Pepper weight="fill" /></li> {:else if label === Labels.spicy}
{/if} <li class="spicy"><Pepper weight="fill" /></li>
{/each} {/if}
{/each}
{/if}
</ul> </ul>
<a class="menu-item-link" href="/item/{item.uuid}" use:link> <a class="menu-item-link" href="/item/{item.uuid}" use:link>

View file

@ -1,29 +0,0 @@
import TestData from "%/lib/test-data.ts";
export async function getPopularToday() {
const res = await fetch("/api/items");
const data = res.json();
if (res.ok) {
return data;
} else {
throw new Error("Failed to fetch popular today");
}
}
export function getMenuItems() {
return [
{
name: "Main Menu",
items: TestData,
},
{
name: "Breakfast",
items: [],
},
{
name: "Seasonal",
items: TestData,
},
];
}

36
front/src/lib/api.ts Normal file
View file

@ -0,0 +1,36 @@
import { type Item, type JSONResponse } from "./types";
import TestData from "./test-data";
const API_URL = "http://127.0.0.1:8080";
export async function getPopularToday(): Promise<Item[]> {
const response = await fetch(API_URL + "/api/items");
const {data, error}: JSONResponse = await response.json();
if (response.ok) {
if (data?.item) {
return data?.item;
} else {
return Promise.reject(new Error("Failed to fetch popular today"))
}
} else {
return Promise.reject(error)
}
}
export function getMenuItems() {
return [
{
name: "Main Menu",
items: TestData,
},
{
name: "Breakfast",
items: [],
},
{
name: "Seasonal",
items: TestData,
},
];
}

View file

@ -6,17 +6,22 @@ export enum Labels {
gluten = "GLUTEN", gluten = "GLUTEN",
} }
export interface Item { export type Item = {
uuid: string; uuid: string;
availability: boolean; availability?: boolean;
name: string; name: string;
price: number; price: number;
labels: Labels[]; description: string;
description?: string; labels?: Labels[];
images?: string[]; images?: string[];
} }
export interface CartItem { export type CartItem = {
amount: number; amount: number;
data: Item; data: Item;
} }
export type JSONResponse = {
data?: { item: Item[] }
error?: string,
}