@graphcommerce/google-datalayer 8.0.5-canary.0 → 8.0.5-canary.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/Config.graphqls +5 -13
  3. package/README.md +2 -3
  4. package/api/sendEvent.ts +50 -0
  5. package/components/DatalayerViewItemList.tsx +45 -0
  6. package/index.ts +1 -0
  7. package/mapping/cartItemToDatalayerItem/CartItem_DatalayerItem.graphql +31 -0
  8. package/mapping/cartItemToDatalayerItem/cartItemToDatalayerItem.ts +27 -0
  9. package/mapping/cartItemToRemoveFromCart/CartItem_RemoveFromCart.graphql +3 -0
  10. package/mapping/cartItemToRemoveFromCart/cartToRemoveFromCart.ts +13 -0
  11. package/mapping/cartToAddPaymentInfo/Cart_AddPaymentInfo.graphql +10 -0
  12. package/mapping/cartToAddPaymentInfo/cartToAddPaymentInfo.ts +10 -0
  13. package/mapping/cartToAddShippingInfo/Cart_AddShippingInfo.graphql +12 -0
  14. package/mapping/cartToAddShippingInfo/cartToAddShippingInfo.ts +15 -0
  15. package/mapping/cartToBeginCheckout/Cart_BeginCheckout.graphql +6 -0
  16. package/mapping/cartToBeginCheckout/cartToBeginCheckout.ts +9 -0
  17. package/mapping/cartToDatalayerItems/Cart_DatalayerItems.graphql +11 -0
  18. package/mapping/cartToDatalayerItems/cartToDatalayerItems.ts +10 -0
  19. package/mapping/cartToViewCart/Cart_ViewCart.graphql +4 -0
  20. package/mapping/cartToViewCart/cartToViewCart.ts +6 -0
  21. package/mapping/datalayerItemsToCurrencyValue/datalayerItemsToCurrencyValue.ts +8 -0
  22. package/mapping/orderToPurchase/orderToPurchase.ts +17 -0
  23. package/mapping/productItemsToViewItemList/productItemsToViewItemList.ts +22 -0
  24. package/{lib/productToItem/ProductToItem.graphql → mapping/productToDatalayerItem/Product_DatalayerItem.graphql} +3 -6
  25. package/{lib/productToItem/productToItem.ts → mapping/productToDatalayerItem/productToDatalayerItem.ts} +17 -9
  26. package/mapping/productToViewItem/Product_ViewItem.graphql +3 -0
  27. package/mapping/productToViewItem/productToViewItem.ts +11 -0
  28. package/package.json +12 -11
  29. package/plugins/GoogleDatalayerAddProductsToCartForm.tsx +33 -4
  30. package/plugins/GoogleDatalayerCartStartCheckout.tsx +17 -3
  31. package/plugins/GoogleDatalayerCartStartCheckoutLinkOrButton.tsx +4 -14
  32. package/plugins/GoogleDatalayerPaymentMethodButton.tsx +6 -4
  33. package/plugins/GoogleDatalayerPaymentMethodContextProvider.tsx +4 -2
  34. package/plugins/GoogleDatalayerProductListItem.tsx +7 -8
  35. package/plugins/GoogleDatalayerProductListItemsBase.tsx +4 -4
  36. package/plugins/GoogleDatalayerRemoveItemFromCart.tsx +13 -10
  37. package/plugins/GoogleDatalayerRemoveItemFromCartFab.tsx +9 -8
  38. package/plugins/GoogleDatalayerShippingMethodForm.tsx +10 -4
  39. package/plugins/GoogleDatalayerUpdateItemQuantity.tsx +15 -32
  40. package/plugins/GoogleDatalayerViewItem.tsx +5 -13
  41. package/plugins/GoogleDatalayerWebVitals.tsx +40 -0
  42. package/components/AnalyticsItemList.tsx +0 -63
  43. package/events/add_payment_info/AddPaymentInfoFragment.graphql +0 -36
  44. package/events/add_payment_info/addPaymentInfo.ts +0 -23
  45. package/events/add_payment_info/index.ts +0 -2
  46. package/events/add_shipping_info/AddSchippingInfoFragment.graphql +0 -38
  47. package/events/add_shipping_info/addShippingInfo.ts +0 -22
  48. package/events/add_shipping_info/index.ts +0 -2
  49. package/events/add_to_cart/AddToCartFragment.graphql +0 -30
  50. package/events/add_to_cart/addToCart.ts +0 -58
  51. package/events/add_to_cart/index.ts +0 -2
  52. package/events/begin_checkout/BeginCheckoutFragment.graphql +0 -38
  53. package/events/begin_checkout/beginCheckout.ts +0 -22
  54. package/events/begin_checkout/index.ts +0 -2
  55. package/events/purchase/index.ts +0 -1
  56. package/events/purchase/purchase.ts +0 -27
  57. package/events/remove_from_cart/RemoveFromCartFragment.graphql +0 -36
  58. package/events/remove_from_cart/index.ts +0 -2
  59. package/events/remove_from_cart/removeFromCart.ts +0 -21
  60. package/events/select_item/index.ts +0 -1
  61. package/events/select_item/select_item.ts +0 -8
  62. package/events/view_cart/ViewCartFragment.graphql +0 -35
  63. package/events/view_cart/index.ts +0 -2
  64. package/events/view_cart/viewCart.ts +0 -21
  65. package/events/view_item/index.ts +0 -1
  66. package/events/view_item/view_item.ts +0 -8
  67. package/events/view_item_list/index.ts +0 -1
  68. package/events/view_item_list/view_item_list.ts +0 -8
  69. package/lib/event.ts +0 -39
  70. package/lib/index.ts +0 -2
  71. package/plugins/GoogleDatalayerAllPagesPageview.tsx +0 -37
