package controllers import ( "math" "strconv" "github.com/gofiber/fiber/v2" "github.com/sujit-baniya/fiber-boilerplate/pkg/models" ) // SaasIndex renderiza la vista del panel de gestión de productos SaaS. func SaasIndex(c *fiber.Ctx) error { data := fiber.Map{ "user": c.Locals("user").(map[string]interface{}), "modules": c.Locals("userModules"), } if err := c.Render("saas", data, "layouts/main"); err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()}) } return nil } // GetSaasProductos devuelve la lista paginada en JSON (para Alpine/HTMX). func GetSaasProductos(c *fiber.Ctx) error { page, _ := strconv.Atoi(c.Query("page", "1")) if page < 1 { page = 1 } search := c.Query("search", "") limit := 10 offset := (page - 1) * limit items, total, err := models.GetAllSaasProductos(limit, offset, search) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()}) } servicios, _ := models.GetAllServiciosSelect() return c.JSON(fiber.Map{ "items": items, "servicios": servicios, "total": total, "totalPages": int(math.Ceil(float64(total) / float64(limit))), "page": page, "limit": limit, }) } // CreateSaasProducto crea un nuevo producto SaaS. func CreateSaasProducto(c *fiber.Ctx) error { type Req struct { Nombre string `json:"nombre"` Slug string `json:"slug"` Descripcion string `json:"descripcion"` LogoURL string `json:"logo_url"` ServicioID *uint `json:"servicio_id"` Activo bool `json:"activo"` Orden int `json:"orden"` } var req Req if err := c.BodyParser(&req); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Datos inválidos"}) } if req.Nombre == "" || req.Slug == "" { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Nombre y slug son obligatorios"}) } item := &models.SaasProducto{ Nombre: req.Nombre, Slug: req.Slug, Descripcion: req.Descripcion, LogoURL: req.LogoURL, ServicioID: req.ServicioID, Activo: req.Activo, Orden: req.Orden, } if err := models.CreateSaasProducto(item); err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()}) } return c.JSON(fiber.Map{"message": "Producto SaaS creado", "item": item}) } // UpdateSaasProducto actualiza un producto SaaS existente. func UpdateSaasProducto(c *fiber.Ctx) error { id, err := strconv.ParseUint(c.Params("id"), 10, 32) if err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "ID inválido"}) } type Req struct { Nombre string `json:"nombre"` Slug string `json:"slug"` Descripcion string `json:"descripcion"` LogoURL string `json:"logo_url"` ServicioID *uint `json:"servicio_id"` Activo bool `json:"activo"` Orden int `json:"orden"` } var req Req if err := c.BodyParser(&req); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Datos inválidos"}) } item := &models.SaasProducto{ Nombre: req.Nombre, Slug: req.Slug, Descripcion: req.Descripcion, LogoURL: req.LogoURL, ServicioID: req.ServicioID, Activo: req.Activo, Orden: req.Orden, } item.ID = uint(id) if err := models.UpdateSaasProducto(item); err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()}) } return c.JSON(fiber.Map{"message": "Producto SaaS actualizado"}) } // DeleteSaasProducto elimina un producto SaaS. func DeleteSaasProducto(c *fiber.Ctx) error { id, err := strconv.ParseUint(c.Params("id"), 10, 32) if err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "ID inválido"}) } if err := models.DeleteSaasProducto(uint(id)); err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()}) } return c.JSON(fiber.Map{"message": "Producto SaaS eliminado"}) }