package router import ( "bookhoard/internal/database" "bookhoard/templates" "bytes" "encoding/json" "net/http" "strings" "github.com/google/uuid" "github.com/jackc/pgx/v5/pgtype" "github.com/labstack/echo/v5" ) func registerFiltersRoutes(cfg *Config) { e := cfg.Echo // JWT middleware for protected routes jwtMiddleware := createJWTMiddleware(cfg) protected := e.Group("/api", jwtMiddleware) // Saved filters routes filters := protected.Group("/saved-filters") filters.GET("", cfg.FiltersHandler.GetSavedFilters) filters.GET("/:id", cfg.FiltersHandler.GetSavedFilterByID) // POST route with HTMX support filters.POST("", func(c *echo.Context) error { // Check if HTMX request (expects HTML) if c.Request().Header.Get("HX-Request") == "true" { return handleCreateFilterHTML(c, cfg) } // Otherwise return JSON (API clients) return cfg.FiltersHandler.CreateSavedFilter(c) }) filters.PUT("/:id", cfg.FiltersHandler.UpdateSavedFilter) filters.DELETE("/:id", cfg.FiltersHandler.DeleteSavedFilter) } // handleCreateFilterHTML renders HTML response for HTMX requests func handleCreateFilterHTML(c *echo.Context, cfg *Config) error { user, ok := c.Get("user").(database.Users) if !ok { return c.String(http.StatusUnauthorized, "Unauthorized") } userUUID := uuid.UUID(user.ID.Bytes) // Parse form data var req struct { Name string `form:"filter_name"` ResourceType string `form:"resource_type"` } if err := c.Bind(&req); err != nil { return c.String(http.StatusBadRequest, "Invalid request body") } if req.Name == "" || req.ResourceType == "" { return c.String(http.StatusBadRequest, "name and resource_type are required") } // Collect filter data from individual form fields (via hx-include) filtersMap := collectFilterFormData(c) // Convert to JSON for database storage filtersJSON, err := json.Marshal(filtersMap) if err != nil { return c.String(http.StatusInternalServerError, "Failed to encode filters") } // Create filter using service layer filter, err := cfg.Queries.CreateSavedFilter(c.Request().Context(), database.CreateSavedFilterParams{ UserID: pgtype.UUID{Bytes: userUUID, Valid: true}, Name: req.Name, ResourceType: req.ResourceType, Filters: filtersJSON, }) if err != nil { errorMsg := err.Error() // Check for duplicate name error (wrapped or unwrapped) if strings.Contains(errorMsg, "filter with name") && strings.Contains(errorMsg, "already exists") { if c.Request().Header.Get("HX-Request") == "true" { return c.HTML(http.StatusConflict, `