Merged in feature/IO-3325-amplitude (pull request #2500)

IO-3325 Add amplitude tracking.
This commit is contained in:
Patrick Fic
2025-08-22 17:40:33 +00:00
5 changed files with 1884 additions and 1033 deletions

2846
client/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -8,6 +8,7 @@
"private": true, "private": true,
"proxy": "http://localhost:4000", "proxy": "http://localhost:4000",
"dependencies": { "dependencies": {
"@amplitude/analytics-browser": "^2.23.1",
"@ant-design/pro-layout": "^7.22.6", "@ant-design/pro-layout": "^7.22.6",
"@apollo/client": "^3.13.9", "@apollo/client": "^3.13.9",
"@emotion/is-prop-valid": "^1.3.1", "@emotion/is-prop-valid": "^1.3.1",

View File

@@ -4,6 +4,7 @@ import { getAuth, updatePassword, updateProfile } from "@firebase/auth";
import { getFirestore } from "@firebase/firestore"; import { getFirestore } from "@firebase/firestore";
import { getMessaging, getToken, onMessage } from "@firebase/messaging"; import { getMessaging, getToken, onMessage } from "@firebase/messaging";
import { store } from "../redux/store"; import { store } from "../redux/store";
import * as amplitude from '@amplitude/analytics-browser';
const config = JSON.parse(import.meta.env.VITE_APP_FIREBASE_CONFIG); const config = JSON.parse(import.meta.env.VITE_APP_FIREBASE_CONFIG);
initializeApp(config); initializeApp(config);
@@ -71,25 +72,31 @@ onMessage(messaging, (payload) => {
}); });
export const logImEXEvent = (eventName, additionalParams, stateProp = null) => { export const logImEXEvent = (eventName, additionalParams, stateProp = null) => {
const state = stateProp || store.getState(); try {
const eventParams = {
shop: (state.user && state.user.bodyshop && state.user.bodyshop.shopname) || null, const state = stateProp || store.getState();
user: (state.user && state.user.currentUser && state.user.currentUser.email) || null, const eventParams = {
...additionalParams shop: (state.user && state.user.bodyshop && state.user.bodyshop.shopname) || null,
}; user: (state.user && state.user.currentUser && state.user.currentUser.email) || null,
// axios.post("/ioevent", { ...additionalParams
// useremail: (state.user && state.user.currentUser && state.user.currentUser.email) || null, };
// bodyshopid: (state.user && state.user.bodyshop && state.user.bodyshop.id) || null, // axios.post("/ioevent", {
// operationName: eventName, // useremail: (state.user && state.user.currentUser && state.user.currentUser.email) || null,
// variables: additionalParams, // bodyshopid: (state.user && state.user.bodyshop && state.user.bodyshop.id) || null,
// dbevent: false, // operationName: eventName,
// env: `master-AIO|${import.meta.env.VITE_APP_GIT_SHA_DATE}` // variables: additionalParams,
// }); // dbevent: false,
// console.log( // env: `master-AIO|${import.meta.env.VITE_APP_GIT_SHA_DATE}`
// "%c[Analytics]", // });
// "background-color: green ;font-weight:bold;", // console.log(
// eventName, // "%c[Analytics]",
// eventParams // "background-color: green ;font-weight:bold;",
// ); // eventName,
logEvent(analytics, eventName, eventParams); // eventParams
// );
logEvent(analytics, eventName, eventParams);
amplitude.track(eventName, eventParams);
} finally {
//If it fails, just keep going.
}
}; };

View File

@@ -14,7 +14,7 @@ import { persistor, store } from "./redux/store";
import reportWebVitals from "./reportWebVitals"; import reportWebVitals from "./reportWebVitals";
import "./translations/i18n"; import "./translations/i18n";
import "./utils/CleanAxios"; import "./utils/CleanAxios";
import * as amplitude from "@amplitude/analytics-browser";
window.global ||= window; window.global ||= window;
registerSW({ immediate: true }); registerSW({ immediate: true });
@@ -23,10 +23,10 @@ registerSW({ immediate: true });
// Dinero.globalLocale = "en-CA"; // Dinero.globalLocale = "en-CA";
Dinero.globalRoundingMode = "HALF_EVEN"; Dinero.globalRoundingMode = "HALF_EVEN";
amplitude.init("6228a598e57cd66875cfd41604f1f891", {});
const sentryCreateBrowserRouter = Sentry.wrapCreateBrowserRouterV6(createBrowserRouter); const sentryCreateBrowserRouter = Sentry.wrapCreateBrowserRouterV6(createBrowserRouter);
const router = sentryCreateBrowserRouter(createRoutesFromElements(<Route path="*" element={<AppContainer />} />)); const router = sentryCreateBrowserRouter(createRoutesFromElements(<Route path="*" element={<AppContainer />} />));
if (import.meta.env.DEV) { if (import.meta.env.DEV) {
let styles = let styles =
"font-weight: bold; font-size: 50px;color: red; 6px 6px 0 rgb(226,91,14) , 9px 9px 0 rgb(245,221,8) , 12px 12px 0 rgb(5,148,68) "; "font-weight: bold; font-size: 50px;color: red; 6px 6px 0 rgb(226,91,14) , 9px 9px 0 rgb(245,221,8) , 12px 12px 0 rgb(5,148,68) ";

View File

@@ -49,6 +49,7 @@ import {
validatePasswordResetSuccess validatePasswordResetSuccess
} from "./user.actions"; } from "./user.actions";
import UserActionTypes from "./user.types"; import UserActionTypes from "./user.types";
import * as amplitude from '@amplitude/analytics-browser';
const fpPromise = FingerprintJS.load(); const fpPromise = FingerprintJS.load();
@@ -83,8 +84,6 @@ export function* onCheckUserSession() {
export function* isUserAuthenticated() { export function* isUserAuthenticated() {
try { try {
logImEXEvent("redux_auth_check");
const user = yield getCurrentUser(); const user = yield getCurrentUser();
if (!user) { if (!user) {
yield put(unauthorizedUser()); yield put(unauthorizedUser());
@@ -92,6 +91,7 @@ export function* isUserAuthenticated() {
} }
LogRocket.identify(user.email); LogRocket.identify(user.email);
amplitude.setUserId(user.email)
const eulaQuery = yield client.query({ const eulaQuery = yield client.query({
query: QUERY_EULA, query: QUERY_EULA,
@@ -137,6 +137,7 @@ export function* signOutStart() {
imexshopid: state.user.bodyshop.imexshopid, imexshopid: state.user.bodyshop.imexshopid,
type: "messaging" type: "messaging"
}); });
amplitude.reset();
} catch { } catch {
console.log("No FCM token. Skipping unsubscribe."); console.log("No FCM token. Skipping unsubscribe.");
} }
@@ -266,11 +267,11 @@ export function* signInSuccessSaga({ payload }) {
instanceSeg, instanceSeg,
...(isParts ...(isParts
? [ ? [
InstanceRenderManager({ InstanceRenderManager({
imex: "ImexPartsManagement", imex: "ImexPartsManagement",
rome: "RomePartsManagement" rome: "RomePartsManagement"
}) })
] ]
: []) : [])
]; ];
window.$crisp.push(["set", "session:segments", [segs]]); window.$crisp.push(["set", "session:segments", [segs]]);
@@ -295,7 +296,6 @@ export function* signInSuccessSaga({ payload }) {
setUserId(analytics, payload.email); setUserId(analytics, payload.email);
setUserProperties(analytics, payload); setUserProperties(analytics, payload);
yield logImEXEvent("redux_sign_in_success");
} }
export function* onSendPasswordResetStart() { export function* onSendPasswordResetStart() {
@@ -362,6 +362,7 @@ export function* SetAuthLevelFromShopDetails({ payload }) {
} }
try { try {
amplitude.setGroup('Shop', payload.shopname);
window.$crisp.push(["set", "user:company", [payload.shopname]]); window.$crisp.push(["set", "user:company", [payload.shopname]]);
if (authRecord[0] && authRecord[0].user.validemail) { if (authRecord[0] && authRecord[0].user.validemail) {
window.$crisp.push(["set", "user:email", [authRecord[0].user.email]]); window.$crisp.push(["set", "user:email", [authRecord[0].user.email]]);