diff --git a/src/components/frontend/notifications/NotificationsBell.tsx b/src/components/frontend/notifications/NotificationsBell.tsx
index 353bb62..f3330f4 100644
--- a/src/components/frontend/notifications/NotificationsBell.tsx
+++ b/src/components/frontend/notifications/NotificationsBell.tsx
@@ -49,6 +49,8 @@ export function NotificationsBell() {
const [open, setOpen] = useState(false);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);
+ const [actionError, setActionError] = useState(null);
+ const [marking, setMarking] = useState(false);
const intervalRef = useRef | null>(null);
const unreadCount = notifications.filter((n) => !n.read).length;
@@ -78,9 +80,24 @@ export function NotificationsBell() {
}, [fetchNotifications]);
async function handleItemClick(item: NotificationItem) {
+ if (marking) return;
if (!item.read) {
- await markNotificationsRead([item.id]);
- setNotifications((prev) => prev.map((n) => (n.id === item.id ? { ...n, read: true } : n)));
+ setMarking(true);
+ setActionError(null);
+ try {
+ const result = await markNotificationsRead([item.id]);
+ if (result.success) {
+ setNotifications((prev) =>
+ prev.map((n) => (n.id === item.id ? { ...n, read: true } : n)),
+ );
+ } else {
+ setActionError(result.error ?? "Failed to update notifications.");
+ }
+ } catch (err) {
+ setActionError(err instanceof Error ? err.message : "Failed to update notifications.");
+ } finally {
+ setMarking(false);
+ }
}
if (item.link) {
router.push(item.link);
@@ -89,9 +106,21 @@ export function NotificationsBell() {
}
async function handleMarkAll() {
- if (unreadCount === 0) return;
- await markAllNotificationsRead();
- setNotifications((prev) => prev.map((n) => (n.read ? n : { ...n, read: true })));
+ if (unreadCount === 0 || marking) return;
+ setMarking(true);
+ setActionError(null);
+ try {
+ const result = await markAllNotificationsRead();
+ if (result.success) {
+ setNotifications((prev) => prev.map((n) => (n.read ? n : { ...n, read: true })));
+ } else {
+ setActionError(result.error ?? "Failed to update notifications.");
+ }
+ } catch (err) {
+ setActionError(err instanceof Error ? err.message : "Failed to update notifications.");
+ } finally {
+ setMarking(false);
+ }
}
return (
@@ -104,6 +133,11 @@ export function NotificationsBell() {
{unreadCount > 9 ? "9+" : unreadCount}
)}
+
+ {unreadCount > 0
+ ? `${unreadCount} unread notification${unreadCount === 1 ? "" : "s"}`
+ : "No unread notifications"}
+
@@ -112,9 +146,11 @@ export function NotificationsBell() {
{unreadCount > 0 && (
)}
@@ -131,34 +167,44 @@ export function NotificationsBell() {
No notifications yet.
) : (
- notifications.map((item) => (
- void handleItemClick(item)}
- >
-
-
- {!item.read && (
-
- )}
- {item.title}
+ <>
+ {actionError && (
+
+ {actionError}
+
+ )}
+ {notifications.map((item) => (
+ void handleItemClick(item)}
+ >
+
+
+ {!item.read && (
+
+ )}
+ {item.title}
+
+
+ {timeAgo(item.createdAt)}
+
-
- {timeAgo(item.createdAt)}
+ {item.message && (
+
+ {item.message}
+
+ )}
+
+ {notificationLabel(item.type)}
-
- {item.message && (
- {item.message}
- )}
-
- {notificationLabel(item.type)}
-
-
- ))
+
+ ))}
+ >
)}
diff --git a/src/components/frontend/notifications/NotificationsInbox.tsx b/src/components/frontend/notifications/NotificationsInbox.tsx
index 39a0aa4..23c21ff 100644
--- a/src/components/frontend/notifications/NotificationsInbox.tsx
+++ b/src/components/frontend/notifications/NotificationsInbox.tsx
@@ -185,7 +185,9 @@ export function NotificationsInbox({
{timeAgo(item.createdAt)}
- {item.title}
+
+ {item.title}
+
{item.message && {item.message}}
{item.link && (