'use client'; import { MutableRefObject, useEffect, useMemo, useRef, useState } from 'react'; import clsx from 'clsx'; import { basketApi, useGetBasketQuery, useGetMiniBasketQuery, useUpdateQuantityMutation } from '@akinon/next/data/client/basket'; import { useAppDispatch, useAppSelector } from '@akinon/next/redux/hooks'; import { closeMiniBasket } from '@akinon/next/redux/reducers/root'; import { BasketItem } from '@akinon/next/types'; import { Price, Button, Icon, LoaderSpinner, Link } from '@theme/components'; import { ROUTES } from '@theme/routes'; import { useCommonProductAttributes, useLocalization } from '@akinon/next/hooks'; import { Image } from '@akinon/next/components/image'; import { pushRemoveFromCart } from '@theme/utils/gtm'; interface MiniBasketItemProps { basketItem: BasketItem; highlightedItem: number; miniBasketListRef: MutableRefObject; } function MiniBasketItem(props: MiniBasketItemProps) { const { basketItem, highlightedItem, miniBasketListRef } = props; const dispatch = useAppDispatch(); const [updateQuantityMutation] = useUpdateQuantityMutation(); const commonProductAttributes = useCommonProductAttributes({ attributes: basketItem.product.attributes_kwargs }); const { t } = useLocalization(); const isHighlighted = useMemo(() => { return highlightedItem === basketItem.product.pk; }, [highlightedItem, basketItem.product.pk]); useEffect(() => { const miniBasketList = miniBasketListRef.current; if (highlightedItem === basketItem.product.pk) { if (miniBasketList.scrollTop > 0) { miniBasketList.scrollTop = 0; } } }, [highlightedItem, basketItem.product.pk, miniBasketListRef]); const removeItem = () => { updateQuantityMutation({ product: basketItem.product.pk, quantity: 0, attributes: {} // TODO: Handle attributes }) .unwrap() .then((data) => { dispatch( basketApi.util.updateQueryData( 'getBasket', undefined, (draftBasket) => { Object.assign(draftBasket, data.basket); } ) ); pushRemoveFromCart(basketItem?.product); }); }; return (
  • {basketItem.product.name}

    {t('basket.mini_basket.in_the_bag')}

    {basketItem.product.name} {/* TODO: Get correct variants */} {commonProductAttributes.map((attribute, index) => ( {attribute.name}: {attribute.value} ))}
    {parseFloat(basketItem.retail_price) > parseFloat(basketItem.price) && ( )}
  • ); } export default function MiniBasket() { const { open: miniBasketOpen } = useAppSelector( (state) => state.root.miniBasket ); const dispatch = useAppDispatch(); const { data: basket, isLoading, isSuccess } = useGetBasketQuery(undefined, { skip: !miniBasketOpen }); const { data: miniBasket } = useGetMiniBasketQuery(); const { t } = useLocalization(); const { highlightedItem } = useAppSelector((state) => state.root.miniBasket); const [highlightedItemPk, setHighlightedItemPk] = useState(0); const [sortedBasket, setSortedBasket] = useState([]); const totalQuantity = useMemo( () => miniBasket?.total_quantity ?? 0, [miniBasket] ); const miniBasketList = useRef(null); useEffect(() => { if (highlightedItem > 0) { setHighlightedItemPk(highlightedItem); } }, [highlightedItem]); useEffect(() => { if (isSuccess) { if (highlightedItemPk > 0) { setSortedBasket( basket.basketitem_set.slice().sort((a, b) => { if (a.product.pk === highlightedItemPk) { return -1; } else if (b.product.pk === highlightedItemPk) { return 1; } else { return a.product.pk - b.product.pk; } }) ); } else { setSortedBasket(basket.basketitem_set); } } }, [isSuccess, highlightedItem, basket, highlightedItemPk]); return ( <>
    { dispatch(closeMiniBasket()); }} />

    {t('basket.mini_basket.my_bag')}

    {totalQuantity} {t('basket.mini_basket.items')} dispatch(closeMiniBasket())} />
    {isLoading && } {/* TODO: Fix spinner position */} {isSuccess && (
      {sortedBasket.map((basketItem) => ( ))}
    )}
    ); }