This commit is contained in:
Tomas Dvorak
2026-01-26 08:13:18 +01:00
parent aa036b6550
commit dfc079288f
505 changed files with 95755 additions and 5712 deletions
+132 -18
View File
@@ -1,7 +1,10 @@
package controllers
import (
"fotbal-club/internal/config"
"fotbal-club/internal/middleware"
"fotbal-club/internal/models"
"log"
"net/http"
"strconv"
@@ -13,6 +16,61 @@ type NavigationController struct {
DB *gorm.DB
}
// translateNavigationLabels translates navigation item labels using the i18n system
func (nc *NavigationController) translateNavigationLabels(items []models.NavigationItem, languageCode string) {
// Create translation helper
th := middleware.NewTranslationHelper()
// Create a mock gin context for translation (we only need the language)
c := &gin.Context{}
c.Set("language", languageCode)
// Translation map for common navigation keys
translationMap := map[string]string{
"Domů": "nav.home",
"O klubu": "nav.about",
"Kalendář": "nav.calendar",
"Zápasy": "nav.matches",
"Aktivity": "nav.activities",
"Hráči": "nav.players",
"Tabulky": "nav.tables",
"Články": "nav.articles",
"Blog": "nav.articles",
"Videa": "nav.videos",
"Galerie": "homepage.gallery",
"Sponzoři": "nav.sponsors",
"Kontakt": "nav.contact",
"Hledat": "action.search",
"Obchod": "nav.shop",
"Více": "action.more",
}
// Translate function
translateLabel := func(label string) string {
// Check if we have a mapping for this label
if key, exists := translationMap[label]; exists {
translated := th.T(c, key)
// Debug: log what we're translating
log.Printf("Translating label '%s' with key '%s' -> '%s'", label, key, translated)
// If translation is the same as key (not found), return original label
if translated == key {
return label
}
return translated
}
log.Printf("No translation key found for label '%s'", label)
return label
}
// Translate all items and their children
for i := range items {
items[i].Label = translateLabel(items[i].Label)
for j := range items[i].Children {
items[i].Children[j].Label = translateLabel(items[i].Children[j].Label)
}
}
}
func NewNavigationController(db *gorm.DB) *NavigationController {
return &NavigationController{DB: db}
}
@@ -50,6 +108,10 @@ func (nc *NavigationController) GetNavigationItems(c *gin.Context) {
}
}
// Translate navigation labels based on current language
languageCode := middleware.GetLanguage(c)
nc.translateNavigationLabels(items, languageCode)
c.JSON(http.StatusOK, items)
}
@@ -396,29 +458,20 @@ func (nc *NavigationController) GetEditorAllowedAdminNav(c *gin.Context) {
return
}
// Filter according to allow_editor rules
// Filter according to allow_editor rules only (no hardcoded page_type allow-list)
out := make([]models.NavigationItem, 0, len(top))
// Only allow a curated set of admin pages that have editor-capable APIs
allowed := map[string]bool{
"articles": true,
"activities": true,
"shortlinks": true,
}
for i := range top {
it := top[i]
include := false
if it.Type == models.NavTypeDropdown {
// Filter children by page_type allow-list (children already have allow_editor=true from preload)
if len(it.Children) > 0 {
children := make([]models.NavigationItem, 0, len(it.Children))
for _, ch := range it.Children {
if allowed[ch.PageType] {
// ensure URL is set
if ch.URL == "" {
ch.URL = ch.GetURL()
}
children = append(children, ch)
// Children are already filtered to allow_editor = true and visible = true in Preload
if ch.URL == "" {
ch.URL = ch.GetURL()
}
children = append(children, ch)
}
it.Children = children
if len(it.Children) > 0 {
@@ -426,13 +479,12 @@ func (nc *NavigationController) GetEditorAllowedAdminNav(c *gin.Context) {
}
}
} else {
// direct admin page: include only when marked allow_editor
if it.AllowEditor && allowed[it.PageType] {
// Direct admin page: include only when explicitly marked for editors and visible
if it.AllowEditor && it.Visible {
include = true
}
}
if include {
// Ensure URLs are computed
if it.URL == "" {
it.URL = it.GetURL()
}
@@ -666,7 +718,29 @@ func (nc *NavigationController) SeedDefaultNavigation(c *gin.Context) {
pid := parent.ID
allowEditor := false
switch pageType {
case "articles", "activities", "shortlinks":
case "dashboard",
"teams",
"matches",
"players",
"competition_aliases",
"scoreboard",
"scoreboard_remote",
"articles",
"activities",
"about",
"videos",
"gallery",
"shortlinks",
"i18n",
"financial_dashboard",
"expenses",
"invoices",
"invoice_settings",
"customers",
"eshop_products",
"tickets",
"manual_facr",
"qr_codes":
allowEditor = true
}
child := &models.NavigationItem{Label: label, Type: models.NavTypeInternal, PageType: pageType, DisplayOrder: order, Visible: true, RequiresAdmin: true, AllowEditor: allowEditor}
@@ -788,6 +862,46 @@ func (nc *NavigationController) SeedDefaultNavigation(c *gin.Context) {
if err := createChild(nastroje, "Prefetch & Cache", "prefetch", 0); err != nil {
return err
}
if err := createChild(nastroje, "Manuální FACR", "manual_facr", 1); err != nil {
return err
}
if err := createChild(nastroje, "QR kódy", "qr_codes", 3); err != nil {
return err
}
finance, err := createCategory("Finance")
if err != nil {
return err
}
if err := createChild(finance, "Finanční přehled", "financial_dashboard", 0); err != nil {
return err
}
if err := createChild(finance, "Výdaje", "expenses", 1); err != nil {
return err
}
if err := createChild(finance, "Faktury", "invoices", 2); err != nil {
return err
}
if err := createChild(finance, "Nastavení faktur", "invoice_settings", 3); err != nil {
return err
}
if err := createChild(finance, "Kontakty", "customers", 4); err != nil {
return err
}
// E-shop category - only add if e-shop is enabled
if config.AppConfig.EshopEnabled {
eshop, err := createCategory("E-shop")
if err != nil {
return err
}
if err := createChild(eshop, "Produkty", "eshop_products", 0); err != nil {
return err
}
if err := createChild(eshop, "Vstupenky", "tickets", 1); err != nil {
return err
}
}
nastaveni, err := createCategory("Nastavení")
if err != nil {