All files / src/components/features/cart/Cart SingleItem.tsx

100% Statements 126/126
90% Branches 9/10
100% Functions 7/7
100% Lines 126/126

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 1271x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 17x 17x 17x 17x 17x 1x 1x 17x 17x 17x 3x 3x 3x 3x 17x 17x 17x 3x 2x 2x 2x 2x 3x 1x 1x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 1x 1x  
import React, { useState } from "react";
import { AppDispatch } from "@/redux/store";
import { useDispatch } from "react-redux";
import {
  removeItemFromCart,
  updateCartItemQuantity,
  type CartItem } from "@/redux/features/cartSlice";
 
import { eventTracking } from "@/lib/event-tracking";
import { Icon } from "@/components/ui/icons";
import { ProductThumbnail, PriceDisplay, HStack, Center } from "@/components/ui";
import { ProductLink } from "@/components/ui/links";
 
interface SingleItemProps {
  item: CartItem;
}
 
const SingleItem: React.FC<SingleItemProps> = ({ item }) => {
  const [quantity, setQuantity] = useState(item.quantity);
 
  const dispatch = useDispatch<AppDispatch>();
 
  const handleRemoveFromCart = () => {
    dispatch(removeItemFromCart(item.id));
    eventTracking.removeFromCart(item.id, item.title);
  };
 
  const handleIncreaseQuantity = () => {
    const newQuantity = quantity + 1;
    setQuantity(newQuantity);
    dispatch(updateCartItemQuantity({ id: item.id, quantity: newQuantity }));
    eventTracking.updateCartQuantity(item.id, item.title, newQuantity);
  };
 
  const handleDecreaseQuantity = () => {
    if (quantity > 1) {
      const newQuantity = quantity - 1;
      setQuantity(newQuantity);
      dispatch(updateCartItemQuantity({ id: item.id, quantity: newQuantity }));
      eventTracking.updateCartQuantity(item.id, item.title, newQuantity);
    } else {
      return;
    }
  };
 
  return (
    <HStack align="center" className="border-t border-gray-3 dark:border-gray-700 py-5 px-7.5">
      <div className="min-w-[400px]">
        <HStack align="center" justify="between" gap={5}>
          <HStack align="center" gap={5.5} className="w-full">
            <Center className="rounded-[5px] bg-gray-2 dark:bg-gray-700 max-w-[80px] w-full h-17.5">
              <ProductThumbnail
                src={item.imgs?.thumbnails[0]}
                alt={item.title}
                size={80}
              />
            </Center>
 
            <div>
              <h3 className="text-dark dark:text-gray-200">
                <ProductLink product={{ id: item.id, title: item.title }}>
                  {item.title}
                </ProductLink>
              </h3>
            </div>
          </HStack>
        </HStack>
      </div>
 
      <div className="min-w-[180px]">
        <PriceDisplay
          price={item.price}
          discountedPrice={item.discountedPrice}
          size="sm"
        />
      </div>
 
      <div className="min-w-[275px]">
        <HStack align="center" className="w-max rounded-md border border-gray-3 dark:border-gray-600">
          <Center
            as="button"
            onClick={() => handleDecreaseQuantity()}
            aria-label="Decrease quantity"
            className="w-11.5 h-11.5 ease-out duration-200 hover:text-blue dark:text-gray-300"
          >
            <Icon name="minus" size={20} />
          </Center>
 
          <Center as="span" className="w-16 h-11.5 border-x border-gray-4 dark:border-gray-600 dark:text-gray-200">
            {quantity}
          </Center>
 
          <Center
            as="button"
            onClick={() => handleIncreaseQuantity()}
            aria-label="Increase quantity"
            className="w-11.5 h-11.5 ease-out duration-200 hover:text-blue dark:text-gray-300"
          >
            <Icon name="plus" size={20} />
          </Center>
        </HStack>
      </div>
 
      <div className="min-w-[200px]">
        <PriceDisplay
          price={item.price * quantity}
          discountedPrice={item.discountedPrice * quantity}
          size="sm"
        />
      </div>
 
      <HStack justify="end" className="min-w-[50px]">
        <Center
          as="button"
          onClick={() => handleRemoveFromCart()}
          aria-label="Remove item from cart"
          className="rounded-lg max-w-[38px] w-full h-9.5 bg-gray-2 dark:bg-gray-700 border border-gray-3 dark:border-gray-600 text-dark dark:text-gray-300 ease-out duration-200 hover:bg-red-light-6 hover:border-red-light-4 hover:text-red"
        >
          <Icon name="trash" size={22} />
        </Center>
      </HStack>
    </HStack>
  );
};
 
export default SingleItem;