From db5352bc9c632ad2210ac340b4a6b63eeee41ac7 Mon Sep 17 00:00:00 2001
From: H3ALY
Date: Wed, 2 Apr 2025 22:18:02 +0100
Subject: [PATCH] Add restore functionality for archived messages
- Added `RestoreMessageHandler` and route at `/account/messages/restore`
- Updated `users_messages` table to support `archived_at` reset
- Added restore button to archived messages template
- Ensures archived messages can be moved back into inbox
---
handlers/messages.go | 48 +++++++++++++++++-
helpers/pagination.go | 8 +++
helpers/template.go | 10 ++++
main.go | 1 +
storage/messages.go | 49 +++++++++++++++++++
.../messages/{achived.html => archived.html} | 5 ++
templates/account/messages/index.html | 47 +++++++++---------
templates/topbar.html | 3 +-
8 files changed, 146 insertions(+), 25 deletions(-)
rename templates/account/messages/{achived.html => archived.html} (81%)
diff --git a/handlers/messages.go b/handlers/messages.go
index 5e5ecd2..47a167f 100644
--- a/handlers/messages.go
+++ b/handlers/messages.go
@@ -11,13 +11,37 @@ import (
func MessagesInboxHandler(db *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
+ userID, ok := helpers.GetCurrentUserID(r)
+ if !ok {
+ helpers.RenderError(w, r, 403)
+ return
+ }
+
+ page := helpers.Atoi(r.URL.Query().Get("page"))
+ if page < 1 {
+ page = 1
+ }
+ perPage := 10
+
+ totalCount := storage.GetInboxMessageCount(db, userID)
+ totalPages := (totalCount + perPage - 1) / perPage
+ if totalPages == 0 {
+ totalPages = 1
+ }
+
+ messages := storage.GetInboxMessages(db, userID, page, perPage)
+
data := BuildTemplateData(db, w, r)
context := helpers.TemplateContext(w, r, data)
+ context["Messages"] = messages
+ context["CurrentPage"] = page
+ context["TotalPages"] = totalPages
+ context["PageRange"] = helpers.PageRange(page, totalPages)
+
tmpl := helpers.LoadTemplateFiles("messages.html", "templates/account/messages/index.html")
- err := tmpl.ExecuteTemplate(w, "layout", context)
- if err != nil {
+ if err := tmpl.ExecuteTemplate(w, "layout", context); err != nil {
helpers.RenderError(w, r, 500)
}
}
@@ -136,3 +160,23 @@ func SendMessageHandler(db *sql.DB) http.HandlerFunc {
}
}
}
+
+func RestoreMessageHandler(db *sql.DB) http.HandlerFunc {
+ return func(w http.ResponseWriter, r *http.Request) {
+ id := helpers.Atoi(r.URL.Query().Get("id"))
+ userID, ok := helpers.GetCurrentUserID(r)
+ if !ok {
+ helpers.RenderError(w, r, 403)
+ return
+ }
+
+ err := storage.RestoreMessage(db, userID, id)
+ if err != nil {
+ helpers.SetFlash(w, r, "Failed to restore message.")
+ } else {
+ helpers.SetFlash(w, r, "Message restored.")
+ }
+
+ http.Redirect(w, r, "/account/messages/archived", http.StatusSeeOther)
+ }
+}
diff --git a/helpers/pagination.go b/helpers/pagination.go
index dbdd7d6..6cf9919 100644
--- a/helpers/pagination.go
+++ b/helpers/pagination.go
@@ -16,3 +16,11 @@ func GetTotalPages(db *sql.DB, tableName, whereClause string, args []interface{}
}
return totalPages, totalCount
}
+
+func MakePageRange(current, total int) []int {
+ var pages []int
+ for i := 1; i <= total; i++ {
+ pages = append(pages, i)
+ }
+ return pages
+}
diff --git a/helpers/template.go b/helpers/template.go
index ffff078..d7d165d 100644
--- a/helpers/template.go
+++ b/helpers/template.go
@@ -44,6 +44,7 @@ func TemplateFuncs() template.FuncMap {
},
"mul": func(a, b int) int { return a * b },
"add": func(a, b int) int { return a + b },
+ "sub": func(a, b int) int { return a - b },
"min": func(a, b int) int {
if a < b {
return a
@@ -66,6 +67,7 @@ func TemplateFuncs() template.FuncMap {
}
return s[:max] + "..."
},
+ "PageRange": PageRange,
}
}
@@ -115,3 +117,11 @@ func rangeClass(n int) string {
return "50-plus"
}
}
+
+func PageRange(current, total int) []int {
+ var pages []int
+ for i := 1; i <= total; i++ {
+ pages = append(pages, i)
+ }
+ return pages
+}
diff --git a/main.go b/main.go
index 39c35ea..c5edc5e 100644
--- a/main.go
+++ b/main.go
@@ -72,6 +72,7 @@ func setupAccountRoutes(mux *http.ServeMux, db *sql.DB) {
mux.HandleFunc("/account/messages/read", middleware.Auth(true)(handlers.ReadMessageHandler(db)))
mux.HandleFunc("/account/messages/archive", middleware.Auth(true)(handlers.ArchiveMessageHandler(db)))
mux.HandleFunc("/account/messages/archived", middleware.Auth(true)(handlers.ArchivedMessagesHandler(db)))
+ mux.HandleFunc("/account/messages/restore", middleware.Auth(true)(handlers.RestoreMessageHandler(db)))
mux.HandleFunc("/account/messages/send", middleware.Auth(true)(handlers.SendMessageHandler(db)))
mux.HandleFunc("/account/notifications", middleware.Auth(true)(handlers.NotificationsHandler(db)))
mux.HandleFunc("/account/notifications/read", middleware.Auth(true)(handlers.MarkNotificationReadHandler(db)))
diff --git a/storage/messages.go b/storage/messages.go
index 4bebf36..f65cbde 100644
--- a/storage/messages.go
+++ b/storage/messages.go
@@ -127,3 +127,52 @@ func GetArchivedMessages(db *sql.DB, userID int, page, perPage int) []models.Mes
}
return messages
}
+
+func GetInboxMessages(db *sql.DB, userID int, page, perPage int) []models.Message {
+ offset := (page - 1) * perPage
+ rows, err := db.Query(`
+ SELECT id, senderId, recipientId, subject, message, is_read, created_at
+ FROM users_messages
+ WHERE recipientId = ? AND is_archived = FALSE
+ ORDER BY created_at DESC
+ LIMIT ? OFFSET ?
+ `, userID, perPage, offset)
+ if err != nil {
+ return nil
+ }
+ defer rows.Close()
+
+ var messages []models.Message
+ for rows.Next() {
+ var m models.Message
+ err := rows.Scan(
+ &m.ID, &m.SenderId, &m.RecipientId,
+ &m.Subject, &m.Message, &m.IsRead, &m.CreatedAt,
+ )
+ if err == nil {
+ messages = append(messages, m)
+ }
+ }
+ return messages
+}
+
+func GetInboxMessageCount(db *sql.DB, userID int) int {
+ var count int
+ err := db.QueryRow(`
+ SELECT COUNT(*) FROM users_messages
+ WHERE recipientId = ? AND is_archived = FALSE
+ `, userID).Scan(&count)
+ if err != nil {
+ return 0
+ }
+ return count
+}
+
+func RestoreMessage(db *sql.DB, userID, messageID int) error {
+ _, err := db.Exec(`
+ UPDATE users_messages
+ SET is_archived = FALSE, archived_at = NULL
+ WHERE id = ? AND recipientId = ?
+ `, messageID, userID)
+ return err
+}
diff --git a/templates/account/messages/achived.html b/templates/account/messages/archived.html
similarity index 81%
rename from templates/account/messages/achived.html
rename to templates/account/messages/archived.html
index 16b8456..ece8187 100644
--- a/templates/account/messages/achived.html
+++ b/templates/account/messages/archived.html
@@ -13,6 +13,11 @@
+
{{ end }}
diff --git a/templates/account/messages/index.html b/templates/account/messages/index.html
index ed4b662..b690fa5 100644
--- a/templates/account/messages/index.html
+++ b/templates/account/messages/index.html
@@ -10,7 +10,7 @@
{{ .CreatedAt.Format "02 Jan 2006 15:04" }}
-