1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-02-09 00:18:00 +01:00

feat: add user tracking to demo (#3637)

https://linear.app/unleash/issue/2-946/explore-and-implement-options-for-user-tracking

Adds user tracking to the interactive demo, so we can measure how users
are using this feature and improve it in the feature.

## Events

- **start** - When the user starts the demo by clicking on the "Try
Unleash Demo" button;
- **finish** - When the user finishes the demo by seeing the "You
finished the demo" dialog;
- **restart** - When the user decides to restart the demo on the "You
finished the demo" dialog;
- **close** - When the user closes a demo dialog;
- **topic** - In what topic this happened (topic title, can also be
`start` if user closes on the start dialog);
- **step** - In what step this happened (step number, `1` would mean
first step);
- **start_topic** - When the user decides to start a specific topic by
clicking it in the list;
  - **topic** - What topic was clicked (topic title);
- **ask_questions** - When the user decides to ask questions by clicking
the appropriate option in the top banner;
- **see_plans** - When the user decides to see the plans by clicking the
appropriate option in the top banner;
- **plan** - What plan was clicked (one of: `open_source`, `pro`,
`enterprise` or `compare_plans`);
- **open_demo_web** - User decided to open the demo website using the
link on the start dialog;
- **view_demo_link** - User decided to open the start dialog again on
the bottom of the topics list;

Relates to [roadmap](https://github.com/orgs/Unleash/projects/10) item:
#3537
This commit is contained in:
Nuno Góis 2023-04-27 14:12:02 +01:00 committed by GitHub
parent 9deff83d74
commit 3c48171c78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 260 additions and 131 deletions

View File

@ -8,6 +8,7 @@ import { DemoDialogFinish } from './DemoDialog/DemoDialogFinish/DemoDialogFinish
import { DemoDialogPlans } from './DemoDialog/DemoDialogPlans/DemoDialogPlans';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { DemoBanner } from './DemoBanner/DemoBanner';
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
const defaultProgress = {
welcomeOpen: true,
@ -22,6 +23,7 @@ interface IDemoProps {
export const Demo = ({ children }: IDemoProps): JSX.Element => {
const { uiConfig } = useUiConfig();
const { trackEvent } = usePlausibleTracker();
const { value: storedProgress, setValue: setStoredProgress } =
createLocalStorage('Tutorial:v1', defaultProgress);
@ -66,6 +68,12 @@ export const Demo = ({ children }: IDemoProps): JSX.Element => {
if (completedSteps === totalSteps) {
setFinishOpen(true);
trackEvent('demo', {
props: {
eventType: 'finish',
},
});
}
};
@ -76,6 +84,12 @@ export const Demo = ({ children }: IDemoProps): JSX.Element => {
<DemoBanner
onPlans={() => {
setPlansOpen(true);
trackEvent('demo', {
props: {
eventType: 'see_plans',
},
});
}}
/>
{children}
@ -84,10 +98,23 @@ export const Demo = ({ children }: IDemoProps): JSX.Element => {
onClose={() => {
setWelcomeOpen(false);
setExpanded(false);
trackEvent('demo', {
props: {
eventType: 'close',
topic: 'start',
},
});
}}
onStart={() => {
setWelcomeOpen(false);
onStart();
trackEvent('demo', {
props: {
eventType: 'start',
},
});
}}
/>
<DemoDialogFinish
@ -99,6 +126,12 @@ export const Demo = ({ children }: IDemoProps): JSX.Element => {
onRestart={() => {
setFinishOpen(false);
onStart();
trackEvent('demo', {
props: {
eventType: 'restart',
},
});
}}
/>
<DemoDialogPlans
@ -117,9 +150,24 @@ export const Demo = ({ children }: IDemoProps): JSX.Element => {
newSteps[topic] = 0;
return newSteps;
});
trackEvent('demo', {
props: {
eventType: 'start_topic',
step: TOPICS[topic].title,
},
});
}}
topics={TOPICS}
onWelcome={() => setWelcomeOpen(true)}
onWelcome={() => {
setWelcomeOpen(true);
trackEvent('demo', {
props: {
eventType: 'view_demo_link',
},
});
}}
/>
<DemoSteps
setExpanded={setExpanded}

View File

@ -1,4 +1,5 @@
import { Button, styled } from '@mui/material';
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
const StyledBanner = styled('div')(({ theme }) => ({
position: 'sticky',
@ -30,17 +31,27 @@ interface IDemoBannerProps {
onPlans: () => void;
}
export const DemoBanner = ({ onPlans }: IDemoBannerProps) => (
export const DemoBanner = ({ onPlans }: IDemoBannerProps) => {
const { trackEvent } = usePlausibleTracker();
return (
<StyledBanner>
<span>
This is a <strong>demo of Unleash</strong>. Play around as much as
you want. Reach out when you're ready.
This is a <strong>demo of Unleash</strong>. Play around as much
as you want. Reach out when you're ready.
</span>
<StyledQuestionsButton
variant="outlined"
sx={{ ml: 1 }}
href="https://slack.unleash.run/"
target="_blank"
onClick={() => {
trackEvent('demo', {
props: {
eventType: 'ask_questions',
},
});
}}
>
Ask questions
</StyledQuestionsButton>
@ -48,4 +59,5 @@ export const DemoBanner = ({ onPlans }: IDemoBannerProps) => (
Get Unleash
</StyledButton>
</StyledBanner>
);
);
};

View File

@ -2,6 +2,7 @@ import { Button, Typography, styled } from '@mui/material';
import { DemoDialog } from '../DemoDialog';
import { GitHub } from '@mui/icons-material';
import { Launch } from '@mui/icons-material';
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
const StyledDemoDialog = styled(DemoDialog)(({ theme }) => ({
'& .MuiDialog-paper': {
@ -51,9 +52,14 @@ interface IDemoDialogPlansProps {
onClose: () => void;
}
export const DemoDialogPlans = ({ open, onClose }: IDemoDialogPlansProps) => (
export const DemoDialogPlans = ({ open, onClose }: IDemoDialogPlansProps) => {
const { trackEvent } = usePlausibleTracker();
return (
<StyledDemoDialog open={open} onClose={onClose}>
<DemoDialog.Header>Want to keep going with Unleash?</DemoDialog.Header>
<DemoDialog.Header>
Want to keep going with Unleash?
</DemoDialog.Header>
<StyledPlans>
<StyledPlan>
<Typography variant="h5" fontWeight="bold">
@ -71,6 +77,14 @@ export const DemoDialogPlans = ({ open, onClose }: IDemoDialogPlansProps) => (
startIcon={<GitHub />}
href="https://github.com/unleash/unleash"
target="_blank"
onClick={() => {
trackEvent('demo', {
props: {
eventType: 'see_plan',
plan: 'open_source',
},
});
}}
>
View project on GitHub
</Button>
@ -80,19 +94,30 @@ export const DemoDialogPlans = ({ open, onClose }: IDemoDialogPlansProps) => (
Pro
</Typography>
<Typography variant="body2" color="textSecondary">
Free your team to collaborate. We'll do the heavy lifting.
Free your team to collaborate. We'll do the heavy
lifting.
</Typography>
<div>
<Typography variant="h6" fontWeight="normal">
$80/month
</Typography>
<Typography variant="body2">includes 5 seats</Typography>
<Typography variant="body2">
includes 5 seats
</Typography>
</div>
<Button
variant="contained"
color="primary"
href="https://www.getunleash.io/plans/pro"
target="_blank"
onClick={() => {
trackEvent('demo', {
props: {
eventType: 'see_plan',
plan: 'pro',
},
});
}}
>
Start 14-day free trial
</Button>
@ -102,7 +127,8 @@ export const DemoDialogPlans = ({ open, onClose }: IDemoDialogPlansProps) => (
Enterprise
</Typography>
<Typography variant="body2" color="textSecondary">
Security, compliance, and development controls for scale.
Security, compliance, and development controls for
scale.
</Typography>
<div>
<Typography variant="h6" fontWeight="normal">
@ -115,6 +141,14 @@ export const DemoDialogPlans = ({ open, onClose }: IDemoDialogPlansProps) => (
color="web"
href="https://www.getunleash.io/plans/enterprise"
target="_blank"
onClick={() => {
trackEvent('demo', {
props: {
eventType: 'see_plan',
plan: 'enterprise',
},
});
}}
>
Contact sales
</Button>
@ -123,8 +157,17 @@ export const DemoDialogPlans = ({ open, onClose }: IDemoDialogPlansProps) => (
<StyledCompareLink
href="https://www.getunleash.io/plans"
target="_blank"
onClick={() => {
trackEvent('demo', {
props: {
eventType: 'see_plan',
plan: 'compare_plans',
},
});
}}
>
Compare plans <Launch />
</StyledCompareLink>
</StyledDemoDialog>
);
);
};

View File

@ -3,6 +3,7 @@ import qrImage from 'assets/img/demo_qr.png';
import { formatAssetPath } from 'utils/formatPath';
import { Launch } from '@mui/icons-material';
import { DemoDialog } from '../DemoDialog';
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
const StyledDemoPane = styled('div')(({ theme }) => ({
display: 'flex',
@ -55,25 +56,38 @@ export const DemoDialogWelcome = ({
open,
onClose,
onStart,
}: IDemoDialogWelcomeProps) => (
}: IDemoDialogWelcomeProps) => {
const { trackEvent } = usePlausibleTracker();
return (
<DemoDialog open={open} onClose={onClose}>
<DemoDialog.Header>Explore Unleash</DemoDialog.Header>
<Typography color="textSecondary" sx={{ mt: 2 }}>
You can explore Unleash on your own, however for the best experience
it's recommended you follow our interactive demo. To get started,
you will need to open the demo website below.
You can explore Unleash on your own, however for the best
experience it's recommended you follow our interactive demo. To
get started, you will need to open the demo website below.
</Typography>
<StyledDemoPane>
<StyledScanMessage>
Scan the QR code with your phone
</StyledScanMessage>
<StyledQRCode src={formatAssetPath(qrImage)} alt="Demo QR Code" />
<StyledQRCode
src={formatAssetPath(qrImage)}
alt="Demo QR Code"
/>
<StyledDivider>OR</StyledDivider>
<Typography>
Open demo website in another tab:{' '}
<StyledLink
href="https://demo.unleash-hosted.com/"
target="_blank"
onClick={() => {
trackEvent('demo', {
props: {
eventType: 'open_demo_web',
},
});
}}
>
demo.unleash-hosted.com <Launch />
</StyledLink>
@ -90,4 +104,5 @@ export const DemoDialogWelcome = ({
Try Unleash demo
</StyledStartButton>
</DemoDialog>
);
);
};

View File

@ -8,6 +8,7 @@ import { ITutorialTopic, ITutorialTopicStep } from '../demo-topics';
import { useEffect, useState } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import { DemoStepTooltip } from './DemoStepTooltip/DemoStepTooltip';
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
interface IDemoStepsProps {
setExpanded: React.Dispatch<React.SetStateAction<boolean>>;
@ -31,6 +32,7 @@ export const DemoSteps = ({
const theme = useTheme();
const navigate = useNavigate();
const location = useLocation();
const { trackEvent } = usePlausibleTracker();
const [run, setRun] = useState(false);
const [flow, setFlow] = useState<'next' | 'back' | 'load'>('load');
@ -51,6 +53,14 @@ export const DemoSteps = ({
const close = () => {
abortController.abort();
setTopicStep(-1);
trackEvent('demo', {
props: {
eventType: 'close',
topic: topics[topic].title,
step: steps[topic] + 1,
},
});
};
const back = () => {

View File

@ -24,7 +24,8 @@ export type CustomEvents =
| 'project_stickiness_set'
| 'notifications'
| 'batch_operations'
| 'strategyTitle';
| 'strategyTitle'
| 'demo';
export const usePlausibleTracker = () => {
const plausible = useContext(PlausibleContext);