Skip to main content
Glama
cart-recommendation.tsx4.62 kB
'use client' import React, { useState, useEffect, useRef } from 'react' import { useCart } from '@/lib/cart-context' import { mcpClient } from '@/lib/mcp-client' import { Product } from '@/lib/types' import { Button } from '@/components/ui/button' import { Plus, Star } from 'lucide-react' interface CartRecommendationProps { className?: string } export function CartRecommendation({ className }: CartRecommendationProps) { const { items, addItem } = useCart() const [recommendation, setRecommendation] = useState<Product | null>(null) const [loading, setLoading] = useState(true) const [addingToCart, setAddingToCart] = useState(false) const previousProductIdsRef = useRef<Set<number>>(new Set()) useEffect(() => { const currentProductIds = new Set(items.map(item => item.product.id)) const previousProductIds = previousProductIdsRef.current // Check if a new product was added (not just quantity changes or removals) const hasNewProduct = Array.from(currentProductIds).some(id => !previousProductIds.has(id)) // Update the ref for next comparison previousProductIdsRef.current = currentProductIds const fetchRecommendation = async () => { try { setLoading(true) // Get all products const result = await mcpClient.getProducts() if (!result.success || !result.products) { return } // Filter products not in cart const availableProducts = result.products.filter( product => !currentProductIds.has(product.id) ) // Select a random product from available ones if (availableProducts.length > 0) { const randomIndex = Math.floor(Math.random() * availableProducts.length) setRecommendation(availableProducts[randomIndex]) } else { setRecommendation(null) } } catch (error) { console.error('Failed to fetch recommendation:', error) } finally { setLoading(false) } } // Only fetch recommendations when: // 1. We have items in cart AND // 2. A new product was added (not just quantity changes or removals) if (items.length > 0 && (hasNewProduct || previousProductIds.size === 0)) { fetchRecommendation() } else if (items.length === 0) { // Clear recommendation when cart is empty setLoading(false) setRecommendation(null) } }, [items]) const handleAddToCart = async () => { if (!recommendation) return try { setAddingToCart(true) await addItem(recommendation, 1) } catch (error) { console.error('Failed to add recommendation to cart:', error) } finally { setAddingToCart(false) } } // Don't show if cart is empty or no recommendation if (items.length === 0 || loading || !recommendation) { return null } return ( <div className={`border rounded-lg p-3 bg-gradient-to-r from-blue-50 to-indigo-50 ${className}`}> <div className="flex items-center gap-2 mb-2"> <Star className="h-4 w-4 text-amber-500" fill="currentColor" /> <span className="text-sm font-medium text-gray-700">You might also like</span> </div> <div className="flex items-center gap-3"> <div className="h-12 w-12 flex-shrink-0 flex items-center justify-center overflow-hidden bg-white rounded border"> <img src={recommendation.image} alt={recommendation.title} className="max-h-full max-w-full" /> </div> <div className="flex-1 min-w-0"> <p className="font-medium text-sm text-gray-900 leading-tight"> {recommendation.title} </p> <div className="flex items-center gap-2 mt-1 flex-wrap"> <span className="text-sm font-semibold text-green-600 flex-shrink-0"> ${recommendation.price.toFixed(2)} </span> <div className="flex items-center gap-1 flex-shrink-0"> <Star className="h-3 w-3 text-amber-400" fill="currentColor" /> <span className="text-xs text-gray-500 whitespace-nowrap"> {recommendation.rating.rate} ({recommendation.rating.count}) </span> </div> </div> </div> <Button size="sm" onClick={handleAddToCart} disabled={addingToCart} className="flex-shrink-0" > <Plus className="h-4 w-4 mr-1" /> {addingToCart ? 'Adding...' : 'Add'} </Button> </div> </div> ) }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Mithgroth/fakestore-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server