From 998986b9fc33f4869af6d5d7921d5c2a0c1e03b4 Mon Sep 17 00:00:00 2001 From: NotII <46204250+NotII@users.noreply.github.com> Date: Tue, 18 Mar 2025 19:12:29 +0100 Subject: [PATCH] Update BuyerOrderInfo.tsx --- components/dashboard/BuyerOrderInfo.tsx | 228 ++++++++++++++++-------- 1 file changed, 157 insertions(+), 71 deletions(-) diff --git a/components/dashboard/BuyerOrderInfo.tsx b/components/dashboard/BuyerOrderInfo.tsx index 708570a..af1c231 100644 --- a/components/dashboard/BuyerOrderInfo.tsx +++ b/components/dashboard/BuyerOrderInfo.tsx @@ -1,7 +1,7 @@ "use client"; -import React, { useState, useEffect } from "react"; -import { Package, ShoppingBag, Info, ExternalLink } from "lucide-react"; +import React, { useState, useEffect, useCallback, useRef } from "react"; +import { Package, ShoppingBag, Info, ExternalLink, Loader2 } from "lucide-react"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { @@ -35,73 +35,138 @@ interface BuyerOrderInfoProps { export default function BuyerOrderInfo({ buyerId, chatId }: BuyerOrderInfoProps) { const router = useRouter(); - const [loading, setLoading] = useState(true); + const [loading, setLoading] = useState(false); const [orders, setOrders] = useState([]); + const [hasOrders, setHasOrders] = useState(null); + const [isTooltipOpen, setIsTooltipOpen] = useState(false); + const lastFetchedRef = useRef(0); + const isFetchingRef = useRef(false); + const tooltipDelayRef = useRef(null); - useEffect(() => { - // Only load if we have a chatId + // Fetch data without unnecessary dependencies to reduce render cycles + const fetchBuyerOrders = useCallback(async (force = false) => { + // Prevent multiple simultaneous fetches + if (isFetchingRef.current) return; + + // Don't fetch if we already know there are no orders + if (hasOrders === false && !force) return; + + // Don't fetch if we already have orders and data was fetched less than 10 seconds ago + const now = Date.now(); + if (!force && orders.length > 0 && now - lastFetchedRef.current < 10000) return; + + // Only continue if we have a chatId if (!chatId) return; - const fetchBuyerOrders = async () => { - try { - const authToken = getCookie("Authorization"); - - if (!authToken) return; - - const authAxios = axios.create({ - baseURL: process.env.NEXT_PUBLIC_API_URL, - headers: { - Authorization: `Bearer ${authToken}` - } - }); - - // Use the new endpoint that works with sub-users - const response = await authAxios.get(`/chats/${chatId}/orders?limit=250`); - - if (response.data && response.data.orders) { - setOrders(response.data.orders); + isFetchingRef.current = true; + setLoading(true); + + try { + const authToken = getCookie("Authorization"); + + if (!authToken) { + isFetchingRef.current = false; + setLoading(false); + return; + } + + const authAxios = axios.create({ + baseURL: process.env.NEXT_PUBLIC_API_URL, + headers: { + Authorization: `Bearer ${authToken}` } - - setLoading(false); - } catch (error) { - console.error("Error fetching buyer orders:", error); - setLoading(false); + }); + + // Use the new endpoint that works with sub-users + const response = await authAxios.get(`/chats/${chatId}/orders?limit=10`); // Limit to fewer orders for faster response + + if (response.data && response.data.orders) { + setOrders(response.data.orders); + setHasOrders(response.data.orders.length > 0); + } else { + setHasOrders(false); + } + + lastFetchedRef.current = Date.now(); + } catch (error) { + console.error("Error fetching buyer orders:", error); + setHasOrders(false); + } finally { + setLoading(false); + isFetchingRef.current = false; + } + }, [chatId]); // Minimize dependencies even further + + // Start fetching immediately when component mounts + useEffect(() => { + if (chatId) { + // Immediately attempt to fetch in the background + fetchBuyerOrders(); + } + + return () => { + // Clean up any pending timeouts + if (tooltipDelayRef.current) { + clearTimeout(tooltipDelayRef.current); } }; - - fetchBuyerOrders(); - }, [chatId]); + }, [chatId, fetchBuyerOrders]); const handleViewOrder = (orderId: string) => { router.push(`/dashboard/orders/${orderId}`); }; + // Handle hover with immediate tooltip opening + const handleButtonMouseEnter = () => { + // Start fetching data, but don't wait for it to complete + if (!isFetchingRef.current) { + queueMicrotask(() => { + fetchBuyerOrders(); + }); + } + }; + + // Handle tooltip state change + const handleTooltipOpenChange = (open: boolean) => { + setIsTooltipOpen(open); + if (open && !isFetchingRef.current) { + queueMicrotask(() => { + fetchBuyerOrders(); + }); + } + }; + // Format the price as currency const formatPrice = (price: number) => { return `£${price.toFixed(2)}`; }; - // Don't show anything while loading or if no orders - if (loading || orders.length === 0) { + // If we know there are no orders, don't show the component at all + if (hasOrders === false) { return null; } - // Count products across all orders - const productCount = orders.reduce((total, order) => { - return total + order.products.reduce((sum, product) => sum + product.quantity, 0); - }, 0); + // Precompute product count for button display (only if we have orders) + const productCount = orders.length > 0 + ? orders.reduce((total, order) => { + return total + order.products.reduce((sum, product) => sum + product.quantity, 0); + }, 0) + : 0; return ( - + - +
Recent Orders from this Customer
-
- {orders.map((order) => ( -
handleViewOrder(order._id)} - > -
-
- - Order #{order.orderId} + + {loading ? ( + // Show loading state +
+ + Loading orders... +
+ ) : orders.length === 0 ? ( + // Show no orders state +
+ No orders found for this customer +
+ ) : ( + // Show orders +
+ {orders.map((order) => ( +
handleViewOrder(order._id)} + > +
+
+ + Order #{order.orderId} +
+ + {order.status.toUpperCase()} +
- - {order.status.toUpperCase()} - -
- -
-
- {order.products.length} {order.products.length === 1 ? 'product' : 'products'} - · - {formatPrice(order.totalPrice)} + +
+
+ {order.products.length} {order.products.length === 1 ? 'product' : 'products'} + · + {formatPrice(order.totalPrice)} +
+ {new Date(order.orderDate).toLocaleDateString()}
- {new Date(order.orderDate).toLocaleDateString()}
-
- ))} -
+ ))} +
+ )} +