"use client"; import { useEffect, useRef } from 'react'; import { usePathname } from 'next/navigation'; export default function AnalyticsTracker() { const pathname = usePathname(); const startTimeRef = useRef(Date.now()); // Helper to send events const sendEvent = async (data: { type: string; path: string; label?: string; value?: number; metadata?: any; }) => { try { // Use standard fetch for development reliability await fetch('/api/analytics', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(data), }); } catch (err) { console.error('[Analytics] Error:', err); } }; // 1. Track Page Views useEffect(() => { // Attempt to get userId from localStorage (common in this app's auth setup) let userId = null; try { const userStr = localStorage.getItem('user'); if (userStr) { const user = JSON.parse(userStr); userId = user.id; } } catch (e) {} sendEvent({ type: 'PAGE_VIEW', path: pathname, metadata: { userAgent: navigator.userAgent, screen: `${window.innerWidth}x${window.innerHeight}`, referrer: document.referrer, userId: userId } }); // Reset start time for dwell time calculation startTimeRef.current = Date.now(); // 2. Track Dwell Time on cleanup (when leaving page) return () => { const dwellTime = Math.round((Date.now() - startTimeRef.current) / 1000); if (dwellTime > 0) { sendEvent({ type: 'DWELL_TIME', path: pathname, value: dwellTime, }); } }; }, [pathname]); // 3. Track Global Clicks useEffect(() => { const handleClick = (e: MouseEvent) => { const target = e.target as HTMLElement; // Look for clickable elements (buttons, links) const clickable = target.closest('button, a, [role="button"]'); if (clickable) { const label = clickable.textContent?.trim().slice(0, 50) || (clickable as HTMLAnchorElement).href || clickable.getAttribute('aria-label') || 'Unnamed Action'; sendEvent({ type: 'CLICK', path: window.location.pathname, label, metadata: { tagName: clickable.tagName, id: clickable.id, className: clickable.className, } }); } }; window.addEventListener('click', handleClick); return () => window.removeEventListener('click', handleClick); }, []); return null; // Invisible component }