/** * External dependencies */ import type { ProductResponseItem, CartResponseItem, StoreCart, } from '@woocommerce/types'; interface ImpressionItem extends Gtag.Item { list_name?: string; } /** * Formats data into the productFieldObject shape. * * @see https://developers.google.com/analytics/devguides/collection/gtagjs/enhanced-ecommerce#product-data */ export const getProductFieldObject = ( product: ProductResponseItem | CartResponseItem, quantity: number | undefined ): Gtag.Item => { const productIdentifier = product.sku ? product.sku : '#' + product.id; const productCategory = 'categories' in product && product.categories.length ? product.categories[ 0 ].name : ''; return { id: productIdentifier, name: product.name, quantity, category: productCategory, price: ( parseInt( product.prices.price, 10 ) / 10 ** product.prices.currency_minor_unit ).toString(), }; }; /** * Formats data into the impressionFieldObject shape. * * @see https://developers.google.com/analytics/devguides/collection/gtagjs/enhanced-ecommerce#impression-data */ export const getProductImpressionObject = ( product: ProductResponseItem, listName: string ): ImpressionItem => { const productIdentifier = product.sku ? product.sku : '#' + product.id; const productCategory = product.categories.length ? product.categories[ 0 ].name : ''; return { id: productIdentifier, name: product.name, list_name: listName, category: productCategory, price: ( parseInt( product.prices.price, 10 ) / 10 ** product.prices.currency_minor_unit ).toString(), }; }; /** * Track an event using the global gtag function. */ export const trackEvent = ( eventName: Gtag.EventNames | string, eventParams?: Gtag.ControlParams | Gtag.EventParams | Gtag.CustomParams ): void => { if ( typeof gtag !== 'function' ) { throw new Error( 'Function gtag not implemented.' ); } // eslint-disable-next-line no-console console.log( `Tracking event ${ eventName }` ); window.gtag( 'event', eventName, eventParams ); }; let currentStep = -1; export const trackCheckoutStep = ( step: number ) => ( { storeCart, }: { storeCart: StoreCart; } ): void => { if ( currentStep === step ) { return; } trackEvent( step === 0 ? 'begin_checkout' : 'checkout_progress', { items: storeCart.cartItems.map( getProductFieldObject ), coupon: storeCart.cartCoupons[ 0 ]?.code || '', currency: storeCart.cartTotals.currency_code, value: ( parseInt( storeCart.cartTotals.total_price, 10 ) / 10 ** storeCart.cartTotals.currency_minor_unit ).toString(), checkout_step: step, } ); currentStep = step; }; export const trackCheckoutOption = ( { step, option, value, }: { step: number; option: string; value: string; } ) => (): void => { trackEvent( 'set_checkout_option', { checkout_step: step, checkout_option: option, value, } ); currentStep = step; };