Add privacy-friendly analytics and cookie consent, integrated into the CMS
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
This commit is contained in:
+29
-2
@@ -16,6 +16,8 @@ import { Availability } from "@/collections/Availability";
|
||||
import { AvailabilityOverrides } from "@/collections/AvailabilityOverrides";
|
||||
import { BookingRequests } from "@/collections/BookingRequests";
|
||||
import { Redirects } from "@/collections/Redirects";
|
||||
import { AnalyticsEvents } from "@/collections/AnalyticsEvents";
|
||||
import { AnalyticsDailyStats } from "@/collections/AnalyticsDailyStats";
|
||||
|
||||
import { Home } from "@/globals/Home";
|
||||
import { About } from "@/globals/About";
|
||||
@@ -26,6 +28,8 @@ import { Booking } from "@/globals/Booking";
|
||||
import { MeetingSettings } from "@/globals/MeetingSettings";
|
||||
import { BookingSettings } from "@/globals/BookingSettings";
|
||||
import { SEOSettings } from "@/globals/SEOSettings";
|
||||
import { CookieSettings } from "@/globals/CookieSettings";
|
||||
import { AnalyticsSettings } from "@/globals/AnalyticsSettings";
|
||||
|
||||
const filename = fileURLToPath(import.meta.url);
|
||||
const dirname = path.dirname(filename);
|
||||
@@ -41,7 +45,10 @@ export default buildConfig({
|
||||
titleSuffix: "— Anouma Admin",
|
||||
},
|
||||
components: {
|
||||
afterNavLinks: ["/components/admin/CalendarNavLink#CalendarNavLink"],
|
||||
afterNavLinks: [
|
||||
"/components/admin/CalendarNavLink#CalendarNavLink",
|
||||
"/components/admin/AnalyticsNavLink#AnalyticsNavLink",
|
||||
],
|
||||
views: {
|
||||
kalender: {
|
||||
Component: "/components/admin/AdminCalendarView#AdminCalendarView",
|
||||
@@ -49,6 +56,12 @@ export default buildConfig({
|
||||
exact: true,
|
||||
meta: { title: "Kalender" },
|
||||
},
|
||||
analytics: {
|
||||
Component: "/components/admin/AdminAnalyticsView#AdminAnalyticsView",
|
||||
path: "/analytics",
|
||||
exact: true,
|
||||
meta: { title: "Analytics" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -64,8 +77,22 @@ export default buildConfig({
|
||||
AvailabilityOverrides,
|
||||
BookingRequests,
|
||||
Redirects,
|
||||
AnalyticsEvents,
|
||||
AnalyticsDailyStats,
|
||||
],
|
||||
globals: [
|
||||
Home,
|
||||
About,
|
||||
AngeboteIntro,
|
||||
AktuellesIntro,
|
||||
Contact,
|
||||
Booking,
|
||||
MeetingSettings,
|
||||
BookingSettings,
|
||||
SEOSettings,
|
||||
CookieSettings,
|
||||
AnalyticsSettings,
|
||||
],
|
||||
globals: [Home, About, AngeboteIntro, AktuellesIntro, Contact, Booking, MeetingSettings, BookingSettings, SEOSettings],
|
||||
editor: lexicalEditor(),
|
||||
secret: process.env.PAYLOAD_SECRET || "",
|
||||
typescript: {
|
||||
|
||||
Reference in New Issue
Block a user