src/frontend/components/CartDropdown/CartDropdown.tsx (51 lines of code) (raw):

// Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 import Link from 'next/link'; import { useEffect, useRef } from 'react'; import { CypressFields } from '../../utils/Cypress'; import { IProductCartItem } from '../../types/Cart'; import ProductPrice from '../ProductPrice'; import * as S from './CartDropdown.styled'; interface IProps { isOpen: boolean; onClose(): void; productList: IProductCartItem[]; } const CartDropdown = ({ productList, isOpen, onClose }: IProps) => { const ref = useRef<HTMLDivElement>(null); useEffect(() => { const handleClickOutside = (event: Event) => { if (ref.current && !ref.current.contains(event.target as Node)) { onClose(); } }; // Bind the event listener document.addEventListener('mousedown', handleClickOutside); return () => { // Unbind the event listener on clean up document.removeEventListener('mousedown', handleClickOutside); }; }, [ref, onClose]); return isOpen ? ( <S.CartDropdown ref={ref} data-cy={CypressFields.CartDropdown}> <div> <S.Header> <S.Title>Shopping Cart</S.Title> <span onClick={onClose}>Close</span> </S.Header> <S.ItemList> {!productList.length && <S.EmptyCart>Your shopping cart is empty</S.EmptyCart>} {productList.map( ({ quantity, product: { name, picture, id, priceUsd = { nanos: 0, currencyCode: 'USD', units: 0 } } }) => ( <S.Item key={id} data-cy={CypressFields.CartDropdownItem}> <S.ItemImage src={"/images/products/" + picture} alt={name} /> <S.ItemDetails> <S.ItemName>{name}</S.ItemName> <ProductPrice price={priceUsd} /> <S.ItemQuantity>Quantity: {quantity}</S.ItemQuantity> </S.ItemDetails> </S.Item> ) )} </S.ItemList> </div> <Link href="/cart"> <S.CartButton data-cy={CypressFields.CartGoToShopping}>Go to Shopping Cart</S.CartButton> </Link> </S.CartDropdown> ) : null; }; export default CartDropdown;