94 lines
2.1 KiB
TypeScript
94 lines
2.1 KiB
TypeScript
'use client';
|
|
|
|
import posthog from 'posthog-js';
|
|
|
|
let initialized = false;
|
|
let posthogReady = false;
|
|
|
|
export function initAnalytics(): void {
|
|
if (initialized || typeof window === 'undefined') return;
|
|
initialized = true;
|
|
const key = process.env.NEXT_PUBLIC_POSTHOG_KEY;
|
|
if (!key) return;
|
|
posthog.init(key, {
|
|
api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST || 'https://us.i.posthog.com',
|
|
capture_pageview: false,
|
|
persistence: 'localStorage+cookie',
|
|
autocapture: false,
|
|
loaded: (ph) => {
|
|
posthogReady = true;
|
|
if (process.env.NODE_ENV === 'development') ph.debug();
|
|
},
|
|
});
|
|
}
|
|
|
|
function safeCapture(event: string, properties: Record<string, unknown> = {}) {
|
|
if (!posthogReady) return;
|
|
try {
|
|
posthog.capture(event, properties);
|
|
} catch {
|
|
// analytics failures should never break the app
|
|
}
|
|
}
|
|
|
|
export function identifyUser(userId: string, properties: Record<string, unknown> = {}) {
|
|
if (!posthogReady) return;
|
|
try {
|
|
posthog.identify(userId, properties);
|
|
} catch {
|
|
/* noop */
|
|
}
|
|
}
|
|
|
|
export function resetIdentity() {
|
|
if (!posthogReady) return;
|
|
try {
|
|
posthog.reset();
|
|
} catch {
|
|
/* noop */
|
|
}
|
|
}
|
|
|
|
export function trackPageView(path: string) {
|
|
safeCapture('page_viewed', { path });
|
|
}
|
|
|
|
export function trackScanCompleted(data: {
|
|
sport: string;
|
|
player: string;
|
|
stat: string;
|
|
line: number;
|
|
grade: string;
|
|
tier: string;
|
|
}) {
|
|
safeCapture('scan_completed', data);
|
|
}
|
|
|
|
export function trackParlayBuilt(data: { legs: number; sports: string[]; grade: string }) {
|
|
safeCapture('parlay_built', data);
|
|
}
|
|
|
|
export function trackUpgradeClicked(data: {
|
|
current_tier: string;
|
|
target_tier: string;
|
|
trigger_location: string;
|
|
}) {
|
|
safeCapture('upgrade_clicked', data);
|
|
}
|
|
|
|
export function trackShareCardGenerated(data: { sport: string; grade: string }) {
|
|
safeCapture('share_card_generated', data);
|
|
}
|
|
|
|
export function trackScanLimitHit(data: { current_scan_count: number; tier: string }) {
|
|
safeCapture('scan_limit_hit', data);
|
|
}
|
|
|
|
export function trackSignup(data: { method: string }) {
|
|
safeCapture('signup', data);
|
|
}
|
|
|
|
export function trackLogin(data: { method: string }) {
|
|
safeCapture('login', data);
|
|
}
|