From 02b3e3c3f93cdc87cfd90705e1969689b3683816 Mon Sep 17 00:00:00 2001 From: Jeremy-Z Date: Mon, 16 Mar 2026 12:20:21 -0400 Subject: [PATCH 1/9] Initial digital session logging commits. --- src/constants/endpoints.js | 8 ++ src/mixins/analytics-mixin.js | 172 ++++++++++++++++++++++++++++++++++ src/router/index.js | 6 ++ src/store/index.js | 160 +++++++++++++++++++++++++++++++ 4 files changed, 346 insertions(+) diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index 057ef9e4..897f9873 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -181,6 +181,14 @@ const endpoints = Object.freeze({ url: `${ANALYTICS_BASE_URL}/initialize`, method: 'POST' }, + LogDigitalConsumer: { + url: "/analytics/api/v1/analytics/digitalconsumer-log", + method: "POST", + }, + LogIssSessionData: { + url: "/analytics/api/v1/analytics/digitalconsumer-session-logging", + method: "POST", + }, GetExperimentsByUser: { url: `${ANALYTICS_BASE_URL}/get-experiments`, method: 'GET' diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index 297bb8e2..71477ca2 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -161,6 +161,178 @@ export default { return baseMethod.apply(object, arguments); }; }, + + logDigitalConsumer() { + const store = useMainStore(); + const currentPageName = this.getPageNameByQueryString(); + const universes = store.applicationUser.experiments; + const deviceId = getDeviceIdValue(); // cookieNames.DXDEV + const userId = getUserIdValue(); // cookieNames.ISS_USER_ID + const sid = getSessionIdValue(); // cookieNames.SESSION_ID + + const variationNames = universes + .filter((item) => item.universeName === experimentSettings.CONCEPT_FUNNEL) + .map((item) => item.variationName) + .filter(Boolean); // removes undefined/null + + const conceptVariation = variationNames.length > 0 ? variationNames[0] : ""; + + const isConceptExposed = universes.find( + (item) => item.universeName === experimentSettings.CONCEPT_FUNNEL + )?.isExposed; + + // TODO: Find equivalent ISS methods for these: + const submittedOrder = null;//baseMixin.methods.getSubmittedOrder(); + const hasSubmittedOrder = false;//baseMixin.methods.hasSubmittedOrder(); + const hasSubmittedOrderAtConfirmationPage = + hasSubmittedOrder && currentPageName?.toLowerCase() == routeData.CONFIRMATION.name; + + var payload = { + deviceId: deviceId, + sessionId: sid, + actionName: `Browser page:${currentPageName}`, + referralSequenceNumber: hasSubmittedOrderAtConfirmationPage + ? submittedOrder.referralSequenceNumber + : store.order.referralSequenceNumber, + referralNumber: hasSubmittedOrderAtConfirmationPage + ? submittedOrder.referralNumber + : store.order.referralNumber, + workOrderId: hasSubmittedOrderAtConfirmationPage + ? submittedOrder.workOrderId + : store.order.workOrderId, + workOrderNumber: hasSubmittedOrderAtConfirmationPage + ? submittedOrder.workOrderNumber + : store.order.workOrderNumber, + conceptVariation: conceptVariation, + isConceptExposed: isConceptExposed, + }; + + store.logDigitalConsumer(payload); + }, + + // This sends session data to the session logging endpoint on the analytics service. + // From there, it uses aws kinesis data stream, DigitalConsumer-Session-Data-Stream, + // and aws FireHose stream, DigitalConsumer-Session-Firehose, to push data to an + // S3 bucket, safelite-dev-digitalconsumer-session-data-us-east-2/1. + // This bucket data is then picked up by snowflake for analytics use. + pushIssSessionData() { + const store = useMainStore(); + const hasSubmittedOrder = baseMixin.methods.hasSubmittedOrder(); + const submittedOrder = baseMixin.methods.getSubmittedOrder(); + const order = hasSubmittedOrder ? submittedOrder : store.order; + + const hasSubmittedApplicationUser = baseMixin.methods.hasSubmittedApplicationUser(); + const submittedApplicationUser = baseMixin.methods.getSubmittedApplicationUser(); + const applicationUser = hasSubmittedApplicationUser + ? submittedApplicationUser + : store.applicationUser; + + const isEarlyBird = order?.lineItems?.supportingItems?.find( + (lineItem) => lineItem.partType == partTypeStrings.EARLY_BIRD + ); + + const promoCodes = Array.isArray(order?.lineItems?.promos) + ? order?.lineItems?.promos + .map((item) => item.promoCode) + .filter((code) => code) + .join(", ") + : null; + + const glassProducts = order?.damage?.glassToReplace?.map( + (part) => `${part.glassLocation}-${part.glassName}` + ); + + const format = (part) => `${part?.partNumber}-${part?.partType ? part.partType : ""}`; + const mapParts = (arr) => (arr ?? []).map(format); + + const glassParts = mapParts(order?.lineItems?.glassParts); + const supportingItems = mapParts(order?.lineItems?.supportingItems); + const vaps = mapParts(order?.lineItems?.vaps); + const childParts = [].concat( + ...(order?.lineItems?.glassParts ?? []).map((gp) => mapParts(gp?.childParts)) + ); + const allParts = [...glassParts, ...supportingItems, ...vaps, ...childParts]; + + if (applicationUser?.pageData?.quote?.servicePackageSelected) { + allParts.push(applicationUser.pageData.quote.servicePackageSelected); + } + + var appointment = `${order?.schedule?.date ?? ""} ${order?.schedule?.startTime ?? ""}`; + var currentPageName = this.getPageNameByQueryString(); +/* + // add query strings to the page name for debugging. on the vehicle page, if from an external link, pull it from the stash + if (currentPageName === "vehicle") { + if (!window.location.search) { + if (store.getters.externalParameterState?.qsStash) { + currentPageName += `${store.getters.externalParameterState.qsStash}`; + } + } else { + currentPageName += `${window.location.search}`; + } + } else { + if (window.location.search) { + currentPageName += `${window.location.search}`; + } + } +*/ + var sessionData = {}; + sessionData.currentPage = currentPageName; + sessionData.sid = getSessionIdValue(); + sessionData.deviceId = getDeviceIdValue(); + sessionData.fmgSessionId = applicationUser?.savedSessionId; + sessionData.skey = getskeyValue().toString(); + sessionData.userId = getUserIdValue(); + sessionData.carId = order?.vehicle?.carId; + sessionData.vehicleYear = order?.vehicle?.year; + sessionData.vehicleMake = order?.vehicle?.make; + sessionData.vehicleModel = order?.vehicle?.model; + sessionData.vehicleStyle = order?.vehicle?.style; + sessionData.hasVin = order?.vehicle?.vin ? true : false; + sessionData.cashOrInsuranceAccountType = order?.payment?.isInsurance + ? "Insurance" + : "Cash"; + sessionData.damageType = order?.damage?.isRepair ? "Repair" : "Replace"; + sessionData.productType = allParts; + sessionData.eon = order?.eon; + sessionData.referralNumber = order?.referralNumber; + sessionData.referralSequenceNumber = order?.referralSequenceNumber; + sessionData.referralDate = order?.referralDate; + sessionData.workOrderNumber = order?.workOrderNumber; + sessionData.workOrderId = order?.workOrderId; + sessionData.isPia = order?.payment?.isPia ?? false; + sessionData.piaType = order?.payment?.piaType; + sessionData.parentAccountNumber = order?.payment?.parentAccountNumber; + sessionData.billToAccountNumber = order?.payment?.billToAccountNumber; + sessionData.settledTenderAmount = order?.settledTenderAmount; + sessionData.recalRequired = containsRecalParts(order?.lineItems); + sessionData.recalType = getRecalPartNumbers(order?.lineItems?.glassParts); + sessionData.serviceZipCode = order?.serviceLocation?.provider?.address?.zipCode + ? order?.serviceLocation?.provider?.address?.zipCode + : order?.serviceLocation?.zipCode; + sessionData.providerCtu = order?.serviceLocation?.provider?.address?.zipCodeCtu + ? order?.serviceLocation?.provider?.address?.zipCodeCtu + : order?.serviceLocation?.zipCodeCtu; + sessionData.appointmentDate = appointment; + sessionData.serviceType = order?.serviceLocation?.appointmentType; + sessionData.promoCodes = promoCodes; + sessionData.hasTechnicianNotes = order?.serviceLocation?.techNotes ? true : false; + sessionData.paymentMethod = order?.payment?.piaType; + sessionData.isTextingOptedIn = order?.customer?.isSmsOptIn ? true : false; + sessionData.isEarlyBird = isEarlyBird ? true : false; + sessionData.insuranceCo = order?.policy?.insuranceCompanyName; + sessionData.deductible = order?.policy?.currentDeductible; + sessionData.isVerified = order?.payment?.insuranceCoverage?.isVerified ?? false; + sessionData.coverageStatus = order?.payment?.insuranceCoverage?.coverageStatus; + sessionData.coverageSubStatus = order?.payment?.insuranceCoverage?.coverageSubStatus; + sessionData.isNoComp = order?.policy?.isNoComp; + sessionData.isItac = order?.policy?.isItac; + sessionData.subTotalPrice = getSubTotal(order?.lineItems); + sessionData.totalPrice = getAmountDue(order?.lineItems, true); + sessionData.userAgent = navigator.userAgent; + sessionData.cashPriceSubTotal = order?.cashPriceSubTotal; + + store.logIssSessionData(sessionData); + }, async initSession() { regenerateDeviceId(); diff --git a/src/router/index.js b/src/router/index.js index c6a18493..3b7b205f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -178,6 +178,12 @@ router.afterEach(async (to, from) => { if (to.query.issPage !== issPageValues.ENTRY_PAGE) { document.title = routerTitles[to.query.issPage] || 'Safelite Solutions®'; + // digital consumer logging + analyticsMixin.methods.logDigitalConsumer(); + + // digital consumer ISS session logging to snowflake + //analyticsMixin.methods.pushIssSessionData(); + // Push page view to GA analyticsMixin.methods.pushPageViewToGA(); diff --git a/src/store/index.js b/src/store/index.js index 59df6e99..963929b1 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -2622,6 +2622,166 @@ export const useMainStore = defineStore({ updateTriggeredSiteEntry(wasSiteEntryTriggered) { this.applicationUser.triggeredSiteEntry = wasSiteEntryTriggered; }, + + logDigitalConsumer( + { + deviceId, + sessionId, + actionName, + referralSequenceNumber, + referralNumber, + workOrderId, + workOrderNumber, + conceptVariation, + isConceptExposed, + } + ) { + var payload = { + sessionId: sessionId, + deviceId: deviceId, + actionName: actionName ?? "", + referralSequenceNumber: referralSequenceNumber ?? "", + referralNumber: referralNumber ?? "", + applicationName: "ISS", //baseMixin.methods.isMobileDevice() ? "2.0 Mobile" : "2.0", + workOrderId: workOrderId ?? "", + workOrderNumber: workOrderNumber ?? "", + conceptVariation: conceptVariation, + isConceptExposed: isConceptExposed, + }; + + console.error("Logging Digital Consumer Action: ", payload); + + return globalMethods.callHttpClient({ + method: endpoints.LogDigitalConsumer.method, + endpoint: endpoints.LogDigitalConsumer.url, + payload, + logApiCall: false, + bailoutOnError: false + }).then( + (response) => response, + (error) => { + console.log(`Analytics Service Error: ${error.data}`); + } + ); + }, + + logIssSessionData( + { + currentPage, + sid, + deviceId, + issSessionId, + skey, + userId, + carId, + vehicleYear, + vehicleMake, + vehicleModel, + vehicleStyle, + hasVin, + cashOrInsuranceAccountType, + damageType, + productType, + eon, + referralNumber, + referralSequenceNumber, + referralDate, + workOrderNumber, + workOrderId, + isPia, + piaType, + parentAccountNumber, + billToAccountNumber, + settledTenderAmount, + recalRequired, + recalType, + serviceZipCode, + providerCtu, + appointmentDate, + serviceType, + promoCodes, + hasTechnicianNotes, + paymentMethod, + isTextingOptedIn, + isEarlyBird, + insuranceCo, + deductible, + isVerified, + coverageStatus, + coverageSubStatus, + isNoComp, + isItac, + subTotalPrice, + totalPrice, + userAgent, + cashPriceSubTotal, + } + ) { + var payload = { + currentPage: currentPage, + sid: sid, + deviceId: deviceId, + fmgSessionId: issSessionId, + skey: skey, + userId: userId, + carId: carId, + vehicleYear: vehicleYear, + vehicleMake: vehicleMake, + vehicleModel: vehicleModel, + vehicleStyle: vehicleStyle, + hasVin: hasVin, + cashOrInsuranceAccountType: cashOrInsuranceAccountType, + isVerified: isVerified, + coverageStatus: coverageStatus, + coverageSubStatus: coverageSubStatus, + damageType: damageType, + productType: productType, + eon: eon, + referralNumber: referralNumber, + referralSequenceNumber: referralSequenceNumber, + referralDate: referralDate, + workOrderNumber: workOrderNumber, + workOrderId: workOrderId, + isPia: isPia, + piaType: piaType, + parentAccountNumber: parentAccountNumber, + settledTenderAmount: settledTenderAmount, + recalRequired: recalRequired, + recalType: recalType, + serviceZipCode: serviceZipCode, + providerCtu: providerCtu, + appointmentDate: appointmentDate, + serviceType: serviceType, + promoCodes: promoCodes, + hasTechnicianNotes: hasTechnicianNotes, + paymentMethod: paymentMethod, + isTextingOptedIn: isTextingOptedIn, + isEarlyBird: isEarlyBird, + insuranceCo: insuranceCo, + deductible: deductible, + isNoComp: isNoComp, + isItac: isItac, + subTotalPrice: subTotalPrice, + totalPrice: totalPrice, + userAgent: userAgent, + cashPriceSubTotal: cashPriceSubTotal, + billToAccountNumber: billToAccountNumber, + }; + + return globalMethods.callHttpClient({ + method: endpoints.LogIssSessionData.method, + endpoint: endpoints.LogIssSessionData.url, + payload, + logApiCall: false, + bailoutOnError: false + }).then( + (response) => response, + (error) => { + console.log(`Analytics Service Error: ${error.data}`); + } + ); + }, + updateContactInfo(contactInfo) { this.order.customer.firstName = contactInfo?.firstName ?? this.order.customer.firstName; From 7565ac85f0e7b24dbd43dbc01677d8edaad97aae Mon Sep 17 00:00:00 2001 From: Jeremy-Z Date: Mon, 16 Mar 2026 14:54:20 -0400 Subject: [PATCH 2/9] Refinements. --- src/mixins/analytics-mixin.js | 23 +++++++++++++++-------- src/store/index.js | 2 ++ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index 71477ca2..56a1c574 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -166,9 +166,8 @@ export default { const store = useMainStore(); const currentPageName = this.getPageNameByQueryString(); const universes = store.applicationUser.experiments; - const deviceId = getDeviceIdValue(); // cookieNames.DXDEV - const userId = getUserIdValue(); // cookieNames.ISS_USER_ID - const sid = getSessionIdValue(); // cookieNames.SESSION_ID + const deviceId = getDeviceIdValue(); + const sid = getSessionIdValue(); const variationNames = universes .filter((item) => item.universeName === experimentSettings.CONCEPT_FUNNEL) @@ -180,10 +179,11 @@ export default { const isConceptExposed = universes.find( (item) => item.universeName === experimentSettings.CONCEPT_FUNNEL )?.isExposed; + + const submittedOrder = store.getSubmittedOrder(); + const hasSubmittedOrder = store.hasSubmittedOrder(); // TODO: Find equivalent ISS methods for these: - const submittedOrder = null;//baseMixin.methods.getSubmittedOrder(); - const hasSubmittedOrder = false;//baseMixin.methods.hasSubmittedOrder(); const hasSubmittedOrderAtConfirmationPage = hasSubmittedOrder && currentPageName?.toLowerCase() == routeData.CONFIRMATION.name; @@ -217,10 +217,11 @@ export default { // This bucket data is then picked up by snowflake for analytics use. pushIssSessionData() { const store = useMainStore(); - const hasSubmittedOrder = baseMixin.methods.hasSubmittedOrder(); - const submittedOrder = baseMixin.methods.getSubmittedOrder(); + const submittedOrder = store.getSubmittedOrder(); + const hasSubmittedOrder = store.hasSubmittedOrder(); const order = hasSubmittedOrder ? submittedOrder : store.order; + // TODO: Find equivalent ISS methods for these: const hasSubmittedApplicationUser = baseMixin.methods.hasSubmittedApplicationUser(); const submittedApplicationUser = baseMixin.methods.getSubmittedApplicationUser(); const applicationUser = hasSubmittedApplicationUser @@ -280,7 +281,7 @@ export default { sessionData.sid = getSessionIdValue(); sessionData.deviceId = getDeviceIdValue(); sessionData.fmgSessionId = applicationUser?.savedSessionId; - sessionData.skey = getskeyValue().toString(); + sessionData.skey = getSessionKeyValue().toString(); sessionData.userId = getUserIdValue(); sessionData.carId = order?.vehicle?.carId; sessionData.vehicleYear = order?.vehicle?.year; @@ -304,8 +305,11 @@ export default { sessionData.parentAccountNumber = order?.payment?.parentAccountNumber; sessionData.billToAccountNumber = order?.payment?.billToAccountNumber; sessionData.settledTenderAmount = order?.settledTenderAmount; + + // TODO: Find equivalent ISS methods for these: sessionData.recalRequired = containsRecalParts(order?.lineItems); sessionData.recalType = getRecalPartNumbers(order?.lineItems?.glassParts); + sessionData.serviceZipCode = order?.serviceLocation?.provider?.address?.zipCode ? order?.serviceLocation?.provider?.address?.zipCode : order?.serviceLocation?.zipCode; @@ -326,8 +330,11 @@ export default { sessionData.coverageSubStatus = order?.payment?.insuranceCoverage?.coverageSubStatus; sessionData.isNoComp = order?.policy?.isNoComp; sessionData.isItac = order?.policy?.isItac; + + // TODO: Find equivalent ISS methods for these: sessionData.subTotalPrice = getSubTotal(order?.lineItems); sessionData.totalPrice = getAmountDue(order?.lineItems, true); + sessionData.userAgent = navigator.userAgent; sessionData.cashPriceSubTotal = order?.cashPriceSubTotal; diff --git a/src/store/index.js b/src/store/index.js index 963929b1..b6c113cd 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -2623,6 +2623,7 @@ export const useMainStore = defineStore({ this.applicationUser.triggeredSiteEntry = wasSiteEntryTriggered; }, + // TODO: Shouldn't this be async? logDigitalConsumer( { deviceId, @@ -2665,6 +2666,7 @@ export const useMainStore = defineStore({ ); }, + // TODO: Shouldn't this be async? logIssSessionData( { currentPage, From e2e705f00084e72c0c8e9ddda4e197eee2ecdc81 Mon Sep 17 00:00:00 2001 From: Jeremy-Z Date: Tue, 17 Mar 2026 12:24:05 -0400 Subject: [PATCH 3/9] Refinements. --- src/mixins/analytics-mixin.js | 59 ++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index 56a1c574..3821022e 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -20,6 +20,7 @@ import { GaEvents, ValueToLogTypes } from '@/constants/analytics'; +import { getCartTotal, getSubTotal } from '@/helpers/cart-helper'; import { useMainStore } from '@/store'; function pushToDataLayerIfDefined(data) { @@ -219,7 +220,8 @@ export default { const store = useMainStore(); const submittedOrder = store.getSubmittedOrder(); const hasSubmittedOrder = store.hasSubmittedOrder(); - const order = hasSubmittedOrder ? submittedOrder : store.order; + const order = hasSubmittedOrder ? submittedOrder : store.order; + const issConfig = store.issConfig; // TODO: Find equivalent ISS methods for these: const hasSubmittedApplicationUser = baseMixin.methods.hasSubmittedApplicationUser(); @@ -231,13 +233,14 @@ export default { const isEarlyBird = order?.lineItems?.supportingItems?.find( (lineItem) => lineItem.partType == partTypeStrings.EARLY_BIRD ); - - const promoCodes = Array.isArray(order?.lineItems?.promos) + + const promoCodes = ""; /*Array.isArray(order?.lineItems?.promos) ? order?.lineItems?.promos .map((item) => item.promoCode) .filter((code) => code) .join(", ") : null; + */ const glassProducts = order?.damage?.glassToReplace?.map( (part) => `${part.glassLocation}-${part.glassName}` @@ -289,21 +292,27 @@ export default { sessionData.vehicleModel = order?.vehicle?.model; sessionData.vehicleStyle = order?.vehicle?.style; sessionData.hasVin = order?.vehicle?.vin ? true : false; - sessionData.cashOrInsuranceAccountType = order?.payment?.isInsurance - ? "Insurance" - : "Cash"; + sessionData.cashOrInsuranceAccountType = "Insurance"; sessionData.damageType = order?.damage?.isRepair ? "Repair" : "Replace"; + + // TODO: Find equivalent ISS methods for these: sessionData.productType = allParts; + sessionData.eon = order?.eon; sessionData.referralNumber = order?.referralNumber; sessionData.referralSequenceNumber = order?.referralSequenceNumber; sessionData.referralDate = order?.referralDate; sessionData.workOrderNumber = order?.workOrderNumber; sessionData.workOrderId = order?.workOrderId; + + // TODO: Find equivalent ISS methods for these: sessionData.isPia = order?.payment?.isPia ?? false; sessionData.piaType = order?.payment?.piaType; - sessionData.parentAccountNumber = order?.payment?.parentAccountNumber; - sessionData.billToAccountNumber = order?.payment?.billToAccountNumber; + + sessionData.parentAccountNumber = order?.parentAccountNumber; + sessionData.billToAccountNumber = issConfig.billToAccountNumber; + + // TODO: Find equivalent ISS methods for these: sessionData.settledTenderAmount = order?.settledTenderAmount; // TODO: Find equivalent ISS methods for these: @@ -319,24 +328,30 @@ export default { sessionData.appointmentDate = appointment; sessionData.serviceType = order?.serviceLocation?.appointmentType; sessionData.promoCodes = promoCodes; - sessionData.hasTechnicianNotes = order?.serviceLocation?.techNotes ? true : false; - sessionData.paymentMethod = order?.payment?.piaType; - sessionData.isTextingOptedIn = order?.customer?.isSmsOptIn ? true : false; - sessionData.isEarlyBird = isEarlyBird ? true : false; - sessionData.insuranceCo = order?.policy?.insuranceCompanyName; - sessionData.deductible = order?.policy?.currentDeductible; - sessionData.isVerified = order?.payment?.insuranceCoverage?.isVerified ?? false; - sessionData.coverageStatus = order?.payment?.insuranceCoverage?.coverageStatus; - sessionData.coverageSubStatus = order?.payment?.insuranceCoverage?.coverageSubStatus; - sessionData.isNoComp = order?.policy?.isNoComp; - sessionData.isItac = order?.policy?.isItac; + sessionData.hasTechnicianNotes = order?.contactInfo?.notesForTechnician ? true : false; // TODO: Find equivalent ISS methods for these: - sessionData.subTotalPrice = getSubTotal(order?.lineItems); - sessionData.totalPrice = getAmountDue(order?.lineItems, true); + sessionData.paymentMethod = order?.payment?.piaType; + sessionData.isTextingOptedIn = order?.contactInfo?.requestTextUpdates ? true : false; + + // TODO: Find equivalent ISS methods for these: + sessionData.isEarlyBird = isEarlyBird ? true : false; + + sessionData.insuranceCo = issConfig.clientName; + sessionData.deductible = store.currentDeductible(); + sessionData.isVerified = store.isVerified(); + + // TODO: Need mappings here? + sessionData.coverageStatus = order?.payment?.insuranceCoverage?.coverageStatus; + sessionData.coverageSubStatus = order?.payment?.insuranceCoverage?.coverageSubStatus; + + sessionData.isNoComp = store.isNoComp(); + sessionData.isItac = store.isITAC(); + sessionData.subTotalPrice = getSubTotal(order); + sessionData.totalPrice = getCartTotal(order); sessionData.userAgent = navigator.userAgent; - sessionData.cashPriceSubTotal = order?.cashPriceSubTotal; + sessionData.cashPriceSubTotal = getSubTotal(order); store.logIssSessionData(sessionData); }, From 1d459cdacda5316da561eb42658f8c2f33475698 Mon Sep 17 00:00:00 2001 From: Jeremy-Z Date: Tue, 17 Mar 2026 12:58:05 -0400 Subject: [PATCH 4/9] Updates to the session logging logic. --- src/helpers/recal-helper.js | 28 +++++++++++++++++ src/mixins/analytics-mixin.js | 57 ++++++++++++++--------------------- src/router/index.js | 2 +- 3 files changed, 52 insertions(+), 35 deletions(-) diff --git a/src/helpers/recal-helper.js b/src/helpers/recal-helper.js index 8d680881..c007b24c 100644 --- a/src/helpers/recal-helper.js +++ b/src/helpers/recal-helper.js @@ -23,3 +23,31 @@ export function getTopLevelGlassPartsWithRecal(glassParts) { return glassParts.filter((gp) => isRecalPartOrHasChildRecalPart(gp)); } + +export function getItemsWithoutRecalParts(lineItemsArray) { + if (!lineItemsArray || !Array.isArray(lineItemsArray)) return null; + const firstLevelFiltered = deepClone(lineItemsArray).filter((li) => !isRecalPart(li)); + + const childrenFiltered = firstLevelFiltered.map((li) => { + if (li.childParts && li.childParts.length > 0) { + li.childParts = getItemsWithoutRecalParts(li.childParts); + } + + return li; + }); + + return childrenFiltered; +} + +export function getRecalPartNumbers(glassPartsArray) { + if (glassPartsArray && glassPartsArray.length > 0) { + const topLevel = glassPartsArray.filter((gp) => isRecalPart(gp)).map((gp) => gp.partNumber); + + const children = glassPartsArray.map((gp) => getRecalPartNumbers(gp.childParts)).flat(); + + return [...topLevel, ...children]; + } else { + return []; + } +} + diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index 3821022e..13d93347 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -20,7 +20,10 @@ import { GaEvents, ValueToLogTypes } from '@/constants/analytics'; -import { getCartTotal, getSubTotal } from '@/helpers/cart-helper'; +import { getCartTotal, getSubtotal } from '@/helpers/cart-helper'; +import { getRecalPartNumbers } from "@/helpers/recal-helper"; +import coverageStatuses from '@/constants/coverage-statuses'; +import coverageType from '@/constants/coverage-type'; import { useMainStore } from '@/store'; function pushToDataLayerIfDefined(data) { @@ -222,17 +225,13 @@ export default { const hasSubmittedOrder = store.hasSubmittedOrder(); const order = hasSubmittedOrder ? submittedOrder : store.order; const issConfig = store.issConfig; + const applicationUser = store.applicationUser; - // TODO: Find equivalent ISS methods for these: - const hasSubmittedApplicationUser = baseMixin.methods.hasSubmittedApplicationUser(); - const submittedApplicationUser = baseMixin.methods.getSubmittedApplicationUser(); - const applicationUser = hasSubmittedApplicationUser - ? submittedApplicationUser - : store.applicationUser; - + /* const isEarlyBird = order?.lineItems?.supportingItems?.find( (lineItem) => lineItem.partType == partTypeStrings.EARLY_BIRD ); + */ const promoCodes = ""; /*Array.isArray(order?.lineItems?.promos) ? order?.lineItems?.promos @@ -294,10 +293,7 @@ export default { sessionData.hasVin = order?.vehicle?.vin ? true : false; sessionData.cashOrInsuranceAccountType = "Insurance"; sessionData.damageType = order?.damage?.isRepair ? "Repair" : "Replace"; - - // TODO: Find equivalent ISS methods for these: sessionData.productType = allParts; - sessionData.eon = order?.eon; sessionData.referralNumber = order?.referralNumber; sessionData.referralSequenceNumber = order?.referralSequenceNumber; @@ -306,17 +302,13 @@ export default { sessionData.workOrderId = order?.workOrderId; // TODO: Find equivalent ISS methods for these: - sessionData.isPia = order?.payment?.isPia ?? false; - sessionData.piaType = order?.payment?.piaType; + sessionData.isPia = false;//order?.payment?.isPia ?? false; + sessionData.piaType = null;//order?.payment?.piaType; sessionData.parentAccountNumber = order?.parentAccountNumber; sessionData.billToAccountNumber = issConfig.billToAccountNumber; - - // TODO: Find equivalent ISS methods for these: - sessionData.settledTenderAmount = order?.settledTenderAmount; - - // TODO: Find equivalent ISS methods for these: - sessionData.recalRequired = containsRecalParts(order?.lineItems); + sessionData.settledTenderAmount = order?.payment?.nextGenSettledAmount; + sessionData.recalRequired = store.hasRecalibrationPart; sessionData.recalType = getRecalPartNumbers(order?.lineItems?.glassParts); sessionData.serviceZipCode = order?.serviceLocation?.provider?.address?.zipCode @@ -329,29 +321,26 @@ export default { sessionData.serviceType = order?.serviceLocation?.appointmentType; sessionData.promoCodes = promoCodes; sessionData.hasTechnicianNotes = order?.contactInfo?.notesForTechnician ? true : false; - - // TODO: Find equivalent ISS methods for these: - sessionData.paymentMethod = order?.payment?.piaType; - + sessionData.paymentMethod = order?.payment?.paymentMethod; sessionData.isTextingOptedIn = order?.contactInfo?.requestTextUpdates ? true : false; // TODO: Find equivalent ISS methods for these: - sessionData.isEarlyBird = isEarlyBird ? true : false; + sessionData.isEarlyBird = false;//isEarlyBird ? true : false; sessionData.insuranceCo = issConfig.clientName; - sessionData.deductible = store.currentDeductible(); - sessionData.isVerified = store.isVerified(); + sessionData.deductible = store.currentDeductible ?? 0; + sessionData.isVerified = store.isVerified; + sessionData.coverageStatus = coverageStatuses.mapToApi(order?.insuranceCoverage.coverageStatus); + sessionData.coverageSubStatus = coverageType.mapToApi(order?.insuranceCoverage.coverageType); - // TODO: Need mappings here? - sessionData.coverageStatus = order?.payment?.insuranceCoverage?.coverageStatus; - sessionData.coverageSubStatus = order?.payment?.insuranceCoverage?.coverageSubStatus; - - sessionData.isNoComp = store.isNoComp(); - sessionData.isItac = store.isITAC(); - sessionData.subTotalPrice = getSubTotal(order); + sessionData.isNoComp = store.isNoComp; + sessionData.isItac = store.isITAC; + sessionData.subTotalPrice = getSubtotal(order); sessionData.totalPrice = getCartTotal(order); sessionData.userAgent = navigator.userAgent; - sessionData.cashPriceSubTotal = getSubTotal(order); + + // Why does this need to be a string? + sessionData.cashPriceSubTotal = getSubtotal(order).toString(); store.logIssSessionData(sessionData); }, diff --git a/src/router/index.js b/src/router/index.js index 3b7b205f..eeca615e 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -182,7 +182,7 @@ router.afterEach(async (to, from) => { analyticsMixin.methods.logDigitalConsumer(); // digital consumer ISS session logging to snowflake - //analyticsMixin.methods.pushIssSessionData(); + analyticsMixin.methods.pushIssSessionData(); // Push page view to GA analyticsMixin.methods.pushPageViewToGA(); From 6c657861099854a749d939e07e3f10038bfa604c Mon Sep 17 00:00:00 2001 From: Jeremy-Z Date: Wed, 18 Mar 2026 11:28:12 -0400 Subject: [PATCH 5/9] Adding population of work order id. Fixed some formatting issues. --- src/mixins/analytics-mixin.js | 20 +++++++++++--------- src/store/index.js | 3 +++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index 13d93347..e35c8f0d 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -24,6 +24,7 @@ import { getCartTotal, getSubtotal } from '@/helpers/cart-helper'; import { getRecalPartNumbers } from "@/helpers/recal-helper"; import coverageStatuses from '@/constants/coverage-statuses'; import coverageType from '@/constants/coverage-type'; +import issPageValues from '@/router/router-constants/issPage-values'; import { useMainStore } from '@/store'; function pushToDataLayerIfDefined(data) { @@ -189,7 +190,7 @@ export default { // TODO: Find equivalent ISS methods for these: const hasSubmittedOrderAtConfirmationPage = - hasSubmittedOrder && currentPageName?.toLowerCase() == routeData.CONFIRMATION.name; + hasSubmittedOrder && currentPageName?.toLowerCase() === issPageValues.ORDER_CONFIRMATION;; var payload = { deviceId: deviceId, @@ -278,6 +279,8 @@ export default { } } */ + var parentAccountNumber = (order?.parentAccountNumber ?? ( issConfig.parentAccountNumber ?? 0)).toString(); + var sessionData = {}; sessionData.currentPage = currentPageName; sessionData.sid = getSessionIdValue(); @@ -301,11 +304,11 @@ export default { sessionData.workOrderNumber = order?.workOrderNumber; sessionData.workOrderId = order?.workOrderId; - // TODO: Find equivalent ISS methods for these: + // TODO: Find equivalent ISS methods for these: sessionData.isPia = false;//order?.payment?.isPia ?? false; sessionData.piaType = null;//order?.payment?.piaType; - sessionData.parentAccountNumber = order?.parentAccountNumber; + sessionData.parentAccountNumber = parentAccountNumber; sessionData.billToAccountNumber = issConfig.billToAccountNumber; sessionData.settledTenderAmount = order?.payment?.nextGenSettledAmount; sessionData.recalRequired = store.hasRecalibrationPart; @@ -324,7 +327,7 @@ export default { sessionData.paymentMethod = order?.payment?.paymentMethod; sessionData.isTextingOptedIn = order?.contactInfo?.requestTextUpdates ? true : false; - // TODO: Find equivalent ISS methods for these: + // TODO: Find equivalent ISS methods for these: - I do not think we have early bird support in ISS. sessionData.isEarlyBird = false;//isEarlyBird ? true : false; sessionData.insuranceCo = issConfig.clientName; @@ -335,13 +338,12 @@ export default { sessionData.isNoComp = store.isNoComp; sessionData.isItac = store.isITAC; - sessionData.subTotalPrice = getSubtotal(order); - sessionData.totalPrice = getCartTotal(order); - sessionData.userAgent = navigator.userAgent; - - // Why does this need to be a string? + sessionData.subTotalPrice = getSubtotal(order).toString(); + sessionData.totalPrice = getCartTotal(order).toString(); sessionData.cashPriceSubTotal = getSubtotal(order).toString(); + sessionData.userAgent = navigator.userAgent; + store.logIssSessionData(sessionData); }, diff --git a/src/store/index.js b/src/store/index.js index b6c113cd..9713dd4e 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1396,6 +1396,7 @@ export const useMainStore = defineStore({ this.order.referralDate = response.referralDate; this.order.referralCorrelationId = response.referralCorrelationId; this.order.eon = response.eon; + this.order.workOrderId = response.workOrderId; this.order.workOrderNumber = response.workOrderNumber; this.order.settledTenderAmount = response.settledTenderAmount; this.order.lockToken = response.lockToken; @@ -2770,6 +2771,8 @@ export const useMainStore = defineStore({ billToAccountNumber: billToAccountNumber, }; + console.error("Logging Digital Consumer Session Action: ", payload); + return globalMethods.callHttpClient({ method: endpoints.LogIssSessionData.method, endpoint: endpoints.LogIssSessionData.url, From 6a80a9b1b0e67d067e301c03e06f6e276f049fbc Mon Sep 17 00:00:00 2001 From: Jeremy-Z Date: Wed, 18 Mar 2026 12:11:07 -0400 Subject: [PATCH 6/9] More updates. --- src/mixins/analytics-mixin.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index e35c8f0d..f0f135fe 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -228,12 +228,13 @@ export default { const issConfig = store.issConfig; const applicationUser = store.applicationUser; - /* - const isEarlyBird = order?.lineItems?.supportingItems?.find( + // NOTE: ISS does not support early bird times. + const isEarlyBird = false; /*order?.lineItems?.supportingItems?.find( (lineItem) => lineItem.partType == partTypeStrings.EARLY_BIRD ); */ + // NOTE: No promo codes on ISS at the moment. const promoCodes = ""; /*Array.isArray(order?.lineItems?.promos) ? order?.lineItems?.promos .map((item) => item.promoCode) @@ -304,9 +305,8 @@ export default { sessionData.workOrderNumber = order?.workOrderNumber; sessionData.workOrderId = order?.workOrderId; - // TODO: Find equivalent ISS methods for these: - sessionData.isPia = false;//order?.payment?.isPia ?? false; - sessionData.piaType = null;//order?.payment?.piaType; + sessionData.isPia = store.isPayInAdvance; + sessionData.piaType = (store.isPayInAdvance ? order?.payment?.paymentMethod : null); sessionData.parentAccountNumber = parentAccountNumber; sessionData.billToAccountNumber = issConfig.billToAccountNumber; @@ -326,9 +326,7 @@ export default { sessionData.hasTechnicianNotes = order?.contactInfo?.notesForTechnician ? true : false; sessionData.paymentMethod = order?.payment?.paymentMethod; sessionData.isTextingOptedIn = order?.contactInfo?.requestTextUpdates ? true : false; - - // TODO: Find equivalent ISS methods for these: - I do not think we have early bird support in ISS. - sessionData.isEarlyBird = false;//isEarlyBird ? true : false; + sessionData.isEarlyBird = isEarlyBird; sessionData.insuranceCo = issConfig.clientName; sessionData.deductible = store.currentDeductible ?? 0; From 597685a02b48c4176da424706a0d9975e0cc5f76 Mon Sep 17 00:00:00 2001 From: Jeremy-Z Date: Wed, 18 Mar 2026 12:27:03 -0400 Subject: [PATCH 7/9] Refactoring. --- src/constants/endpoints.js | 4 ++-- src/helpers/recal-helper.js | 1 + src/mixins/analytics-mixin.js | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index 897f9873..6300c23b 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -182,11 +182,11 @@ const endpoints = Object.freeze({ method: 'POST' }, LogDigitalConsumer: { - url: "/analytics/api/v1/analytics/digitalconsumer-log", + url: `${ANALYTICS_BASE_URL}/digitalconsumer-log`, method: "POST", }, LogIssSessionData: { - url: "/analytics/api/v1/analytics/digitalconsumer-session-logging", + url: `${ANALYTICS_BASE_URL}/digitalconsumer-session-logging`, method: "POST", }, GetExperimentsByUser: { diff --git a/src/helpers/recal-helper.js b/src/helpers/recal-helper.js index c007b24c..e72c2d63 100644 --- a/src/helpers/recal-helper.js +++ b/src/helpers/recal-helper.js @@ -1,4 +1,5 @@ import partTypeStrings from '@/constants/part-type-strings'; +import { deepClone } from '@/helpers/object-helper'; const recalPartTypes = [partTypeStrings.RECALIBRATION, partTypeStrings.ADAS_RECALIBRATION]; diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index f0f135fe..b3ef198d 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -190,7 +190,7 @@ export default { // TODO: Find equivalent ISS methods for these: const hasSubmittedOrderAtConfirmationPage = - hasSubmittedOrder && currentPageName?.toLowerCase() === issPageValues.ORDER_CONFIRMATION;; + hasSubmittedOrder && currentPageName?.toLowerCase() === issPageValues.ORDER_CONFIRMATION; var payload = { deviceId: deviceId, @@ -286,7 +286,7 @@ export default { sessionData.currentPage = currentPageName; sessionData.sid = getSessionIdValue(); sessionData.deviceId = getDeviceIdValue(); - sessionData.fmgSessionId = applicationUser?.savedSessionId; + sessionData.issSessionId = applicationUser?.savedSessionId; sessionData.skey = getSessionKeyValue().toString(); sessionData.userId = getUserIdValue(); sessionData.carId = order?.vehicle?.carId; From 686f07ec44d33519794d20f88b25d29c56ac3c70 Mon Sep 17 00:00:00 2001 From: Jeremy-Z Date: Wed, 18 Mar 2026 12:54:35 -0400 Subject: [PATCH 8/9] Refactoring. --- src/mixins/base-mixin.js | 28 ++++++++++++++++++++++++++++ src/store/index.js | 7 ++----- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index ac36cbf0..dcf83070 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -43,6 +43,34 @@ export default { scrollToPageBottom() { const container = document.getElementsByClassName('fade-on-route-transition')[0]; container.scrollTo({ top: container.scrollHeight, left: 0, behavior: 'smooth' }); + }, + getiOSversion() { + if (/iP(hone|od|ad)/.test(navigator.platform)) { + // supports iOS 2.0 and later: + var v = navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/); + return [parseInt(v[1], 10), parseInt(v[2], 10), parseInt(v[3] || 0, 10)]; + } + }, + isMobileDevice() { + const userAgent = navigator.userAgent; + return ( + userAgent.includes("Android") || + userAgent.includes("Mobile") || + userAgent.includes("iPod") || + userAgent.includes("iPhone") || + userAgent.includes("IEMobile") || + userAgent.includes("BlackBerry") || + userAgent.includes("webOS") + ); + }, + isAppleBrowser() { + const userAgent = navigator.userAgent; + return ( + userAgent.includes("iPod") || + userAgent.includes("iPad") || + userAgent.includes("iPhone") || + userAgent.includes("Mac") + ); } }, computed: { diff --git a/src/store/index.js b/src/store/index.js index 9713dd4e..9018c518 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -26,6 +26,7 @@ import { getTopLevelGlassPartsWithRecal } from '@/helpers/recal-helper'; import { getDateForSavedSessionTimeout } from '@/helpers/session-helper'; import issPageValues from '@/router/router-constants/issPage-values'; import CoverageStatuses from '@/constants/coverage-statuses'; +import baseMixin from '@/mixins/base-mixin'; const storeId = 'main'; @@ -2644,15 +2645,13 @@ export const useMainStore = defineStore({ actionName: actionName ?? "", referralSequenceNumber: referralSequenceNumber ?? "", referralNumber: referralNumber ?? "", - applicationName: "ISS", //baseMixin.methods.isMobileDevice() ? "2.0 Mobile" : "2.0", + applicationName: baseMixin.methods.isMobileDevice() ? "ISS Mobile" : "ISS", workOrderId: workOrderId ?? "", workOrderNumber: workOrderNumber ?? "", conceptVariation: conceptVariation, isConceptExposed: isConceptExposed, }; - console.error("Logging Digital Consumer Action: ", payload); - return globalMethods.callHttpClient({ method: endpoints.LogDigitalConsumer.method, endpoint: endpoints.LogDigitalConsumer.url, @@ -2771,8 +2770,6 @@ export const useMainStore = defineStore({ billToAccountNumber: billToAccountNumber, }; - console.error("Logging Digital Consumer Session Action: ", payload); - return globalMethods.callHttpClient({ method: endpoints.LogIssSessionData.method, endpoint: endpoints.LogIssSessionData.url, From a96695da3a3168cd2921bcb6264c04fed568d9c8 Mon Sep 17 00:00:00 2001 From: Jeremy-Z Date: Wed, 18 Mar 2026 13:45:39 -0400 Subject: [PATCH 9/9] Added a helper class for useragent utilities. --- src/helpers/session-helper.js | 45 +++++++++++++++++++++++++++++++++ src/helpers/useragent-helper.js | 42 ++++++++++++++++++++++++++++++ src/mixins/base-mixin.js | 28 -------------------- src/store/index.js | 4 +-- 4 files changed, 89 insertions(+), 30 deletions(-) create mode 100644 src/helpers/useragent-helper.js diff --git a/src/helpers/session-helper.js b/src/helpers/session-helper.js index a82e1618..47185a25 100644 --- a/src/helpers/session-helper.js +++ b/src/helpers/session-helper.js @@ -47,3 +47,48 @@ export function getDateForSavedSessionTimeout() { currentDate.setDate(currentDate.getDate() + applicationConfig.SAVED_SESSION_TIMEOUT_DAYS); return currentDate.toUTCString(); } + + +/* +Function to return the iOS version of the device. +*/ + +export function getiOSversion() { + if (/iP(hone|od|ad)/.test(navigator.platform)) { + // supports iOS 2.0 and later: + var v = navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/); + return [parseInt(v[1], 10), parseInt(v[2], 10), parseInt(v[3] || 0, 10)]; + } +} + +/* +Function to return true/false if the user agent is a mobile device or not. +*/ + +export function isMobileDevice() { + const userAgent = navigator.userAgent; + return ( + userAgent.includes("Android") || + userAgent.includes("Mobile") || + userAgent.includes("iPod") || + userAgent.includes("iPhone") || + userAgent.includes("IEMobile") || + userAgent.includes("BlackBerry") || + userAgent.includes("webOS") + ); +} + +/* +Function to return true/false if the user is using an apple browser on a device. +*/ + +export function isAppleBrowser() { + const userAgent = navigator.userAgent; + return ( + userAgent.includes("iPod") || + userAgent.includes("iPad") || + userAgent.includes("iPhone") || + userAgent.includes("Mac") + ); +} + diff --git a/src/helpers/useragent-helper.js b/src/helpers/useragent-helper.js new file mode 100644 index 00000000..d1db7efe --- /dev/null +++ b/src/helpers/useragent-helper.js @@ -0,0 +1,42 @@ +/* +Function to return the iOS version of the device. +*/ + +export function getiOSversion() { + if (/iP(hone|od|ad)/.test(navigator.platform)) { + // supports iOS 2.0 and later: + var v = navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/); + return [parseInt(v[1], 10), parseInt(v[2], 10), parseInt(v[3] || 0, 10)]; + } +} + +/* +Function to return true/false if the user agent is a mobile device or not. +*/ + +export function isMobileDevice() { + const userAgent = navigator.userAgent; + return ( + userAgent.includes("Android") || + userAgent.includes("Mobile") || + userAgent.includes("iPod") || + userAgent.includes("iPhone") || + userAgent.includes("IEMobile") || + userAgent.includes("BlackBerry") || + userAgent.includes("webOS") + ); +} + +/* +Function to return true/false if the user is using an apple browser on a device. +*/ + +export function isAppleBrowser() { + const userAgent = navigator.userAgent; + return ( + userAgent.includes("iPod") || + userAgent.includes("iPad") || + userAgent.includes("iPhone") || + userAgent.includes("Mac") + ); +} \ No newline at end of file diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index dcf83070..ac36cbf0 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -43,34 +43,6 @@ export default { scrollToPageBottom() { const container = document.getElementsByClassName('fade-on-route-transition')[0]; container.scrollTo({ top: container.scrollHeight, left: 0, behavior: 'smooth' }); - }, - getiOSversion() { - if (/iP(hone|od|ad)/.test(navigator.platform)) { - // supports iOS 2.0 and later: - var v = navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/); - return [parseInt(v[1], 10), parseInt(v[2], 10), parseInt(v[3] || 0, 10)]; - } - }, - isMobileDevice() { - const userAgent = navigator.userAgent; - return ( - userAgent.includes("Android") || - userAgent.includes("Mobile") || - userAgent.includes("iPod") || - userAgent.includes("iPhone") || - userAgent.includes("IEMobile") || - userAgent.includes("BlackBerry") || - userAgent.includes("webOS") - ); - }, - isAppleBrowser() { - const userAgent = navigator.userAgent; - return ( - userAgent.includes("iPod") || - userAgent.includes("iPad") || - userAgent.includes("iPhone") || - userAgent.includes("Mac") - ); } }, computed: { diff --git a/src/store/index.js b/src/store/index.js index f43ace52..6622f9b3 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -24,9 +24,9 @@ import { import { buildURLSearchParams, getPartNumbersListForQueryString } from '@/helpers/querystring-helper'; import { getTopLevelGlassPartsWithRecal } from '@/helpers/recal-helper'; import { getDateForSavedSessionTimeout } from '@/helpers/session-helper'; +import { isMobileDevice } from '@/helpers/useragent-helper'; import issPageValues from '@/router/router-constants/issPage-values'; import CoverageStatuses from '@/constants/coverage-statuses'; -import baseMixin from '@/mixins/base-mixin'; const storeId = 'main'; @@ -2645,7 +2645,7 @@ export const useMainStore = defineStore({ actionName: actionName ?? "", referralSequenceNumber: referralSequenceNumber ?? "", referralNumber: referralNumber ?? "", - applicationName: baseMixin.methods.isMobileDevice() ? "ISS Mobile" : "ISS", + applicationName: isMobileDevice() ? "ISS Mobile" : "ISS", workOrderId: workOrderId ?? "", workOrderNumber: workOrderNumber ?? "", conceptVariation: conceptVariation,