feat: Add segments events (#1001)
Add segments events to track popular and trending recommendations stats. VAN-1569 Co-authored-by: Syed Sajjad Hussain Shah <52817156+syedsajjadkazmii@users.noreply.github.com>
This commit is contained in:
@@ -124,11 +124,11 @@ const ProgressiveProfiling = (props) => {
|
||||
trackRecommendationsGroup(variation, authenticatedUser.userId);
|
||||
setShowRecommendationsPage(showRecommendations);
|
||||
if (!showRecommendations) {
|
||||
trackRecommendationsViewed([], true, authenticatedUser.userId);
|
||||
trackRecommendationsViewed([], '', true, authenticatedUser.userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [authenticatedUser, enablePopularAndTrendingRecommendations, registrationResult, queryParams]);
|
||||
}, [authenticatedUser, enablePopularAndTrendingRecommendations, registrationResult, queryParams?.next]);
|
||||
|
||||
if (
|
||||
!(location.state?.registrationResult || registrationEmbedded)
|
||||
|
||||
@@ -231,8 +231,8 @@ describe('ProgressiveProfilingTests', () => {
|
||||
it('should fire segments recommendations viewed and variation group events', async () => {
|
||||
const viewedEventProperties = {
|
||||
page: 'authn_recommendations',
|
||||
course_key_array: [],
|
||||
amplitude_recommendations: false,
|
||||
products: [],
|
||||
recommendation_type: '',
|
||||
is_control: true,
|
||||
user_id: 3,
|
||||
};
|
||||
|
||||
@@ -6,7 +6,6 @@ import PropTypes from 'prop-types';
|
||||
import { truncateText } from '../../data/utils';
|
||||
|
||||
const BaseCard = ({
|
||||
url,
|
||||
customHeaderImage,
|
||||
schoolLogo,
|
||||
title,
|
||||
@@ -20,7 +19,6 @@ const BaseCard = ({
|
||||
}) => (
|
||||
<div className="mr-4 recommendation-card" key={`container-${uuid}`}>
|
||||
<Hyperlink
|
||||
destination={url}
|
||||
target="_blank"
|
||||
className="card-box"
|
||||
showLaunchIcon={false}
|
||||
@@ -29,7 +27,6 @@ const BaseCard = ({
|
||||
<Card
|
||||
className={`base-card ${variant}`}
|
||||
variant={variant}
|
||||
onClick={handleOnClick}
|
||||
isLoading={isLoading}
|
||||
>
|
||||
<Card.ImageCap
|
||||
@@ -67,7 +64,6 @@ BaseCard.propTypes = {
|
||||
productTypeCopy: PropTypes.string.isRequired,
|
||||
subtitle: PropTypes.string.isRequired,
|
||||
variant: PropTypes.string.isRequired,
|
||||
url: PropTypes.string.isRequired,
|
||||
customHeaderImage: PropTypes.string.isRequired,
|
||||
schoolLogo: PropTypes.string.isRequired,
|
||||
isLoading: PropTypes.bool,
|
||||
|
||||
@@ -9,8 +9,7 @@ import { createCodeFriendlyProduct, getVariant, useProductType } from '../data/u
|
||||
import {
|
||||
cardBadgesMessages,
|
||||
} from '../messages';
|
||||
import { trackRecommendationCardClickOptimizely } from '../optimizelyExperiment';
|
||||
import { trackRecommendationsClicked } from '../track';
|
||||
import { trackRecommendationClick } from '../track';
|
||||
|
||||
const ProductCard = ({
|
||||
product,
|
||||
@@ -64,20 +63,16 @@ const ProductCard = ({
|
||||
],
|
||||
);
|
||||
const handleCardClick = () => {
|
||||
trackRecommendationCardClickOptimizely(userId?.toString());
|
||||
trackRecommendationsClicked(
|
||||
product.courseKey,
|
||||
false,
|
||||
trackRecommendationClick(
|
||||
product,
|
||||
position + 1,
|
||||
false,
|
||||
userId,
|
||||
product.marketingUrl,
|
||||
product.recommendationType || 'algolia',
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<BaseCard
|
||||
url={product.url}
|
||||
customHeaderImage={headerImage}
|
||||
schoolLogo={isMultipleOwner ? '' : schoolLogo}
|
||||
title={product.title}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { useIntl } from '@edx/frontend-platform/i18n';
|
||||
@@ -8,8 +8,10 @@ import {
|
||||
import PropTypes from 'prop-types';
|
||||
import { Helmet } from 'react-helmet';
|
||||
|
||||
import { POPULAR, TRENDING } from './data/constants';
|
||||
import messages from './messages';
|
||||
import RecommendationsList from './RecommendationsList';
|
||||
import { trackRecommendationsViewed } from './track';
|
||||
import { DEFAULT_REDIRECT_URL } from '../data/constants';
|
||||
|
||||
const RecommendationsPage = ({ location }) => {
|
||||
@@ -22,6 +24,10 @@ const RecommendationsPage = ({ location }) => {
|
||||
const POPULAR_PRODUCTS = JSON.parse(getConfig().POPULAR_PRODUCTS);
|
||||
const TRENDING_PRODUCTS = JSON.parse(getConfig().TRENDING_PRODUCTS);
|
||||
|
||||
useEffect(() => {
|
||||
trackRecommendationsViewed(POPULAR_PRODUCTS, POPULAR, false, userId);
|
||||
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
const handleRedirection = () => {
|
||||
window.history.replaceState(location.state, null, '');
|
||||
if (registrationResponse) {
|
||||
@@ -45,6 +51,11 @@ const RecommendationsPage = ({ location }) => {
|
||||
handleRedirection();
|
||||
}
|
||||
|
||||
const handleOnSelect = (tabKey) => {
|
||||
const recommendations = tabKey === POPULAR ? POPULAR_PRODUCTS : TRENDING_PRODUCTS;
|
||||
trackRecommendationsViewed(recommendations, tabKey, false, userId);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
@@ -66,16 +77,17 @@ const RecommendationsPage = ({ location }) => {
|
||||
</h2>
|
||||
<Tabs
|
||||
variant="tabs"
|
||||
defaultActiveKey="popular"
|
||||
defaultActiveKey={POPULAR}
|
||||
id="recommendations-selection"
|
||||
onSelect={handleOnSelect}
|
||||
>
|
||||
<Tab tabClassName="mb-3" eventKey="popular" title={formatMessage(messages['recommendation.option.popular'])}>
|
||||
<Tab tabClassName="mb-3" eventKey={POPULAR} title={formatMessage(messages['recommendation.option.popular'])}>
|
||||
<RecommendationsList
|
||||
recommendations={POPULAR_PRODUCTS}
|
||||
userId={userId}
|
||||
/>
|
||||
</Tab>
|
||||
<Tab tabClassName="mb-3" eventKey="trending" title={formatMessage(messages['recommendation.option.trending'])}>
|
||||
<Tab tabClassName="mb-3" eventKey={TRENDING} title={formatMessage(messages['recommendation.option.trending'])}>
|
||||
<RecommendationsList
|
||||
recommendations={TRENDING_PRODUCTS}
|
||||
userId={userId}
|
||||
|
||||
@@ -9,3 +9,6 @@ export const EDUCATION_LEVEL_MAPPING = {
|
||||
hs: 'Introductory',
|
||||
jhs: 'Introductory',
|
||||
};
|
||||
|
||||
export const POPULAR = 'popular';
|
||||
export const TRENDING = 'trending';
|
||||
|
||||
@@ -3,7 +3,7 @@ import { sendTrackEvent } from '@edx/frontend-platform/analytics';
|
||||
export const LINK_TIMEOUT = 300;
|
||||
|
||||
export const eventNames = {
|
||||
recommendedCourseClicked: 'edx.bi.user.recommended.course.click',
|
||||
recommendedProductClicked: 'edx.bi.user.recommended.product.clicked',
|
||||
recommendationsGroup: 'edx.bi.user.recommendations.group',
|
||||
recommendationsViewed: 'edx.bi.user.recommendations.viewed',
|
||||
};
|
||||
@@ -17,27 +17,36 @@ export const createLinkTracker = (tracker, href, openInNewTab = false) => (e) =>
|
||||
return setTimeout(() => { global.location.href = href; }, LINK_TIMEOUT);
|
||||
};
|
||||
|
||||
export const trackRecommendationsClicked = (courseKey, isControl, position, userId, href, recommendationType) => {
|
||||
createLinkTracker(
|
||||
sendTrackEvent(eventNames.recommendedCourseClicked, {
|
||||
page: 'authn_recommendations',
|
||||
position,
|
||||
recommendation_type: recommendationType,
|
||||
course_key: courseKey,
|
||||
is_control: isControl,
|
||||
user_id: userId,
|
||||
}),
|
||||
href,
|
||||
true,
|
||||
);
|
||||
const generateProductKey = (product) => {
|
||||
const productKey = product.cardType === 'program' ? `${product.title} [${product.uuid}]` : product.activeRunKey;
|
||||
return productKey;
|
||||
};
|
||||
|
||||
export const trackRecommendationsViewed = (recommendedCourseKeys, isControl, userId) => {
|
||||
export const trackRecommendationClick = (product, position, isControl, userId) => {
|
||||
sendTrackEvent(eventNames.recommendedProductClicked, {
|
||||
page: 'authn_recommendations',
|
||||
position,
|
||||
recommendation_type: product.recommendationType,
|
||||
product_key: generateProductKey(product),
|
||||
product_line: product.cardType,
|
||||
product_source: product.productSource.name,
|
||||
is_control: isControl,
|
||||
user_id: userId,
|
||||
});
|
||||
return setTimeout(() => { global.open(product.url, '_blank'); }, LINK_TIMEOUT);
|
||||
};
|
||||
|
||||
export const trackRecommendationsViewed = (recommendedProducts, type, isControl, userId) => {
|
||||
const viewedProductsList = recommendedProducts.map((product) => ({
|
||||
product_key: generateProductKey(product),
|
||||
product_line: product.cardType,
|
||||
product_source: product.productSource.name,
|
||||
}));
|
||||
sendTrackEvent(
|
||||
eventNames.recommendationsViewed, {
|
||||
page: 'authn_recommendations',
|
||||
course_key_array: recommendedCourseKeys,
|
||||
amplitude_recommendations: false,
|
||||
recommendation_type: type,
|
||||
products: viewedProductsList,
|
||||
is_control: isControl,
|
||||
user_id: userId,
|
||||
},
|
||||
@@ -55,7 +64,7 @@ export const trackRecommendationsGroup = (variation, userId) => {
|
||||
};
|
||||
|
||||
export default {
|
||||
trackRecommendationsClicked,
|
||||
trackRecommendationClick,
|
||||
trackRecommendationsGroup,
|
||||
trackRecommendationsViewed,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user