mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-03 18:22:57 +00:00
dev day #99
This commit is contained in:
@@ -26,7 +26,7 @@ func NewNavigationController(db *gorm.DB) *NavigationController {
|
||||
// @Router /api/v1/navigation [get]
|
||||
func (nc *NavigationController) GetNavigationItems(c *gin.Context) {
|
||||
var items []models.NavigationItem
|
||||
|
||||
|
||||
// Get only top-level items (no parent) that are visible and NOT admin-only
|
||||
if err := nc.DB.Where("parent_id IS NULL AND visible = ? AND requires_admin = ?", true, false).
|
||||
Order("display_order ASC").
|
||||
@@ -37,7 +37,7 @@ func (nc *NavigationController) GetNavigationItems(c *gin.Context) {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch navigation items"})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Compute URLs for items
|
||||
for i := range items {
|
||||
if items[i].URL == "" {
|
||||
@@ -49,7 +49,7 @@ func (nc *NavigationController) GetNavigationItems(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
c.JSON(http.StatusOK, items)
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ func (nc *NavigationController) GetNavigationItems(c *gin.Context) {
|
||||
// @Router /api/v1/admin/navigation [get]
|
||||
func (nc *NavigationController) GetAllNavigationItems(c *gin.Context) {
|
||||
var items []models.NavigationItem
|
||||
|
||||
|
||||
if err := nc.DB.Where("parent_id IS NULL").
|
||||
Order("requires_admin ASC, display_order ASC").
|
||||
Preload("Children", func(db *gorm.DB) *gorm.DB {
|
||||
@@ -73,7 +73,7 @@ func (nc *NavigationController) GetAllNavigationItems(c *gin.Context) {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch navigation items"})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Compute URLs for items
|
||||
for i := range items {
|
||||
if items[i].URL == "" {
|
||||
@@ -85,7 +85,7 @@ func (nc *NavigationController) GetAllNavigationItems(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
c.JSON(http.StatusOK, items)
|
||||
}
|
||||
|
||||
@@ -101,40 +101,40 @@ func (nc *NavigationController) GetAllNavigationItems(c *gin.Context) {
|
||||
// @Router /api/v1/admin/navigation [post]
|
||||
func (nc *NavigationController) CreateNavigationItem(c *gin.Context) {
|
||||
var item models.NavigationItem
|
||||
|
||||
|
||||
if err := c.ShouldBindJSON(&item); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// If no display order is set, put it at the end
|
||||
if item.DisplayOrder == 0 {
|
||||
var maxOrder int
|
||||
query := nc.DB.Model(&models.NavigationItem{})
|
||||
|
||||
|
||||
// Calculate max order for items at the same level (same parent) and same admin status
|
||||
if item.ParentID == nil {
|
||||
query = query.Where("parent_id IS NULL")
|
||||
} else {
|
||||
query = query.Where("parent_id = ?", *item.ParentID)
|
||||
}
|
||||
|
||||
|
||||
// Also consider requires_admin to keep frontend and admin items separate
|
||||
query = query.Where("requires_admin = ?", item.RequiresAdmin)
|
||||
|
||||
|
||||
query.Select("COALESCE(MAX(display_order), -1) + 1").Scan(&maxOrder)
|
||||
item.DisplayOrder = maxOrder
|
||||
}
|
||||
|
||||
|
||||
if err := nc.DB.Create(&item).Error; err != nil {
|
||||
// Log the actual error for debugging
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": "Failed to create navigation item",
|
||||
"error": "Failed to create navigation item",
|
||||
"details": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
c.JSON(http.StatusCreated, item)
|
||||
}
|
||||
|
||||
@@ -155,13 +155,13 @@ func (nc *NavigationController) UpdateNavigationItem(c *gin.Context) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid ID"})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
var item models.NavigationItem
|
||||
if err := nc.DB.First(&item, id).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Navigation item not found"})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Bind into a generic map to know which fields are present (partial update)
|
||||
var raw map[string]interface{}
|
||||
if err := c.ShouldBindJSON(&raw); err != nil {
|
||||
@@ -173,19 +173,29 @@ func (nc *NavigationController) UpdateNavigationItem(c *gin.Context) {
|
||||
updates := map[string]interface{}{}
|
||||
|
||||
if v, ok := raw["label"]; ok {
|
||||
if s, ok2 := v.(string); ok2 { updates["label"] = s }
|
||||
if s, ok2 := v.(string); ok2 {
|
||||
updates["label"] = s
|
||||
}
|
||||
}
|
||||
if v, ok := raw["url"]; ok {
|
||||
if s, ok2 := v.(string); ok2 { updates["url"] = s }
|
||||
if s, ok2 := v.(string); ok2 {
|
||||
updates["url"] = s
|
||||
}
|
||||
}
|
||||
if v, ok := raw["icon"]; ok {
|
||||
if s, ok2 := v.(string); ok2 { updates["icon"] = s }
|
||||
if s, ok2 := v.(string); ok2 {
|
||||
updates["icon"] = s
|
||||
}
|
||||
}
|
||||
if v, ok := raw["type"]; ok {
|
||||
if s, ok2 := v.(string); ok2 { updates["type"] = s }
|
||||
if s, ok2 := v.(string); ok2 {
|
||||
updates["type"] = s
|
||||
}
|
||||
}
|
||||
if v, ok := raw["page_type"]; ok {
|
||||
if s, ok2 := v.(string); ok2 { updates["page_type"] = s }
|
||||
if s, ok2 := v.(string); ok2 {
|
||||
updates["page_type"] = s
|
||||
}
|
||||
}
|
||||
if v, ok := raw["page_id"]; ok {
|
||||
switch t := v.(type) {
|
||||
@@ -202,7 +212,9 @@ func (nc *NavigationController) UpdateNavigationItem(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
if v, ok := raw["visible"]; ok {
|
||||
if b, ok2 := v.(bool); ok2 { updates["visible"] = b }
|
||||
if b, ok2 := v.(bool); ok2 {
|
||||
updates["visible"] = b
|
||||
}
|
||||
}
|
||||
if v, ok := raw["display_order"]; ok {
|
||||
switch t := v.(type) {
|
||||
@@ -231,16 +243,24 @@ func (nc *NavigationController) UpdateNavigationItem(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
if v, ok := raw["target"]; ok {
|
||||
if s, ok2 := v.(string); ok2 { updates["target"] = s }
|
||||
if s, ok2 := v.(string); ok2 {
|
||||
updates["target"] = s
|
||||
}
|
||||
}
|
||||
if v, ok := raw["css_class"]; ok {
|
||||
if s, ok2 := v.(string); ok2 { updates["css_class"] = s }
|
||||
if s, ok2 := v.(string); ok2 {
|
||||
updates["css_class"] = s
|
||||
}
|
||||
}
|
||||
if v, ok := raw["requires_auth"]; ok {
|
||||
if b, ok2 := v.(bool); ok2 { updates["requires_auth"] = b }
|
||||
if b, ok2 := v.(bool); ok2 {
|
||||
updates["requires_auth"] = b
|
||||
}
|
||||
}
|
||||
if v, ok := raw["requires_admin"]; ok {
|
||||
if b, ok2 := v.(bool); ok2 { updates["requires_admin"] = b }
|
||||
if b, ok2 := v.(bool); ok2 {
|
||||
updates["requires_admin"] = b
|
||||
}
|
||||
}
|
||||
|
||||
if len(updates) == 0 {
|
||||
@@ -251,7 +271,7 @@ func (nc *NavigationController) UpdateNavigationItem(c *gin.Context) {
|
||||
|
||||
if err := nc.DB.Model(&item).Updates(updates).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": "Failed to update navigation item",
|
||||
"error": "Failed to update navigation item",
|
||||
"details": err.Error(),
|
||||
})
|
||||
return
|
||||
@@ -280,12 +300,12 @@ func (nc *NavigationController) DeleteNavigationItem(c *gin.Context) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid ID"})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if err := nc.DB.Delete(&models.NavigationItem{}, id).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete navigation item"})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Navigation item deleted successfully"})
|
||||
}
|
||||
|
||||
@@ -305,7 +325,7 @@ func (nc *NavigationController) ReorderNavigationItems(c *gin.Context) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Update each item's order in a transaction
|
||||
err := nc.DB.Transaction(func(tx *gorm.DB) error {
|
||||
for _, order := range orders {
|
||||
@@ -314,7 +334,7 @@ func (nc *NavigationController) ReorderNavigationItems(c *gin.Context) {
|
||||
if !ok1 || !ok2 {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
if err := tx.Model(&models.NavigationItem{}).
|
||||
Where("id = ?", id).
|
||||
Update("display_order", displayOrder).Error; err != nil {
|
||||
@@ -323,12 +343,12 @@ func (nc *NavigationController) ReorderNavigationItems(c *gin.Context) {
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to reorder navigation items"})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Navigation items reordered successfully"})
|
||||
}
|
||||
|
||||
@@ -341,14 +361,14 @@ func (nc *NavigationController) ReorderNavigationItems(c *gin.Context) {
|
||||
// @Router /api/v1/social-links [get]
|
||||
func (nc *NavigationController) GetSocialLinks(c *gin.Context) {
|
||||
var links []models.SocialLink
|
||||
|
||||
|
||||
if err := nc.DB.Where("visible = ?", true).
|
||||
Order("display_order ASC").
|
||||
Find(&links).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch social links"})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
c.JSON(http.StatusOK, links)
|
||||
}
|
||||
|
||||
@@ -362,12 +382,12 @@ func (nc *NavigationController) GetSocialLinks(c *gin.Context) {
|
||||
// @Router /api/v1/admin/social-links [get]
|
||||
func (nc *NavigationController) GetAllSocialLinks(c *gin.Context) {
|
||||
var links []models.SocialLink
|
||||
|
||||
|
||||
if err := nc.DB.Order("display_order ASC").Find(&links).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch social links"})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
c.JSON(http.StatusOK, links)
|
||||
}
|
||||
|
||||
@@ -383,12 +403,12 @@ func (nc *NavigationController) GetAllSocialLinks(c *gin.Context) {
|
||||
// @Router /api/v1/admin/social-links [post]
|
||||
func (nc *NavigationController) CreateSocialLink(c *gin.Context) {
|
||||
var link models.SocialLink
|
||||
|
||||
|
||||
if err := c.ShouldBindJSON(&link); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// If no display order is set, put it at the end
|
||||
if link.DisplayOrder == 0 {
|
||||
var maxOrder int
|
||||
@@ -397,12 +417,12 @@ func (nc *NavigationController) CreateSocialLink(c *gin.Context) {
|
||||
Scan(&maxOrder)
|
||||
link.DisplayOrder = maxOrder
|
||||
}
|
||||
|
||||
|
||||
if err := nc.DB.Create(&link).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create social link"})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
c.JSON(http.StatusCreated, link)
|
||||
}
|
||||
|
||||
@@ -423,30 +443,30 @@ func (nc *NavigationController) UpdateSocialLink(c *gin.Context) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid ID"})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
var link models.SocialLink
|
||||
if err := nc.DB.First(&link, id).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Social link not found"})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
var updates models.SocialLink
|
||||
if err := c.ShouldBindJSON(&updates); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
link.Platform = updates.Platform
|
||||
link.URL = updates.URL
|
||||
link.DisplayOrder = updates.DisplayOrder
|
||||
link.Visible = updates.Visible
|
||||
link.Icon = updates.Icon
|
||||
|
||||
|
||||
if err := nc.DB.Save(&link).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update social link"})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
c.JSON(http.StatusOK, link)
|
||||
}
|
||||
|
||||
@@ -465,12 +485,12 @@ func (nc *NavigationController) DeleteSocialLink(c *gin.Context) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid ID"})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if err := nc.DB.Delete(&models.SocialLink{}, id).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete social link"})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Social link deleted successfully"})
|
||||
}
|
||||
|
||||
@@ -490,7 +510,7 @@ func (nc *NavigationController) ReorderSocialLinks(c *gin.Context) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
err := nc.DB.Transaction(func(tx *gorm.DB) error {
|
||||
for _, order := range orders {
|
||||
id, ok1 := order["id"]
|
||||
@@ -498,7 +518,7 @@ func (nc *NavigationController) ReorderSocialLinks(c *gin.Context) {
|
||||
if !ok1 || !ok2 {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
if err := tx.Model(&models.SocialLink{}).
|
||||
Where("id = ?", id).
|
||||
Update("display_order", displayOrder).Error; err != nil {
|
||||
@@ -507,12 +527,12 @@ func (nc *NavigationController) ReorderSocialLinks(c *gin.Context) {
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to reorder social links"})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Social links reordered successfully"})
|
||||
}
|
||||
|
||||
@@ -524,17 +544,17 @@ func (nc *NavigationController) ReorderSocialLinks(c *gin.Context) {
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /api/v1/admin/navigation/seed [post]
|
||||
func (nc *NavigationController) SeedDefaultNavigation(c *gin.Context) {
|
||||
// Check existing counts for frontend and admin separately
|
||||
var frontendCount int64
|
||||
var adminCount int64
|
||||
nc.DB.Model(&models.NavigationItem{}).Where("requires_admin = ?", false).Count(&frontendCount)
|
||||
nc.DB.Model(&models.NavigationItem{}).Where("requires_admin = ?", true).Count(&adminCount)
|
||||
|
||||
// Default frontend navigation items
|
||||
frontendItems := []models.NavigationItem{
|
||||
{Label: "Domů", Type: models.NavTypePage, PageType: "home", DisplayOrder: 0, Visible: true, RequiresAdmin: false},
|
||||
{Label: "O klubu", Type: models.NavTypePage, PageType: "about", DisplayOrder: 1, Visible: true, RequiresAdmin: false},
|
||||
{Label: "Kalendář", Type: models.NavTypePage, PageType: "calendar", DisplayOrder: 2, Visible: true, RequiresAdmin: false},
|
||||
// Check existing counts for frontend and admin separately
|
||||
var frontendCount int64
|
||||
var adminCount int64
|
||||
nc.DB.Model(&models.NavigationItem{}).Where("requires_admin = ?", false).Count(&frontendCount)
|
||||
nc.DB.Model(&models.NavigationItem{}).Where("requires_admin = ?", true).Count(&adminCount)
|
||||
|
||||
// Default frontend navigation items
|
||||
frontendItems := []models.NavigationItem{
|
||||
{Label: "Domů", Type: models.NavTypePage, PageType: "home", DisplayOrder: 0, Visible: true, RequiresAdmin: false},
|
||||
{Label: "O klubu", Type: models.NavTypePage, PageType: "about", DisplayOrder: 1, Visible: true, RequiresAdmin: false},
|
||||
{Label: "Kalendář", Type: models.NavTypePage, PageType: "calendar", DisplayOrder: 2, Visible: true, RequiresAdmin: false},
|
||||
{Label: "Zápasy", Type: models.NavTypePage, PageType: "matches", DisplayOrder: 3, Visible: true, RequiresAdmin: false},
|
||||
{Label: "Aktivity", Type: models.NavTypePage, PageType: "activities", DisplayOrder: 4, Visible: true, RequiresAdmin: false},
|
||||
{Label: "Hráči", Type: models.NavTypePage, PageType: "players", DisplayOrder: 5, Visible: true, RequiresAdmin: false},
|
||||
@@ -545,128 +565,257 @@ func (nc *NavigationController) SeedDefaultNavigation(c *gin.Context) {
|
||||
{Label: "Sponzoři", Type: models.NavTypePage, PageType: "sponsors", DisplayOrder: 10, Visible: true, RequiresAdmin: false},
|
||||
{Label: "Kontakt", Type: models.NavTypePage, PageType: "contact", DisplayOrder: 11, Visible: true, RequiresAdmin: false},
|
||||
}
|
||||
|
||||
// Create items in a transaction with admin categories and children (seed missing parts only)
|
||||
seededFrontend := false
|
||||
seededAdmin := false
|
||||
err := nc.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if frontendCount == 0 {
|
||||
for _, item := range frontendItems {
|
||||
if err := tx.Create(&item).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
seededFrontend = true
|
||||
}
|
||||
|
||||
if adminCount == 0 {
|
||||
catOrder := 0
|
||||
createCategory := func(label string) (*models.NavigationItem, error) {
|
||||
cat := &models.NavigationItem{Label: label, Type: models.NavTypeDropdown, DisplayOrder: catOrder, Visible: true, RequiresAdmin: true}
|
||||
catOrder++
|
||||
if err := tx.Create(cat).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cat, nil
|
||||
}
|
||||
// Create items in a transaction with admin categories and children (seed missing parts only)
|
||||
seededFrontend := false
|
||||
seededAdmin := false
|
||||
addedMissing := false
|
||||
err := nc.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if frontendCount == 0 {
|
||||
for _, item := range frontendItems {
|
||||
if err := tx.Create(&item).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
seededFrontend = true
|
||||
}
|
||||
|
||||
createChild := func(parent *models.NavigationItem, label, pageType string, order int) error {
|
||||
pid := parent.ID
|
||||
child := &models.NavigationItem{Label: label, Type: models.NavTypeInternal, PageType: pageType, DisplayOrder: order, Visible: true, RequiresAdmin: true}
|
||||
child.ParentID = &pid
|
||||
return tx.Create(child).Error
|
||||
}
|
||||
if adminCount == 0 {
|
||||
catOrder := 0
|
||||
createCategory := func(label string) (*models.NavigationItem, error) {
|
||||
cat := &models.NavigationItem{Label: label, Type: models.NavTypeDropdown, DisplayOrder: catOrder, Visible: true, RequiresAdmin: true}
|
||||
catOrder++
|
||||
if err := tx.Create(cat).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cat, nil
|
||||
}
|
||||
|
||||
zakladni, err := createCategory("Základní")
|
||||
if err != nil { return err }
|
||||
if err := createChild(zakladni, "Nástěnka", "dashboard", 0); err != nil { return err }
|
||||
if err := createChild(zakladni, "Analytika", "analytics", 1); err != nil { return err }
|
||||
createChild := func(parent *models.NavigationItem, label, pageType string, order int) error {
|
||||
pid := parent.ID
|
||||
child := &models.NavigationItem{Label: label, Type: models.NavTypeInternal, PageType: pageType, DisplayOrder: order, Visible: true, RequiresAdmin: true}
|
||||
child.ParentID = &pid
|
||||
return tx.Create(child).Error
|
||||
}
|
||||
|
||||
sport, err := createCategory("Sport")
|
||||
if err != nil { return err }
|
||||
if err := createChild(sport, "Týmy", "teams", 0); err != nil { return err }
|
||||
if err := createChild(sport, "Zápasy", "matches", 1); err != nil { return err }
|
||||
if err := createChild(sport, "Hráči", "players", 2); err != nil { return err }
|
||||
if err := createChild(sport, "Alias soutěží", "competition_aliases", 3); err != nil { return err }
|
||||
if err := createChild(sport, "Tabule (Scoreboard)", "scoreboard", 4); err != nil { return err }
|
||||
if err := createChild(sport, "Scoreboard Remote", "scoreboard_remote", 5); err != nil { return err }
|
||||
zakladni, err := createCategory("Základní")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(zakladni, "Nástěnka", "dashboard", 0); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(zakladni, "Analytika", "analytics", 1); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
obsah, err := createCategory("Obsah")
|
||||
if err != nil { return err }
|
||||
if err := createChild(obsah, "Články", "articles", 0); err != nil { return err }
|
||||
if err := createChild(obsah, "Aktivity", "activities", 1); err != nil { return err }
|
||||
// Kategorie admin page removed (categories derived from competition aliases)
|
||||
if err := createChild(obsah, "Komentáře", "comments", 2); err != nil { return err }
|
||||
sport, err := createCategory("Sport")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(sport, "Týmy", "teams", 0); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(sport, "Zápasy", "matches", 1); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(sport, "Hráči", "players", 2); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(sport, "Alias soutěží", "competition_aliases", 3); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(sport, "Tabule (Scoreboard)", "scoreboard", 4); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(sport, "Scoreboard Remote", "scoreboard_remote", 5); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
media, err := createCategory("Média")
|
||||
if err != nil { return err }
|
||||
if err := createChild(media, "Videa", "videos", 0); err != nil { return err }
|
||||
if err := createChild(media, "Galerie (Zonerama)", "gallery", 1); err != nil { return err }
|
||||
if err := createChild(media, "Soubory", "files", 2); err != nil { return err }
|
||||
obsah, err := createCategory("Obsah")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(obsah, "Články", "articles", 0); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(obsah, "Aktivity", "activities", 1); err != nil {
|
||||
return err
|
||||
}
|
||||
// "O klubu" admin page
|
||||
if err := createChild(obsah, "O klubu", "about", 2); err != nil {
|
||||
return err
|
||||
}
|
||||
// Kategorie admin page removed (categories derived from competition aliases)
|
||||
if err := createChild(obsah, "Komentáře", "comments", 3); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
kom, err := createCategory("Komunikace")
|
||||
if err != nil { return err }
|
||||
if err := createChild(kom, "Zprávy", "messages", 0); err != nil { return err }
|
||||
if err := createChild(kom, "Zpravodaj", "newsletter", 1); err != nil { return err }
|
||||
if err := createChild(kom, "Kontakty", "contacts", 2); err != nil { return err }
|
||||
media, err := createCategory("Média")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(media, "Videa", "videos", 0); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(media, "Galerie (Zonerama)", "gallery", 1); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(media, "Soubory", "files", 2); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
marketing, err := createCategory("Marketing")
|
||||
if err != nil { return err }
|
||||
if err := createChild(marketing, "Sponzoři", "sponsors", 0); err != nil { return err }
|
||||
if err := createChild(marketing, "Bannery", "banners", 1); err != nil { return err }
|
||||
if err := createChild(marketing, "Oblečení", "clothing", 2); err != nil { return err }
|
||||
if err := createChild(marketing, "Ankety", "polls", 3); err != nil { return err }
|
||||
if err := createChild(marketing, "Soutěže", "sweepstakes", 4); err != nil { return err }
|
||||
if err := createChild(marketing, "Odměny & Úspěchy", "engagement", 5); err != nil { return err }
|
||||
if err := createChild(marketing, "Zkrácené odkazy", "shortlinks", 6); err != nil { return err }
|
||||
kom, err := createCategory("Komunikace")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(kom, "Zprávy", "messages", 0); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(kom, "Zpravodaj", "newsletter", 1); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(kom, "Kontakty", "contacts", 2); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nastroje, err := createCategory("Nástroje")
|
||||
if err != nil { return err }
|
||||
if err := createChild(nastroje, "Prefetch & Cache", "prefetch", 0); err != nil { return err }
|
||||
marketing, err := createCategory("Marketing")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(marketing, "Sponzoři", "sponsors", 0); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(marketing, "Bannery", "banners", 1); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(marketing, "Oblečení", "clothing", 2); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(marketing, "Ankety", "polls", 3); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(marketing, "Soutěže", "sweepstakes", 4); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(marketing, "Odměny & Úspěchy", "engagement", 5); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(marketing, "Zkrácené odkazy", "shortlinks", 6); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nastaveni, err := createCategory("Nastavení")
|
||||
if err != nil { return err }
|
||||
if err := createChild(nastaveni, "Nastavení", "settings", 0); err != nil { return err }
|
||||
if err := createChild(nastaveni, "Uživatelé", "users", 1); err != nil { return err }
|
||||
if err := createChild(nastaveni, "Navigace", "navigation", 2); err != nil { return err }
|
||||
nastroje, err := createCategory("Nástroje")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(nastroje, "Prefetch & Cache", "prefetch", 0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
napoveda, err := createCategory("Nápověda")
|
||||
if err != nil { return err }
|
||||
if err := createChild(napoveda, "Dokumentace", "docs", 0); err != nil { return err }
|
||||
nastaveni, err := createCategory("Nastavení")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(nastaveni, "Nastavení", "settings", 0); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(nastaveni, "Uživatelé", "users", 1); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(nastaveni, "Navigace", "navigation", 2); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
seededAdmin = true
|
||||
}
|
||||
napoveda, err := createCategory("Nápověda")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := createChild(napoveda, "Dokumentace", "docs", 0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
seededAdmin = true
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to seed navigation items"})
|
||||
return
|
||||
}
|
||||
|
||||
// Since creation is split, compute counts again
|
||||
var total int64
|
||||
nc.DB.Model(&models.NavigationItem{}).Count(&total)
|
||||
nc.DB.Model(&models.NavigationItem{}).Where("requires_admin = ?", false).Count(&frontendCount)
|
||||
nc.DB.Model(&models.NavigationItem{}).Where("requires_admin = ?", true).Count(&adminCount)
|
||||
|
||||
message := "Navigation items already exist"
|
||||
if seededFrontend && seededAdmin {
|
||||
message = "Default frontend and admin navigation created successfully"
|
||||
} else if seededFrontend {
|
||||
message = "Default frontend navigation created successfully"
|
||||
} else if seededAdmin {
|
||||
message = "Default admin navigation created successfully"
|
||||
}
|
||||
// Also add missing admin "O klubu" item under "Obsah" when admin navigation exists but the item is missing
|
||||
if adminCount > 0 {
|
||||
var aboutCount int64
|
||||
// Check if an admin nav item with page_type 'about' exists
|
||||
if err := nc.DB.Model(&models.NavigationItem{}).
|
||||
Where("requires_admin = ? AND page_type = ?", true, "about").
|
||||
Count(&aboutCount).Error; err == nil {
|
||||
if aboutCount == 0 {
|
||||
// Ensure the 'Obsah' category exists (admin dropdown)
|
||||
var obsah models.NavigationItem
|
||||
findCatErr := nc.DB.Where("parent_id IS NULL AND requires_admin = ? AND type = ? AND label = ?", true, models.NavTypeDropdown, "Obsah").First(&obsah).Error
|
||||
if findCatErr != nil {
|
||||
if findCatErr == gorm.ErrRecordNotFound {
|
||||
// Create category at the end of admin categories
|
||||
var maxCat int
|
||||
nc.DB.Model(&models.NavigationItem{}).
|
||||
Where("parent_id IS NULL AND requires_admin = ?", true).
|
||||
Select("COALESCE(MAX(display_order), -1) + 1").Scan(&maxCat)
|
||||
obsah = models.NavigationItem{Label: "Obsah", Type: models.NavTypeDropdown, DisplayOrder: maxCat, Visible: true, RequiresAdmin: true}
|
||||
if err := nc.DB.Create(&obsah).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create admin category"})
|
||||
return
|
||||
}
|
||||
} else {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Database error"})
|
||||
return
|
||||
}
|
||||
}
|
||||
// Create the missing child under 'Obsah'
|
||||
var maxChild int
|
||||
nc.DB.Model(&models.NavigationItem{}).
|
||||
Where("parent_id = ?", obsah.ID).
|
||||
Select("COALESCE(MAX(display_order), -1) + 1").Scan(&maxChild)
|
||||
pid := obsah.ID
|
||||
aboutNav := models.NavigationItem{Label: "O klubu", Type: models.NavTypeInternal, PageType: "about", DisplayOrder: maxChild, Visible: true, RequiresAdmin: true}
|
||||
aboutNav.ParentID = &pid
|
||||
if err := nc.DB.Create(&aboutNav).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create about nav item"})
|
||||
return
|
||||
}
|
||||
addedMissing = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": message,
|
||||
"count": total,
|
||||
"frontend_count": frontendCount,
|
||||
"admin_count": adminCount,
|
||||
"seeded": seededFrontend || seededAdmin,
|
||||
"seeded_frontend": seededFrontend,
|
||||
"seeded_admin": seededAdmin,
|
||||
})
|
||||
// Since creation is split, compute counts again
|
||||
var total int64
|
||||
nc.DB.Model(&models.NavigationItem{}).Count(&total)
|
||||
nc.DB.Model(&models.NavigationItem{}).Where("requires_admin = ?", false).Count(&frontendCount)
|
||||
nc.DB.Model(&models.NavigationItem{}).Where("requires_admin = ?", true).Count(&adminCount)
|
||||
|
||||
message := "Navigation items already exist"
|
||||
if seededFrontend && seededAdmin {
|
||||
message = "Default frontend and admin navigation created successfully"
|
||||
} else if seededFrontend {
|
||||
message = "Default frontend navigation created successfully"
|
||||
} else if seededAdmin {
|
||||
message = "Default admin navigation created successfully"
|
||||
}
|
||||
if addedMissing && !(seededFrontend || seededAdmin) {
|
||||
message = "Added missing navigation items"
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": message,
|
||||
"count": total,
|
||||
"frontend_count": frontendCount,
|
||||
"admin_count": adminCount,
|
||||
"seeded": (seededFrontend || seededAdmin || addedMissing),
|
||||
"seeded_frontend": seededFrontend,
|
||||
"seeded_admin": seededAdmin,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user