fix(collections): add form binding and HTMX redirect support
Add form:"" tags to CreateCollectionRequest and UpdateCollectionRequest structs to enable proper form data binding with Echo's c.Bind(). This change aligns with the pattern used in auth handlers where both form:"" and json:"" tags are present, allowing the same request structs to work with both JSON payloads (API) and form data (HTMX). Changes: - Add form:"name", form:"description", form:"color", form:"icon", form:"auto_assign_rules", and form:"view_settings" tags to both CreateCollectionRequest and UpdateCollectionRequest Additionally, add HTMX redirect support to CreateCollection and UpdateCollection handlers: - Add HX-Redirect header for HTMX requests after successful create/update - Add HTML redirect response to DeleteCollection for HTMX requests (follows pattern from auth.go: inline script with window.location.href) This ensures HTMX form submissions properly redirect to /collections after successful operations, while maintaining API compatibility for JSON requests.
This commit is contained in:
@@ -35,21 +35,21 @@ func NewCollectionHandler(db *database.Queries, libraryService *services.Library
|
|||||||
}
|
}
|
||||||
|
|
||||||
type CreateCollectionRequest struct {
|
type CreateCollectionRequest struct {
|
||||||
Name string `json:"name" validate:"required"`
|
Name string `form:"name" json:"name" validate:"required"`
|
||||||
Description string `json:"description"`
|
Description string `form:"description" json:"description"`
|
||||||
Color string `json:"color"`
|
Color string `form:"color" json:"color"`
|
||||||
Icon string `json:"icon"`
|
Icon string `form:"icon" json:"icon"`
|
||||||
AutoAssignRules []services.Rule `json:"auto_assign_rules"`
|
AutoAssignRules []services.Rule `form:"auto_assign_rules" json:"auto_assign_rules"`
|
||||||
ViewSettings map[string]interface{} `json:"view_settings"`
|
ViewSettings map[string]interface{} `form:"view_settings" json:"view_settings"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type UpdateCollectionRequest struct {
|
type UpdateCollectionRequest struct {
|
||||||
Name string `json:"name" validate:"required"`
|
Name string `form:"name" json:"name" validate:"required"`
|
||||||
Description string `json:"description"`
|
Description string `form:"description" json:"description"`
|
||||||
Color string `json:"color"`
|
Color string `form:"color" json:"color"`
|
||||||
Icon string `json:"icon"`
|
Icon string `form:"icon" json:"icon"`
|
||||||
AutoAssignRules []services.Rule `json:"auto_assign_rules"`
|
AutoAssignRules []services.Rule `form:"auto_assign_rules" json:"auto_assign_rules"`
|
||||||
ViewSettings map[string]interface{} `json:"view_settings"`
|
ViewSettings map[string]interface{} `form:"view_settings" json:"view_settings"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AddBooksRequest struct {
|
type AddBooksRequest struct {
|
||||||
@@ -113,7 +113,7 @@ func (h *CollectionHandler) CreateCollection(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bookCount := int32(0)
|
bookCount := int32(0)
|
||||||
return c.JSON(http.StatusCreated, map[string]interface{}{
|
response := map[string]interface{}{
|
||||||
"id": uuid.UUID(collection.ID.Bytes).String(),
|
"id": uuid.UUID(collection.ID.Bytes).String(),
|
||||||
"user_id": uuid.UUID(collection.UserID.Bytes).String(),
|
"user_id": uuid.UUID(collection.UserID.Bytes).String(),
|
||||||
"name": collection.Name,
|
"name": collection.Name,
|
||||||
@@ -124,7 +124,14 @@ func (h *CollectionHandler) CreateCollection(c echo.Context) error {
|
|||||||
"view_settings": collection.ViewSettings,
|
"view_settings": collection.ViewSettings,
|
||||||
"book_count": bookCount,
|
"book_count": bookCount,
|
||||||
"created_at": collection.CreatedAt.Time.String(),
|
"created_at": collection.CreatedAt.Time.String(),
|
||||||
})
|
}
|
||||||
|
|
||||||
|
// Add redirect header for HTMX requests
|
||||||
|
if c.Request().Header.Get("HX-Request") == "true" {
|
||||||
|
c.Response().Header().Set("HX-Redirect", "/collections")
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(http.StatusCreated, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *CollectionHandler) GetCollections(c echo.Context) error {
|
func (h *CollectionHandler) GetCollections(c echo.Context) error {
|
||||||
@@ -252,7 +259,7 @@ func (h *CollectionHandler) UpdateCollection(c echo.Context) error {
|
|||||||
return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
|
return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, map[string]interface{}{
|
response := map[string]interface{}{
|
||||||
"id": uuid.UUID(collection.ID.Bytes).String(),
|
"id": uuid.UUID(collection.ID.Bytes).String(),
|
||||||
"user_id": uuid.UUID(collection.UserID.Bytes).String(),
|
"user_id": uuid.UUID(collection.UserID.Bytes).String(),
|
||||||
"name": collection.Name,
|
"name": collection.Name,
|
||||||
@@ -262,7 +269,14 @@ func (h *CollectionHandler) UpdateCollection(c echo.Context) error {
|
|||||||
"auto_assign_rules": json.RawMessage(collection.AutoAssignRules),
|
"auto_assign_rules": json.RawMessage(collection.AutoAssignRules),
|
||||||
"view_settings": json.RawMessage(collection.ViewSettings),
|
"view_settings": json.RawMessage(collection.ViewSettings),
|
||||||
"created_at": collection.CreatedAt.Time.String(),
|
"created_at": collection.CreatedAt.Time.String(),
|
||||||
})
|
}
|
||||||
|
|
||||||
|
// Add redirect header for HTMX requests
|
||||||
|
if c.Request().Header.Get("HX-Request") == "true" {
|
||||||
|
c.Response().Header().Set("HX-Redirect", "/collections")
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(http.StatusCreated, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *CollectionHandler) DeleteCollection(c echo.Context) error {
|
func (h *CollectionHandler) DeleteCollection(c echo.Context) error {
|
||||||
@@ -276,6 +290,11 @@ func (h *CollectionHandler) DeleteCollection(c echo.Context) error {
|
|||||||
return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
|
return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.Request().Header.Get("HX-Request") == "true" {
|
||||||
|
html := `<div class="text-green-500">Collection deleted! Redirecting...</div><script>window.location.href = '/collections';</script>`
|
||||||
|
return c.HTML(http.StatusOK, html)
|
||||||
|
}
|
||||||
|
|
||||||
return c.NoContent(http.StatusNoContent)
|
return c.NoContent(http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user