package httpapi import ( "errors" "net/http" "strings" "github.com/gin-gonic/gin" "github.com/szabadpalya/api/internal/hu" "github.com/szabadpalya/api/internal/store" ) func (s *Server) adminListCampaigns(c *gin.Context) { rows, err := s.store.ListAdminCampaigns(c.Request.Context()) if err != nil { s.fail(c, err) return } c.JSON(http.StatusOK, rows) } func (s *Server) adminOrganizations(c *gin.Context) { orgs, err := s.store.ListOrganizations(c.Request.Context()) if err != nil { s.fail(c, err) return } c.JSON(http.StatusOK, orgs) } func (s *Server) adminGetCampaign(c *gin.Context) { campaign, err := s.store.GetAdminCampaign(c.Request.Context(), c.Param("slug")) if errors.Is(err, store.ErrNotFound) { c.JSON(http.StatusNotFound, gin.H{"error": "not found"}) return } if err != nil { s.fail(c, err) return } c.JSON(http.StatusOK, campaign) } var validStatus = map[string]bool{ "DRAFT": true, "BEADVA": true, "AKTIV": true, "FINANSZIROZOTT": true, "LEZART": true, "ELUTASITVA": true, } var validTierType = map[string]bool{"DONATION": true, "DIGITAL": true, "PHYSICAL": true} // adminSaveCampaign handles both create and update: a body carrying an id // updates that campaign, a body without one creates it. func (s *Server) adminSaveCampaign(c *gin.Context) { var in store.CampaignInput if err := c.ShouldBindJSON(&in); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "hianyzo"}) return } in.Title = strings.TrimSpace(in.Title) in.Summary = strings.TrimSpace(in.Summary) in.Slug = hu.Slugify(firstNonEmpty(in.Slug, in.Title)) if in.Title == "" || in.Slug == "" || in.GoalAmount <= 0 || in.EndsAt == "" || in.OrganizationID == "" { c.JSON(http.StatusBadRequest, gin.H{"error": "hianyzo"}) return } if !validStatus[in.Status] { in.Status = "DRAFT" } // Enum values reach SQL as parameters, but an unknown one would surface as // a Postgres cast error rather than something the editor can explain. for i := range in.Tiers { if !validTierType[in.Tiers[i].Type] { in.Tiers[i].Type = "DONATION" } } result, err := s.store.SaveCampaign(c.Request.Context(), in) if errors.Is(err, store.ErrSlugTaken) { c.JSON(http.StatusConflict, gin.H{"error": "slug"}) return } // The editor only ever saves a campaign it loaded, so a missing id means a // request that was not made by it — an attempt to create one, which is a // thing this API no longer does. if errors.Is(err, store.ErrNotFound) { c.JSON(http.StatusNotFound, gin.H{"error": "nincs ilyen kampany"}) return } if err != nil { s.fail(c, err) return } c.JSON(http.StatusOK, result) } func (s *Server) adminDeleteCampaign(c *gin.Context) { slug := c.Param("slug") campaign, err := s.store.GetAdminCampaign(c.Request.Context(), slug) if errors.Is(err, store.ErrNotFound) { c.JSON(http.StatusNotFound, gin.H{"error": "not found"}) return } if err != nil { s.fail(c, err) return } err = s.store.DeleteCampaign(c.Request.Context(), campaign.ID) if errors.Is(err, store.ErrHasPledges) { c.JSON(http.StatusConflict, gin.H{"error": "van-tamogatas"}) return } if err != nil { s.fail(c, err) return } c.JSON(http.StatusOK, gin.H{"ok": true}) } func firstNonEmpty(values ...string) string { for _, v := range values { if strings.TrimSpace(v) != "" { return v } } return "" }