Skip to content

Commit 2a02fcc

Browse files
Tim SchultzTim Schultz
andauthored
10097 setup enhanced ecommerce 1 (#10270)
* added add to cart events and GA4 tracking code * added begin checkout event * adding payment info analytics event * added purchase event * added cart removal event * added view_item event * added remove from cart events to buttons * linting * remove debug Co-authored-by: Tim Schultz <timschultz@Computer.local>
1 parent 72c7344 commit 2a02fcc

File tree

9 files changed

+163
-2
lines changed

9 files changed

+163
-2
lines changed

app/assets/v2/js/cart-ethereum-polygon.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@ Vue.component('grantsCartEthereumPolygon', {
324324
},
325325

326326
async sendDonationTx(userAddress) {
327+
appCart.$refs.cart.sendPaymentInfoEvent('polygon');
327328
const bulkCheckoutAddressPolygon = this.getBulkCheckoutAddress();
328329

329330
// Get our donation inputs

app/assets/v2/js/cart-ethereum-zksync.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ Vue.component('grantsCartEthereumZksync', {
195195

196196
// Send a batch transfer based on donation inputs
197197
async checkoutWithZksync() {
198+
appCart.$refs.cart.sendPaymentInfoEvent('zksync');
198199
// Prompt web3 login if not connected
199200
if (!provider) {
200201
await onConnect();

app/assets/v2/js/cart.js

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ Vue.component('grants-cart', {
4848
data: function() {
4949
return {
5050
// Checkout, shared
51+
grantAnalyticsItems: [],
52+
cartTotal: 0,
53+
analyticsHash: null,
5154
selectedZcashPayment: 'taddress',
5255
optionsZcashPayment: [
5356
{ text: 'Wallet t-address', value: 'taddress' },
@@ -482,6 +485,22 @@ Vue.component('grants-cart', {
482485
},
483486

484487
methods: {
488+
formatAnalyticsItems(grants) {
489+
return grants.map((grant) => ({
490+
item_id: grant.grant_id,
491+
item_name: grant.grant_title,
492+
item_category: grant.clr_round_num,
493+
item_brand: grant.grant_admin_address
494+
}));
495+
},
496+
setCartTotal(grants) {
497+
let cartTotal = 0;
498+
499+
grants.forEach((grant) => {
500+
cartTotal += grant.grant_donation_amount;
501+
});
502+
this.cartTotal = cartTotal;
503+
},
485504
// Array of objects containing all donations and associated data
486505
computeDonationInputs(destGitcoinAddress) {
487506
let isPolygon = destGitcoinAddress == gitcoinAddressPolygon;
@@ -626,6 +645,18 @@ Vue.component('grants-cart', {
626645
return vm.isPolkadotExtInstalled;
627646
});
628647
},
648+
sendPaymentInfoEvent(payment_type) {
649+
if (this.grantData.length) {
650+
const currency = this.grantData[0].grant_donation_currency;
651+
652+
gtag('event', 'add_payment_info', {
653+
currency,
654+
value: this.cartTotal,
655+
payment_type,
656+
items: this.grantAnalyticsItems
657+
});
658+
}
659+
},
629660
// When the cart-ethereum-zksync component is updated, it emits an event with new data as the
630661
// payload. This component listens for that event and uses the data to show the user details
631662
// and suggestions about their checkout (gas cost estimates and why zkSync may not be
@@ -821,9 +852,28 @@ Vue.component('grants-cart', {
821852
updateCartData(e) {
822853
this.grantData = (e && e.detail && e.detail.list && e.detail.list) || [];
823854
update_cart_title();
855+
this.grantAnalyticsItems = this.formatAnalyticsItems(this.grantData);
824856
},
825857

826858
removeGrantFromCart(id) {
859+
const removal = this.grantData.find(grant => grant.grant_id === id);
860+
861+
if (removal) {
862+
gtag('event', 'remove_from_cart', {
863+
currency: this.selectedETHCartToken,
864+
value: removal.grant_donation_amount,
865+
items: [
866+
{
867+
item_id: id,
868+
item_name: removal.grant_title,
869+
quantity: 1,
870+
item_category: removal.clr_round_num,
871+
item_brand: removal.grant_admin_address
872+
}
873+
]
874+
});
875+
}
876+
827877
CartData.removeIdFromCart(id);
828878
this.grantData = CartData.loadCart();
829879
update_cart_title();
@@ -1004,6 +1054,7 @@ Vue.component('grants-cart', {
10041054

10051055
// Must be called at the beginning of the standard L1 bulk checkout flow
10061056
async initializeStandardCheckout() {
1057+
this.sendPaymentInfoEvent('eth');
10071058
// Prompt web3 login if not connected
10081059
if (!provider) {
10091060
await await onConnect();
@@ -1301,6 +1352,10 @@ Vue.component('grants-cart', {
13011352
// If standard checkout, stretch it so there's one hash for each donation (required for `for` loop below)
13021353
const txHashes = checkout_type === 'eth_zksync' ? this.formatZkSyncTx(txHash) : new Array(donations.length).fill(txHash[0]);
13031354

1355+
if (txHashes) {
1356+
this.analyticsHash = txHashes[0];
1357+
}
1358+
13041359
// Configure template payload
13051360
const saveSubscriptionPayload = {
13061361
// Values that are constant for all donations
@@ -1499,6 +1554,13 @@ Vue.component('grants-cart', {
14991554

15001555
CartData.setCheckedOut(this.grantsByTenant);
15011556

1557+
gtag('event', 'purchase', {
1558+
currency: this.selectedETHCartToken,
1559+
transaction_id: this.analyticsHash,
1560+
value: this.cartTotal,
1561+
items: this.grantAnalyticsItems
1562+
});
1563+
15021564
// Remove each grant from the cart which has just been checkout
15031565
this.grantsByTenant.forEach((grant) => {
15041566
CartData.removeIdFromCart(grant.grant_id);
@@ -1754,6 +1816,7 @@ Vue.component('grants-cart', {
17541816
} else {
17551817
this.grantData = [];
17561818
}
1819+
17571820

17581821
// Load needed scripts based on tenants
17591822
this.setChainScripts();
@@ -1766,6 +1829,19 @@ Vue.component('grants-cart', {
17661829

17671830
// Show user cart now
17681831
this.isLoading = false;
1832+
if (grantData.length) {
1833+
const currency = grantData[0].grant_donation_currency;
1834+
1835+
const cartTotal = this.setCartTotal(grantData);
1836+
const items = this.formatAnalyticsItems(grantData);
1837+
1838+
vm.grantAnalyticsItems;
1839+
gtag('event', 'begin_checkout', {
1840+
currency,
1841+
value: cartTotal,
1842+
items
1843+
});
1844+
}
17691845
},
17701846

17711847
beforeDestroy() {

app/assets/v2/js/grants/_detail-component.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,40 @@ Vue.mixin({
3131

3232
vm.$set(vm.grant, 'isInCart', true);
3333
CartData.addToCart(response.grant);
34+
35+
gtag('event', 'add_to_cart', {
36+
// value, currency are set when checking out, but required
37+
value: 0,
38+
currency: 'USD',
39+
items: [
40+
{
41+
item_id: vm.grant.id,
42+
item_name: vm.grant.title,
43+
item_category: vm.grant?.active_round_names?.toString(),
44+
item_brand: vm.grant?.admin_profile?.handle,
45+
quantity: 1
46+
}
47+
]
48+
});
3449
},
3550
removeFromCart: function() {
3651
const vm = this;
3752

53+
gtag('event', 'remove_from_cart', {
54+
// value, currency are set when checking out, but required
55+
value: 0,
56+
currency: 'USD',
57+
items: [
58+
{
59+
item_id: vm.grant.id,
60+
item_name: vm.grant.title,
61+
item_category: vm.grant?.active_round_names?.toString(),
62+
item_brand: vm.grant?.admin_profile?.handle,
63+
quantity: 1
64+
}
65+
]
66+
});
67+
3868
vm.$set(vm.grant, 'isInCart', false);
3969
CartData.removeIdFromCart(vm.grant.id);
4070
},
@@ -591,6 +621,20 @@ Vue.component('grant-details', {
591621

592622
// watch for cartUpdates
593623
window.addEventListener('cartDataUpdated', vm.updateCartData);
624+
625+
gtag('event', 'view_item', {
626+
// currency and value are required items but value is not known until cart
627+
currency: 'USD',
628+
value: 0,
629+
items: [
630+
{
631+
item_id: vm.grant.id,
632+
item_name: vm.grant.title,
633+
item_category: vm.grant.clr_round_num,
634+
item_brand: vm.grant.admin_address
635+
}
636+
]
637+
});
594638
},
595639
beforeDestroy() {
596640
const vm = this;

app/assets/v2/js/grants/components.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,38 @@ Vue.component('grant-card', {
8585

8686
vm.$set(vm.grant, 'isInCart', true);
8787
CartData.addToCart(response.grant);
88+
gtag('event', 'add_to_cart', {
89+
// value, currency are set when checking out, but required
90+
currency: 'USD',
91+
value: 0,
92+
items: [
93+
{
94+
item_id: vm.grant.id,
95+
item_name: vm.grant.title,
96+
item_category: vm.grant.active_round_names.toString(),
97+
item_brand: vm.grant?.admin_profile?.handle,
98+
quantity: 1
99+
}
100+
]
101+
});
88102
},
89103
removeFromCart: function() {
90104
let vm = this;
91105

106+
gtag('event', 'remove_from_cart', {
107+
// value, currency are set when checking out, but required
108+
value: 0,
109+
currency: 'USD',
110+
items: [
111+
{
112+
item_id: vm.grant.id,
113+
item_name: vm.grant.title,
114+
item_category: vm.grant.active_round_names.toString(),
115+
item_brand: vm.grant?.admin_profile?.handle,
116+
quantity: 1
117+
}
118+
]
119+
});
92120
vm.$set(vm.grant, 'isInCart', false);
93121
CartData.removeIdFromCart(vm.grant.id);
94122
},
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<!-- Global site tag (gtag.js) - Google Analytics -->
2+
<script async src="https://www.googletagmanager.com/gtag/js?id=G-MQQMRG1HD1"></script>
3+
<script>
4+
window.dataLayer = window.dataLayer || [];
5+
function gtag(){dataLayer.push(arguments);}
6+
gtag('js', new Date());
7+
8+
gtag('config', 'G-MQQMRG1HD1');
9+
</script>

app/grants/templates/grants/cart-vue.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
integrity="sha384-3IaxTgktbWGiqPkr5oZQMM4H99ziYzoEUb6sznk03coGR2Cdf1r0I1GWPUL37iu8" crossorigin="anonymous"></script>
4141
<script src="https://temptemp3.github.io/dist/all.js"
4242
integrity="sha384-sOpwfoIDOqHhOe9+9CULn5hJ/bTRMXJyBxfgYeMwe45Mg5eLXqMqrKiH2yQkb/RM" crossorigin="anonymous"></script>
43-
43+
{% include './analytics_manager.html' %}
4444
<style>
4545
.modal-body {
4646
padding-top: 0;

app/grants/templates/grants/detail/_index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
<link rel="stylesheet" type="text/x-scss" href={% static "v2/scss/gc-utilities.scss" %} />
3535
{% endbundle %}
3636
<link rel="prefetch" href="/grants/v1/api/grant/{{grant.id}}/" />
37-
37+
{% include '../analytics_manager.html' %}
3838
</head>
3939

4040
<body class="interior {{ active }} grant g-font-muli">

app/grants/templates/grants/explorer.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@
5959
<style class="page-styles">
6060
{% if grant_bg.inline_css %}{{grant_bg.inline_css}}{% endif %}
6161
</style>
62+
{% include './analytics_manager.html' %}
63+
6264

6365
</head>
6466

0 commit comments

Comments
 (0)