This commit is contained in:
Tomas Dvorak
2025-11-11 10:29:30 +01:00
parent d5b4faea61
commit 8762bde4bf
139 changed files with 7240 additions and 2870 deletions
+51 -24
View File
@@ -196,29 +196,35 @@ func (ec *EngagementController) PatchAvatar(c *gin.Context) {
// GET /api/v1/engagement/rewards (public)
func (ec *EngagementController) GetRewards(c *gin.Context) {
var unlock models.RewardItem
if err := ec.DB.Where("type = ?", "avatar_upload_unlock").First(&unlock).Error; err != nil {
unlock = models.RewardItem{
Name: "Odemknout vlastní avatar (upload)",
Type: "avatar_upload_unlock",
CostPoints: 250,
ImageURL: "",
Stock: -1,
Active: true,
}
_ = ec.DB.Create(&unlock).Error
} else {
if !unlock.Active {
_ = ec.DB.Model(&models.RewardItem{}).Where("id = ?", unlock.ID).Update("active", true).Error
}
}
var items []models.RewardItem
q := ec.DB.Where("active = ?", true)
if err := q.Order("created_at DESC").Find(&items).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to load rewards"})
return
}
c.JSON(http.StatusOK, items)
var unlock models.RewardItem
if err := ec.DB.Where("type = ?", "avatar_upload_unlock").First(&unlock).Error; err != nil {
unlock = models.RewardItem{
Name: "Odemknout vlastní avatar (upload)",
Type: "avatar_upload_unlock",
CostPoints: 50,
ImageURL: "",
Stock: -1,
Active: true,
}
_ = ec.DB.Create(&unlock).Error
} else {
updates := map[string]interface{}{}
if !unlock.Active { updates["active"] = true }
if unlock.Stock != -1 { updates["stock"] = -1 }
if strings.TrimSpace(unlock.Name) == "" || unlock.Name != "Odemknout vlastní avatar (upload)" {
updates["name"] = "Odemknout vlastní avatar (upload)"
}
if len(updates) > 0 {
_ = ec.DB.Model(&models.RewardItem{}).Where("id = ?", unlock.ID).Updates(updates).Error
}
}
var items []models.RewardItem
q := ec.DB.Where("active = ?", true)
if err := q.Order("created_at DESC").Find(&items).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to load rewards"})
return
}
c.JSON(http.StatusOK, items)
}
// POST /api/v1/engagement/redeem (auth)
@@ -419,6 +425,24 @@ func (ec *EngagementController) GetAchievements(c *gin.Context) {
// GET /api/v1/admin/engagement/rewards
func (ec *EngagementController) AdminListRewards(c *gin.Context) {
var items []models.RewardItem
var unlock models.RewardItem
if err := ec.DB.Where("type = ?", "avatar_upload_unlock").First(&unlock).Error; err != nil {
unlock = models.RewardItem{
Name: "Odemknout vlastní avatar (upload)",
Type: "avatar_upload_unlock",
CostPoints: 50,
ImageURL: "",
Stock: -1,
Active: true,
}
_ = ec.DB.Create(&unlock).Error
} else {
updates := map[string]interface{}{}
if !unlock.Active { updates["active"] = true }
if unlock.Stock != -1 { updates["stock"] = -1 }
if strings.TrimSpace(unlock.Name) == "" || unlock.Name != "Odemknout vlastní avatar (upload)" { updates["name"] = "Odemknout vlastní avatar (upload)" }
if len(updates) > 0 { _ = ec.DB.Model(&models.RewardItem{}).Where("id = ?", unlock.ID).Updates(updates).Error }
}
q := ec.DB.Model(&models.RewardItem{})
if v := strings.TrimSpace(c.Query("active")); v != "" {
if v == "true" || v == "1" { q = q.Where("active = ?", true) }
@@ -470,13 +494,16 @@ func (ec *EngagementController) AdminUpdateReward(c *gin.Context) {
var existing models.RewardItem
_ = ec.DB.First(&existing, id).Error
if strings.EqualFold(existing.Type, "avatar_upload_unlock") {
// Disallow disabling or changing type of the mandatory reward
// Disallow disabling or changing type, and restrict updates to cost_points only
if body.Active != nil && *body.Active == false {
c.JSON(http.StatusBadRequest, gin.H{"error": "This reward cannot be deactivated"}); return
}
if body.Type != nil && strings.ToLower(strings.TrimSpace(*body.Type)) != existing.Type {
c.JSON(http.StatusBadRequest, gin.H{"error": "Type cannot be changed for this reward"}); return
}
if body.Name != nil || body.ImageURL != nil || body.Stock != nil || body.Active != nil || body.Metadata != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Only price (cost_points) can be edited for this reward"}); return
}
}
updates := map[string]interface{}{}
if body.Name != nil { updates["name"] = strings.TrimSpace(*body.Name) }