mirror of
https://github.com/Unleash/unleash.git
synced 2025-02-04 00:18:01 +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:
parent
9deff83d74
commit
3c48171c78
@ -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}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Button, styled } from '@mui/material';
|
||||
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
|
||||
|
||||
const StyledBanner = styled('div')(({ theme }) => ({
|
||||
position: 'sticky',
|
||||
@ -30,22 +31,33 @@ interface IDemoBannerProps {
|
||||
onPlans: () => void;
|
||||
}
|
||||
|
||||
export const DemoBanner = ({ onPlans }: IDemoBannerProps) => (
|
||||
<StyledBanner>
|
||||
<span>
|
||||
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"
|
||||
>
|
||||
Ask questions
|
||||
</StyledQuestionsButton>
|
||||
<StyledButton variant="contained" color="primary" onClick={onPlans}>
|
||||
Get Unleash
|
||||
</StyledButton>
|
||||
</StyledBanner>
|
||||
);
|
||||
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.
|
||||
</span>
|
||||
<StyledQuestionsButton
|
||||
variant="outlined"
|
||||
sx={{ ml: 1 }}
|
||||
href="https://slack.unleash.run/"
|
||||
target="_blank"
|
||||
onClick={() => {
|
||||
trackEvent('demo', {
|
||||
props: {
|
||||
eventType: 'ask_questions',
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
Ask questions
|
||||
</StyledQuestionsButton>
|
||||
<StyledButton variant="contained" color="primary" onClick={onPlans}>
|
||||
Get Unleash
|
||||
</StyledButton>
|
||||
</StyledBanner>
|
||||
);
|
||||
};
|
||||
|
@ -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,80 +52,122 @@ interface IDemoDialogPlansProps {
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
export const DemoDialogPlans = ({ open, onClose }: IDemoDialogPlansProps) => (
|
||||
<StyledDemoDialog open={open} onClose={onClose}>
|
||||
<DemoDialog.Header>Want to keep going with Unleash?</DemoDialog.Header>
|
||||
<StyledPlans>
|
||||
<StyledPlan>
|
||||
<Typography variant="h5" fontWeight="bold">
|
||||
Open Source
|
||||
</Typography>
|
||||
<Typography variant="body2" color="textSecondary">
|
||||
Self-hosted basic feature management solution
|
||||
</Typography>
|
||||
<Typography variant="h6" fontWeight="normal">
|
||||
Free
|
||||
</Typography>
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
startIcon={<GitHub />}
|
||||
href="https://github.com/unleash/unleash"
|
||||
target="_blank"
|
||||
>
|
||||
View project on GitHub
|
||||
</Button>
|
||||
</StyledPlan>
|
||||
<StyledPlan>
|
||||
<Typography variant="h5" fontWeight="bold">
|
||||
Pro
|
||||
</Typography>
|
||||
<Typography variant="body2" color="textSecondary">
|
||||
Free your team to collaborate. We'll do the heavy lifting.
|
||||
</Typography>
|
||||
<div>
|
||||
<Typography variant="h6" fontWeight="normal">
|
||||
$80/month
|
||||
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>
|
||||
<StyledPlans>
|
||||
<StyledPlan>
|
||||
<Typography variant="h5" fontWeight="bold">
|
||||
Open Source
|
||||
</Typography>
|
||||
<Typography variant="body2">includes 5 seats</Typography>
|
||||
</div>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
href="https://www.getunleash.io/plans/pro"
|
||||
target="_blank"
|
||||
>
|
||||
Start 14-day free trial
|
||||
</Button>
|
||||
</StyledPlan>
|
||||
<StyledPlan>
|
||||
<Typography variant="h5" fontWeight="bold">
|
||||
Enterprise
|
||||
</Typography>
|
||||
<Typography variant="body2" color="textSecondary">
|
||||
Security, compliance, and development controls for scale.
|
||||
</Typography>
|
||||
<div>
|
||||
<Typography variant="h6" fontWeight="normal">
|
||||
Custom
|
||||
<Typography variant="body2" color="textSecondary">
|
||||
Self-hosted basic feature management solution
|
||||
</Typography>
|
||||
<Typography variant="body2">unlimited seats</Typography>
|
||||
</div>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="web"
|
||||
href="https://www.getunleash.io/plans/enterprise"
|
||||
target="_blank"
|
||||
>
|
||||
Contact sales
|
||||
</Button>
|
||||
</StyledPlan>
|
||||
</StyledPlans>
|
||||
<StyledCompareLink
|
||||
href="https://www.getunleash.io/plans"
|
||||
target="_blank"
|
||||
>
|
||||
Compare plans <Launch />
|
||||
</StyledCompareLink>
|
||||
</StyledDemoDialog>
|
||||
);
|
||||
<Typography variant="h6" fontWeight="normal">
|
||||
Free
|
||||
</Typography>
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
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>
|
||||
</StyledPlan>
|
||||
<StyledPlan>
|
||||
<Typography variant="h5" fontWeight="bold">
|
||||
Pro
|
||||
</Typography>
|
||||
<Typography variant="body2" color="textSecondary">
|
||||
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>
|
||||
</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>
|
||||
</StyledPlan>
|
||||
<StyledPlan>
|
||||
<Typography variant="h5" fontWeight="bold">
|
||||
Enterprise
|
||||
</Typography>
|
||||
<Typography variant="body2" color="textSecondary">
|
||||
Security, compliance, and development controls for
|
||||
scale.
|
||||
</Typography>
|
||||
<div>
|
||||
<Typography variant="h6" fontWeight="normal">
|
||||
Custom
|
||||
</Typography>
|
||||
<Typography variant="body2">unlimited seats</Typography>
|
||||
</div>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="web"
|
||||
href="https://www.getunleash.io/plans/enterprise"
|
||||
target="_blank"
|
||||
onClick={() => {
|
||||
trackEvent('demo', {
|
||||
props: {
|
||||
eventType: 'see_plan',
|
||||
plan: 'enterprise',
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
Contact sales
|
||||
</Button>
|
||||
</StyledPlan>
|
||||
</StyledPlans>
|
||||
<StyledCompareLink
|
||||
href="https://www.getunleash.io/plans"
|
||||
target="_blank"
|
||||
onClick={() => {
|
||||
trackEvent('demo', {
|
||||
props: {
|
||||
eventType: 'see_plan',
|
||||
plan: 'compare_plans',
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
Compare plans <Launch />
|
||||
</StyledCompareLink>
|
||||
</StyledDemoDialog>
|
||||
);
|
||||
};
|
||||
|
@ -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,39 +56,53 @@ export const DemoDialogWelcome = ({
|
||||
open,
|
||||
onClose,
|
||||
onStart,
|
||||
}: IDemoDialogWelcomeProps) => (
|
||||
<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.
|
||||
</Typography>
|
||||
<StyledDemoPane>
|
||||
<StyledScanMessage>
|
||||
Scan the QR code with your phone
|
||||
</StyledScanMessage>
|
||||
<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"
|
||||
>
|
||||
demo.unleash-hosted.com <Launch />
|
||||
</StyledLink>
|
||||
}: 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.
|
||||
</Typography>
|
||||
<Typography color="textSecondary">
|
||||
(we recommend you keep the pages open side by side)
|
||||
</Typography>
|
||||
</StyledDemoPane>
|
||||
<StyledStartButton
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={onStart}
|
||||
>
|
||||
Try Unleash demo
|
||||
</StyledStartButton>
|
||||
</DemoDialog>
|
||||
);
|
||||
<StyledDemoPane>
|
||||
<StyledScanMessage>
|
||||
Scan the QR code with your phone
|
||||
</StyledScanMessage>
|
||||
<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>
|
||||
</Typography>
|
||||
<Typography color="textSecondary">
|
||||
(we recommend you keep the pages open side by side)
|
||||
</Typography>
|
||||
</StyledDemoPane>
|
||||
<StyledStartButton
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={onStart}
|
||||
>
|
||||
Try Unleash demo
|
||||
</StyledStartButton>
|
||||
</DemoDialog>
|
||||
);
|
||||
};
|
||||
|
@ -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 = () => {
|
||||
|
@ -24,7 +24,8 @@ export type CustomEvents =
|
||||
| 'project_stickiness_set'
|
||||
| 'notifications'
|
||||
| 'batch_operations'
|
||||
| 'strategyTitle';
|
||||
| 'strategyTitle'
|
||||
| 'demo';
|
||||
|
||||
export const usePlausibleTracker = () => {
|
||||
const plausible = useContext(PlausibleContext);
|
||||
|
Loading…
Reference in New Issue
Block a user