diff --git a/internal/domain/messages/domain.go b/internal/domain/messages/domain.go index 446bb0e..2ae6554 100644 --- a/internal/domain/messages/domain.go +++ b/internal/domain/messages/domain.go @@ -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 } diff --git a/internal/handlers/account/messages/archive.go b/internal/handlers/account/messages/archive.go index 6f58800..4dcca0f 100644 --- a/internal/handlers/account/messages/archive.go +++ b/internal/handlers/account/messages/archive.go @@ -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") } diff --git a/internal/handlers/messages.go b/internal/handlers/messages.go index 9f23797..53b10a5 100644 --- a/internal/handlers/messages.go +++ b/internal/handlers/messages.go @@ -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) } } diff --git a/internal/http/routes/accountroutes.go b/internal/http/routes/accountroutes.go index feb457d..8f2c6bf 100644 --- a/internal/http/routes/accountroutes.go +++ b/internal/http/routes/accountroutes.go @@ -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) diff --git a/internal/models/message.go b/internal/models/message.go index 18f4442..387758f 100644 --- a/internal/models/message.go +++ b/internal/models/message.go @@ -1,6 +1,8 @@ package models -import "time" +import ( + "time" +) type Message struct { ID int diff --git a/internal/platform/services/messages/service.go b/internal/platform/services/messages/service.go index ab470ac..e784562 100644 --- a/internal/platform/services/messages/service.go +++ b/internal/platform/services/messages/service.go @@ -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 +} diff --git a/web/templates/account/messages/archived.html b/web/templates/account/messages/archived.html index 5160a7e..8cba0f5 100644 --- a/web/templates/account/messages/archived.html +++ b/web/templates/account/messages/archived.html @@ -11,7 +11,7 @@
Archived:
- {{ if .ArchivedAt.Valid }}
+ {{ with .ArchivedAt }}
{{ .Format "02 Jan 2006 15:04" }}
{{ else }}
—
@@ -28,20 +28,20 @@
{{ end }}
-
{{ else }}