package components import ( "fmt" "maps" "dk/internal/auth" "dk/internal/csrf" "dk/internal/middleware" "dk/internal/router" "dk/internal/template" "dk/internal/users" ) // GenerateTopNav generates the top navigation HTML based on authentication status func GenerateTopNav(ctx router.Ctx) string { if middleware.IsAuthenticated(ctx) { csrfField := csrf.HiddenField(ctx, auth.Manager) return fmt.Sprintf(`
%s
Help`, csrfField) } else { return `Log In Register Help` } } // GenerateLeftSide generates the left sidebar content for authenticated users func GenerateLeftSide(ctx router.Ctx) string { if !middleware.IsAuthenticated(ctx) { return "" } // Load and render the leftside template with user data leftSideTmpl, err := template.Cache.Load("leftside.html") if err != nil { return "" // Silently fail - sidebar is optional } // Get the current user from session currentUser := middleware.GetCurrentUser(ctx) if currentUser == nil { return "" } user, err := users.Find(currentUser.ID) if err != nil { return "" } // Pass the user object directly to the template leftSideData := map[string]any{ "user": user.ToMap(), } return leftSideTmpl.RenderNamed(leftSideData) } // GenerateRightSide generates the right sidebar content for authenticated users func GenerateRightSide(ctx router.Ctx) string { if !middleware.IsAuthenticated(ctx) { return "" } // Load and render the rightside template with user data rightSideTmpl, err := template.Cache.Load("rightside.html") if err != nil { return "" // Silently fail - sidebar is optional } // Get the current user from session currentUser := middleware.GetCurrentUser(ctx) if currentUser == nil { return "" } user, err := users.Find(currentUser.ID) if err != nil { return "" } // Pass the user object directly to the template rightSideData := map[string]any{ "user": user.ToMap(), } return rightSideTmpl.RenderNamed(rightSideData) } // PageData holds common page template data type PageData struct { Title string Content string TopNav string LeftSide string RightSide string TotalTime string NumQueries string Version string Build string } // RenderPage renders a page using the layout template with common data and additional custom data func RenderPage(ctx router.Ctx, pageData PageData, additionalData map[string]any) error { if template.Cache == nil || auth.Manager == nil { return fmt.Errorf("singleton template.Cache or auth.Manager not initialized") } layoutTmpl, err := template.Cache.Load("layout.html") if err != nil { return fmt.Errorf("failed to load layout template: %w", err) } // Build the base template data with common fields data := map[string]any{ "title": pageData.Title, "content": pageData.Content, "topnav": GenerateTopNav(ctx), "leftside": pageData.LeftSide, "rightside": pageData.RightSide, "totaltime": middleware.GetRequestTime(ctx), "numqueries": pageData.NumQueries, "version": pageData.Version, "build": pageData.Build, } // Merge in additional data (overwrites common data if keys conflict) maps.Copy(data, additionalData) // Set defaults for empty fields if data["leftside"] == "" { data["leftside"] = GenerateLeftSide(ctx) } if data["rightside"] == "" { data["rightside"] = GenerateRightSide(ctx) } if data["numqueries"] == "" { data["numqueries"] = "0" } if data["version"] == "" { data["version"] = "1.0.0" } if data["build"] == "" { data["build"] = "dev" } layoutTmpl.WriteTo(ctx, data) return nil } // NewPageData creates a new PageData with sensible defaults func NewPageData(title, content string) PageData { return PageData{ Title: title, Content: content, LeftSide: "", RightSide: "", NumQueries: "0", Version: "1.0.0", Build: "dev", } }