// Analytics event names — single source of truth export const ANALYTICS_EVENTS = { BOOKING_STEP_SERVICE: "booking_step_service", BOOKING_STEP_TIME: "booking_step_time", BOOKING_STEP_CONTACT: "booking_step_contact", BOOKING_STEP_SUBMIT: "booking_step_submit", BOOKING_CONFIRMED: "booking_confirmed", BOOKING_ERROR: "booking_error", } as const; export type AnalyticsEventName = (typeof ANALYTICS_EVENTS)[keyof typeof ANALYTICS_EVENTS]; export type AnalyticsPayload = { step?: string; flow?: "public" | "portal"; [key: string]: string | undefined; }; /** * Fires a lightweight analytics event via window.dispatchEvent. * No-op safe: failures are swallowed so analytics never breaks the booking flow. * Designed for later Plausible/GTM integration. */ export function fireAnalyticsEvent( eventName: AnalyticsEventName, payload: AnalyticsPayload = {} ): void { try { window.dispatchEvent( new CustomEvent(eventName, { detail: { ...payload, timestamp: new Date().toISOString(), }, }) ); } catch { // no-op: analytics must never break the booking flow } }