import { Injectable } from '@angular/core'; import { environment } from '@environment'; import { PropertyNamesOfType } from '@yourcause/common'; import type { Config, OverridedMixpanel } from 'mixpanel-browser'; import { LocationService } from './location.service'; @Injectable({ providedIn: 'root' }) export class MixpanelService { private initialized = false; private mixpanel: OverridedMixpanel; private initParams: Partial = { autotrack: false, persistence: 'localStorage', disable_persistence: false, disable_cookie: true, ignore_dnt: true, disable_notifications: true, debug: false, api_host: environment.apiUrl + '/skyuxanalytics' }; private globalParams: Record = {}; constructor ( private locationService: LocationService ) { } async load () { const mixpanel = await import('mixpanel-browser'); this.mixpanel = mixpanel.default; } async init () { await this.load(); this.mixpanel.init(environment.mixpanelProjectId, this.initParams); this.initialized = true; } track (event: string, props: Record = {}) { props['Active Route'] = this.locationService.getGenericRoute(); props['Page Name'] = this.locationService.getCurrentDefaultTitle(); this.callMixpanel(this.mixpanel, 'track', event, props); } register (props: Record) { this.callMixpanel(this.mixpanel, 'register', props); } unregister (prop: string) { this.callMixpanel(this.mixpanel, 'unregister', prop); } reset () { this.callMixpanel(this.mixpanel, 'reset'); } identify (userId: string) { this.callMixpanel(this.mixpanel, 'identify', userId); } setProfile (profile: Record) { this.callMixpanel(this.mixpanel?.people, 'set', profile); } setGroup (groupId: number, groupType: string) { this.callMixpanel(this.mixpanel, 'set_group', groupType, groupId); } // eslint-disable-next-line @typescript-eslint/ban-types private callMixpanel&string, A extends T[K] extends (...a: any) => any ? Parameters : never> (item: T, method: K, ...args: A) { if (this.initialized) { (item[method] as any)(...(args as any)); } } /** * * @param params record of what we want to store globally */ appendGlobalParams (params: Record) { for (const paramName in params) { if (params[paramName]) { this.globalParams[paramName] = params[paramName]; } else { delete this.globalParams[paramName]; } } } }