refactor: remove realtime visitors detail page

Remove the individual session journey page and make the live visitor
count a static indicator. Prepares for the new aggregated User Journeys
feature (v0.17).
This commit is contained in:
Usman Baig
2026-03-12 20:45:58 +01:00
parent bae492e8d9
commit 6964be9610
10 changed files with 11 additions and 445 deletions

View File

@@ -1,42 +0,0 @@
import apiRequest from './client'
export interface Visitor {
session_id: string
first_seen: string
last_seen: string
pageviews: number
current_path: string
browser: string
os: string
device_type: string
country: string
city: string
}
export interface SessionEvent {
id: string
site_id: string
session_id: string
path: string
referrer: string | null
user_agent: string
country: string | null
city: string | null
region: string | null
device_type: string
screen_resolution: string | null
browser: string | null
os: string | null
timestamp: string
created_at: string
}
export async function getRealtimeVisitors(siteId: string): Promise<Visitor[]> {
const data = await apiRequest<{ visitors: Visitor[] }>(`/sites/${siteId}/realtime/visitors`)
return data.visitors
}
export async function getSessionDetails(siteId: string, sessionId: string): Promise<SessionEvent[]> {
const data = await apiRequest<{ events: SessionEvent[] }>(`/sites/${siteId}/sessions/${sessionId}`)
return data.events
}

View File

@@ -1,53 +0,0 @@
// * SSE hook for real-time visitor streaming.
// * Replaces 5-second polling with a persistent EventSource connection.
// * The backend broadcasts one DB query per site to all connected clients,
// * so 1,000 users on the same site share a single query instead of each
// * triggering their own.
import { useEffect, useRef, useState, useCallback } from 'react'
import { API_URL } from '@/lib/api/client'
import type { Visitor } from '@/lib/api/realtime'
interface UseRealtimeSSEReturn {
visitors: Visitor[]
connected: boolean
}
export function useRealtimeSSE(siteId: string): UseRealtimeSSEReturn {
const [visitors, setVisitors] = useState<Visitor[]>([])
const [connected, setConnected] = useState(false)
const esRef = useRef<EventSource | null>(null)
// Stable callback so we don't recreate EventSource on every render
const handleMessage = useCallback((event: MessageEvent) => {
try {
const data = JSON.parse(event.data)
setVisitors(data.visitors || [])
} catch {
// Ignore malformed messages
}
}, [])
useEffect(() => {
if (!siteId) return
const url = `${API_URL}/api/v1/sites/${siteId}/realtime/stream`
const es = new EventSource(url, { withCredentials: true })
esRef.current = es
es.onopen = () => setConnected(true)
es.onmessage = handleMessage
es.onerror = () => {
setConnected(false)
// EventSource auto-reconnects with exponential backoff
}
return () => {
es.close()
esRef.current = null
setConnected(false)
}
}, [siteId, handleMessage])
return { visitors, connected }
}