'use client'; import { ReactNode, useMemo, useRef, useCallback } from 'react'; import { useGetMiniBasketQuery } from '@akinon/next/data/client/basket'; import { useAppDispatch, useAppSelector } from '@akinon/next/redux/hooks'; import { closeMiniBasket, toggleMiniBasket } from '@akinon/next/redux/reducers/root'; import { openSearch } from '@akinon/next/redux/reducers/header'; import clsx from 'clsx'; import { ROUTES } from '@theme/routes'; import MiniBasket from './mini-basket'; import { Badge, Icon, Link } from '@theme/components'; import { useOnClickOutside } from '@akinon/next/hooks'; interface MenuItem { label: string; url?: string; action?: () => void; icon: string; className?: string; badge?: ReactNode; miniBasket?: ReactNode; dataTestId?: string; } export default function ActionMenu() { const dispatch = useAppDispatch(); const { data: miniBasket } = useGetMiniBasketQuery(); const totalQuantity = useMemo( () => miniBasket?.total_quantity ?? 0, [miniBasket] ); const { open: miniBasketOpen } = useAppSelector( (state) => state.root.miniBasket ); const miniBasketRef = useRef(null); const closeMiniBasketCb = useCallback(() => { if (miniBasketOpen) dispatch(closeMiniBasket()); }, [miniBasketOpen, dispatch]); useOnClickOutside(miniBasketRef, closeMiniBasketCb); const MenuItems: MenuItem[] = [ { label: 'Search', action: () => { dispatch(openSearch()); }, icon: 'search', className: 'sm:hidden', dataTestId: 'header-search' }, { label: 'Favourite Products', url: ROUTES.ACCOUNT_WISHLIST, icon: 'heart-stroke', dataTestId: 'header-favourite' }, { label: 'Basket', action() { dispatch(toggleMiniBasket()); }, icon: 'cart', dataTestId: 'header-basket', badge: ( {totalQuantity} ), miniBasket: } ]; return ( ); }