599514c0db
- WebSocket: Spring STOMP + SockJS, NotificationService, persistent notifications table - NotificationController: GET/PUT endpoints for notification management - Frontend: notification bell with unread badge, dropdown panel, real-time via STOMP - PWA: manifest.json, service worker (manual sw.js), offline page, install prompt - PWA icons (192+512), dark theme colors, standalone display - Full i18n (de/en) for notifications and PWA - Flyway V10 migration for notifications table - spring-boot-starter-websocket dependency added
69 lines
2.3 KiB
Java
69 lines
2.3 KiB
Java
package de.cannamanage.api.controller;
|
|
|
|
import de.cannamanage.domain.entity.Notification;
|
|
import de.cannamanage.service.NotificationService;
|
|
import lombok.RequiredArgsConstructor;
|
|
import org.springframework.http.ResponseEntity;
|
|
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
|
import org.springframework.security.core.userdetails.UserDetails;
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.UUID;
|
|
|
|
/**
|
|
* REST endpoints for notification management.
|
|
*/
|
|
@RestController
|
|
@RequestMapping("/api/v1/notifications")
|
|
@RequiredArgsConstructor
|
|
public class NotificationController {
|
|
|
|
private final NotificationService notificationService;
|
|
|
|
/**
|
|
* Get current user's notifications (last 10, unread first).
|
|
*/
|
|
@GetMapping
|
|
public ResponseEntity<Map<String, Object>> getNotifications(@AuthenticationPrincipal UserDetails user) {
|
|
UUID userId = UUID.fromString(user.getUsername());
|
|
List<Notification> notifications = notificationService.getRecentNotifications(userId);
|
|
long unreadCount = notificationService.getUnreadCount(userId);
|
|
|
|
var items = notifications.stream().map(n -> Map.of(
|
|
"id", (Object) n.getId(),
|
|
"type", n.getType().name(),
|
|
"title", n.getTitle(),
|
|
"message", n.getMessage(),
|
|
"link", n.getLink() != null ? n.getLink() : "",
|
|
"read", n.isRead(),
|
|
"createdAt", n.getCreatedAt().toString()
|
|
)).toList();
|
|
|
|
return ResponseEntity.ok(Map.of(
|
|
"notifications", items,
|
|
"unreadCount", unreadCount
|
|
));
|
|
}
|
|
|
|
/**
|
|
* Mark a single notification as read.
|
|
*/
|
|
@PutMapping("/{id}/read")
|
|
public ResponseEntity<Void> markAsRead(@PathVariable UUID id) {
|
|
notificationService.markAsRead(id);
|
|
return ResponseEntity.noContent().build();
|
|
}
|
|
|
|
/**
|
|
* Mark all notifications as read.
|
|
*/
|
|
@PutMapping("/read-all")
|
|
public ResponseEntity<Map<String, Object>> markAllAsRead(@AuthenticationPrincipal UserDetails user) {
|
|
UUID userId = UUID.fromString(user.getUsername());
|
|
int updated = notificationService.markAllAsRead(userId);
|
|
return ResponseEntity.ok(Map.of("updated", updated));
|
|
}
|
|
}
|