Skip to content

Commit

Permalink
feat: content tracking example
Browse files Browse the repository at this point in the history
  • Loading branch information
auto200 committed Feb 13, 2024
1 parent 1fb84dd commit 61507dc
Show file tree
Hide file tree
Showing 8 changed files with 236 additions and 0 deletions.
44 changes: 44 additions & 0 deletions example/src/components/ContentTracking/ContentTrackingMethods.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Box, Button, Paper } from '@mui/material'
import { ElementRef, useEffect, useRef } from 'react'
import { ContentTracking } from '@piwikpro/react-piwik-pro'

export function ContentTrackingMethods() {
const ref = useRef<ElementRef<'div'>>(null)

useEffect(() => {
if (!ref.current) return

ContentTracking.trackContentImpressionsWithinNode(ref.current)
ContentTracking.trackContentInteractionNode(ref.current, 'click')
}, [])

return (
<>
<Paper sx={{ p: 2 }}>
<Box
ref={ref}
data-track-content
data-content-name='element'
data-content-piece='slow element'
>
Track content within a specific dom node
</Box>
</Paper>

<Box sx={{ my: 5 }}>
<Button
variant='outlined'
onClick={() =>
ContentTracking.trackContentImpression(
'tracking element',
'button',
'button'
)
}
>
Manual content tracking on demand
</Button>
</Box>
</>
)
}
57 changes: 57 additions & 0 deletions example/src/components/ContentTrackingForm/ContentTrackingForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import Box from '@mui/material/Box'
import Tab from '@mui/material/Tab'
import Tabs from '@mui/material/Tabs'
import { useState } from 'react'
import { Login } from './Login'
import { Register } from './Register'

interface TabPanelProps {
children?: React.ReactNode
index: number
value: number
}

function CustomTabPanel(props: TabPanelProps) {
const { children, value, index, ...other } = props

return (
<div
role='tabpanel'
hidden={value !== index}
id={`simple-tabpanel-${index}`}
aria-labelledby={`simple-tab-${index}`}
{...other}
>
{value === index && <Box sx={{ p: 3 }}>{children}</Box>}
</div>
)
}

export function ContentTrackingForm() {
const [value, setValue] = useState(0)

const handleChange = (_event: React.SyntheticEvent, newValue: number) => {
setValue(newValue)
}

return (
<Box sx={{ width: '100%', maxWidth: '750px' }}>
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
<Tabs
value={value}
onChange={handleChange}
aria-label='basic tabs example'
>
<Tab label='Login' />
<Tab label='Register' />
</Tabs>
</Box>
<CustomTabPanel value={value} index={0}>
<Login />
</CustomTabPanel>
<CustomTabPanel value={value} index={1}>
<Register />
</CustomTabPanel>
</Box>
)
}
22 changes: 22 additions & 0 deletions example/src/components/ContentTrackingForm/Login.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Button, Stack, TextField } from '@mui/material'
import { useEffect } from 'react'
import { ContentTracking } from '@piwikpro/react-piwik-pro'

export function Login() {
// NOTE: candidate for a custom hook useTrackAllContentImpressions()
useEffect(() => {
ContentTracking.trackAllContentImpressions()

return () => ContentTracking.clearTrackedContentImpressions()
}, [])

return (
<Stack gap={2} data-track-content data-content-name='Login form'>
<TextField label='Login' data-content-piece='Login input' />
<TextField label='Password' data-content-piece='Password input' />
<Button variant='contained' data-content-piece='Login button'>
Login
</Button>
</Stack>
)
}
31 changes: 31 additions & 0 deletions example/src/components/ContentTrackingForm/Register.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Button, Stack, TextField } from '@mui/material'
import { ContentTracking } from '@piwikpro/react-piwik-pro'
import { useEffect } from 'react'

