sbsqlitessgcms/handler.go

143 lines
3.3 KiB
Go
Raw Normal View History

2022-11-19 02:19:28 +00:00
package main
import (
"log"
"net/http"
"strconv"
h "gitlab.codemonkeysoftware.net/b/hatmill"
ha "gitlab.codemonkeysoftware.net/b/hatmill/attribute"
he "gitlab.codemonkeysoftware.net/b/hatmill/element"
)
const (
pathRoot = "/"
pathCreatePost = "/create-post"
pathDoCreatePost = "/create-post/do"
)
type handler struct {
mux *http.ServeMux
store *Store
baseURL string
}
func NewHandler(store *Store, baseURL string) http.Handler {
h := &handler{
store: store,
mux: http.NewServeMux(),
baseURL: baseURL,
}
h.mux.HandleFunc(pathRoot, h.getPosts)
h.mux.HandleFunc(pathCreatePost, h.createPost)
h.mux.HandleFunc(pathDoCreatePost, h.doCreatePost)
return h
}
func (hnd *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
hnd.mux.ServeHTTP(w, r)
}
func (hnd *handler) getPosts(w http.ResponseWriter, r *http.Request) {
result, err := hnd.store.GetPosts(r.Context())
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
var rows h.Terms
for _, post := range result.Posts {
rows = append(rows, he.Tr()(
he.Td()(h.Text(strconv.FormatInt(post.Id, 10))),
he.Td()(h.Text(post.CreatedAt)),
he.Td()(h.Text(post.UpdatedAt)),
he.Td()(h.Text(post.Author)),
he.Td()(h.Text(post.Title)),
// he.Td()(h.Text(post.Body)),
))
}
html := he.Html()(
he.Head()(),
he.Body()(
he.H1()(h.Text("Posts")),
he.Table()(
he.Thead()(
he.Tr()(
he.Th()(h.Text("ID")),
he.Th()(h.Text("Created")),
he.Th()(h.Text("Updated")),
he.Th()(h.Text("Author")),
he.Th()(h.Text("Title")),
),
),
he.Tbody()(
rows...,
),
),
he.A(ha.Href(hnd.baseURL+pathCreatePost))(h.Text("Create post")),
),
)
_, err = h.WriteDocument(w, html)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
const (
fieldNamePostTitle = "post-title"
fieldNamePostBody = "post-body"
fieldNamePostAuthor = "post-author"
)
func (hnd *handler) createPost(w http.ResponseWriter, r *http.Request) {
html := he.Html()(
he.Head()(),
he.Body()(
he.H1()(h.Text("Create post")),
he.Form(ha.Action(hnd.baseURL+pathDoCreatePost), ha.Method("POST"))(
he.Label(ha.For(fieldNamePostTitle))(h.Text("Title")),
he.Input(ha.Name(fieldNamePostTitle)),
he.Br(),
he.Label(ha.For(fieldNamePostAuthor))(h.Text("Author")),
he.Input(ha.Name(fieldNamePostAuthor)),
he.Br(),
he.Label(ha.For(fieldNamePostBody))(h.Text("Body")),
he.Textarea(ha.For(fieldNamePostBody))(),
he.Br(),
he.Input(ha.Type("submit")),
),
),
)
_, err := h.WriteDocument(w, html)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
func (hnd *handler) doCreatePost(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
cmd := CreatePostCommand{
Title: r.PostForm.Get(fieldNamePostTitle),
Author: r.PostForm.Get(fieldNamePostAuthor),
Body: r.PostForm.Get(fieldNamePostBody),
}
result, err := hnd.store.CreatePost(r.Context(), cmd)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
log.Println("created post", result.PostId)
http.Redirect(w, r, pathRoot, http.StatusFound)
}