@roomstay/frontend 2.6.102 → 2.6.103

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/dist/177.bundle.js +1 -1
  2. package/dist/211.bundle.js +1 -0
  3. package/dist/288.bundle.js +1 -1
  4. package/dist/326.bundle.js +2 -0
  5. package/dist/326.bundle.js.LICENSE.txt +16 -0
  6. package/dist/328.bundle.js +1 -1
  7. package/dist/main.bundle.js +1 -1
  8. package/dist/src/api/AnalyticsEventsAPI.d.ts +13 -0
  9. package/dist/src/api/AnalyticsEventsAPI.js +55 -0
  10. package/dist/src/api/AnalyticsEventsAPI.js.map +1 -0
  11. package/dist/src/components/generic/PromotionalCodeInput.js +1 -1
  12. package/dist/src/components/generic/PromotionalCodeInput.js.map +1 -1
  13. package/dist/src/components/steps/confirmation/PayPalPaymentOption/PayPalPaymentOption.d.ts +2 -0
  14. package/dist/src/components/steps/confirmation/PayPalPaymentOption/PayPalPaymentOption.js +86 -0
  15. package/dist/src/components/steps/confirmation/PayPalPaymentOption/PayPalPaymentOption.js.map +1 -0
  16. package/dist/src/components/steps/confirmation/RoomContactDetails.js +2 -0
  17. package/dist/src/components/steps/confirmation/RoomContactDetails.js.map +1 -1
  18. package/dist/src/components/steps/confirmation/StepConfirmationForm.js +1 -1
  19. package/dist/src/components/steps/confirmation/StepConfirmationForm.js.map +1 -1
  20. package/dist/src/components/steps/date/PeoplePicker.js +1 -1
  21. package/dist/src/components/steps/date/PeoplePicker.js.map +1 -1
  22. package/dist/src/components/steps/date/PeoplePickerRow.js +2 -2
  23. package/dist/src/components/steps/date/PeoplePickerRow.js.map +1 -1
  24. package/dist/src/components/steps/room/RoomListCrossSellBlock.js +1 -0
  25. package/dist/src/components/steps/room/RoomListCrossSellBlock.js.map +1 -1
  26. package/dist/src/components/steps/room/UserSearchSummary/UserSearchSummary.js +5 -3
  27. package/dist/src/components/steps/room/UserSearchSummary/UserSearchSummary.js.map +1 -1
  28. package/dist/src/components/steps/room/UserSearchSummary/UserSearchSummaryRow.js +2 -2
  29. package/dist/src/components/steps/room/UserSearchSummary/UserSearchSummaryRow.js.map +1 -1
  30. package/dist/src/components/steps/room/roomBuilderProgress/NumberOfAdultsPicker.js +3 -3
  31. package/dist/src/components/steps/room/roomBuilderProgress/NumberOfAdultsPicker.js.map +1 -1
  32. package/dist/src/components/steps/room/roomBuilderProgress/RoomBuilderProgress.js +3 -3
  33. package/dist/src/components/steps/room/roomBuilderProgress/RoomBuilderProgress.js.map +1 -1
  34. package/dist/src/contexts/BasketContext/BasketContextType.d.ts +4 -0
  35. package/dist/src/contexts/BasketContext/BasketContextType.js.map +1 -1
  36. package/dist/src/contexts/BasketContext/BasketContextWrapper.js +46 -6
  37. package/dist/src/contexts/BasketContext/BasketContextWrapper.js.map +1 -1
  38. package/dist/src/contexts/CompanyContext/CompanyContextWrapper.js +10 -0
  39. package/dist/src/contexts/CompanyContext/CompanyContextWrapper.js.map +1 -1
  40. package/dist/src/contexts/ConfirmationStepContext/ConfirmationStepContextWrapper.js +21 -3
  41. package/dist/src/contexts/ConfirmationStepContext/ConfirmationStepContextWrapper.js.map +1 -1
  42. package/dist/src/contexts/ConfirmationStepContext/ConfirmationStepPriceQuoteErrorModal.d.ts +9 -0
  43. package/dist/src/contexts/ConfirmationStepContext/ConfirmationStepPriceQuoteErrorModal.js +67 -0
  44. package/dist/src/contexts/ConfirmationStepContext/ConfirmationStepPriceQuoteErrorModal.js.map +1 -0
  45. package/dist/src/contexts/FullPageEngineContext/FullPageEngineContextWrapper.js +43 -7
  46. package/dist/src/contexts/FullPageEngineContext/FullPageEngineContextWrapper.js.map +1 -1
  47. package/dist/src/handlers/payment/PayPalPaymentHandler.d.ts +2 -0
  48. package/dist/src/handlers/payment/PayPalPaymentHandler.js +41 -0
  49. package/dist/src/handlers/payment/PayPalPaymentHandler.js.map +1 -0
  50. package/dist/src/hooks/useSearchScopeHook.d.ts +5 -2
  51. package/dist/src/hooks/useSearchScopeHook.js +57 -14
  52. package/dist/src/hooks/useSearchScopeHook.js.map +1 -1
  53. package/dist/src/models/Addon/Addon.js +4 -0
  54. package/dist/src/models/Addon/Addon.js.map +1 -1
  55. package/dist/src/models/Api/HotelDTO.d.ts +1 -1
  56. package/dist/src/models/Api/HotelDTO.js.map +1 -1
  57. package/dist/src/models/BasketRow.d.ts +5 -0
  58. package/dist/src/models/BasketRow.js +13 -1
  59. package/dist/src/models/BasketRow.js.map +1 -1
  60. package/dist/src/models/Client/Hotel/Hotel.d.ts +12 -0
  61. package/dist/src/models/Client/Hotel/Hotel.js.map +1 -1
  62. package/dist/src/pages/findReservation/FindReservationResults.js +2 -2
  63. package/dist/src/pages/findReservation/FindReservationResults.js.map +1 -1
  64. package/dist/src/pages/steps/StepAddon/StepAddonValidator.js +1 -1
  65. package/dist/src/pages/steps/StepAddon/StepAddonValidator.js.map +1 -1
  66. package/dist/src/pages/steps/StepConfirmation/StepConfirmationValidator.js +1 -1
  67. package/dist/src/pages/steps/StepConfirmation/StepConfirmationValidator.js.map +1 -1
  68. package/dist/src/pages/steps/StepRoom/StepRoomValidator.js +1 -1
  69. package/dist/src/pages/steps/StepRoom/StepRoomValidator.js.map +1 -1
  70. package/dist/src/pages/steps/StepThanks/StepThanksComponent.js +2 -2
  71. package/dist/src/pages/steps/StepThanks/StepThanksComponent.js.map +1 -1
  72. package/dist/src/providers/FeatureProvider.js +2 -0
  73. package/dist/src/providers/FeatureProvider.js.map +1 -1
  74. package/dist/src/providers/RatePillProvider.d.ts +1 -0
  75. package/dist/src/providers/RatePillProvider.js +11 -4
  76. package/dist/src/providers/RatePillProvider.js.map +1 -1
  77. package/dist/src/providers/feature/AnalyticsEventsFeature.d.ts +23 -0
  78. package/dist/src/providers/feature/AnalyticsEventsFeature.js +83 -0
  79. package/dist/src/providers/feature/AnalyticsEventsFeature.js.map +1 -0
  80. package/dist/src/translations/Translation.d.ts +5 -0
  81. package/dist/src/translations/Translation.js +5 -0
  82. package/dist/src/translations/Translation.js.map +1 -1
  83. package/dist/src/translations/languages/en-gb.js +9 -4
  84. package/dist/src/translations/languages/en-gb.js.map +1 -1
  85. package/dist/src/util/Analytics/Analytics.d.ts +7 -0
  86. package/dist/src/util/Analytics/Analytics.js +8 -1
  87. package/dist/src/util/Analytics/Analytics.js.map +1 -1
  88. package/dist/src/util/AnalyticsEvents/AnalyticsEvents.d.ts +61 -0
  89. package/dist/src/util/AnalyticsEvents/AnalyticsEvents.js +329 -0
  90. package/dist/src/util/AnalyticsEvents/AnalyticsEvents.js.map +1 -0
  91. package/dist/src/util/AnalyticsEvents/helpers.d.ts +30 -0
  92. package/dist/src/util/AnalyticsEvents/helpers.js +96 -0
  93. package/dist/src/util/AnalyticsEvents/helpers.js.map +1 -0
  94. package/dist/src/util/DataLayer.js +4 -4
  95. package/dist/src/util/DataLayer.js.map +1 -1
  96. package/dist/test.bundle.js +1 -1
  97. package/dist/vendors.bundle.js +1 -1
  98. package/package.json +3 -2
  99. package/dist/180.bundle.js +0 -1
  100. package/dist/570.bundle.js +0 -1
