mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2025-06-09 19:31:10 -04:00
feat: [UEPR-177] send user properties and feedback submition data to google analytics
This commit is contained in:
parent
1dd87fdec6
commit
e90aa45e37
11 changed files with 124 additions and 37 deletions
|
@ -7,6 +7,7 @@ import {
|
|||
} from './qualitative_feedback_data.js';
|
||||
import {QualitativeFeedback} from './qualitative_feedback.jsx';
|
||||
import {connect} from 'react-redux';
|
||||
import {triggerAnalyticsEvent} from '../../../lib/google-analytics-utils.js';
|
||||
|
||||
const DebuggingFeedback = ({hideFeedback, isOpen}) => {
|
||||
const onHideFeedback = useCallback(
|
||||
|
@ -14,11 +15,22 @@ const DebuggingFeedback = ({hideFeedback, isOpen}) => {
|
|||
[hideFeedback]
|
||||
);
|
||||
|
||||
const sendGAEvent = useCallback(
|
||||
data =>
|
||||
triggerAnalyticsEvent({
|
||||
event: 'qualitative-feedback',
|
||||
feedbackName: 'Debugging Feedback',
|
||||
feedbackResponse: data
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<QualitativeFeedback
|
||||
feedbackData={QUALITATIVE_FEEDBACK_DATA.debugging}
|
||||
hideFeedback={onHideFeedback}
|
||||
isOpen={isOpen}
|
||||
sendGAEvent={sendGAEvent}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
} from './qualitative_feedback_data.js';
|
||||
import {QualitativeFeedback} from './qualitative_feedback.jsx';
|
||||
import {connect} from 'react-redux';
|
||||
import {triggerAnalyticsEvent} from '../../../lib/google-analytics-utils.js';
|
||||
|
||||
const IdeasGeneratorFeedback = ({hideFeedback, isOpen}) => {
|
||||
const onHideFeedback = useCallback(
|
||||
|
@ -14,11 +15,22 @@ const IdeasGeneratorFeedback = ({hideFeedback, isOpen}) => {
|
|||
[hideFeedback]
|
||||
);
|
||||
|
||||
const sendGAEvent = useCallback(
|
||||
data =>
|
||||
triggerAnalyticsEvent({
|
||||
event: 'qualitative-feedback',
|
||||
feedbackName: 'Ideas Generator Feedback',
|
||||
feedbackResponse: data
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<QualitativeFeedback
|
||||
feedbackData={QUALITATIVE_FEEDBACK_DATA.ideasGenerator}
|
||||
hideFeedback={onHideFeedback}
|
||||
isOpen={isOpen}
|
||||
sendGAEvent={sendGAEvent}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -45,7 +45,7 @@ FeedbackOption.propTypes = {
|
|||
value: PropTypes.string
|
||||
};
|
||||
|
||||
export const QualitativeFeedback = ({feedbackData, hideFeedback, isOpen}) => {
|
||||
export const QualitativeFeedback = ({feedbackData, hideFeedback, isOpen, sendGAEvent}) => {
|
||||
const [displayModal, setDisplayModal] = useState(false);
|
||||
const [_, setFilledFeedback] = useLocalStorage(
|
||||
feedbackData.questionId,
|
||||
|
@ -54,6 +54,7 @@ export const QualitativeFeedback = ({feedbackData, hideFeedback, isOpen}) => {
|
|||
const intl = useIntl();
|
||||
|
||||
const onClose = useCallback(() => {
|
||||
sendGAEvent('closed');
|
||||
setFilledFeedback(true);
|
||||
hideFeedback();
|
||||
setDisplayModal(false);
|
||||
|
@ -63,6 +64,7 @@ export const QualitativeFeedback = ({feedbackData, hideFeedback, isOpen}) => {
|
|||
const onSubmit = useCallback(
|
||||
formData => {
|
||||
if (formData.feedback) {
|
||||
sendGAEvent(formData.feedback);
|
||||
setFilledFeedback(true);
|
||||
hideFeedback();
|
||||
setDisplayModal(false);
|
||||
|
@ -144,5 +146,6 @@ QualitativeFeedback.propTypes = {
|
|||
).isRequired
|
||||
}).isRequired,
|
||||
hideFeedback: PropTypes.func,
|
||||
isOpen: PropTypes.bool
|
||||
isOpen: PropTypes.bool,
|
||||
sendGAEvent: PropTypes.func
|
||||
};
|
||||
|
|
|
@ -7,25 +7,39 @@ import {
|
|||
} from './qualitative_feedback_data.js';
|
||||
import {QualitativeFeedback} from './qualitative_feedback.jsx';
|
||||
import {connect} from 'react-redux';
|
||||
import {triggerAnalyticsEvent} from '../../../lib/google-analytics-utils.js';
|
||||
|
||||
const StarterProjectsFeedback = ({hideFeedback, isOpen}) => {
|
||||
const StarterProjectsFeedback = ({hideFeedback, isOpen, projectName}) => {
|
||||
const onHideFeedback = useCallback(
|
||||
() => hideFeedback(QUALITATIVE_FEEDBACK_QUESTION_ID.starterProjects),
|
||||
[hideFeedback]
|
||||
);
|
||||
|
||||
const sendGAEvent = useCallback(
|
||||
data =>
|
||||
triggerAnalyticsEvent({
|
||||
event: 'qualitative-feedback',
|
||||
feedbackName: 'Starter Projects Feedback',
|
||||
projectName: projectName,
|
||||
feedbackResponse: data
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<QualitativeFeedback
|
||||
feedbackData={QUALITATIVE_FEEDBACK_DATA.starterProjects}
|
||||
hideFeedback={onHideFeedback}
|
||||
isOpen={isOpen}
|
||||
sendGAEvent={sendGAEvent}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
StarterProjectsFeedback.propTypes = {
|
||||
isOpen: PropTypes.bool,
|
||||
hideFeedback: PropTypes.func
|
||||
hideFeedback: PropTypes.func,
|
||||
projectName: PropTypes.string
|
||||
};
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
} from './qualitative_feedback_data.js';
|
||||
import {QualitativeFeedback} from './qualitative_feedback.jsx';
|
||||
import {connect} from 'react-redux';
|
||||
import {triggerAnalyticsEvent} from '../../../lib/google-analytics-utils.js';
|
||||
|
||||
const TutorialsFeedback = ({hideFeedback, isOpen}) => {
|
||||
const onHideFeedback = useCallback(
|
||||
|
@ -14,11 +15,22 @@ const TutorialsFeedback = ({hideFeedback, isOpen}) => {
|
|||
[hideFeedback]
|
||||
);
|
||||
|
||||
const sendGAEvent = useCallback(
|
||||
data =>
|
||||
triggerAnalyticsEvent({
|
||||
event: 'qualitative-feedback',
|
||||
feedbackName: 'Tutorials Feedback',
|
||||
feedbackResponse: data
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<QualitativeFeedback
|
||||
feedbackData={QUALITATIVE_FEEDBACK_DATA.tutorials}
|
||||
hideFeedback={onHideFeedback}
|
||||
isOpen={isOpen}
|
||||
sendGAEvent={sendGAEvent}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
const {isDateInRange, isUserEligible} = require('./user-eligibility');
|
||||
import {sendUserProperties} from './google-analytics-utils';
|
||||
|
||||
const {isDateInRange, isUserEligible, getUserRoles} = require('./user-eligibility');
|
||||
|
||||
const localStorageAvailable =
|
||||
'localStorage' in window && window.localStorage !== null;
|
||||
|
@ -51,3 +53,11 @@ export const shouldDisplayFeedbackWidget = (
|
|||
isUserEligibleForFeedback(user, permissions, feedbackQuestionId, feedbackUserRate) &&
|
||||
isFeedbackDisplayed(feedbacksDisplayed)
|
||||
);
|
||||
|
||||
export const sendUserPropertiesForFeedback = (user, permissions, shouldDisplayFeedback) => {
|
||||
sendUserProperties(
|
||||
user,
|
||||
shouldDisplayFeedback,
|
||||
{userRoles: getUserRoles(permissions)}
|
||||
);
|
||||
};
|
||||
|
|
|
@ -8,10 +8,10 @@ export const triggerAnalyticsEvent = eventVaribles => {
|
|||
});
|
||||
};
|
||||
|
||||
export const sendUserProperties = (user, permissions, eligibilityCheck, userProperties) => {
|
||||
export const sendUserProperties = (user, eligibilityCheck, userProperties) => {
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
|
||||
if (!eligibilityCheck(user, permissions)) {
|
||||
if (!eligibilityCheck) {
|
||||
const nulledUserProperties = Object.keys(userProperties).reduce(
|
||||
(acc, current) => {
|
||||
acc[current] = null;
|
||||
|
@ -21,7 +21,7 @@ export const sendUserProperties = (user, permissions, eligibilityCheck, userProp
|
|||
);
|
||||
|
||||
window.dataLayer.push({
|
||||
testGroup: null,
|
||||
gender: null,
|
||||
ageGroup: null,
|
||||
...nulledUserProperties
|
||||
});
|
||||
|
|
|
@ -49,8 +49,7 @@ export const shouldDisplayOnboarding = (user, permissions) =>
|
|||
export const sendUserPropertiesForOnboarding = (user, permissions) => {
|
||||
sendUserProperties(
|
||||
user,
|
||||
permissions,
|
||||
isUserEligibleForOnboarding,
|
||||
isUserEligibleForOnboarding(user, permissions),
|
||||
{testGroup: onboardingTestGroup(user)}
|
||||
);
|
||||
};
|
||||
|
|
|
@ -36,6 +36,15 @@ export const calculateAgeGroup = (birthYear, birthMonth) => {
|
|||
return '[17+]';
|
||||
};
|
||||
|
||||
export const getUserRoles = permissions => {
|
||||
const permissionsToExclude = ['social', 'mute_status'];
|
||||
|
||||
return Object.keys(permissions)
|
||||
.filter(permissionKey => !permissionsToExclude.includes(permissionKey))
|
||||
.filter(userRole => permissions[userRole])
|
||||
.join(',');
|
||||
};
|
||||
|
||||
export const isUserEligible = (user, permissions, callback = () => true) =>
|
||||
Object.keys(user).length !== 0 &&
|
||||
Object.keys(permissions).length !== 0 &&
|
||||
|
|
|
@ -30,7 +30,7 @@ const {useRef} = require('react');
|
|||
const {
|
||||
QUALITATIVE_FEEDBACK_QUESTION_ID
|
||||
} = require('../../components/modal/feedback/qualitative_feedback_data.js');
|
||||
const {shouldDisplayFeedbackWidget} = require('../../lib/feedback.js');
|
||||
const {shouldDisplayFeedbackWidget, sendUserPropertiesForFeedback} = require('../../lib/feedback.js');
|
||||
|
||||
require('./ideas.scss');
|
||||
|
||||
|
@ -164,17 +164,21 @@ const Ideas = ({
|
|||
addGreenFlagClickListeners(iframe);
|
||||
}
|
||||
};
|
||||
|
||||
const shoulDisplayFeedback = shouldDisplayFeedbackWidget(
|
||||
user,
|
||||
permissions,
|
||||
QUALITATIVE_FEEDBACK_QUESTION_ID.ideasGenerator,
|
||||
process.env.QUALITATIVE_FEEDBACK_IDEAS_GENERATOR_USER_RATE,
|
||||
feedback
|
||||
);
|
||||
|
||||
if (
|
||||
iframe &&
|
||||
shouldDisplayFeedbackWidget(
|
||||
if (iframe && shoulDisplayFeedback) {
|
||||
sendUserPropertiesForFeedback(
|
||||
user,
|
||||
permissions,
|
||||
QUALITATIVE_FEEDBACK_QUESTION_ID.ideasGenerator,
|
||||
process.env.QUALITATIVE_FEEDBACK_IDEAS_GENERATOR_USER_RATE,
|
||||
feedback
|
||||
)
|
||||
) {
|
||||
shoulDisplayFeedback
|
||||
);
|
||||
iframe.addEventListener('load', onIframeLoad);
|
||||
}
|
||||
|
||||
|
@ -193,7 +197,7 @@ const Ideas = ({
|
|||
<div className="banner-wrapper">
|
||||
<iframe
|
||||
ref={iframeRef}
|
||||
src={`${process.env.IDEAS_GENERATOR_SOURCE}/embed`}
|
||||
src={`http://localhost:8333/projects/9999923/embed`}
|
||||
width="485"
|
||||
height="402"
|
||||
allowfullscreen
|
||||
|
|
|
@ -48,7 +48,7 @@ const {sendUserPropertiesForOnboarding, shouldDisplayOnboarding} = require('../.
|
|||
const {triggerAnalyticsEvent} = require('../../lib/google-analytics-utils.js');
|
||||
const {StarterProjectsFeedback} = require('../../components/modal/feedback/starter-projects-feedback.jsx');
|
||||
const {QUALITATIVE_FEEDBACK_QUESTION_ID} = require('../../components/modal/feedback/qualitative_feedback_data.js');
|
||||
const {shouldDisplayFeedbackWidget} = require('../../lib/feedback.js');
|
||||
const {shouldDisplayFeedbackWidget, sendUserPropertiesForFeedback} = require('../../lib/feedback.js');
|
||||
const {displayQualitativeFeedback} = require('../../redux/qualitative-feedback.js');
|
||||
const {DebuggingFeedback} = require('../../components/modal/feedback/debugging-feedback.jsx');
|
||||
const {TutorialsFeedback} = require('../../components/modal/feedback/tutorials-feedback.jsx');
|
||||
|
@ -73,15 +73,20 @@ const IntlGUIWithProjectHandler = ({...props}) => {
|
|||
}, [props.projectId, prevProjectId, props.user, props.permissions]);
|
||||
|
||||
const displayGuiFeedback = useCallback((feedbackQuestionId, feedbackUserRate) => {
|
||||
if (
|
||||
shouldDisplayFeedbackWidget(
|
||||
const shoulDisplayFeedback = shouldDisplayFeedbackWidget(
|
||||
props.user,
|
||||
props.permissions,
|
||||
feedbackQuestionId,
|
||||
feedbackUserRate,
|
||||
props.feedback
|
||||
);
|
||||
|
||||
if (shoulDisplayFeedback) {
|
||||
sendUserPropertiesForFeedback(
|
||||
props.user,
|
||||
props.permissions,
|
||||
feedbackQuestionId,
|
||||
feedbackUserRate,
|
||||
props.feedback
|
||||
)
|
||||
) {
|
||||
shoulDisplayFeedback
|
||||
);
|
||||
props.displayFeedback(feedbackQuestionId);
|
||||
}
|
||||
}, [props.user, props.permissions, props.feedback, props.displayFeedback]);
|
||||
|
@ -300,17 +305,22 @@ class Preview extends React.Component {
|
|||
sendUserPropertiesForOnboarding(this.props.user, this.props.permissions);
|
||||
|
||||
const fromStarterProjectsPage = queryString.parse(location.search).fromStarterProjectsPage === 'true';
|
||||
if (
|
||||
fromStarterProjectsPage &&
|
||||
shouldDisplayFeedbackWidget(
|
||||
const shoulDisplayFeedback = shouldDisplayFeedbackWidget(
|
||||
this.props.user,
|
||||
this.props.permissions,
|
||||
QUALITATIVE_FEEDBACK_QUESTION_ID.starterProjects,
|
||||
process.env.QUALITATIVE_FEEDBACK_STARTER_PROJECTS_USER_RATE,
|
||||
this.props.feedback
|
||||
);
|
||||
if (fromStarterProjectsPage && shoulDisplayFeedback) {
|
||||
sendUserPropertiesForFeedback(
|
||||
this.props.user,
|
||||
this.props.permissions,
|
||||
QUALITATIVE_FEEDBACK_QUESTION_ID.starterProjects,
|
||||
process.env.QUALITATIVE_FEEDBACK_STARTER_PROJECTS_USER_RATE,
|
||||
this.props.feedback
|
||||
)
|
||||
) {
|
||||
this.props.displayFeedback(QUALITATIVE_FEEDBACK_QUESTION_ID.starterProjects);
|
||||
shoulDisplayFeedback
|
||||
);
|
||||
this.props.displayFeedback(
|
||||
QUALITATIVE_FEEDBACK_QUESTION_ID.starterProjects
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -876,6 +886,7 @@ class Preview extends React.Component {
|
|||
>
|
||||
<StarterProjectsFeedback
|
||||
isOpen={this.props.feedback[QUALITATIVE_FEEDBACK_QUESTION_ID.starterProjects]}
|
||||
projectName={this.props.projectInfo.title}
|
||||
/>
|
||||
<PreviewPresentation
|
||||
addToStudioOpen={this.state.addToStudioOpen}
|
||||
|
@ -978,6 +989,7 @@ class Preview extends React.Component {
|
|||
<>
|
||||
<StarterProjectsFeedback
|
||||
isOpen={this.props.feedback[QUALITATIVE_FEEDBACK_QUESTION_ID.starterProjects]}
|
||||
projectName={this.props.projectInfo.title}
|
||||
/>
|
||||
<IntlGUIWithProjectHandler
|
||||
assetHost={this.props.assetHost}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue