Fix reading of messages.
This commit is contained in:
@@ -1,15 +1,20 @@
|
|||||||
// Package accountMessageHandler
|
// Package accountMessageHandler
|
||||||
// Path: /internal/handlers/account/messages
|
// Path: /internal/handlers/account/messages
|
||||||
// File: read.go
|
// File: read.go
|
||||||
|
// ToDo: Remove SQL
|
||||||
|
// add LIMIT/OFFSET in service
|
||||||
|
|
||||||
package accountMessageHandler
|
package accountMessageHandler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
templateHandlers "synlotto-website/internal/handlers/template"
|
templateHandlers "synlotto-website/internal/handlers/template"
|
||||||
templateHelpers "synlotto-website/internal/helpers/template"
|
templateHelpers "synlotto-website/internal/helpers/template"
|
||||||
|
|
||||||
|
errors "synlotto-website/internal/http/error"
|
||||||
"synlotto-website/internal/logging"
|
"synlotto-website/internal/logging"
|
||||||
"synlotto-website/internal/platform/bootstrap"
|
"synlotto-website/internal/platform/bootstrap"
|
||||||
|
|
||||||
@@ -25,72 +30,105 @@ func (h *AccountMessageHandlers) List(c *gin.Context) {
|
|||||||
|
|
||||||
userID := mustUserID(c)
|
userID := mustUserID(c)
|
||||||
|
|
||||||
// Pull messages (via service)
|
// 1) Parse page param (default 1)
|
||||||
msgs, err := h.Svc.ListInbox(userID)
|
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 {
|
if err != nil {
|
||||||
logging.Info("❌ list inbox error: %v", err)
|
logging.Info("❌ list inbox error: %v", err)
|
||||||
c.String(http.StatusInternalServerError, "Failed to load messages")
|
c.String(http.StatusInternalServerError, "Failed to load messages")
|
||||||
return
|
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)
|
data := templateHandlers.BuildTemplateData(app, c.Writer, c.Request)
|
||||||
ctx := templateHelpers.TemplateContext(c.Writer, c.Request, data)
|
ctx := templateHelpers.TemplateContext(c.Writer, c.Request, data)
|
||||||
|
|
||||||
if f := sm.PopString(c.Request.Context(), "flash"); f != "" {
|
if f := sm.PopString(c.Request.Context(), "flash"); f != "" {
|
||||||
ctx["Flash"] = f
|
ctx["Flash"] = f
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx["CSRFToken"] = nosurf.Token(c.Request)
|
ctx["CSRFToken"] = nosurf.Token(c.Request)
|
||||||
ctx["Title"] = "Messages"
|
ctx["Title"] = "Messages"
|
||||||
ctx["Messages"] = msgs
|
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")
|
tmpl := templateHelpers.LoadTemplateFiles("layout.html", "web/templates/account/messages/index.html")
|
||||||
|
|
||||||
c.Status(http.StatusOK)
|
var buf bytes.Buffer
|
||||||
if err := tmpl.ExecuteTemplate(c.Writer, "layout", ctx); err != nil {
|
if err := tmpl.ExecuteTemplate(&buf, "layout", ctx); err != nil {
|
||||||
logging.Info("❌ Template render error: %v", err)
|
logging.Info("❌ Template render error: %v", err)
|
||||||
c.String(http.StatusInternalServerError, "Error rendering messages page")
|
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
|
// Renders: web/templates/account/messages/read.html
|
||||||
func (h *AccountMessageHandlers) ReadGet(c *gin.Context) {
|
func (h *AccountMessageHandlers) ReadGet(c *gin.Context) {
|
||||||
app := c.MustGet("app").(*bootstrap.App)
|
app := c.MustGet("app").(*bootstrap.App)
|
||||||
sm := app.SessionManager
|
sm := app.SessionManager
|
||||||
|
|
||||||
userID := mustUserID(c)
|
userID := mustUserID(c)
|
||||||
id, err := parseIDParam(c, "id")
|
|
||||||
if err != nil {
|
idStr := c.Query("id")
|
||||||
c.AbortWithStatus(http.StatusNotFound)
|
id, err := strconv.ParseInt(idStr, 10, 64)
|
||||||
|
if err != nil || id <= 0 {
|
||||||
|
errors.RenderStatus(c, sm, http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
msg, err := h.Svc.GetByID(userID, id)
|
msg, err := h.Svc.GetByID(userID, id)
|
||||||
if err != nil || msg == nil {
|
if err != nil || msg == nil {
|
||||||
c.AbortWithStatus(http.StatusNotFound)
|
errors.RenderStatus(c, sm, http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
data := templateHandlers.BuildTemplateData(app, c.Writer, c.Request)
|
data := templateHandlers.BuildTemplateData(app, c.Writer, c.Request)
|
||||||
ctx := templateHelpers.TemplateContext(c.Writer, c.Request, data)
|
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["CSRFToken"] = nosurf.Token(c.Request)
|
||||||
ctx["Title"] = msg.Subject
|
ctx["Title"] = msg.Subject
|
||||||
ctx["Message"] = msg
|
ctx["Message"] = msg
|
||||||
|
|
||||||
tmpl := templateHelpers.LoadTemplateFiles(
|
tmpl := templateHelpers.LoadTemplateFiles("layout.html", "web/templates/account/messages/read.html")
|
||||||
"layout.html",
|
|
||||||
"web/templates/account/messages/read.html",
|
|
||||||
)
|
|
||||||
|
|
||||||
c.Status(http.StatusOK)
|
var buf bytes.Buffer
|
||||||
if err := tmpl.ExecuteTemplate(c.Writer, "layout", ctx); err != nil {
|
if err := tmpl.ExecuteTemplate(&buf, "layout", ctx); err != nil {
|
||||||
logging.Info("❌ Template render error: %v", err)
|
logging.Info("❌ Template render error: %v", err)
|
||||||
c.String(http.StatusInternalServerError, "Error rendering message")
|
c.String(http.StatusInternalServerError, "Error rendering message")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
c.Data(http.StatusOK, "text/html; charset=utf-8", buf.Bytes())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user