'use client'; import Link from 'next/link'; import { useEffect } from 'react'; import { useSWRConfig } from 'swr'; import useSWRInfinite from 'swr/infinite'; import { notificationPath, notificationText, timeAgo, type NotificationListDTO } from '@musicshare/shared'; import { Avatar } from '@/components/Avatar'; import { client, useMe } from '@/lib/api'; const ADMIN_ACTOR_USERNAME = 'seriouscritter'; /** Reactions, comments, new followers and songs sent to you, newest first. Opening it marks them read. */ export default function NotificationsPage() { const { me, loggedOut } = useMe(); const { mutate } = useSWRConfig(); // Fetch all notifications for the user const { data, size, setSize, isLoading } = useSWRInfinite( (i, prev: NotificationListDTO | null) => (!me || (i > 0 && !prev?.nextCursor) ? null : ['notifications', prev?.nextCursor ?? null]), ([, cursor]: [string, string | null]) => client.notifications(cursor), { revalidateOnFocus: false }, ); const allItems = data?.flatMap((p) => p.notifications) ?? []; const unread = data?.[0]?.unread ?? 0; // Filter messages specifically from seriouscritter const seriousCritterMessages = allItems.filter(n => n.actor?.username === ADMIN_ACTOR_USERNAME); // Seen once you've looked: clear the bell (rows stay highlighted until you come back). useEffect(() => { if (unread) client.markNotificationsRead().then(() => mutate('/notifications'), () => {}); }, [unread, mutate]); if (loggedOut) return

Log in to see your notifications.

; return (

Notifications

{/* Dedicated section for seriouscritter's messages */} {seriousCritterMessages.length > 0 && (

From {ADMIN_ACTOR_USERNAME}

    {seriousCritterMessages.map((n) => { const { title, body } = notificationText(n); return (
  • {title} {body} {timeAgo(n.createdAt)} {n.track?.artworkUrl && }
  • ); })}
)} {/* General notifications list */} {allItems.length === 0 && !isLoading && (

Nothing yet. Reactions, new followers and songs sent to you show up here.

)} {data?.at(-1)?.nextCursor && ( )}
); }