Files
kleiax 904d14b64c
CI / test (push) Canceled after 0s
Initial commit
2026-09-12 22:22:17 +02:00

180 lines
4.9 KiB
Go

package web
import (
"errors"
"net/http"
"strings"
"time"
"gardomatic.kleiax.de/lib/client"
)
type assignmentForm struct {
CSRFToken string `form:"csrf_token"`
LocationID int `form:"location_id"`
Quantity int `form:"quantity"`
PlantedAt string `form:"planted_at"`
Notes string `form:"notes"`
Errors map[string]string
}
func (app *application) plantLocationCreate(w http.ResponseWriter, r *http.Request) {
app.renderPlantLocationForm(w, r, assignmentForm{Quantity: 1, Errors: map[string]string{}}, http.StatusOK, 0)
}
func (app *application) plantLocationEdit(w http.ResponseWriter, r *http.Request) {
gardenID, err := app.readPathID(r, "gardenID")
if err != nil {
app.notFound(w)
return
}
plantID, err := app.readPathID(r, "plantID")
if err != nil {
app.notFound(w)
return
}
assignmentID, err := app.readPathID(r, "assignmentID")
if err != nil {
app.notFound(w)
return
}
items, _, err := client.FromContext(r.Context()).PlantLocations(r.Context(), gardenID, plantID)
if err != nil {
app.handleAPIError(w, r, err)
return
}
form := assignmentForm{Errors: map[string]string{}}
found := false
for _, item := range items {
if item.ID == assignmentID {
found = true
form.LocationID = item.LocationID
form.Quantity = item.Quantity
form.Notes = item.Notes
if item.PlantedAt != nil {
form.PlantedAt = item.PlantedAt.Format("2006-01-02")
}
break
}
}
if !found {
app.notFound(w)
return
}
app.renderPlantLocationForm(w, r, form, http.StatusOK, assignmentID)
}
func (app *application) plantLocationSave(w http.ResponseWriter, r *http.Request) {
gardenID, err := app.readPathID(r, "gardenID")
if err != nil {
app.notFound(w)
return
}
plantID, err := app.readPathID(r, "plantID")
if err != nil {
app.notFound(w)
return
}
assignmentID, _ := app.readPathID(r, "assignmentID")
var form assignmentForm
if err = app.decodePostForm(r, &form); err != nil {
app.clientError(w, http.StatusBadRequest)
return
}
form.Notes = strings.TrimSpace(form.Notes)
form.Errors = map[string]string{}
if form.LocationID < 1 {
form.Errors["location_id"] = "Ein Ort ist erforderlich."
}
if form.Quantity < 1 {
form.Errors["quantity"] = "Die Anzahl muss mindestens 1 sein."
}
var plantedAt *time.Time
if form.PlantedAt != "" {
parsed, parseErr := time.Parse("2006-01-02", form.PlantedAt)
if parseErr != nil {
form.Errors["planted_at"] = "Das Datum ist ungültig."
} else {
plantedAt = &parsed
}
}
if len(form.Errors) == 0 {
locationID, quantity, notes := form.LocationID, form.Quantity, form.Notes
input := client.PlantLocationInput{LocationID: &locationID, Quantity: &quantity, PlantedAt: plantedAt, ClearPlantedAt: plantedAt == nil, Notes: &notes}
apiClient := client.FromContext(r.Context())
if assignmentID > 0 {
_, _, err = apiClient.UpdatePlantLocation(r.Context(), gardenID, plantID, assignmentID, input)
} else {
_, _, err = apiClient.CreatePlantLocation(r.Context(), gardenID, plantID, input)
}
if err == nil {
http.Redirect(w, r, webPath("plants", gardenID), http.StatusSeeOther)
return
}
var apiError *client.APIError
if errors.As(err, &apiError) && apiError.StatusCode == http.StatusUnprocessableEntity {
form.Errors = apiError.Validation
} else {
app.handleAPIError(w, r, err)
return
}
}
app.renderPlantLocationForm(w, r, form, http.StatusUnprocessableEntity, assignmentID)
}
func (app *application) plantLocationDeletePost(w http.ResponseWriter, r *http.Request) {
gardenID, err := app.readPathID(r, "gardenID")
if err != nil {
app.notFound(w)
return
}
plantID, err := app.readPathID(r, "plantID")
if err != nil {
app.notFound(w)
return
}
assignmentID, err := app.readPathID(r, "assignmentID")
if err != nil {
app.notFound(w)
return
}
if _, err = client.FromContext(r.Context()).DeletePlantLocation(r.Context(), gardenID, plantID, assignmentID); err != nil {
app.handleAPIError(w, r, err)
return
}
http.Redirect(w, r, webPath("plants", gardenID), http.StatusSeeOther)
}
func (app *application) renderPlantLocationForm(w http.ResponseWriter, r *http.Request, form assignmentForm, status, assignmentID int) {
gardenID, err := app.readPathID(r, "gardenID")
if err != nil {
app.notFound(w)
return
}
plantID, err := app.readPathID(r, "plantID")
if err != nil {
app.notFound(w)
return
}
apiClient := client.FromContext(r.Context())
garden, _, err := apiClient.Garden(r.Context(), gardenID)
if err != nil {
app.handleAPIError(w, r, err)
return
}
plant, _, err := apiClient.Plant(r.Context(), gardenID, plantID)
if err != nil {
app.handleAPIError(w, r, err)
return
}
locations, _, err := apiClient.Locations(r.Context(), gardenID)
if err != nil {
app.handleAPIError(w, r, err)
return
}
data := app.newTemplateData(r)
data.Garden = &garden
data.Plants = []client.Plant{plant}
data.PlantID = plantID
data.LocationID = assignmentID
data.Locations = locations
data.Form = form
app.render(w, status, "plant_location_form.tmpl", data)
}