diff --git a/frontend/src/component/demo/Demo.tsx b/frontend/src/component/demo/Demo.tsx index 3dafe512e8..cd2384f684 100644 --- a/frontend/src/component/demo/Demo.tsx +++ b/frontend/src/component/demo/Demo.tsx @@ -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 => { { 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', + }, + }); }} /> { onRestart={() => { setFinishOpen(false); onStart(); + + trackEvent('demo', { + props: { + eventType: 'restart', + }, + }); }} /> { 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', + }, + }); + }} /> ({ position: 'sticky', @@ -30,22 +31,33 @@ interface IDemoBannerProps { onPlans: () => void; } -export const DemoBanner = ({ onPlans }: IDemoBannerProps) => ( - - - This is a demo of Unleash. Play around as much as - you want. Reach out when you're ready. - - - Ask questions - - - Get Unleash - - -); +export const DemoBanner = ({ onPlans }: IDemoBannerProps) => { + const { trackEvent } = usePlausibleTracker(); + + return ( + + + This is a demo of Unleash. Play around as much + as you want. Reach out when you're ready. + + { + trackEvent('demo', { + props: { + eventType: 'ask_questions', + }, + }); + }} + > + Ask questions + + + Get Unleash + + + ); +}; diff --git a/frontend/src/component/demo/DemoDialog/DemoDialogPlans/DemoDialogPlans.tsx b/frontend/src/component/demo/DemoDialog/DemoDialogPlans/DemoDialogPlans.tsx index 193adf1749..15361d3416 100644 --- a/frontend/src/component/demo/DemoDialog/DemoDialogPlans/DemoDialogPlans.tsx +++ b/frontend/src/component/demo/DemoDialog/DemoDialogPlans/DemoDialogPlans.tsx @@ -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) => ( - - Want to keep going with Unleash? - - - - Open Source - - - Self-hosted basic feature management solution - - - Free - - - - - - Pro - - - Free your team to collaborate. We'll do the heavy lifting. - -
- - $80/month +export const DemoDialogPlans = ({ open, onClose }: IDemoDialogPlansProps) => { + const { trackEvent } = usePlausibleTracker(); + + return ( + + + Want to keep going with Unleash? + + + + + Open Source - includes 5 seats -
- -
- - - Enterprise - - - Security, compliance, and development controls for scale. - -
- - Custom + + Self-hosted basic feature management solution - unlimited seats -
- -
-
- - Compare plans - -
-); + + Free + + + + + + Pro + + + Free your team to collaborate. We'll do the heavy + lifting. + +
+ + $80/month + + + includes 5 seats + +
+ +
+ + + Enterprise + + + Security, compliance, and development controls for + scale. + +
+ + Custom + + unlimited seats +
+ +
+ + { + trackEvent('demo', { + props: { + eventType: 'see_plan', + plan: 'compare_plans', + }, + }); + }} + > + Compare plans + + + ); +}; diff --git a/frontend/src/component/demo/DemoDialog/DemoDialogWelcome/DemoDialogWelcome.tsx b/frontend/src/component/demo/DemoDialog/DemoDialogWelcome/DemoDialogWelcome.tsx index 204ecc2b1e..e280eba4b1 100644 --- a/frontend/src/component/demo/DemoDialog/DemoDialogWelcome/DemoDialogWelcome.tsx +++ b/frontend/src/component/demo/DemoDialog/DemoDialogWelcome/DemoDialogWelcome.tsx @@ -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) => ( - - Explore Unleash - - 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. - - - - Scan the QR code with your phone - - - OR - - Open demo website in another tab:{' '} - - demo.unleash-hosted.com - +}: IDemoDialogWelcomeProps) => { + const { trackEvent } = usePlausibleTracker(); + + return ( + + Explore Unleash + + 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. - - (we recommend you keep the pages open side by side) - - - - Try Unleash demo - - -); + + + Scan the QR code with your phone + + + OR + + Open demo website in another tab:{' '} + { + trackEvent('demo', { + props: { + eventType: 'open_demo_web', + }, + }); + }} + > + demo.unleash-hosted.com + + + + (we recommend you keep the pages open side by side) + + + + Try Unleash demo + + + ); +}; diff --git a/frontend/src/component/demo/DemoSteps/DemoSteps.tsx b/frontend/src/component/demo/DemoSteps/DemoSteps.tsx index 1d146a5288..24ea044bb5 100644 --- a/frontend/src/component/demo/DemoSteps/DemoSteps.tsx +++ b/frontend/src/component/demo/DemoSteps/DemoSteps.tsx @@ -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>; @@ -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 = () => { diff --git a/frontend/src/hooks/usePlausibleTracker.ts b/frontend/src/hooks/usePlausibleTracker.ts index 8e876cbeb9..b66edb6c19 100644 --- a/frontend/src/hooks/usePlausibleTracker.ts +++ b/frontend/src/hooks/usePlausibleTracker.ts @@ -24,7 +24,8 @@ export type CustomEvents = | 'project_stickiness_set' | 'notifications' | 'batch_operations' - | 'strategyTitle'; + | 'strategyTitle' + | 'demo'; export const usePlausibleTracker = () => { const plausible = useContext(PlausibleContext);