@@ -7,6 +7,39 @@ interface UseAnalyticsTrackingOptions {
77 trackClick ?: boolean
88}
99
10+ // Helper to get or create session ID
11+ const getSessionId = ( ) => {
12+ if ( typeof window === 'undefined' ) return null
13+
14+ let sessionId = sessionStorage . getItem ( 'analytics_session_id' )
15+ if ( ! sessionId ) {
16+ sessionId = `session_${ Date . now ( ) } _${ Math . random ( ) . toString ( 36 ) . substr ( 2 , 9 ) } `
17+ sessionStorage . setItem ( 'analytics_session_id' , sessionId )
18+ }
19+ return sessionId
20+ }
21+
22+ // Helper to check if already viewed in this session
23+ const hasViewedInSession = ( slug : string , type : 'event' | 'hackathon' ) : boolean => {
24+ if ( typeof window === 'undefined' ) return false
25+
26+ const key = `viewed_${ type } s`
27+ const viewed = JSON . parse ( sessionStorage . getItem ( key ) || '[]' )
28+ return viewed . includes ( slug )
29+ }
30+
31+ // Helper to mark as viewed in this session
32+ const markAsViewed = ( slug : string , type : 'event' | 'hackathon' ) : void => {
33+ if ( typeof window === 'undefined' ) return
34+
35+ const key = `viewed_${ type } s`
36+ const viewed = JSON . parse ( sessionStorage . getItem ( key ) || '[]' )
37+ if ( ! viewed . includes ( slug ) ) {
38+ viewed . push ( slug )
39+ sessionStorage . setItem ( key , JSON . stringify ( viewed ) )
40+ }
41+ }
42+
1043export function useAnalyticsTracking ( {
1144 eventSlug,
1245 hackathonId,
@@ -16,30 +49,79 @@ export function useAnalyticsTracking({
1649 const viewTracked = useRef ( false )
1750 const clickTracked = useRef ( false )
1851
19- // Track view on mount
52+ console . log ( '[Analytics Hook] Initialized with:' , { eventSlug, hackathonId, trackView, trackClick } )
53+
54+ // Track view on mount with session-based deduplication
2055 useEffect ( ( ) => {
21- if ( ! trackView || viewTracked . current ) return
56+ console . log ( '[Analytics Hook] useEffect triggered' , { trackView, viewTracked : viewTracked . current } )
57+ if ( ! trackView || viewTracked . current ) {
58+ console . log ( '[Analytics Hook] Skipping - trackView:' , trackView , 'viewTracked:' , viewTracked . current )
59+ return
60+ }
2261
2362 const trackViewAsync = async ( ) => {
2463 try {
64+ const sessionId = getSessionId ( )
65+ if ( ! sessionId ) {
66+ console . log ( '[Analytics] No session ID available' )
67+ return
68+ }
69+
2570 if ( eventSlug ) {
26- await fetch ( `/api/events/${ eventSlug } /track-view` , {
71+ console . log ( '[Analytics] Tracking view for event:' , eventSlug )
72+
73+ // Check if already viewed in this session
74+ if ( hasViewedInSession ( eventSlug , 'event' ) ) {
75+ console . log ( '[Analytics] Event already viewed in this session' )
76+ viewTracked . current = true
77+ return
78+ }
79+
80+ console . log ( '[Analytics] Sending track-view request...' )
81+ const response = await fetch ( `/api/events/${ eventSlug } /track-view` , {
2782 method : 'POST' ,
83+ headers : {
84+ 'Content-Type' : 'application/json' ,
85+ } ,
86+ body : JSON . stringify ( { sessionId } ) ,
2887 } )
29- viewTracked . current = true
88+
89+ console . log ( '[Analytics] Track-view response:' , response . status , response . ok )
90+
91+ if ( response . ok ) {
92+ markAsViewed ( eventSlug , 'event' )
93+ viewTracked . current = true
94+ console . log ( '[Analytics] View tracked successfully' )
95+ } else {
96+ console . error ( '[Analytics] Failed to track view:' , await response . text ( ) )
97+ }
3098 } else if ( hackathonId ) {
31- await fetch ( `/api/hackathons/${ hackathonId } /track-view` , {
99+ // Check if already viewed in this session
100+ if ( hasViewedInSession ( hackathonId , 'hackathon' ) ) {
101+ viewTracked . current = true
102+ return
103+ }
104+
105+ const response = await fetch ( `/api/hackathons/${ hackathonId } /track-view` , {
32106 method : 'POST' ,
107+ headers : {
108+ 'Content-Type' : 'application/json' ,
109+ } ,
110+ body : JSON . stringify ( { sessionId } ) ,
33111 } )
34- viewTracked . current = true
112+
113+ if ( response . ok ) {
114+ markAsViewed ( hackathonId , 'hackathon' )
115+ viewTracked . current = true
116+ }
35117 }
36118 } catch ( error ) {
37119 console . error ( 'Error tracking view:' , error )
38120 }
39121 }
40122
41- // Track view after a short delay to avoid tracking bots
42- const timer = setTimeout ( trackViewAsync , 1000 )
123+ // Track view after a short delay to avoid tracking bots and ensure real engagement
124+ const timer = setTimeout ( trackViewAsync , 2000 )
43125
44126 return ( ) => clearTimeout ( timer )
45127 } , [ eventSlug , hackathonId , trackView ] )
0 commit comments