143 lines
3.3 KiB
Go
143 lines
3.3 KiB
Go
|
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)
|
||
|
}
|