go-recipe-book/pkg/web/handler_ingredients.go
Alessio 10cc9342b1
Some checks failed
Build / release (push) Blocked by required conditions
Build / build (push) Has been cancelled
Add beginning of web package
2024-11-18 16:25:39 -08:00

106 lines
2.2 KiB
Go

package web
import (
"context"
"encoding/json"
"errors"
"fmt"
"github.com/a-h/templ"
"io"
"net/http"
"strconv"
"strings"
. "recipe_book/pkg/db"
"recipe_book/pkg/web/tpl/pages"
)
// Router: `/ingredients`
func (app *Application) Ingredients(w http.ResponseWriter, r *http.Request) {
app.traceLog.Printf("Ingredient: %s", r.URL.Path)
parts := strings.Split(strings.Trim(r.URL.Path, "/"), "/")
if parts[0] == "" {
// Index page
switch r.Method {
case "GET":
app.IngredientsIndex(w, r)
case "POST":
app.IngredientCreate(w, r)
}
return
}
// Details page
food_id, err := strconv.Atoi(parts[0])
if err != nil {
app.error_400(w, r, fmt.Sprintf("invalid ID: %s", parts[0]))
return
}
food, err := app.DB.GetFoodByID(FoodID(food_id))
if errors.Is(err, ErrNotInDB) {
app.error_404(w, r)
return
} else if err != nil {
panic(err)
}
app.IngredientDetail(food, w, r)
}
// Handler: `GET /ingredients`
func (app *Application) IngredientsIndex(w http.ResponseWriter, r *http.Request) {
foods := app.DB.GetAllBaseFoods()
err := pages.Base("Ingredients").Render(
templ.WithChildren(
context.Background(),
pages.IngredientsIndex(foods),
),
w)
panic_if(err)
}
// Handler: `POST /ingredients`
func (app *Application) IngredientCreate(w http.ResponseWriter, r *http.Request) {
var food Food
data, err := io.ReadAll(r.Body)
if err != nil {
panic(err)
}
err = json.Unmarshal(data, &food)
if err != nil {
app.ErrorLog.Print(err)
panic(err)
}
app.DB.SaveFood(&food)
http.Redirect(w, r, fmt.Sprintf("/ingredients/%d", food.ID), 303)
}
// Handler: `GET /ingredients/:id`
func (app *Application) IngredientDetail(food Food, w http.ResponseWriter, r *http.Request) {
// If it's a POST request, update the food
if r.Method == "POST" {
data, err := io.ReadAll(r.Body)
if err != nil {
panic(err)
}
err = json.Unmarshal(data, &food)
if err != nil {
app.ErrorLog.Print(err)
panic(err)
}
// Save the updated food
app.DB.SaveFood(&food)
app.traceLog.Printf("POST Ingredient Detail: %#v", food)
}
err := pages.Base(fmt.Sprintf("Ingredient: %s", food.Name)).Render(
templ.WithChildren(
context.Background(),
pages.IngredientDetail(food),
),
w)
panic_if(err)
}