@@ -1,13 +1,13 @@
1
1
  import { useCartQuery } from '@graphcommerce/magento-cart'
2
2
  import { PaymentMethodButtonProps } from '@graphcommerce/magento-cart-payment-method'
3
3
  import { GetPaymentMethodContextDocument } from '@graphcommerce/magento-cart-payment-method/PaymentMethodContext/GetPaymentMethodContext.gql'
4
- import { PluginProps } from '@graphcommerce/next-config'
5
- import { addPaymentInfo } from '../events/add_payment_info'
4
+ import type { PluginProps } from '@graphcommerce/next-config'
5
+ import { sendEvent } from '../api/sendEvent'
6
+ import { cartToAddPaymentInfo } from '../mapping/cartToAddPaymentInfo/cartToAddPaymentInfo'
6
7
 
7
8
  export const component = 'PaymentMethodButton'
8
9
  export const exported = '@graphcommerce/magento-cart-payment-method'
9
10
 
10
- // @todo This plugin can probably be migrated to the actual form that is submitted.
11
11
  function GoogleDatalayerPaymentMethodButton(props: PluginProps<PaymentMethodButtonProps>) {
12
12
  const { Prev, onSubmitSuccessful, ...rest } = props
13
13
  const methodContext = useCartQuery(GetPaymentMethodContextDocument)
@@ -16,7 +16,9 @@ function GoogleDatalayerPaymentMethodButton(props: PluginProps<PaymentMethodButt
16
16
  <Prev
17
17
  {...rest}
18
18
  onSubmitSuccessful={() => {
19
- addPaymentInfo(methodContext.data?.cart)
19
+ if (methodContext.data?.cart) {
20
+ sendEvent('add_payment_info', cartToAddPaymentInfo(methodContext.data.cart))
21
+ }
20
22
  return onSubmitSuccessful?.()
21
23
  }}
22
24
  />
@@ -1,6 +1,8 @@
1
1
  import type { PaymentMethodContextProviderProps } from '@graphcommerce/magento-cart-payment-method'
2
2
  import type { PluginProps } from '@graphcommerce/next-config'
3
- import { purchase } from '../events/purchase'
3
+ import { purchase } from '../mapping/orderToPurchase'
4
+ import { orderToPurchase } from '../mapping/orderToPurchase/orderToPurchase'
5
+ import { sendEvent } from '../api/sendEvent'
4
6
 
5
7
  export const component = 'PaymentMethodContextProvider'
6
8
  export const exported = '@graphcommerce/magento-cart-payment-method'
@@ -13,7 +15,7 @@ function GoogleDatalayerPaymentMethodContextProvider(
13
15
  <Prev
14
16
  {...rest}
15
17
  onSuccess={(orderNumber, cart) => {
16
- purchase(orderNumber, cart)
18
+ sendEvent('purchase', orderToPurchase(orderNumber, cart))
17
19
  return onSuccess?.(orderNumber, cart)
18
20
  }}
19
21
  />
@@ -1,24 +1,23 @@
1
- import { ProductListItemReal } from '@graphcommerce/magento-product'
2
- import { PluginProps } from '@graphcommerce/next-config'
1
+ import { ProductListItem } from '@graphcommerce/magento-product'
2
+ import type { PluginProps } from '@graphcommerce/next-config'
3
3
  import { useEventCallback } from '@mui/material'
4
4
  import { ComponentProps } from 'react'
5
- import { useListItemHandler } from '../components/AnalyticsItemList'
5
+ import { useViewItemList } from '../components/DatalayerViewItemList'
6
6
 
7
- export const component = 'ProductListItemReal'
7
+ export const component = 'ProductListItem'
8
8
  export const exported = '@graphcommerce/magento-product'
9
9
 
10
10
  function GoogleDatalayerProductListItem(
11
- props: PluginProps<ComponentProps<typeof ProductListItemReal>>,
11
+ props: PluginProps<ComponentProps<typeof ProductListItem>>,
12
12
  ) {
13
13
  const { Prev, onClick, ...rest } = props
14
- const { sku, price_range, name } = rest
15
- const handle = useListItemHandler({ sku, price_range, name })
14
+ const selectItem = useViewItemList()
16
15
 
17
16
  return (
18
17
  <Prev
19
18
  {...rest}
20
19
  onClick={useEventCallback<NonNullable<typeof onClick>>((e, item) => {
21
- handle()
20
+ if (item.sku) selectItem(item.sku)
22
21
  return onClick?.(e, item)
23
22
  })}
24
23
  />
@@ -1,6 +1,6 @@
1
1
  import type { ProductItemsGridProps } from '@graphcommerce/magento-product'
2
- import { PluginProps } from '@graphcommerce/next-config'
3
- import { ItemList } from '../components/AnalyticsItemList'
2
+ import type { PluginProps } from '@graphcommerce/next-config'
3
+ import { DatalayerViewItemList } from '../components/DatalayerViewItemList'
4
4
 
5
5
  export const component = 'ProductListItemsBase'
6
6
  export const exported = '@graphcommerce/magento-product'
@@ -8,9 +8,9 @@ export const exported = '@graphcommerce/magento-product'
8
8
  export function GoogleDatalayerProductListItemsBase(props: PluginProps<ProductItemsGridProps>) {
9
9
  const { Prev, ...rest } = props
10
10
  return (
11
- <ItemList {...rest}>
11
+ <DatalayerViewItemList {...rest}>
12
12
  <Prev {...rest} />
13
- </ItemList>
13
+ </DatalayerViewItemList>
14
14
  )
15
15
  }
16
16
 
@@ -1,24 +1,27 @@
1
- import type { RemoveItemFromCart as Original } from '@graphcommerce/magento-cart-items'
2
- import { ReactPlugin } from '@graphcommerce/next-config'
3
- import { removeFromCart } from '../events/remove_from_cart'
1
+ import type { RemoveItemFromCart } from '@graphcommerce/magento-cart-items'
2
+ import type { ReactPlugin } from '@graphcommerce/next-config'
3
+ import { sendEvent } from '../api/sendEvent'
4
+ import { cartItemToRemoveFromCart } from '../mapping/cartItemToRemoveFromCart/cartToRemoveFromCart'
4
5
 
5
6
  export const component = 'RemoveItemFromCart'
6
7
  export const exported =
7
8
  '@graphcommerce/magento-cart-items/components/RemoveItemFromCart/RemoveItemFromCart'
8
9
 
9
- export const GoogleDatalayerRemoveItemFromCart: ReactPlugin<typeof Original> = (props) => {
10
- const { Prev, uid, quantity, prices, product, buttonProps } = props
10
+ export const GoogleDatalayerRemoveItemFromCart: ReactPlugin<typeof RemoveItemFromCart> = (
11
+ props,
12
+ ) => {
13
+ const { Prev, buttonProps } = props
11
14
 
12
15
  return (
13
16
  <Prev
14
17
  {...props}
15
- product={product}
16
18
  buttonProps={{
19
+ ...buttonProps,
17
20
  onClick: (e) => {
18
- removeFromCart({
19
- __typename: 'Cart',
20
- items: [{ uid, __typename: 'SimpleCartItem', product, quantity, prices }],
21
- })
21
+ sendEvent(
22
+ 'remove_from_cart',
23
+ cartItemToRemoveFromCart({ __typename: 'SimpleCartItem', ...props }),
24
+ )
22
25
  buttonProps?.onClick?.(e)
23
26
  },
24
27
  }}
@@ -1,24 +1,25 @@
1
1
  import type { RemoveItemFromCartFab as Original } from '@graphcommerce/magento-cart-items'
2
- import { ReactPlugin } from '@graphcommerce/next-config'
3
- import { removeFromCart } from '../events/remove_from_cart'
2
+ import type { ReactPlugin } from '@graphcommerce/next-config'
3
+ import { sendEvent } from '../api/sendEvent'
4
+ import { cartItemToRemoveFromCart } from '../mapping/cartItemToRemoveFromCart/cartToRemoveFromCart'
4
5
 
5
6
  export const component = 'RemoveItemFromCartFab'
6
7
  export const exported =
7
8
  '@graphcommerce/magento-cart-items/components/RemoveItemFromCart/RemoveItemFromCartFab'
8
9
 
9
10
  export const GoogleDatalayerRemoveItemFromCartFab: ReactPlugin<typeof Original> = (props) => {
10
- const { Prev, uid, quantity, prices, product, fabProps } = props
11
+ const { Prev, fabProps } = props
11
12
 
12
13
  return (
13
14
  <Prev
14
15
  {...props}
15
- product={product}
16
16
  fabProps={{
17
+ ...fabProps,
17
18
  onClick: (e) => {
18
- removeFromCart({
19
- __typename: 'Cart',
20
- items: [{ uid, __typename: 'SimpleCartItem', product, quantity, prices }],
21
- })
19
+ sendEvent(
20
+ 'remove_from_cart',
21
+ cartItemToRemoveFromCart({ __typename: 'SimpleCartItem', ...props }),
22
+ )
22
23
  fabProps?.onClick?.(e)
23
24
  },
24
25
  }}
@@ -1,18 +1,24 @@
1
1
  import { ShippingMethodFormProps } from '@graphcommerce/magento-cart-shipping-method'
2
- import { PluginProps } from '@graphcommerce/next-config'
3
- import { addShippingInfo } from '../events/add_shipping_info'
2
+ import type { PluginProps } from '@graphcommerce/next-config'
3
+ import { sendEvent } from '../api/sendEvent'
4
+ import { cartToAddShippingInfo } from '../mapping/cartToAddShippingInfo/cartToAddShippingInfo'
4
5
 
5
6
  export const component = 'ShippingMethodForm'
6
7
  export const exported = '@graphcommerce/magento-cart-shipping-method'
7
8
 
8
- /** When the ShippingMethod is submitted the result is sent to Google Analytics */
9
9
  export function GoogleDatalayerShippingMethodForm(props: PluginProps<ShippingMethodFormProps>) {
10
10
  const { Prev, onComplete, ...rest } = props
11
11
  return (
12
12
  <Prev
13
13
  {...rest}
14
14
  onComplete={(result, variables) => {
15
- addShippingInfo(result.data?.setShippingMethodsOnCart?.cart)
15
+ if (result.data?.setShippingMethodsOnCart?.cart) {
16
+ sendEvent(
17
+ 'add_shipping_info',
18
+ cartToAddShippingInfo(result.data?.setShippingMethodsOnCart?.cart),
19
+ )
20
+ }
21
+
16
22
  return onComplete?.(result, variables)
17
23
  }}
18
24
  />
@@ -1,6 +1,8 @@
1
1
  import type { UpdateItemQuantityProps } from '@graphcommerce/magento-cart-items'
2
- import { PluginProps } from '@graphcommerce/next-config'
3
- import { event } from '../lib/event'
2
+ import type { PluginProps } from '@graphcommerce/next-config'
3
+ import { sendEvent } from '../api/sendEvent'
4
+ import { cartItemToDatalayerItem } from '../mapping/cartItemToDatalayerItem/cartItemToDatalayerItem'
5
+ import { datalayerItemsToCurrencyValue } from '../mapping/datalayerItemsToCurrencyValue/datalayerItemsToCurrencyValue'
4
6
 
5
7
  export const component = 'UpdateItemQuantity'
6
8
  export const exported =
@@ -21,39 +23,20 @@ function GoogleDatalayerUpdateItemQuantity(props: PluginProps<UpdateItemQuantity
21
23
  ...formOptions,
22
24
  onComplete: (data, variables) => {
23
25
  const original = formOptions?.onComplete?.(data, variables)
24
- const diffQuantity = variables.quantity - quantity
25
- if (diffQuantity === 0) return original
26
-
27
- const itemId = variables.uid
28
- const addedItem = data.data?.updateCartItems?.cart.items?.find(
29
- (item) => item?.uid === itemId,
26
+ const itemInCart = data.data?.updateCartItems?.cart.items?.find(
27
+ (item) => item?.uid === variables.uid,
30
28
  )
31
29
 
32
- if (addedItem && addedItem.prices && addedItem.prices.row_total_including_tax.value) {
33
- // we need to manually calculate pricePerItemInclTax (https://github.com/magento/magento2/issues/33848)
34
- const pricePerItemInclTax =
35
- addedItem.prices.row_total_including_tax.value / addedItem.quantity
36
- const addToCartValue = pricePerItemInclTax * diffQuantity
30
+ const diffQuantity = variables.quantity - quantity
31
+ const absQuantity = Math.abs(diffQuantity)
32
+
33
+ if (!itemInCart?.quantity || diffQuantity === 0) return original
37
34
 
38
- event('add_to_cart', {
39
- currency: addedItem?.prices?.price.currency,
40
- value: addToCartValue,
41
- items: [
42
- {
43
- item_id: addedItem?.product.sku,
44
- item_name: addedItem?.product.name,
45
- currency: addedItem?.prices?.price.currency,
46
- price: pricePerItemInclTax,
47
- quantity: variables.quantity,
48
- discount: addedItem?.prices?.discounts?.reduce(
49
- // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
50
- (sum, discount) => sum + (discount?.amount?.value ?? 0),
51
- 0,
52
- ),
53
- },
54
- ],
55
- })
56
- }
35
+ const items = [{ ...cartItemToDatalayerItem(itemInCart), quantity: absQuantity }]
36
+ sendEvent(diffQuantity < 0 ? 'remove_from_cart' : 'add_to_cart', {
37
+ ...datalayerItemsToCurrencyValue(items),
38
+ items,
39
+ })
57
40
 
58
41
  return original
59
42
  },
@@ -1,9 +1,9 @@
1
1
  import type { ProductPageMeta } from '@graphcommerce/magento-product'
2
- import { PluginProps } from '@graphcommerce/next-config'
2
+ import type { PluginProps } from '@graphcommerce/next-config'
3
3
  import { useMemoObject } from '@graphcommerce/next-ui'
4
4
  import React, { useEffect } from 'react'
5
- import { productToItem } from '../lib'
6
- import { event } from '../lib/event'
5
+ import { sendEvent } from '../api/sendEvent'
6
+ import { productToViewItem } from '../mapping/productToViewItem/productToViewItem'
7
7
 
8
8
  export const component = 'ProductPageMeta'
9
9
  export const exported = '@graphcommerce/magento-product'
@@ -11,17 +11,9 @@ export const exported = '@graphcommerce/magento-product'
11
11
  /** When a product is added to the Cart, send a Google Analytics event */
12
12
  function GoogleDatalayerViewItem(props: PluginProps<React.ComponentProps<typeof ProductPageMeta>>) {
13
13
  const { Prev, product } = props
14
- const { price_range } = product
15
14
 
16
- const viewItem = useMemoObject({
17
- currency: price_range.minimum_price.final_price.currency,
18
- value: price_range.minimum_price.final_price.value,
19
- items: [productToItem(product)],
20
- })
21
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
22
- useEffect(() => {
23
- event('view_item', viewItem)
24
- }, [viewItem])
15
+ const viewItem = useMemoObject(productToViewItem(product))
16
+ useEffect(() => sendEvent('view_item', viewItem), [viewItem])
25
17
 
26
18
  return <Prev {...props} />
27
19
  }
@@ -0,0 +1,40 @@
1
+ import type { PagesProps } from '@graphcommerce/framer-next-pages'
2
+ import type { IfConfig, PluginProps } from '@graphcommerce/next-config'
3
+ import { useEventCallback } from '@mui/material'
4
+ import { useEffect } from 'react'
5
+ import { onCLS, onFCP, onFID, onINP, onLCP, onTTFB, Metric } from 'web-vitals/attribution'
6
+ import { sendEvent } from '../api/sendEvent'
7
+
8
+ export const component = 'FramerNextPages'
9
+ export const exported = '@graphcommerce/framer-next-pages'
10
+ export const ifConfig: IfConfig = 'dataLayer.coreWebVitals'
11
+
12
+ /** When a product is added to the Cart, send a Google Analytics event.
13
+ *
14
+ * Based on this information: https://github.com/GoogleChrome/web-vitals?tab=readme-ov-file#send-the-results-to-google-analytics
15
+ */
16
+ function GoogleDatalayerCoreWebVitals(props: PluginProps<PagesProps>) {
17
+ const { Prev, ...rest } = props
18
+
19
+ const sendCoreWebVitals = useEventCallback((m: Metric, debug_target?: string | undefined) => {
20
+ sendEvent(`cwv_${m.name.toLowerCase()}`, {
21
+ value: m.delta,
22
+ debug_target,
23
+ ...Object.fromEntries(Object.entries(m).map(([key, value]) => [`metric_${key}`, value])),
24
+ })
25
+ })
26
+
27
+ useEffect(() => {
28
+ const opts = { reportAllChanges: true }
29
+ onCLS((m) => sendCoreWebVitals(m, m.attribution.largestShiftTarget))
30
+ onFCP((m) => sendCoreWebVitals(m), opts)
31
+ onFID((m) => sendCoreWebVitals(m, m.attribution.eventTarget), opts)
32
+ onINP((m) => sendCoreWebVitals(m, m.attribution.eventTarget), opts)
33
+ onLCP((m) => sendCoreWebVitals(m, m.attribution.element), opts)
34
+ onTTFB((m) => sendCoreWebVitals(m), opts)
35
+ }, [sendCoreWebVitals])
36
+
37
+ return <Prev {...rest} />
38
+ }
39
+
40
+ export const Plugin = GoogleDatalayerCoreWebVitals
@@ -1,63 +0,0 @@
1
- import { nonNullable, useMemoObject } from '@graphcommerce/next-ui'
2
- import { useEventCallback } from '@mui/material'
3
- import React, { useContext, useEffect, useMemo } from 'react'
4
- import { Item, ProductToItemFragment, productToItem } from '../lib'
5
- import { event } from '../lib/event'
6
-
7
- export type UseViewItemListProps<P extends ProductToItemFragment = ProductToItemFragment> = {
8
- title: string
9
- items?: (P | null | undefined)[] | null
10
- listId?: string
11
- }
12
-
13
- export type ViewItemList = {
14
- item_list_id: string
15
- item_list_name: string
16
- items: Item[]
17
- }
18
-
19
- const GoogleTagManagerItemListContext = React.createContext<{
20
- item_list_id: string
21
- item_list_name: string
22
- }>({ item_list_id: '', item_list_name: '' })
23
-
24
- export function useListItemHandler(item: ProductToItemFragment) {
25
- const { item_list_id, item_list_name } = useContext(GoogleTagManagerItemListContext)
26
- return useEventCallback(() =>
27
- event('select_item', {
28
- item_list_id,
29
- item_list_name,
30
- items: productToItem(item),
31
- }),
32
- )
33
- }
34
-
35
- export function ItemList<P extends ProductToItemFragment = ProductToItemFragment>(
36
- props: UseViewItemListProps<P> & { children: React.ReactNode },
37
- ) {
38
- const { title, items, listId, children } = props
39
-
40
- const eventData: ViewItemList = useMemoObject({
41
- item_list_id: listId ?? title?.toLowerCase().replace(/\s/g, '_'),
42
- item_list_name: title,
43
- items: items?.map((item) => (item ? productToItem(item) : null)).filter(nonNullable) ?? [],
44
- })
45
-
46
- useEffect(() => {
47
- event('view_item_list', eventData)
48
- }, [eventData])
49
-
50
- const value = useMemo(
51
- () => ({
52
- item_list_id: listId ?? title?.toLowerCase().replace(/\s/g, '_'),
53
- item_list_name: title ?? listId,
54
- }),
55
- [listId, title],
56
- )
57
-
58
- return (
59
- <GoogleTagManagerItemListContext.Provider value={value}>
60
- {children}
61
- </GoogleTagManagerItemListContext.Provider>
62
- )
63
- }
@@ -1,36 +0,0 @@
1
- fragment AddPaymentInfoFragment on Cart
2
- @inject(into: ["PaymentMethodContext", "PaymentMethodUpdated"]) {
3
- items {
4
- uid
5
- prices {
6
- price {
7
- currency
8
- value
9
- }
10
- discounts {
11
- amount {
12
- currency
13
- value
14
- }
15
- }
16
- }
17
- quantity
18
- product {
19
- uid
20
- name
21
- sku
22
- }
23
- }
24
- applied_coupons {
25
- code
26
- }
27
- prices {
28
- grand_total {
29
- currency
30
- value
31
- }
32
- }
33
- selected_payment_method {
34
- code
35
- }
36
- }
@@ -1,23 +0,0 @@
1
- import { event } from '../../lib/event'
2
- import { AddPaymentInfoFragment } from './AddPaymentInfoFragment.gql'
3
-
4
- export const addPaymentInfo = <C extends AddPaymentInfoFragment>(cart?: C | null) =>
5
- event('add_payment_info', {
6
- ...cart,
7
- currency: cart?.prices?.grand_total?.currency,
8
- value: cart?.prices?.grand_total?.value,
9
- coupon: cart?.applied_coupons?.map((coupon) => coupon?.code),
10
- payment_type: cart?.selected_payment_method?.code,
11
- items: cart?.items?.map((item) => ({
12
- item_id: item?.product.sku,
13
- item_name: item?.product.name,
14
- currency: item?.prices?.price.currency,
15
- discount: item?.prices?.discounts?.reduce(
16
- // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
17
- (sum, discount) => sum + (discount?.amount?.value ?? 0),
18
- 0,
19
- ),
20
- price: item?.prices?.price.value,
21
- quantity: item?.quantity,
22
- })),
23
- })
@@ -1,2 +0,0 @@
1
- export * from './addPaymentInfo'
2
- export * from './AddPaymentInfoFragment.gql'
@@ -1,38 +0,0 @@
1
- fragment AddShippingInfoFragment on Cart @inject(into: ["ShippingMethodSelected"]) {
2
- prices {
3
- grand_total {
4
- currency
5
- value
6
- }
7
- }
8
- applied_coupons {
9
- code
10
- }
11
- items {
12
- __typename
13
- uid
14
- product {
15
- uid
16
- sku
17
- name
18
- }
19
- prices {
20
- price {
21
- value
22
- currency
23
- }
24
- discounts {
25
- amount {
26
- value
27
- }
28
- }
29
- }
30
- quantity
31
- ... on ConfigurableCartItem {
32
- configured_variant {
33
- uid
34
- sku
35
- }
36
- }
37
- }
38
- }
@@ -1,22 +0,0 @@
1
- import { event } from '../../lib/event'
2
- import { AddShippingInfoFragment } from './AddSchippingInfoFragment.gql'
3
-
4
- export const addShippingInfo = <C extends AddShippingInfoFragment>(cart?: C) =>
5
- event('add_shipping_info', {
6
- ...cart,
7
- currency: cart?.prices?.grand_total?.currency,
8
- value: cart?.prices?.grand_total?.value,
9
- coupon: cart?.applied_coupons?.map((coupon) => coupon?.code),
10
- items: cart?.items?.map((item) => ({
11
- item_id: item?.product.sku,
12
- item_name: item?.product.name,
13
- currency: item?.prices?.price.currency,
14
- discount: item?.prices?.discounts?.reduce(
15
- (sum, discount) => sum + (discount?.amount?.value ?? 0),
16
- 0,
17
- ),
18
- item_variant: item && 'configured_variant' in item ? item.configured_variant.sku : '',
19
- price: item?.prices?.price.value,
20
- quantity: item?.quantity,
21
- })),
22
- })
@@ -1,2 +0,0 @@
1
- export * from './addShippingInfo'
2
- export * from './AddSchippingInfoFragment.gql'
@@ -1,30 +0,0 @@
1
- fragment AddToCartFragment on Cart @inject(into: ["CartItemCountChanged"]) {
2
- items {
3
- quantity
4
- product {
5
- sku
6
- name
7
- }
8
- prices {
9
- discounts {
10
- amount {
11
- currency
12
- value
13
- }
14
- }
15
- row_total_including_tax {
16
- currency
17
- value
18
- }
19
- price {
20
- currency
21
- value
22
- }
23
- }
24
- }
25
- prices {
26
- grand_total {
27
- currency
28
- }
29
- }
30
- }
@@ -1,58 +0,0 @@
1
- import type { FetchResult } from '@graphcommerce/graphql'
2
- import {
3
- AddProductsToCartFields,
4
- AddProductsToCartMutation,
5
- findAddedItems,
6
- toUserErrors,
7
- } from '@graphcommerce/magento-product'
8
- import { nonNullable } from '@graphcommerce/next-ui'
9
- import { event } from '../../lib/event'
10
-
11
- export const addToCart = (
12
- result: FetchResult<AddProductsToCartMutation>,
13
- variables: AddProductsToCartFields,
14
- ) => {
15
- const { data, errors } = result
16
- const cart = data?.addProductsToCart?.cart
17
-
18
- const addedItems = findAddedItems(data, variables)
19
-
20
- const items = addedItems
21
- .map(({ itemVariable, itemInCart }) => {
22
- if (!itemInCart) return null
23
- const { product, prices } = itemInCart
24
- return {
25
- item_id: product.sku,
26
- item_name: product.name,
27
- currency: prices?.price.currency,
28
- price: (prices?.row_total_including_tax.value ?? 1) / itemInCart.quantity,
29
- quantity: itemVariable.quantity,
30
- discount: prices?.discounts?.reduce(
31
- (sum, discount) => sum + (discount?.amount?.value ?? 0) / itemVariable.quantity,
32
- 0,
33
- ),
34
- }
35
- })
36
- .filter(nonNullable)
37
-
38
- const userErrors = toUserErrors(result.data)
39
- if ((errors && errors.length > 0) || userErrors.length > 0) {
40
- event('add_to_cart_error', {
41
- userErrors: userErrors?.map((e) => e.message),
42
- errors: errors?.map((e) => e.message),
43
- variables,
44
- })
45
- }
46
-
47
- if (!items.length) return
48
-
49
- event('add_to_cart', {
50
- currency: cart?.prices?.grand_total?.currency,
51
- value: addedItems.reduce(
52
- (sum, { itemVariable, itemInCart }) =>
53
- sum + (itemInCart?.prices?.row_total_including_tax.value ?? 1) / itemVariable.quantity,
54
- 0,
55
- ),
56
- items,
57
- })
58
- }
@@ -1,2 +0,0 @@
1
- export * from './addToCart'
2
- export * from './AddToCartFragment.gql'