Fix archiving and unarchiving functionality.
This commit is contained in:
@@ -21,6 +21,6 @@ type MessageService interface {
|
||||
Archive(userID, id int64) error
|
||||
//Restore()
|
||||
//ToDo: implement
|
||||
//Unarchive(userID, id int64) error
|
||||
Unarchive(userID, id int64) error
|
||||
//MarkRead(userID, id int64) error
|
||||
}
|
||||
|
||||
@@ -6,12 +6,14 @@ package accountMessageHandler
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
templateHandlers "synlotto-website/internal/handlers/template"
|
||||
templateHelpers "synlotto-website/internal/helpers/template"
|
||||
errors "synlotto-website/internal/http/error"
|
||||
httpErrors "synlotto-website/internal/http/error"
|
||||
|
||||
"synlotto-website/internal/logging"
|
||||
"synlotto-website/internal/platform/bootstrap"
|
||||
@@ -104,7 +106,7 @@ func (h *AccountMessageHandlers) ArchivePost(c *gin.Context) {
|
||||
idStr := c.PostForm("id")
|
||||
id, err := strconv.ParseInt(idStr, 10, 64)
|
||||
if err != nil || id <= 0 {
|
||||
errors.RenderStatus(c, sm, http.StatusBadRequest)
|
||||
httpErrors.RenderStatus(c, sm, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -119,24 +121,32 @@ func (h *AccountMessageHandlers) ArchivePost(c *gin.Context) {
|
||||
c.Redirect(http.StatusSeeOther, "/account/messages")
|
||||
}
|
||||
|
||||
// POST /account/messages/restore
|
||||
func (h *AccountMessageHandlers) RestorePost(c *gin.Context) {
|
||||
// POST /account/messages/archived
|
||||
func (h *AccountMessageHandlers) RestoreArchived(c *gin.Context) {
|
||||
app := c.MustGet("app").(*bootstrap.App)
|
||||
sm := app.SessionManager
|
||||
//userID := mustUserID(c)
|
||||
userID := mustUserID(c)
|
||||
|
||||
idStr := c.PostForm("id")
|
||||
id, err := strconv.ParseInt(idStr, 10, 64)
|
||||
if err != nil || id <= 0 {
|
||||
errors.RenderStatus(c, sm, http.StatusBadRequest)
|
||||
sm.Put(c.Request.Context(), "flash", "Invalid message id.")
|
||||
c.Redirect(http.StatusSeeOther, "/account/messages/archive")
|
||||
return
|
||||
}
|
||||
//
|
||||
// if err := h.Svc.Unarchive(userID, id); err != nil {
|
||||
// logging.Info("❌ Restore error: %v", err)
|
||||
// sm.Put(c.Request.Context(), "flash", "Could not restore message.")
|
||||
// } else {
|
||||
// sm.Put(c.Request.Context(), "flash", "Message restored.")
|
||||
// }
|
||||
c.Redirect(http.StatusSeeOther, "/account/messages/archived")
|
||||
|
||||
if err := h.Svc.Unarchive(userID, id); err != nil {
|
||||
logging.Info("❌ restore/unarchive error: %v", err)
|
||||
// If no rows affected, show friendly flash; otherwise generic message.
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
sm.Put(c.Request.Context(), "flash", "Message not found or not permitted.")
|
||||
} else {
|
||||
sm.Put(c.Request.Context(), "flash", "Could not restore message.")
|
||||
}
|
||||
c.Redirect(http.StatusSeeOther, "/account/messages/archive")
|
||||
return
|
||||
}
|
||||
|
||||
sm.Put(c.Request.Context(), "flash", "Message restored.")
|
||||
c.Redirect(http.StatusSeeOther, "/account/messages/archive")
|
||||
}
|
||||
|
||||
@@ -177,6 +177,6 @@ func RestoreMessageHandler(app *bootstrap.App) http.HandlerFunc {
|
||||
templateHelpers.SetFlash(r, "Message restored.")
|
||||
}
|
||||
|
||||
http.Redirect(w, r, "/account/messages/archived", http.StatusSeeOther)
|
||||
http.Redirect(w, r, "/account/messages/archive", http.StatusSeeOther)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ func RegisterAccountRoutes(app *bootstrap.App) {
|
||||
messages.POST("/send", msgH.SendPost)
|
||||
messages.GET("/archive", msgH.ArchivedList) // view archived messages
|
||||
messages.POST("/archive", msgH.ArchivePost) // archive a message
|
||||
messages.POST("/restore", msgH.RestorePost)
|
||||
messages.POST("/restore", msgH.RestoreArchived)
|
||||
}
|
||||
|
||||
// Notifications (auth-required)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Message struct {
|
||||
ID int
|
||||
|
||||
@@ -76,7 +76,8 @@ func (s *Service) ListArchived(userID int64) ([]domain.Message, error) {
|
||||
defer cancel()
|
||||
|
||||
q := `
|
||||
SELECT id, senderId, recipientId, subject, body, is_read, is_archived, created_at
|
||||
SELECT id, senderId, recipientId, subject, body,
|
||||
is_read, is_archived, created_at, archived_at
|
||||
FROM user_messages
|
||||
WHERE recipientId = ? AND is_archived = TRUE
|
||||
ORDER BY created_at DESC`
|
||||
@@ -91,11 +92,32 @@ func (s *Service) ListArchived(userID int64) ([]domain.Message, error) {
|
||||
var out []domain.Message
|
||||
for rows.Next() {
|
||||
var m domain.Message
|
||||
if err := rows.Scan(&m.ID, &m.SenderId, &m.RecipientId, &m.Subject, &m.Body, &m.IsRead, &m.IsArchived, &m.CreatedAt); err != nil {
|
||||
var archived sql.NullTime
|
||||
|
||||
if err := rows.Scan(
|
||||
&m.ID,
|
||||
&m.SenderId,
|
||||
&m.RecipientId,
|
||||
&m.Subject,
|
||||
&m.Body,
|
||||
&m.IsRead,
|
||||
&m.IsArchived,
|
||||
&m.CreatedAt,
|
||||
&archived,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if archived.Valid {
|
||||
t := archived.Time
|
||||
m.ArchivedAt = &t
|
||||
} else {
|
||||
m.ArchivedAt = nil
|
||||
}
|
||||
|
||||
out = append(out, m)
|
||||
}
|
||||
|
||||
return out, rows.Err()
|
||||
}
|
||||
|
||||
@@ -233,3 +255,25 @@ func intToStr(n int) string {
|
||||
}
|
||||
return string(b[i:])
|
||||
}
|
||||
|
||||
func (s *Service) Unarchive(userID, id int64) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), s.Timeout)
|
||||
defer cancel()
|
||||
|
||||
q := `
|
||||
UPDATE user_messages
|
||||
SET is_archived = 0, archived_at = NULL
|
||||
WHERE id = ? AND recipientId = ?
|
||||
`
|
||||
q = s.bind(q)
|
||||
|
||||
res, err := s.DB.ExecContext(ctx, q, id, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
n, _ := res.RowsAffected()
|
||||
if n == 0 {
|
||||
return sql.ErrNoRows
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user