Adds a first-party analytics system with no third-party trackers and no persistent per-visitor identifiers: events are grouped into sessions via a daily-rotating pseudonymous hash (IP+UA+host, HMAC-salted, never stored raw). - New "Analytics" section in the Payload admin, gated by a canViewAnalytics permission on Users, following the existing custom-admin-view pattern used by the calendar feature - Sessions, page views, unique visitors, top/entry/exit pages, events, device/browser breakdown, date range filter with period comparison - Raw events and daily aggregate rollups as their own collections, with configurable retention and a cron endpoint that rolls up before purging - Cookie consent banner (necessary/preferences/statistics) with categories and copy editable from a new CMS global; a track() helper that is a complete no-op without statistics consent, so nothing is ever sent before a visitor opts in - track() calls wired into the booking flow, contact form, and navigation
27 lines
1.1 KiB
TypeScript
27 lines
1.1 KiB
TypeScript
/**
|
|
* Central, extensible registry of known analytics event names. Adding a new
|
|
* event elsewhere in the app never requires a migration — the database
|
|
* column (collections/AnalyticsEvents.ts#eventName) is free-text — this
|
|
* list exists purely so `track()` calls get autocomplete/type-checking and
|
|
* the dashboard can show a nice German label instead of a raw event name.
|
|
*
|
|
* To add a new event: add one entry here, then call `track("your_event")`
|
|
* anywhere in the app (see lib/analytics/client.ts).
|
|
*/
|
|
export const ANALYTICS_EVENTS = {
|
|
page_view: "Seitenaufruf",
|
|
booking_started: "Buchung gestartet",
|
|
booking_completed: "Buchung abgeschlossen",
|
|
contact_clicked: "Kontakt angeklickt",
|
|
navigation_clicked: "Navigation geklickt",
|
|
} as const;
|
|
|
|
export type KnownAnalyticsEvent = keyof typeof ANALYTICS_EVENTS;
|
|
|
|
/** Any string works (see the collection comment above) — known ones just get a label. */
|
|
export type AnalyticsEventName = KnownAnalyticsEvent | (string & {});
|
|
|
|
export function analyticsEventLabel(eventName: string): string {
|
|
return (ANALYTICS_EVENTS as Record<string, string>)[eventName] ?? eventName;
|
|
}
|