86 lines
3.0 KiB
Go
86 lines
3.0 KiB
Go
package handler
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
|
|
"github.com/prabhupadasays/spsays-bff/internal/middleware"
|
|
"github.com/prabhupadasays/spsays-bff/internal/service"
|
|
"github.com/prabhupadasays/spsays-bff/pkg/response"
|
|
)
|
|
|
|
// NotificationHandler serves the signed-in user's notification feed +
|
|
// unread badge count, and marks them read. All routes sit behind
|
|
// RequireAuth, so middleware.UserID is always populated.
|
|
type NotificationHandler struct{ svc *service.NotificationService }
|
|
|
|
func NewNotificationHandler(svc *service.NotificationService) *NotificationHandler {
|
|
return &NotificationHandler{svc: svc}
|
|
}
|
|
|
|
// List returns the caller's notifications, newest first.
|
|
func (h *NotificationHandler) List(w http.ResponseWriter, r *http.Request) {
|
|
uid := middleware.UserID(r.Context())
|
|
limit, offset := parseLimitOffset(r)
|
|
items, err := h.svc.List(r.Context(), uid, limit, offset)
|
|
if err != nil {
|
|
response.Error(w, http.StatusInternalServerError, "could not load notifications")
|
|
return
|
|
}
|
|
response.JSON(w, http.StatusOK, items)
|
|
}
|
|
|
|
// UnreadCount returns {"count": N} for the bell badge.
|
|
func (h *NotificationHandler) UnreadCount(w http.ResponseWriter, r *http.Request) {
|
|
uid := middleware.UserID(r.Context())
|
|
n, err := h.svc.UnreadCount(r.Context(), uid)
|
|
if err != nil {
|
|
response.Error(w, http.StatusInternalServerError, "could not load unread count")
|
|
return
|
|
}
|
|
response.JSON(w, http.StatusOK, map[string]int{"count": n})
|
|
}
|
|
|
|
// MarkAllRead marks every notification read (called when the page opens).
|
|
func (h *NotificationHandler) MarkAllRead(w http.ResponseWriter, r *http.Request) {
|
|
uid := middleware.UserID(r.Context())
|
|
if err := h.svc.MarkAllRead(r.Context(), uid); err != nil {
|
|
response.Error(w, http.StatusInternalServerError, "could not mark notifications read")
|
|
return
|
|
}
|
|
response.NoContent(w)
|
|
}
|
|
|
|
type emailPrefsResp struct {
|
|
LikeEmails bool `json:"like_emails"`
|
|
}
|
|
|
|
// GetEmailPrefs — GET /notifications/email-prefs. The caller's email-notification
|
|
// preferences (currently just aggregated like emails).
|
|
func (h *NotificationHandler) GetEmailPrefs(w http.ResponseWriter, r *http.Request) {
|
|
uid := middleware.UserID(r.Context())
|
|
enabled, err := h.svc.LikeEmailPref(r.Context(), uid)
|
|
if err != nil {
|
|
response.Error(w, http.StatusInternalServerError, "could not load email preferences")
|
|
return
|
|
}
|
|
response.JSON(w, http.StatusOK, emailPrefsResp{LikeEmails: enabled})
|
|
}
|
|
|
|
// UpdateEmailPrefs — PUT /notifications/email-prefs { like_emails }.
|
|
func (h *NotificationHandler) UpdateEmailPrefs(w http.ResponseWriter, r *http.Request) {
|
|
uid := middleware.UserID(r.Context())
|
|
var req struct {
|
|
LikeEmails bool `json:"like_emails"`
|
|
}
|
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
|
response.Error(w, http.StatusBadRequest, "invalid JSON body")
|
|
return
|
|
}
|
|
if err := h.svc.SetLikeEmailPref(r.Context(), uid, req.LikeEmails); err != nil {
|
|
response.Error(w, http.StatusInternalServerError, "could not update email preferences")
|
|
return
|
|
}
|
|
response.JSON(w, http.StatusOK, emailPrefsResp{LikeEmails: req.LikeEmails})
|
|
}
|