summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxengineering <me@xengineering.eu>2024-01-08 19:36:01 +0100
committerxengineering <me@xengineering.eu>2024-01-08 19:36:01 +0100
commitae1a31f226de5701683231afaabf0f66503ca17d (patch)
treeb11a8b8c91ac41ee7ffb783de23b5c38dd9e2e6a
parent43e7bb10eaade56a9444ec089aa3102218231868 (diff)
downloadceres-ae1a31f226de5701683231afaabf0f66503ca17d.tar
ceres-ae1a31f226de5701683231afaabf0f66503ca17d.tar.zst
ceres-ae1a31f226de5701683231afaabf0f66503ca17d.zip
Implement recipe editing
-rw-r--r--controller/common.go37
-rw-r--r--main.go3
-rw-r--r--model/data.go4
-rw-r--r--model/sql/recipe-update.sql7
-rw-r--r--view/common.go18
-rw-r--r--view/html/recipe-edit.html40
6 files changed, 109 insertions, 0 deletions
diff --git a/controller/common.go b/controller/common.go
new file mode 100644
index 0000000..014c001
--- /dev/null
+++ b/controller/common.go
@@ -0,0 +1,37 @@
+package controller
+
+import (
+ "net/http"
+
+ "xengineering.eu/ceres/model"
+
+ "github.com/gorilla/mux"
+)
+
+func RecipePost(w http.ResponseWriter, r *http.Request) {
+ var data model.Recipe
+ var err error
+
+ vars := mux.Vars(r)
+ data.Id = vars[`id`]
+
+ err = r.ParseForm()
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ // TODO error handling and generic implementation
+ data.Title = r.PostForm[`title`][0]
+ data.Portions = r.PostForm[`portions`][0]
+ data.URL = r.PostForm[`url`][0]
+ data.Notes = r.PostForm[`notes`][0]
+
+ err = data.ToDB()
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ http.Redirect(w, r, r.URL.Path, http.StatusSeeOther)
+}
diff --git a/main.go b/main.go
index e7acac1..a546d86 100644
--- a/main.go
+++ b/main.go
@@ -9,6 +9,7 @@ import (
"os/signal"
"syscall"
+ "xengineering.eu/ceres/controller"
"xengineering.eu/ceres/model"
"xengineering.eu/ceres/view"
@@ -45,6 +46,8 @@ func startServer(addr string) *http.Server {
Handler(http.StripPrefix("/static/", http.FileServer(http.FS(static))))
r.HandleFunc("/recipes/{id}", view.HandlerHTML(&model.Recipe{})).Methods(`GET`)
+ r.HandleFunc("/recipes/{id}/edit", view.RecipeEditHandler).Methods(`GET`)
+ r.HandleFunc("/recipes/{id}", controller.RecipePost).Methods(`POST`)
r.HandleFunc("/", view.HandlerHTML(&model.Index{})).Methods(`GET`)
diff --git a/model/data.go b/model/data.go
index b5edd85..3e0e73d 100644
--- a/model/data.go
+++ b/model/data.go
@@ -3,3 +3,7 @@ package model
type ReadableData interface {
FromDB() error
}
+
+type WritableData interface {
+ ToDB() error
+}
diff --git a/model/sql/recipe-update.sql b/model/sql/recipe-update.sql
new file mode 100644
index 0000000..fbc03fa
--- /dev/null
+++ b/model/sql/recipe-update.sql
@@ -0,0 +1,7 @@
+UPDATE recipes
+SET
+ title = ?,
+ portions = ?,
+ url = ?,
+ notes = ?
+WHERE id = ?;
diff --git a/view/common.go b/view/common.go
index c371fa0..b4df532 100644
--- a/view/common.go
+++ b/view/common.go
@@ -62,3 +62,21 @@ func HandlerHTML(prototype model.ReadableData) http.HandlerFunc {
}
}
}
+
+func RecipeEditHandler(w http.ResponseWriter, r *http.Request) {
+ var recipe model.Recipe
+ var err error
+
+ vars := mux.Vars(r)
+ recipe.Id = vars[`id`]
+
+ err = recipe.FromDB()
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ }
+
+ err = html.ExecuteTemplate(w, `recipe-edit`, recipe)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ }
+}
diff --git a/view/html/recipe-edit.html b/view/html/recipe-edit.html
new file mode 100644
index 0000000..b4d6da5
--- /dev/null
+++ b/view/html/recipe-edit.html
@@ -0,0 +1,40 @@
+{{define "recipe-edit"}}
+<html>
+ {{ template "head" }}
+ <header>
+ <nav>
+ <a href="/">HOME</a>
+ </nav>
+ <h1>Recipe editor</h1>
+ </header>
+ <body>
+ <main>
+ <form action="/recipes/{{.Id}}" method="POST">
+ <p>
+ <label>Title</label>
+ <input type="text" name="title" value="{{.Title}}">
+ </p>
+
+ <p>
+ <label>Portions</label>
+ <input type="number" name="portions" value="{{.Portions}}">
+ </p>
+
+ <p>
+ <label>URL</label>
+ <input type="text" name="url" value="{{.URL}}">
+ </p>
+
+ <p>
+ <label>Notes</label>
+ <input type="text" name="notes" value="{{.Notes}}">
+ </p>
+
+ <input type="submit" value="save">
+ <a href="/recipes/{{.Id}}"><button type="button">cancel</button></a>
+ </form>
+ </main>
+ {{ template "footer" }}
+ </body>
+</html>
+{{end}}