"use client" import React, { useState, useEffect, useRef } from "react"; import { useRouter } from "next/navigation"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Bell } from "lucide-react"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import axios from "axios"; import { getCookie } from "@/lib/client-utils"; interface UnreadCounts { totalUnread: number; chatCounts: Record; } export default function ChatNotifications() { const router = useRouter(); const [unreadCounts, setUnreadCounts] = useState({ totalUnread: 0, chatCounts: {} }); const [previousUnreadTotal, setPreviousUnreadTotal] = useState(0); const [loading, setLoading] = useState(true); const [chatMetadata, setChatMetadata] = useState>({}); const audioRef = useRef(null); useEffect(() => { audioRef.current = new Audio('/notification.mp3'); // Fallback if notification.mp3 doesn't exist - use browser API for a simple beep audioRef.current.addEventListener('error', () => { audioRef.current = null; }); return () => { if (audioRef.current) { audioRef.current = null; } }; }, []); // Function to play notification sound const playNotificationSound = () => { if (audioRef.current) { audioRef.current.currentTime = 0; audioRef.current.play().catch(err => { console.log('Error playing sound:', err); // Fallback to simple beep if audio file fails try { const context = new (window.AudioContext || (window as any).webkitAudioContext)(); const oscillator = context.createOscillator(); oscillator.type = 'sine'; oscillator.frequency.setValueAtTime(800, context.currentTime); oscillator.connect(context.destination); oscillator.start(); oscillator.stop(context.currentTime + 0.2); } catch (e) { console.error('Could not play fallback audio', e); } }); } else { // Fallback to simple beep if audio element is not available try { const context = new (window.AudioContext || (window as any).webkitAudioContext)(); const oscillator = context.createOscillator(); oscillator.type = 'sine'; oscillator.frequency.setValueAtTime(800, context.currentTime); oscillator.connect(context.destination); oscillator.start(); oscillator.stop(context.currentTime + 0.2); } catch (e) { console.error('Could not play fallback audio', e); } } }; // Fetch unread counts useEffect(() => { const fetchUnreadCounts = async () => { try { const authToken = getCookie("Authorization"); if (!authToken) return; const authAxios = axios.create({ baseURL: process.env.NEXT_PUBLIC_API_URL, headers: { Authorization: `Bearer ${authToken}` } }); // Get vendor info from profile endpoint - removing /api prefix const vendorResponse = await authAxios.get('/auth/me'); // Access correct property - the vendor ID is in vendor._id const vendorId = vendorResponse.data.vendor?._id; if (!vendorId) { console.error("Vendor ID not found in profile response:", vendorResponse.data); return; } const response = await authAxios.get(`/chats/vendor/${vendorId}/unread`); // Check if there are new notifications and play sound if needed if (!loading && response.data.totalUnread > previousUnreadTotal) { playNotificationSound(); } // Update state setUnreadCounts(response.data); setPreviousUnreadTotal(response.data.totalUnread); if (response.data.totalUnread > 0) { const chatIds = Object.keys(response.data.chatCounts); if (chatIds.length > 0) { // Create a simplified metadata object with just needed info const metadata: Record = {}; // Fetch each chat to get buyer IDs - removing /api prefix await Promise.all( chatIds.map(async (chatId) => { try { // Use markAsRead=false to ensure we don't mark messages as read const chatResponse = await authAxios.get(`/chats/${chatId}?markAsRead=false`); metadata[chatId] = { buyerId: chatResponse.data.buyerId, }; } catch (error) { console.error(`Error fetching chat ${chatId}:`, error); } }) ); setChatMetadata(metadata); } } } catch (error) { console.error("Error fetching unread counts:", error); } finally { setLoading(false); } }; fetchUnreadCounts(); // Set polling interval (every 10 seconds for more responsive notifications) const intervalId = setInterval(fetchUnreadCounts, 10000); return () => clearInterval(intervalId); }, [loading, previousUnreadTotal]); const handleChatClick = (chatId: string) => { router.push(`/dashboard/chats/${chatId}`); }; return (

Messages

{unreadCounts.totalUnread === 0 ? (

No new notifications

) : ( <>
{Object.entries(unreadCounts.chatCounts).map(([chatId, count]) => ( handleChatClick(chatId)} >

Customer {chatMetadata[chatId]?.buyerId.slice(-4) || 'Unknown'}

{count} new {count === 1 ? 'message' : 'messages'}

{count}
))}
)}
); }