diff --git a/app/actions/getUnreadMessageCount.js b/app/actions/getUnreadMessageCount.js new file mode 100644 index 0000000..47352fe --- /dev/null +++ b/app/actions/getUnreadMessageCount.js @@ -0,0 +1,26 @@ +'use server'; + +import connectDB from '@/config/database'; +import Message from '@/models/Message'; +import { getSessionUser } from '@/utils/getSessionUser'; + +async function getUnreadMessageCount() { + await connectDB(); + + const sessionUser = await getSessionUser(); + + if (!sessionUser || !sessionUser.user) { + return { error: 'User ID is required' }; + } + + const { userId } = sessionUser; + + const count = await Message.countDocuments({ + recipient: userId, + read: false, + }); + + return { count }; +} + +export default getUnreadMessageCount; diff --git a/app/layout.jsx b/app/layout.jsx index e9459bf..3503270 100644 --- a/app/layout.jsx +++ b/app/layout.jsx @@ -1,5 +1,6 @@ import Navbar from '@/components/Navbar'; import AuthProvider from '@/components/AuthProvider'; +import { GlobalProvider } from '@/context/GlobalContext'; import { ToastContainer } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; import '@/assets/styles/globals.css'; @@ -13,13 +14,15 @@ export const metadata = { const MainLayout = ({ children }) => { return ( - - - -
{children}
- - - + + + + +
{children}
+ + + +
); }; diff --git a/components/MessageCard.jsx b/components/MessageCard.jsx index 493c84c..1fbbd8f 100644 --- a/components/MessageCard.jsx +++ b/components/MessageCard.jsx @@ -3,20 +3,25 @@ import { useState } from 'react'; import { toast } from 'react-toastify'; import markMessageAsRead from '@/app/actions/markMessageAsRead'; import deleteMessage from '@/app/actions/deleteMessage'; +import { useGlobalContext } from '@/context/GlobalContext'; const MessageCard = ({ message }) => { const [isRead, setIsRead] = useState(message.read); const [isDeleted, setIsDeleted] = useState(false); + const { setUnreadCount } = useGlobalContext(); + const handleReadClick = async () => { const read = await markMessageAsRead(message._id); setIsRead(read); + setUnreadCount((prevCount) => (read ? prevCount - 1 : prevCount + 1)); toast.success(`Marked as ${read ? 'read' : 'new'}`); }; const handleDeleteClick = async () => { await deleteMessage(message._id); setIsDeleted(true); + setUnreadCount((prevCount) => (isRead ? prevCount : prevCount - 1)); toast.success('Message Deleted'); }; diff --git a/components/Navbar.jsx b/components/Navbar.jsx index 6835dfc..e48e68b 100644 --- a/components/Navbar.jsx +++ b/components/Navbar.jsx @@ -7,6 +7,7 @@ import { FaGoogle } from 'react-icons/fa'; import logo from '@/assets/images/logo-white.png'; import profileDefault from '@/assets/images/profile.png'; import { signIn, signOut, useSession, getProviders } from 'next-auth/react'; +import UnreadMessageCount from './UnreadMessageCount'; const Navbar = () => { const { data: session } = useSession(); @@ -151,10 +152,7 @@ const Navbar = () => { /> - - 2 - {/* */} - + {/* */}
diff --git a/components/UnreadMessageCount.jsx b/components/UnreadMessageCount.jsx new file mode 100644 index 0000000..b3b22e1 --- /dev/null +++ b/components/UnreadMessageCount.jsx @@ -0,0 +1,13 @@ +'use client'; +import { useGlobalContext } from '@/context/GlobalContext'; + +const UnreadMessageCount = () => { + const { unreadCount } = useGlobalContext(); + + return unreadCount > 0 ? ( + + {unreadCount} + + ) : null; +}; +export default UnreadMessageCount; diff --git a/context/GlobalContext.js b/context/GlobalContext.js new file mode 100644 index 0000000..dfe9cbf --- /dev/null +++ b/context/GlobalContext.js @@ -0,0 +1,38 @@ +'use client'; +import getUnreadMessageCount from '@/app/actions/getUnreadMessageCount'; +import { useSession } from 'next-auth/react'; +import { createContext, useContext, useState, useEffect } from 'react'; + +// Create context +const GlobalContext = createContext(); + +// Create a provider +export function GlobalProvider({ children }) { + const [unreadCount, setUnreadCount] = useState(0); + + const { data: session } = useSession(); + + useEffect(() => { + if (session && session.user) { + getUnreadMessageCount().then((res) => { + if (res.count) setUnreadCount(res.count); + }); + } + }, [getUnreadMessageCount, session]); + + return ( + + {children} + + ); +} + +// Create a custom hook to access context +export function useGlobalContext() { + return useContext(GlobalContext); +}