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,359 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"fotbal-club/internal/models"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// ContactInfoController handles contact information and categories
|
||||
type ContactInfoController struct {
|
||||
DB *gorm.DB
|
||||
}
|
||||
|
||||
// NewContactInfoController creates a new ContactInfoController
|
||||
func NewContactInfoController(db *gorm.DB) *ContactInfoController {
|
||||
return &ContactInfoController{DB: db}
|
||||
}
|
||||
|
||||
// ==================== PUBLIC ENDPOINTS ====================
|
||||
|
||||
// GetPublicContacts returns all active contacts grouped by category (public)
|
||||
func (ctrl *ContactInfoController) GetPublicContacts(c *gin.Context) {
|
||||
var contacts []models.Contact
|
||||
if err := ctrl.DB.Preload("Category").
|
||||
Where("is_active = ?", true).
|
||||
Order("display_order ASC, created_at ASC").
|
||||
Find(&contacts).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to load contacts"})
|
||||
return
|
||||
}
|
||||
|
||||
// Group by category
|
||||
grouped := make(map[string][]models.Contact)
|
||||
uncategorized := []models.Contact{}
|
||||
|
||||
for _, contact := range contacts {
|
||||
if contact.Category != nil && contact.Category.IsActive {
|
||||
grouped[contact.Category.Name] = append(grouped[contact.Category.Name], contact)
|
||||
} else {
|
||||
uncategorized = append(uncategorized, contact)
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"categories": grouped,
|
||||
"uncategorized": uncategorized,
|
||||
})
|
||||
}
|
||||
|
||||
// GetPublicContactCategories returns all active contact categories (public)
|
||||
func (ctrl *ContactInfoController) GetPublicContactCategories(c *gin.Context) {
|
||||
var categories []models.ContactCategory
|
||||
if err := ctrl.DB.Where("is_active = ?", true).
|
||||
Order("display_order ASC, name ASC").
|
||||
Find(&categories).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to load categories"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, categories)
|
||||
}
|
||||
|
||||
// ==================== ADMIN: CONTACT CATEGORIES ====================
|
||||
|
||||
// GetContactCategories lists all contact categories (admin)
|
||||
func (ctrl *ContactInfoController) GetContactCategories(c *gin.Context) {
|
||||
var categories []models.ContactCategory
|
||||
if err := ctrl.DB.Order("display_order ASC, name ASC").Find(&categories).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to load categories"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, categories)
|
||||
}
|
||||
|
||||
// CreateContactCategory creates a new contact category (admin)
|
||||
func (ctrl *ContactInfoController) CreateContactCategory(c *gin.Context) {
|
||||
var body struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Description string `json:"description"`
|
||||
DisplayOrder *int `json:"display_order"`
|
||||
IsActive *bool `json:"is_active"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&body); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
category := models.ContactCategory{
|
||||
Name: strings.TrimSpace(body.Name),
|
||||
Description: strings.TrimSpace(body.Description),
|
||||
}
|
||||
|
||||
if body.DisplayOrder != nil {
|
||||
category.DisplayOrder = *body.DisplayOrder
|
||||
}
|
||||
if body.IsActive != nil {
|
||||
category.IsActive = *body.IsActive
|
||||
} else {
|
||||
category.IsActive = true
|
||||
}
|
||||
|
||||
if err := ctrl.DB.Create(&category).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create category"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusCreated, category)
|
||||
}
|
||||
|
||||
// UpdateContactCategory updates a contact category (admin)
|
||||
func (ctrl *ContactInfoController) UpdateContactCategory(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
|
||||
var category models.ContactCategory
|
||||
if err := ctrl.DB.First(&category, id).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Category not found"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Database error"})
|
||||
return
|
||||
}
|
||||
|
||||
var body struct {
|
||||
Name *string `json:"name"`
|
||||
Description *string `json:"description"`
|
||||
DisplayOrder *int `json:"display_order"`
|
||||
IsActive *bool `json:"is_active"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&body); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if body.Name != nil {
|
||||
category.Name = strings.TrimSpace(*body.Name)
|
||||
}
|
||||
if body.Description != nil {
|
||||
category.Description = strings.TrimSpace(*body.Description)
|
||||
}
|
||||
if body.DisplayOrder != nil {
|
||||
category.DisplayOrder = *body.DisplayOrder
|
||||
}
|
||||
if body.IsActive != nil {
|
||||
category.IsActive = *body.IsActive
|
||||
}
|
||||
|
||||
if err := ctrl.DB.Save(&category).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update category"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, category)
|
||||
}
|
||||
|
||||
// DeleteContactCategory deletes a contact category (admin)
|
||||
func (ctrl *ContactInfoController) DeleteContactCategory(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
|
||||
// Check if any contacts use this category
|
||||
var count int64
|
||||
if err := ctrl.DB.Model(&models.Contact{}).Where("category_id = ?", id).Count(&count).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Database error"})
|
||||
return
|
||||
}
|
||||
|
||||
if count > 0 {
|
||||
c.JSON(http.StatusConflict, gin.H{"error": "Cannot delete category with contacts. Remove contacts first."})
|
||||
return
|
||||
}
|
||||
|
||||
if err := ctrl.DB.Delete(&models.ContactCategory{}, id).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete category"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Category deleted"})
|
||||
}
|
||||
|
||||
// ==================== ADMIN: CONTACTS ====================
|
||||
|
||||
// GetContacts lists all contacts (admin)
|
||||
func (ctrl *ContactInfoController) GetContacts(c *gin.Context) {
|
||||
var contacts []models.Contact
|
||||
if err := ctrl.DB.Preload("Category").
|
||||
Order("display_order ASC, created_at ASC").
|
||||
Find(&contacts).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to load contacts"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, contacts)
|
||||
}
|
||||
|
||||
// CreateContact creates a new contact (admin)
|
||||
func (ctrl *ContactInfoController) CreateContact(c *gin.Context) {
|
||||
var body struct {
|
||||
CategoryID *uint `json:"category_id"`
|
||||
Name string `json:"name" binding:"required"`
|
||||
Position string `json:"position"`
|
||||
Email string `json:"email"`
|
||||
Phone string `json:"phone"`
|
||||
ImageURL string `json:"image_url"`
|
||||
Description string `json:"description"`
|
||||
DisplayOrder *int `json:"display_order"`
|
||||
IsActive *bool `json:"is_active"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&body); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
contact := models.Contact{
|
||||
CategoryID: body.CategoryID,
|
||||
Name: strings.TrimSpace(body.Name),
|
||||
Position: strings.TrimSpace(body.Position),
|
||||
Email: strings.TrimSpace(body.Email),
|
||||
Phone: strings.TrimSpace(body.Phone),
|
||||
ImageURL: strings.TrimSpace(body.ImageURL),
|
||||
Description: strings.TrimSpace(body.Description),
|
||||
}
|
||||
|
||||
if body.DisplayOrder != nil {
|
||||
contact.DisplayOrder = *body.DisplayOrder
|
||||
}
|
||||
if body.IsActive != nil {
|
||||
contact.IsActive = *body.IsActive
|
||||
} else {
|
||||
contact.IsActive = true
|
||||
}
|
||||
|
||||
// Validate category if provided
|
||||
if contact.CategoryID != nil {
|
||||
var cat models.ContactCategory
|
||||
if err := ctrl.DB.First(&cat, *contact.CategoryID).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid category_id"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Database error"})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err := ctrl.DB.Create(&contact).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create contact"})
|
||||
return
|
||||
}
|
||||
|
||||
// Reload with category
|
||||
ctrl.DB.Preload("Category").First(&contact, contact.ID)
|
||||
|
||||
c.JSON(http.StatusCreated, contact)
|
||||
}
|
||||
|
||||
// UpdateContact updates a contact (admin)
|
||||
func (ctrl *ContactInfoController) UpdateContact(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
|
||||
var contact models.Contact
|
||||
if err := ctrl.DB.First(&contact, id).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Contact not found"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Database error"})
|
||||
return
|
||||
}
|
||||
|
||||
var body struct {
|
||||
CategoryID *uint `json:"category_id"`
|
||||
Name *string `json:"name"`
|
||||
Position *string `json:"position"`
|
||||
Email *string `json:"email"`
|
||||
Phone *string `json:"phone"`
|
||||
ImageURL *string `json:"image_url"`
|
||||
Description *string `json:"description"`
|
||||
DisplayOrder *int `json:"display_order"`
|
||||
IsActive *bool `json:"is_active"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&body); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// Allow setting category to null by sending explicit null
|
||||
if c.Request.Header.Get("Content-Type") == "application/json" {
|
||||
var raw map[string]interface{}
|
||||
if err := c.ShouldBindJSON(&raw); err == nil {
|
||||
if _, exists := raw["category_id"]; exists {
|
||||
contact.CategoryID = body.CategoryID
|
||||
}
|
||||
}
|
||||
} else if body.CategoryID != nil {
|
||||
// Validate new category
|
||||
var cat models.ContactCategory
|
||||
if err := ctrl.DB.First(&cat, *body.CategoryID).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid category_id"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Database error"})
|
||||
return
|
||||
}
|
||||
contact.CategoryID = body.CategoryID
|
||||
}
|
||||
|
||||
if body.Name != nil {
|
||||
contact.Name = strings.TrimSpace(*body.Name)
|
||||
}
|
||||
if body.Position != nil {
|
||||
contact.Position = strings.TrimSpace(*body.Position)
|
||||
}
|
||||
if body.Email != nil {
|
||||
contact.Email = strings.TrimSpace(*body.Email)
|
||||
}
|
||||
if body.Phone != nil {
|
||||
contact.Phone = strings.TrimSpace(*body.Phone)
|
||||
}
|
||||
if body.ImageURL != nil {
|
||||
contact.ImageURL = strings.TrimSpace(*body.ImageURL)
|
||||
}
|
||||
if body.Description != nil {
|
||||
contact.Description = strings.TrimSpace(*body.Description)
|
||||
}
|
||||
if body.DisplayOrder != nil {
|
||||
contact.DisplayOrder = *body.DisplayOrder
|
||||
}
|
||||
if body.IsActive != nil {
|
||||
contact.IsActive = *body.IsActive
|
||||
}
|
||||
|
||||
if err := ctrl.DB.Save(&contact).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update contact"})
|
||||
return
|
||||
}
|
||||
|
||||
// Reload with category
|
||||
ctrl.DB.Preload("Category").First(&contact, contact.ID)
|
||||
|
||||
c.JSON(http.StatusOK, contact)
|
||||
}
|
||||
|
||||
// DeleteContact deletes a contact (admin)
|
||||
func (ctrl *ContactInfoController) DeleteContact(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
|
||||
if err := ctrl.DB.Delete(&models.Contact{}, id).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete contact"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Contact deleted"})
|
||||
}
|
||||
Reference in New Issue
Block a user