import { ClubOfferData, PurchaseFromCatalogComposer } from '@nitrots/nitro-renderer'; import { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { CatalogPurchaseState, LocalizeText, SanitizeHtml, SendMessageComposer } from '../../../../../api'; import { Button, Column, Flex, Grid, LayoutCurrencyIcon, LayoutGridItem, LayoutLoadingSpinnerView, Text } from '../../../../../common'; import { CatalogEvent, CatalogPurchaseFailureEvent, CatalogPurchasedEvent } from '../../../../../events'; import { useCatalogData, useClubOffers, usePurse, useUiEvent } from '../../../../../hooks'; import { CatalogHeaderView } from '../../catalog-header/CatalogHeaderView'; import { CatalogLayoutProps } from './CatalogLayout.types'; const BUILDERS_CLUB_WINDOW_ID = 2; const BUILDERS_CLUB_ADDONS_WINDOW_ID = 3; export const CatalogLayoutBuildersClubBuyView: FC = () => { const [ pendingOffer, setPendingOffer ] = useState(null); const [ purchaseState, setPurchaseState ] = useState(CatalogPurchaseState.NONE); const { currentPage = null } = useCatalogData(); const { getCurrencyAmount = null } = usePurse(); const isPurchasingRef = useRef(false); const isAddonLayout = (currentPage?.layoutCode === 'builders_club_addons'); const windowId = (isAddonLayout ? BUILDERS_CLUB_ADDONS_WINDOW_ID : BUILDERS_CLUB_WINDOW_ID); const { data: offers = null } = useClubOffers(windowId); const onCatalogEvent = useCallback((event: CatalogEvent) => { switch(event.type) { case CatalogPurchasedEvent.PURCHASE_SUCCESS: isPurchasingRef.current = false; setPurchaseState(CatalogPurchaseState.NONE); return; case CatalogPurchaseFailureEvent.PURCHASE_FAILED: isPurchasingRef.current = false; setPurchaseState(CatalogPurchaseState.FAILED); return; } }, []); useUiEvent(CatalogPurchasedEvent.PURCHASE_SUCCESS, onCatalogEvent); useUiEvent(CatalogPurchaseFailureEvent.PURCHASE_FAILED, onCatalogEvent); const getOfferTotalUnits = useCallback((offer: ClubOfferData) => { if(!offer) return 0; return ((offer.months * 31) + offer.extraDays); }, []); const getOfferName = useCallback((offer: ClubOfferData) => { if(!offer) return ''; const localized = LocalizeText(offer.productCode); if(localized && (localized !== offer.productCode)) return localized; return offer.productCode.replace(/_/g, ' '); }, []); const getOfferMeta = useCallback((offer: ClubOfferData) => { if(!offer) return ''; if(isAddonLayout) { const units = getOfferTotalUnits(offer); return (units > 0) ? `+${ units }` : ''; } const parts: string[] = []; if(offer.months > 0) parts.push(LocalizeText('catalog.vip.item.header.months', [ 'num_months' ], [ offer.months.toString() ])); if(offer.extraDays > 0) parts.push(LocalizeText('catalog.vip.item.header.days', [ 'num_days' ], [ offer.extraDays.toString() ])); return parts.join(' '); }, [ getOfferTotalUnits, isAddonLayout ]); const purchaseOffer = useCallback(() => { if(!pendingOffer || !currentPage || isPurchasingRef.current) return; isPurchasingRef.current = true; setPurchaseState(CatalogPurchaseState.PURCHASE); SendMessageComposer(new PurchaseFromCatalogComposer(currentPage.pageId, pendingOffer.offerId, null, 1)); }, [ pendingOffer, currentPage ]); const getPurchaseButton = useCallback(() => { if(!pendingOffer) return null; if(pendingOffer.priceCredits > getCurrencyAmount(-1)) { return ; } if(pendingOffer.priceActivityPoints > getCurrencyAmount(pendingOffer.priceActivityPointsType)) { return ; } switch(purchaseState) { case CatalogPurchaseState.CONFIRM: return ; case CatalogPurchaseState.PURCHASE: return ; case CatalogPurchaseState.FAILED: return ; case CatalogPurchaseState.NONE: default: return ; } }, [ getCurrencyAmount, pendingOffer, purchaseOffer, purchaseState ]); const pageDescription = useMemo(() => { if(!currentPage) return ''; return currentPage.localization.getText(1) || currentPage.localization.getText(2) || currentPage.localization.getText(0) || ''; }, [ currentPage ]); useEffect(() => { if(!offers || !offers.length) return; setPendingOffer(prevValue => { if(prevValue && offers.some(offer => (offer.offerId === prevValue.offerId))) return prevValue; return offers[0]; }); }, [ offers ]); return (
{ currentPage?.localization?.getImage(0) && } { offers && (offers.length > 0) && offers.map((offer, index) => { const meta = getOfferMeta(offer); return ( { setPurchaseState(CatalogPurchaseState.NONE); setPendingOffer(offer); } }> { getOfferName(offer) } { meta.length > 0 && { meta } }
{ (offer.priceCredits > 0) && { offer.priceCredits } } { (offer.priceActivityPoints > 0) && { offer.priceActivityPoints } }
); }) }
{ currentPage?.localization.getImage(1) && } { pageDescription.length > 0 && } { pendingOffer && { getOfferName(pendingOffer) } { getOfferMeta(pendingOffer).length > 0 && { getOfferMeta(pendingOffer) } } { currentPage?.localization.getText(0) || '' }
{ (pendingOffer.priceCredits > 0) && { pendingOffer.priceCredits } } { (pendingOffer.priceActivityPoints > 0) && { pendingOffer.priceActivityPoints } }
{ getPurchaseButton() }
}
); };