Files
anouma/lib/payload/globals.ts
T
maro 65b6eeac51 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
2026-09-06 21:59:59 +02:00

49 lines
1.7 KiB
TypeScript

import { cache } from "react";
import { getCMS } from "@/lib/payload/getPayload";
import type { About, AktuellesIntro, AngeboteIntro, Booking, BookingSetting, Contact, CookieSetting, Home, SeoSetting } from "@/payload-types";
export const getHomeGlobal = cache(async (): Promise<Home> => {
const payload = await getCMS();
return payload.findGlobal({ slug: "home" });
});
export const getAboutGlobal = cache(async (): Promise<About> => {
const payload = await getCMS();
return payload.findGlobal({ slug: "about" });
});
export const getAngeboteIntroGlobal = cache(async (): Promise<AngeboteIntro> => {
const payload = await getCMS();
return payload.findGlobal({ slug: "angebote-intro" });
});
export const getAktuellesIntroGlobal = cache(async (): Promise<AktuellesIntro> => {
const payload = await getCMS();
return payload.findGlobal({ slug: "aktuelles-intro" });
});
export const getContactGlobal = cache(async (): Promise<Contact> => {
const payload = await getCMS();
return payload.findGlobal({ slug: "contact" });
});
export const getBookingGlobal = cache(async (): Promise<Booking> => {
const payload = await getCMS();
return payload.findGlobal({ slug: "booking" });
});
export const getBookingSettingsGlobal = cache(async (): Promise<BookingSetting> => {
const payload = await getCMS();
return payload.findGlobal({ slug: "booking-settings" });
});
export const getSEOSettingsGlobal = cache(async (): Promise<SeoSetting> => {
const payload = await getCMS();
return payload.findGlobal({ slug: "seo-settings" });
});
export const getCookieSettingsGlobal = cache(async (): Promise<CookieSetting> => {
const payload = await getCMS();
return payload.findGlobal({ slug: "cookie-settings" });
});