export function Register() {
useEffect(() => {
ContentTracking.trackAllContentImpressions()

return () => ContentTracking.clearTrackedContentImpressions()
}, [])

return (
<Stack gap={2} data-track-content data-content-name='Register form'>
<TextField label='Login' data-content-piece='Login input' />
<TextField type='email' label='Email' data-content-piece='Email input' />
<TextField
type='password'
label='Password'
data-content-piece='Password input'
/>
<TextField
type='password'
label='Confirm Password'
data-content-piece='Confirm password input'
/>
<Button variant='contained' data-content-piece='Register button'>
Register
</Button>
</Stack>
)
}
71 changes: 71 additions & 0 deletions example/src/pages/ContentTrackingPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { Box, CircularProgress } from '@mui/material'
import Paper from '@mui/material/Paper'
import Typography from '@mui/material/Typography'
import { FunctionComponent, useEffect, useState } from 'react'
import { ContentTrackingMethods } from '../components/ContentTracking/ContentTrackingMethods'
import { ContentTrackingForm } from '../components/ContentTrackingForm/ContentTrackingForm'

const ContentTrackingPage: FunctionComponent = () => {
const [isLoading, setIsLoading] = useState(true)

useEffect(() => {
document.title = 'Content Tracking'
}, [])

useEffect(() => {
const timeout = setTimeout(() => {
setIsLoading(false)
}, 3000)

return () => {
clearTimeout(timeout)
}
}, [])

return (
<Paper
sx={{
p: 2,
display: 'flex',
flexDirection: 'column'
}}
>
<Typography component='h1' variant='h4' align='center'>
Content Tracking Example
</Typography>

<Box>
<Paper sx={{ p: 5, mt: 5 }}>
<Typography
data-track-content
data-content-name='block'
data-content-piece='paragraph'
data-content-target='target'
>
This element will be tracked automatically if it's present in DOM
before tracking script is loaded and `Interactions with popups and
content` setting is turned on in the administration panel
</Typography>
</Paper>

<Paper sx={{ mt: 5, p: 3 }}>
<Typography>
For content that will appear later in the DOM, like modals or
components that are waiting for data to be loaded, use{' '}
<b>ContentTracking</b> module
</Typography>

<Box sx={{ py: 5 }}>
{isLoading ? <CircularProgress /> : <ContentTrackingMethods />}
</Box>
</Paper>

<Paper sx={{ mt: 3 }}>
<ContentTrackingForm />
</Paper>
</Box>
</Paper>
)
}

export default ContentTrackingPage
6 changes: 6 additions & 0 deletions example/src/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import HomePage from './pages/HomePage.tsx'
import ECommercePage from './pages/ECommercePage.tsx'
import CustomEventPage from './pages/CustomEventPage.tsx'
import GoalConversionsPage from './pages/GoalConversionsPage.tsx'
import ContentTrackingPage from './pages/ContentTrackingPage.tsx'

export const routes = [
{
Expand All @@ -23,5 +24,10 @@ export const routes = [
path: '/goal-conversions',
name: 'Goal Conversions',
element: <GoalConversionsPage />
},
{
path: '/content-tracking',
name: 'Content Tracking',
element: <ContentTrackingPage />
}
]
1 change: 1 addition & 0 deletions src/constants/track-event.constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export enum TRACK_EVENT {
LOG_ALL_CONTENT_BLOCKS_ON_PAGE = 'logAllContentBlocksOnPage',
CONTENT_INTERACTION_NODE = 'trackContentInteractionNode',
CONTENT_INTERACTION = 'trackContentInteraction',
CLEAR_TRACKED_CONTENT_IMPRESSIONS = 'clearTrackedContentImpressions',
LINK = 'trackLink',
ENABLE_LINK_TRACKING = 'enableLinkTracking',
SET_IGNORE_CLASSES = 'setIgnoreClasses',
Expand Down
4 changes: 4 additions & 0 deletions src/services/content-tracking/contentTracking.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,7 @@ export function trackContentInteraction(contentInteraction: string, contentName:
contentTarget
]);
}

export function clearTrackedContentImpressions(){
PaqService.push([TRACK_EVENT.CLEAR_TRACKED_CONTENT_IMPRESSIONS])
}

0 comments on commit 61507dc

Please sign in to comment.