Skip to content

Commit

Permalink
feat: Add tracking to banner button
Browse files Browse the repository at this point in the history
  • Loading branch information
LautaroPetaccio committed Jan 22, 2025
1 parent 25cd94f commit 6995b11
Show file tree
Hide file tree
Showing 11 changed files with 72 additions and 27 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "decentraland-dapps",
"version": "0.0.0-development",
"version": "27.0.2",
"type": "module",
"main": "dist/index.js",
"files": [
Expand All @@ -25,7 +25,7 @@
"decentraland-crypto-fetch": "^2.0.1",
"decentraland-transactions": "^2.18.0",
"decentraland-ui": "^6.11.0",
"decentraland-ui2": "^0.9.2",
"decentraland-ui2": "^0.10.0",
"ethers": "^5.6.8",
"events": "^3.3.0",
"flat": "^5.0.2",
Expand Down
37 changes: 31 additions & 6 deletions src/containers/Banner/Banner.container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,38 @@ import {
getError,
isLoading
} from '../../modules/campaign'
import { getAnalytics } from '../../modules/analytics/utils'
import { MapStateProps, OwnProps } from './Banner.types'
import { sleep } from '../../lib/time'

const mapState = (state: any, ownProps: OwnProps): MapStateProps => ({
fields: getBanner(state, ownProps.id) ?? null,
assets: getBannerAssets(state, ownProps.id),
isLoading: isLoading(state),
error: getError(state)
})
const mapState = (state: any, ownProps: OwnProps): MapStateProps => {
const fields = getBanner(state, ownProps.id) ?? null
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
const anchorEvent = (event as unknown) as React.MouseEvent<
HTMLAnchorElement
>
anchorEvent.preventDefault()

const analytics = getAnalytics()
if (analytics) {
analytics.track('CLICK_BANNER', {
id: fields?.id,
location: ownProps.id
})
}
// Delay the navigation to allow the analytics to be tracked
sleep(300).then(() => {
window.location.href = (anchorEvent.target as HTMLAnchorElement).href
})
}

return {
onClick: handleClick,
fields,
assets: getBannerAssets(state, ownProps.id),
isLoading: isLoading(state),
error: getError(state)
}
}

export default connect<MapStateProps, {}, OwnProps>(mapState)(Banner)
8 changes: 5 additions & 3 deletions src/containers/Banner/Banner.types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { BannerProps as UIBannerProps } from "decentraland-ui2"
import { BannerProps as UIBannerProps } from 'decentraland-ui2'

export type BannerProps = UIBannerProps & { id: string }
export type OwnProps = Pick<BannerProps, 'id'>
export type MapStateProps = Pick<BannerProps, 'fields' | 'assets' | 'isLoading' | 'error'>

export type MapStateProps = Pick<
BannerProps,
'fields' | 'assets' | 'isLoading' | 'error' | 'onClick'
>
6 changes: 6 additions & 0 deletions src/lib/time.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
export function fromMillisecondsToSeconds(timeInMilliseconds: number): number {
return Math.floor(timeInMilliseconds / 1000)
}

export function sleep(delay: number) {
return new Promise(resolve => {
setTimeout(resolve, delay)
})
}
2 changes: 1 addition & 1 deletion src/modules/campaign/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const FETCH_CAMPAIGN_FAILURE = '[Failure] Fetch Campaign'
export const fetchCampaignRequest = () => action(FETCH_CAMPAIGN_REQUEST)

