106 lines
2.2 KiB
Go
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)
|
|
}
|