import React, { forwardRef } from 'react'; import { Box, MarketingLayout, SkeletonLine, Card, Button, BadgeSkin, ButtonSkin, Image, Text, TextButton, Badge, SkeletonRectangle, ButtonPriority, } from '@wix/design-system'; import { Offer } from '@wix/bex-utils/@wix/ambassador-dealer-v1-serving-offer/types'; import { BaseCardComponentProps, SuggestionsCardProps } from './types'; import { SuggestionCtaWrapper } from './SuggestionCtaWrapper'; /** * Schema for marketing card content. * This defines the structure expected in offer.asset.creative for MarketingCard rendering. */ export interface MarketingCardSchema { title: string; description: { text: string; learnMore?: { link: string; text?: string; // defaults to 'Learn more' }; }; imageUrl: string; ctaButton?: { text: string; link: string; skin?: Extract; // defaults to 'standard' priority?: Extract; // defaults to 'secondary' }; badge?: { text: string; skin?: Extract; // defaults to 'general' }; } const getCardWidth = (totalOffers: number) => { if (totalOffers === 1) { return '100%'; } if (totalOffers === 2) { return '50%'; } return '550px'; }; interface MarketingCardInternalProps { schema: MarketingCardSchema; totalOffers: number; offerId: string; } const MarketingCardInternal = forwardRef< HTMLDivElement, MarketingCardInternalProps >(({ schema, totalOffers, offerId }, ref) => { const { title, description: descriptionData, imageUrl, ctaButton: ctaButtonData, badge: badgeData, } = schema; const handleCtaClick = () => { if (ctaButtonData?.link) { window.open(ctaButtonData.link, '_blank'); } }; const handleLearnMoreClick = () => { if (descriptionData?.learnMore?.link) { window.open(descriptionData.learnMore.link, '_blank'); } }; const description = ( <> {descriptionData.text}{' '} {descriptionData.learnMore && ( {descriptionData.learnMore.text ?? 'Learn more'} )} ); const ctaButton = ctaButtonData ? ( ) : null; const badge = badgeData ? ( {badgeData.text} ) : null; const image = ( ); return ( ); }); /** * Creates a render function for marketing cards. * @param transformOffer - Optional function to transform offer data into MarketingCardSchema. * If not provided, uses offer.asset.creative directly. * @returns A render function compatible with Suggestions.renderCard prop. */ export const renderMarketingCard = (transformOffer?: (offer: Offer) => MarketingCardSchema | null) => (props: SuggestionsCardProps): React.ReactElement | null => { const schema = transformOffer ? transformOffer(props.offer) : (props.offer?.asset?.creative as MarketingCardSchema | null); const requiredFieldsExist = schema?.title && schema?.imageUrl && schema?.description?.text; if (!requiredFieldsExist) { console.error( `Can't render MarketingCard for offer ${props.offer.offerGuid} - missing required fields (title, imageUrl, description.text) in schema:`, schema, ); return null; } return ( ); }; /** * Skeleton component for MarketingCard during loading state. */ export const MarketingCardSkeleton: React.FC = ({ totalOffers, }) => { return ( } description={} actions={[]} image={} badge={} hiddenBadge={true} /> ); };