@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.
- package/CHANGELOG.md +12 -0
- package/Config.graphqls +5 -13
- package/README.md +2 -3
- package/api/sendEvent.ts +50 -0
- package/components/DatalayerViewItemList.tsx +45 -0
- package/index.ts +1 -0
- package/mapping/cartItemToDatalayerItem/CartItem_DatalayerItem.graphql +31 -0
- package/mapping/cartItemToDatalayerItem/cartItemToDatalayerItem.ts +27 -0
- package/mapping/cartItemToRemoveFromCart/CartItem_RemoveFromCart.graphql +3 -0
- package/mapping/cartItemToRemoveFromCart/cartToRemoveFromCart.ts +13 -0
- package/mapping/cartToAddPaymentInfo/Cart_AddPaymentInfo.graphql +10 -0
- package/mapping/cartToAddPaymentInfo/cartToAddPaymentInfo.ts +10 -0
- package/mapping/cartToAddShippingInfo/Cart_AddShippingInfo.graphql +12 -0
- package/mapping/cartToAddShippingInfo/cartToAddShippingInfo.ts +15 -0
- package/mapping/cartToBeginCheckout/Cart_BeginCheckout.graphql +6 -0
- package/mapping/cartToBeginCheckout/cartToBeginCheckout.ts +9 -0
- package/mapping/cartToDatalayerItems/Cart_DatalayerItems.graphql +11 -0
- package/mapping/cartToDatalayerItems/cartToDatalayerItems.ts +10 -0
- package/mapping/cartToViewCart/Cart_ViewCart.graphql +4 -0
- package/mapping/cartToViewCart/cartToViewCart.ts +6 -0
- package/mapping/datalayerItemsToCurrencyValue/datalayerItemsToCurrencyValue.ts +8 -0
- package/mapping/orderToPurchase/orderToPurchase.ts +17 -0
- package/mapping/productItemsToViewItemList/productItemsToViewItemList.ts +22 -0
- package/{lib/productToItem/ProductToItem.graphql → mapping/productToDatalayerItem/Product_DatalayerItem.graphql} +3 -6
- package/{lib/productToItem/productToItem.ts → mapping/productToDatalayerItem/productToDatalayerItem.ts} +17 -9
- package/mapping/productToViewItem/Product_ViewItem.graphql +3 -0
- package/mapping/productToViewItem/productToViewItem.ts +11 -0
- package/package.json +12 -11
- package/plugins/GoogleDatalayerAddProductsToCartForm.tsx +33 -4
- package/plugins/GoogleDatalayerCartStartCheckout.tsx +17 -3
- package/plugins/GoogleDatalayerCartStartCheckoutLinkOrButton.tsx +4 -14
- package/plugins/GoogleDatalayerPaymentMethodButton.tsx +6 -4
- package/plugins/GoogleDatalayerPaymentMethodContextProvider.tsx +4 -2
- package/plugins/GoogleDatalayerProductListItem.tsx +7 -8
- package/plugins/GoogleDatalayerProductListItemsBase.tsx +4 -4
- package/plugins/GoogleDatalayerRemoveItemFromCart.tsx +13 -10
- package/plugins/GoogleDatalayerRemoveItemFromCartFab.tsx +9 -8
- package/plugins/GoogleDatalayerShippingMethodForm.tsx +10 -4
- package/plugins/GoogleDatalayerUpdateItemQuantity.tsx +15 -32
- package/plugins/GoogleDatalayerViewItem.tsx +5 -13
- package/plugins/GoogleDatalayerWebVitals.tsx +40 -0
- package/components/AnalyticsItemList.tsx +0 -63
- package/events/add_payment_info/AddPaymentInfoFragment.graphql +0 -36
- package/events/add_payment_info/addPaymentInfo.ts +0 -23
- package/events/add_payment_info/index.ts +0 -2
- package/events/add_shipping_info/AddSchippingInfoFragment.graphql +0 -38
- package/events/add_shipping_info/addShippingInfo.ts +0 -22
- package/events/add_shipping_info/index.ts +0 -2
- package/events/add_to_cart/AddToCartFragment.graphql +0 -30
- package/events/add_to_cart/addToCart.ts +0 -58
- package/events/add_to_cart/index.ts +0 -2
- package/events/begin_checkout/BeginCheckoutFragment.graphql +0 -38
- package/events/begin_checkout/beginCheckout.ts +0 -22
- package/events/begin_checkout/index.ts +0 -2
- package/events/purchase/index.ts +0 -1
- package/events/purchase/purchase.ts +0 -27
- package/events/remove_from_cart/RemoveFromCartFragment.graphql +0 -36
- package/events/remove_from_cart/index.ts +0 -2
- package/events/remove_from_cart/removeFromCart.ts +0 -21
- package/events/select_item/index.ts +0 -1
- package/events/select_item/select_item.ts +0 -8
- package/events/view_cart/ViewCartFragment.graphql +0 -35
- package/events/view_cart/index.ts +0 -2
- package/events/view_cart/viewCart.ts +0 -21
- package/events/view_item/index.ts +0 -1
- package/events/view_item/view_item.ts +0 -8
- package/events/view_item_list/index.ts +0 -1
- package/events/view_item_list/view_item_list.ts +0 -8
- package/lib/event.ts +0 -39
- package/lib/index.ts +0 -2
- 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 {
|
|
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
|
-
|
|
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 '../
|
|
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 {
|
|
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 {
|
|
5
|
+
import { useViewItemList } from '../components/DatalayerViewItemList'
|
|
6
6
|
|
|
7
|
-
export const component = '
|
|
7
|
+
export const component = 'ProductListItem'
|
|
8
8
|
export const exported = '@graphcommerce/magento-product'
|
|
9
9
|
|
|
10
10
|
function GoogleDatalayerProductListItem(
|
|
11
|
-
props: PluginProps<ComponentProps<typeof
|
|
11
|
+
props: PluginProps<ComponentProps<typeof ProductListItem>>,
|
|
12
12
|
) {
|
|
13
13
|
const { Prev, onClick, ...rest } = props
|
|
14
|
-
const
|
|
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
|
-
|
|
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 {
|
|
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
|
-
<
|
|
11
|
+
<DatalayerViewItemList {...rest}>
|
|
12
12
|
<Prev {...rest} />
|
|
13
|
-
</
|
|
13
|
+
</DatalayerViewItemList>
|
|
14
14
|
)
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -1,24 +1,27 @@
|
|
|
1
|
-
import type { RemoveItemFromCart
|
|
2
|
-
import { ReactPlugin } from '@graphcommerce/next-config'
|
|
3
|
-
import {
|
|
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
|
|
10
|
-
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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 {
|
|
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,
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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 {
|
|
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
|
-
|
|
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 {
|
|
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
|
|
25
|
-
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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 {
|
|
6
|
-
import {
|
|
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
|
-
|
|
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,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,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
|
-
}
|