179 lines
4.5 KiB
Go
179 lines
4.5 KiB
Go
package components
|
|
|
|
import (
|
|
"fmt"
|
|
"maps"
|
|
|
|
"dk/internal/auth"
|
|
"dk/internal/csrf"
|
|
"dk/internal/database"
|
|
"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(`<form action="/logout" method="post" class="logout">
|
|
%s
|
|
<button class="img-button" type="submit"><img src="/assets/images/button_logout.gif" alt="Log Out" title="Log Out"></button>
|
|
</form>
|
|
<a href="/help"><img src="/assets/images/button_help.gif" alt="Help" title="Help"></a>`, csrfField)
|
|
} else {
|
|
return `<a href="/login"><img src="/assets/images/button_login.gif" alt="Log In" title="Log In"></a>
|
|
<a href="/register"><img src="/assets/images/button_register.gif" alt="Register" title="Register"></a>
|
|
<a href="/help"><img src="/assets/images/button_help.gif" alt="Help" title="Help"></a>`
|
|
}
|
|
}
|
|
|
|
// 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 ""
|
|
}
|
|
|
|
// Get the full user object from database
|
|
db := database.GetDB()
|
|
if db == nil {
|
|
return ""
|
|
}
|
|
|
|
user, err := users.Find(db, currentUser.ID)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
|
|
// Pass the user object directly to the template
|
|
leftSideData := map[string]any{
|
|
"user": user,
|
|
}
|
|
|
|
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 ""
|
|
}
|
|
|
|
// Get the full user object from database
|
|
db := database.GetDB()
|
|
if db == nil {
|
|
return ""
|
|
}
|
|
|
|
user, err := users.Find(db, currentUser.ID)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
|
|
// Pass the user object directly to the template
|
|
rightSideData := map[string]any{
|
|
"user": user,
|
|
}
|
|
|
|
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",
|
|
}
|
|
}
|