| // src/components/NotificationCenter.tsx | |
| import React, { useState, useEffect } from 'react'; | |
| import { useNotifications } from '../context/NotificationContext'; | |
| import { useWebSocket } from '../hooks/useWebSocket'; | |
| export const NotificationCenter: React.FC = () => { | |
| const { | |
| notifications, | |
| unreadCount, | |
| loading, | |
| hasMore, | |
| loadNotifications, | |
| markAsRead, | |
| markAllAsRead, | |
| deleteNotification, | |
| } = useNotifications(); | |
| const { connectionStatus } = useWebSocket(); | |
| const isConnected = connectionStatus === 'connected'; | |
| const [isOpen, setIsOpen] = useState<boolean>(false); | |
| const [page, setPage] = useState<number>(0); | |
| useEffect(() => { | |
| if (isOpen && notifications.length === 0) { | |
| loadNotifications(0); | |
| } | |
| }, [isOpen, loadNotifications, notifications.length]); | |
| const handleLoadMore = () => { | |
| const nextPage = page + 1; | |
| setPage(nextPage); | |
| loadNotifications(nextPage); | |
| }; | |
| const getNotificationIcon = (type: string) => { | |
| switch (type) { | |
| case 'LIKE': return '❤️'; | |
| case 'COMMENT': return '💬'; | |
| case 'FOLLOW': return '👥'; | |
| case 'MENTION': return '@'; | |
| case 'SYSTEM': return '🔔'; | |
| case 'ALERT': return '⚠️'; | |
| default: return '📢'; | |
| } | |
| }; | |
| const getPriorityColor = (priority?: string) => { | |
| switch (priority) { | |
| case 'HIGH': return '#dc2626'; | |
| case 'MEDIUM': return '#f59e0b'; | |
| default: return '#6b7280'; | |
| } | |
| }; | |
| return ( | |
| <div className="notification-center"> | |
| <button | |
| className="notification-bell" | |
| onClick={() => setIsOpen(!isOpen)} | |
| > | |
| 🔔 | |
| {unreadCount > 0 && ( | |
| <span className="notification-badge">{unreadCount}</span> | |
| )} | |
| {!isConnected && <span className="offline-dot" />} | |
| </button> | |
| {isOpen && ( | |
| <div className="notification-dropdown"> | |
| <div className="notification-header"> | |
| <h3>Notifications</h3> | |
| {unreadCount > 0 && ( | |
| <button onClick={markAllAsRead}>Mark all as read</button> | |
| )} | |
| </div> | |
| <div className="notification-list"> | |
| {loading && notifications.length === 0 ? ( | |
| <div className="notification-loading">Loading...</div> | |
| ) : notifications.length === 0 ? ( | |
| <div className="notification-empty">No notifications</div> | |
| ) : ( | |
| <> | |
| {notifications.map((notif: any) => ( | |
| <div | |
| key={notif.id} | |
| className={} | |
| onClick={() => { | |
| if (!notif.isRead) markAsRead(notif.id); | |
| if (notif.link) window.location.href = notif.link; | |
| }} | |
| > | |
| <div className="notification-icon"> | |
| {getNotificationIcon(notif.type)} | |
| </div> | |
| <div className="notification-content"> | |
| <div className="notification-title">{notif.title}</div> | |
| <div className="notification-body">{notif.body || notif.message}</div> | |
| <div className="notification-time"> | |
| {new Date(notif.createdAt).toLocaleString()} | |
| </div> | |
| </div> | |
| <button | |
| className="notification-delete" | |
| onClick={(e) => { | |
| e.stopPropagation(); | |
| deleteNotification(notif.id); | |
| }} | |
| > | |
| × | |
| </button> | |
| <div | |
| className="notification-priority" | |
| style={{ backgroundColor: getPriorityColor(notif.priority) }} | |
| /> | |
| </div> | |
| ))} | |
| {hasMore && ( | |
| <button className="load-more" onClick={handleLoadMore}> | |
| Load more | |
| </button> | |
| )} | |
| </> | |
| )} | |
| </div> | |
| </div> | |
| )} | |
| </div> | |
| ); | |
| }; | |
| export default NotificationCenter; | |
Xet Storage Details
- Size:
- 4.22 kB
- Xet hash:
- b59fa1536f9d1073100c2c4fd7de2c407ed64e0026150529bc3f49280fa6cf03
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.