Updated event handling in `analytics-provider.tsx` to return results, enhancing consistency. Added a new function `registerActiveServices` in `analytics-manager.ts` for initializing active services, streamlining provider setup. Clarified types for `AnalyticsProviderFactory` to accept optional configuration.
96 lines
2.4 KiB
TypeScript
96 lines
2.4 KiB
TypeScript
'use client';
|
|
|
|
import { useEffect } from 'react';
|
|
|
|
import { usePathname, useSearchParams } from 'next/navigation';
|
|
|
|
import { analytics } from '@kit/analytics';
|
|
import {
|
|
AppEvent,
|
|
AppEventType,
|
|
ConsumerProvidedEventTypes,
|
|
useAppEvents,
|
|
} from '@kit/shared/events';
|
|
|
|
type AnalyticsMapping<
|
|
T extends ConsumerProvidedEventTypes = NonNullable<unknown>,
|
|
> = {
|
|
[K in AppEventType<T>]?: (event: AppEvent<T, K>) => unknown;
|
|
};
|
|
|
|
/**
|
|
* Hook to subscribe to app events and map them to analytics actions
|
|
* @param mapping
|
|
*/
|
|
function useAnalyticsMapping<T extends ConsumerProvidedEventTypes>(
|
|
mapping: AnalyticsMapping<T>,
|
|
) {
|
|
const appEvents = useAppEvents<T>();
|
|
|
|
useEffect(() => {
|
|
const subscriptions = Object.entries(mapping).map(
|
|
([eventType, handler]) => {
|
|
appEvents.on(eventType as AppEventType<T>, handler);
|
|
|
|
return () => appEvents.off(eventType as AppEventType<T>, handler);
|
|
},
|
|
);
|
|
|
|
return () => {
|
|
subscriptions.forEach((unsubscribe) => unsubscribe());
|
|
};
|
|
}, [appEvents, mapping]);
|
|
}
|
|
|
|
/**
|
|
* Define a mapping of app events to analytics actions
|
|
* Add new mappings here to track new events in the analytics service from app events
|
|
*/
|
|
const analyticsMapping: AnalyticsMapping = {
|
|
'user.signedIn': (event) => {
|
|
const userId = event.payload.userId;
|
|
|
|
if (userId) {
|
|
return analytics.identify(userId);
|
|
}
|
|
},
|
|
'user.signedUp': (event) => {
|
|
return analytics.trackEvent(event.type, event.payload);
|
|
},
|
|
'checkout.started': (event) => {
|
|
return analytics.trackEvent(event.type, event.payload);
|
|
},
|
|
'user.updated': (event) => {
|
|
return analytics.trackEvent(event.type, event.payload);
|
|
},
|
|
};
|
|
|
|
/**
|
|
* Provider for the analytics service
|
|
*/
|
|
export function AnalyticsProvider(props: React.PropsWithChildren) {
|
|
// Subscribe to app events and map them to analytics actions
|
|
useAnalyticsMapping(analyticsMapping);
|
|
|
|
// Report page views to the analytics service
|
|
useReportPageView((url) => analytics.trackPageView(url));
|
|
|
|
// Render children
|
|
return props.children;
|
|
}
|
|
|
|
/**
|
|
* Hook to report page views to the analytics service
|
|
* @param reportAnalyticsFn
|
|
*/
|
|
function useReportPageView(reportAnalyticsFn: (url: string) => unknown) {
|
|
const pathname = usePathname();
|
|
const searchParams = useSearchParams();
|
|
|
|
useEffect(() => {
|
|
const url = [pathname, searchParams.toString()].filter(Boolean).join('?');
|
|
|
|
reportAnalyticsFn(url);
|
|
}, [pathname, reportAnalyticsFn, searchParams]);
|
|
}
|