Skip to content

Commit

Permalink
feat: Add IntersectionObserver to PayPalButton and PlaceOrderButton
Browse files Browse the repository at this point in the history
  • Loading branch information
julianajlk committed Nov 5, 2024
1 parent b8fae94 commit 793ce67
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 12 deletions.
47 changes: 45 additions & 2 deletions src/payment/checkout/payment-form/PlaceOrderButton.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import React from 'react';
import React, { useEffect, useRef } from 'react';
import { useDispatch } from 'react-redux';
import PropTypes from 'prop-types';
import { injectIntl, FormattedMessage } from '@edx/frontend-platform/i18n';
import { StatefulButton } from '@openedx/paragon';
import { trackElementIntersection } from '../../data/actions';
import { ElementType, PaymentTitle, IS_FULLY_SHOWN_THRESHOLD_OR_MARGIN } from '../../../cohesion/constants';

const PlaceOrderButton = ({
showLoadingButton, onSubmitButtonClick, stripeSelectedPaymentMethod, disabled, isProcessing,
Expand All @@ -12,9 +15,49 @@ const PlaceOrderButton = ({
// istanbul ignore if
if (isProcessing) { submitButtonState = 'processing'; }

const buttonRef = useRef(null);
const dispatch = useDispatch();

// RV event tracking for Place Order Button
useEffect(() => {
const observerCallback = (entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const tagularElement = {
title: PaymentTitle,
url: window.location.href,
pageType: 'checkout',
elementType: ElementType.Button,
position: 'placeOrderButton',
name: 'stripe',
text: 'Stripe',
};
dispatch(trackElementIntersection(tagularElement));
}
});
};

const observer = new IntersectionObserver(observerCallback, {
threshold: IS_FULLY_SHOWN_THRESHOLD_OR_MARGIN,
});

const currentElement = buttonRef.current;

if (currentElement) {
observer.observe(currentElement);
}

return () => {
if (currentElement) {
observer.unobserve(currentElement);
}
observer.disconnect();
};
}, [dispatch]);

return (
<div className="col-lg-6 form-group float-right">
<div className="row justify-content-end mt-4">
<div className="row justify-content-end mt-4" ref={buttonRef}>
{
showLoadingButton ? (
<div className="skeleton btn btn-block btn-lg">&nbsp;</div>
Expand Down
66 changes: 56 additions & 10 deletions src/payment/payment-methods/paypal/PayPalButton.jsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,65 @@
import React from 'react';
import React, { useEffect, useRef } from 'react';
import { useDispatch } from 'react-redux';
import PropTypes from 'prop-types';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { trackElementIntersection } from '../../data/actions';
import { ElementType, PaymentTitle, IS_FULLY_SHOWN_THRESHOLD_OR_MARGIN } from '../../../cohesion/constants';

import PayPalLogo from './assets/paypal-logo.png';
import messages from './PayPalButton.messages';

const PayPalButton = ({ intl, isProcessing, ...props }) => (
<button type="button" {...props}>
{ isProcessing ? <span className="button-spinner-icon text-primary mr-2" /> : null }
<img
src={PayPalLogo}
alt={intl.formatMessage(messages['payment.type.paypal'])}
/>
</button>
);
const PayPalButton = ({ intl, isProcessing, ...props }) => {
const buttonRef = useRef(null);
const dispatch = useDispatch();

// RV event tracking for PayPal Button
useEffect(() => {
const observerCallback = (entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const elementId = entry.target?.id;
const tagularElement = {
title: PaymentTitle,
url: window.location.href,
pageType: 'checkout',
elementType: ElementType.Button,
position: elementId,
name: 'paypal',
text: 'PayPal',
};
dispatch(trackElementIntersection(tagularElement));
}
});
};

const observer = new IntersectionObserver(observerCallback, {
threshold: IS_FULLY_SHOWN_THRESHOLD_OR_MARGIN,
});

const currentElement = buttonRef.current;

if (currentElement) {
observer.observe(currentElement);
}

return () => {
if (currentElement) {
observer.unobserve(currentElement);
}
observer.disconnect();
};
}, [dispatch]);

return (
<button type="button" {...props} ref={buttonRef}>
{ isProcessing ? <span className="button-spinner-icon text-primary mr-2" /> : null }
<img
src={PayPalLogo}
alt={intl.formatMessage(messages['payment.type.paypal'])}
/>
</button>
);
};

PayPalButton.propTypes = {
intl: intlShape.isRequired,
Expand Down

0 comments on commit 793ce67

Please sign in to comment.