mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-04 02:32:57 +00:00
upload
This commit is contained in:
@@ -0,0 +1,217 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
"fotbal-club/internal/models"
|
||||
"fotbal-club/internal/services"
|
||||
)
|
||||
|
||||
type EventController struct{ DB *gorm.DB }
|
||||
|
||||
// GetEventByID returns a single event by its ID (public; returns only public events unless owner)
|
||||
func (ctrl *EventController) GetEventByID(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
var ev models.Event
|
||||
if err := ctrl.DB.Preload("Attachments").First(&ev, id).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Event not found"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Database error"})
|
||||
return
|
||||
}
|
||||
// If not public, allow only owner (when identified upstream)
|
||||
if !ev.IsPublic {
|
||||
if userID, exists := c.Get("userID"); !exists || ev.CreatedByID != userID {
|
||||
c.JSON(http.StatusForbidden, gin.H{"error": "Not allowed"})
|
||||
return
|
||||
}
|
||||
}
|
||||
c.JSON(http.StatusOK, ev)
|
||||
}
|
||||
|
||||
type EventInput struct {
|
||||
Title string `json:"title" binding:"required"`
|
||||
Description string `json:"description"`
|
||||
StartTime time.Time `json:"start_time" binding:"required"`
|
||||
EndTime *time.Time `json:"end_time"`
|
||||
Location string `json:"location"`
|
||||
Type string `json:"type" binding:"required,oneof=match training meeting other"`
|
||||
IsPublic bool `json:"is_public"`
|
||||
CategoryName string `json:"category_name"`
|
||||
ImageURL string `json:"image_url"`
|
||||
FileURL string `json:"file_url"`
|
||||
YoutubeURL string `json:"youtube_url"`
|
||||
Latitude *float64 `json:"latitude"`
|
||||
Longitude *float64 `json:"longitude"`
|
||||
Attachments []struct {
|
||||
Name string `json:"name"`
|
||||
URL string `json:"url"`
|
||||
MimeType string `json:"mime_type"`
|
||||
Size int64 `json:"size"`
|
||||
} `json:"attachments"`
|
||||
}
|
||||
|
||||
func (ctrl *EventController) CreateEvent(c *gin.Context) {
|
||||
// Ensure latest schema (adds columns if missing)
|
||||
_ = ctrl.DB.AutoMigrate(&models.Event{}, &models.EventAttachment{})
|
||||
var input EventInput
|
||||
if err := c.ShouldBindJSON(&input); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
userID, _ := c.Get("userID")
|
||||
event := models.Event{
|
||||
Title: input.Title,
|
||||
Description: input.Description,
|
||||
StartTime: input.StartTime,
|
||||
EndTime: input.EndTime,
|
||||
Location: input.Location,
|
||||
Type: models.EventType(input.Type),
|
||||
IsPublic: input.IsPublic,
|
||||
CreatedByID: userID.(uint),
|
||||
CategoryName: input.CategoryName,
|
||||
ImageURL: input.ImageURL,
|
||||
FileURL: input.FileURL,
|
||||
YoutubeURL: input.YoutubeURL,
|
||||
Latitude: input.Latitude,
|
||||
Longitude: input.Longitude,
|
||||
}
|
||||
|
||||
if err := ctrl.DB.Create(&event).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create event"})
|
||||
return
|
||||
}
|
||||
// Create attachments if any
|
||||
if len(input.Attachments) > 0 {
|
||||
var atts []models.EventAttachment
|
||||
for _, a := range input.Attachments {
|
||||
if a.URL == "" { continue }
|
||||
atts = append(atts, models.EventAttachment{ EventID: event.ID, Name: a.Name, URL: a.URL, MimeType: a.MimeType, Size: a.Size })
|
||||
}
|
||||
if len(atts) > 0 {
|
||||
if err := ctrl.DB.Create(&atts).Error; err != nil {
|
||||
// non-fatal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reload with attachments
|
||||
var out models.Event
|
||||
_ = ctrl.DB.Preload("Attachments").First(&out, event.ID).Error
|
||||
|
||||
// Track file usage
|
||||
fileTracker := services.NewFileTracker(ctrl.DB)
|
||||
go fileTracker.TrackEventFiles(&out)
|
||||
|
||||
c.JSON(http.StatusCreated, out)
|
||||
}
|
||||
|
||||
func (ctrl *EventController) GetEvents(c *gin.Context) {
|
||||
var events []models.Event
|
||||
query := ctrl.DB.Preload("Attachments")
|
||||
|
||||
if userID, exists := c.Get("userID"); !exists {
|
||||
query = query.Where("is_public = ?", true)
|
||||
} else {
|
||||
query = query.Where("created_by_id = ? OR is_public = ?", userID, true)
|
||||
}
|
||||
|
||||
if err := query.Find(&events).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch events"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, events)
|
||||
}
|
||||
|
||||
func (ctrl *EventController) GetUpcomingEvents(c *gin.Context) {
|
||||
var events []models.Event
|
||||
query := ctrl.DB.Preload("Attachments").Where("start_time >= ?", time.Now()).Order("start_time ASC").Limit(5)
|
||||
|
||||
if userID, exists := c.Get("userID"); !exists {
|
||||
query = query.Where("is_public = ?", true)
|
||||
} else {
|
||||
query = query.Where("created_by_id = ? OR is_public = ?", userID, true)
|
||||
}
|
||||
|
||||
if err := query.Find(&events).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch events"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, events)
|
||||
}
|
||||
|
||||
// UpdateEvent updates an existing event (protected)
|
||||
func (ctrl *EventController) UpdateEvent(c *gin.Context) {
|
||||
// Ensure latest schema (adds columns if missing)
|
||||
_ = ctrl.DB.AutoMigrate(&models.Event{}, &models.EventAttachment{})
|
||||
id := c.Param("id")
|
||||
var ev models.Event
|
||||
if err := ctrl.DB.First(&ev, id).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Event not found"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Database error"})
|
||||
return
|
||||
}
|
||||
var input EventInput
|
||||
if err := c.ShouldBindJSON(&input); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
ev.Title = input.Title
|
||||
ev.Description = input.Description
|
||||
ev.StartTime = input.StartTime
|
||||
ev.EndTime = input.EndTime
|
||||
ev.Location = input.Location
|
||||
ev.Type = models.EventType(input.Type)
|
||||
ev.IsPublic = input.IsPublic
|
||||
ev.CategoryName = input.CategoryName
|
||||
ev.ImageURL = input.ImageURL
|
||||
ev.FileURL = input.FileURL
|
||||
ev.YoutubeURL = input.YoutubeURL
|
||||
ev.Latitude = input.Latitude
|
||||
ev.Longitude = input.Longitude
|
||||
if err := ctrl.DB.Save(&ev).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update event"})
|
||||
return
|
||||
}
|
||||
// Replace attachments (simple strategy)
|
||||
if err := ctrl.DB.Where("event_id = ?", ev.ID).Delete(&models.EventAttachment{}).Error; err == nil {
|
||||
if len(input.Attachments) > 0 {
|
||||
var atts []models.EventAttachment
|
||||
for _, a := range input.Attachments {
|
||||
if a.URL == "" { continue }
|
||||
atts = append(atts, models.EventAttachment{ EventID: ev.ID, Name: a.Name, URL: a.URL, MimeType: a.MimeType, Size: a.Size })
|
||||
}
|
||||
if len(atts) > 0 {
|
||||
_ = ctrl.DB.Create(&atts).Error
|
||||
}
|
||||
}
|
||||
}
|
||||
var out models.Event
|
||||
_ = ctrl.DB.Preload("Attachments").First(&out, ev.ID).Error
|
||||
|
||||
// Track file usage
|
||||
fileTracker := services.NewFileTracker(ctrl.DB)
|
||||
go fileTracker.TrackEventFiles(&out)
|
||||
|
||||
c.JSON(http.StatusOK, out)
|
||||
}
|
||||
|
||||
// DeleteEvent removes an event (protected)
|
||||
func (ctrl *EventController) DeleteEvent(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
if err := ctrl.DB.Delete(&models.Event{}, id).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete event"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"ok": true})
|
||||
}
|
||||
Reference in New Issue
Block a user