From f149d6dce5dbcd65f296e85a982bc9035b70a8dc Mon Sep 17 00:00:00 2001 From: Ridwa Date: Tue, 16 Jul 2024 13:02:06 +0530 Subject: [PATCH 1/6] Implemented: added mixin functionality to track events and login user data --- package-lock.json | 175 ++++++++++++++++++++++++++++++++++++++++ package.json | 3 + src/index.ts | 5 +- src/mixins/analytics.ts | 64 +++++++++++++++ tsconfig.json | 13 ++- 5 files changed, 258 insertions(+), 2 deletions(-) create mode 100644 src/mixins/analytics.ts diff --git a/package-lock.json b/package-lock.json index c0d99be3..e90cad7f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@ionic/vue": "^7.6.0", "firebase": "^10.3.1", "luxon": "^3.3.0", + "mixpanel-browser": "^2.53.0", "pinia": "2.0.36", "pinia-plugin-persistedstate": "^3.1.0", "register-service-worker": "^1.7.2", @@ -24,7 +25,9 @@ "devDependencies": { "@babel/types": "^7.22.11", "@types/luxon": "^3.3.0", + "@types/mixpanel-browser": "^2.49.1", "@types/node": "^20.5.7", + "@types/vue": "^2.0.0", "@vitejs/plugin-vue": "^4.3.4", "@vue/eslint-config-prettier": "^8.0.0", "@vue/eslint-config-typescript": "^11.0.3", @@ -1269,6 +1272,14 @@ "node": ">= 8.0.0" } }, + "node_modules/@rrweb/types": { + "version": "2.0.0-alpha.16", + "resolved": "https://registry.npmjs.org/@rrweb/types/-/types-2.0.0-alpha.16.tgz", + "integrity": "sha512-E6cACNVsm+NUhn7dzocQoKyXI7BHrHRRm5Ab23yrAzEQ2caWocCEYJhqDlc4KRVJBkQfXZfyWm8+2d0uggFuZg==", + "dependencies": { + "rrweb-snapshot": "^2.0.0-alpha.16" + } + }, "node_modules/@stencil/core": { "version": "4.9.0", "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.9.0.tgz", @@ -1281,6 +1292,11 @@ "npm": ">=7.10.0" } }, + "node_modules/@types/css-font-loading-module": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/@types/css-font-loading-module/-/css-font-loading-module-0.0.7.tgz", + "integrity": "sha512-nl09VhutdjINdWyXxHWN/w9zlNCfr60JUqJbd24YXUuCwgeL0TpFSdElCwb6cxfB6ybE19Gjj4g0jsgkXxKv1Q==" + }, "node_modules/@types/json-schema": { "version": "7.0.12", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", @@ -1293,6 +1309,12 @@ "integrity": "sha512-l5cpE57br4BIjK+9BSkFBOsWtwv6J9bJpC7gdXIzZyI0vuKvNTk0wZZrkQxMGsUAuGW9+WMNWF2IJMD7br2yeQ==", "dev": true }, + "node_modules/@types/mixpanel-browser": { + "version": "2.49.1", + "resolved": "https://registry.npmjs.org/@types/mixpanel-browser/-/mixpanel-browser-2.49.1.tgz", + "integrity": "sha512-W9VZxD7haNMenkRwXxPZBJLhED7Sx1l89nZsGcWi3WzdIk417k/KnpmfDFn2sEyL31G/h0rY1E6erAny+8ItOw==", + "dev": true + }, "node_modules/@types/node": { "version": "20.6.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz", @@ -1309,6 +1331,16 @@ "integrity": "sha512-7aqorHYgdNO4DM36stTiGO3DvKoex9TQRwsJU6vMaFGyqpBA1MNZkz+PG3gaNUPpTAOYhT1WR7M1JyA3fbS9Cw==", "dev": true }, + "node_modules/@types/vue": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/vue/-/vue-2.0.0.tgz", + "integrity": "sha512-WDElkBv/o4lVwu6wYHB06AXs4Xo2fwDjJUpvPRc1QQdzkUSiGFjrYuSCy8raxLE5FObgKq8ND7R5gSZTFLK60w==", + "deprecated": "This is a stub types definition for vuejs (https://github.com/vuejs/vue). vuejs provides its own type definitions, so you don't need @types/vue installed!", + "dev": true, + "dependencies": { + "vue": "*" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "5.62.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", @@ -1853,6 +1885,11 @@ "@vue/language-core": "1.8.11" } }, + "node_modules/@xstate/fsm": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@xstate/fsm/-/fsm-1.6.5.tgz", + "integrity": "sha512-b5o1I6aLNeYlU/3CPlj/Z91ybk1gUsKT+5NAJI+2W4UjvS5KLG28K9v5UvNoFVjHV8PajVZ00RH3vnjyQO7ZAw==" + }, "node_modules/acorn": { "version": "8.10.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", @@ -1938,6 +1975,14 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/big-integer": { "version": "1.6.51", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", @@ -2811,6 +2856,11 @@ "node": ">=0.8.0" } }, + "node_modules/fflate": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.4.8.tgz", + "integrity": "sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==" + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -3533,6 +3583,19 @@ "node": "*" } }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==" + }, + "node_modules/mixpanel-browser": { + "version": "2.53.0", + "resolved": "https://registry.npmjs.org/mixpanel-browser/-/mixpanel-browser-2.53.0.tgz", + "integrity": "sha512-8U7zCTT82yCIH2vfdCvs0ZRWlCgyHMuU4jtC6yOAiNUR4HhnQYk7re/o2GnhfdvYtkPxdda60/3eH1igUlIXuw==", + "dependencies": { + "rrweb": "2.0.0-alpha.13" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -4159,6 +4222,34 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "node_modules/rrdom": { + "version": "2.0.0-alpha.16", + "resolved": "https://registry.npmjs.org/rrdom/-/rrdom-2.0.0-alpha.16.tgz", + "integrity": "sha512-m8aoeORWUz7AFdEb7hES7wPeL6fl/oP23RoAlzLXyA/f2+NqCDM7KEyCXY4sHu6CChN3OAUP2BaUGEXn0zynlw==", + "dependencies": { + "rrweb-snapshot": "^2.0.0-alpha.16" + } + }, + "node_modules/rrweb": { + "version": "2.0.0-alpha.13", + "resolved": "https://registry.npmjs.org/rrweb/-/rrweb-2.0.0-alpha.13.tgz", + "integrity": "sha512-a8GXOCnzWHNaVZPa7hsrLZtNZ3CGjiL+YrkpLo0TfmxGLhjNZbWY2r7pE06p+FcjFNlgUVTmFrSJbK3kO7yxvw==", + "dependencies": { + "@rrweb/types": "^2.0.0-alpha.13", + "@types/css-font-loading-module": "0.0.7", + "@xstate/fsm": "^1.4.0", + "base64-arraybuffer": "^1.0.1", + "fflate": "^0.4.4", + "mitt": "^3.0.0", + "rrdom": "^2.0.0-alpha.13", + "rrweb-snapshot": "^2.0.0-alpha.13" + } + }, + "node_modules/rrweb-snapshot": { + "version": "2.0.0-alpha.16", + "resolved": "https://registry.npmjs.org/rrweb-snapshot/-/rrweb-snapshot-2.0.0-alpha.16.tgz", + "integrity": "sha512-p81OrzUiCmUMZzJu4fGHeLB00PIbVIqsV/zhqzr2pitHTUXpMYcyOvDWt0vHdla0vnowEPaHq3Wsu6cUc732/w==" + }, "node_modules/run-applescript": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", @@ -5831,11 +5922,24 @@ "picomatch": "^2.2.2" } }, + "@rrweb/types": { + "version": "2.0.0-alpha.16", + "resolved": "https://registry.npmjs.org/@rrweb/types/-/types-2.0.0-alpha.16.tgz", + "integrity": "sha512-E6cACNVsm+NUhn7dzocQoKyXI7BHrHRRm5Ab23yrAzEQ2caWocCEYJhqDlc4KRVJBkQfXZfyWm8+2d0uggFuZg==", + "requires": { + "rrweb-snapshot": "^2.0.0-alpha.16" + } + }, "@stencil/core": { "version": "4.9.0", "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.9.0.tgz", "integrity": "sha512-aWSkhBmk3yPwRAkUwBbzRwmdhb8hKiQ/JMr9m5jthpBZLjtppYbzz6PN2MhSMDfRp6K93eQw5WogSEH4HHuB6w==" }, + "@types/css-font-loading-module": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/@types/css-font-loading-module/-/css-font-loading-module-0.0.7.tgz", + "integrity": "sha512-nl09VhutdjINdWyXxHWN/w9zlNCfr60JUqJbd24YXUuCwgeL0TpFSdElCwb6cxfB6ybE19Gjj4g0jsgkXxKv1Q==" + }, "@types/json-schema": { "version": "7.0.12", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", @@ -5848,6 +5952,12 @@ "integrity": "sha512-l5cpE57br4BIjK+9BSkFBOsWtwv6J9bJpC7gdXIzZyI0vuKvNTk0wZZrkQxMGsUAuGW9+WMNWF2IJMD7br2yeQ==", "dev": true }, + "@types/mixpanel-browser": { + "version": "2.49.1", + "resolved": "https://registry.npmjs.org/@types/mixpanel-browser/-/mixpanel-browser-2.49.1.tgz", + "integrity": "sha512-W9VZxD7haNMenkRwXxPZBJLhED7Sx1l89nZsGcWi3WzdIk417k/KnpmfDFn2sEyL31G/h0rY1E6erAny+8ItOw==", + "dev": true + }, "@types/node": { "version": "20.6.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz", @@ -5864,6 +5974,15 @@ "integrity": "sha512-7aqorHYgdNO4DM36stTiGO3DvKoex9TQRwsJU6vMaFGyqpBA1MNZkz+PG3gaNUPpTAOYhT1WR7M1JyA3fbS9Cw==", "dev": true }, + "@types/vue": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/vue/-/vue-2.0.0.tgz", + "integrity": "sha512-WDElkBv/o4lVwu6wYHB06AXs4Xo2fwDjJUpvPRc1QQdzkUSiGFjrYuSCy8raxLE5FObgKq8ND7R5gSZTFLK60w==", + "dev": true, + "requires": { + "vue": "*" + } + }, "@typescript-eslint/eslint-plugin": { "version": "5.62.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", @@ -6253,6 +6372,11 @@ "@vue/language-core": "1.8.11" } }, + "@xstate/fsm": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@xstate/fsm/-/fsm-1.6.5.tgz", + "integrity": "sha512-b5o1I6aLNeYlU/3CPlj/Z91ybk1gUsKT+5NAJI+2W4UjvS5KLG28K9v5UvNoFVjHV8PajVZ00RH3vnjyQO7ZAw==" + }, "acorn": { "version": "8.10.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", @@ -6317,6 +6441,11 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==" + }, "big-integer": { "version": "1.6.51", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", @@ -6943,6 +7072,11 @@ "websocket-driver": ">=0.5.1" } }, + "fflate": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.4.8.tgz", + "integrity": "sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==" + }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -7480,6 +7614,19 @@ "brace-expansion": "^1.1.7" } }, + "mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==" + }, + "mixpanel-browser": { + "version": "2.53.0", + "resolved": "https://registry.npmjs.org/mixpanel-browser/-/mixpanel-browser-2.53.0.tgz", + "integrity": "sha512-8U7zCTT82yCIH2vfdCvs0ZRWlCgyHMuU4jtC6yOAiNUR4HhnQYk7re/o2GnhfdvYtkPxdda60/3eH1igUlIXuw==", + "requires": { + "rrweb": "2.0.0-alpha.13" + } + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -7881,6 +8028,34 @@ } } }, + "rrdom": { + "version": "2.0.0-alpha.16", + "resolved": "https://registry.npmjs.org/rrdom/-/rrdom-2.0.0-alpha.16.tgz", + "integrity": "sha512-m8aoeORWUz7AFdEb7hES7wPeL6fl/oP23RoAlzLXyA/f2+NqCDM7KEyCXY4sHu6CChN3OAUP2BaUGEXn0zynlw==", + "requires": { + "rrweb-snapshot": "^2.0.0-alpha.16" + } + }, + "rrweb": { + "version": "2.0.0-alpha.13", + "resolved": "https://registry.npmjs.org/rrweb/-/rrweb-2.0.0-alpha.13.tgz", + "integrity": "sha512-a8GXOCnzWHNaVZPa7hsrLZtNZ3CGjiL+YrkpLo0TfmxGLhjNZbWY2r7pE06p+FcjFNlgUVTmFrSJbK3kO7yxvw==", + "requires": { + "@rrweb/types": "^2.0.0-alpha.13", + "@types/css-font-loading-module": "0.0.7", + "@xstate/fsm": "^1.4.0", + "base64-arraybuffer": "^1.0.1", + "fflate": "^0.4.4", + "mitt": "^3.0.0", + "rrdom": "^2.0.0-alpha.13", + "rrweb-snapshot": "^2.0.0-alpha.13" + } + }, + "rrweb-snapshot": { + "version": "2.0.0-alpha.16", + "resolved": "https://registry.npmjs.org/rrweb-snapshot/-/rrweb-snapshot-2.0.0-alpha.16.tgz", + "integrity": "sha512-p81OrzUiCmUMZzJu4fGHeLB00PIbVIqsV/zhqzr2pitHTUXpMYcyOvDWt0vHdla0vnowEPaHq3Wsu6cUc732/w==" + }, "run-applescript": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", diff --git a/package.json b/package.json index 1b488b38..fc03502c 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "@ionic/vue": "^7.6.0", "firebase": "^10.3.1", "luxon": "^3.3.0", + "mixpanel-browser": "^2.53.0", "pinia": "2.0.36", "pinia-plugin-persistedstate": "^3.1.0", "register-service-worker": "^1.7.2", @@ -39,7 +40,9 @@ "devDependencies": { "@babel/types": "^7.22.11", "@types/luxon": "^3.3.0", + "@types/mixpanel-browser": "^2.49.1", "@types/node": "^20.5.7", + "@types/vue": "^2.0.0", "@vitejs/plugin-vue": "^4.3.4", "@vue/eslint-config-prettier": "^8.0.0", "@vue/eslint-config-typescript": "^11.0.3", diff --git a/src/index.ts b/src/index.ts index 74f81851..4bfc4c0b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -10,6 +10,8 @@ import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' import { createI18n } from 'vue-i18n' import { useUserStore } from "./store/user"; import { IonicVue } from '@ionic/vue'; +import useAnalytics from "./mixins/analytics"; + import "./service-worker" @@ -140,5 +142,6 @@ export { useAuthStore, useProductIdentificationStore, useUserStore, - userContext + userContext, + useAnalytics } diff --git a/src/mixins/analytics.ts b/src/mixins/analytics.ts new file mode 100644 index 00000000..71c2a2a3 --- /dev/null +++ b/src/mixins/analytics.ts @@ -0,0 +1,64 @@ +// composables/useAnalytics.ts + +import { onMounted, onBeforeUnmount } from 'vue'; +import mixpanel from 'mixpanel-browser'; +import { appContext } from '../index'; + +function useAnalytics() { + const handleButtonClick = (event: MouseEvent) => { + if (event.button === 0) { // Left mouse button + const target = event.target as HTMLElement; + const button = target.closest('button, ion-button') as HTMLElement; + + if (button && button.hasAttribute('trackable')) { + const buttonLabel = (button.innerText || button.getAttribute('aria-label') || 'Unnamed button') as string; + + mixpanel.track(buttonLabel, { + label: buttonLabel, + id: button.id || 'no-id', + }); + } + } + }; + onMounted(() => { + console.log('Initializing Mixpanel'); + + try { + mixpanel.init('5d1a58b28169000ca197c14274eddf87', { debug: true }); + } catch (error) { + console.error('Error initializing Mixpanel:', error); + return; + } + + const appState = appContext.config.globalProperties.$store; + + if (!appState) { + return; + } + + const userProfile = appState.getters['user/getUserProfile']; + + const userEmail = userProfile.email; + const userID = userProfile.userLoginId; + + console.log('User Profile:', { userID, userEmail }); + + try { + mixpanel.identify(userID); + mixpanel.people.set({ + $email: userEmail, + $userId: userID, + }); + } catch (error) { + return; + } + + document.addEventListener('click', handleButtonClick); + }); + + onBeforeUnmount(() => { + document.removeEventListener('click', handleButtonClick); + }); +} + +export default useAnalytics; diff --git a/tsconfig.json b/tsconfig.json index 30d820a7..21186a51 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,18 @@ { "compilerOptions": { "baseUrl": ".", - "strictNullChecks": false + "strictNullChecks": false, + "target": "esnext", + "module": "esnext", + "moduleResolution": "node", + "strict": true, + "isolatedModules": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "importsNotUsedAsValues": "error", + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, }, "include": [ "src/**/*.ts", From 679c00681190f2fdfe18e9430bb22607620aba6e Mon Sep 17 00:00:00 2001 From: Ridwa Date: Tue, 16 Jul 2024 15:54:44 +0530 Subject: [PATCH 2/6] Improved: Made suggested changes in fetching ButtonLabel (#285) --- src/mixins/analytics.ts | 38 ++++++++++++++++++++++++++++++++++---- tsconfig.json | 13 +------------ 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/mixins/analytics.ts b/src/mixins/analytics.ts index 71c2a2a3..45ccb365 100644 --- a/src/mixins/analytics.ts +++ b/src/mixins/analytics.ts @@ -4,27 +4,48 @@ import { onMounted, onBeforeUnmount } from 'vue'; import mixpanel from 'mixpanel-browser'; import { appContext } from '../index'; +interface TrackableMetadata { + label?: string; + id?: string; + [key: string]: any; // Allow other properties as well +} + function useAnalytics() { const handleButtonClick = (event: MouseEvent) => { if (event.button === 0) { // Left mouse button const target = event.target as HTMLElement; const button = target.closest('button, ion-button') as HTMLElement; - + if (button && button.hasAttribute('trackable')) { - const buttonLabel = (button.innerText || button.getAttribute('aria-label') || 'Unnamed button') as string; - + const trackableData = button.getAttribute('trackable'); + let metadata: TrackableMetadata = {}; + + try { + metadata = trackableData ? JSON.parse(trackableData) : {}; + } catch (error) { + console.error('Error parsing trackable attribute:', error); + } + + const buttonLabel = metadata.label || button.innerText || button.getAttribute('aria-label') || 'Unnamed button'; + const buttonId = button.id || metadata.id || 'no-id'; + + console.log('Trackable Button Clicked:', { label: buttonLabel, id: buttonId }); + mixpanel.track(buttonLabel, { label: buttonLabel, - id: button.id || 'no-id', + id: buttonId, + ...metadata, }); } } }; + onMounted(() => { console.log('Initializing Mixpanel'); try { mixpanel.init('5d1a58b28169000ca197c14274eddf87', { debug: true }); + console.log('Mixpanel initialized'); } catch (error) { console.error('Error initializing Mixpanel:', error); return; @@ -33,11 +54,17 @@ function useAnalytics() { const appState = appContext.config.globalProperties.$store; if (!appState) { + console.error('appState is not defined'); return; } const userProfile = appState.getters['user/getUserProfile']; + if (!userProfile) { + console.error('userProfile is not defined'); + return; + } + const userEmail = userProfile.email; const userID = userProfile.userLoginId; @@ -50,14 +77,17 @@ function useAnalytics() { $userId: userID, }); } catch (error) { + console.error('Error identifying user in Mixpanel:', error); return; } document.addEventListener('click', handleButtonClick); + console.log('Event listener added for button clicks'); }); onBeforeUnmount(() => { document.removeEventListener('click', handleButtonClick); + console.log('Event listener removed for button clicks'); }); } diff --git a/tsconfig.json b/tsconfig.json index 21186a51..30d820a7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,18 +1,7 @@ { "compilerOptions": { "baseUrl": ".", - "strictNullChecks": false, - "target": "esnext", - "module": "esnext", - "moduleResolution": "node", - "strict": true, - "isolatedModules": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "importsNotUsedAsValues": "error", - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true, + "strictNullChecks": false }, "include": [ "src/**/*.ts", From 1b9ebaf084ee8f402ac783dbef7d8a4a0f166788 Mon Sep 17 00:00:00 2001 From: Ridwa Date: Tue, 16 Jul 2024 16:29:30 +0530 Subject: [PATCH 3/6] Improved: removed console logs(#285) --- src/mixins/analytics.ts | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/src/mixins/analytics.ts b/src/mixins/analytics.ts index 45ccb365..1f106784 100644 --- a/src/mixins/analytics.ts +++ b/src/mixins/analytics.ts @@ -1,5 +1,3 @@ -// composables/useAnalytics.ts - import { onMounted, onBeforeUnmount } from 'vue'; import mixpanel from 'mixpanel-browser'; import { appContext } from '../index'; @@ -7,7 +5,7 @@ import { appContext } from '../index'; interface TrackableMetadata { label?: string; id?: string; - [key: string]: any; // Allow other properties as well + [key: string]: any; } function useAnalytics() { @@ -29,8 +27,6 @@ function useAnalytics() { const buttonLabel = metadata.label || button.innerText || button.getAttribute('aria-label') || 'Unnamed button'; const buttonId = button.id || metadata.id || 'no-id'; - console.log('Trackable Button Clicked:', { label: buttonLabel, id: buttonId }); - mixpanel.track(buttonLabel, { label: buttonLabel, id: buttonId, @@ -45,31 +41,15 @@ function useAnalytics() { try { mixpanel.init('5d1a58b28169000ca197c14274eddf87', { debug: true }); - console.log('Mixpanel initialized'); } catch (error) { - console.error('Error initializing Mixpanel:', error); return; } const appState = appContext.config.globalProperties.$store; - - if (!appState) { - console.error('appState is not defined'); - return; - } - const userProfile = appState.getters['user/getUserProfile']; - - if (!userProfile) { - console.error('userProfile is not defined'); - return; - } - const userEmail = userProfile.email; const userID = userProfile.userLoginId; - console.log('User Profile:', { userID, userEmail }); - try { mixpanel.identify(userID); mixpanel.people.set({ @@ -77,17 +57,14 @@ function useAnalytics() { $userId: userID, }); } catch (error) { - console.error('Error identifying user in Mixpanel:', error); return; } document.addEventListener('click', handleButtonClick); - console.log('Event listener added for button clicks'); }); onBeforeUnmount(() => { document.removeEventListener('click', handleButtonClick); - console.log('Event listener removed for button clicks'); }); } From cdf5de99e3cc66de80494907cc330f557a33afc9 Mon Sep 17 00:00:00 2001 From: Ridwa Date: Wed, 17 Jul 2024 11:23:53 +0530 Subject: [PATCH 4/6] Implemented: setted OMS property to be tracked in mix-panel --- src/mixins/analytics.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/mixins/analytics.ts b/src/mixins/analytics.ts index 1f106784..af04dd15 100644 --- a/src/mixins/analytics.ts +++ b/src/mixins/analytics.ts @@ -1,6 +1,7 @@ -import { onMounted, onBeforeUnmount } from 'vue'; +import { onMounted, onBeforeUnmount , computed } from 'vue'; import mixpanel from 'mixpanel-browser'; import { appContext } from '../index'; +import { useAuthStore } from '../index'; interface TrackableMetadata { label?: string; @@ -13,6 +14,8 @@ function useAnalytics() { if (event.button === 0) { // Left mouse button const target = event.target as HTMLElement; const button = target.closest('button, ion-button') as HTMLElement; + const authStore = useAuthStore(); + const oms = computed(() => authStore.getOms) if (button && button.hasAttribute('trackable')) { const trackableData = button.getAttribute('trackable'); @@ -28,6 +31,7 @@ function useAnalytics() { const buttonId = button.id || metadata.id || 'no-id'; mixpanel.track(buttonLabel, { + oms : oms.value, label: buttonLabel, id: buttonId, ...metadata, @@ -44,7 +48,8 @@ function useAnalytics() { } catch (error) { return; } - + const authStore = useAuthStore(); + const oms = computed(() => authStore.getOms) const appState = appContext.config.globalProperties.$store; const userProfile = appState.getters['user/getUserProfile']; const userEmail = userProfile.email; @@ -55,6 +60,7 @@ function useAnalytics() { mixpanel.people.set({ $email: userEmail, $userId: userID, + $oms : oms.value }); } catch (error) { return; From 65cd403a65d68cd8fd433be79dc9ae0eda65402f Mon Sep 17 00:00:00 2001 From: Ridwa Date: Tue, 30 Jul 2024 15:01:10 +0530 Subject: [PATCH 5/6] Fixed: fixed token for mixpanel , looked after indentation(#310) --- src/mixins/analytics.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/mixins/analytics.ts b/src/mixins/analytics.ts index af04dd15..8e75de69 100644 --- a/src/mixins/analytics.ts +++ b/src/mixins/analytics.ts @@ -1,7 +1,7 @@ -import { onMounted, onBeforeUnmount , computed } from 'vue'; +import { computed, onMounted, onBeforeUnmount } from 'vue'; import mixpanel from 'mixpanel-browser'; -import { appContext } from '../index'; import { useAuthStore } from '../index'; +import { appContext } from '../index'; interface TrackableMetadata { label?: string; @@ -13,25 +13,25 @@ function useAnalytics() { const handleButtonClick = (event: MouseEvent) => { if (event.button === 0) { // Left mouse button const target = event.target as HTMLElement; - const button = target.closest('button, ion-button') as HTMLElement; + const button = target.closest('button, ion-button, ion-item') as HTMLElement; const authStore = useAuthStore(); - const oms = computed(() => authStore.getOms) - + const oms = computed(() => authStore.getOms); + if (button && button.hasAttribute('trackable')) { const trackableData = button.getAttribute('trackable'); let metadata: TrackableMetadata = {}; - + try { metadata = trackableData ? JSON.parse(trackableData) : {}; } catch (error) { console.error('Error parsing trackable attribute:', error); } - + const buttonLabel = metadata.label || button.innerText || button.getAttribute('aria-label') || 'Unnamed button'; const buttonId = button.id || metadata.id || 'no-id'; - + console.log('Button clicked:', event); mixpanel.track(buttonLabel, { - oms : oms.value, + oms: oms.value, label: buttonLabel, id: buttonId, ...metadata, @@ -44,12 +44,12 @@ function useAnalytics() { console.log('Initializing Mixpanel'); try { - mixpanel.init('5d1a58b28169000ca197c14274eddf87', { debug: true }); + mixpanel.init('1d60dbd4447efd425c428afe044012e3', { debug: true }); } catch (error) { return; - } + } const authStore = useAuthStore(); - const oms = computed(() => authStore.getOms) + const oms = computed(() => authStore.getOms); const appState = appContext.config.globalProperties.$store; const userProfile = appState.getters['user/getUserProfile']; const userEmail = userProfile.email; @@ -60,7 +60,7 @@ function useAnalytics() { mixpanel.people.set({ $email: userEmail, $userId: userID, - $oms : oms.value + $oms: oms.value }); } catch (error) { return; From d214534f2124dc8696a0388c7367bc0adfe457e5 Mon Sep 17 00:00:00 2001 From: Ridwa Date: Wed, 31 Jul 2024 11:39:25 +0530 Subject: [PATCH 6/6] fixed: fixed code in context of memory leak , added comments and used method to stop propogation up the DOM tree (#310) --- src/mixins/analytics.ts | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/mixins/analytics.ts b/src/mixins/analytics.ts index 8e75de69..9bb20e61 100644 --- a/src/mixins/analytics.ts +++ b/src/mixins/analytics.ts @@ -2,8 +2,9 @@ import { computed, onMounted, onBeforeUnmount } from 'vue'; import mixpanel from 'mixpanel-browser'; import { useAuthStore } from '../index'; import { appContext } from '../index'; +declare var process: any; -interface TrackableMetadata { +interface TrackableMetadata { //defining the interface for trackable metadata label?: string; id?: string; [key: string]: any; @@ -11,15 +12,16 @@ interface TrackableMetadata { function useAnalytics() { const handleButtonClick = (event: MouseEvent) => { + event.stopPropagation(); //method to stop the click event from propagating up the DOM tree if (event.button === 0) { // Left mouse button const target = event.target as HTMLElement; - const button = target.closest('button, ion-button, ion-item') as HTMLElement; + const button = target.closest('ion-button, ion-item') as HTMLElement; //finds the closest parent element that matches the selectors ion-button or ion-item const authStore = useAuthStore(); const oms = computed(() => authStore.getOms); if (button && button.hasAttribute('trackable')) { const trackableData = button.getAttribute('trackable'); - let metadata: TrackableMetadata = {}; + let metadata: TrackableMetadata = {}; //object initialization for trackable metadata try { metadata = trackableData ? JSON.parse(trackableData) : {}; @@ -29,7 +31,6 @@ function useAnalytics() { const buttonLabel = metadata.label || button.innerText || button.getAttribute('aria-label') || 'Unnamed button'; const buttonId = button.id || metadata.id || 'no-id'; - console.log('Button clicked:', event); mixpanel.track(buttonLabel, { oms: oms.value, label: buttonLabel, @@ -41,19 +42,18 @@ function useAnalytics() { }; onMounted(() => { - console.log('Initializing Mixpanel'); - try { - mixpanel.init('1d60dbd4447efd425c428afe044012e3', { debug: true }); + mixpanel.init( process.env.VUE_APP_MIXPANEL_TOKEN , { debug: true }); } catch (error) { + console.log(error); return; } const authStore = useAuthStore(); const oms = computed(() => authStore.getOms); const appState = appContext.config.globalProperties.$store; - const userProfile = appState.getters['user/getUserProfile']; - const userEmail = userProfile.email; - const userID = userProfile.userLoginId; + const userProfile = appState.getters['user/getUserProfile']; //retrieves the user profile using a Vuex getter. + const userEmail = userProfile.email; //fetch user email from userProfile + const userID = userProfile.userLoginId; // fetch user ID from userProfile try { mixpanel.identify(userID); @@ -63,14 +63,15 @@ function useAnalytics() { $oms: oms.value }); } catch (error) { + console.log(error); return; } - document.addEventListener('click', handleButtonClick); + document.addEventListener('click', handleButtonClick); //adds the event listener }); onBeforeUnmount(() => { - document.removeEventListener('click', handleButtonClick); + document.removeEventListener('click', handleButtonClick); //removes the event listener , to prevent memory leaks }); }