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 @@