import { useId, useRef, type ReactNode } from "react"; import { DEFAULT_DASHBOARD_LAYOUT, displayPath, panelNavItem, sectionInRoot, useCurrentNavSection, visiblePanels, type RecentEvent, } from "@razorsoft/causewise-react"; export const ANALYTICS_SECTIONS = visiblePanels(DEFAULT_DASHBOARD_LAYOUT).map((panel) => panelNavItem(panel.type)); export type AnalyticsSectionId = (typeof ANALYTICS_SECTIONS)[number]["id"]; export type EventFilter = "all" | "pageviews" | "custom"; const EVENT_FILTERS: { id: EventFilter; label: string }[] = [ { id: "all", label: "All" }, { id: "pageviews", label: "Pageviews" }, { id: "custom", label: "Custom Events" }, ]; export function isPageview(type: string | null | undefined) { return (type ?? "").trim().toLowerCase() === "pageview"; } export function eventName(type: string | null | undefined) { const name = (type ?? "").trim(); return name || "Custom event"; } export function filterEvents(events: T[], filter: EventFilter) { if (filter === "pageviews") return events.filter((event) => isPageview(event.type)); if (filter === "custom") return events.filter((event) => !isPageview(event.type)); return events; } export function adminBarOffset(doc: Document = document) { const bar = doc.getElementById("wpadminbar"); if (!bar) return 0; const height = bar.getBoundingClientRect().height; return Number.isFinite(height) && height > 0 ? Math.round(height) : 0; } export function sectionScrollOffset(adminBarHeight: number, navHeight: number) { const bar = Number.isFinite(adminBarHeight) && adminBarHeight > 0 ? adminBarHeight : 0; const nav = Number.isFinite(navHeight) && navHeight > 0 ? navHeight : 48; return bar + nav + 8; } export function activateSectionLink(link: HTMLAnchorElement, id: string) { const target = sectionInRoot(link, id); if (!target) return false; const nav = link.closest("nav"); const offset = sectionScrollOffset(adminBarOffset(link.ownerDocument), nav?.getBoundingClientRect().height ?? 0); target.style.scrollMarginTop = `${offset}px`; if (typeof target.scrollIntoView === "function") { target.scrollIntoView({ behavior: "smooth", block: "start" }); } return true; } export function AnalyticsAnchor({ id, children }: { id: AnalyticsSectionId; children: ReactNode }) { return (
{children}
); } export function SectionPlaceholder({ id, title }: { id: AnalyticsSectionId; title: string }) { return (

{title}

Loading

); } export function SectionNav({ watch = "ready" }: { watch?: string }) { const navRef = useRef(null); const sectionIds = ANALYTICS_SECTIONS.map((section) => section.id); const { active, activate } = useCurrentNavSection( navRef, sectionIds, (nav) => sectionScrollOffset(adminBarOffset(nav.ownerDocument), nav.getBoundingClientRect().height), watch, ); return ( ); } function formatTimestamp(value: string) { if (!value) return "—"; const date = new Date(value); if (Number.isNaN(date.getTime())) return value; return new Intl.DateTimeFormat(undefined, { dateStyle: "medium", timeStyle: "short" }).format(date); } function eventFields(event: RecentEvent) { return { id: typeof event.id === "string" ? event.id : "", type: typeof event.type === "string" ? event.type : "", path: typeof event.path === "string" ? event.path : "", timestamp: typeof event.timestamp === "string" ? event.timestamp : "", }; } export const EVENT_PAGE_SIZES = [10, 20, 50] as const; export function RecentEventsPanel({ events, activityHref, filter, pageSize, hasMore, loading, loadingMore, refreshing, error, onFilter, onPageSize, onLoadMore, onRefresh, }: { events: RecentEvent[] | null; activityHref: string; filter: EventFilter; pageSize: number; hasMore: boolean; loading: boolean; loadingMore: boolean; refreshing: boolean; error: string | null; onFilter: (filter: EventFilter) => void; onPageSize: (size: number) => void; onLoadMore: () => void; onRefresh: () => void; }) { const titleId = useId(); const rows = events ? events.map(eventFields) : []; const busy = loading || loadingMore || refreshing; const emptyCopy = filter === "pageviews" ? "No pageviews in this period." : filter === "custom" ? "No custom events in this period." : "No activity in this period."; return (

Recent events

{EVENT_FILTERS.map((item) => ( ))}
{error ? (

{error}

) : null} {loading && events === null ?

Loading recent events.

: null} {!loading && events === null && !error ?

Recent events could not be loaded.

: null} {events && events.length === 0 ? ( <>

{emptyCopy}

Page views and other actions appear here after people visit your site.

) : null} {rows.length > 0 ? (
{rows.map((event) => { const pageview = isPageview(event.type); return ( ); })}
Event Type Time Path
{pageview ? "Pageview" : eventName(event.type)} {pageview ? "Pageview" : "Custom event"} {formatTimestamp(event.timestamp)} {displayPath(event.path) || "—"}
) : null} {hasMore ? (

) : null}

View activity

); }