import type {CartApiQueryFragment} from 'storefrontapi.generated'; import type {CartLayout} from '~/components/CartMain'; import {CartForm, Money, type OptimisticCart} from '@shopify/hydrogen'; import {useEffect, useId, useRef, useState} from 'react'; import {useFetcher} from 'react-router'; type CartSummaryProps = { cart: OptimisticCart; layout: CartLayout; }; export function CartSummary({cart, layout}: CartSummaryProps) { const className = layout === 'page' ? 'cart-summary-page' : 'cart-summary-aside'; const summaryId = useId(); const discountsHeadingId = useId(); const discountCodeInputId = useId(); const giftCardHeadingId = useId(); const giftCardInputId = useId(); return (

Totals

Subtotal
{cart?.cost?.subtotalAmount?.amount ? ( ) : ( '-' )}
); } function CartCheckoutActions({checkoutUrl}: {checkoutUrl?: string}) { if (!checkoutUrl) return null; return (

Continue to Checkout →


); } function CartDiscounts({ discountCodes, discountsHeadingId, discountCodeInputId, }: { discountCodes?: CartApiQueryFragment['discountCodes']; discountsHeadingId: string; discountCodeInputId: string; }) { const codes: string[] = discountCodes ?.filter((discount) => discount.applicable) ?.map(({code}) => code) || []; return (
{/* Have existing discount, display it with a remove option */} {/* Show an input to apply a discount */}
 
); } function UpdateDiscountForm({ discountCodes, children, }: { discountCodes?: string[]; children: React.ReactNode; }) { return ( {children} ); } function CartGiftCard({ giftCardCodes, giftCardHeadingId, giftCardInputId, }: { giftCardCodes: CartApiQueryFragment['appliedGiftCards'] | undefined; giftCardHeadingId: string; giftCardInputId: string; }) { const giftCardCodeInput = useRef(null); const removeButtonRefs = useRef>(new Map()); const previousCardIdsRef = useRef([]); const giftCardAddFetcher = useFetcher({key: 'gift-card-add'}); const [removedCardIndex, setRemovedCardIndex] = useState(null); useEffect(() => { if (giftCardAddFetcher.data) { if (giftCardCodeInput.current !== null) { giftCardCodeInput.current.value = ''; } } }, [giftCardAddFetcher.data]); useEffect(() => { const currentCardIds = giftCardCodes?.map((card) => card.id) || []; if (removedCardIndex !== null && giftCardCodes) { const focusTargetIndex = Math.min( removedCardIndex, giftCardCodes.length - 1, ); const focusTargetCard = giftCardCodes[focusTargetIndex]; const focusButton = focusTargetCard ? removeButtonRefs.current.get(focusTargetCard.id) : null; if (focusButton) { focusButton.focus(); } else if (giftCardCodeInput.current) { giftCardCodeInput.current.focus(); } setRemovedCardIndex(null); } previousCardIdsRef.current = currentCardIds; }, [giftCardCodes, removedCardIndex]); const handleRemoveClick = (cardId: string) => { const index = previousCardIdsRef.current.indexOf(cardId); if (index !== -1) { setRemovedCardIndex(index); } }; return (
{giftCardCodes && giftCardCodes.length > 0 && (
Applied Gift Card(s)
{giftCardCodes.map((giftCard) => (
handleRemoveClick(giftCard.id)} buttonRef={(el: HTMLButtonElement | null) => { if (el) { removeButtonRefs.current.set(giftCard.id, el); } else { removeButtonRefs.current.delete(giftCard.id); } }} > ***{giftCard.lastCharacters}  
))}
)}
 
); } function AddGiftCardForm({ fetcherKey, children, }: { fetcherKey?: string; children: React.ReactNode; }) { return ( {children} ); } function RemoveGiftCardForm({ giftCardId, lastCharacters, children, onRemoveClick, buttonRef, }: { giftCardId: string; lastCharacters: string; children: React.ReactNode; onRemoveClick?: () => void; buttonRef?: (el: HTMLButtonElement | null) => void; }) { return ( {children}   ); }