BrainMinder/cmd/web/categories_handler.go
2024-08-22 10:13:16 +02:00

274 lines
6.9 KiB
Go

package main
import (
"bytes"
"fmt"
"net/http"
"strconv"
"brainminder.speedtech.it/internal/request"
"brainminder.speedtech.it/internal/response"
"brainminder.speedtech.it/internal/validator"
"brainminder.speedtech.it/models"
"github.com/alexedwards/flow"
)
type categoryForm struct {
Id int64 `form:"Id"`
Name string `form:"Name"`
Validator validator.Validator `form:"-"`
}
func (form *categoryForm) Validate(w http.ResponseWriter, r *http.Request, app *application, data map[string]any) bool {
var fullBuf = new(bytes.Buffer)
form.Validator.CheckField(form.Name != "", "Name", "Name is required")
if form.Validator.HasErrors() {
w.Header().Add("HX-Retarget", "#message")
data["messageType"] = "failure"
data["messageContent"] = "Impossible to save the type"
data["messageFieldErrors"] = form.Validator.FieldErrors
buf, err := response.Fragment([]string{"partials/message.tmpl"}, "message", data)
if err != nil {
app.serverError(w, r, err)
}
fullBuf.Write(buf.Bytes())
if err != nil {
app.serverError(w, r, err)
}
fullBuf.WriteTo(w)
w.WriteHeader(http.StatusUnprocessableEntity)
return false
}
return true
}
func (app *application) categories(w http.ResponseWriter, r *http.Request) {
data := app.newTemplateData(r)
categoryModel := &models.CategoryModel{DB: app.db}
rows, _, _ := categoryModel.All()
data["categories"] = &rows
data["messageType"] = ""
data["messageContent"] = ""
if r.Header.Get("HX-Request") == "true" {
var fullBuf = new(bytes.Buffer)
err := response.HXFragment(fullBuf, []string{"categories/list.tmpl"}, "categories:list", data)
if err != nil {
app.serverError(w, r, err)
}
err = response.HXFragmentOOB(fullBuf, []string{"categories/list_title.tmpl"}, "page:title", data, "page-title")
if err != nil {
app.serverError(w, r, err)
}
fullBuf.WriteTo(w)
} else {
err := response.Page(w, http.StatusOK, data, []string{"categories/index.tmpl", "categories/list.tmpl", "categories/list_title.tmpl"})
if err != nil {
app.serverError(w, r, err)
}
}
w.WriteHeader(http.StatusOK)
}
func (app *application) categoryCreate(w http.ResponseWriter, r *http.Request) {
categoryModel := &models.CategoryModel{DB: app.db}
var fullBuf = new(bytes.Buffer)
var category_id int64
data := app.newTemplateData(r)
data["formAction"] = "/category/create"
data["formTarget"] = "#page-content"
data["messageType"] = ""
data["messageContent"] = ""
switch r.Method {
case http.MethodGet:
data["category"] = categoryForm{
Name: "",
}
if r.Header.Get("HX-Request") == "true" {
err := response.HXFragment(fullBuf, []string{"categories/form.tmpl"}, "page:content", data)
if err != nil {
app.serverError(w, r, err)
}
err = response.HXFragmentOOB(fullBuf, []string{"categories/create_title.tmpl"}, "page:title", data, "page-title")
if err != nil {
app.serverError(w, r, err)
}
fullBuf.WriteTo(w)
} else {
err := response.Page(w, http.StatusOK, data, []string{"categories/create_title.tmpl", "categories/form.tmpl"})
if err != nil {
app.serverError(w, r, err)
}
}
case http.MethodPost:
var categoryFromForm categoryForm
err := request.DecodePostForm(r, &categoryFromForm)
if err != nil {
app.serverError(w, r, err)
}
if !categoryFromForm.Validate(w, r, app, data) {
return
}
category := &models.Category{
Name: categoryFromForm.Name,
}
category_id, err = categoryModel.Create(category)
if err != nil {
app.badRequest(w, err)
return
}
data["formAction"] = fmt.Sprint("/category/update/", category_id)
data["formTarget"] = "#message"
data["category"] = categoryForm{
Id: category_id,
Name: category.Name,
}
err = response.HXFragment(fullBuf, []string{"categories/form.tmpl"}, "page:content", data)
if err != nil {
app.serverError(w, r, err)
}
err = response.HXFragmentOOB(fullBuf, []string{"categories/update_title.tmpl"}, "page:title", data, "page-title")
if err != nil {
app.serverError(w, r, err)
}
dataMessage := make(map[string]string)
dataMessage["messageType"] = "success"
dataMessage["messageContent"] = "Category created successfully"
err = response.HXFragmentOOB(fullBuf, []string{"partials/message.tmpl"}, "message", dataMessage, "message")
if err != nil {
app.serverError(w, r, err)
}
w.Header().Add("HX-Replace-Url", fmt.Sprint("/type/update/", category_id))
fullBuf.WriteTo(w)
w.WriteHeader(http.StatusUnprocessableEntity)
}
}
func (app *application) categoryUpdate(w http.ResponseWriter, r *http.Request) {
categoryModel := &models.CategoryModel{DB: app.db}
category_id_str := flow.Param(r.Context(), "category_id")
category_id, _ := strconv.Atoi(category_id_str)
category, _, _ := categoryModel.One(category_id)
data := app.newTemplateData(r)
data["formAction"] = "/category/update/" + category_id_str
data["formTarget"] = "#message"
data["messageType"] = ""
data["messageContent"] = ""
var fullBuf = new(bytes.Buffer)
switch r.Method {
case http.MethodGet:
data["category"] = categoryForm{
Id: category.Id,
Name: category.Name,
}
if r.Header.Get("HX-Request") == "true" {
err := response.HXFragment(fullBuf, []string{"categories/form.tmpl"}, "page:content", data)
if err != nil {
app.serverError(w, r, err)
}
err = response.HXFragmentOOB(fullBuf, []string{"categories/update_title.tmpl"}, "page:title", data, "page-title")
if err != nil {
app.serverError(w, r, err)
}
fullBuf.WriteTo(w)
} else {
err := response.Page(w, http.StatusOK, data, []string{"categories/update_title.tmpl", "categories/form.tmpl"})
if err != nil {
app.serverError(w, r, err)
}
}
case http.MethodPost:
var categoryFromForm categoryForm
err := request.DecodePostForm(r, &categoryFromForm)
if err != nil {
app.serverError(w, r, err)
}
if !categoryFromForm.Validate(w, r, app, data) {
return
}
category.Name = categoryFromForm.Name
err = categoryModel.Update(category)
if err != nil {
app.badRequest(w, err)
return
}
data["category"] = categoryForm{
Id: category.Id,
Name: category.Name,
}
dataMessage := make(map[string]string)
dataMessage["messageType"] = "success"
dataMessage["messageContent"] = "Category saved successfully"
err = response.HXFragment(fullBuf, []string{"partials/message.tmpl"}, "message", dataMessage)
if err != nil {
app.serverError(w, r, err)
}
err = response.HXFragmentOOB(fullBuf, []string{"categories/update_title.tmpl"}, "page:title", data, "page-title")
if err != nil {
app.serverError(w, r, err)
}
fullBuf.WriteTo(w)
w.WriteHeader(http.StatusUnprocessableEntity)
}
}
func (app *application) categoryDelete(w http.ResponseWriter, r *http.Request) {
categoryModel := &models.CategoryModel{DB: app.db}
category_id_str := flow.Param(r.Context(), "category_id")
category_id, _ := strconv.Atoi(category_id_str)
_, err := categoryModel.Delete(category_id)
if err != nil {
app.serverError(w, r, err)
}
}