Skip to content

Commit

Permalink
Change logic of the useVIewCartPixel hook (#335)
Browse files Browse the repository at this point in the history
#### What problem is this solving?

The app has problems with pushing view_cart pixel event when
variant="drawer". This problem happens because of the wrong logic of
handling open/close state of the Drawer component. It switches isOpen
from true to false and back when user presses on the Cart Button in the
store front header:
1. User presses on the Cart button --> isOpen changes to true -->
view_cart event is pushed;
2. User presses on the close Drawer button --> nothing changed;
3. User presses on the Cart button --> isOpen changed to false -->
view_cart event is not pushed because isOpen state == false.

To solve this wrong behavior I added onVisibilityChanged callback
function as a property argument to the Drawer component in the drawer
app and made these changes in the minicart app to handle open/close
events properly.

#### How to test it?

In the browser inspector console tab type dataLayer to see events that
have been pushed. It should add view_cart event on every Drawer opening
and when user adds a new product to the cart (at the moment when Drawer
is opening)

https://devalex--dunnesstorespreprod.myvtex.com/

#### Screenshots or example usage:


https://github.com/user-attachments/assets/aff7f680-d649-452a-8837-30242f287454


https://github.com/user-attachments/assets/adeb1c36-71e8-45ca-8778-e6e9e3a419d6

![Снимок экрана 2024-08-02 в 15 13
17](https://github.com/user-attachments/assets/c702ae07-fa85-41ee-9db5-9be349b9cb26)

#### Related PR

vtex-apps/drawer#75
  • Loading branch information
efremov-av authored Aug 14, 2024
1 parent e407f3b commit bcbe843
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 18 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

### Added
- Drawer component onVisibilityChanged property to handle open/close state

### Changed
- Logic of the useViewCartPixel hook

## [2.67.1] - 2023-05-05
### Fixed
- Fixes of i18n on readme.md accorrding to task LOC-10558.
Expand Down
17 changes: 15 additions & 2 deletions react/Minicart.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { FC } from 'react'
import React, { FC, useCallback, useState } from 'react'
import { IconCart } from 'vtex.store-icons'
import { BackdropMode } from 'vtex.store-drawer'
import { useOrderForm } from 'vtex.order-manager/OrderForm'
Expand Down Expand Up @@ -62,9 +62,21 @@ export const Minicart: FC<MinicartProps> = ({
const { orderForm }: OrderFormContext = useOrderForm()

const { variation, open } = useMinicartState()
const [isDrawerOpen, setIsDrawerOpen] = useState(open ?? false)
const { url: checkoutUrl } = useCheckoutURL()

useViewCartPixel(open, orderForm?.items)
const onDrawerVisibilityChanged = useCallback(
(visible: boolean) => {
setIsDrawerOpen(visible)
},
[setIsDrawerOpen]
)

// for Popup it uses "open" and for Drawer it uses "isDrawerOpen" to send view_cart pixel event
useViewCartPixel(
variation === 'drawer' ? isDrawerOpen : open,
orderForm?.items
)

if (variation === 'link') {
return (
Expand Down Expand Up @@ -121,6 +133,7 @@ export const Minicart: FC<MinicartProps> = ({
drawerSlideDirection={drawerSlideDirection}
customPixelEventId={customPixelEventId}
customPixelEventName={customPixelEventName}
onVisibilityChanged={onDrawerVisibilityChanged}
>
{children}
</DrawerMode>
Expand Down
3 changes: 3 additions & 0 deletions react/components/DrawerMode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ interface Props {
backdropMode?: ResponsiveValuesTypes.ResponsiveValue<BackdropMode>
customPixelEventId?: string
customPixelEventName?: PixelEventTypes.EventName
onVisibilityChanged?: (visible: boolean) => void
}

const DrawerMode: FC<Props> = ({
Expand All @@ -31,6 +32,7 @@ const DrawerMode: FC<Props> = ({
backdropMode = 'visible',
customPixelEventId,
customPixelEventName,
onVisibilityChanged,
}) => {
const { handles } = useMinicartCssHandles()

Expand All @@ -41,6 +43,7 @@ const DrawerMode: FC<Props> = ({
slideDirection={drawerSlideDirection}
customPixelEventId={customPixelEventId}
customPixelEventName={customPixelEventName}
onVisibilityChanged={onVisibilityChanged}
customIcon={
<MinicartIconButton
Icon={Icon}
Expand Down
19 changes: 11 additions & 8 deletions react/legacy/__tests__/MiniCartV2.test.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/* eslint-disable global-require */
import React from 'react'
import { render, wait } from '@vtex/test-tools/react'

import { Minicart } from '../../Minicart'
import { MinicartStateContext } from '../../MinicartContext'
import { transformOrderFormItems } from '../../modules/pixelHelper'
Expand All @@ -15,11 +17,13 @@ jest.mock('vtex.order-manager/OrderForm', () => {
const mockData = require('../__fixtures__/orderForm')

return {
useOrderForm: jest.fn(() => ({
orderForm: mockData.default
})).mockImplementationOnce(() => ({
orderForm: []
}))
useOrderForm: jest
.fn(() => ({
orderForm: mockData.default,
}))
.mockImplementationOnce(() => ({
orderForm: [],
})),
}
})

Expand Down Expand Up @@ -55,7 +59,7 @@ describe('<MiniCart /> v2', () => {
expect(mockedUsePixelPush).toHaveBeenCalledWith(expectedPixelEvent)
})

it('should trigger vtex:viewCart when cart is opened and match items when cart is with products', async () => {
it('should trigger vtex:viewCart when cart is opened and match items when cart is with products', async () => {
render(
<MinicartStateContext.Provider value={minicartMockContextValue}>
<Minicart variation="drawer" />
Expand All @@ -73,5 +77,4 @@ describe('<MiniCart /> v2', () => {

expect(mockedUsePixelPush).toHaveBeenCalledWith(expectedPixelEvent)
})

})
})
2 changes: 1 addition & 1 deletion react/modules/pixelHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export function transformOrderFormItems(orderFormItems: OrderForm['items']) {
return orderFormItems.map(item => mapCartItemToPixel(item))
}

interface PixelCartItem {
export interface PixelCartItem {
skuId: string
variant: string
price: number
Expand Down
22 changes: 15 additions & 7 deletions react/modules/useViewCartPixel.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { useEffect } from 'react'
import { useCallback, useEffect } from 'react'
import { usePixel } from 'vtex.pixel-manager'
import { debounce } from 'debounce'

import { transformOrderFormItems } from './pixelHelper'
import { PixelCartItem, transformOrderFormItems } from './pixelHelper'

const useViewCartPixel = (
isOpen: boolean,
Expand All @@ -11,16 +12,23 @@ const useViewCartPixel = (

const transformedItems = transformOrderFormItems(orderFormItems)

const pushViewCart = useCallback(
debounce((items: PixelCartItem[]) => {
push({
event: 'viewCart',
items,
})
}, 1000),
[push]
)

useEffect(() => {
if (!isOpen) {
return
}

push({
event: 'viewCart',
items: transformedItems,
})
}, [push, isOpen, transformedItems])
pushViewCart(transformedItems)
}, [pushViewCart, isOpen, transformedItems])
}

export default useViewCartPixel

0 comments on commit bcbe843

Please sign in to comment.