import React, { useEffect, useRef, useState } from 'react' import { Bell, CheckCheck, Trash2 } from 'lucide-react' import { useTranslation } from '../i18n' import { useInAppNotificationStore } from '../store/inAppNotificationStore.ts' import { useSettingsStore } from '../store/settingsStore' import Navbar from '../components/Layout/Navbar' import InAppNotificationItem from '../components/Notifications/InAppNotificationItem.tsx' export default function InAppNotificationsPage(): React.ReactElement { const { t } = useTranslation() const { settings } = useSettingsStore() const darkMode = settings.dark_mode const dark = darkMode === true || darkMode === 'dark' || (darkMode === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches) const { notifications, unreadCount, total, isLoading, hasMore, fetchNotifications, markAllRead, deleteAll } = useInAppNotificationStore() const [unreadOnly, setUnreadOnly] = useState(false) const loaderRef = useRef(null) useEffect(() => { fetchNotifications(true) }, []) // Reload when filter changes useEffect(() => { // We need to fetch with the unreadOnly filter — re-fetch from scratch // The store fetchNotifications doesn't take a filter param directly, // so we use the API directly for filtered view via a side channel. // For now, reset and fetch — store always loads all, filter is client-side. fetchNotifications(true) }, [unreadOnly]) // Infinite scroll useEffect(() => { if (!loaderRef.current) return const observer = new IntersectionObserver(entries => { if (entries[0].isIntersecting && hasMore && !isLoading) { fetchNotifications(false) } }, { threshold: 0.1 }) observer.observe(loaderRef.current) return () => observer.disconnect() }, [hasMore, isLoading]) const displayed = unreadOnly ? notifications.filter(n => !n.is_read) : notifications return (
{/* Header */}

{t('notifications.title')} {unreadCount > 0 && ( {unreadCount} )}

{total} {total === 1 ? 'notification' : 'notifications'}

{/* Bulk actions */}
{unreadCount > 0 && ( )} {notifications.length > 0 && ( )}
{/* Filter toggle */}
{/* Notification list */}
{isLoading && displayed.length === 0 ? (
) : displayed.length === 0 ? (

{t('notifications.empty')}

{t('notifications.emptyDescription')}

) : ( displayed.map(n => ( )) )} {/* Infinite scroll trigger */} {hasMore && (
{isLoading &&
}
)}
) }