This commit is contained in:
Tomas Dvorak
2026-01-26 08:13:18 +01:00
parent aa036b6550
commit dfc079288f
505 changed files with 95755 additions and 5712 deletions
@@ -0,0 +1,193 @@
package controllers
import (
"net/http"
"strconv"
"fotbal-club/internal/models"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
// EshopAdminController handles admin management of eshop products and variants.
type EshopAdminController struct {
DB *gorm.DB
}
func NewEshopAdminController(db *gorm.DB) *EshopAdminController {
return &EshopAdminController{DB: db}
}
// AdminListProducts returns all products for admin management.
func (ctl *EshopAdminController) AdminListProducts(c *gin.Context) {
var products []models.EshopProduct
q := ctl.DB.Preload("Category").Preload("Variants").Order("created_at DESC, id DESC")
if err := q.Find(&products).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to load products"})
return
}
c.JSON(http.StatusOK, gin.H{"data": products})
}
// AdminGetProduct returns a single product by ID.
func (ctl *EshopAdminController) AdminGetProduct(c *gin.Context) {
id := c.Param("id")
var product models.EshopProduct
if err := ctl.DB.Preload("Category").Preload("Variants").First(&product, id).Error; err != nil {
if err == gorm.ErrRecordNotFound {
c.JSON(http.StatusNotFound, gin.H{"error": "Product not found"})
return
}
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to load product"})
return
}
c.JSON(http.StatusOK, product)
}
// AdminCreateProduct creates a new product.
func (ctl *EshopAdminController) AdminCreateProduct(c *gin.Context) {
var input models.EshopProduct
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if input.Currency == "" {
input.Currency = "CZK"
}
if err := ctl.DB.Create(&input).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create product"})
return
}
c.JSON(http.StatusCreated, input)
}
// AdminUpdateProduct updates an existing product.
func (ctl *EshopAdminController) AdminUpdateProduct(c *gin.Context) {
id := c.Param("id")
var existing models.EshopProduct
if err := ctl.DB.First(&existing, id).Error; err != nil {
if err == gorm.ErrRecordNotFound {
c.JSON(http.StatusNotFound, gin.H{"error": "Product not found"})
return
}
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to load product"})
return
}
var input models.EshopProduct
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
existing.Name = input.Name
existing.Slug = input.Slug
existing.ShortDescription = input.ShortDescription
existing.DescriptionHTML = input.DescriptionHTML
existing.PriceCents = input.PriceCents
existing.Currency = input.Currency
existing.VATRate = input.VATRate
existing.Active = input.Active
existing.StockMode = input.StockMode
existing.DefaultImageURL = input.DefaultImageURL
existing.GalleryJSON = input.GalleryJSON
existing.Tags = input.Tags
existing.MetadataJSON = input.MetadataJSON
existing.CategoryID = input.CategoryID
if existing.Currency == "" {
existing.Currency = "CZK"
}
if err := ctl.DB.Save(&existing).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update product"})
return
}
c.JSON(http.StatusOK, existing)
}
// AdminDeleteProduct soft-deletes a product.
func (ctl *EshopAdminController) AdminDeleteProduct(c *gin.Context) {
id := c.Param("id")
if err := ctl.DB.Delete(&models.EshopProduct{}, id).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete product"})
return
}
c.Status(http.StatusNoContent)
}
// ---- Variants ----
// AdminListVariants lists variants for a product.
func (ctl *EshopAdminController) AdminListVariants(c *gin.Context) {
productIDStr := c.Param("id")
productID, err := strconv.ParseUint(productIDStr, 10, 64)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid product id"})
return
}
var variants []models.EshopProductVariant
if err := ctl.DB.Where("product_id = ?", uint(productID)).Find(&variants).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to load variants"})
return
}
c.JSON(http.StatusOK, gin.H{"data": variants})
}
// AdminCreateVariant creates a variant for a product.
func (ctl *EshopAdminController) AdminCreateVariant(c *gin.Context) {
productIDStr := c.Param("id")
productID, err := strconv.ParseUint(productIDStr, 10, 64)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid product id"})
return
}
var input models.EshopProductVariant
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
input.ProductID = uint(productID)
if err := ctl.DB.Create(&input).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create variant"})
return
}
c.JSON(http.StatusCreated, input)
}
// AdminUpdateVariant updates a variant.
func (ctl *EshopAdminController) AdminUpdateVariant(c *gin.Context) {
variantID := c.Param("id")
var existing models.EshopProductVariant
if err := ctl.DB.First(&existing, variantID).Error; err != nil {
if err == gorm.ErrRecordNotFound {
c.JSON(http.StatusNotFound, gin.H{"error": "Variant not found"})
return
}
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to load variant"})
return
}
var input models.EshopProductVariant
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
existing.SKU = input.SKU
existing.Name = input.Name
existing.AttributesJSON = input.AttributesJSON
existing.StockQty = input.StockQty
existing.Barcode = input.Barcode
existing.ImageURL = input.ImageURL
if err := ctl.DB.Save(&existing).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update variant"})
return
}
c.JSON(http.StatusOK, existing)
}
// AdminDeleteVariant deletes a variant.
func (ctl *EshopAdminController) AdminDeleteVariant(c *gin.Context) {
variantID := c.Param("id")
if err := ctl.DB.Delete(&models.EshopProductVariant{}, variantID).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete variant"})
return
}
c.Status(http.StatusNoContent)
}