first commit
This commit is contained in:
364
api/handlers/banner_handler.go
Normal file
364
api/handlers/banner_handler.go
Normal file
@@ -0,0 +1,364 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"gauth-central/config"
|
||||
"gauth-central/internal/services"
|
||||
"gauth-central/pkg/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type BannerHandler struct {
|
||||
bannerService *services.BannerService
|
||||
}
|
||||
|
||||
func NewBannerHandler(bannerService *services.BannerService) *BannerHandler {
|
||||
return &BannerHandler{bannerService: bannerService}
|
||||
}
|
||||
|
||||
// GetAllBanners godoc
|
||||
// @Summary Get all active banners
|
||||
// @Description Retrieve a list of active banners
|
||||
// @Tags banners
|
||||
// @Produce json
|
||||
// @Success 200 {array} models.Banner
|
||||
// @Failure 500 {object} map[string]string
|
||||
// @Router /banners [get]
|
||||
func (h *BannerHandler) GetAllBanners(c *gin.Context) {
|
||||
items, err := h.bannerService.GetAllBanners(true)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, items)
|
||||
}
|
||||
|
||||
// GetActiveBanner godoc
|
||||
// @Summary Get active banner
|
||||
// @Description Retrieve the newest active banner
|
||||
// @Tags banners
|
||||
// @Produce json
|
||||
// @Success 200 {object} models.Banner
|
||||
// @Failure 404 {object} map[string]string
|
||||
// @Router /banners/active [get]
|
||||
func (h *BannerHandler) GetActiveBanner(c *gin.Context) {
|
||||
item, err := h.bannerService.GetFirstActiveBanner()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, item)
|
||||
}
|
||||
|
||||
// AdminGetAllBanners godoc
|
||||
// @Summary Get all banners (Admin)
|
||||
// @Description Retrieve a list of all banners including inactive ones
|
||||
// @Tags admin
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce json
|
||||
// @Success 200 {array} models.Banner
|
||||
// @Failure 500 {object} map[string]string
|
||||
// @Router /admin/banners [get]
|
||||
func (h *BannerHandler) AdminGetAllBanners(c *gin.Context) {
|
||||
items, err := h.bannerService.GetAllBanners(false)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, items)
|
||||
}
|
||||
|
||||
// AdminGetBannerByID godoc
|
||||
// @Summary Get banner by ID (Admin)
|
||||
// @Description Retrieve details of a specific banner
|
||||
// @Tags admin
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce json
|
||||
// @Param id path string true "Banner ID"
|
||||
// @Success 200 {object} models.Banner
|
||||
// @Failure 404 {object} map[string]string
|
||||
// @Router /admin/banners/{id} [get]
|
||||
func (h *BannerHandler) AdminGetBannerByID(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
item, err := h.bannerService.GetBannerByID(id)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, item)
|
||||
}
|
||||
|
||||
// CreateBanner godoc
|
||||
// @Summary Create a new banner (Admin)
|
||||
// @Description Create a new banner entry
|
||||
// @Tags admin
|
||||
// @Security ApiKeyAuth
|
||||
// @Accept multipart/form-data
|
||||
// @Produce json
|
||||
// @Param color formData string false "Text color"
|
||||
// @Param title formData string false "Title"
|
||||
// @Param text1 formData string false "Text 1"
|
||||
// @Param text2 formData string false "Text 2"
|
||||
// @Param text4 formData string false "Text 4"
|
||||
// @Param text5 formData string false "Text 5"
|
||||
// @Param image formData file true "Image"
|
||||
// @Param image_k formData file false "Small image"
|
||||
// @Param image_k_txt formData string false "Small image text"
|
||||
// @Param is_active formData bool false "Is active"
|
||||
// @Success 201 {object} models.Banner
|
||||
// @Failure 400 {object} map[string]string
|
||||
// @Router /admin/banners [post]
|
||||
func (h *BannerHandler) CreateBanner(c *gin.Context) {
|
||||
color := strings.TrimSpace(c.PostForm("color"))
|
||||
title := strings.TrimSpace(c.PostForm("title"))
|
||||
text1 := strings.TrimSpace(c.PostForm("text1"))
|
||||
text2 := strings.TrimSpace(c.PostForm("text2"))
|
||||
text4 := strings.TrimSpace(c.PostForm("text4"))
|
||||
text5 := strings.TrimSpace(c.PostForm("text5"))
|
||||
imageKTxt := strings.TrimSpace(c.PostForm("image_k_txt"))
|
||||
|
||||
isActive := true
|
||||
isActivePtr, err := parseOptionalBool(c, "is_active")
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "is_active must be true or false"})
|
||||
return
|
||||
}
|
||||
if isActivePtr != nil {
|
||||
isActive = *isActivePtr
|
||||
}
|
||||
|
||||
imageFile, imageErr := c.FormFile("image")
|
||||
if imageErr != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "image is required"})
|
||||
return
|
||||
}
|
||||
if imageFile.Size > 5*1024*1024 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Image size exceeds 5MB limit"})
|
||||
return
|
||||
}
|
||||
|
||||
imageURL, err := utils.SaveOptimizedImage(imageFile, "./uploads/banner", "banner", &utils.ImageOptions{
|
||||
Width: config.AppConfig.BannerImageWidth,
|
||||
Height: config.AppConfig.BannerImageHeight,
|
||||
Quality: float32(config.AppConfig.BannerImageQuality),
|
||||
Format: config.AppConfig.BannerImageFormat,
|
||||
Mode: config.AppConfig.BannerImageMode,
|
||||
})
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save image: " + err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
imageKURL := ""
|
||||
imageKFile, imageKErr := c.FormFile("image_k")
|
||||
if imageKErr == nil {
|
||||
if imageKFile.Size > 5*1024*1024 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "image_k size exceeds 5MB limit"})
|
||||
return
|
||||
}
|
||||
imageKURL, err = utils.SaveOptimizedImage(imageKFile, "./uploads/banner/kucuk", "banner_k", &utils.ImageOptions{
|
||||
Width: config.AppConfig.BannerThumbWidth,
|
||||
Height: config.AppConfig.BannerThumbHeight,
|
||||
Quality: float32(config.AppConfig.BannerThumbQuality),
|
||||
Format: config.AppConfig.BannerThumbFormat,
|
||||
Mode: config.AppConfig.BannerThumbMode,
|
||||
})
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save image_k: " + err.Error()})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
item, err := h.bannerService.CreateBanner(
|
||||
color,
|
||||
title,
|
||||
text1,
|
||||
text2,
|
||||
text4,
|
||||
text5,
|
||||
imageURL,
|
||||
imageKURL,
|
||||
imageKTxt,
|
||||
isActive,
|
||||
)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusCreated, item)
|
||||
}
|
||||
|
||||
// UpdateBanner godoc
|
||||
// @Summary Update a banner (Admin)
|
||||
// @Description Update an existing banner entry
|
||||
// @Tags admin
|
||||
// @Security ApiKeyAuth
|
||||
// @Accept multipart/form-data
|
||||
// @Produce json
|
||||
// @Param id path string true "Banner ID"
|
||||
// @Param color formData string false "Text color"
|
||||
// @Param title formData string false "Title"
|
||||
// @Param text1 formData string false "Text 1"
|
||||
// @Param text2 formData string false "Text 2"
|
||||
// @Param text4 formData string false "Text 4"
|
||||
// @Param text5 formData string false "Text 5"
|
||||
// @Param image formData file false "Image"
|
||||
// @Param image_k formData file false "Small image"
|
||||
// @Param image_k_txt formData string false "Small image text"
|
||||
// @Param is_active formData bool false "Is active"
|
||||
// @Success 200 {object} models.Banner
|
||||
// @Failure 400 {object} map[string]string
|
||||
// @Failure 404 {object} map[string]string
|
||||
// @Router /admin/banners/{id} [put]
|
||||
func (h *BannerHandler) UpdateBanner(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
|
||||
color, hasColor := getOptionalFormValue(c, "color")
|
||||
title, hasTitle := getOptionalFormValue(c, "title")
|
||||
text1, hasText1 := getOptionalFormValue(c, "text1")
|
||||
text2, hasText2 := getOptionalFormValue(c, "text2")
|
||||
text4, hasText4 := getOptionalFormValue(c, "text4")
|
||||
text5, hasText5 := getOptionalFormValue(c, "text5")
|
||||
imageKTxt, hasImageKTxt := getOptionalFormValue(c, "image_k_txt")
|
||||
|
||||
var colorPtr *string
|
||||
var titlePtr *string
|
||||
var text1Ptr *string
|
||||
var text2Ptr *string
|
||||
var text4Ptr *string
|
||||
var text5Ptr *string
|
||||
var imageKTxtPtr *string
|
||||
|
||||
if hasColor {
|
||||
colorPtr = &color
|
||||
}
|
||||
if hasTitle {
|
||||
titlePtr = &title
|
||||
}
|
||||
if hasText1 {
|
||||
text1Ptr = &text1
|
||||
}
|
||||
if hasText2 {
|
||||
text2Ptr = &text2
|
||||
}
|
||||
if hasText4 {
|
||||
text4Ptr = &text4
|
||||
}
|
||||
if hasText5 {
|
||||
text5Ptr = &text5
|
||||
}
|
||||
if hasImageKTxt {
|
||||
imageKTxtPtr = &imageKTxt
|
||||
}
|
||||
|
||||
isActivePtr, err := parseOptionalBool(c, "is_active")
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "is_active must be true or false"})
|
||||
return
|
||||
}
|
||||
|
||||
var imagePtr *string
|
||||
imageFile, imageErr := c.FormFile("image")
|
||||
if imageErr == nil {
|
||||
if imageFile.Size > 5*1024*1024 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Image size exceeds 5MB limit"})
|
||||
return
|
||||
}
|
||||
item, fetchErr := h.bannerService.GetBannerByID(id)
|
||||
if fetchErr != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": fetchErr.Error()})
|
||||
return
|
||||
}
|
||||
if item.Image != "" && strings.HasPrefix(item.Image, "/uploads/") {
|
||||
_ = os.Remove("." + item.Image)
|
||||
}
|
||||
imageURL, saveErr := utils.SaveOptimizedImage(imageFile, "./uploads/banner", id, &utils.ImageOptions{
|
||||
Width: config.AppConfig.BannerImageWidth,
|
||||
Height: config.AppConfig.BannerImageHeight,
|
||||
Quality: float32(config.AppConfig.BannerImageQuality),
|
||||
Format: config.AppConfig.BannerImageFormat,
|
||||
Mode: config.AppConfig.BannerImageMode,
|
||||
})
|
||||
if saveErr != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save image: " + saveErr.Error()})
|
||||
return
|
||||
}
|
||||
imagePtr = &imageURL
|
||||
}
|
||||
|
||||
var imageKPtr *string
|
||||
imageKFile, imageKErr := c.FormFile("image_k")
|
||||
if imageKErr == nil {
|
||||
if imageKFile.Size > 5*1024*1024 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "image_k size exceeds 5MB limit"})
|
||||
return
|
||||
}
|
||||
item, fetchErr := h.bannerService.GetBannerByID(id)
|
||||
if fetchErr != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": fetchErr.Error()})
|
||||
return
|
||||
}
|
||||
if item.ImageK != "" && strings.HasPrefix(item.ImageK, "/uploads/") {
|
||||
_ = os.Remove("." + item.ImageK)
|
||||
}
|
||||
imageKURL, saveErr := utils.SaveOptimizedImage(imageKFile, "./uploads/banner/kucuk", id+"_k", &utils.ImageOptions{
|
||||
Width: config.AppConfig.BannerThumbWidth,
|
||||
Height: config.AppConfig.BannerThumbHeight,
|
||||
Quality: float32(config.AppConfig.BannerThumbQuality),
|
||||
Format: config.AppConfig.BannerThumbFormat,
|
||||
Mode: config.AppConfig.BannerThumbMode,
|
||||
})
|
||||
if saveErr != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save image_k: " + saveErr.Error()})
|
||||
return
|
||||
}
|
||||
imageKPtr = &imageKURL
|
||||
}
|
||||
|
||||
item, err := h.bannerService.UpdateBanner(
|
||||
id,
|
||||
colorPtr,
|
||||
titlePtr,
|
||||
text1Ptr,
|
||||
text2Ptr,
|
||||
text4Ptr,
|
||||
text5Ptr,
|
||||
imagePtr,
|
||||
imageKPtr,
|
||||
imageKTxtPtr,
|
||||
isActivePtr,
|
||||
)
|
||||
if err != nil {
|
||||
status := http.StatusInternalServerError
|
||||
if err.Error() == "banner not found" {
|
||||
status = http.StatusNotFound
|
||||
}
|
||||
c.JSON(status, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, item)
|
||||
}
|
||||
|
||||
// DeleteBanner godoc
|
||||
// @Summary Delete a banner (Admin)
|
||||
// @Description Delete a banner by ID
|
||||
// @Tags admin
|
||||
// @Security ApiKeyAuth
|
||||
// @Param id path string true "Banner ID"
|
||||
// @Success 200 {object} map[string]string
|
||||
// @Failure 404 {object} map[string]string
|
||||
// @Router /admin/banners/{id} [delete]
|
||||
func (h *BannerHandler) DeleteBanner(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
if err := h.bannerService.DeleteBanner(id); err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Banner deleted successfully"})
|
||||
}
|
||||
Reference in New Issue
Block a user