| |
| |
| |
| |
|
|
| (function() { |
| 'use strict'; |
| |
| const ANALYTICS_KEY = 'bbplease_analytics'; |
| const USER_ID_KEY = 'bbplease_user_id'; |
| const APP_VERSION = '1.0.0'; |
| |
| |
| |
| |
| function getUserId() { |
| let userId = localStorage.getItem(USER_ID_KEY); |
| if (!userId) { |
| userId = 'user_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9); |
| localStorage.setItem(USER_ID_KEY, userId); |
| } |
| return userId; |
| } |
| |
| |
| |
| |
| function getAppVersion() { |
| return window.APP_CONFIG ? window.APP_CONFIG.VERSION : APP_VERSION; |
| } |
| |
| |
| |
| |
| function getPlatformInfo() { |
| const isCapacitor = window.Capacitor !== undefined; |
| const platform = isCapacitor ? window.Capacitor.getPlatform() : 'web'; |
| |
| return { |
| platform: platform, |
| isMobile: isCapacitor && (platform === 'android' || platform === 'ios'), |
| userAgent: navigator.userAgent, |
| language: navigator.language, |
| online: navigator.onLine |
| }; |
| } |
| |
| |
| |
| |
| function trackEvent(eventName, eventData = {}) { |
| const event = { |
| name: eventName, |
| timestamp: new Date().toISOString(), |
| userId: getUserId(), |
| version: getAppVersion(), |
| platform: getPlatformInfo(), |
| data: eventData |
| }; |
| |
| |
| const analytics = getAnalytics(); |
| analytics.events.push(event); |
| |
| |
| if (analytics.events.length > 100) { |
| analytics.events = analytics.events.slice(-100); |
| } |
| |
| saveAnalytics(analytics); |
| |
| console.log('📊 Event tracked:', eventName, eventData); |
| |
| return event; |
| } |
| |
| |
| |
| |
| function trackError(error, context = {}) { |
| const errorEvent = { |
| name: 'error', |
| timestamp: new Date().toISOString(), |
| userId: getUserId(), |
| version: getAppVersion(), |
| platform: getPlatformInfo(), |
| error: { |
| message: error.message || String(error), |
| stack: error.stack, |
| name: error.name, |
| context: context |
| } |
| }; |
| |
| const analytics = getAnalytics(); |
| analytics.errors.push(errorEvent); |
| |
| |
| if (analytics.errors.length > 50) { |
| analytics.errors = analytics.errors.slice(-50); |
| } |
| |
| saveAnalytics(analytics); |
| |
| console.error('❌ Error tracked:', errorEvent); |
| |
| |
| sendErrorToServer(errorEvent); |
| |
| return errorEvent; |
| } |
| |
| |
| |
| |
| async function sendErrorToServer(errorEvent) { |
| try { |
| if (!navigator.onLine) { |
| return; |
| } |
| |
| const url = (window.APP_CONFIG && window.APP_CONFIG.getApiUrl) |
| ? window.APP_CONFIG.getApiUrl('/api/analytics/error') |
| : '/api/analytics/error'; |
| |
| await fetch(url, { |
| method: 'POST', |
| headers: { 'Content-Type': 'application/json' }, |
| body: JSON.stringify(errorEvent) |
| }); |
| } catch (e) { |
| console.warn('Failed to send error to server:', e); |
| } |
| } |
| |
| |
| |
| |
| function getAnalytics() { |
| try { |
| const data = localStorage.getItem(ANALYTICS_KEY); |
| return data ? JSON.parse(data) : { |
| userId: getUserId(), |
| version: getAppVersion(), |
| firstLaunch: new Date().toISOString(), |
| events: [], |
| errors: [], |
| sessionCount: 0 |
| }; |
| } catch (e) { |
| return { |
| userId: getUserId(), |
| version: getAppVersion(), |
| firstLaunch: new Date().toISOString(), |
| events: [], |
| errors: [], |
| sessionCount: 0 |
| }; |
| } |
| } |
| |
| |
| |
| |
| function saveAnalytics(analytics) { |
| try { |
| localStorage.setItem(ANALYTICS_KEY, JSON.stringify(analytics)); |
| } catch (e) { |
| console.error('Failed to save analytics:', e); |
| } |
| } |
| |
| |
| |
| |
| function trackSessionStart() { |
| const analytics = getAnalytics(); |
| analytics.sessionCount = (analytics.sessionCount || 0) + 1; |
| analytics.lastSession = new Date().toISOString(); |
| saveAnalytics(analytics); |
| |
| trackEvent('session_start', { |
| sessionNumber: analytics.sessionCount |
| }); |
| } |
| |
| |
| |
| |
| function getAnalyticsSummary() { |
| const analytics = getAnalytics(); |
| return { |
| userId: analytics.userId || getUserId(), |
| version: analytics.version || getAppVersion(), |
| firstLaunch: analytics.firstLaunch, |
| sessionCount: analytics.sessionCount || 0, |
| eventCount: analytics.events ? analytics.events.length : 0, |
| errorCount: analytics.errors ? analytics.errors.length : 0, |
| platform: getPlatformInfo() |
| }; |
| } |
| |
| |
| |
| |
| function clearAnalytics() { |
| localStorage.removeItem(ANALYTICS_KEY); |
| console.log('🗑️ Analytics cleared'); |
| } |
| |
| |
| |
| |
| function init() { |
| trackSessionStart(); |
| |
| |
| trackEvent('app_loaded', { |
| platform: getPlatformInfo() |
| }); |
| |
| |
| window.addEventListener('online', () => { |
| trackEvent('network_online'); |
| }); |
| |
| window.addEventListener('offline', () => { |
| trackEvent('network_offline'); |
| }); |
| |
| |
| window.addEventListener('error', (event) => { |
| trackError(event.error || new Error(event.message), { |
| filename: event.filename, |
| lineno: event.lineno, |
| colno: event.colno |
| }); |
| }); |
| |
| |
| window.addEventListener('unhandledrejection', (event) => { |
| trackError(event.reason, { |
| type: 'unhandled_promise_rejection' |
| }); |
| }); |
| |
| console.log('📊 Analytics initialized'); |
| } |
| |
| |
| window.AppAnalytics = { |
| trackEvent: trackEvent, |
| trackError: trackError, |
| getAnalyticsSummary: getAnalyticsSummary, |
| getUserId: getUserId, |
| getAppVersion: getAppVersion, |
| getPlatformInfo: getPlatformInfo, |
| clearAnalytics: clearAnalytics |
| }; |
| |
| |
| if (document.readyState === 'loading') { |
| document.addEventListener('DOMContentLoaded', init); |
| } else { |
| init(); |
| } |
| })(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|