'use client'; import { useState, MouseEvent } from 'react'; import { IconButton, Badge, Popover, Box, Typography, List, ListItem, ListItemButton, ListItemText, Button, CircularProgress, Alert, Divider, useTheme, useMediaQuery, } from '@mui/material'; import { Notifications as NotificationsIcon, Circle, Restaurant, Bedtime, ChildCare, Medication, EmojiEvents, Group, Settings, NotificationsOff, } from '@mui/icons-material'; import { formatDistanceToNow } from 'date-fns'; import { useNotifications } from '@/hooks/useNotifications'; import { Notification } from '@/lib/api/notifications'; interface NotificationBellProps { variant?: 'default' | 'compact'; } const notificationIcons: Record = { feeding: Restaurant, sleep: Bedtime, diaper: ChildCare, medication: Medication, milestone: EmojiEvents, family: Group, system: Settings, reminder: NotificationsIcon, }; export function NotificationBell({ variant = 'default' }: NotificationBellProps) { const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down('sm')); const [anchorEl, setAnchorEl] = useState(null); const { notifications, unreadCount, loading, error, refresh, markAsRead, markAllAsRead, } = useNotifications({ limit: 10 }); const open = Boolean(anchorEl); const handleClick = (event: MouseEvent) => { setAnchorEl(event.currentTarget); }; const handleClose = () => { setAnchorEl(null); }; const handleNotificationClick = async (notification: Notification) => { if (!notification.isRead) { await markAsRead(notification.id); } // TODO: Navigate to related content based on notification.data }; const handleMarkAllAsRead = async () => { await markAllAsRead(); }; const getNotificationIcon = (type: Notification['type']) => { const IconComponent = notificationIcons[type] || NotificationsIcon; return ; }; const formatTimestamp = (timestamp: string) => { try { return formatDistanceToNow(new Date(timestamp), { addSuffix: true }); } catch { return 'Recently'; } }; const displayCount = unreadCount > 99 ? '99+' : unreadCount; return ( <> 0 ? 'pulse 2s ease-in-out infinite' : 'none', '@keyframes pulse': { '0%, 100%': { transform: 'scale(1)', }, '50%': { transform: 'scale(1.1)', }, }, }, }} > Notifications {unreadCount > 0 && ( )} {loading && notifications.length === 0 ? ( ) : error ? ( {error} ) : notifications.length === 0 ? ( No notifications You're all caught up! ) : ( {notifications.map((notification, index) => ( {index > 0 && } handleNotificationClick(notification)} sx={{ px: 2, py: 1.5, backgroundColor: notification.isRead ? 'transparent' : 'action.hover', '&:hover': { backgroundColor: notification.isRead ? 'action.hover' : 'action.selected', }, }} > {getNotificationIcon(notification.type)} {!notification.isRead && ( )} {notification.title} {notification.message} {formatTimestamp(notification.createdAt)} ))} )} {notifications.length > 0 && ( )} ); }