export const fetchCampaignSuccess = (
banners: Record<string, BannerFields>,
banners: Record<string, BannerFields & { id: string }>,
assets: Record<string, ContentfulAsset>,
name?: LocalizedField<string>,
tabName?: LocalizedField<string>,
Expand Down
5 changes: 4 additions & 1 deletion src/modules/campaign/sagas.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ describe('when handling the fetch campaign request', () => {
.put(
fetchCampaignSuccess(
{
marketplaceHomepageBanner: { ...mockHomepageBannerEntry.fields }
marketplaceHomepageBanner: {
...mockHomepageBannerEntry.fields,
id: mockHomepageBannerEntry.sys.id
}
},
{
[marketplaceHomepageBannerAssets[0].sys.id]:
Expand Down
7 changes: 5 additions & 2 deletions src/modules/campaign/sagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,15 @@ export function* campaignSagas(
bannerEntry &&
bannerEntry.sys.contentType.sys.id === BANNER_CONTENT_TYPE
) {
acc[key] = (bannerEntry.fields as unknown) as BannerFields
acc[key] = {
...bannerEntry.fields,
id: linkedEntryId
} as BannerFields & { id: string }
}
}
return acc
},
{} as Record<string, BannerFields>
{} as Record<string, BannerFields & { id: string }>
)

const campaignField = Object.values(items[0].fields).find(field => {
Expand Down
5 changes: 3 additions & 2 deletions src/modules/campaign/selectors.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type MockState = {

let mockState: MockState
let mockAsset: ContentfulAsset
let mockBanner: BannerFields
let mockBanner: BannerFields & { id: string }

describe('Campaign selectors', () => {
beforeEach(() => {
Expand Down Expand Up @@ -68,6 +68,7 @@ describe('Campaign selectors', () => {
}

mockBanner = {
id: 'someId',
fullSizeBackground: {
'en-US': {
sys: {
Expand All @@ -77,7 +78,7 @@ describe('Campaign selectors', () => {
}
}
}
} as BannerFields
} as BannerFields & { id: string }

mockState = {
campaign: {
Expand Down
15 changes: 10 additions & 5 deletions src/modules/campaign/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { isLoadingType, type LoadingState } from '../loading'
import { CampaignState } from './types'
import { FETCH_CAMPAIGN_REQUEST } from './actions'

const isLocalizedField = (value: any): value is LocalizedField<any> => typeof value === 'object' && value !== null && 'en-US' in value

export const getState = (state: any): CampaignState => state.campaign
export const getData = (state: any): CampaignState['data'] | null => getState(state).data
export const getLoading = (state: any): LoadingState => getState(state).loading
Expand All @@ -19,7 +21,7 @@ export const getAllTags = (state: any): string[] => {
}
export const getAssets = (state: any): Record<string, ContentfulAsset> | null => getData(state)?.assets || null
export const getTabName = (state: any): LocalizedField<string> | null => getData(state)?.tabName || null
export const getBanner = (state: any, id: string): BannerFields | null => {
export const getBanner = (state: any, id: string): BannerFields & { id: string } | null => {
return getData(state)?.banners[id] ?? null
}
export const getBannerAssets = (state: any, bannerId: string): Record<string, ContentfulAsset> => {
Expand All @@ -29,10 +31,13 @@ export const getBannerAssets = (state: any, bannerId: string): Record<string, Co
if (!banner) return {}

return Object.entries(banner).reduce((acc, [_, value]) => {
if (isSysLink(value['en-US'])) {
const asset = assets?.[value['en-US'].sys.id]
if (asset) {
acc[value['en-US'].sys.id] = asset
if (isLocalizedField(value)) {
const usLocalizedValue = value['en-US']
if (isSysLink(usLocalizedValue)) {
const asset = assets?.[usLocalizedValue.sys.id]
if (asset) {
acc[usLocalizedValue.sys.id] = asset
}
}
}
return acc
Expand Down
2 changes: 1 addition & 1 deletion src/modules/campaign/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export type CampaignState = {
tabName?: LocalizedField<string>
mainTag?: string
additionalTags?: string[]
banners: Record<string, BannerFields>
banners: Record<string, BannerFields & { id: string }>
assets: Record<string, ContentfulAsset>
} | null
loading: LoadingState
Expand Down

0 comments on commit 6995b11

Please sign in to comment.