import React, { useEffect, useState } from 'react'; import { Carousel, CarouselProps, COLOR_TOKENS, Box, } from '@wix/design-system'; import { SuggestionsState } from '../../state/Suggestions/SuggestionsState'; import { observer } from 'mobx-react-lite'; import { useWixPatternsContainer } from '@wix/bex-core/react'; import { MarketingCardSkeleton } from './MarketingCard'; import { SuggestionsProps } from './types'; import { VisibilityTrackedCard } from './VisibilityTrackedCard'; import { SuggestionsProvider } from './SuggestionsContext'; const defaultCarouselProps: CarouselProps = { dots: false, infinite: false, variableWidth: true, slideSpacing: 24, controlsPosition: 'overlay', showControlsShadow: true, gradientColor: COLOR_TOKENS['--wsr-color-D70'], gradient: true, controlsStartEnd: 'hidden', }; interface SuggestionsContainerProps { count: number; children: React.ReactNode; carouselProps?: CarouselProps; dataHook: string; dataState: 'idle' | 'loading'; maxInlineItems: number; } export interface SuggestionItemProps { children: React.ReactNode; dataId?: string; } export interface NonNullableElementCard { key: string; offerGuid: string | undefined; element: T; } const SuggestionsContainer: React.FC = ({ count, children, carouselProps, dataHook, dataState, maxInlineItems, }) => { if (count <= maxInlineItems) { return (
{children}
); } return (
{children}
); }; export const SuggestionItem: React.FC = ({ children, dataId, }) => (
{children}
); export const Suggestions: React.FC = observer( ({ placementId, renderCard, CardSkeleton = MarketingCardSkeleton, carouselProps, skeletonsNumber = 4, dataHook = 'suggestions', maxInlineItems = 2, }) => { const container = useWixPatternsContainer(); const [state] = useState( () => new SuggestionsState({ placementId, container }), ); useEffect(() => { return state.init(); }, [state]); if (state.hasOffers) { // use initial cards count for container, to match the count the cards get rendered with const cardCount = state.offers.length; const cards = state.offers .map((offer, index) => { const key = offer.offerGuid || `suggestion-${index}`; return { key, offerGuid: offer.offerGuid, element: renderCard({ offer, index, totalOffers: cardCount, }), }; }) .filter( (card): card is NonNullableElementCard => card.element != null, ); if (cards.length === 0) { return null; } return ( {cards.map(({ key, offerGuid, element }) => ( offerGuid && state.onOfferViewed(offerGuid)} /> ))} ); } if (state.isFetching) { const skeletons = Array.from({ length: skeletonsNumber }).map( (_, index) => ( ), ); return ( {skeletons} ); } return null; }, );