From 027e380ce2b4ae8c328783f816c2406befe12236 Mon Sep 17 00:00:00 2001 From: NotII <46204250+NotII@users.noreply.github.com> Date: Sat, 8 Mar 2025 05:35:40 +0000 Subject: [PATCH] weewoo --- components/dashboard/ChatList.tsx | 379 ----------------------------- components/dashboard/ChatTable.tsx | 32 ++- 2 files changed, 22 insertions(+), 389 deletions(-) delete mode 100644 components/dashboard/ChatList.tsx diff --git a/components/dashboard/ChatList.tsx b/components/dashboard/ChatList.tsx deleted file mode 100644 index 572e2ec..0000000 --- a/components/dashboard/ChatList.tsx +++ /dev/null @@ -1,379 +0,0 @@ -"use client" - -import React, { useState, useEffect, useRef } 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 { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "@/components/ui/select"; -import { - Plus, - MessageCircle, - Loader2, - RefreshCw -} from "lucide-react"; -import axios from "axios"; -import { toast } from "sonner"; -import { getCookie } from "@/lib/client-utils"; - -interface Chat { - _id: string; - buyerId: string; - vendorId: string; - storeId: string; - lastUpdated: string; - orderId?: string; -} - -interface UnreadCounts { - totalUnread: number; - chatCounts: Record; -} - -export default function ChatList() { - const router = useRouter(); - const [chats, setChats] = useState([]); - const [loading, setLoading] = useState(true); - const [unreadCounts, setUnreadCounts] = useState({ totalUnread: 0, chatCounts: {} }); - const [previousTotalUnread, setPreviousTotalUnread] = useState(0); - const [selectedStore, setSelectedStore] = useState(""); - const [vendorStores, setVendorStores] = useState<{ _id: string, name: string }[]>([]); - const audioRef = useRef(null); - - // Initialize audio element - useEffect(() => { - // Create audio element for notification sound - 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 vendor ID and stores - useEffect(() => { - const fetchVendorData = async () => { - try { - // Get auth token from cookies - const authToken = getCookie("Authorization"); - - if (!authToken) { - toast.error("You need to be logged in to view chats"); - router.push("/auth/login"); - return; - } - - // Set up axios with the auth token - const authAxios = axios.create({ - baseURL: process.env.NEXT_PUBLIC_API_URL, - headers: { - Authorization: `Bearer ${authToken}` - } - }); - - // First, get vendor info using the /auth/me endpoint - const vendorResponse = await authAxios.get('/auth/me'); - console.log("Vendor auth response:", vendorResponse.data); - - // 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); - toast.error("Could not retrieve vendor information"); - return; - } - - // Fetch vendor's store using storefront endpoint - const storeResponse = await authAxios.get(`/storefront`); - console.log("Store response:", storeResponse.data); - - // Handle both array and single object responses - if (Array.isArray(storeResponse.data)) { - // If it's an array, use it as is - setVendorStores(storeResponse.data); - - if (storeResponse.data.length > 0) { - setSelectedStore(storeResponse.data[0]._id); - } - } else if (storeResponse.data && typeof storeResponse.data === 'object' && storeResponse.data._id) { - // If it's a single store object, convert it to an array with one element - const singleStore = [storeResponse.data]; - setVendorStores(singleStore); - setSelectedStore(storeResponse.data._id); - } else { - console.error("Expected store data but received:", storeResponse.data); - setVendorStores([]); - toast.error("Failed to load store data in expected format"); - } - } catch (error) { - console.error("Error fetching vendor data:", error); - toast.error("Failed to load vendor data"); - setVendorStores([]); - } - }; - - fetchVendorData(); - }, [router]); - - // Fetch chats and unread counts when store is selected - const fetchChats = async () => { - if (!selectedStore && vendorStores.length > 0) { - setSelectedStore("all"); // Set default "all" if we have stores but none selected - } - - setLoading(true); - - try { - const endpoint = selectedStore && selectedStore !== "all" - ? `/chats?storeId=${selectedStore}` - : "/chats"; - - const response = await axios.get(`${process.env.NEXT_PUBLIC_API_URL}/api${endpoint}`, { - headers: { - Authorization: getCookie("Authorization") || "", - "Content-Type": "application/json", - }, - }); - - setChats(response.data || []); - - // Fetch unread counts after loading chats - await fetchUnreadCounts(); - } catch (error) { - console.error("Failed to fetch chats:", error); - toast.error("Failed to load chat conversations"); - setChats([]); - } finally { - setLoading(false); - } - }; - - // Add polling effect - useEffect(() => { - if (selectedStore) { - fetchChats(); - - // Poll for updates every 10 seconds - const intervalId = setInterval(fetchChats, 10000); - - return () => clearInterval(intervalId); - } - }, [selectedStore]); - - // Handle chat selection - const handleChatClick = (chatId: string) => { - router.push(`/dashboard/chats/${chatId}`); - }; - - // Handle store change - const handleStoreChange = (e: React.ChangeEvent) => { - setSelectedStore(e.target.value); - }; - - // Create a new chat - const handleCreateChat = () => { - router.push("/dashboard/chats/new"); - }; - - if (loading) { - return ( - - - - Loading chats... - - - -
- {[1, 2, 3].map((n) => ( -
- ))} -
-
-
- ); - } - - return ( -
-
-
- - - -
- - -
- -
- - - - Customer - Last Activity - Status - Actions - - - - {loading ? ( - - - - - - ) : chats.length === 0 ? ( - - -
- -

No chats found

-
-
-
- ) : ( - chats.map((chat) => ( - handleChatClick(chat._id)} - > - -
- - - {chat.buyerId?.slice(0, 2).toUpperCase() || 'CU'} - - -
-
Customer {chat.buyerId.slice(0, 4)}
- {chat.orderId && ( -
- Order #{chat.orderId} -
- )} -
-
-
- - {formatDistanceToNow(new Date(chat.lastUpdated), { addSuffix: true })} - - - {unreadCounts.chatCounts[chat._id] > 0 ? ( - - {unreadCounts.chatCounts[chat._id]} new - - ) : ( - Read - )} - - - - -
- )) - )} -
-
-
-
- ); -} \ No newline at end of file diff --git a/components/dashboard/ChatTable.tsx b/components/dashboard/ChatTable.tsx index df14763..e8515c4 100644 --- a/components/dashboard/ChatTable.tsx +++ b/components/dashboard/ChatTable.tsx @@ -250,16 +250,28 @@ export default function ChatTable() { )} - +
+ + +
))