Skip to content

Commit 07b59b9

Browse files
committed
feat: add dismissNotification per-item control
1 parent 0041b03 commit 07b59b9

2 files changed

Lines changed: 31 additions & 8 deletions

File tree

‎components/layout/notification-bell.tsx‎

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
'use client'
22

33
import { useState, useRef, useEffect } from 'react'
4-
import { Bell } from 'lucide-react'
4+
import { Bell, X } from 'lucide-react'
55
import { formatTimeAgo } from '@/lib/stream-utils'
66
import { useWallet } from '@/hooks/use-wallet'
77
import { useNotifications, type AppNotification } from '@/hooks/use-notifications'
88

9-
function NotificationItem({ notification }: { notification: AppNotification }) {
9+
function NotificationItem({
10+
notification,
11+
onDismiss,
12+
}: {
13+
notification: AppNotification
14+
onDismiss: (id: string) => void
15+
}) {
1016
return (
1117
<div
1218
className={
@@ -16,9 +22,18 @@ function NotificationItem({ notification }: { notification: AppNotification }) {
1622
>
1723
<div className="flex items-start justify-between gap-2">
1824
<p className="text-sm font-medium">{notification.title}</p>
19-
{!notification.read && (
20-
<span className="mt-1 size-2 shrink-0 rounded-full bg-primary" />
21-
)}
25+
<div className="flex shrink-0 items-center gap-1.5 mt-0.5">
26+
{!notification.read && (
27+
<span className="size-2 rounded-full bg-primary" />
28+
)}
29+
<button
30+
onClick={() => onDismiss(notification.id)}
31+
aria-label="Dismiss notification"
32+
className="text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:rounded"
33+
>
34+
<X className="size-3.5" />
35+
</button>
36+
</div>
2237
</div>
2338
<p className="mt-0.5 text-xs text-muted-foreground">{notification.body}</p>
2439
<p className="mt-1 text-xs text-muted-foreground">{formatTimeAgo(notification.timestamp)}</p>
@@ -28,7 +43,7 @@ function NotificationItem({ notification }: { notification: AppNotification }) {
2843

2944
export function NotificationBell() {
3045
const { address } = useWallet()
31-
const { notifications, unreadCount, markAllRead, clearAll } = useNotifications(address)
46+
const { notifications, unreadCount, markAllRead, clearAll, dismissNotification } = useNotifications(address)
3247
const [open, setOpen] = useState(false)
3348
const ref = useRef<HTMLDivElement>(null)
3449
const triggerRef = useRef<HTMLButtonElement>(null)
@@ -105,7 +120,7 @@ export function NotificationBell() {
105120
</p>
106121
) : (
107122
notifications.map((n) => (
108-
<NotificationItem key={n.id} notification={n} />
123+
<NotificationItem key={n.id} notification={n} onDismiss={dismissNotification} />
109124
))
110125
)}
111126
</div>

‎hooks/use-notifications.ts‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,14 @@ export function useNotifications(walletAddress: string | null) {
252252
saveNotifications([]);
253253
}, []);
254254

255+
const dismissNotification = useCallback((id: string) => {
256+
setNotifications((prev) => {
257+
const updated = prev.filter((n) => n.id !== id);
258+
saveNotifications(updated);
259+
return updated;
260+
});
261+
}, []);
262+
255263
useEffect(() => {
256264
const rpcUrl = config.rpcUrl;
257265
const contractId = config.streamContractId;
@@ -388,5 +396,5 @@ export function useNotifications(walletAddress: string | null) {
388396
network,
389397
]);
390398

391-
return { notifications, unreadCount, markAllRead, clearAll };
399+
return { notifications, unreadCount, markAllRead, clearAll, dismissNotification };
392400
}

0 commit comments

Comments
 (0)