Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions app/_layout.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,35 @@
import { Stack } from "expo-router";
import React from "react";
import { Stack, usePathname, useSegments } from "expo-router";
import React, { useEffect } from "react";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import "react-native-reanimated";
import "../global.css"; // NativeWind CSS
import { ErrorBoundary } from '../src/components/common/ErrorBoundary';
import { AnalyticsProvider } from "../src/components/mobile/AnalyticsProvider";
import { OfflineIndicatorProvider } from "../src/components/mobile/OfflineIndicatorProvider";
import { SwipeableNavigation } from '../src/components/mobile/SwipeableNavigation';
import { useAnalytics } from '../src/hooks/useAnalytics';

// Component to handle auto screen tracking
function ScreenTracker() {
const pathname = usePathname();
const segments = useSegments();
const { trackScreen } = useAnalytics();

useEffect(() => {
if (pathname) {
// Basic screen tracking based on pathname
trackScreen(pathname, { segments: segments.join('/') });
}
}, [pathname, segments, trackScreen]);

return null;
}

export default function RootLayout() {
return (
<ErrorBoundary boundaryName="RootLayout">
<AnalyticsProvider>
<ScreenTracker />
<OfflineIndicatorProvider>
<GestureHandlerRootView style={{ flex: 1 }}>
<Stack>
Expand Down
38 changes: 38 additions & 0 deletions src/hooks/useAnalytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,49 @@ export const useAnalytics = () => {
[service]
);

/**
* Track button clicks
*/
const trackButtonClick = useCallback(
(buttonName: string, properties?: EventProperties) => {
service.trackEvent(AnalyticsEvent.UI_CLICK, { button: buttonName, ...properties });
},
[service]
);

/**
* Track form submissions
*/
const trackFormSubmit = useCallback(
(formName: string, properties?: EventProperties) => {
service.trackEvent(AnalyticsEvent.FORM_SUBMIT, { form: formName, ...properties });
},
[service]
);

/**
* Track errors
*/
const trackError = useCallback(
(error: Error | string, isFatal: boolean = false, properties?: EventProperties) => {
const errorMessage = error instanceof Error ? error.message : error;
service.trackEvent(isFatal ? AnalyticsEvent.CRASH_REPORT : AnalyticsEvent.API_ERROR, {
error: errorMessage,
isFatal,
...properties,
});
},
[service]
);

return {
trackEvent,
trackScreen,
trackTiming,
identify,
trackButtonClick,
trackFormSubmit,
trackError,
service, // Direct access if needed
};
};
Expand Down
Loading