"use client" import React, { useState, useEffect, useRef, useCallback } from 'react'; import { useRouter } from 'next/navigation'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Avatar, AvatarFallback } from "@/components/ui/avatar"; import { formatDistanceToNow } from "date-fns"; import { Plus, MessageCircle, Loader2, RefreshCw, Eye, User, ChevronLeft, ChevronRight, MessageSquare, ArrowRightCircle, X, Clock, CheckCheck, Search, Volume2, VolumeX } from "lucide-react"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { toast } from "sonner"; import { clientFetch, getCookie } from "@/lib/api"; import { formatDistance } from 'date-fns'; import Link from 'next/link'; import { cn } from '@/lib/utils/general'; interface Chat { _id: string; buyerId: string; vendorId: string; storeId: string; lastUpdated: string; orderId?: string; telegramUsername?: string | null; } interface UnreadCounts { totalUnread: number; chatCounts: Record; } interface ChatResponse { chats: Chat[]; page: number; totalPages: number; totalChats: number; } export default function ChatTable() { const router = useRouter(); const [chats, setChats] = useState([]); const [loading, setLoading] = useState(true); const [unreadCounts, setUnreadCounts] = useState({ totalUnread: 0, chatCounts: {} }); const audioRef = useRef(null); const [currentPage, setCurrentPage] = useState(1); const [totalPages, setTotalPages] = useState(1); const [totalChats, setTotalChats] = useState(0); const [itemsPerPage, setItemsPerPage] = useState(10); const isManualRefresh = useRef(false); // Initialize audio element for notifications useEffect(() => { audioRef.current = new Audio('/notification.mp3'); return () => { if (audioRef.current) { audioRef.current = null; } }; }, []); // Play notification sound const playNotificationSound = () => { if (audioRef.current) { audioRef.current.play().catch(e => { console.log("Failed to play notification sound:", e); }); } }; // Get vendor ID from JWT token const getVendorIdFromToken = () => { const authToken = getCookie("Authorization") || ""; if (!authToken) { throw new Error("No auth token found"); } const tokenParts = authToken.split("."); if (tokenParts.length !== 3) { throw new Error("Invalid token format"); } const payload = JSON.parse(atob(tokenParts[1])); const vendorId = payload.id; if (!vendorId) { throw new Error("Vendor ID not found in token"); } return { vendorId, authToken }; }; // Fetch chats when component mounts or page/limit changes useEffect(() => { // Skip fetch if this effect was triggered by a manual refresh // since we'll call fetchChats directly in that case if (!isManualRefresh.current) { fetchChats(); } isManualRefresh.current = false; // Set up polling for unread messages const interval = setInterval(() => { fetchUnreadCounts(); }, 30000); // Check every 30 seconds return () => clearInterval(interval); }, [currentPage, itemsPerPage]); // Handle refresh button click const handleRefresh = () => { isManualRefresh.current = true; setCurrentPage(1); fetchChats(); }; // Fetch unread counts const fetchUnreadCounts = async () => { try { // Get the vendor ID from the auth token const { vendorId } = getVendorIdFromToken(); // Fetch unread counts for this vendor using clientFetch const response = await clientFetch(`/chats/vendor/${vendorId}/unread`); const newUnreadCounts = response; // Play sound if there are new messages if (newUnreadCounts.totalUnread > unreadCounts.totalUnread) { //playNotificationSound(); } setUnreadCounts(newUnreadCounts); } catch (error) { console.error("Failed to fetch unread counts:", error); } }; // Fetch chats with pagination const fetchChats = async (page = currentPage, limit = itemsPerPage) => { setLoading(true); try { // Get the vendor ID from the auth token const { vendorId } = getVendorIdFromToken(); // Now fetch chats for this vendor using clientFetch with pagination const response = await clientFetch(`/chats/vendor/${vendorId}?page=${page}&limit=${limit}`); // Check if the response is the old format (array) or new paginated format if (Array.isArray(response)) { // Handle old API response format (backward compatibility) setChats(response); setTotalPages(1); setTotalChats(response.length); } else { // Handle new paginated response format setChats(response.chats || []); setTotalPages(response.totalPages || 1); setCurrentPage(response.page || 1); setTotalChats(response.totalChats || 0); } await fetchUnreadCounts(); } catch (error) { console.error("Failed to fetch chats:", error); toast.error("Failed to load chat conversations"); setChats([]); } finally { setLoading(false); } }; // Navigate to chat detail page const handleChatClick = (chatId: string) => { router.push(`/dashboard/chats/${chatId}`); }; // Create new chat const handleCreateChat = () => { router.push("/dashboard/chats/new"); }; // Handle pagination const goToNextPage = () => { if (currentPage < totalPages) { isManualRefresh.current = true; const nextPage = currentPage + 1; setCurrentPage(nextPage); fetchChats(nextPage); } }; const goToPrevPage = () => { if (currentPage > 1) { isManualRefresh.current = true; const prevPage = currentPage - 1; setCurrentPage(prevPage); fetchChats(prevPage); } }; // Handle items per page change const handleItemsPerPageChange = (value: string) => { const newLimit = parseInt(value); isManualRefresh.current = true; setItemsPerPage(newLimit); setCurrentPage(1); // Reset to first page when changing limit fetchChats(1, newLimit); }; return (
Customer Last Activity Status Actions {loading ? ( ) : chats.length === 0 ? (

No chats found

) : ( chats.map((chat) => ( handleChatClick(chat._id)} >
{chat.telegramUsername ? `@${chat.telegramUsername}` : 'Customer'}
ID: {chat.buyerId}
{chat.orderId && (
Order #{chat.orderId}
)}
{formatDistanceToNow(new Date(chat.lastUpdated), { addSuffix: true })} {unreadCounts.chatCounts[chat._id] > 0 ? ( {unreadCounts.chatCounts[chat._id]} new ) : ( Read )}
)) )}
{/* Pagination controls */} {!loading && chats.length > 0 && (
Showing {chats.length} of {totalChats} chats
Rows per page:
Page {currentPage} of {totalPages}
)}
); }