package controllers import ( configs "ares/config" database "ares/database/config" "ares/database/models" "fmt" "net/http" "os" "path/filepath" "strconv" "time" "github.com/gofiber/fiber/v3" ) // GetHero godoc // @Summary Get active hero/banner // @Tags Hero // @Produce json // @Success 200 {object} map[string]interface{} // @Failure 404 {object} map[string]string // @Router /api/v1/hero [get] func GetHero(c fiber.Ctx) error { var heroes []models.Hero // Aktif olan tüm hero'ları getir if err := database.DB.Where("is_active = ?", true).Find(&heroes).Error; err != nil { return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": "database error"}) } if len(heroes) == 0 { return c.Status(http.StatusNotFound).JSON(fiber.Map{"error": "no active hero found"}) } return c.JSON(heroes) } // GetHeroAll godoc // @Summary Get all heroes // @Description Returns all hero/banner records (no filter) // @Tags Hero // @Produce json // @Success 200 {array} map[string]interface{} // @Failure 404 {object} map[string]string // @Router /api/v1/heroes [get] func GetHeroAll(c fiber.Ctx) error { var heroes []models.Hero // Tüm hero'ları getir (filtre yok) if err := database.DB.Find(&heroes).Error; err != nil { return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": "database error"}) } if len(heroes) == 0 { return c.Status(http.StatusNotFound).JSON(fiber.Map{"error": "no hero found"}) } return c.JSON(heroes) } func CreateHero(c fiber.Ctx) error { var hero models.Hero if err := c.Bind().Body(&hero); err != nil { return c.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "invalid request body"}) } // Image upload file, err := c.FormFile("image") if err == nil { if _, err := os.Stat("./uploads/heroes"); os.IsNotExist(err) { os.MkdirAll("./uploads/heroes", 0755) } filename := fmt.Sprintf("%d_%s", time.Now().Unix(), file.Filename) filePath := filepath.Join("./uploads/heroes", filename) if err := c.SaveFile(file, filePath); err != nil { return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": "failed to save image"}) } hero.Image = "/uploads/heroes/" + filename } // Eğer sadece bir aktif hero olacaksa, diğerlerini pasife çekebiliriz //if hero.IsActive { // database.DB.Model(&models.Hero{}).Where("is_active = ?", true).Update("is_active", false) //} if err := database.DB.Create(&hero).Error; err != nil { return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": "hero could not be created"}) } return c.Status(http.StatusCreated).JSON(hero) } func UpdateHero(c fiber.Ctx) error { id, err := strconv.ParseUint(c.Params("id"), 10, 64) if err != nil { return c.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "invalid id"}) } var hero models.Hero if err := database.DB.First(&hero, id).Error; err != nil { return c.Status(http.StatusNotFound).JSON(fiber.Map{"error": "hero not found"}) } // Log raw request body (works for JSON). For multipart/form-data, also log form values. //log.Printf("Raw request body: %s\n", string(c.Body())) //log.Printf("Form title: %s, is_active: %s\n", c.FormValue("title"), c.FormValue("is_active")) var updateData models.Hero if err := c.Bind().Body(&updateData); err != nil { return c.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "invalid request body"}) } //log.Printf("Received update data: %+v\n", updateData) // Debug log // Image upload file, err := c.FormFile("image") if err == nil { if _, err := os.Stat("./uploads/heroes"); os.IsNotExist(err) { os.MkdirAll("./uploads/heroes", 0755) } filename := fmt.Sprintf("%d_%s", time.Now().Unix(), file.Filename) filePath := filepath.Join("./uploads/heroes", filename) if err := c.SaveFile(file, filePath); err != nil { return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": "failed to save image"}) } updateData.Image = "/uploads/heroes/" + filename } // Eğer bu hero aktif yapılıyorsa diğerlerini pasife çek //if updateData.IsActive { // database.DB.Model(&models.Hero{}).Where("id != ?", id).Where("is_active = ?", true).Update("is_active", false) //} // Handle is_active coming from multipart/form-data: parse and update explicitly if v := c.FormValue("is_active"); v != "" { if parsed, err := strconv.ParseBool(v); err == nil { // Ensure boolean field is updated even if it's false (zero value) if err := database.DB.Model(&hero).Update("is_active", parsed).Error; err != nil { return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": "hero could not be updated"}) } // reflect into updateData for consistency updateData.IsActive = parsed } else { configs.Logger.Sugar().Warnf("invalid is_active value: %s", v) } } if err := database.DB.Model(&hero).Updates(updateData).Error; err != nil { return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": "hero could not be updated"}) } return c.JSON(hero) } func DeleteHero(c fiber.Ctx) error { id, err := strconv.ParseUint(c.Params("id"), 10, 64) if err != nil { return c.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "invalid id"}) } var hero models.Hero if err := database.DB.First(&hero, id).Error; err != nil { return c.Status(http.StatusNotFound).JSON(fiber.Map{"error": "hero not found"}) } if err := database.DB.Delete(&hero).Error; err != nil { return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": "hero could not be deleted"}) } return c.JSON(fiber.Map{"message": "hero deleted successfully"}) }