@@ -0,0 +1,329 @@
1
+ "use strict";
2
+ /**
3
+ * Analytics Events Utility
4
+ */
5
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
6
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7
+ return new (P || (P = Promise))(function (resolve, reject) {
8
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
9
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
10
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
11
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
12
+ });
13
+ };
14
+ var __importDefault = (this && this.__importDefault) || function (mod) {
15
+ return (mod && mod.__esModule) ? mod : { "default": mod };
16
+ };
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ const core_1 = require("@roomstay/core");
19
+ const AnalyticsEventsAPI_1 = require("../../api/AnalyticsEventsAPI");
20
+ const AddToCartEvent_1 = require("../../events/actions/AddToCartEvent");
21
+ const RoomstayEventManager_1 = __importDefault(require("../../events/RoomstayEventManager"));
22
+ const CommittedBookingEvent_1 = require("../../events/views/CommittedBookingEvent");
23
+ const StepCheckoutViewEvent_1 = require("../../events/views/StepCheckoutViewEvent");
24
+ const helpers_1 = require("./helpers");
25
+ /**
26
+ * Validate session from storage
27
+ */
28
+ function isValidSession(obj) {
29
+ if (!obj || typeof obj !== 'object')
30
+ return false;
31
+ const session = obj;
32
+ return typeof session.sessionId === 'string' && typeof session.createdAt === 'number' && typeof session.hotelId === 'string' && typeof session.currency === 'string';
33
+ }
34
+ const STORAGE_KEY_PREFIX = 'roomstay-analytics-session';
35
+ const SESSION_MAX_AGE = 12 * 60 * 60 * 1000; // 12 hours
36
+ /**
37
+ * Get storage key for a specific hotel's session
38
+ */
39
+ function getStorageKey(hotelId) {
40
+ return `${STORAGE_KEY_PREFIX}-${hotelId}`;
41
+ }
42
+ function generateUUID() {
43
+ return crypto.randomUUID();
44
+ }
45
+ /**
46
+ * Fire a Meta Pixel event with Event ID for deduplication
47
+ */
48
+ function firePixelEvent(eventName, eventId, customData) {
49
+ const metaPixelIsAvailable = typeof window !== 'undefined' && typeof window.fbq === 'function';
50
+ if (!metaPixelIsAvailable)
51
+ return;
52
+ try {
53
+ window.fbq('track', eventName, customData, { eventID: eventId });
54
+ }
55
+ catch (error) {
56
+ console.error('[AnalyticsEvents] Error firing pixel event:', error);
57
+ }
58
+ }
59
+ class AnalyticsEvents {
60
+ constructor() {
61
+ this.session = null;
62
+ this.config = {};
63
+ this.initialized = false;
64
+ this.listenersRegistered = false;
65
+ this.sessionReady = null;
66
+ }
67
+ /**
68
+ * Initialize analytics with configuration
69
+ */
70
+ initialize(config) {
71
+ var _a, _b, _c, _d;
72
+ if (this.initialized) {
73
+ return;
74
+ }
75
+ this.config = config || {};
76
+ // Try to restore existing session
77
+ const existingSession = this.loadSession();
78
+ const cookies = (0, helpers_1.getMetaCookies)();
79
+ // Resolve hotelId and currency from config or existing session
80
+ const hotelFrontendId = (_a = this.config.hotelId) !== null && _a !== void 0 ? _a : existingSession === null || existingSession === void 0 ? void 0 : existingSession.hotelFrontendId;
81
+ const currency = (_b = this.config.currency) !== null && _b !== void 0 ? _b : existingSession === null || existingSession === void 0 ? void 0 : existingSession.currency;
82
+ // Cannot initialize without required fields
83
+ if (!hotelFrontendId || !currency) {
84
+ this.log('Cannot initialize: hotelId and currency are required');
85
+ return;
86
+ }
87
+ if (existingSession) {
88
+ this.session = Object.assign(Object.assign({}, existingSession), { fbc: (_c = cookies.fbc) !== null && _c !== void 0 ? _c : existingSession.fbc, fbp: (_d = cookies.fbp) !== null && _d !== void 0 ? _d : existingSession.fbp, hotelFrontendId,
89
+ currency });
90
+ this.sessionReady = Promise.resolve(true);
91
+ this.log('Session restored:', this.session.sessionId);
92
+ }
93
+ else {
94
+ this.session = {
95
+ sessionId: generateUUID(),
96
+ fbc: cookies.fbc,
97
+ fbp: cookies.fbp,
98
+ createdAt: Date.now(),
99
+ hotelFrontendId,
100
+ currency,
101
+ };
102
+ this.sessionReady = this.createServerSession();
103
+ }
104
+ this.saveSession();
105
+ this.initialized = true;
106
+ this.registerEventListeners();
107
+ this.log('Session initialized:', this.session.sessionId);
108
+ }
109
+ /**
110
+ * Create session on the server
111
+ */
112
+ createServerSession() {
113
+ return __awaiter(this, void 0, void 0, function* () {
114
+ if (!this.session)
115
+ return false;
116
+ try {
117
+ const response = yield AnalyticsEventsAPI_1.analyticsEventsAPI.createSession({
118
+ sessionId: this.session.sessionId,
119
+ hotelFrontendId: this.session.hotelFrontendId,
120
+ fbc: this.session.fbc,
121
+ fbp: this.session.fbp,
122
+ });
123
+ if (!response.success) {
124
+ console.warn('[AnalyticsEvents] Failed to create server session:', response.message);
125
+ return false;
126
+ }
127
+ this.log('Server session ready:', this.session.sessionId);
128
+ return true;
129
+ }
130
+ catch (error) {
131
+ console.error('[AnalyticsEvents] Error creating server session:', error);
132
+ return false;
133
+ }
134
+ });
135
+ }
136
+ /**
137
+ * Register listeners for Roomstay events
138
+ */
139
+ registerEventListeners() {
140
+ if (this.listenersRegistered)
141
+ return;
142
+ // View/Checkout event
143
+ RoomstayEventManager_1.default.addEvent(StepCheckoutViewEvent_1.StepCheckoutViewEvent, (event) => __awaiter(this, void 0, void 0, function* () {
144
+ this.trackInitiateCheckout(event.basketRows);
145
+ }), 'analytics-events-checkout');
146
+ // Basket/Add event
147
+ RoomstayEventManager_1.default.addEvent(AddToCartEvent_1.AddToCartEvent, (event) => __awaiter(this, void 0, void 0, function* () {
148
+ this.trackAddToCart(event.basketRow);
149
+ }), 'analytics-events-add-to-cart');
150
+ // Booking/Committed event
151
+ RoomstayEventManager_1.default.addEvent(CommittedBookingEvent_1.CommittedBookingEvent, (event) => __awaiter(this, void 0, void 0, function* () {
152
+ this.trackPurchase(event.reservation, event.basketRows);
153
+ }), 'analytics-events-purchase');
154
+ this.listenersRegistered = true;
155
+ this.log('Event listeners registered');
156
+ }
157
+ /**
158
+ * Track View/Checkout event
159
+ */
160
+ trackInitiateCheckout(basketRows) {
161
+ const session = this.getValidatedSession();
162
+ if (!session)
163
+ return;
164
+ const { currency } = session;
165
+ const items = (0, helpers_1.serializeBasketRows)(basketRows);
166
+ // Build event data in Roomstay format
167
+ const eventData = {
168
+ items,
169
+ currency,
170
+ totalValue: (0, helpers_1.calculateTotalValue)(items),
171
+ };
172
+ const payload = this.createEventPayload(core_1.ERoomstayEventName.ViewCheckout, eventData);
173
+ // Fire Meta Pixel with transformed data
174
+ if (this.config.firePixelEvents) {
175
+ const metaEventData = (0, core_1.transformToMetaEventData)(eventData);
176
+ firePixelEvent('InitiateCheckout', payload.eventId, metaEventData);
177
+ }
178
+ this.sendEvent(payload);
179
+ this.log('View/Checkout tracked:', payload);
180
+ }
181
+ /**
182
+ * Track Basket/Add event
183
+ */
184
+ trackAddToCart(basketRow) {
185
+ const session = this.getValidatedSession();
186
+ if (!session)
187
+ return;
188
+ const { currency } = session;
189
+ // Build event data in Roomstay format
190
+ const eventData = {
191
+ item: (0, helpers_1.serializeBasketRow)(basketRow),
192
+ currency,
193
+ };
194
+ const payload = this.createEventPayload(core_1.ERoomstayEventName.BasketAdd, eventData);
195
+ // Fire Meta Pixel with transformed data
196
+ if (this.config.firePixelEvents) {
197
+ const metaEventData = (0, core_1.transformToMetaEventData)(eventData);
198
+ firePixelEvent('AddToCart', payload.eventId, metaEventData);
199
+ }
200
+ this.sendEvent(payload);
201
+ this.log('Basket/Add tracked:', payload);
202
+ }
203
+ /**
204
+ * Track Booking/Committed event
205
+ */
206
+ trackPurchase(reservation, basketRows) {
207
+ const session = this.getValidatedSession();
208
+ if (!session)
209
+ return;
210
+ const { currency } = session;
211
+ const items = (0, helpers_1.serializeBasketRows)(basketRows);
212
+ // Build event data in Roomstay format with embedded guest data
213
+ const eventData = {
214
+ items,
215
+ currency,
216
+ totalValue: (0, helpers_1.calculateTotalValue)(items),
217
+ roomstayId: reservation.roomstayId,
218
+ itineraryNumber: reservation.itineraryNumber,
219
+ reservationNumbers: reservation.reservations.map((r) => r.reservationNumber),
220
+ guest: Object.assign(Object.assign({}, (0, helpers_1.extractGuestData)(reservation)), { externalId: session.externalId }),
221
+ };
222
+ const payload = this.createEventPayload(core_1.ERoomstayEventName.BookingCommitted, eventData);
223
+ // Fire Meta Pixel with transformed data
224
+ if (this.config.firePixelEvents) {
225
+ const metaEventData = (0, core_1.transformToMetaEventData)(eventData);
226
+ firePixelEvent('Purchase', payload.eventId, metaEventData);
227
+ }
228
+ this.sendEvent(payload);
229
+ this.log('Booking/Committed tracked:', payload);
230
+ }
231
+ /**
232
+ * Set external user ID (e.g. member portal ID)
233
+ */
234
+ setExternalId(externalId) {
235
+ if (this.session) {
236
+ this.log('Setting external ID:', externalId);
237
+ this.session.externalId = externalId;
238
+ this.saveSession();
239
+ }
240
+ }
241
+ /**
242
+ * Ensure session is initialized and has required fields for tracking.
243
+ * Returns the session if tracking can proceed, null otherwise.
244
+ */
245
+ getValidatedSession() {
246
+ if (!this.initialized) {
247
+ this.initialize(this.config);
248
+ }
249
+ if (!this.session) {
250
+ console.warn('[AnalyticsEvents] Cannot track: session not initialized');
251
+ return null;
252
+ }
253
+ return this.session;
254
+ }
255
+ createEventPayload(eventName, eventData) {
256
+ var _a, _b;
257
+ const session = this.session;
258
+ return {
259
+ eventId: generateUUID(),
260
+ sessionId: (_a = session === null || session === void 0 ? void 0 : session.sessionId) !== null && _a !== void 0 ? _a : '',
261
+ eventName,
262
+ eventTime: Math.floor(Date.now() / 1000),
263
+ hotelFrontendId: (_b = session === null || session === void 0 ? void 0 : session.hotelFrontendId) !== null && _b !== void 0 ? _b : '',
264
+ fbc: (session === null || session === void 0 ? void 0 : session.fbc) || undefined,
265
+ fbp: (session === null || session === void 0 ? void 0 : session.fbp) || undefined,
266
+ eventData,
267
+ };
268
+ }
269
+ sendEvent(eventData) {
270
+ return __awaiter(this, void 0, void 0, function* () {
271
+ try {
272
+ // Wait for session to be created on server before sending events
273
+ if (!this.sessionReady) {
274
+ console.warn('[AnalyticsEvents] Skipping event - sessionReady not initialized');
275
+ return;
276
+ }
277
+ const sessionCreated = yield this.sessionReady;
278
+ if (!sessionCreated) {
279
+ console.warn('[AnalyticsEvents] Skipping event - session not created on server');
280
+ return;
281
+ }
282
+ const response = yield AnalyticsEventsAPI_1.analyticsEventsAPI.sendEvent(eventData);
283
+ if (!response.success) {
284
+ console.warn('[AnalyticsEvents] Backend error:', response.message);
285
+ }
286
+ }
287
+ catch (error) {
288
+ console.error('[AnalyticsEvents] Failed to send event:', error);
289
+ }
290
+ });
291
+ }
292
+ loadSession() {
293
+ if (typeof localStorage === 'undefined')
294
+ return null;
295
+ const hotelId = this.config.hotelId;
296
+ if (!hotelId)
297
+ return null;
298
+ try {
299
+ const stored = localStorage.getItem(getStorageKey(hotelId));
300
+ if (stored) {
301
+ const session = JSON.parse(stored);
302
+ if (isValidSession(session) && Date.now() - session.createdAt < SESSION_MAX_AGE) {
303
+ return session;
304
+ }
305
+ }
306
+ }
307
+ catch (e) {
308
+ this.log('Failed to load session:', e);
309
+ }
310
+ return null;
311
+ }
312
+ saveSession() {
313
+ if (typeof localStorage === 'undefined' || !this.session)
314
+ return;
315
+ try {
316
+ localStorage.setItem(getStorageKey(this.session.hotelFrontendId), JSON.stringify(this.session));
317
+ }
318
+ catch (e) {
319
+ this.log('Failed to save session:', e);
320
+ }
321
+ }
322
+ log(...args) {
323
+ if (this.config.debug) {
324
+ console.log('[AnalyticsEvents]', ...args);
325
+ }
326
+ }
327
+ }
328
+ exports.default = new AnalyticsEvents();
329
+ //# sourceMappingURL=AnalyticsEvents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnalyticsEvents.js","sourceRoot":"/","sources":["src/util/AnalyticsEvents/AnalyticsEvents.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Analytics Events Utility\n */\n\nimport {\n ERoomstayEventName,\n IAnalyticsEventRequest,\n IMetaEventData,\n IRoomstayBasketAddEventData,\n IRoomstayBookingCommittedEventData,\n IRoomstayCheckoutViewEventData,\n IRoomstayEventData,\n ReservationsDTO,\n transformToMetaEventData,\n} from '@roomstay/core';\n\nimport { analyticsEventsAPI } from '@/api/AnalyticsEventsAPI';\nimport { AddToCartEvent } from '@/events/actions/AddToCartEvent';\nimport RoomstayEventManager from '@/events/RoomstayEventManager';\nimport { CommittedBookingEvent } from '@/events/views/CommittedBookingEvent';\nimport { StepCheckoutViewEvent } from '@/events/views/StepCheckoutViewEvent';\nimport BasketRow from '@/models/BasketRow';\n\nimport { calculateTotalValue, extractGuestData, getMetaCookies, serializeBasketRow, serializeBasketRows } from './helpers';\n\n/**\n * Configuration for AnalyticsEvents\n */\nexport interface AnalyticsEventsConfig {\n hotelId?: string;\n currency?: string;\n firePixelEvents?: boolean;\n debug?: boolean;\n}\n\n/**\n * Analytics session data\n */\ninterface AnalyticsSession {\n sessionId: string;\n fbc?: string;\n fbp?: string;\n createdAt: number;\n hotelFrontendId: string;\n currency: string;\n externalId?: string;\n}\n\n/**\n * Validate session from storage\n */\nfunction isValidSession(obj: unknown): obj is AnalyticsSession {\n if (!obj || typeof obj !== 'object') return false;\n const session = obj as Record<string, unknown>;\n return typeof session.sessionId === 'string' && typeof session.createdAt === 'number' && typeof session.hotelId === 'string' && typeof session.currency === 'string';\n}\n\nconst STORAGE_KEY_PREFIX = 'roomstay-analytics-session';\nconst SESSION_MAX_AGE = 12 * 60 * 60 * 1000; // 12 hours\n\n/**\n * Get storage key for a specific hotel's session\n */\nfunction getStorageKey(hotelId: string): string {\n return `${STORAGE_KEY_PREFIX}-${hotelId}`;\n}\n\nfunction generateUUID(): string {\n return crypto.randomUUID();\n}\n\n/**\n * Fire a Meta Pixel event with Event ID for deduplication\n */\nfunction firePixelEvent(eventName: string, eventId: string, customData?: IMetaEventData): void {\n const metaPixelIsAvailable = typeof window !== 'undefined' && typeof (window as any).fbq === 'function';\n if (!metaPixelIsAvailable) return;\n\n try {\n (window as any).fbq('track', eventName, customData, { eventID: eventId });\n } catch (error) {\n console.error('[AnalyticsEvents] Error firing pixel event:', error);\n }\n}\n\nclass AnalyticsEvents {\n private session: AnalyticsSession | null = null;\n private config: AnalyticsEventsConfig = {};\n private initialized = false;\n private listenersRegistered = false;\n private sessionReady: Promise<boolean> | null = null;\n\n /**\n * Initialize analytics with configuration\n */\n public initialize(config?: AnalyticsEventsConfig): void {\n if (this.initialized) {\n return;\n }\n\n this.config = config || {};\n\n // Try to restore existing session\n const existingSession = this.loadSession();\n const cookies = getMetaCookies();\n\n // Resolve hotelId and currency from config or existing session\n const hotelFrontendId = this.config.hotelId ?? existingSession?.hotelFrontendId;\n const currency = this.config.currency ?? existingSession?.currency;\n\n // Cannot initialize without required fields\n if (!hotelFrontendId || !currency) {\n this.log('Cannot initialize: hotelId and currency are required');\n return;\n }\n\n if (existingSession) {\n this.session = {\n ...existingSession,\n fbc: cookies.fbc ?? existingSession.fbc,\n fbp: cookies.fbp ?? existingSession.fbp,\n hotelFrontendId,\n currency,\n };\n this.sessionReady = Promise.resolve(true);\n this.log('Session restored:', this.session.sessionId);\n } else {\n this.session = {\n sessionId: generateUUID(),\n fbc: cookies.fbc,\n fbp: cookies.fbp,\n createdAt: Date.now(),\n hotelFrontendId,\n currency,\n };\n\n this.sessionReady = this.createServerSession();\n }\n\n this.saveSession();\n this.initialized = true;\n this.registerEventListeners();\n\n this.log('Session initialized:', this.session.sessionId);\n }\n\n /**\n * Create session on the server\n */\n private async createServerSession(): Promise<boolean> {\n if (!this.session) return false;\n\n try {\n const response = await analyticsEventsAPI.createSession({\n sessionId: this.session.sessionId,\n hotelFrontendId: this.session.hotelFrontendId,\n fbc: this.session.fbc,\n fbp: this.session.fbp,\n });\n\n if (!response.success) {\n console.warn('[AnalyticsEvents] Failed to create server session:', response.message);\n return false;\n }\n\n this.log('Server session ready:', this.session.sessionId);\n return true;\n } catch (error) {\n console.error('[AnalyticsEvents] Error creating server session:', error);\n return false;\n }\n }\n\n /**\n * Register listeners for Roomstay events\n */\n private registerEventListeners(): void {\n if (this.listenersRegistered) return;\n\n // View/Checkout event\n RoomstayEventManager.addEvent(\n StepCheckoutViewEvent,\n async (event: StepCheckoutViewEvent) => {\n this.trackInitiateCheckout(event.basketRows);\n },\n 'analytics-events-checkout'\n );\n\n // Basket/Add event\n RoomstayEventManager.addEvent(\n AddToCartEvent,\n async (event: AddToCartEvent) => {\n this.trackAddToCart(event.basketRow);\n },\n 'analytics-events-add-to-cart'\n );\n\n // Booking/Committed event\n RoomstayEventManager.addEvent(\n CommittedBookingEvent,\n async (event: CommittedBookingEvent) => {\n this.trackPurchase(event.reservation, event.basketRows);\n },\n 'analytics-events-purchase'\n );\n\n this.listenersRegistered = true;\n this.log('Event listeners registered');\n }\n\n /**\n * Track View/Checkout event\n */\n public trackInitiateCheckout(basketRows: BasketRow[]): void {\n const session = this.getValidatedSession();\n if (!session) return;\n\n const { currency } = session;\n const items = serializeBasketRows(basketRows);\n\n // Build event data in Roomstay format\n const eventData: IRoomstayCheckoutViewEventData = {\n items,\n currency,\n totalValue: calculateTotalValue(items),\n };\n\n const payload = this.createEventPayload(ERoomstayEventName.ViewCheckout, eventData);\n\n // Fire Meta Pixel with transformed data\n if (this.config.firePixelEvents) {\n const metaEventData = transformToMetaEventData(eventData);\n firePixelEvent('InitiateCheckout', payload.eventId, metaEventData);\n }\n\n this.sendEvent(payload);\n this.log('View/Checkout tracked:', payload);\n }\n\n /**\n * Track Basket/Add event\n */\n public trackAddToCart(basketRow: BasketRow): void {\n const session = this.getValidatedSession();\n if (!session) return;\n\n const { currency } = session;\n\n // Build event data in Roomstay format\n const eventData: IRoomstayBasketAddEventData = {\n item: serializeBasketRow(basketRow),\n currency,\n };\n\n const payload = this.createEventPayload(ERoomstayEventName.BasketAdd, eventData);\n\n // Fire Meta Pixel with transformed data\n if (this.config.firePixelEvents) {\n const metaEventData = transformToMetaEventData(eventData);\n firePixelEvent('AddToCart', payload.eventId, metaEventData);\n }\n\n this.sendEvent(payload);\n this.log('Basket/Add tracked:', payload);\n }\n\n /**\n * Track Booking/Committed event\n */\n public trackPurchase(reservation: ReservationsDTO, basketRows: BasketRow[]): void {\n const session = this.getValidatedSession();\n if (!session) return;\n\n const { currency } = session;\n const items = serializeBasketRows(basketRows);\n\n // Build event data in Roomstay format with embedded guest data\n const eventData: IRoomstayBookingCommittedEventData = {\n items,\n currency,\n totalValue: calculateTotalValue(items),\n roomstayId: reservation.roomstayId,\n itineraryNumber: reservation.itineraryNumber,\n reservationNumbers: reservation.reservations.map((r) => r.reservationNumber),\n guest: {\n ...extractGuestData(reservation),\n externalId: session.externalId,\n },\n };\n\n const payload = this.createEventPayload(ERoomstayEventName.BookingCommitted, eventData);\n\n // Fire Meta Pixel with transformed data\n if (this.config.firePixelEvents) {\n const metaEventData = transformToMetaEventData(eventData);\n firePixelEvent('Purchase', payload.eventId, metaEventData);\n }\n\n this.sendEvent(payload);\n this.log('Booking/Committed tracked:', payload);\n }\n\n /**\n * Set external user ID (e.g. member portal ID)\n */\n public setExternalId(externalId: string): void {\n if (this.session) {\n this.log('Setting external ID:', externalId);\n this.session.externalId = externalId;\n this.saveSession();\n }\n }\n\n /**\n * Ensure session is initialized and has required fields for tracking.\n * Returns the session if tracking can proceed, null otherwise.\n */\n private getValidatedSession(): AnalyticsSession | null {\n if (!this.initialized) {\n this.initialize(this.config);\n }\n\n if (!this.session) {\n console.warn('[AnalyticsEvents] Cannot track: session not initialized');\n return null;\n }\n\n return this.session;\n }\n\n private createEventPayload(eventName: ERoomstayEventName, eventData: IRoomstayEventData): IAnalyticsEventRequest {\n const session = this.session;\n return {\n eventId: generateUUID(),\n sessionId: session?.sessionId ?? '',\n eventName,\n eventTime: Math.floor(Date.now() / 1000),\n hotelFrontendId: session?.hotelFrontendId ?? '',\n fbc: session?.fbc || undefined,\n fbp: session?.fbp || undefined,\n eventData,\n };\n }\n\n private async sendEvent(eventData: IAnalyticsEventRequest): Promise<void> {\n try {\n // Wait for session to be created on server before sending events\n if (!this.sessionReady) {\n console.warn('[AnalyticsEvents] Skipping event - sessionReady not initialized');\n return;\n }\n\n const sessionCreated = await this.sessionReady;\n if (!sessionCreated) {\n console.warn('[AnalyticsEvents] Skipping event - session not created on server');\n return;\n }\n\n const response = await analyticsEventsAPI.sendEvent(eventData);\n if (!response.success) {\n console.warn('[AnalyticsEvents] Backend error:', response.message);\n }\n } catch (error) {\n console.error('[AnalyticsEvents] Failed to send event:', error);\n }\n }\n\n private loadSession(): AnalyticsSession | null {\n if (typeof localStorage === 'undefined') return null;\n\n const hotelId = this.config.hotelId;\n if (!hotelId) return null;\n\n try {\n const stored = localStorage.getItem(getStorageKey(hotelId));\n if (stored) {\n const session: unknown = JSON.parse(stored);\n if (isValidSession(session) && Date.now() - session.createdAt < SESSION_MAX_AGE) {\n return session;\n }\n }\n } catch (e) {\n this.log('Failed to load session:', e);\n }\n\n return null;\n }\n\n private saveSession(): void {\n if (typeof localStorage === 'undefined' || !this.session) return;\n try {\n localStorage.setItem(getStorageKey(this.session.hotelFrontendId), JSON.stringify(this.session));\n } catch (e) {\n this.log('Failed to save session:', e);\n }\n }\n\n private log(...args: any[]): void {\n if (this.config.debug) {\n console.log('[AnalyticsEvents]', ...args);\n }\n }\n}\n\nexport default new AnalyticsEvents();\n"]}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Analytics Events Helpers
3
+ */
4
+ import { IRoomstayBasketItem, IRoomstayGuestData, ReservationsDTO } from '@roomstay/core';
5
+ import BasketRow from '../../models/BasketRow';
6
+ /**
7
+ * Get Meta cookies for tracking
8
+ * - fbc (_fbc): Click ID - tracks users who clicked on a Facebook ad
9
+ * - fbp (_fbp): Browser ID - unique identifier for the browser
10
+ */
11
+ export declare function getMetaCookies(): {
12
+ fbc?: string;
13
+ fbp?: string;
14
+ };
15
+ /**
16
+ * Serialize a BasketRow to IRoomstayBasketItem for analytics events.
17
+ */
18
+ export declare function serializeBasketRow(basketRow: BasketRow): IRoomstayBasketItem;
19
+ /**
20
+ * Serialize multiple BasketRows
21
+ */
22
+ export declare function serializeBasketRows(basketRows: BasketRow[]): IRoomstayBasketItem[];
23
+ /**
24
+ * Extract guest data from a ReservationsDTO
25
+ */
26
+ export declare function extractGuestData(reservation: ReservationsDTO): IRoomstayGuestData;
27
+ /**
28
+ * Calculate total value from basket items
29
+ */
30
+ export declare function calculateTotalValue(items: IRoomstayBasketItem[]): number;
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ /**
3
+ * Analytics Events Helpers
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getMetaCookies = getMetaCookies;
7
+ exports.serializeBasketRow = serializeBasketRow;
8
+ exports.serializeBasketRows = serializeBasketRows;
9
+ exports.extractGuestData = extractGuestData;
10
+ exports.calculateTotalValue = calculateTotalValue;
11
+ /**
12
+ * Get a cookie value by name
13
+ */
14
+ function getCookie(name) {
15
+ if (typeof document === 'undefined') {
16
+ return undefined;
17
+ }
18
+ const cookies = document.cookie.split(';');
19
+ for (const cookie of cookies) {
20
+ const [cookieName, cookieValue] = cookie.trim().split('=');
21
+ if (cookieName === name) {
22
+ return decodeURIComponent(cookieValue);
23
+ }
24
+ }
25
+ return undefined;
26
+ }
27
+ /**
28
+ * Get Meta cookies for tracking
29
+ * - fbc (_fbc): Click ID - tracks users who clicked on a Facebook ad
30
+ * - fbp (_fbp): Browser ID - unique identifier for the browser
31
+ */
32
+ function getMetaCookies() {
33
+ return {
34
+ fbc: getCookie('_fbc'),
35
+ fbp: getCookie('_fbp'),
36
+ };
37
+ }
38
+ /**
39
+ * Serialize a BasketRow to IRoomstayBasketItem for analytics events.
40
+ */
41
+ function serializeBasketRow(basketRow) {
42
+ const room = basketRow.getRoom();
43
+ const rate = basketRow.getRate();
44
+ const startDate = basketRow.getStartDate();
45
+ const endDate = basketRow.getEndDate();
46
+ return {
47
+ roomCode: (room === null || room === void 0 ? void 0 : room.code) || '',
48
+ roomId: room === null || room === void 0 ? void 0 : room.id,
49
+ roomName: room === null || room === void 0 ? void 0 : room.name,
50
+ rateCode: (rate === null || rate === void 0 ? void 0 : rate.code) || '',
51
+ rateName: rate === null || rate === void 0 ? void 0 : rate.name,
52
+ startDate: (startDate === null || startDate === void 0 ? void 0 : startDate.format('YYYY-MM-DD')) || '',
53
+ endDate: (endDate === null || endDate === void 0 ? void 0 : endDate.format('YYYY-MM-DD')) || '',
54
+ numberOfNights: basketRow.getNumberOfDays(),
55
+ adults: basketRow.getAdults(),
56
+ children: basketRow.getChildren(),
57
+ infants: basketRow.getInfants(),
58
+ totalPrice: basketRow.getTotalPrice() || 0,
59
+ averageNightlyRate: (rate === null || rate === void 0 ? void 0 : rate.getAveragePrice()) || 0,
60
+ promoCode: basketRow.getPromoCode() || undefined,
61
+ };
62
+ }
63
+ /**
64
+ * Serialize multiple BasketRows
65
+ */
66
+ function serializeBasketRows(basketRows) {
67
+ return basketRows.map(serializeBasketRow);
68
+ }
69
+ /**
70
+ * Extract guest data from a ReservationsDTO
71
+ */
72
+ function extractGuestData(reservation) {
73
+ var _a, _b, _c, _d, _e;
74
+ const firstReservation = (_a = reservation.reservations) === null || _a === void 0 ? void 0 : _a[0];
75
+ const guest = firstReservation === null || firstReservation === void 0 ? void 0 : firstReservation.guest;
76
+ if (!guest) {
77
+ return {};
78
+ }
79
+ return {
80
+ email: guest.email,
81
+ phone: guest.phone,
82
+ firstName: guest.firstName,
83
+ lastName: guest.lastName,
84
+ city: (_b = guest.address) === null || _b === void 0 ? void 0 : _b.city,
85
+ state: (_c = guest.address) === null || _c === void 0 ? void 0 : _c.state,
86
+ postalCode: (_d = guest.address) === null || _d === void 0 ? void 0 : _d.postalCode,
87
+ country: (_e = guest.address) === null || _e === void 0 ? void 0 : _e.country,
88
+ };
89
+ }
90
+ /**
91
+ * Calculate total value from basket items
92
+ */
93
+ function calculateTotalValue(items) {
94
+ return items.reduce((sum, item) => sum + item.totalPrice, 0);
95
+ }
96
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"/","sources":["src/util/AnalyticsEvents/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Analytics Events Helpers\n */\n\nimport { IRoomstayBasketItem, IRoomstayGuestData, ReservationsDTO } from '@roomstay/core';\n\nimport BasketRow from '@/models/BasketRow';\n\n/**\n * Get a cookie value by name\n */\nfunction getCookie(name: string): string | undefined {\n if (typeof document === 'undefined') {\n return undefined;\n }\n\n const cookies = document.cookie.split(';');\n for (const cookie of cookies) {\n const [cookieName, cookieValue] = cookie.trim().split('=');\n if (cookieName === name) {\n return decodeURIComponent(cookieValue);\n }\n }\n return undefined;\n}\n\n/**\n * Get Meta cookies for tracking\n * - fbc (_fbc): Click ID - tracks users who clicked on a Facebook ad\n * - fbp (_fbp): Browser ID - unique identifier for the browser\n */\nexport function getMetaCookies(): { fbc?: string; fbp?: string } {\n return {\n fbc: getCookie('_fbc'),\n fbp: getCookie('_fbp'),\n };\n}\n\n/**\n * Serialize a BasketRow to IRoomstayBasketItem for analytics events.\n */\nexport function serializeBasketRow(basketRow: BasketRow): IRoomstayBasketItem {\n const room = basketRow.getRoom();\n const rate = basketRow.getRate();\n const startDate = basketRow.getStartDate();\n const endDate = basketRow.getEndDate();\n\n return {\n roomCode: room?.code || '',\n roomId: room?.id,\n roomName: room?.name,\n\n rateCode: rate?.code || '',\n rateName: rate?.name,\n\n startDate: startDate?.format('YYYY-MM-DD') || '',\n endDate: endDate?.format('YYYY-MM-DD') || '',\n numberOfNights: basketRow.getNumberOfDays(),\n\n adults: basketRow.getAdults(),\n children: basketRow.getChildren(),\n infants: basketRow.getInfants(),\n\n totalPrice: basketRow.getTotalPrice() || 0,\n averageNightlyRate: rate?.getAveragePrice() || 0,\n\n promoCode: basketRow.getPromoCode() || undefined,\n };\n}\n\n/**\n * Serialize multiple BasketRows\n */\nexport function serializeBasketRows(basketRows: BasketRow[]): IRoomstayBasketItem[] {\n return basketRows.map(serializeBasketRow);\n}\n\n/**\n * Extract guest data from a ReservationsDTO\n */\nexport function extractGuestData(reservation: ReservationsDTO): IRoomstayGuestData {\n const firstReservation = reservation.reservations?.[0];\n const guest = firstReservation?.guest;\n\n if (!guest) {\n return {};\n }\n\n return {\n email: guest.email,\n phone: guest.phone,\n firstName: guest.firstName,\n lastName: guest.lastName,\n city: guest.address?.city,\n state: guest.address?.state,\n postalCode: guest.address?.postalCode,\n country: guest.address?.country,\n };\n}\n\n/**\n * Calculate total value from basket items\n */\nexport function calculateTotalValue(items: IRoomstayBasketItem[]): number {\n return items.reduce((sum, item) => sum + item.totalPrice, 0);\n}\n"]}
@@ -96,9 +96,9 @@ class DataLayer {
96
96
  sendAwayWindowOpen() {
97
97
  this.log('away window triggered');
98
98
  react_gtm_module_1.default.dataLayer({
99
- dataLayer: {
99
+ dataLayer: analytics.withClientDetailsData({
100
100
  event: 'awayWindow',
101
- },
101
+ }),
102
102
  });
103
103
  }
104
104
  sendRoomRateAddToCart(rate, quantity, startDate, endDate, originalRoomRate) {
@@ -206,9 +206,9 @@ class DataLayer {
206
206
  }
207
207
  sendMemberSignUp() {
208
208
  react_gtm_module_1.default.dataLayer({
209
- dataLayer: {
209
+ dataLayer: analytics.withClientDetailsData({
210
210
  event: 'Email Sign up',
211
- },
211
+ }),
212
212
  });
213
213
  }
214
214
  sendMemberSignedIn() {
@@ -1 +1 @@
1
- {"version":3,"file":"DataLayer.js","sourceRoot":"/","sources":["src/util/DataLayer.ts"],"names":[],"mappings":"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","sourcesContent":["import { ReservationDTO, ReservationsDTO } from '@roomstay/core';\nimport { Dayjs } from 'dayjs';\nimport TagManager from 'react-gtm-module';\n\nimport BasketAddonRow from '@/models/BasketAddonRow';\nimport BasketRow from '@/models/BasketRow';\nimport { ConfigCompany } from '@/models/Client/Hotel/Company';\nimport { Room } from '@/models/Room/Room';\nimport { RoomRate } from '@/models/Room/RoomRate';\n\nimport { Hotel } from '..';\nimport { Analytics } from './Analytics/Analytics';\nimport { UniversalAnalytics } from './Analytics/UniversalAnalytics';\n\nconst DATALAYER_DATE_FORMAT = 'YYYY-M-D';\n\nexport enum DatalayerAnalyticsMode {\n UniversalAnaltics = 'UniversalAnalytics',\n GoogleAnalytics4 = 'GoogleAnalytics4',\n}\n\nexport type GenericAnalyticsAccommodation = {\n room: Room;\n dateRange: { from: Dayjs; to: Dayjs };\n\n rate?: RoomRate;\n quantity?: number;\n promoCode?: string;\n /**\n * What the original room rate was before the upsell\n */\n originalRoomRate?: RoomRate;\n basketAddonRow?: BasketAddonRow;\n};\n\nlet analytics: Analytics = UniversalAnalytics;\n\nexport interface DateRange {\n from: Dayjs;\n to: Dayjs;\n}\n\nexport default class DataLayer {\n static instance = new DataLayer();\n\n private enableLogging = true;\n\n private originalCurrencyCode?: string;\n private currentCurrencyCode = '';\n\n private impressions: GenericAnalyticsAccommodation[] = [];\n\n private hotel?: Hotel;\n private company?: ConfigCompany;\n\n public initialiseGTM(company: ConfigCompany, hotel?: Hotel) {\n let datalayer;\n if (hotel?.datalayer?.gtmIds?.length) {\n datalayer = hotel.datalayer;\n } else if (company) {\n datalayer = company.datalayer;\n }\n const gtmIds = datalayer?.gtmIds ?? [];\n const itemListName = datalayer?.itemListName || 'BE List';\n\n gtmIds.forEach((gtmId) => {\n TagManager.initialize({ gtmId });\n });\n\n this.hotel = hotel;\n this.company = company;\n\n // We set the analytics mode as it will also initilaise it.\n analytics.initialise(this.company, this.hotel);\n analytics.setItemListName(itemListName);\n }\n\n // Use for testing change analytics type only\n public setAnalyticsMode(mode: Analytics) {\n analytics = mode;\n analytics.initialise(this.company, this.hotel);\n }\n\n public setItemListName(itemListName?: string) {\n analytics.setItemListName(itemListName);\n }\n\n public setCurrencyCodes(currentCurrencyCode: string, originalCurrencyCode?: string) {\n this.currentCurrencyCode = currentCurrencyCode;\n\n if (originalCurrencyCode) {\n this.originalCurrencyCode = originalCurrencyCode;\n }\n\n if (analytics) {\n analytics.updateCurrency(this.currentCurrencyCode, this.originalCurrencyCode ?? '');\n }\n }\n\n public setUserId = (id?: string): this => {\n analytics.setUserId(id);\n return this;\n };\n\n addRoomImpression(room: Room, dateRange: DateRange, promoCode: string) {\n this.impressions.push({\n room: room,\n promoCode,\n dateRange,\n });\n }\n\n addRoomRateImpression(room: Room, rate: RoomRate, dateRange: DateRange, promoCode: string) {\n this.impressions.push({\n room: room,\n rate: rate,\n promoCode,\n dateRange,\n });\n }\n\n sendRoomImpressions() {\n this.log('sending ' + this.impressions.length + ' impressions');\n\n if (this.impressions.length > 0) {\n const eventObject = analytics.withUserData(analytics.generateRoomImpressionMessageObject(this.impressions));\n\n TagManager.dataLayer({\n dataLayer: eventObject,\n });\n\n this.impressions = [];\n }\n }\n\n sendRoomClick(room: Room, startDate: Dayjs, endDate: Dayjs, promoCode?: string) {\n const eventObject = analytics.withUserData(analytics.generateProductClickMessageObject({ room, dateRange: { from: startDate, to: endDate }, promoCode }));\n this.log('sending room click', eventObject);\n\n TagManager.dataLayer({\n dataLayer: eventObject,\n });\n }\n\n sendAwayWindowOpen() {\n this.log('away window triggered');\n\n TagManager.dataLayer({\n dataLayer: {\n event: 'awayWindow',\n },\n });\n }\n\n sendRoomRateAddToCart(rate: RoomRate, quantity: number, startDate: Dayjs, endDate: Dayjs, originalRoomRate?: RoomRate) {\n this.log('sending room rate add to cart');\n\n TagManager.dataLayer({\n dataLayer: analytics.withUserData(\n analytics.generateAddToCartMessageObject({\n room: rate.getRoom(),\n rate,\n dateRange: { from: startDate, to: endDate },\n quantity,\n promoCode: rate.promoCode,\n originalRoomRate,\n })\n ),\n });\n }\n\n sendRoomAddonAddToCart(basketAddonRow: BasketAddonRow, quantity: number, startDate: Dayjs, endDate: Dayjs) {\n this.log('sending room addons add to cart');\n\n TagManager.dataLayer({\n dataLayer: analytics.withUserData(\n analytics.generateAddonsAddToCartMessageObject({\n dateRange: { from: startDate, to: endDate },\n basketAddonRow,\n quantity,\n })\n ),\n });\n }\n\n sendUpsellConfirmed(dateRange: DateRange, oldRate: RoomRate, newRate: RoomRate) {\n this.log('sending room upgrade notification');\n\n const event = analytics.generateUpsellConfirmedMessageObject(\n { dateRange, room: oldRate.getRoom(), rate: oldRate, promoCode: oldRate.promoCode },\n { dateRange, room: newRate.getRoom(), rate: newRate, promoCode: newRate.promoCode }\n );\n\n if (!event) {\n console.error('Failed sending upsell confirmation event');\n return;\n }\n\n TagManager.dataLayer({\n dataLayer: analytics.withUserData(event),\n });\n }\n\n sendUpsellCancelled(dateRange: DateRange, rate: RoomRate) {\n this.log('sending room upgrade cancellation event');\n\n const event = analytics.withUserData(analytics.generateUpsellCancelledMessageObject({ dateRange, room: rate.getRoom(), rate, promoCode: rate.promoCode }));\n\n TagManager.dataLayer({\n dataLayer: event,\n });\n }\n\n sendRoomView(startDate: Dayjs, endDate: Dayjs) {\n this.log('sending room view');\n\n TagManager.dataLayer({\n dataLayer: analytics.withUserData({\n event: 'room',\n ecommerce: {\n currencyCode: this.originalCurrencyCode,\n StartDate: startDate?.format(DATALAYER_DATE_FORMAT),\n EndDate: endDate?.format(DATALAYER_DATE_FORMAT),\n PageType: 'offerdetail',\n },\n }),\n });\n }\n\n sendCheckoutView(basketRows: BasketRow[], addonRows: BasketAddonRow[]) {\n this.log('sending checkout view');\n\n const event = analytics.withUserData(analytics.generateCheckoutViewMessageObject(basketRows, addonRows));\n\n TagManager.dataLayer({\n dataLayer: event,\n });\n }\n\n sendReservationConfirmed(basketRows: BasketRow[], addonRows: BasketAddonRow[], reservations: ReservationsDTO) {\n const event = analytics.generateRoomPurchaseMessageObject(basketRows, addonRows, reservations);\n\n for (const element of event) {\n this.log('sending reservation confirmation', element);\n\n TagManager.dataLayer({\n dataLayer: analytics.withUserData(element),\n });\n }\n }\n\n sendCancellation(reservation: ReservationDTO) {\n this.log('sending cancellation for reservation ' + reservation);\n\n TagManager.dataLayer({\n dataLayer: analytics.withUserData(analytics.generateRefundMessageObject(reservation)),\n });\n }\n\n sendCancellationByReservationNumber(reservationNumber: string) {\n this.log('sending cancellation for reservation number ' + reservationNumber);\n\n TagManager.dataLayer({\n dataLayer: analytics.withUserData(analytics.generateRefundMessageObjectByReservationNumber(reservationNumber)),\n });\n }\n\n sendInteraction(name: string, type: InteractionType, step: InteractionStep) {\n const interaction = {\n 'Interaction Name': name,\n 'Interaction Type': type,\n 'Interaction Step': step,\n };\n\n this.log('sending interaction', interaction);\n\n TagManager.dataLayer({\n dataLayer: interaction,\n });\n }\n\n sendDateSelection({ startDate, endDate, adult, children, infant }: { startDate: Dayjs; endDate: Dayjs; adult?: number; children?: number; infant?: number }) {\n if (!startDate || !endDate) {\n return;\n }\n\n this.log('sending date selection ', startDate, endDate);\n\n TagManager.dataLayer({\n dataLayer: analytics.withUserData(analytics.generateDateSelectionMessageObject({ from: startDate, to: endDate }, adult || 0, children || 0, infant || 0)),\n });\n }\n\n sendMemberSignUp() {\n TagManager.dataLayer({\n dataLayer: {\n event: 'Email Sign up',\n },\n });\n }\n sendMemberSignedIn() {\n TagManager.dataLayer({\n dataLayer: analytics.withUserData({\n event: 'login',\n }),\n });\n }\n\n protected log(...output: any) {\n if (!this.enableLogging) {\n return;\n }\n\n console.log(\n '[DATALAYER]: ' +\n output\n .map((it: any) => {\n if (typeof it === 'object') {\n return JSON.stringify(it);\n }\n return it;\n })\n .join('; ')\n );\n }\n}\n\nexport enum InteractionType {\n NUMBER_INPUT = '+-widget',\n CALENDAR = 'Calendar',\n BUTTON = 'Button',\n DROPDOWN = 'Dropdown',\n LINK_DROPDOWN = 'Link dropdown',\n LINK = 'Link',\n FORM_FIELD = 'Form field',\n CHECKBOX = 'Checkbox',\n}\n\nexport enum InteractionStep {\n DATES = 'Dates',\n ROOMS = 'Rooms',\n GUEST_DETAILS = 'Guest Details',\n}\n"]}
1
+ {"version":3,"file":"DataLayer.js","sourceRoot":"/","sources":["src/util/DataLayer.ts"],"names":[],"mappings":"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","sourcesContent":["import { ReservationDTO, ReservationsDTO } from '@roomstay/core';\nimport { Dayjs } from 'dayjs';\nimport TagManager from 'react-gtm-module';\n\nimport BasketAddonRow from '@/models/BasketAddonRow';\nimport BasketRow from '@/models/BasketRow';\nimport { ConfigCompany } from '@/models/Client/Hotel/Company';\nimport { Room } from '@/models/Room/Room';\nimport { RoomRate } from '@/models/Room/RoomRate';\n\nimport { Hotel } from '..';\nimport { Analytics } from './Analytics/Analytics';\nimport { UniversalAnalytics } from './Analytics/UniversalAnalytics';\n\nconst DATALAYER_DATE_FORMAT = 'YYYY-M-D';\n\nexport enum DatalayerAnalyticsMode {\n UniversalAnaltics = 'UniversalAnalytics',\n GoogleAnalytics4 = 'GoogleAnalytics4',\n}\n\nexport type GenericAnalyticsAccommodation = {\n room: Room;\n dateRange: { from: Dayjs; to: Dayjs };\n\n rate?: RoomRate;\n quantity?: number;\n promoCode?: string;\n /**\n * What the original room rate was before the upsell\n */\n originalRoomRate?: RoomRate;\n basketAddonRow?: BasketAddonRow;\n};\n\nlet analytics: Analytics = UniversalAnalytics;\n\nexport interface DateRange {\n from: Dayjs;\n to: Dayjs;\n}\n\nexport default class DataLayer {\n static instance = new DataLayer();\n\n private enableLogging = true;\n\n private originalCurrencyCode?: string;\n private currentCurrencyCode = '';\n\n private impressions: GenericAnalyticsAccommodation[] = [];\n\n private hotel?: Hotel;\n private company?: ConfigCompany;\n\n public initialiseGTM(company: ConfigCompany, hotel?: Hotel) {\n let datalayer;\n if (hotel?.datalayer?.gtmIds?.length) {\n datalayer = hotel.datalayer;\n } else if (company) {\n datalayer = company.datalayer;\n }\n const gtmIds = datalayer?.gtmIds ?? [];\n const itemListName = datalayer?.itemListName || 'BE List';\n\n gtmIds.forEach((gtmId) => {\n TagManager.initialize({ gtmId });\n });\n\n this.hotel = hotel;\n this.company = company;\n\n // We set the analytics mode as it will also initilaise it.\n analytics.initialise(this.company, this.hotel);\n analytics.setItemListName(itemListName);\n }\n\n // Use for testing change analytics type only\n public setAnalyticsMode(mode: Analytics) {\n analytics = mode;\n analytics.initialise(this.company, this.hotel);\n }\n\n public setItemListName(itemListName?: string) {\n analytics.setItemListName(itemListName);\n }\n\n public setCurrencyCodes(currentCurrencyCode: string, originalCurrencyCode?: string) {\n this.currentCurrencyCode = currentCurrencyCode;\n\n if (originalCurrencyCode) {\n this.originalCurrencyCode = originalCurrencyCode;\n }\n\n if (analytics) {\n analytics.updateCurrency(this.currentCurrencyCode, this.originalCurrencyCode ?? '');\n }\n }\n\n public setUserId = (id?: string): this => {\n analytics.setUserId(id);\n return this;\n };\n\n addRoomImpression(room: Room, dateRange: DateRange, promoCode: string) {\n this.impressions.push({\n room: room,\n promoCode,\n dateRange,\n });\n }\n\n addRoomRateImpression(room: Room, rate: RoomRate, dateRange: DateRange, promoCode: string) {\n this.impressions.push({\n room: room,\n rate: rate,\n promoCode,\n dateRange,\n });\n }\n\n sendRoomImpressions() {\n this.log('sending ' + this.impressions.length + ' impressions');\n\n if (this.impressions.length > 0) {\n const eventObject = analytics.withUserData(analytics.generateRoomImpressionMessageObject(this.impressions));\n\n TagManager.dataLayer({\n dataLayer: eventObject,\n });\n\n this.impressions = [];\n }\n }\n\n sendRoomClick(room: Room, startDate: Dayjs, endDate: Dayjs, promoCode?: string) {\n const eventObject = analytics.withUserData(analytics.generateProductClickMessageObject({ room, dateRange: { from: startDate, to: endDate }, promoCode }));\n this.log('sending room click', eventObject);\n\n TagManager.dataLayer({\n dataLayer: eventObject,\n });\n }\n\n sendAwayWindowOpen() {\n this.log('away window triggered');\n\n TagManager.dataLayer({\n dataLayer: analytics.withClientDetailsData({\n event: 'awayWindow',\n }),\n });\n }\n\n sendRoomRateAddToCart(rate: RoomRate, quantity: number, startDate: Dayjs, endDate: Dayjs, originalRoomRate?: RoomRate) {\n this.log('sending room rate add to cart');\n\n TagManager.dataLayer({\n dataLayer: analytics.withUserData(\n analytics.generateAddToCartMessageObject({\n room: rate.getRoom(),\n rate,\n dateRange: { from: startDate, to: endDate },\n quantity,\n promoCode: rate.promoCode,\n originalRoomRate,\n })\n ),\n });\n }\n\n sendRoomAddonAddToCart(basketAddonRow: BasketAddonRow, quantity: number, startDate: Dayjs, endDate: Dayjs) {\n this.log('sending room addons add to cart');\n\n TagManager.dataLayer({\n dataLayer: analytics.withUserData(\n analytics.generateAddonsAddToCartMessageObject({\n dateRange: { from: startDate, to: endDate },\n basketAddonRow,\n quantity,\n })\n ),\n });\n }\n\n sendUpsellConfirmed(dateRange: DateRange, oldRate: RoomRate, newRate: RoomRate) {\n this.log('sending room upgrade notification');\n\n const event = analytics.generateUpsellConfirmedMessageObject(\n { dateRange, room: oldRate.getRoom(), rate: oldRate, promoCode: oldRate.promoCode },\n { dateRange, room: newRate.getRoom(), rate: newRate, promoCode: newRate.promoCode }\n );\n\n if (!event) {\n console.error('Failed sending upsell confirmation event');\n return;\n }\n\n TagManager.dataLayer({\n dataLayer: analytics.withUserData(event),\n });\n }\n\n sendUpsellCancelled(dateRange: DateRange, rate: RoomRate) {\n this.log('sending room upgrade cancellation event');\n\n const event = analytics.withUserData(analytics.generateUpsellCancelledMessageObject({ dateRange, room: rate.getRoom(), rate, promoCode: rate.promoCode }));\n\n TagManager.dataLayer({\n dataLayer: event,\n });\n }\n\n sendRoomView(startDate: Dayjs, endDate: Dayjs) {\n this.log('sending room view');\n\n TagManager.dataLayer({\n dataLayer: analytics.withUserData({\n event: 'room',\n ecommerce: {\n currencyCode: this.originalCurrencyCode,\n StartDate: startDate?.format(DATALAYER_DATE_FORMAT),\n EndDate: endDate?.format(DATALAYER_DATE_FORMAT),\n PageType: 'offerdetail',\n },\n }),\n });\n }\n\n sendCheckoutView(basketRows: BasketRow[], addonRows: BasketAddonRow[]) {\n this.log('sending checkout view');\n\n const event = analytics.withUserData(analytics.generateCheckoutViewMessageObject(basketRows, addonRows));\n\n TagManager.dataLayer({\n dataLayer: event,\n });\n }\n\n sendReservationConfirmed(basketRows: BasketRow[], addonRows: BasketAddonRow[], reservations: ReservationsDTO) {\n const event = analytics.generateRoomPurchaseMessageObject(basketRows, addonRows, reservations);\n\n for (const element of event) {\n this.log('sending reservation confirmation', element);\n\n TagManager.dataLayer({\n dataLayer: analytics.withUserData(element),\n });\n }\n }\n\n sendCancellation(reservation: ReservationDTO) {\n this.log('sending cancellation for reservation ' + reservation);\n\n TagManager.dataLayer({\n dataLayer: analytics.withUserData(analytics.generateRefundMessageObject(reservation)),\n });\n }\n\n sendCancellationByReservationNumber(reservationNumber: string) {\n this.log('sending cancellation for reservation number ' + reservationNumber);\n\n TagManager.dataLayer({\n dataLayer: analytics.withUserData(analytics.generateRefundMessageObjectByReservationNumber(reservationNumber)),\n });\n }\n\n sendInteraction(name: string, type: InteractionType, step: InteractionStep) {\n const interaction = {\n 'Interaction Name': name,\n 'Interaction Type': type,\n 'Interaction Step': step,\n };\n\n this.log('sending interaction', interaction);\n\n TagManager.dataLayer({\n dataLayer: interaction,\n });\n }\n\n sendDateSelection({ startDate, endDate, adult, children, infant }: { startDate: Dayjs; endDate: Dayjs; adult?: number; children?: number; infant?: number }) {\n if (!startDate || !endDate) {\n return;\n }\n\n this.log('sending date selection ', startDate, endDate);\n\n TagManager.dataLayer({\n dataLayer: analytics.withUserData(analytics.generateDateSelectionMessageObject({ from: startDate, to: endDate }, adult || 0, children || 0, infant || 0)),\n });\n }\n\n sendMemberSignUp() {\n TagManager.dataLayer({\n dataLayer: analytics.withClientDetailsData({\n event: 'Email Sign up',\n }),\n });\n }\n sendMemberSignedIn() {\n TagManager.dataLayer({\n dataLayer: analytics.withUserData({\n event: 'login',\n }),\n });\n }\n\n protected log(...output: any) {\n if (!this.enableLogging) {\n return;\n }\n\n console.log(\n '[DATALAYER]: ' +\n output\n .map((it: any) => {\n if (typeof it === 'object') {\n return JSON.stringify(it);\n }\n return it;\n })\n .join('; ')\n );\n }\n}\n\nexport enum InteractionType {\n NUMBER_INPUT = '+-widget',\n CALENDAR = 'Calendar',\n BUTTON = 'Button',\n DROPDOWN = 'Dropdown',\n LINK_DROPDOWN = 'Link dropdown',\n LINK = 'Link',\n FORM_FIELD = 'Form field',\n CHECKBOX = 'Checkbox',\n}\n\nexport enum InteractionStep {\n DATES = 'Dates',\n ROOMS = 'Rooms',\n GUEST_DETAILS = 'Guest Details',\n}\n"]}