From 5880d1ca4320df8131720722a29bf6b703ec83b3 Mon Sep 17 00:00:00 2001 From: H3ALY Date: Fri, 31 Oct 2025 12:00:08 +0000 Subject: [PATCH] Fix reading of messages. --- internal/handlers/account/messages/read.go | 82 ++++++++++++++++------ 1 file changed, 60 insertions(+), 22 deletions(-) diff --git a/internal/handlers/account/messages/read.go b/internal/handlers/account/messages/read.go index f039acb..537812f 100644 --- a/internal/handlers/account/messages/read.go +++ b/internal/handlers/account/messages/read.go @@ -1,15 +1,20 @@ // Package accountMessageHandler // Path: /internal/handlers/account/messages // File: read.go +// ToDo: Remove SQL +// add LIMIT/OFFSET in service package accountMessageHandler import ( + "bytes" "net/http" + "strconv" templateHandlers "synlotto-website/internal/handlers/template" templateHelpers "synlotto-website/internal/helpers/template" + errors "synlotto-website/internal/http/error" "synlotto-website/internal/logging" "synlotto-website/internal/platform/bootstrap" @@ -25,72 +30,105 @@ func (h *AccountMessageHandlers) List(c *gin.Context) { userID := mustUserID(c) - // Pull messages (via service) - msgs, err := h.Svc.ListInbox(userID) + // 1) Parse page param (default 1) + page := 1 + if ps := c.Query("page"); ps != "" { + if n, err := strconv.Atoi(ps); err == nil && n > 0 { + page = n + } + } + pageSize := 20 + + // 2) Count total for this user (so TotalPages is accurate) + totalPages, totalCount := templateHelpers.GetTotalPages( + app.DB, + "user_messages", + "WHERE recipientId = ? AND is_archived = FALSE", + []interface{}{userID}, + pageSize, + ) + if page > totalPages { + page = totalPages + } + + // 3) Fetch (existing service returns all inbox items) + msgsAll, err := h.Svc.ListInbox(userID) if err != nil { logging.Info("❌ list inbox error: %v", err) c.String(http.StatusInternalServerError, "Failed to load messages") return } + // 4) Slice in-memory for now (until you add LIMIT/OFFSET in service) + start := (page - 1) * pageSize + if start > len(msgsAll) { + start = len(msgsAll) + } + end := start + pageSize + if end > len(msgsAll) { + end = len(msgsAll) + } + msgs := msgsAll[start:end] + + // 5) Build context with paging + CSRF + session-driven user meta data := templateHandlers.BuildTemplateData(app, c.Writer, c.Request) ctx := templateHelpers.TemplateContext(c.Writer, c.Request, data) if f := sm.PopString(c.Request.Context(), "flash"); f != "" { ctx["Flash"] = f } - ctx["CSRFToken"] = nosurf.Token(c.Request) ctx["Title"] = "Messages" ctx["Messages"] = msgs + ctx["CurrentPage"] = page + ctx["TotalPages"] = totalPages + ctx["TotalCount"] = totalCount + ctx["PageRange"] = templateHelpers.MakePageRange(1, totalPages) - // Use the same loader + layout pattern + // 6) Render (Buffer to avoid “headers already written” on error tmpl := templateHelpers.LoadTemplateFiles("layout.html", "web/templates/account/messages/index.html") - c.Status(http.StatusOK) - if err := tmpl.ExecuteTemplate(c.Writer, "layout", ctx); err != nil { + var buf bytes.Buffer + if err := tmpl.ExecuteTemplate(&buf, "layout", ctx); err != nil { logging.Info("❌ Template render error: %v", err) c.String(http.StatusInternalServerError, "Error rendering messages page") + return } + c.Data(http.StatusOK, "text/html; charset=utf-8", buf.Bytes()) } -// GET /account/messages/:id // Renders: web/templates/account/messages/read.html func (h *AccountMessageHandlers) ReadGet(c *gin.Context) { app := c.MustGet("app").(*bootstrap.App) sm := app.SessionManager - userID := mustUserID(c) - id, err := parseIDParam(c, "id") - if err != nil { - c.AbortWithStatus(http.StatusNotFound) + + idStr := c.Query("id") + id, err := strconv.ParseInt(idStr, 10, 64) + if err != nil || id <= 0 { + errors.RenderStatus(c, sm, http.StatusNotFound) return } msg, err := h.Svc.GetByID(userID, id) if err != nil || msg == nil { - c.AbortWithStatus(http.StatusNotFound) + errors.RenderStatus(c, sm, http.StatusNotFound) return } data := templateHandlers.BuildTemplateData(app, c.Writer, c.Request) ctx := templateHelpers.TemplateContext(c.Writer, c.Request, data) - - if f := sm.PopString(c.Request.Context(), "flash"); f != "" { - ctx["Flash"] = f - } ctx["CSRFToken"] = nosurf.Token(c.Request) ctx["Title"] = msg.Subject ctx["Message"] = msg - tmpl := templateHelpers.LoadTemplateFiles( - "layout.html", - "web/templates/account/messages/read.html", - ) + tmpl := templateHelpers.LoadTemplateFiles("layout.html", "web/templates/account/messages/read.html") - c.Status(http.StatusOK) - if err := tmpl.ExecuteTemplate(c.Writer, "layout", ctx); err != nil { + var buf bytes.Buffer + if err := tmpl.ExecuteTemplate(&buf, "layout", ctx); err != nil { logging.Info("❌ Template render error: %v", err) c.String(http.StatusInternalServerError, "Error rendering message") + return } + c.Data(http.StatusOK, "text/html; charset=utf-8", buf.Bytes()) }