package ui import ( "fmt" "log" "os" "path/filepath" "regexp" "strings" "git.ourworld.tf/herocode/heroagent/pkg/servers/ui/routes" // Import the routes package "github.com/gofiber/fiber/v2" jetadapter "github.com/gofiber/template/jet/v2" // Aliased for clarity ) // AppConfig holds the configuration for the UI application. type AppConfig struct { // Any specific configurations can be added here later } // NewApp creates and configures a new Fiber application for the UI. func NewApp(config AppConfig) *fiber.App { // Initialize Jet template engine // Using OSFileSystemLoader to load templates from the filesystem. // The path is relative to where the application is run. // Get current working directory and construct absolute path to views cwd, err := os.Getwd() if err != nil { panic("Failed to get current working directory: " + err.Error()) } viewsPath := filepath.Join(cwd, "pkg", "servers", "ui", "views") // Validate that the views directory and key template files exist if _, err := os.Stat(viewsPath); os.IsNotExist(err) { panic("Views directory does not exist: " + viewsPath) } // Check for key template files baseLayoutPath := filepath.Join(viewsPath, "layouts", "base.jet") dashboardPath := filepath.Join(viewsPath, "pages", "dashboard.jet") navbarPath := filepath.Join(viewsPath, "components", "navbar.jet") sidebarPath := filepath.Join(viewsPath, "components", "sidebar.jet") requiredFiles := []string{baseLayoutPath, dashboardPath, navbarPath, sidebarPath} for _, filePath := range requiredFiles { if _, err := os.Stat(filePath); os.IsNotExist(err) { panic("Required template file does not exist: " + filePath) } } // Log the views path for debugging println("Views directory found at:", viewsPath) println("All required template files exist") // Create Fiber Jet adapter engine := jetadapter.New(viewsPath, ".jet") // Enable template reloading for development engine.Reload(true) // No custom functions for now // Create a new Fiber app with the configured Jet engine and enhanced error handling app := fiber.New(fiber.Config{ Views: engine, ErrorHandler: func(c *fiber.Ctx, err error) error { // Log the detailed error log.Printf("ERROR: %v", err) // Check if it's a template rendering error if err.Error() != "" && (c.Route().Path != "" && c.Method() == "GET") { // Extract template name and line number from error message errorMsg := err.Error() templateInfo := "Unknown template" lineInfo := "Unknown line" variableInfo := "Unknown variable" // Try to extract template name and line number if strings.Contains(errorMsg, "Jet Runtime Error") { // Extract template and line number templateLineRegex := regexp.MustCompile(`"([^"]+)":(\d+)`) templateMatches := templateLineRegex.FindStringSubmatch(errorMsg) if len(templateMatches) >= 3 { templateInfo = templateMatches[1] lineInfo = templateMatches[2] } // Extract variable name varRegex := regexp.MustCompile(`there is no field or method '([^']+)'`) varMatches := varRegex.FindStringSubmatch(errorMsg) if len(varMatches) >= 2 { variableInfo = varMatches[1] } // Log more detailed information log.Printf("Template Error Details - Template: %s, Line: %s, Variable: %s", templateInfo, lineInfo, variableInfo) } // Create a more detailed error page errorHTML := fmt.Sprintf(` Template Error

Template Error

Error Details:

Template: %s

Line: %s

Missing Variable: %s

%s

Debugging Tips:

1. Check if the variable %s is passed to the template

2. Visit /debug to see available template variables

3. Check for typos in variable names

4. Ensure the variable is of the expected type

5. Check the controller that renders this template to ensure all required data is provided

`, templateInfo, lineInfo, variableInfo, errorMsg, variableInfo) return c.Status(fiber.StatusInternalServerError).Type("html").SendString(errorHTML) } // For other errors, use the default error handler return fiber.DefaultErrorHandler(c, err) }, }) // Setup static file serving // Files in ./pkg/servers/ui/static will be accessible via /static URL path app.Static("/static", "./pkg/servers/ui/static") // Setup routes routes.SetupRoutes(app) return app }