veza/veza-backend-api/internal/handlers/notification_handlers.go
senke cc2ebae4dc feat: Visual masterpiece - true light mode & premium UI
🎨 **True Light/Dark Mode**
- Implemented proper light mode with inverted color scheme
- Smooth theme transitions (0.3s ease)
- Light mode colors: white backgrounds, dark text, vibrant accents
- System theme detection with proper class application

🌈 **Enhanced Theme System**
- 4 color themes work in both light and dark modes
- Cyber (cyan/magenta), Ocean (blue/teal), Forest (green/lime), Sunset (orange/purple)
- Theme-specific glassmorphism effects
- Proper contrast in light mode

 **Premium Animations**
- Float, glow-pulse, slide-in, scale-in, rotate-in animations
- Smooth page transitions
- Hover effects with depth (lift, glow, scale)
- Micro-interactions on all interactive elements

🎯 **Visual Polish**
- Enhanced glassmorphism for light/dark modes
- Custom scrollbar with theme colors
- Beautiful text selection
- Focus indicators for accessibility
- Premium utility classes

🔧 **Technical Improvements**
- Updated UIStore to properly apply light/dark classes
- Added data-theme attribute for CSS targeting
- Smooth scroll behavior
- Optimized transitions

The app is now a visual masterpiece with perfect light/dark mode support!
2026-01-11 02:32:21 +01:00

159 lines
4.8 KiB
Go

package handlers
import (
"net/http"
apperrors "veza-backend-api/internal/errors"
"veza-backend-api/internal/services"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
var NotificationHandlersInstance *NotificationHandlers
// NotificationServiceInterface defines the interface for notification operations
// This allows for easier testing with mocks
type NotificationServiceInterface interface {
GetNotifications(userID uuid.UUID, unreadOnly bool) ([]services.Notification, error)
MarkAsRead(userID uuid.UUID, notificationID uuid.UUID) error
MarkAllAsRead(userID uuid.UUID) error
GetUnreadCount(userID uuid.UUID) (int, error)
DeleteNotification(userID uuid.UUID, notificationID uuid.UUID) error
DeleteAllNotifications(userID uuid.UUID) error
}
type NotificationHandlers struct {
notificationService NotificationServiceInterface
}
func NewNotificationHandlers(notificationService *services.NotificationService) {
NotificationHandlersInstance = &NotificationHandlers{
notificationService: notificationService,
}
}
// NewNotificationHandlersWithInterface creates new notification handlers with an interface (for testing)
func NewNotificationHandlersWithInterface(notificationService NotificationServiceInterface) *NotificationHandlers {
return &NotificationHandlers{
notificationService: notificationService,
}
}
// GetNotifications retrieves all notifications for the authenticated user
// GET /api/v1/notifications
// BE-API-016: Implement notifications endpoints
func (nh *NotificationHandlers) GetNotifications(c *gin.Context) {
userID, ok := GetUserIDUUID(c)
if !ok {
return // Erreur déjà envoyée par GetUserIDUUID
}
read := c.DefaultQuery("read", "")
var unreadOnly bool
if read == "false" {
unreadOnly = true
}
notifications, err := nh.notificationService.GetNotifications(userID, unreadOnly)
if err != nil {
RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "Failed to get notifications", err))
return
}
RespondSuccess(c, http.StatusOK, notifications)
}
// MarkAsRead marks a notification as read
// POST /api/v1/notifications/:id/read
// BE-API-016: Implement notifications endpoints
func (nh *NotificationHandlers) MarkAsRead(c *gin.Context) {
userID, ok := GetUserIDUUID(c)
if !ok {
return // Erreur déjà envoyée par GetUserIDUUID
}
notificationID, err := uuid.Parse(c.Param("id"))
if err != nil {
RespondWithAppError(c, apperrors.NewValidationError("invalid notification id"))
return
}
err = nh.notificationService.MarkAsRead(userID, notificationID)
if err != nil {
RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "Failed to mark notification as read", err))
return
}
RespondSuccess(c, http.StatusOK, gin.H{"message": "Notification marked as read"})
}
// MarkAllAsRead marks all notifications as read for the user
// POST /api/v1/notifications/read-all
// BE-API-016: Implement notifications endpoints
func (nh *NotificationHandlers) MarkAllAsRead(c *gin.Context) {
userID, ok := GetUserIDUUID(c)
if !ok {
return // Erreur déjà envoyée par GetUserIDUUID
}
if err := nh.notificationService.MarkAllAsRead(userID); err != nil {
RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "Failed to mark all notifications as read", err))
return
}
RespondSuccess(c, http.StatusOK, gin.H{"message": "All notifications marked as read"})
}
// GetUnreadCount returns the count of unread notifications
func (nh *NotificationHandlers) GetUnreadCount(c *gin.Context) {
userID, ok := GetUserIDUUID(c)
if !ok {
return
}
count, err := nh.notificationService.GetUnreadCount(userID)
if err != nil {
RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "Failed to get unread count", err))
return
}
RespondSuccess(c, http.StatusOK, gin.H{"count": count})
}
// DeleteNotification deletes a notification
func (nh *NotificationHandlers) DeleteNotification(c *gin.Context) {
userID, ok := GetUserIDUUID(c)
if !ok {
return
}
notificationID, err := uuid.Parse(c.Param("id"))
if err != nil {
RespondWithAppError(c, apperrors.NewValidationError("invalid notification id"))
return
}
err = nh.notificationService.DeleteNotification(userID, notificationID)
if err != nil {
RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "Failed to delete notification", err))
return
}
RespondSuccess(c, http.StatusOK, gin.H{"message": "Notification deleted"})
}
// DeleteAllNotifications deletes all notifications for the user
func (nh *NotificationHandlers) DeleteAllNotifications(c *gin.Context) {
userID, ok := GetUserIDUUID(c)
if !ok {
return
}
if err := nh.notificationService.DeleteAllNotifications(userID); err != nil {
RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "Failed to delete all notifications", err))
return
}
RespondSuccess(c, http.StatusOK, gin.H{"message": "All notifications deleted"})
}