198 lines
5.3 KiB
Go
198 lines
5.3 KiB
Go
package handlers
|
|
|
|
import (
|
|
"database/sql"
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"admintemplate/internal/database"
|
|
"admintemplate/internal/models"
|
|
)
|
|
|
|
type MenuHandler struct {
|
|
db *database.DB
|
|
}
|
|
|
|
func NewMenuHandler(db *database.DB) *MenuHandler {
|
|
return &MenuHandler{db: db}
|
|
}
|
|
|
|
// GetMenuItems returns all menu items organized in a tree structure
|
|
func (h *MenuHandler) GetMenuItems(c *gin.Context) {
|
|
userRole := c.GetString("userRole")
|
|
|
|
// Get all active menu items
|
|
rows, err := h.db.Query(`
|
|
SELECT id, parent_id, title, icon, route, sort_order, active, role_required
|
|
FROM menu_items
|
|
WHERE active = 1
|
|
ORDER BY sort_order
|
|
`)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch menu items"})
|
|
return
|
|
}
|
|
defer rows.Close()
|
|
|
|
var allItems []models.MenuItem
|
|
for rows.Next() {
|
|
var item models.MenuItem
|
|
var parentID sql.NullInt64
|
|
err := rows.Scan(&item.ID, &parentID, &item.Title, &item.Icon, &item.Route, &item.SortOrder, &item.Active, &item.RoleReq)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
if parentID.Valid {
|
|
item.ParentID = &parentID.Int64
|
|
}
|
|
|
|
// Filter by role
|
|
if item.RoleReq != "" && item.RoleReq != userRole && userRole != "admin" {
|
|
continue
|
|
}
|
|
|
|
allItems = append(allItems, item)
|
|
}
|
|
|
|
// Build tree structure
|
|
menuTree := buildMenuTree(allItems, nil)
|
|
c.JSON(http.StatusOK, menuTree)
|
|
}
|
|
|
|
// buildMenuTree creates a nested menu structure
|
|
func buildMenuTree(items []models.MenuItem, parentID *int64) []models.MenuItem {
|
|
var result []models.MenuItem
|
|
|
|
for _, item := range items {
|
|
if (parentID == nil && item.ParentID == nil) ||
|
|
(parentID != nil && item.ParentID != nil && *parentID == *item.ParentID) {
|
|
item.Children = buildMenuTree(items, &item.ID)
|
|
result = append(result, item)
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
// GetToolbarItems returns all toolbar items
|
|
func (h *MenuHandler) GetToolbarItems(c *gin.Context) {
|
|
rows, err := h.db.Query(`
|
|
SELECT id, title, icon, action, shortcut, sort_order, active, separator
|
|
FROM toolbar_items
|
|
WHERE active = 1
|
|
ORDER BY sort_order
|
|
`)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch toolbar items"})
|
|
return
|
|
}
|
|
defer rows.Close()
|
|
|
|
var items []models.ToolbarItem
|
|
for rows.Next() {
|
|
var item models.ToolbarItem
|
|
err := rows.Scan(&item.ID, &item.Title, &item.Icon, &item.Action, &item.Shortcut, &item.SortOrder, &item.Active, &item.Separator)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
items = append(items, item)
|
|
}
|
|
|
|
c.JSON(http.StatusOK, items)
|
|
}
|
|
|
|
// GetUserSettings returns user settings
|
|
func (h *MenuHandler) GetUserSettings(c *gin.Context) {
|
|
userID := c.GetInt64("userID")
|
|
|
|
var settings models.UserSettings
|
|
err := h.db.QueryRow(`
|
|
SELECT id, user_id, sidebar_position, sidebar_collapsed, theme
|
|
FROM user_settings
|
|
WHERE user_id = ?
|
|
`, userID).Scan(&settings.ID, &settings.UserID, &settings.SidebarPosition, &settings.SidebarCollapsed, &settings.Theme)
|
|
|
|
if err == sql.ErrNoRows {
|
|
// Return default settings
|
|
settings = models.UserSettings{
|
|
UserID: userID,
|
|
SidebarPosition: "left",
|
|
SidebarCollapsed: false,
|
|
Theme: "light",
|
|
}
|
|
} else if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch settings"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, settings)
|
|
}
|
|
|
|
// UpdateUserSettings updates user settings
|
|
func (h *MenuHandler) UpdateUserSettings(c *gin.Context) {
|
|
userID := c.GetInt64("userID")
|
|
|
|
var req models.UpdateSettingsRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
// Check if settings exist
|
|
var existingID int64
|
|
err := h.db.QueryRow("SELECT id FROM user_settings WHERE user_id = ?", userID).Scan(&existingID)
|
|
|
|
if err == sql.ErrNoRows {
|
|
// Insert new settings
|
|
position := "left"
|
|
collapsed := false
|
|
theme := "light"
|
|
|
|
if req.SidebarPosition != nil {
|
|
position = *req.SidebarPosition
|
|
}
|
|
if req.SidebarCollapsed != nil {
|
|
collapsed = *req.SidebarCollapsed
|
|
}
|
|
if req.Theme != nil {
|
|
theme = *req.Theme
|
|
}
|
|
|
|
_, err = h.db.Exec(`
|
|
INSERT INTO user_settings (user_id, sidebar_position, sidebar_collapsed, theme)
|
|
VALUES (?, ?, ?, ?)
|
|
`, userID, position, collapsed, theme)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create settings"})
|
|
return
|
|
}
|
|
} else if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to check settings"})
|
|
return
|
|
} else {
|
|
// Update existing settings
|
|
if req.SidebarPosition != nil {
|
|
if _, err := h.db.Exec("UPDATE user_settings SET sidebar_position = ? WHERE user_id = ?", *req.SidebarPosition, userID); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update sidebar position"})
|
|
return
|
|
}
|
|
}
|
|
if req.SidebarCollapsed != nil {
|
|
if _, err := h.db.Exec("UPDATE user_settings SET sidebar_collapsed = ? WHERE user_id = ?", *req.SidebarCollapsed, userID); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update sidebar collapsed"})
|
|
return
|
|
}
|
|
}
|
|
if req.Theme != nil {
|
|
if _, err := h.db.Exec("UPDATE user_settings SET theme = ? WHERE user_id = ?", *req.Theme, userID); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update theme"})
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
// Return updated settings
|
|
h.GetUserSettings(c)
|
|
}
|