'use client' import { useEffect, useRef } from 'react' import Button from './Button' import { formatDistanceToNow } from 'date-fns' import { de } from 'date-fns/locale' type Notification = { id: string text: string read: boolean actionType?: string actionData?: string createdAt?: string } type Props = { notifications: Notification[] markAllAsRead: () => void onSingleRead: (id: string) => void onClose: () => void onAction: (action: 'accept' | 'reject', invitationId: string) => void onClickNotification?: (notification: Notification) => void anchorRef?: React.RefObject // Glocke } export default function NotificationCenter({ notifications, markAllAsRead, onSingleRead, onClose, onAction, onClickNotification, anchorRef }: Props) { const panelRef = useRef(null) // EIN Outside-Click Listener, der sowohl Panel als auch Anchor ignoriert useEffect(() => { const onDocPointerDown = (e: PointerEvent) => { const t = e.target as Node if (panelRef.current?.contains(t)) return if (anchorRef?.current?.contains(t)) return onClose() } document.addEventListener('pointerdown', onDocPointerDown, { passive: true }) return () => document.removeEventListener('pointerdown', onDocPointerDown) }, [onClose, anchorRef]) return (
{/* Kopfzeile */}
Benachrichtigungen
{/* Liste */}
{notifications.length === 0 ? (
Keine Benachrichtigungen
) : ( notifications.map((n) => { const needsAction = !n.read && (n.actionType === 'team-invite' || n.actionType === 'team-join-request') return (
{ onClickNotification?.(n) if (!n.read) onSingleRead(n.id) }} >
{n.text} {n.createdAt && formatDistanceToNow(new Date(n.createdAt), { addSuffix: true, locale: de })}
{needsAction ? ( <> ) : ( !n.read && ( ) )}
) }) )}
) }