package errors import ( "fmt" "net/http" "os" templateHelpers "synlotto-website/internal/helpers/template" "synlotto-website/internal/models" "synlotto-website/internal/platform/sessionkeys" "github.com/alexedwards/scs/v2" "github.com/gin-gonic/gin" ) // RenderStatus renders web/templates/error/.html inside layout.html, // using ONLY session data (no DB) so 404/500 pages don't crash and still // look "logged in" when a session exists. func RenderStatus(c *gin.Context, sessions *scs.SessionManager, status int) { r := c.Request uid := int64(0) if v := sessions.Get(r.Context(), sessionkeys.UserID); v != nil { switch t := v.(type) { case int64: uid = t case int: uid = int64(t) } } // --- build minimal template data from session var data models.TemplateData if uid > 0 { uname := "" if v := sessions.Get(r.Context(), sessionkeys.Username); v != nil { if s, ok := v.(string); ok { uname = s } } isAdmin := false if v := sessions.Get(r.Context(), sessionkeys.IsAdmin); v != nil { if b, ok := v.(bool); ok { isAdmin = b } } data.User = &models.User{ Id: uid, Username: uname, IsAdmin: isAdmin, } data.IsAdmin = isAdmin } ctxMap := templateHelpers.TemplateContext(c.Writer, r, data) if f := sessions.PopString(r.Context(), sessionkeys.Flash); f != "" { ctxMap["Flash"] = f } pagePath := fmt.Sprintf("web/templates/error/%d.html", status) if _, err := os.Stat(pagePath); err != nil { c.String(status, http.StatusText(status)) return } tmpl := templateHelpers.LoadTemplateFiles( "web/templates/layout.html", pagePath, ) c.Status(status) if err := tmpl.ExecuteTemplate(c.Writer, "layout", ctxMap); err != nil { c.String(status, http.StatusText(status)) } } // Adapters so bootstrap can wire these without lambdas everywhere. func NoRoute(sessions *scs.SessionManager) gin.HandlerFunc { return func(c *gin.Context) { RenderStatus(c, sessions, http.StatusNotFound) } } func NoMethod(sessions *scs.SessionManager) gin.HandlerFunc { return func(c *gin.Context) { RenderStatus(c, sessions, http.StatusMethodNotAllowed) } } func Recovery(sessions *scs.SessionManager) gin.RecoveryFunc { return func(c *gin.Context, rec interface{}) { RenderStatus(c, sessions, http.StatusInternalServerError) } }