diff --git a/public/assets/icons/message-orange-icon.svg b/public/assets/icons/message-orange-icon.svg new file mode 100644 index 0000000..1afc874 --- /dev/null +++ b/public/assets/icons/message-orange-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/layout/CommonHeader.tsx b/src/components/layout/CommonHeader.tsx index 161b86f..41fcf47 100644 --- a/src/components/layout/CommonHeader.tsx +++ b/src/components/layout/CommonHeader.tsx @@ -14,7 +14,7 @@ const navLinks = [ export function CommonHeader() { const { data: session, status } = useSession(); - const { profileImage, profileName, avatarLoaded, setAvatarLoaded, notificationCount } = useHeaderData(); + const { profileImage, profileName, avatarLoaded, setAvatarLoaded, notificationCount, messageCount } = useHeaderData(); const [showProfileMenu, setShowProfileMenu] = useState(false); const [showGuestMenu, setShowGuestMenu] = useState(false); const [showMobileMenu, setShowMobileMenu] = useState(false); @@ -90,6 +90,28 @@ export function CommonHeader() {
) : session ? ( <> + {/* Message Icon - User role only */} + {userRole === 'USER' && ( + + Messages + {messageCount > 0 && ( + + + {messageCount > 99 ? '99+' : messageCount} + + + )} + + )} + {/* Notification Bell */} void; notificationCount: number; + messageCount: number; } const HeaderContext = createContext({ @@ -24,6 +26,7 @@ const HeaderContext = createContext({ avatarLoaded: false, setAvatarLoaded: () => {}, notificationCount: 0, + messageCount: 0, }); export function useHeaderData() { @@ -37,6 +40,7 @@ export function HeaderProvider({ children }: { children: React.ReactNode }) { const [profileTitle, setProfileTitle] = useState(null); const [avatarLoaded, setAvatarLoaded] = useState(false); const [notificationCount, setNotificationCount] = useState(0); + const [messageCount, setMessageCount] = useState(0); const lastAvatarKeyRef = useRef(null); const hasFetchedRef = useRef(false); @@ -116,18 +120,30 @@ export function HeaderProvider({ children }: { children: React.ReactNode }) { } }; + const fetchMessageCount = async () => { + try { + const count = await messagesService.getUnreadCount(); + setMessageCount(count); + } catch { + // Silently fail + } + }; + fetchCount(); + fetchMessageCount(); const interval = setInterval(fetchCount, 30000); + const messageInterval = setInterval(fetchMessageCount, 30000); const handleNotification = () => fetchCount(); window.addEventListener('notification-received', handleNotification); // Listen to socket events for immediate notification count refresh const unsubConnectionReq = socketService.onConnectionRequest(() => fetchCount()); const unsubConnectionRes = socketService.onConnectionResponse(() => fetchCount()); - const unsubNewMessage = socketService.onNewMessage(() => fetchCount()); + const unsubNewMessage = socketService.onNewMessage(() => { fetchCount(); fetchMessageCount(); }); return () => { clearInterval(interval); + clearInterval(messageInterval); window.removeEventListener('notification-received', handleNotification); unsubConnectionReq(); unsubConnectionRes(); @@ -136,7 +152,7 @@ export function HeaderProvider({ children }: { children: React.ReactNode }) { }, [status]); return ( - + {children} );