'use client' import { useState, useTransition } from 'react' import { useRouter } from 'next/navigation' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' import { markNotificationsRead } from '@/lib/actions' export type InboxItem = { id: string type: string subject: string bodyText: string status: string createdAt: string sentAt: string | null readAt: string | null } // The member's in-app notification inbox. Click an item to expand its message // (plain text) and mark it read; "Mark all as read" clears the rest. Read // state lives in notifications.read_at; this is the always-on channel, so a // notification whose email was muted ('skipped') still shows here. export function NotificationsInbox({ items, unreadCount, }: { items: InboxItem[] unreadCount: number }) { const router = useRouter() const [expanded, setExpanded] = useState(null) const [pending, startTransition] = useTransition() function open(n: InboxItem) { setExpanded(e => (e === n.id ? null : n.id)) if (!n.readAt) { startTransition(async () => { await markNotificationsRead({ ids: [n.id] }) router.refresh() }) } } function markAll() { startTransition(async () => { await markNotificationsRead({}) router.refresh() }) } if (items.length === 0) { return (

No notifications yet. Dues receipts, booking and class updates, and form receipts show up here.

) } return (
{unreadCount > 0 && (
{unreadCount} unread
)}
) }