File size: 2,241 Bytes
6111b2b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
"use client";

import { useEffect, useCallback, useRef } from "react";

interface PageAnalyticsProps {
  slug: string;
  title: string;
  section: string;
}

const STORAGE_KEY = "omniroute_docs_analytics";
const MAX_EVENTS = 200;

interface AnalyticsEvent {
  slug: string;
  title: string;
  section: string;
  timestamp: number;
  referrer: string;
}

function getEvents(): AnalyticsEvent[] {
  try {
    const raw = localStorage.getItem(STORAGE_KEY);
    if (!raw) return [];
    return JSON.parse(raw);
  } catch {
    return [];
  }
}

function pruneEvents(events: AnalyticsEvent[]): AnalyticsEvent[] {
  return events.slice(-MAX_EVENTS);
}

export function DocsPageAnalytics({ slug, title, section }: PageAnalyticsProps) {
  const trackedRef = useRef(false);

  const trackPageView = useCallback(() => {
    if (trackedRef.current) return;
    trackedRef.current = true;

    try {
      const events = getEvents();
      events.push({
        slug,
        title,
        section,
        timestamp: Date.now(),
        referrer: typeof document !== "undefined" ? document.referrer : "",
      });
      localStorage.setItem(STORAGE_KEY, JSON.stringify(pruneEvents(events)));
    } catch {
      // localStorage unavailable — silent fail
    }
  }, [slug, title, section]);

  useEffect(() => {
    trackPageView();
  }, [trackPageView]);

  return null; // invisible tracking component
}

export function getPopularPages(

  limit = 5

): { slug: string; title: string; section: string; views: number }[] {
  if (typeof window === "undefined") return [];

  try {
    const events = getEvents();
    const counts = new Map<string, { title: string; section: string; views: number }>();

    for (const event of events) {
      const existing = counts.get(event.slug);
      if (existing) {
        existing.views++;
      } else {
        counts.set(event.slug, {
          slug: event.slug,
          title: event.title,
          section: event.section,
          views: 1,
        });
      }
    }

    return Array.from(counts.values())
      .sort((a, b) => b.views - a.views)
      .slice(0, limit);
  } catch {
    return [];
  }
}