'use client'; import { useState } from 'react'; import { CdnImage as Image } from '@/ui/shared/cdn-image'; import type { CartBundleOffer as CartBundleOfferType } from 'brainerce'; import { formatPrice } from 'brainerce'; import { useCurrency } from '@/core/lib/use-currency'; import { useTranslations } from '@/core/lib/translations'; import { toAddToCartError, type AddToCartError } from '@/core/lib/add-to-cart-error'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { Card } from '@/components/ui/card'; import { Separator } from '@/components/ui/separator'; import { cn } from '@/core/lib/utils'; interface CartBundleOfferCardProps { offer: CartBundleOfferType; cartId: string; onAdd: () => void; className?: string; } export function CartBundleOfferCard({ offer, cartId, onAdd, className }: CartBundleOfferCardProps) { const t = useTranslations('cart'); const tp = useTranslations('productDetail'); const currency = useCurrency(); const [adding, setAdding] = useState(false); const [addError, setAddError] = useState(null); const offered = offer.offeredProducts; const totalOriginal = parseFloat(offer.totalOriginalPrice); const totalDiscounted = parseFloat(offer.totalDiscountedPrice); const discountLabel = offer.discountType === 'PERCENTAGE' ? `${offer.discountValue}%` : (formatPrice(parseFloat(offer.discountValue), { currency }) as string); async function handleAdd() { if (adding) return; setAddError(null); try { setAdding(true); const { getClient } = await import('@/core/lib/brainerce'); const client = getClient(); // No variant selections in the default template — products with // variants are best handled with a dedicated picker per offered item. await client.addBundleToCart(cartId, offer.id); onAdd(); } catch (err) { // The cart page is where a shopper is most likely to be AT the 50-line // cap, and a bundle adds one line per offered product. Logging alone // left the button spinning back to idle with nothing added. setAddError(toAddToCartError(err)); console.error('Failed to add bundle:', err); } finally { setAdding(false); } } return (

{offer.name}

{offer.description && (

{offer.description}

)}
{formatPrice(totalOriginal, { currency }) as string} {formatPrice(totalDiscounted, { currency }) as string} -{discountLabel}
{/* Why the bundle was refused. Without this the button resets and nothing is added, which reads as a broken button. */} {addError && (

{addError === 'CART_FULL' ? tp('cartFull') : tp('addToCartFailed')}

)}
); }