Skip to content

Commit

Permalink
feat: [GPR-385][Sale Widget] Add Coins View and Events (#1432)
Browse files Browse the repository at this point in the history
  • Loading branch information
jwhardwick authored Feb 6, 2024
1 parent a5b5a75 commit 5a7bba9
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 14 deletions.
3 changes: 3 additions & 0 deletions packages/checkout/sdk/src/widgets/definitions/events/sale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ export enum SaleEventType {
TRANSACTION_SUCCESS = 'transaction-success',
LANGUAGE_CHANGED = 'language-changed',
PAYMENT_METHOD = 'payment-method',
REQUEST_BRIDGE = 'request-bridge',
REQUEST_ONRAMP = 'request-onramp',
REQUEST_SWAP = 'request-swap',
}

/**
Expand Down
3 changes: 3 additions & 0 deletions packages/checkout/sdk/src/widgets/definitions/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@ export type WidgetEventData = {
[SaleEventType.CLOSE_WIDGET]: {},
[SaleEventType.TRANSACTION_SUCCESS]: SaleTransactionSuccess,
[SaleEventType.PAYMENT_METHOD]: SalePaymentMethod,
[SaleEventType.REQUEST_BRIDGE]: {},
[SaleEventType.REQUEST_SWAP]: {},
[SaleEventType.REQUEST_ONRAMP]: {},
} & OrchestrationMapping & ProviderEventMapping
};

Expand Down
24 changes: 23 additions & 1 deletion packages/checkout/widgets-lib/src/widgets/sale/SaleWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import {
useCallback, useContext, useEffect, useMemo, useReducer, useRef,
} from 'react';

import { BlockExplorerService, ChainId, SaleWidgetParams } from '@imtbl/checkout-sdk';
import {
BlockExplorerService, ChainId, IMTBLWidgetEvents, SaleWidgetParams,
} from '@imtbl/checkout-sdk';
import { Environment } from '@imtbl/config';
import { useTranslation } from 'react-i18next';
import { ConnectLoaderContext } from '../../context/connect-loader-context/ConnectLoaderContext';
Expand All @@ -25,6 +27,10 @@ import { PaymentMethods } from './views/PaymentMethods';
import { SaleErrorView } from './views/SaleErrorView';
import { SaleSuccessView } from './views/SaleSuccessView';
import { CryptoFiatProvider } from '../../context/crypto-fiat-context/CryptoFiatProvider';
import { TopUpView } from '../../views/top-up/TopUpView';
import { UserJourney } from '../../context/analytics-provider/SegmentAnalyticsProvider';
import { sendSaleWidgetCloseEvent } from './SaleWidgetEvents';
import { EventTargetContext } from '../../context/event-target-context/EventTargetContext';

export interface SaleWidgetProps extends Required<Omit<SaleWidgetParams, 'walletProviderName'>> {
config: StrongCheckoutWidgetsConfig;
Expand All @@ -44,6 +50,10 @@ export function SaleWidget(props: SaleWidgetProps) {
const { checkout, provider } = connectLoaderState;
const chainId = useRef<ChainId>();

const {
eventTargetState: { eventTarget },
} = useContext(EventTargetContext);

const { theme } = config;
const biomeTheme = useMemo(() => widgetTheme(theme), [theme]);

Expand Down Expand Up @@ -131,6 +141,18 @@ export function SaleWidget(props: SaleWidgetProps) {
{viewState.view.type === SaleWidgetViews.FUND_WITH_SMART_CHECKOUT && (
<FundWithSmartCheckout subView={viewState.view.subView} />
)}
{viewState.view.type === SharedViews.TOP_UP_VIEW && (
<TopUpView
analytics={{ userJourney: UserJourney.SALE }}
widgetEvent={IMTBLWidgetEvents.IMTBL_SALE_WIDGET_EVENT}
checkout={checkout}
provider={provider}
showOnrampOption={config.isOnRampEnabled}
showSwapOption={config.isSwapEnabled}
showBridgeOption={config.isBridgeEnabled}
onCloseButtonClick={() => sendSaleWidgetCloseEvent(eventTarget)}
/>
)}
</CryptoFiatProvider>
</SaleContextProvider>
</ViewContext.Provider>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import {
} from '@biom3/react';
import { useContext, useEffect } from 'react';

import { SalePaymentTypes } from '@imtbl/checkout-sdk';
import { useTranslation } from 'react-i18next';
import { IMTBLWidgetEvents, SalePaymentTypes } from '@imtbl/checkout-sdk';
import { FooterLogo } from '../../../components/Footer/FooterLogo';
import { HeaderNavigation } from '../../../components/Header/HeaderNavigation';
import { SimpleLayout } from '../../../components/SimpleLayout/SimpleLayout';
Expand All @@ -14,8 +14,6 @@ import {
ViewActions,
ViewContext,
} from '../../../context/view-context/ViewContext';
import { orchestrationEvents } from '../../../lib/orchestrationEvents';
import { EventTargetContext } from '../../../context/event-target-context/EventTargetContext';

import { PaymentOptions } from '../components/PaymentOptions';
import { useSaleContext } from '../context/SaleContextProvider';
Expand All @@ -27,16 +25,13 @@ export function PaymentMethods() {
const { viewState, viewDispatch } = useContext(ViewContext);
const {
sign,
amount,
fromTokenAddress: tokenAddress,
goToErrorView,
paymentMethod,
setPaymentMethod,
disabledPaymentTypes,
invalidParameters,
} = useSaleContext();
const { sendPageView, sendCloseEvent, sendSelectedPaymentMethod } = useSaleEvent();
const { eventTargetState: { eventTarget } } = useContext(EventTargetContext);

const handleOptionClick = (type: SalePaymentTypes) => setPaymentMethod(type);

Expand Down Expand Up @@ -81,6 +76,17 @@ export function PaymentMethods() {
}
}, [paymentMethod]);

const onClickInsufficientCoinsBanner = () => {
viewDispatch({
payload: {
type: ViewActions.UPDATE_VIEW,
view: {
type: SharedViews.TOP_UP_VIEW,
},
},
});
};

const insufficientCoinsBanner = (
<Box sx={{ paddingX: 'base.spacing.x2' }}>
<Banner>
Expand All @@ -90,10 +96,7 @@ export function PaymentMethods() {
<Link
sx={{ mx: 'base.spacing.x1' }}
onClick={
() => orchestrationEvents
.sendRequestBridgeEvent(eventTarget, IMTBLWidgetEvents.IMTBL_SALE_WIDGET_EVENT, {
amount, tokenAddress,
})
() => onClickInsufficientCoinsBanner()
}
>
{t('views.PAYMENT_METHODS.insufficientCoinsBanner.captionCTA')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useEffect, useMemo, useState } from 'react';
import { Environment } from '@imtbl/config';
import { config, passport } from '@imtbl/sdk';
import { WidgetsFactory } from '@imtbl/checkout-widgets';
import { SaleEventType, SaleItem, WidgetTheme, WidgetType } from '@imtbl/checkout-sdk';
import { BridgeEventType, OnRampEventType, SaleEventType, SaleItem, SwapEventType, WidgetTheme, WidgetType } from '@imtbl/checkout-sdk';
import { Checkout } from '@imtbl/checkout-sdk';
import { Passport } from '@imtbl/passport';

Expand Down Expand Up @@ -86,7 +86,16 @@ export function SaleUI() {
const factory = useMemo(() => new WidgetsFactory(checkout, {theme: WidgetTheme.DARK}), [checkout])
const saleWidget = useMemo(() => factory.create(WidgetType.SALE, { config: { theme: WidgetTheme.DARK } }),
[factory, amount, environmentId, fromTokenAddress, collectionName, defaultItems]
)
);
const bridgeWidget = useMemo(() => factory.create(WidgetType.BRIDGE, { config: { theme: WidgetTheme.DARK } }),
[factory, amount, environmentId, fromTokenAddress, collectionName, defaultItems]
);
const swapWidget = useMemo(() => factory.create(WidgetType.SWAP, { config: { theme: WidgetTheme.DARK } }),
[factory, amount, environmentId, fromTokenAddress, collectionName, defaultItems]
);
const onrampWidget = useMemo(() => factory.create(WidgetType.ONRAMP, { config: { theme: WidgetTheme.DARK } }),
[factory, amount, environmentId, fromTokenAddress, collectionName, defaultItems]
);

// mount sale widget and subscribe to close event
useEffect(() => {
Expand All @@ -98,7 +107,29 @@ export function SaleUI() {
items: defaultItems
});
saleWidget.addListener(SaleEventType.CLOSE_WIDGET, () => { saleWidget.unmount()})
}, [saleWidget])

saleWidget.addListener(SaleEventType.REQUEST_BRIDGE, (event) => {
saleWidget.unmount();

bridgeWidget.mount('bridge');
bridgeWidget.addListener(BridgeEventType.CLOSE_WIDGET, () => { bridgeWidget.unmount()})
return;
});
saleWidget.addListener(SaleEventType.REQUEST_SWAP, (event) => {
saleWidget.unmount();

swapWidget.mount('swap');
swapWidget.addListener(SwapEventType.CLOSE_WIDGET, () => { swapWidget.unmount()})
return;
});
saleWidget.addListener(SaleEventType.REQUEST_ONRAMP, (event) => {
saleWidget.unmount();

onrampWidget.mount('onramp');
onrampWidget.addListener(OnRampEventType.CLOSE_WIDGET, () => { onrampWidget.unmount()})
return;
});
}, [saleWidget, swapWidget, bridgeWidget, onrampWidget])

const handlePassportConfigChange = (e: any) => {
setPassportConfig(e.target.value);
Expand Down Expand Up @@ -157,6 +188,9 @@ export function SaleUI() {
return (
<>
<div id="sale"></div>
<div id="bridge"></div>
<div id="swap"></div>
<div id="onramp"></div>
<button onClick={() => saleWidget.mount('sale', {
amount,
environmentId,
Expand Down

0 comments on commit 5a7bba9

Please sign in to comment.