Feature: Full notification read view with conditional mark-as-read logic

- Added dedicated route and view for reading individual notifications (/account/notifications/read)
- Ensured notification is only marked as read if it hasn't already been
- Updated Notification model to use Subject and Body fields
- Fixed field references in templates (Title → Subject, Message → Body)
- Updated topbar dropdown to use correct field names and display logic
- Gracefully handle "notification not found" cases in template output
- Ensured consistent template parsing with layout and topbar inclusion
- Improved error logging for better diagnosis
This commit is contained in:
2025-04-01 23:08:58 +01:00
parent 06e647d00f
commit e5bf12ad77
10 changed files with 110 additions and 69 deletions

View File

@@ -2,6 +2,7 @@ package handlers
import (
"database/sql"
"log"
"net/http"
"strconv"
"text/template"
@@ -20,11 +21,12 @@ func NotificationsHandler(db *sql.DB) http.HandlerFunc {
ParseFiles(
"templates/layout.html",
"templates/topbar.html",
"templates/account/notifications/index.html",
"templates/account/notifications.html",
))
err := tmpl.ExecuteTemplate(w, "layout", context)
if err != nil {
log.Println("❌ Template render error:", err)
http.Error(w, "Error rendering notifications page", http.StatusInternalServerError)
}
}
@@ -46,12 +48,33 @@ func MarkNotificationReadHandler(db *sql.DB) http.HandlerFunc {
return
}
err = storage.MarkNotificationAsRead(db, userID, notificationID)
notification, err := storage.GetNotificationByID(db, userID, notificationID)
if err != nil {
http.Error(w, "Failed to update", http.StatusInternalServerError)
return
log.Printf("❌ Notification not found or belongs to another user: %v", err)
notification = nil
} else if !notification.IsRead {
err = storage.MarkNotificationAsRead(db, userID, notificationID)
if err != nil {
log.Printf("⚠️ Failed to mark as read: %v", err)
}
}
http.Redirect(w, r, "/account/notifications", http.StatusSeeOther)
data := BuildTemplateData(db, w, r)
context := helpers.TemplateContext(w, r, data)
context["Notification"] = notification
tmpl := template.Must(template.New("read.html").
Funcs(helpers.TemplateFuncs()).
ParseFiles(
"templates/layout.html",
"templates/topbar.html",
"templates/account/notifications/read.html",
))
err = tmpl.ExecuteTemplate(w, "layout", context)
if err != nil {
log.Printf("❌ Template render error: %v", err)
http.Error(w, "Template render error", http.StatusInternalServerError)
}
}
}