@session-services/web-elements 0.1.28 → 0.1.31
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.
- package/README.md +5 -0
- package/dist/cjs/{index-BYBgrATL.js → index-B2ZmNnji.js} +292 -245
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/session-services-elements.cjs.js +3 -3
- package/dist/cjs/session-services-formatted-text.cjs.entry.js +8 -20
- package/dist/cjs/session-services-ticketing.cjs.entry.js +2188 -23012
- package/dist/collection/collection-manifest.json +4 -3
- package/dist/collection/components/session-services-ticketing/bot-detection.js +83 -0
- package/dist/collection/components/session-services-ticketing/bot-detection.test.js +74 -0
- package/dist/collection/components/session-services-ticketing/session-services-ticketing.css +164 -36
- package/dist/collection/components/session-services-ticketing/session-services-ticketing.js +811 -262
- package/dist/collection/components/session-services-ticketing/session-services-ticketing.logic.js +39 -8
- package/dist/collection/components/session-services-ticketing/session-services-ticketing.logic.test.js +47 -3
- package/dist/collection/components/session-services-ticketing/session-services-ticketing.test.js +611 -20
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.js +1 -1311
- package/dist/components/session-services-formatted-text.js +1 -1802
- package/dist/components/session-services-ticketing.js +1 -25072
- package/dist/esm/{index-CNOpF6tk.js → index-DhbVMqIT.js} +292 -245
- package/dist/esm/loader.js +3 -3
- package/dist/esm/session-services-elements.js +4 -4
- package/dist/esm/session-services-formatted-text.entry.js +8 -20
- package/dist/esm/session-services-ticketing.entry.js +2188 -23012
- package/dist/session-services-elements/{p-703444ed.entry.js → p-8483ca88.entry.js} +1 -1
- package/dist/session-services-elements/p-DhbVMqIT.js +2 -0
- package/dist/session-services-elements/p-d7264f6b.entry.js +1 -0
- package/dist/session-services-elements/session-services-elements.esm.js +1 -1
- package/dist/types/components/session-services-ticketing/bot-detection.d.ts +13 -0
- package/dist/types/components/session-services-ticketing/bot-detection.test.d.ts +1 -0
- package/dist/types/components/session-services-ticketing/session-services-ticketing.d.ts +67 -9
- package/dist/types/components/session-services-ticketing/session-services-ticketing.logic.d.ts +11 -2
- package/dist/types/components.d.ts +36 -8
- package/dist/types/index.d.ts +1 -1
- package/dist/types/stencil-public-runtime.d.ts +67 -5
- package/package.json +15 -11
- package/dist/session-services-elements/p-1acfcdfd.entry.js +0 -1
- package/dist/session-services-elements/p-CNOpF6tk.js +0 -2
|
@@ -1,15 +1,58 @@
|
|
|
1
1
|
import { createClient } from "@session-services/sdk";
|
|
2
|
-
import { buildOrderChannel, createAnalytics,
|
|
3
|
-
import {
|
|
2
|
+
import { buildOrderChannel, createAnalytics, } from "@session-services/sdk/analytics";
|
|
3
|
+
import { fromMinorUnits } from "@session-services/utils/currency";
|
|
4
|
+
import { parseNaiveDateTime } from "@session-services/utils/naive-datetime";
|
|
4
5
|
import { isSectionSoldOut } from "@session-services/utils/ticket-availability";
|
|
5
6
|
import { normalizeCouponCode } from "@session-services/utils/ticket-quote";
|
|
6
7
|
import { Host,
|
|
7
8
|
// biome-ignore lint/correctness/noUnusedImports: h is required by Stencil JSX transform
|
|
8
9
|
h, } from "@stencil/core";
|
|
9
|
-
import {
|
|
10
|
+
import { detectBot, isProductionApi } from "./bot-detection";
|
|
11
|
+
import { admissionPriceSavings, discountCouponFromSearch, eventTimeZone, getAdmissionDisplayState, getAdmissionPriceDisplay, getTicketingState, parseSelectionKey, previewQuoteItems, priceTotal, quoteItemsBySelection, selectionKey, topLevelTicketItems, visibleAdmissions, } from "./session-services-ticketing.logic";
|
|
10
12
|
const quoteTotal = (quote) => quote.price?.total ?? 0;
|
|
13
|
+
function majorUnits(value, currency) {
|
|
14
|
+
return fromMinorUnits(value, currency ?? "");
|
|
15
|
+
}
|
|
16
|
+
function priceAmount(price, currency) {
|
|
17
|
+
return majorUnits(priceTotal(price), price?.currency ?? currency);
|
|
18
|
+
}
|
|
19
|
+
function quoteAmount(quote, currency) {
|
|
20
|
+
return majorUnits(quoteTotal(quote), quote.price?.currency ?? currency);
|
|
21
|
+
}
|
|
11
22
|
const QUOTE_DEBOUNCE_MS = 150;
|
|
23
|
+
const REQUEST_TIMEOUT_MS = 15_000;
|
|
12
24
|
const STICKY_CHECKOUT_SCROLL_OFFSET_PX = 100;
|
|
25
|
+
const CHECKOUT_IDEMPOTENCY_PREFIX = "session-services:checkout:";
|
|
26
|
+
function createCheckoutIdempotencyKey() {
|
|
27
|
+
const bytes = globalThis.crypto.getRandomValues(new Uint8Array(16));
|
|
28
|
+
return `elements_${Array.from(bytes, (value) => value.toString(16).padStart(2, "0")).join("")}`;
|
|
29
|
+
}
|
|
30
|
+
async function checkoutStorageName(identity) {
|
|
31
|
+
if (!globalThis.crypto?.subtle)
|
|
32
|
+
return undefined;
|
|
33
|
+
const digest = await globalThis.crypto.subtle.digest("SHA-256", new TextEncoder().encode(identity));
|
|
34
|
+
return `${CHECKOUT_IDEMPOTENCY_PREFIX}${Array.from(new Uint8Array(digest), (value) => value.toString(16).padStart(2, "0")).join("")}`;
|
|
35
|
+
}
|
|
36
|
+
function storedCheckoutIdempotencyKey(name) {
|
|
37
|
+
if (!name || typeof window === "undefined")
|
|
38
|
+
return undefined;
|
|
39
|
+
try {
|
|
40
|
+
return window.sessionStorage?.getItem(name) || undefined;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function storeCheckoutIdempotencyKey(name, key) {
|
|
47
|
+
if (!name || typeof window === "undefined")
|
|
48
|
+
return;
|
|
49
|
+
try {
|
|
50
|
+
window.sessionStorage?.setItem(name, key);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// In-memory state still keeps retries idempotent when storage is blocked.
|
|
54
|
+
}
|
|
55
|
+
}
|
|
13
56
|
function objectValue(value, key) {
|
|
14
57
|
if (!value || typeof value !== "object")
|
|
15
58
|
return undefined;
|
|
@@ -28,6 +71,29 @@ function isPasscodeAccessError(err) {
|
|
|
28
71
|
return true;
|
|
29
72
|
return errorCode(err) === "UNAUTHORIZED" && /passcode/i.test(message);
|
|
30
73
|
}
|
|
74
|
+
function classifyLoadError(err) {
|
|
75
|
+
if (isPasscodeAccessError(err))
|
|
76
|
+
return "access";
|
|
77
|
+
if (errorCode(err) === "NOT_FOUND")
|
|
78
|
+
return "not_found";
|
|
79
|
+
return "transient";
|
|
80
|
+
}
|
|
81
|
+
async function withTimeout(controller, request) {
|
|
82
|
+
let timer;
|
|
83
|
+
const timeout = new Promise((_, reject) => {
|
|
84
|
+
timer = setTimeout(() => {
|
|
85
|
+
controller.abort();
|
|
86
|
+
reject(new Error("The request timed out"));
|
|
87
|
+
}, REQUEST_TIMEOUT_MS);
|
|
88
|
+
});
|
|
89
|
+
try {
|
|
90
|
+
return await Promise.race([request(controller.signal), timeout]);
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
if (timer)
|
|
94
|
+
clearTimeout(timer);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
31
97
|
function parseJson(value) {
|
|
32
98
|
try {
|
|
33
99
|
return JSON.parse(value);
|
|
@@ -36,8 +102,12 @@ function parseJson(value) {
|
|
|
36
102
|
return null;
|
|
37
103
|
}
|
|
38
104
|
}
|
|
39
|
-
function
|
|
40
|
-
|
|
105
|
+
function analyticsSkipReason(event) {
|
|
106
|
+
if (!event.teamId)
|
|
107
|
+
return "missing_team_id";
|
|
108
|
+
if (!event.promoterId)
|
|
109
|
+
return "missing_promoter_id";
|
|
110
|
+
return null;
|
|
41
111
|
}
|
|
42
112
|
function eventVenueName(event) {
|
|
43
113
|
return [event.location?.venue?.name, event.location?.name].find(Boolean);
|
|
@@ -81,7 +151,7 @@ function quoteProductContext({ event, admission, section, }) {
|
|
|
81
151
|
}
|
|
82
152
|
function quoteProductPrice(item) {
|
|
83
153
|
return {
|
|
84
|
-
price:
|
|
154
|
+
price: priceAmount(item.price),
|
|
85
155
|
price_base: item.price?.base,
|
|
86
156
|
price_booking_fee: item.price?.booking,
|
|
87
157
|
};
|
|
@@ -110,8 +180,13 @@ export class SessionsTicketing {
|
|
|
110
180
|
selectedItems = new Map();
|
|
111
181
|
quote = null;
|
|
112
182
|
previewQuote = null;
|
|
113
|
-
|
|
183
|
+
initialLoading = true;
|
|
184
|
+
eventLoading = false;
|
|
185
|
+
retryLoading = false;
|
|
186
|
+
passcodeLoading = false;
|
|
114
187
|
error = null;
|
|
188
|
+
errorKind = null;
|
|
189
|
+
refreshError = null;
|
|
115
190
|
quoteLoading = false;
|
|
116
191
|
previewLoading = false;
|
|
117
192
|
quoteError = null;
|
|
@@ -123,44 +198,85 @@ export class SessionsTicketing {
|
|
|
123
198
|
passcodeDenied = false;
|
|
124
199
|
selectionPrompt = false;
|
|
125
200
|
checkoutLoading = false;
|
|
201
|
+
checkoutError = null;
|
|
126
202
|
currentTheme = "light";
|
|
127
203
|
openModalAdmissionId = null;
|
|
204
|
+
verificationRequired = false;
|
|
128
205
|
checkoutInit;
|
|
129
206
|
cartUpdate;
|
|
130
207
|
errorOccurred;
|
|
208
|
+
analyticsEventSkipped;
|
|
131
209
|
client;
|
|
132
210
|
analytics;
|
|
133
211
|
mediaQueryList;
|
|
134
212
|
requestId = 0;
|
|
135
213
|
previewRequestId = 0;
|
|
214
|
+
eventRequestId = 0;
|
|
215
|
+
checkoutRequestId = 0;
|
|
216
|
+
couponRequestId = 0;
|
|
217
|
+
initializeId = 0;
|
|
218
|
+
initialSettled = false;
|
|
219
|
+
active = true;
|
|
220
|
+
trackedIdentity;
|
|
221
|
+
quoteRevision;
|
|
222
|
+
checkoutIdempotencyKeys = new Map();
|
|
223
|
+
eventController;
|
|
224
|
+
quoteController;
|
|
225
|
+
previewController;
|
|
226
|
+
checkoutController;
|
|
227
|
+
couponController;
|
|
136
228
|
quoteTimer;
|
|
137
229
|
promptTimer;
|
|
138
|
-
|
|
230
|
+
botBypassed = false;
|
|
231
|
+
modalTrigger;
|
|
232
|
+
modalFocusPending = false;
|
|
233
|
+
modalRestorePending = false;
|
|
234
|
+
connectedCallback() {
|
|
235
|
+
this.active = true;
|
|
139
236
|
if (typeof window !== "undefined") {
|
|
140
237
|
window.addEventListener("popstate", this.handleDiscountQueryChange);
|
|
141
238
|
}
|
|
142
|
-
await this.initializeComponent();
|
|
143
239
|
}
|
|
144
|
-
|
|
145
|
-
|
|
240
|
+
componentWillLoad() {
|
|
241
|
+
this.startInitialization();
|
|
146
242
|
}
|
|
147
|
-
|
|
148
|
-
|
|
243
|
+
componentDidRender() {
|
|
244
|
+
if (this.modalFocusPending) {
|
|
245
|
+
const dialog = this.host.shadowRoot?.querySelector(".modal-content");
|
|
246
|
+
if (!dialog)
|
|
247
|
+
return;
|
|
248
|
+
this.modalFocusPending = false;
|
|
249
|
+
dialog.querySelector("button")?.focus();
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
if (!this.modalRestorePending)
|
|
253
|
+
return;
|
|
254
|
+
this.modalRestorePending = false;
|
|
255
|
+
this.modalTrigger?.focus();
|
|
256
|
+
this.modalTrigger = undefined;
|
|
257
|
+
}
|
|
258
|
+
propsChanged() {
|
|
259
|
+
this.startInitialization();
|
|
260
|
+
}
|
|
261
|
+
couponCodeChanged() {
|
|
262
|
+
this.setInitialCoupon().catch((err) => {
|
|
263
|
+
this.setCouponError(errorMessage(err, "Failed to update coupon"));
|
|
264
|
+
});
|
|
149
265
|
}
|
|
150
266
|
themeChanged() {
|
|
151
267
|
this.setupTheme();
|
|
152
268
|
}
|
|
153
269
|
disconnectedCallback() {
|
|
154
|
-
|
|
270
|
+
this.active = false;
|
|
271
|
+
this.initializeId++;
|
|
272
|
+
this.invalidateRequests();
|
|
273
|
+
if (typeof window !== "undefined" && window.removeEventListener) {
|
|
155
274
|
window.removeEventListener("popstate", this.handleDiscountQueryChange);
|
|
156
275
|
}
|
|
157
276
|
if (this.mediaQueryList) {
|
|
158
277
|
this.mediaQueryList.removeEventListener("change", this.handleSystemThemeChange);
|
|
159
278
|
}
|
|
160
|
-
|
|
161
|
-
if (this.openModalAdmissionId) {
|
|
162
|
-
document.removeEventListener("keydown", this.handleModalKeyDown);
|
|
163
|
-
}
|
|
279
|
+
document.removeEventListener("keydown", this.handleModalKeyDown);
|
|
164
280
|
this.clearQuoteTimer();
|
|
165
281
|
this.clearPromptTimer();
|
|
166
282
|
}
|
|
@@ -169,56 +285,144 @@ export class SessionsTicketing {
|
|
|
169
285
|
return;
|
|
170
286
|
this.setInitialCoupon().catch(() => undefined);
|
|
171
287
|
};
|
|
288
|
+
continueAfterVerification = async () => {
|
|
289
|
+
this.botBypassed = true;
|
|
290
|
+
this.verificationRequired = false;
|
|
291
|
+
const pending = this.initializeComponent();
|
|
292
|
+
const id = this.initializeId;
|
|
293
|
+
try {
|
|
294
|
+
await pending;
|
|
295
|
+
}
|
|
296
|
+
catch (err) {
|
|
297
|
+
if (id === this.initializeId)
|
|
298
|
+
this.handleInitializationError(err);
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
startInitialization() {
|
|
302
|
+
const pending = this.initializeComponent();
|
|
303
|
+
const id = this.initializeId;
|
|
304
|
+
pending.catch((err) => {
|
|
305
|
+
if (id === this.initializeId)
|
|
306
|
+
this.handleInitializationError(err);
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
handleInitializationError = (err) => {
|
|
310
|
+
const error = errorMessage(err, "Failed to load event data");
|
|
311
|
+
this.error = error;
|
|
312
|
+
this.errorKind = "transient";
|
|
313
|
+
this.finishInitialLoad(!this.initialSettled);
|
|
314
|
+
this.errorOccurred.emit({ error });
|
|
315
|
+
};
|
|
172
316
|
async initializeComponent() {
|
|
317
|
+
const id = ++this.initializeId;
|
|
318
|
+
const initial = !this.initialSettled;
|
|
319
|
+
this.invalidateRequests();
|
|
173
320
|
this.error = null;
|
|
321
|
+
this.errorKind = null;
|
|
322
|
+
this.refreshError = null;
|
|
174
323
|
this.event = null;
|
|
175
324
|
this.selectedItems = new Map();
|
|
176
325
|
this.quote = null;
|
|
177
326
|
this.previewQuote = null;
|
|
178
327
|
this.quoteError = null;
|
|
328
|
+
this.checkoutError = null;
|
|
329
|
+
this.quoteLoading = false;
|
|
330
|
+
this.previewLoading = false;
|
|
331
|
+
this.checkoutLoading = false;
|
|
179
332
|
this.couponError = null;
|
|
180
333
|
this.couponInput = this.initialCouponCode();
|
|
181
334
|
this.appliedCouponCode = this.couponInput;
|
|
182
335
|
this.activePasscode = this.passcode || "";
|
|
183
336
|
this.passcodeInput = this.activePasscode;
|
|
184
337
|
this.passcodeDenied = false;
|
|
338
|
+
this.verificationRequired = false;
|
|
339
|
+
this.initialLoading = initial;
|
|
340
|
+
this.eventLoading = !initial;
|
|
341
|
+
this.retryLoading = false;
|
|
342
|
+
this.passcodeLoading = false;
|
|
185
343
|
if (!this.tenantId || !this.eventId) {
|
|
186
344
|
this.error = "Missing required configuration: tenantId and eventId";
|
|
187
|
-
this.
|
|
345
|
+
this.errorKind = "configuration";
|
|
346
|
+
this.finishInitialLoad(initial);
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
this.setupTheme();
|
|
350
|
+
if (!this.botBypassed && isProductionApi(this.apiUrl) && detectBot().bot) {
|
|
351
|
+
this.verificationRequired = true;
|
|
352
|
+
this.finishInitialLoad(initial);
|
|
188
353
|
return;
|
|
189
354
|
}
|
|
190
355
|
this.client = createClient({
|
|
191
356
|
environment: this.apiUrl,
|
|
192
357
|
tenantId: this.tenantId,
|
|
193
358
|
});
|
|
194
|
-
this.
|
|
195
|
-
await this.loadEventData(
|
|
359
|
+
this.analytics = undefined;
|
|
360
|
+
const result = await this.loadEventData({
|
|
361
|
+
mode: initial ? "initial" : "refresh",
|
|
362
|
+
});
|
|
363
|
+
if (id !== this.initializeId || result.status !== "success")
|
|
364
|
+
return;
|
|
365
|
+
this.handleLoadedEvent(result.event);
|
|
366
|
+
await this.updatePreviewQuote();
|
|
367
|
+
}
|
|
368
|
+
handleLoadedEvent(event) {
|
|
369
|
+
const identity = `${this.apiUrl}::${this.tenantId}::${this.eventId}`;
|
|
370
|
+
this.setupAnalytics(event);
|
|
371
|
+
if (identity === this.trackedIdentity)
|
|
372
|
+
return;
|
|
373
|
+
this.trackedIdentity = identity;
|
|
374
|
+
this.trackLoadedEvent(event);
|
|
375
|
+
}
|
|
376
|
+
finishInitialLoad(initial) {
|
|
377
|
+
if (initial) {
|
|
378
|
+
this.initialSettled = true;
|
|
379
|
+
this.initialLoading = false;
|
|
380
|
+
}
|
|
381
|
+
this.eventLoading = false;
|
|
382
|
+
}
|
|
383
|
+
invalidateRequests() {
|
|
384
|
+
this.eventRequestId++;
|
|
385
|
+
this.requestId++;
|
|
386
|
+
this.previewRequestId++;
|
|
387
|
+
this.checkoutRequestId++;
|
|
388
|
+
this.couponRequestId++;
|
|
389
|
+
this.eventController?.abort();
|
|
390
|
+
this.quoteController?.abort();
|
|
391
|
+
this.previewController?.abort();
|
|
392
|
+
this.checkoutController?.abort();
|
|
393
|
+
this.couponController?.abort();
|
|
394
|
+
this.eventController = undefined;
|
|
395
|
+
this.quoteController = undefined;
|
|
396
|
+
this.previewController = undefined;
|
|
397
|
+
this.checkoutController = undefined;
|
|
398
|
+
this.couponController = undefined;
|
|
399
|
+
this.clearQuoteTimer();
|
|
400
|
+
this.quoteRevision = undefined;
|
|
401
|
+
this.quoteLoading = false;
|
|
402
|
+
this.previewLoading = false;
|
|
403
|
+
this.checkoutLoading = false;
|
|
196
404
|
}
|
|
197
405
|
async setInitialCoupon() {
|
|
198
406
|
const coupon = this.initialCouponCode();
|
|
199
407
|
this.couponInput = coupon;
|
|
200
|
-
this.quote = null;
|
|
201
|
-
this.previewQuote = this.activeInitialPreviewQuote(coupon);
|
|
202
408
|
this.quoteError = null;
|
|
203
409
|
this.couponError = null;
|
|
204
|
-
if (!
|
|
205
|
-
this.appliedCouponCode =
|
|
206
|
-
|
|
410
|
+
if (!this.event) {
|
|
411
|
+
this.appliedCouponCode = coupon;
|
|
412
|
+
this.previewQuote = this.activeInitialPreviewQuote(coupon);
|
|
207
413
|
return;
|
|
208
414
|
}
|
|
209
415
|
if (this.selectedItems.size > 0) {
|
|
210
416
|
await this.applyCartCoupon(coupon);
|
|
211
417
|
return;
|
|
212
418
|
}
|
|
213
|
-
if (this.previewQuote)
|
|
214
|
-
return;
|
|
215
419
|
await this.applyPreviewCoupon(coupon);
|
|
216
420
|
}
|
|
217
421
|
initialCouponCode() {
|
|
218
422
|
const prop = normalizeCouponCode(this.couponCode);
|
|
219
423
|
if (prop)
|
|
220
424
|
return prop;
|
|
221
|
-
if (typeof window === "undefined")
|
|
425
|
+
if (typeof window === "undefined" || !window.location)
|
|
222
426
|
return "";
|
|
223
427
|
return normalizeCouponCode(discountCouponFromSearch(window.location.search));
|
|
224
428
|
}
|
|
@@ -269,36 +473,62 @@ export class SessionsTicketing {
|
|
|
269
473
|
}
|
|
270
474
|
};
|
|
271
475
|
trackEvent(eventType, properties = {}) {
|
|
272
|
-
const context = this.analyticsContext();
|
|
476
|
+
const context = this.analyticsContext(eventType);
|
|
273
477
|
if (!context)
|
|
274
478
|
return;
|
|
275
479
|
context.analytics.track(eventType, {
|
|
276
|
-
|
|
277
|
-
team_id: context.event.teamId,
|
|
278
|
-
promoter_id: context.event.promoterId,
|
|
279
|
-
event_name: context.event.name,
|
|
280
|
-
event_slug: context.event.slug,
|
|
281
|
-
currency: context.event.currency,
|
|
480
|
+
...this.analyticsProperties(context.event),
|
|
282
481
|
...properties,
|
|
283
482
|
});
|
|
284
483
|
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
484
|
+
analyticsProperties(event, properties = {}) {
|
|
485
|
+
return {
|
|
486
|
+
event_id: this.eventId,
|
|
487
|
+
team_id: event.teamId,
|
|
488
|
+
promoter_id: event.promoterId,
|
|
489
|
+
event_name: event.name,
|
|
490
|
+
event_slug: event.slug,
|
|
491
|
+
currency: event.currency,
|
|
492
|
+
...properties,
|
|
493
|
+
};
|
|
291
494
|
}
|
|
292
|
-
|
|
495
|
+
analyticsForEvent(eventType, event) {
|
|
293
496
|
if (!this.enableAnalytics)
|
|
294
497
|
return undefined;
|
|
498
|
+
const reason = analyticsSkipReason(event);
|
|
499
|
+
if (reason) {
|
|
500
|
+
this.emitAnalyticsEventSkipped(eventType, reason, event);
|
|
501
|
+
return undefined;
|
|
502
|
+
}
|
|
503
|
+
if (!this.analytics) {
|
|
504
|
+
this.emitAnalyticsEventSkipped(eventType, "analytics_not_initialized", event);
|
|
505
|
+
return undefined;
|
|
506
|
+
}
|
|
295
507
|
return this.analytics;
|
|
296
508
|
}
|
|
297
|
-
|
|
509
|
+
analyticsContext(eventType) {
|
|
298
510
|
const event = this.event;
|
|
299
|
-
if (!event)
|
|
511
|
+
if (!event) {
|
|
512
|
+
this.emitAnalyticsEventSkipped(eventType, "missing_event");
|
|
300
513
|
return undefined;
|
|
301
|
-
|
|
514
|
+
}
|
|
515
|
+
const analytics = this.analyticsForEvent(eventType, event);
|
|
516
|
+
if (!analytics)
|
|
517
|
+
return undefined;
|
|
518
|
+
return { analytics, event };
|
|
519
|
+
}
|
|
520
|
+
emitAnalyticsEventSkipped(eventType, reason, event, err) {
|
|
521
|
+
const detail = {
|
|
522
|
+
eventType,
|
|
523
|
+
eventId: this.eventId,
|
|
524
|
+
reason,
|
|
525
|
+
promoterId: event?.promoterId || undefined,
|
|
526
|
+
teamId: event?.teamId || undefined,
|
|
527
|
+
};
|
|
528
|
+
this.analyticsEventSkipped.emit(detail);
|
|
529
|
+
if (this.debugAnalytics) {
|
|
530
|
+
console.warn("[SessionServicesTicketing] Analytics event skipped:", detail, err);
|
|
531
|
+
}
|
|
302
532
|
}
|
|
303
533
|
getLowestPrice() {
|
|
304
534
|
const event = this.event;
|
|
@@ -312,7 +542,7 @@ export class SessionsTicketing {
|
|
|
312
542
|
sku: adm.id,
|
|
313
543
|
name: adm.name,
|
|
314
544
|
category: event.name,
|
|
315
|
-
price:
|
|
545
|
+
price: priceAmount(adm.price, event.currency),
|
|
316
546
|
quantity: 1,
|
|
317
547
|
position: index + 1,
|
|
318
548
|
admission_id: adm.id,
|
|
@@ -323,41 +553,111 @@ export class SessionsTicketing {
|
|
|
323
553
|
capacity: adm.capacity,
|
|
324
554
|
}));
|
|
325
555
|
}
|
|
326
|
-
async loadEventData() {
|
|
556
|
+
async loadEventData(options = {}) {
|
|
557
|
+
const mode = options.mode ?? "refresh";
|
|
558
|
+
const client = this.client;
|
|
559
|
+
const eventId = this.eventId;
|
|
560
|
+
if (!client || !this.tenantId || !eventId) {
|
|
561
|
+
const error = "Missing required configuration: tenantId and eventId";
|
|
562
|
+
this.error = error;
|
|
563
|
+
this.errorKind = "configuration";
|
|
564
|
+
return { status: "error", error, kind: "configuration" };
|
|
565
|
+
}
|
|
566
|
+
const id = ++this.eventRequestId;
|
|
567
|
+
const controller = new AbortController();
|
|
568
|
+
this.eventController?.abort();
|
|
569
|
+
this.eventController = controller;
|
|
570
|
+
if (mode === "coupon")
|
|
571
|
+
this.couponController = controller;
|
|
572
|
+
if (mode === "initial")
|
|
573
|
+
this.initialLoading = true;
|
|
574
|
+
if (mode === "refresh")
|
|
575
|
+
this.eventLoading = true;
|
|
576
|
+
if (mode === "retry")
|
|
577
|
+
this.retryLoading = true;
|
|
578
|
+
if (mode === "passcode")
|
|
579
|
+
this.passcodeLoading = true;
|
|
327
580
|
try {
|
|
328
|
-
|
|
329
|
-
|
|
581
|
+
if (mode !== "coupon" && mode !== "passcode") {
|
|
582
|
+
this.error = null;
|
|
583
|
+
this.errorKind = null;
|
|
584
|
+
this.refreshError = null;
|
|
585
|
+
}
|
|
586
|
+
const response = await withTimeout(controller, (signal) => client.event.get({
|
|
587
|
+
key: eventId,
|
|
588
|
+
couponCode: (options.couponCode ?? this.appliedCouponCode) || undefined,
|
|
589
|
+
passcode: (options.passcode ?? this.activePasscode) || undefined,
|
|
590
|
+
}, { signal }));
|
|
591
|
+
if (!this.isEventRequestCurrent(id, eventId, controller)) {
|
|
592
|
+
return { status: "stale" };
|
|
593
|
+
}
|
|
594
|
+
if (options.commit !== false) {
|
|
595
|
+
this.event = response.event;
|
|
596
|
+
this.pruneSelectedItems(response.event);
|
|
597
|
+
}
|
|
330
598
|
this.passcodeDenied = false;
|
|
331
|
-
|
|
332
|
-
key: this.eventId,
|
|
333
|
-
couponCode: this.appliedCouponCode || undefined,
|
|
334
|
-
passcode: this.activePasscode || undefined,
|
|
335
|
-
});
|
|
336
|
-
this.event = response.event;
|
|
337
|
-
this.pruneSelectedItems(response.event);
|
|
338
|
-
this.trackLoadedEvent(response.event);
|
|
339
|
-
await this.updatePreviewQuote();
|
|
599
|
+
return { status: "success", event: response.event };
|
|
340
600
|
}
|
|
341
601
|
catch (err) {
|
|
342
|
-
this.
|
|
343
|
-
|
|
344
|
-
|
|
602
|
+
if (!this.isEventRequestCurrent(id, eventId, controller)) {
|
|
603
|
+
return { status: "stale" };
|
|
604
|
+
}
|
|
605
|
+
const kind = classifyLoadError(err);
|
|
606
|
+
const error = errorMessage(err, "Failed to load event data");
|
|
607
|
+
this.passcodeDenied = kind === "access";
|
|
608
|
+
if (mode !== "coupon") {
|
|
609
|
+
if (this.event && (mode === "refresh" || mode === "retry")) {
|
|
610
|
+
this.refreshError = error;
|
|
611
|
+
}
|
|
612
|
+
else {
|
|
613
|
+
this.error = error;
|
|
614
|
+
this.errorKind = kind;
|
|
615
|
+
}
|
|
616
|
+
this.errorOccurred.emit({ error });
|
|
617
|
+
}
|
|
618
|
+
return { status: "error", error, kind };
|
|
345
619
|
}
|
|
346
620
|
finally {
|
|
347
|
-
this.
|
|
621
|
+
if (id === this.eventRequestId) {
|
|
622
|
+
if (mode === "initial")
|
|
623
|
+
this.finishInitialLoad(true);
|
|
624
|
+
if (mode === "refresh")
|
|
625
|
+
this.eventLoading = false;
|
|
626
|
+
if (mode === "retry")
|
|
627
|
+
this.retryLoading = false;
|
|
628
|
+
if (mode === "passcode")
|
|
629
|
+
this.passcodeLoading = false;
|
|
630
|
+
if (this.eventController === controller)
|
|
631
|
+
this.eventController = undefined;
|
|
632
|
+
if (this.couponController === controller)
|
|
633
|
+
this.couponController = undefined;
|
|
634
|
+
}
|
|
348
635
|
}
|
|
349
636
|
}
|
|
637
|
+
isEventRequestCurrent(id, eventId, controller) {
|
|
638
|
+
return (this.active &&
|
|
639
|
+
id === this.eventRequestId &&
|
|
640
|
+
eventId === this.eventId &&
|
|
641
|
+
this.eventController === controller);
|
|
642
|
+
}
|
|
350
643
|
pruneSelectedItems(event) {
|
|
644
|
+
if (this.openModalAdmissionId &&
|
|
645
|
+
!event.admissions.some((admission) => admission.id === this.openModalAdmissionId)) {
|
|
646
|
+
this.closeModal();
|
|
647
|
+
}
|
|
351
648
|
const keys = new Set(event.admissions.map((admission) => selectionKey(admission.id, admission.sectionId ?? null)));
|
|
352
649
|
const selected = Array.from(this.selectedItems).filter(([key]) => keys.has(key));
|
|
353
650
|
if (selected.length === this.selectedItems.size)
|
|
354
651
|
return;
|
|
355
652
|
this.selectedItems = new Map(selected);
|
|
356
|
-
this.
|
|
357
|
-
this.
|
|
653
|
+
this.invalidateQuote();
|
|
654
|
+
if (this.selectedItems.size > 0)
|
|
655
|
+
this.scheduleQuoteUpdate();
|
|
358
656
|
}
|
|
359
657
|
trackLoadedEvent(event) {
|
|
360
|
-
this.setupAnalytics(event)
|
|
658
|
+
if (!this.setupAnalytics(event))
|
|
659
|
+
return;
|
|
660
|
+
this.trackPageViewed(event);
|
|
361
661
|
this.trackProductViewed(event);
|
|
362
662
|
this.trackEvent("Product List Viewed", {
|
|
363
663
|
list_id: this.eventId,
|
|
@@ -366,19 +666,32 @@ export class SessionsTicketing {
|
|
|
366
666
|
});
|
|
367
667
|
}
|
|
368
668
|
setupAnalytics(event) {
|
|
369
|
-
if (!this.enableAnalytics
|
|
669
|
+
if (!this.enableAnalytics)
|
|
670
|
+
return false;
|
|
671
|
+
const reason = analyticsSkipReason(event);
|
|
672
|
+
if (reason) {
|
|
673
|
+
this.emitAnalyticsEventSkipped("Page Viewed", reason, event);
|
|
674
|
+
return false;
|
|
675
|
+
}
|
|
676
|
+
if (this.analytics)
|
|
677
|
+
return true;
|
|
678
|
+
try {
|
|
679
|
+
this.analytics = createAnalytics({
|
|
680
|
+
client: this.client,
|
|
681
|
+
debug: this.debugAnalytics,
|
|
682
|
+
});
|
|
683
|
+
}
|
|
684
|
+
catch (err) {
|
|
685
|
+
this.emitAnalyticsEventSkipped("Page Viewed", "analytics_initialization_failed", event, err);
|
|
686
|
+
return false;
|
|
687
|
+
}
|
|
688
|
+
return true;
|
|
689
|
+
}
|
|
690
|
+
trackPageViewed(event) {
|
|
691
|
+
const analytics = this.analyticsForEvent("Page Viewed", event);
|
|
692
|
+
if (!analytics)
|
|
370
693
|
return;
|
|
371
|
-
|
|
372
|
-
client: this.client,
|
|
373
|
-
debug: this.debugAnalytics,
|
|
374
|
-
});
|
|
375
|
-
this.analytics.page("Ticketing Widget", {
|
|
376
|
-
event_id: this.eventId,
|
|
377
|
-
team_id: event.teamId,
|
|
378
|
-
promoter_id: event.promoterId,
|
|
379
|
-
event_name: event.name,
|
|
380
|
-
event_slug: event.slug,
|
|
381
|
-
});
|
|
694
|
+
analytics.page("Ticketing Widget", this.analyticsProperties(event));
|
|
382
695
|
}
|
|
383
696
|
trackProductViewed(event) {
|
|
384
697
|
const lowestPrice = this.getLowestPrice();
|
|
@@ -387,8 +700,8 @@ export class SessionsTicketing {
|
|
|
387
700
|
sku: this.eventId,
|
|
388
701
|
name: event.name,
|
|
389
702
|
category: "Event",
|
|
390
|
-
value: lowestPrice
|
|
391
|
-
price: lowestPrice
|
|
703
|
+
value: majorUnits(lowestPrice, event.currency),
|
|
704
|
+
price: majorUnits(lowestPrice, event.currency),
|
|
392
705
|
event_date: event.entryStartsAt,
|
|
393
706
|
venue_name: eventVenueName(event),
|
|
394
707
|
venue_city: event.location?.city,
|
|
@@ -399,6 +712,8 @@ export class SessionsTicketing {
|
|
|
399
712
|
await this.setQuantity(admissionId, sectionId, (this.selectedItems.get(key) || 0) + delta);
|
|
400
713
|
}
|
|
401
714
|
async setQuantity(admissionId, sectionId, quantity) {
|
|
715
|
+
if (this.checkoutLoading)
|
|
716
|
+
return;
|
|
402
717
|
const key = selectionKey(admissionId, sectionId);
|
|
403
718
|
const admission = this.event?.admissions.find((a) => a.id === admissionId);
|
|
404
719
|
if (!admission)
|
|
@@ -409,6 +724,8 @@ export class SessionsTicketing {
|
|
|
409
724
|
return;
|
|
410
725
|
this.selectionPrompt = false;
|
|
411
726
|
this.setSelectedQuantity(key, next);
|
|
727
|
+
this.invalidateQuote();
|
|
728
|
+
this.checkoutError = null;
|
|
412
729
|
const section = sectionId
|
|
413
730
|
? this.event?.sections.find((s) => s.id === sectionId)
|
|
414
731
|
: null;
|
|
@@ -454,7 +771,7 @@ export class SessionsTicketing {
|
|
|
454
771
|
name: change.admission.name,
|
|
455
772
|
category: this.event?.name,
|
|
456
773
|
variant: change.section?.name,
|
|
457
|
-
price:
|
|
774
|
+
price: priceAmount(change.admission.price, this.event?.currency),
|
|
458
775
|
quantity: Math.abs(change.delta),
|
|
459
776
|
admission_id: change.admission.id,
|
|
460
777
|
section_id: optionalId(change.sectionId),
|
|
@@ -464,19 +781,26 @@ export class SessionsTicketing {
|
|
|
464
781
|
async updateQuote() {
|
|
465
782
|
this.clearQuoteTimer();
|
|
466
783
|
if (this.selectedItems.size === 0) {
|
|
784
|
+
this.invalidateQuote();
|
|
467
785
|
this.quote = null;
|
|
468
786
|
this.quoteError = null;
|
|
469
787
|
this.quoteLoading = false;
|
|
470
788
|
await this.updatePreviewQuote();
|
|
471
789
|
return;
|
|
472
790
|
}
|
|
473
|
-
this.requestId
|
|
474
|
-
const
|
|
791
|
+
const currentId = ++this.requestId;
|
|
792
|
+
const eventId = this.eventId;
|
|
793
|
+
const coupon = this.appliedCouponCode;
|
|
794
|
+
const items = this.getQuoteRequestItems();
|
|
795
|
+
const revision = this.quoteRevisionFor(eventId, coupon, items);
|
|
796
|
+
const controller = new AbortController();
|
|
797
|
+
this.quoteController?.abort();
|
|
798
|
+
this.quoteController = controller;
|
|
475
799
|
try {
|
|
476
800
|
this.quoteLoading = true;
|
|
477
801
|
this.quoteError = null;
|
|
478
|
-
const response = await this.fetchCartQuote(
|
|
479
|
-
this.applyQuote(response.quote, currentId);
|
|
802
|
+
const response = await this.fetchCartQuote(eventId, items, coupon, controller);
|
|
803
|
+
this.applyQuote(response.quote, currentId, revision);
|
|
480
804
|
}
|
|
481
805
|
catch (_err) {
|
|
482
806
|
this.handleQuoteError(currentId);
|
|
@@ -484,6 +808,9 @@ export class SessionsTicketing {
|
|
|
484
808
|
finally {
|
|
485
809
|
if (currentId === this.requestId) {
|
|
486
810
|
this.quoteLoading = false;
|
|
811
|
+
if (this.quoteController === controller) {
|
|
812
|
+
this.quoteController = undefined;
|
|
813
|
+
}
|
|
487
814
|
}
|
|
488
815
|
}
|
|
489
816
|
}
|
|
@@ -505,6 +832,26 @@ export class SessionsTicketing {
|
|
|
505
832
|
clearTimeout(this.quoteTimer);
|
|
506
833
|
this.quoteTimer = undefined;
|
|
507
834
|
}
|
|
835
|
+
invalidateQuote() {
|
|
836
|
+
this.requestId++;
|
|
837
|
+
this.couponRequestId++;
|
|
838
|
+
this.checkoutRequestId++;
|
|
839
|
+
this.quoteController?.abort();
|
|
840
|
+
this.previewController?.abort();
|
|
841
|
+
this.checkoutController?.abort();
|
|
842
|
+
this.couponController?.abort();
|
|
843
|
+
this.quoteController = undefined;
|
|
844
|
+
this.previewController = undefined;
|
|
845
|
+
this.checkoutController = undefined;
|
|
846
|
+
this.couponController = undefined;
|
|
847
|
+
this.quoteRevision = undefined;
|
|
848
|
+
this.quote = null;
|
|
849
|
+
this.quoteError = null;
|
|
850
|
+
this.quoteLoading = false;
|
|
851
|
+
this.previewLoading = false;
|
|
852
|
+
this.checkoutError = null;
|
|
853
|
+
this.checkoutLoading = false;
|
|
854
|
+
}
|
|
508
855
|
clearPromptTimer() {
|
|
509
856
|
if (!this.promptTimer)
|
|
510
857
|
return;
|
|
@@ -529,22 +876,23 @@ export class SessionsTicketing {
|
|
|
529
876
|
};
|
|
530
877
|
});
|
|
531
878
|
}
|
|
532
|
-
fetchCartQuote(couponCode) {
|
|
533
|
-
return this.client.order.quote({
|
|
534
|
-
eventId
|
|
535
|
-
items
|
|
879
|
+
fetchCartQuote(eventId, items, couponCode, controller) {
|
|
880
|
+
return withTimeout(controller, (signal) => this.client.order.quote({
|
|
881
|
+
eventId,
|
|
882
|
+
items,
|
|
536
883
|
couponCode: couponCode || undefined,
|
|
537
|
-
});
|
|
884
|
+
}, { signal }));
|
|
538
885
|
}
|
|
539
|
-
applyQuote(quote, requestId) {
|
|
886
|
+
applyQuote(quote, requestId, revision = this.currentQuoteRevision()) {
|
|
540
887
|
if (requestId !== this.requestId)
|
|
541
888
|
return;
|
|
542
889
|
this.quote = quote;
|
|
890
|
+
this.quoteRevision = revision;
|
|
543
891
|
this.quoteError = null;
|
|
544
892
|
this.cartUpdate.emit(this.quote);
|
|
545
893
|
this.trackEvent("Cart Viewed", {
|
|
546
894
|
products: this.getCartProducts(),
|
|
547
|
-
value:
|
|
895
|
+
value: quoteAmount(this.quote, this.event?.currency),
|
|
548
896
|
currency: this.event?.currency,
|
|
549
897
|
});
|
|
550
898
|
}
|
|
@@ -552,13 +900,22 @@ export class SessionsTicketing {
|
|
|
552
900
|
if (requestId !== this.requestId)
|
|
553
901
|
return;
|
|
554
902
|
this.quote = null;
|
|
903
|
+
this.quoteRevision = undefined;
|
|
555
904
|
this.quoteError = "Failed to update cart. Please try again.";
|
|
556
905
|
this.errorOccurred.emit({ error: this.quoteError });
|
|
557
906
|
}
|
|
907
|
+
quoteRevisionFor(eventId, coupon, items) {
|
|
908
|
+
return JSON.stringify({ eventId, coupon, items });
|
|
909
|
+
}
|
|
910
|
+
currentQuoteRevision() {
|
|
911
|
+
return this.quoteRevisionFor(this.eventId, this.appliedCouponCode, this.getQuoteRequestItems());
|
|
912
|
+
}
|
|
558
913
|
async updatePreviewQuote() {
|
|
559
914
|
const event = this.event;
|
|
560
915
|
if (!event || !this.appliedCouponCode) {
|
|
561
916
|
this.previewRequestId++;
|
|
917
|
+
this.previewController?.abort();
|
|
918
|
+
this.previewController = undefined;
|
|
562
919
|
this.previewLoading = false;
|
|
563
920
|
this.previewQuote = null;
|
|
564
921
|
return;
|
|
@@ -579,35 +936,41 @@ export class SessionsTicketing {
|
|
|
579
936
|
}
|
|
580
937
|
this.previewRequestId++;
|
|
581
938
|
const currentId = this.previewRequestId;
|
|
939
|
+
const coupon = this.appliedCouponCode;
|
|
940
|
+
const eventId = this.eventId;
|
|
941
|
+
const controller = new AbortController();
|
|
942
|
+
this.previewController?.abort();
|
|
943
|
+
this.previewController = controller;
|
|
582
944
|
try {
|
|
583
945
|
this.previewLoading = true;
|
|
584
|
-
const response = await this.fetchPreviewQuote(
|
|
585
|
-
if (currentId === this.previewRequestId
|
|
946
|
+
const response = await this.fetchPreviewQuote(event, coupon, controller);
|
|
947
|
+
if (currentId === this.previewRequestId &&
|
|
948
|
+
eventId === this.eventId &&
|
|
949
|
+
coupon === this.appliedCouponCode) {
|
|
586
950
|
this.previewQuote = response.quote;
|
|
587
951
|
}
|
|
588
952
|
}
|
|
589
953
|
catch (_err) {
|
|
590
954
|
if (currentId === this.previewRequestId) {
|
|
591
955
|
this.previewQuote = null;
|
|
592
|
-
this.appliedCouponCode = "";
|
|
593
956
|
this.setCouponError();
|
|
594
957
|
}
|
|
595
958
|
}
|
|
596
959
|
finally {
|
|
597
960
|
if (currentId === this.previewRequestId) {
|
|
598
961
|
this.previewLoading = false;
|
|
962
|
+
if (this.previewController === controller) {
|
|
963
|
+
this.previewController = undefined;
|
|
964
|
+
}
|
|
599
965
|
}
|
|
600
966
|
}
|
|
601
967
|
}
|
|
602
|
-
fetchPreviewQuote(couponCode) {
|
|
603
|
-
|
|
604
|
-
if (!event)
|
|
605
|
-
throw new Error("Missing event");
|
|
606
|
-
return this.client.order.quote({
|
|
968
|
+
fetchPreviewQuote(event, couponCode, controller) {
|
|
969
|
+
return withTimeout(controller, (signal) => this.client.order.quote({
|
|
607
970
|
eventId: event.id,
|
|
608
971
|
items: previewQuoteItems(event),
|
|
609
972
|
couponCode,
|
|
610
|
-
});
|
|
973
|
+
}, { signal }));
|
|
611
974
|
}
|
|
612
975
|
handleCouponInput = (e) => {
|
|
613
976
|
if (!(e.target instanceof HTMLInputElement))
|
|
@@ -639,136 +1002,136 @@ export class SessionsTicketing {
|
|
|
639
1002
|
await this.removeCartCoupon();
|
|
640
1003
|
return;
|
|
641
1004
|
}
|
|
642
|
-
this.
|
|
643
|
-
const coupon = this.appliedCouponCode;
|
|
644
|
-
this.appliedCouponCode = "";
|
|
645
|
-
await this.loadEventData();
|
|
646
|
-
this.previewRequestId++;
|
|
647
|
-
this.previewLoading = false;
|
|
648
|
-
this.previewQuote = null;
|
|
649
|
-
this.trackCouponRemoved(coupon, null);
|
|
1005
|
+
await this.applyPreviewCoupon("");
|
|
650
1006
|
}
|
|
651
1007
|
async applyCartCoupon(coupon) {
|
|
652
|
-
this.
|
|
653
|
-
const currentId = this.requestId;
|
|
1008
|
+
const operationId = ++this.couponRequestId;
|
|
1009
|
+
const currentId = ++this.requestId;
|
|
654
1010
|
const previousCoupon = this.appliedCouponCode;
|
|
1011
|
+
const items = this.getQuoteRequestItems();
|
|
1012
|
+
const eventId = this.eventId;
|
|
1013
|
+
const revision = this.quoteRevisionFor(eventId, coupon, items);
|
|
1014
|
+
const controller = new AbortController();
|
|
1015
|
+
this.quoteController?.abort();
|
|
1016
|
+
this.quoteController = controller;
|
|
655
1017
|
try {
|
|
656
1018
|
this.quoteLoading = true;
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
1019
|
+
const loaded = await this.loadEventData({
|
|
1020
|
+
commit: false,
|
|
1021
|
+
couponCode: coupon,
|
|
1022
|
+
mode: "coupon",
|
|
1023
|
+
});
|
|
1024
|
+
if (!this.isCouponOperationCurrent(operationId, currentId))
|
|
663
1025
|
return;
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
1026
|
+
if (loaded.status !== "success")
|
|
1027
|
+
throw new Error("Coupon load failed");
|
|
1028
|
+
const response = await this.fetchCartQuote(eventId, items, coupon, controller);
|
|
1029
|
+
if (!this.isCouponOperationCurrent(operationId, currentId))
|
|
667
1030
|
return;
|
|
1031
|
+
this.event = loaded.event;
|
|
668
1032
|
this.appliedCouponCode = coupon;
|
|
1033
|
+
this.couponInput = coupon;
|
|
669
1034
|
this.previewQuote = null;
|
|
670
|
-
this.
|
|
671
|
-
this.
|
|
1035
|
+
this.pruneSelectedItems(loaded.event);
|
|
1036
|
+
if (revision !== this.currentQuoteRevision()) {
|
|
1037
|
+
this.invalidateQuote();
|
|
1038
|
+
this.scheduleQuoteUpdate();
|
|
1039
|
+
return;
|
|
1040
|
+
}
|
|
1041
|
+
this.applyQuote(response.quote, currentId, revision);
|
|
1042
|
+
if (coupon) {
|
|
1043
|
+
this.trackCouponApplied(coupon, response.quote);
|
|
1044
|
+
}
|
|
1045
|
+
else {
|
|
1046
|
+
this.trackCouponRemoved(previousCoupon, response.quote);
|
|
1047
|
+
}
|
|
672
1048
|
}
|
|
673
1049
|
catch (_err) {
|
|
674
|
-
if (
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
this.
|
|
678
|
-
|
|
1050
|
+
if (!this.isCouponOperationCurrent(operationId, currentId))
|
|
1051
|
+
return;
|
|
1052
|
+
this.couponInput = previousCoupon || coupon;
|
|
1053
|
+
this.setCouponError(coupon
|
|
1054
|
+
? undefined
|
|
1055
|
+
: "Failed to remove coupon. Your current discount is still applied.");
|
|
1056
|
+
if (coupon)
|
|
1057
|
+
this.trackCouponDenied(coupon);
|
|
679
1058
|
}
|
|
680
1059
|
finally {
|
|
681
1060
|
if (currentId === this.requestId) {
|
|
682
1061
|
this.quoteLoading = false;
|
|
1062
|
+
if (this.quoteController === controller) {
|
|
1063
|
+
this.quoteController = undefined;
|
|
1064
|
+
}
|
|
683
1065
|
}
|
|
684
1066
|
}
|
|
685
1067
|
}
|
|
686
1068
|
async applyPreviewCoupon(coupon) {
|
|
687
1069
|
const previousCoupon = this.appliedCouponCode;
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
this.appliedCouponCode = previousCoupon;
|
|
694
|
-
this.setCouponError();
|
|
695
|
-
this.trackCouponDenied(coupon);
|
|
696
|
-
return;
|
|
697
|
-
}
|
|
698
|
-
const event = this.event;
|
|
699
|
-
if (!event)
|
|
700
|
-
return;
|
|
701
|
-
const initialQuote = this.activeInitialPreviewQuote(coupon);
|
|
702
|
-
if (initialQuote) {
|
|
703
|
-
this.appliedCouponCode = coupon;
|
|
704
|
-
this.previewQuote = initialQuote;
|
|
705
|
-
this.trackCouponApplied(coupon, initialQuote);
|
|
706
|
-
return;
|
|
707
|
-
}
|
|
708
|
-
if (previewQuoteItems(event).length === 0) {
|
|
709
|
-
this.appliedCouponCode = coupon;
|
|
710
|
-
this.previewQuote = null;
|
|
711
|
-
return;
|
|
712
|
-
}
|
|
713
|
-
this.previewRequestId++;
|
|
714
|
-
const currentId = this.previewRequestId;
|
|
1070
|
+
const operationId = ++this.couponRequestId;
|
|
1071
|
+
const currentId = ++this.previewRequestId;
|
|
1072
|
+
const controller = new AbortController();
|
|
1073
|
+
this.previewController?.abort();
|
|
1074
|
+
this.previewController = controller;
|
|
715
1075
|
try {
|
|
716
1076
|
this.previewLoading = true;
|
|
717
|
-
const
|
|
718
|
-
|
|
1077
|
+
const loaded = await this.loadEventData({
|
|
1078
|
+
commit: false,
|
|
1079
|
+
couponCode: coupon,
|
|
1080
|
+
mode: "coupon",
|
|
1081
|
+
});
|
|
1082
|
+
if (!this.isPreviewCouponOperationCurrent(operationId, currentId))
|
|
1083
|
+
return;
|
|
1084
|
+
if (loaded.status !== "success")
|
|
1085
|
+
throw new Error("Coupon load failed");
|
|
1086
|
+
const initialQuote = this.activeInitialPreviewQuote(coupon);
|
|
1087
|
+
const response = initialQuote || !coupon || previewQuoteItems(loaded.event).length === 0
|
|
1088
|
+
? null
|
|
1089
|
+
: await this.fetchPreviewQuote(loaded.event, coupon, controller);
|
|
1090
|
+
if (!this.isPreviewCouponOperationCurrent(operationId, currentId))
|
|
719
1091
|
return;
|
|
1092
|
+
this.event = loaded.event;
|
|
1093
|
+
this.pruneSelectedItems(loaded.event);
|
|
720
1094
|
this.appliedCouponCode = coupon;
|
|
721
|
-
this.
|
|
722
|
-
this.
|
|
1095
|
+
this.couponInput = coupon;
|
|
1096
|
+
this.previewQuote = initialQuote ?? response?.quote ?? null;
|
|
1097
|
+
if (coupon) {
|
|
1098
|
+
this.trackCouponApplied(coupon, this.previewQuote);
|
|
1099
|
+
}
|
|
1100
|
+
else {
|
|
1101
|
+
this.trackCouponRemoved(previousCoupon, null);
|
|
1102
|
+
}
|
|
723
1103
|
}
|
|
724
1104
|
catch (_err) {
|
|
725
|
-
if (
|
|
726
|
-
|
|
1105
|
+
if (!this.isPreviewCouponOperationCurrent(operationId, currentId))
|
|
1106
|
+
return;
|
|
1107
|
+
this.couponInput = previousCoupon || coupon;
|
|
1108
|
+
this.setCouponError(coupon
|
|
1109
|
+
? undefined
|
|
1110
|
+
: "Failed to remove coupon. Your current discount is still applied.");
|
|
1111
|
+
if (coupon)
|
|
727
1112
|
this.trackCouponDenied(coupon);
|
|
728
|
-
}
|
|
729
1113
|
}
|
|
730
1114
|
finally {
|
|
731
1115
|
if (currentId === this.previewRequestId) {
|
|
732
1116
|
this.previewLoading = false;
|
|
1117
|
+
if (this.previewController === controller) {
|
|
1118
|
+
this.previewController = undefined;
|
|
1119
|
+
}
|
|
733
1120
|
}
|
|
734
1121
|
}
|
|
735
1122
|
}
|
|
736
1123
|
async removeCartCoupon() {
|
|
737
|
-
this.
|
|
738
|
-
const currentId = this.requestId;
|
|
739
|
-
const coupon = this.appliedCouponCode;
|
|
740
|
-
try {
|
|
741
|
-
this.quoteLoading = true;
|
|
742
|
-
this.appliedCouponCode = "";
|
|
743
|
-
await this.loadEventData();
|
|
744
|
-
if (this.selectedItems.size === 0) {
|
|
745
|
-
this.couponInput = "";
|
|
746
|
-
this.previewQuote = null;
|
|
747
|
-
this.trackCouponRemoved(coupon, null);
|
|
748
|
-
return;
|
|
749
|
-
}
|
|
750
|
-
const response = await this.fetchCartQuote("");
|
|
751
|
-
if (currentId !== this.requestId)
|
|
752
|
-
return;
|
|
753
|
-
this.couponInput = "";
|
|
754
|
-
this.appliedCouponCode = "";
|
|
755
|
-
this.previewQuote = null;
|
|
756
|
-
this.applyQuote(response.quote, currentId);
|
|
757
|
-
this.trackCouponRemoved(coupon, response.quote);
|
|
758
|
-
}
|
|
759
|
-
catch (_err) {
|
|
760
|
-
this.handleCouponError(currentId, "Failed to remove coupon. Please try again.");
|
|
761
|
-
}
|
|
762
|
-
finally {
|
|
763
|
-
if (currentId === this.requestId) {
|
|
764
|
-
this.quoteLoading = false;
|
|
765
|
-
}
|
|
766
|
-
}
|
|
1124
|
+
await this.applyCartCoupon("");
|
|
767
1125
|
}
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
1126
|
+
isCouponOperationCurrent(operationId, requestId) {
|
|
1127
|
+
return (this.active &&
|
|
1128
|
+
operationId === this.couponRequestId &&
|
|
1129
|
+
requestId === this.requestId);
|
|
1130
|
+
}
|
|
1131
|
+
isPreviewCouponOperationCurrent(operationId, requestId) {
|
|
1132
|
+
return (this.active &&
|
|
1133
|
+
operationId === this.couponRequestId &&
|
|
1134
|
+
requestId === this.previewRequestId);
|
|
772
1135
|
}
|
|
773
1136
|
setCouponError(message = "Failed to apply coupon. Please check the code.") {
|
|
774
1137
|
this.couponError = message;
|
|
@@ -785,8 +1148,8 @@ export class SessionsTicketing {
|
|
|
785
1148
|
this.trackEvent("Coupon Applied", {
|
|
786
1149
|
coupon,
|
|
787
1150
|
products: this.getProductsForQuote(quote),
|
|
788
|
-
total: quote ?
|
|
789
|
-
value: quote ?
|
|
1151
|
+
total: quote ? quoteAmount(quote, this.event?.currency) : 0,
|
|
1152
|
+
value: quote ? quoteAmount(quote, this.event?.currency) : 0,
|
|
790
1153
|
});
|
|
791
1154
|
}
|
|
792
1155
|
trackCouponDenied(coupon) {
|
|
@@ -803,8 +1166,8 @@ export class SessionsTicketing {
|
|
|
803
1166
|
this.trackEvent("Coupon Removed", {
|
|
804
1167
|
coupon,
|
|
805
1168
|
products: this.getProductsForQuote(quote),
|
|
806
|
-
total: quote ?
|
|
807
|
-
value: quote ?
|
|
1169
|
+
total: quote ? quoteAmount(quote, this.event?.currency) : 0,
|
|
1170
|
+
value: quote ? quoteAmount(quote, this.event?.currency) : 0,
|
|
808
1171
|
});
|
|
809
1172
|
}
|
|
810
1173
|
handlePasscodeInput = (e) => {
|
|
@@ -814,33 +1177,93 @@ export class SessionsTicketing {
|
|
|
814
1177
|
};
|
|
815
1178
|
async submitPasscode(e) {
|
|
816
1179
|
e.preventDefault();
|
|
817
|
-
|
|
818
|
-
|
|
1180
|
+
const passcode = this.passcodeInput.trim();
|
|
1181
|
+
this.activePasscode = passcode;
|
|
1182
|
+
const result = await this.loadEventData({ mode: "passcode", passcode });
|
|
1183
|
+
if (result.status !== "success")
|
|
1184
|
+
return;
|
|
1185
|
+
this.error = null;
|
|
1186
|
+
this.errorKind = null;
|
|
1187
|
+
this.handleLoadedEvent(result.event);
|
|
1188
|
+
await this.updatePreviewQuote();
|
|
1189
|
+
}
|
|
1190
|
+
async retryEventLoad() {
|
|
1191
|
+
if (!this.tenantId || !this.eventId) {
|
|
1192
|
+
await this.initializeComponent();
|
|
1193
|
+
return;
|
|
1194
|
+
}
|
|
1195
|
+
const result = await this.loadEventData({ mode: "retry" });
|
|
1196
|
+
if (result.status !== "success")
|
|
1197
|
+
return;
|
|
1198
|
+
this.handleLoadedEvent(result.event);
|
|
1199
|
+
await this.updatePreviewQuote();
|
|
819
1200
|
}
|
|
820
1201
|
async initiateCheckout() {
|
|
821
1202
|
if (this.isCheckoutDisabled())
|
|
822
1203
|
return;
|
|
823
|
-
|
|
1204
|
+
const quote = this.quote;
|
|
1205
|
+
if (!quote)
|
|
824
1206
|
return;
|
|
1207
|
+
const id = ++this.checkoutRequestId;
|
|
1208
|
+
const eventId = this.eventId;
|
|
1209
|
+
const coupon = this.appliedCouponCode;
|
|
1210
|
+
const revision = this.currentQuoteRevision();
|
|
1211
|
+
const controller = new AbortController();
|
|
1212
|
+
this.checkoutController?.abort();
|
|
1213
|
+
this.checkoutController = controller;
|
|
825
1214
|
try {
|
|
826
1215
|
this.checkoutLoading = true;
|
|
827
|
-
this.
|
|
828
|
-
const
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
1216
|
+
this.checkoutError = null;
|
|
1217
|
+
const idempotencyKey = await this.getCheckoutIdempotencyKey(revision);
|
|
1218
|
+
if (!this.isCheckoutRequestCurrent(id, eventId, coupon, revision))
|
|
1219
|
+
return;
|
|
1220
|
+
const result = await withTimeout(controller, (signal) => this.client.order.create({
|
|
1221
|
+
eventId,
|
|
1222
|
+
items: this.getCheckoutItems(quote),
|
|
1223
|
+
couponCode: coupon || undefined,
|
|
832
1224
|
returnUrl: this.returnUrl,
|
|
833
1225
|
channel: buildOrderChannel("elements"),
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
this.
|
|
1226
|
+
idempotencyKey,
|
|
1227
|
+
}, { signal }));
|
|
1228
|
+
if (!this.isCheckoutRequestCurrent(id, eventId, coupon, revision))
|
|
1229
|
+
return;
|
|
1230
|
+
this.trackCheckoutStarted(quote, result.order.id);
|
|
1231
|
+
this.handleCheckoutOrder(result.order, id);
|
|
837
1232
|
}
|
|
838
1233
|
catch (_err) {
|
|
839
|
-
this.
|
|
1234
|
+
if (this.isCheckoutRequestCurrent(id, eventId, coupon, revision)) {
|
|
1235
|
+
this.handleCheckoutError();
|
|
1236
|
+
}
|
|
840
1237
|
}
|
|
1238
|
+
finally {
|
|
1239
|
+
if (id === this.checkoutRequestId &&
|
|
1240
|
+
this.checkoutController === controller) {
|
|
1241
|
+
this.checkoutController = undefined;
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
async getCheckoutIdempotencyKey(revision) {
|
|
1246
|
+
const current = this.checkoutIdempotencyKeys.get(revision);
|
|
1247
|
+
if (current)
|
|
1248
|
+
return current;
|
|
1249
|
+
const name = await checkoutStorageName(`${this.apiUrl}\u0000${this.tenantId}\u0000${revision}`);
|
|
1250
|
+
const stored = storedCheckoutIdempotencyKey(name);
|
|
1251
|
+
const key = stored ?? createCheckoutIdempotencyKey();
|
|
1252
|
+
this.checkoutIdempotencyKeys.set(revision, key);
|
|
1253
|
+
if (!stored)
|
|
1254
|
+
storeCheckoutIdempotencyKey(name, key);
|
|
1255
|
+
return key;
|
|
1256
|
+
}
|
|
1257
|
+
isCheckoutRequestCurrent(id, eventId, coupon, revision) {
|
|
1258
|
+
return (this.active &&
|
|
1259
|
+
id === this.checkoutRequestId &&
|
|
1260
|
+
eventId === this.eventId &&
|
|
1261
|
+
coupon === this.appliedCouponCode &&
|
|
1262
|
+
revision === this.currentQuoteRevision() &&
|
|
1263
|
+
revision === this.quoteRevision);
|
|
841
1264
|
}
|
|
842
1265
|
trackCheckoutStarted(quote, orderId) {
|
|
843
|
-
const total =
|
|
1266
|
+
const total = quoteAmount(quote, this.event?.currency);
|
|
844
1267
|
this.trackEvent("Checkout Started", {
|
|
845
1268
|
order_id: orderId,
|
|
846
1269
|
value: total,
|
|
@@ -864,7 +1287,9 @@ export class SessionsTicketing {
|
|
|
864
1287
|
sectionId: item.sectionId,
|
|
865
1288
|
}));
|
|
866
1289
|
}
|
|
867
|
-
handleCheckoutOrder(order) {
|
|
1290
|
+
handleCheckoutOrder(order, requestId) {
|
|
1291
|
+
if (!this.active || requestId !== this.checkoutRequestId)
|
|
1292
|
+
return;
|
|
868
1293
|
this.checkoutInit.emit({
|
|
869
1294
|
orderId: order.id,
|
|
870
1295
|
checkoutUrl: order.checkoutUrl,
|
|
@@ -876,8 +1301,9 @@ export class SessionsTicketing {
|
|
|
876
1301
|
this.checkoutLoading = false;
|
|
877
1302
|
}
|
|
878
1303
|
handleCheckoutError() {
|
|
879
|
-
this.
|
|
880
|
-
|
|
1304
|
+
this.checkoutError =
|
|
1305
|
+
"We couldn’t open checkout. Your tickets are still selected, so you can try again.";
|
|
1306
|
+
this.errorOccurred.emit({ error: this.checkoutError });
|
|
881
1307
|
this.checkoutLoading = false;
|
|
882
1308
|
}
|
|
883
1309
|
handleStickyCheckoutClick(state) {
|
|
@@ -892,7 +1318,9 @@ export class SessionsTicketing {
|
|
|
892
1318
|
const target = this.host.shadowRoot?.querySelector(".tickets-wrapper") ??
|
|
893
1319
|
this.host;
|
|
894
1320
|
window.scrollTo({
|
|
895
|
-
behavior: "
|
|
1321
|
+
behavior: window.matchMedia?.("(prefers-reduced-motion: reduce)").matches === true
|
|
1322
|
+
? "auto"
|
|
1323
|
+
: "smooth",
|
|
896
1324
|
top: Math.max(target.getBoundingClientRect().top +
|
|
897
1325
|
window.scrollY -
|
|
898
1326
|
STICKY_CHECKOUT_SCROLL_OFFSET_PX, 0),
|
|
@@ -939,31 +1367,55 @@ export class SessionsTicketing {
|
|
|
939
1367
|
return this.event?.sections.find((section) => section.id === item.sectionId);
|
|
940
1368
|
}
|
|
941
1369
|
formatDateTimeRange(startDate, endDate) {
|
|
942
|
-
|
|
1370
|
+
const zone = this.event ? eventTimeZone(this.event) : "UTC";
|
|
1371
|
+
try {
|
|
1372
|
+
const start = parseNaiveDateTime(startDate, zone);
|
|
1373
|
+
const end = parseNaiveDateTime(endDate, zone);
|
|
1374
|
+
const day = this.dateFormatter({
|
|
1375
|
+
day: "numeric",
|
|
1376
|
+
month: "short",
|
|
1377
|
+
timeZone: zone,
|
|
1378
|
+
weekday: "short",
|
|
1379
|
+
}).format(start);
|
|
1380
|
+
const time = this.dateFormatter({
|
|
1381
|
+
hour: "numeric",
|
|
1382
|
+
minute: "2-digit",
|
|
1383
|
+
timeZone: zone,
|
|
1384
|
+
});
|
|
1385
|
+
return `${day} · ${time.format(start)} – ${time.format(end)}`;
|
|
1386
|
+
}
|
|
1387
|
+
catch {
|
|
1388
|
+
return `${startDate} – ${endDate}`;
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
dateFormatter(options) {
|
|
1392
|
+
try {
|
|
1393
|
+
return new Intl.DateTimeFormat(this.locale, options);
|
|
1394
|
+
}
|
|
1395
|
+
catch {
|
|
1396
|
+
return new Intl.DateTimeFormat("en-US", options);
|
|
1397
|
+
}
|
|
943
1398
|
}
|
|
944
|
-
formatPriceValue(
|
|
1399
|
+
formatPriceValue(priceInMinorUnits) {
|
|
945
1400
|
const currency = this.event?.currency;
|
|
946
1401
|
if (!currency) {
|
|
947
1402
|
return new Intl.NumberFormat(this.locale, {
|
|
948
1403
|
style: "decimal",
|
|
949
1404
|
minimumFractionDigits: 2,
|
|
950
1405
|
maximumFractionDigits: 2,
|
|
951
|
-
}).format(
|
|
1406
|
+
}).format(majorUnits(priceInMinorUnits));
|
|
952
1407
|
}
|
|
953
1408
|
try {
|
|
954
|
-
return formatPrice(priceInCents, currency);
|
|
955
|
-
}
|
|
956
|
-
catch (error) {
|
|
957
|
-
console.error("formatPrice failed, using fallback", {
|
|
958
|
-
error,
|
|
959
|
-
currency,
|
|
960
|
-
priceInCents,
|
|
961
|
-
locale: this.locale,
|
|
962
|
-
});
|
|
963
1409
|
return new Intl.NumberFormat(this.locale, {
|
|
964
1410
|
style: "currency",
|
|
965
1411
|
currency,
|
|
966
|
-
}).format(
|
|
1412
|
+
}).format(majorUnits(priceInMinorUnits, currency));
|
|
1413
|
+
}
|
|
1414
|
+
catch {
|
|
1415
|
+
return new Intl.NumberFormat("en-US", {
|
|
1416
|
+
style: "currency",
|
|
1417
|
+
currency,
|
|
1418
|
+
}).format(majorUnits(priceInMinorUnits, currency));
|
|
967
1419
|
}
|
|
968
1420
|
}
|
|
969
1421
|
handleQuantityDecrease = async (admissionId, sectionId) => {
|
|
@@ -979,16 +1431,47 @@ export class SessionsTicketing {
|
|
|
979
1431
|
};
|
|
980
1432
|
openModal = (admissionId, e) => {
|
|
981
1433
|
e.stopPropagation();
|
|
1434
|
+
this.modalTrigger = e.currentTarget;
|
|
1435
|
+
this.modalFocusPending = true;
|
|
982
1436
|
this.openModalAdmissionId = admissionId;
|
|
983
1437
|
document.addEventListener("keydown", this.handleModalKeyDown);
|
|
984
1438
|
};
|
|
985
1439
|
closeModal = () => {
|
|
986
1440
|
this.openModalAdmissionId = null;
|
|
987
|
-
|
|
1441
|
+
this.modalFocusPending = false;
|
|
1442
|
+
this.modalRestorePending = true;
|
|
1443
|
+
if (typeof document !== "undefined") {
|
|
1444
|
+
document.removeEventListener("keydown", this.handleModalKeyDown);
|
|
1445
|
+
}
|
|
988
1446
|
};
|
|
989
1447
|
handleModalKeyDown = (e) => {
|
|
990
1448
|
if (e.key === "Escape") {
|
|
1449
|
+
e.preventDefault();
|
|
991
1450
|
this.closeModal();
|
|
1451
|
+
return;
|
|
1452
|
+
}
|
|
1453
|
+
if (e.key !== "Tab")
|
|
1454
|
+
return;
|
|
1455
|
+
const dialog = this.host.shadowRoot?.querySelector(".modal-content");
|
|
1456
|
+
if (!dialog)
|
|
1457
|
+
return;
|
|
1458
|
+
const focusable = Array.from(dialog.querySelectorAll('button:not([disabled]), [href], input:not([disabled]), [tabindex]:not([tabindex="-1"])'));
|
|
1459
|
+
if (focusable.length === 0) {
|
|
1460
|
+
e.preventDefault();
|
|
1461
|
+
dialog.focus();
|
|
1462
|
+
return;
|
|
1463
|
+
}
|
|
1464
|
+
const first = focusable[0];
|
|
1465
|
+
const last = focusable.at(-1);
|
|
1466
|
+
const active = this.host.shadowRoot?.activeElement;
|
|
1467
|
+
if (e.shiftKey && active === first) {
|
|
1468
|
+
e.preventDefault();
|
|
1469
|
+
last?.focus();
|
|
1470
|
+
return;
|
|
1471
|
+
}
|
|
1472
|
+
if (!e.shiftKey && active === last) {
|
|
1473
|
+
e.preventDefault();
|
|
1474
|
+
first?.focus();
|
|
992
1475
|
}
|
|
993
1476
|
};
|
|
994
1477
|
handleBackdropClick = (e) => {
|
|
@@ -1008,6 +1491,7 @@ export class SessionsTicketing {
|
|
|
1008
1491
|
return getAdmissionDisplayState({
|
|
1009
1492
|
admission,
|
|
1010
1493
|
event: this.event,
|
|
1494
|
+
locale: this.locale,
|
|
1011
1495
|
section: this.getSection(sectionId),
|
|
1012
1496
|
}).maxQuantity;
|
|
1013
1497
|
}
|
|
@@ -1066,17 +1550,18 @@ export class SessionsTicketing {
|
|
|
1066
1550
|
}
|
|
1067
1551
|
if (mode === "door")
|
|
1068
1552
|
return null;
|
|
1069
|
-
return this.renderQuantityControls(admission, sectionId, state.disabled, state.maxQuantity);
|
|
1553
|
+
return this.renderQuantityControls(admission, sectionId, state.disabled || this.checkoutLoading, state.maxQuantity);
|
|
1070
1554
|
}
|
|
1071
1555
|
renderAdmission(admission, event, section, isSectionSoldOut = false, mode = "default") {
|
|
1072
1556
|
const state = getAdmissionDisplayState({
|
|
1073
1557
|
admission,
|
|
1074
1558
|
event,
|
|
1559
|
+
locale: this.locale,
|
|
1075
1560
|
section,
|
|
1076
1561
|
sectionSoldOut: isSectionSoldOut,
|
|
1077
1562
|
});
|
|
1078
1563
|
const sectionId = section?.id || null;
|
|
1079
|
-
return (h("section", { class: this.getAdmissionClassName(state, section), key: selectionKey(admission.id, sectionId),
|
|
1564
|
+
return (h("section", { class: this.getAdmissionClassName(state, section), key: selectionKey(admission.id, sectionId), "aria-label": this.getAdmissionAriaLabel(admission, section, state), "data-testid": "event-admission-card", "data-admission-id": admission.id, "data-admission-name": admission.name, "data-section-id": section?.id ?? "" }, h("div", { class: "admission-content" }, h("div", { class: "admission-details" }, this.renderAdmissionHeader(admission), this.renderAdmissionBody(admission, event, sectionId, state, mode)))));
|
|
1080
1565
|
}
|
|
1081
1566
|
getAdmissionClassName(state, section) {
|
|
1082
1567
|
return `admission-card ${state.soldOut ? "sold-out" : ""} ${state.disabled && !state.soldOut ? "unavailable" : ""} ${section ? "" : "solo-admission"}`;
|
|
@@ -1118,34 +1603,49 @@ export class SessionsTicketing {
|
|
|
1118
1603
|
return (h("div", { class: `ticket-section ${soldOut ? "section-sold-out" : ""}`, key: section.id }, this.renderSectionHeader(section, admissions), h("div", { class: "admissions-list" }, admissions.map((admission) => this.renderAdmission(admission, event, section, soldOut, mode)))));
|
|
1119
1604
|
}
|
|
1120
1605
|
renderLoadingState() {
|
|
1121
|
-
return (h(Host, { "data-theme": this.currentTheme }, h("div", { class: "session-services-ticketing-container" }, h("div", { class: "tickets-wrapper" }, h("h2", { class: "tickets-heading" }, "Get Tickets"), h("div", { class: "ticket-section loading-ticket-section" }, h("div", { class: "admissions-list" }, [0, 1, 2].map((item) => (h("div", { "aria-hidden": "true", class: "admission-card loading-admission", key: item })))))))));
|
|
1606
|
+
return (h(Host, { "data-theme": this.currentTheme }, h("div", { class: "session-services-ticketing-container", role: "status", "aria-live": "polite", "aria-label": "Loading ticket options" }, h("span", { class: "sr-only" }, "Loading ticket options"), h("div", { class: "tickets-wrapper" }, h("h2", { class: "tickets-heading" }, "Get Tickets"), h("div", { class: "ticket-section loading-ticket-section" }, h("div", { class: "admissions-list" }, [0, 1, 2].map((item) => (h("div", { "aria-hidden": "true", class: "admission-card loading-admission", key: item })))))))));
|
|
1122
1607
|
}
|
|
1123
1608
|
renderErrorState() {
|
|
1124
|
-
if (this.
|
|
1609
|
+
if (this.errorKind === "access")
|
|
1125
1610
|
return this.renderPasscodeState();
|
|
1126
|
-
|
|
1611
|
+
if (this.errorKind === "not_found")
|
|
1612
|
+
return this.renderNotFoundState();
|
|
1613
|
+
const configuration = this.errorKind === "configuration";
|
|
1614
|
+
return (h(Host, { "data-theme": this.currentTheme }, h("div", { class: "session-services-ticketing-container" }, h("div", { class: "message-state", role: "alert", "aria-live": "assertive" }, h("strong", null, configuration
|
|
1615
|
+
? "Ticket widget needs setup"
|
|
1616
|
+
: "Tickets didn’t load"), h("span", null, configuration
|
|
1617
|
+
? "This ticket widget is missing its event or tenant details."
|
|
1618
|
+
: "Something got in the way. Try again to load the ticket options."), !configuration && (h("button", { type: "button", class: "checkout-btn", onClick: () => this.retryEventLoad(), disabled: this.retryLoading }, this.retryLoading ? "Loading tickets…" : "Try again"))))));
|
|
1619
|
+
}
|
|
1620
|
+
renderUpdatingState() {
|
|
1621
|
+
return (h(Host, { "data-theme": this.currentTheme }, h("div", { class: "session-services-ticketing-container", role: "status", "aria-live": "polite" }, h("div", { class: "message-state" }, h("strong", null, "Loading ticket options\u2026"), h("span", null, "This should only take a moment.")))));
|
|
1622
|
+
}
|
|
1623
|
+
renderVerificationState() {
|
|
1624
|
+
return (h(Host, { "data-theme": this.currentTheme }, h("div", { class: "session-services-ticketing-container" }, h("section", { class: "message-state", "aria-labelledby": "ticket-verification-title", "aria-describedby": "ticket-verification-description" }, h("h2", { id: "ticket-verification-title" }, "Let\u2019s get your tickets"), h("p", { id: "ticket-verification-description" }, "We just need you to confirm before we load the ticket options."), h("button", { type: "button", class: "checkout-btn", onClick: this.continueAfterVerification }, "Load tickets")))));
|
|
1127
1625
|
}
|
|
1128
1626
|
renderPasscodeState() {
|
|
1129
|
-
return (h(Host, { "data-theme": this.currentTheme }, h("div", { class: "session-services-ticketing-container" }, h("form", { class: "passcode-form", onSubmit: (e) => this.submitPasscode(e) }, h("h2", null, "Enter passcode"), h("p", null, "Enter the event passcode to view tickets and event details."), h("input", { type: "text", name: "passcode", value: this.passcodeInput, onInput: this.handlePasscodeInput, autocomplete: "one-time-code", placeholder: "Passcode", "aria-label": "Passcode" }), this.passcodeDenied && this.activePasscode && (h("span", { class: "error-message" }, "
|
|
1627
|
+
return (h(Host, { "data-theme": this.currentTheme }, h("div", { class: "session-services-ticketing-container" }, h("form", { class: "passcode-form", onSubmit: (e) => this.submitPasscode(e) }, h("h2", null, "Enter passcode"), h("p", null, "Enter the event passcode to view tickets and event details."), h("input", { type: "text", name: "passcode", value: this.passcodeInput, onInput: this.handlePasscodeInput, autocomplete: "one-time-code", placeholder: "Passcode", "aria-label": "Passcode", "aria-invalid": this.passcodeDenied, "aria-describedby": this.passcodeDenied ? "ticket-passcode-error" : undefined, disabled: this.passcodeLoading }), this.passcodeDenied && this.activePasscode && (h("span", { id: "ticket-passcode-error", class: "error-message", role: "alert", "aria-live": "assertive" }, "That passcode didn\u2019t work. Check it and try again.")), h("button", { type: "submit", class: "checkout-btn", disabled: !this.passcodeInput.trim() || this.passcodeLoading }, this.passcodeLoading ? "Unlocking…" : "Unlock event")))));
|
|
1130
1628
|
}
|
|
1131
1629
|
renderNotFoundState() {
|
|
1132
|
-
return (h(Host, { "data-theme": this.currentTheme }, h("div", { class: "session-services-ticketing-container" }, h("div", { class: "message-state" }, h("strong", null, "Event not found"), h("span", null, "We couldn\u2019t find this event. The link may be incorrect or expired.")))));
|
|
1630
|
+
return (h(Host, { "data-theme": this.currentTheme }, h("div", { class: "session-services-ticketing-container" }, h("div", { class: "message-state", role: "alert" }, h("strong", null, "Event not found"), h("span", null, "We couldn\u2019t find this event. The link may be incorrect or expired.")))));
|
|
1133
1631
|
}
|
|
1134
1632
|
renderCouponPanel() {
|
|
1135
1633
|
const hasInput = this.couponInput.trim().length > 0;
|
|
1136
1634
|
const busy = this.quoteLoading || this.previewLoading || this.checkoutLoading;
|
|
1137
1635
|
const canApply = hasInput && !busy;
|
|
1138
|
-
return (h("div", { class: "coupon-panel" }, h("div", { class: "coupon-row" }, h("input", { id: "coupon-code", name: "coupon-code", placeholder: "Coupon Code", value: this.couponInput, onInput: this.handleCouponInput, onKeyDown: this.handleCouponKeyDown, autocomplete: "off", disabled: busy, "aria-label": "Coupon code", "aria-invalid": Boolean(this.couponError) }), this.appliedCouponCode ? (h("button", { type: "button", class: "coupon-remove", onClick: () => this.removeCoupon(), disabled: busy, "aria-label": "Remove coupon" }, "Remove")) : (h("button", { type: "button", class: "
|
|
1636
|
+
return (h("div", { class: "coupon-panel" }, h("div", { class: "coupon-row" }, h("input", { id: "coupon-code", name: "coupon-code", placeholder: "Coupon Code", value: this.appliedCouponCode || this.couponInput, onInput: this.handleCouponInput, onKeyDown: this.handleCouponKeyDown, autocomplete: "off", disabled: busy || Boolean(this.appliedCouponCode), "aria-label": "Coupon code", "aria-invalid": Boolean(this.couponError), "aria-describedby": this.couponError ? "coupon-error" : undefined }), this.appliedCouponCode ? (h("button", { type: "button", class: "coupon-remove", onClick: () => this.removeCoupon(), disabled: busy, "aria-label": "Remove coupon" }, "Remove")) : (h("button", { type: "button", class: "inline-retry-btn", onClick: () => this.applyCoupon(), disabled: !canApply }, "Apply"))), this.couponError && (h("span", { id: "coupon-error", class: "error-message", role: "alert", "aria-live": "assertive" }, this.couponError))));
|
|
1139
1637
|
}
|
|
1140
1638
|
isCheckoutDisabled() {
|
|
1141
1639
|
return (this.quoteLoading ||
|
|
1142
1640
|
this.checkoutLoading ||
|
|
1143
|
-
|
|
1144
|
-
|
|
1641
|
+
!hasQuoteItems(this.quote) ||
|
|
1642
|
+
this.quoteRevision !== this.currentQuoteRevision());
|
|
1145
1643
|
}
|
|
1146
1644
|
getCheckoutButtonText() {
|
|
1147
1645
|
if (this.checkoutLoading)
|
|
1148
1646
|
return "Processing...";
|
|
1647
|
+
if (this.checkoutError)
|
|
1648
|
+
return "Try checkout again";
|
|
1149
1649
|
if (this.quote)
|
|
1150
1650
|
return this.getQuoteCheckoutText();
|
|
1151
1651
|
return "Pay";
|
|
@@ -1202,22 +1702,26 @@ export class SessionsTicketing {
|
|
|
1202
1702
|
return this.formatPriceValue(total);
|
|
1203
1703
|
}
|
|
1204
1704
|
renderCheckoutActions() {
|
|
1205
|
-
return (h("div", { class: "checkout-actions" }, this.renderCouponPanel(), this.quoteError && h("div", { class: "error-message" }, this.quoteError), h("button", { type: "button", class: "checkout-btn", onClick: () => this.initiateCheckout(), disabled: this.isCheckoutDisabled(), "aria-label": this.quoteLoading ? "Updating" : undefined, "data-testid": "event-checkout-cta-desktop" }, this.renderCheckoutButtonContent())));
|
|
1705
|
+
return (h("div", { class: "checkout-actions" }, this.renderCouponPanel(), this.quoteError && (h("div", { class: "error-message", role: "alert", "aria-live": "assertive" }, this.quoteError, h("button", { type: "button", class: "coupon-apply", onClick: () => this.updateQuote(), disabled: this.quoteLoading }, "Try again"))), this.checkoutError && (h("div", { class: "error-message", role: "alert", "aria-live": "assertive" }, this.checkoutError)), h("button", { type: "button", class: "checkout-btn", onClick: () => this.initiateCheckout(), disabled: this.isCheckoutDisabled(), "aria-label": this.quoteLoading ? "Updating" : undefined, "data-testid": "event-checkout-cta-desktop" }, this.renderCheckoutButtonContent())));
|
|
1206
1706
|
}
|
|
1207
1707
|
renderStickyCheckout(state) {
|
|
1208
1708
|
if (!this.stickyCheckout)
|
|
1209
1709
|
return null;
|
|
1210
1710
|
if (!state.showTicketing)
|
|
1211
1711
|
return null;
|
|
1712
|
+
if (state.isDoorOnly) {
|
|
1713
|
+
return (h("div", { class: "sticky-checkout-bar" }, h("div", { class: "sticky-door-info" }, h("strong", null, "Tickets available at the door"), h("span", null, "Buy yours at the venue when you arrive."))));
|
|
1714
|
+
}
|
|
1212
1715
|
return (h("div", { class: "sticky-checkout-bar" }, h("button", { type: "button", class: `checkout-btn sticky-checkout-btn ${this.selectionPrompt ? "selection-prompt" : ""}`, onClick: () => this.handleStickyCheckoutClick(state), disabled: this.isStickyCheckoutDisabled(state), "aria-label": this.quoteLoading ? "Updating" : undefined }, this.renderStickyCheckoutButtonContent(state))));
|
|
1213
1716
|
}
|
|
1214
1717
|
renderStickyExternalTicketing(state) {
|
|
1215
1718
|
if (!this.stickyCheckout)
|
|
1216
1719
|
return null;
|
|
1217
|
-
|
|
1720
|
+
const url = state.externalTicketUrl;
|
|
1721
|
+
if (!url)
|
|
1218
1722
|
return null;
|
|
1219
|
-
const domain = urlDomain(
|
|
1220
|
-
return (h("div", { class: "sticky-checkout-bar" }, h("a", { class: "external-ticket-button sticky-checkout-btn", href:
|
|
1723
|
+
const domain = urlDomain(url);
|
|
1724
|
+
return (h("div", { class: "sticky-checkout-bar" }, h("a", { class: "external-ticket-button sticky-checkout-btn", href: url, target: "_blank", rel: "noreferrer", onClick: () => this.trackExternalTicketClick(url, "sticky") }, h("span", { class: "external-ticket-label" }, "Get tickets"), h("span", { class: "external-ticket-domain" }, "via ", domain))));
|
|
1221
1725
|
}
|
|
1222
1726
|
renderModal() {
|
|
1223
1727
|
if (!this.openModalAdmissionId)
|
|
@@ -1227,7 +1731,7 @@ export class SessionsTicketing {
|
|
|
1227
1731
|
return null;
|
|
1228
1732
|
return (
|
|
1229
1733
|
// biome-ignore lint/a11y/noStaticElementInteractions lint/a11y/useKeyWithClickEvents: backdrop click-to-close is a common modal pattern, keyboard handled via Escape key
|
|
1230
|
-
h("div", { class: "modal-backdrop", onClick: this.handleBackdropClick }, h("div", { class: "modal-content", role: "dialog", "aria-modal": "true", "aria-labelledby": "modal-title" }, h("button", { type: "button", class: "modal-close-btn", onClick: () => this.closeModal(), "aria-label": "Close" }, CloseIcon()), h("div", { class: "modal-header" }, h("h2", { id: "modal-title", class: "modal-title" }, admission.name), admission.subtitle && (h("p", { class: "modal-subtitle" }, admission.subtitle))), h("p", { class: "modal-description" }, admission.description))));
|
|
1734
|
+
h("div", { class: "modal-backdrop", onClick: this.handleBackdropClick }, h("div", { class: "modal-content", role: "dialog", "aria-modal": "true", "aria-labelledby": "modal-title", "aria-describedby": "modal-description", tabindex: "-1" }, h("button", { type: "button", class: "modal-close-btn", onClick: () => this.closeModal(), "aria-label": "Close" }, CloseIcon()), h("div", { class: "modal-header" }, h("h2", { id: "modal-title", class: "modal-title" }, admission.name), admission.subtitle && (h("p", { class: "modal-subtitle" }, admission.subtitle))), h("p", { id: "modal-description", class: "modal-description" }, admission.description))));
|
|
1231
1735
|
}
|
|
1232
1736
|
renderTicketSections(event) {
|
|
1233
1737
|
const state = getTicketingState(event);
|
|
@@ -1254,16 +1758,28 @@ export class SessionsTicketing {
|
|
|
1254
1758
|
return (h("div", { class: "door-alert" }, h("strong", null, "Tickets are available at ", location), h("span", null, "Online sales are closed. Tickets are available at the venue when you arrive.")));
|
|
1255
1759
|
}
|
|
1256
1760
|
loadingView() {
|
|
1257
|
-
return this.
|
|
1761
|
+
return this.initialLoading ? this.renderLoadingState() : undefined;
|
|
1258
1762
|
}
|
|
1259
1763
|
errorView() {
|
|
1260
1764
|
return this.error && !this.event ? this.renderErrorState() : undefined;
|
|
1261
1765
|
}
|
|
1766
|
+
verificationView() {
|
|
1767
|
+
return this.verificationRequired
|
|
1768
|
+
? this.renderVerificationState()
|
|
1769
|
+
: undefined;
|
|
1770
|
+
}
|
|
1262
1771
|
missingEventView() {
|
|
1263
|
-
|
|
1772
|
+
if (this.event)
|
|
1773
|
+
return undefined;
|
|
1774
|
+
if (this.eventLoading || this.retryLoading)
|
|
1775
|
+
return this.renderUpdatingState();
|
|
1776
|
+
return this.renderNotFoundState();
|
|
1264
1777
|
}
|
|
1265
1778
|
pendingView() {
|
|
1266
|
-
return this.loadingView() ??
|
|
1779
|
+
return (this.loadingView() ??
|
|
1780
|
+
this.verificationView() ??
|
|
1781
|
+
this.errorView() ??
|
|
1782
|
+
this.missingEventView());
|
|
1267
1783
|
}
|
|
1268
1784
|
renderReadyState() {
|
|
1269
1785
|
const event = this.event;
|
|
@@ -1271,19 +1787,22 @@ export class SessionsTicketing {
|
|
|
1271
1787
|
return this.renderNotFoundState();
|
|
1272
1788
|
const state = getTicketingState(event);
|
|
1273
1789
|
if (state.showExternalTicketing) {
|
|
1274
|
-
return (h(Host, { "data-theme": this.currentTheme, "data-sticky-checkout": this.stickyCheckout ? "true" : undefined }, h("div", { class: "session-services-ticketing-container" }, this.renderExternalTicketing(state)), this.renderStickyExternalTicketing(state)));
|
|
1790
|
+
return (h(Host, { "data-theme": this.currentTheme, "data-sticky-checkout": this.stickyCheckout ? "true" : undefined }, h("div", { class: "session-services-ticketing-container", "aria-busy": this.eventLoading ? "true" : "false" }, this.renderExternalTicketing(state)), this.renderStickyExternalTicketing(state)));
|
|
1275
1791
|
}
|
|
1276
|
-
return (h(Host, { "data-theme": this.currentTheme, "data-sticky-checkout": this.stickyCheckout ? "true" : undefined }, h("div", { class: "session-services-ticketing-container"
|
|
1792
|
+
return (h(Host, { "data-theme": this.currentTheme, "data-sticky-checkout": this.stickyCheckout ? "true" : undefined }, h("div", { class: "session-services-ticketing-container", "aria-busy": this.eventLoading || this.retryLoading || this.passcodeLoading
|
|
1793
|
+
? "true"
|
|
1794
|
+
: "false", "aria-hidden": this.openModalAdmissionId ? "true" : undefined, inert: this.openModalAdmissionId ? true : undefined }, this.eventLoading && (h("div", { class: "inline-status", role: "status", "aria-live": "polite" }, "Updating ticket options\u2026")), this.refreshError && (h("div", { class: "error-message", role: "alert", "aria-live": "assertive" }, h("span", null, "We couldn\u2019t refresh the latest ticket details."), h("button", { type: "button", class: "inline-retry-btn", onClick: () => this.retryEventLoad(), disabled: this.retryLoading }, this.retryLoading ? "Refreshing…" : "Try again"))), state.showTicketing
|
|
1277
1795
|
? this.renderTicketSections(event)
|
|
1278
1796
|
: this.renderUnavailableState(state), !state.isDoorOnly &&
|
|
1279
1797
|
state.showTicketing &&
|
|
1280
1798
|
this.renderCheckoutActions()), this.renderStickyCheckout(state), this.renderModal()));
|
|
1281
1799
|
}
|
|
1282
1800
|
renderExternalTicketing(state) {
|
|
1283
|
-
const
|
|
1284
|
-
if (!
|
|
1801
|
+
const url = state.externalTicketUrl;
|
|
1802
|
+
if (!url)
|
|
1285
1803
|
return null;
|
|
1286
|
-
|
|
1804
|
+
const domain = urlDomain(url);
|
|
1805
|
+
return (h("div", { class: "tickets-wrapper" }, h("h2", { class: "tickets-heading" }, state.ticketHeading), h("div", { class: "external-ticket-panel" }, h("p", { class: "external-ticket-warning" }, "This event sells through an external ticketing site. Checkout, tickets, and support are handled there."), h("a", { class: "external-ticket-button inline-external-ticket-button", href: url, target: "_blank", rel: "noreferrer", onClick: () => this.trackExternalTicketClick(url, "inline") }, h("span", { class: "external-ticket-label" }, "Get tickets"), h("span", { class: "external-ticket-domain" }, "via ", domain)))));
|
|
1287
1806
|
}
|
|
1288
1807
|
renderUnavailableState(state) {
|
|
1289
1808
|
return (h("div", { class: "empty-ticketing-state" }, h("strong", null, "Tickets Unavailable"), h("span", null, state.isEnded
|
|
@@ -1428,7 +1947,7 @@ export class SessionsTicketing {
|
|
|
1428
1947
|
"mutable": false,
|
|
1429
1948
|
"complexType": {
|
|
1430
1949
|
"original": "| Record<string, { discount: number; gross: number; total: number }>\n | string",
|
|
1431
|
-
"resolved": "string | {
|
|
1950
|
+
"resolved": "string | { discount: number; gross: number; total: number; }",
|
|
1432
1951
|
"references": {
|
|
1433
1952
|
"Record": {
|
|
1434
1953
|
"location": "global",
|
|
@@ -1452,12 +1971,13 @@ export class SessionsTicketing {
|
|
|
1452
1971
|
"mutable": false,
|
|
1453
1972
|
"complexType": {
|
|
1454
1973
|
"original": "OrderQuote | string",
|
|
1455
|
-
"resolved": "string | { items: { id: string; kind: \"ADMISSION\" | \"ADDON\"; quantity: number; price: { net: number; total: number; gross: number; base: number; booking: number; refunded: number; discount: number; currency: \"AUD\" | \"AED\" | \"ALL\" | \"AMD\" | \"ANG\" | \"AOA\" | \"ARS\" | \"AWG\" | \"AZN\" | \"BAM\" | \"BBD\" | \"BDT\" | \"BGN\" | \"BHD\" | \"BIF\" | \"BMD\" | \"BND\" | \"BOB\" | \"BRL\" | \"BSD\" | \"BTN\" | \"BWP\" | \"BZD\" | \"CAD\" | \"CHF\" | \"CLP\" | \"CNY\" | \"COP\" | \"CRC\" | \"CVE\" | \"CZK\" | \"DJF\" | \"DKK\" | \"DOP\" | \"DZD\" | \"EGP\" | \"ERN\" | \"ETB\" | \"EUR\" | \"FJD\" | \"FKP\" | \"GBP\" | \"GEL\" | \"GHS\" | \"GIP\" | \"GMD\" | \"GNF\" | \"GTQ\" | \"GYD\" | \"HKD\" | \"HNL\" | \"HUF\" | \"IDR\" | \"ILS\" | \"INR\" | \"ISK\" | \"JMD\" | \"JOD\" | \"JPY\" | \"KES\" | \"KGS\" | \"KHR\" | \"KMF\" | \"KRW\" | \"KWD\" | \"KYD\" | \"KZT\" | \"LAK\" | \"LBP\" | \"LKR\" | \"LRD\" | \"LSL\" | \"LYD\" | \"MAD\" | \"MDL\" | \"MGA\" | \"MKD\" | \"MNT\" | \"MOP\" | \"MUR\" | \"MVR\" | \"MWK\" | \"MXN\" | \"MYR\" | \"NAD\" | \"NGN\" | \"NIO\" | \"NOK\" | \"NPR\" | \"NZD\" | \"OMR\" | \"PAB\" | \"PEN\" | \"PGK\" | \"PHP\" | \"PKR\" | \"PLN\" | \"PYG\" | \"QAR\" | \"RON\" | \"RSD\" | \"RWF\" | \"SAR\" | \"SBD\" | \"SCR\" | \"SEK\" | \"SGD\" | \"SHP\" | \"SLE\" | \"SRD\" | \"SVC\" | \"SZL\" | \"THB\" | \"TJS\" | \"TMT\" | \"TND\" | \"TOP\" | \"TRY\" | \"TTD\" | \"TWD\" | \"TZS\" | \"UAH\" | \"UGX\" | \"USD\" | \"UYU\" | \"UZS\" | \"VND\" | \"VUV\" | \"WST\" | \"XAF\" | \"XCD\" | \"XOF\" | \"XPF\" | \"ZAR\" | \"ZMW\" | \"ZWL\"; }; admissionId?: string; sectionId?: string; admission?: { name: string; capacity: number; limit: number; order: number; entryStartsAt: string; entryEndsAt: string; saleStartsAt: string; saleEndsAt: string; saleEndsBehavior: \"SALE_ENDED\" | \"SOLD_OUT\" | \"DOOR\"; price: { base: number; booking: number; currency: \"AUD\" | \"AED\" | \"ALL\" | \"AMD\" | \"ANG\" | \"AOA\" | \"ARS\" | \"AWG\" | \"AZN\" | \"BAM\" | \"BBD\" | \"BDT\" | \"BGN\" | \"BHD\" | \"BIF\" | \"BMD\" | \"BND\" | \"BOB\" | \"BRL\" | \"BSD\" | \"BTN\" | \"BWP\" | \"BZD\" | \"CAD\" | \"CHF\" | \"CLP\" | \"CNY\" | \"COP\" | \"CRC\" | \"CVE\" | \"CZK\" | \"DJF\" | \"DKK\" | \"DOP\" | \"DZD\" | \"EGP\" | \"ERN\" | \"ETB\" | \"EUR\" | \"FJD\" | \"FKP\" | \"GBP\" | \"GEL\" | \"GHS\" | \"GIP\" | \"GMD\" | \"GNF\" | \"GTQ\" | \"GYD\" | \"HKD\" | \"HNL\" | \"HUF\" | \"IDR\" | \"ILS\" | \"INR\" | \"ISK\" | \"JMD\" | \"JOD\" | \"JPY\" | \"KES\" | \"KGS\" | \"KHR\" | \"KMF\" | \"KRW\" | \"KWD\" | \"KYD\" | \"KZT\" | \"LAK\" | \"LBP\" | \"LKR\" | \"LRD\" | \"LSL\" | \"LYD\" | \"MAD\" | \"MDL\" | \"MGA\" | \"MKD\" | \"MNT\" | \"MOP\" | \"MUR\" | \"MVR\" | \"MWK\" | \"MXN\" | \"MYR\" | \"NAD\" | \"NGN\" | \"NIO\" | \"NOK\" | \"NPR\" | \"NZD\" | \"OMR\" | \"PAB\" | \"PEN\" | \"PGK\" | \"PHP\" | \"PKR\" | \"PLN\" | \"PYG\" | \"QAR\" | \"RON\" | \"RSD\" | \"RWF\" | \"SAR\" | \"SBD\" | \"SCR\" | \"SEK\" | \"SGD\" | \"SHP\" | \"SLE\" | \"SRD\" | \"SVC\" | \"SZL\" | \"THB\" | \"TJS\" | \"TMT\" | \"TND\" | \"TOP\" | \"TRY\" | \"TTD\" | \"TWD\" | \"TZS\" | \"UAH\" | \"UGX\" | \"USD\" | \"UYU\" | \"UZS\" | \"VND\" | \"VUV\" | \"WST\" | \"XAF\" | \"XCD\" | \"XOF\" | \"XPF\" | \"ZAR\" | \"ZMW\" | \"ZWL\"; }; visibility: \"ALWAYS\" | \"HIDDEN\"; teamId: string; promoterId: string; eventId: string; eventSlug: string; id?: string; subtitle?: string; description?: string; available?: number; sold?: number; reserved?: number; createdAt?: string; updatedAt?: string; sectionId?: string; }; section?: { name: string; capacity: number; limit: number; order: number; visibility: \"ALWAYS\" | \"HIDDEN\" | \"STACKED\"; location: { createdAt: string; updatedAt: string; name: string; address: string; country: string; latitude: number; longitude: number; timeZone: string; id?: string; googlePlaceId?: string; city?: string; state?: string; postcode?: string; types?: string[]; description?: string; image?: { src: string; alt: string; width: number; height: number; }; venueId?: string; }; teamId: string; promoterId: string; eventId: string; eventSlug: string; id?: string; createdAt?: string; updatedAt?: string; available?: number; sold?: number; reserved?: number; }; }[]; price: { net: number; total: number; gross: number; base: number; booking: number; shipping: number; sms: number; refunded: number; discount: number; gateway: number; dispute: number; currency: \"AUD\" | \"AED\" | \"ALL\" | \"AMD\" | \"ANG\" | \"AOA\" | \"ARS\" | \"AWG\" | \"AZN\" | \"BAM\" | \"BBD\" | \"BDT\" | \"BGN\" | \"BHD\" | \"BIF\" | \"BMD\" | \"BND\" | \"BOB\" | \"BRL\" | \"BSD\" | \"BTN\" | \"BWP\" | \"BZD\" | \"CAD\" | \"CHF\" | \"CLP\" | \"CNY\" | \"COP\" | \"CRC\" | \"CVE\" | \"CZK\" | \"DJF\" | \"DKK\" | \"DOP\" | \"DZD\" | \"EGP\" | \"ERN\" | \"ETB\" | \"EUR\" | \"FJD\" | \"FKP\" | \"GBP\" | \"GEL\" | \"GHS\" | \"GIP\" | \"GMD\" | \"GNF\" | \"GTQ\" | \"GYD\" | \"HKD\" | \"HNL\" | \"HUF\" | \"IDR\" | \"ILS\" | \"INR\" | \"ISK\" | \"JMD\" | \"JOD\" | \"JPY\" | \"KES\" | \"KGS\" | \"KHR\" | \"KMF\" | \"KRW\" | \"KWD\" | \"KYD\" | \"KZT\" | \"LAK\" | \"LBP\" | \"LKR\" | \"LRD\" | \"LSL\" | \"LYD\" | \"MAD\" | \"MDL\" | \"MGA\" | \"MKD\" | \"MNT\" | \"MOP\" | \"MUR\" | \"MVR\" | \"MWK\" | \"MXN\" | \"MYR\" | \"NAD\" | \"NGN\" | \"NIO\" | \"NOK\" | \"NPR\" | \"NZD\" | \"OMR\" | \"PAB\" | \"PEN\" | \"PGK\" | \"PHP\" | \"PKR\" | \"PLN\" | \"PYG\" | \"QAR\" | \"RON\" | \"RSD\" | \"RWF\" | \"SAR\" | \"SBD\" | \"SCR\" | \"SEK\" | \"SGD\" | \"SHP\" | \"SLE\" | \"SRD\" | \"SVC\" | \"SZL\" | \"THB\" | \"TJS\" | \"TMT\" | \"TND\" | \"TOP\" | \"TRY\" | \"TTD\" | \"TWD\" | \"TZS\" | \"UAH\" | \"UGX\" | \"USD\" | \"UYU\" | \"UZS\" | \"VND\" | \"VUV\" | \"WST\" | \"XAF\" | \"XCD\" | \"XOF\" | \"XPF\" | \"ZAR\" | \"ZMW\" | \"ZWL\"; }; couponCode?: { name: string; active: boolean; couponId: string; teamId: string; id?: string; createdAt?: string; updatedAt?: string; uses?: number; }; }",
|
|
1974
|
+
"resolved": "string | { items: { id: string; kind: \"ADMISSION\" | \"ADDON\"; quantity: number; price: { net: number; total: number; gross: number; base: number; booking: number; refunded: number; discount: number; currency: \"AUD\" | \"AED\" | \"ALL\" | \"AMD\" | \"ANG\" | \"AOA\" | \"ARS\" | \"AWG\" | \"AZN\" | \"BAM\" | \"BBD\" | \"BDT\" | \"BGN\" | \"BHD\" | \"BIF\" | \"BMD\" | \"BND\" | \"BOB\" | \"BRL\" | \"BSD\" | \"BTN\" | \"BWP\" | \"BZD\" | \"CAD\" | \"CHF\" | \"CLP\" | \"CNY\" | \"COP\" | \"CRC\" | \"CVE\" | \"CZK\" | \"DJF\" | \"DKK\" | \"DOP\" | \"DZD\" | \"EGP\" | \"ERN\" | \"ETB\" | \"EUR\" | \"FJD\" | \"FKP\" | \"GBP\" | \"GEL\" | \"GHS\" | \"GIP\" | \"GMD\" | \"GNF\" | \"GTQ\" | \"GYD\" | \"HKD\" | \"HNL\" | \"HUF\" | \"IDR\" | \"ILS\" | \"INR\" | \"ISK\" | \"JMD\" | \"JOD\" | \"JPY\" | \"KES\" | \"KGS\" | \"KHR\" | \"KMF\" | \"KRW\" | \"KWD\" | \"KYD\" | \"KZT\" | \"LAK\" | \"LBP\" | \"LKR\" | \"LRD\" | \"LSL\" | \"LYD\" | \"MAD\" | \"MDL\" | \"MGA\" | \"MKD\" | \"MNT\" | \"MOP\" | \"MUR\" | \"MVR\" | \"MWK\" | \"MXN\" | \"MYR\" | \"NAD\" | \"NGN\" | \"NIO\" | \"NOK\" | \"NPR\" | \"NZD\" | \"OMR\" | \"PAB\" | \"PEN\" | \"PGK\" | \"PHP\" | \"PKR\" | \"PLN\" | \"PYG\" | \"QAR\" | \"RON\" | \"RSD\" | \"RWF\" | \"SAR\" | \"SBD\" | \"SCR\" | \"SEK\" | \"SGD\" | \"SHP\" | \"SLE\" | \"SRD\" | \"SVC\" | \"SZL\" | \"THB\" | \"TJS\" | \"TMT\" | \"TND\" | \"TOP\" | \"TRY\" | \"TTD\" | \"TWD\" | \"TZS\" | \"UAH\" | \"UGX\" | \"USD\" | \"UYU\" | \"UZS\" | \"VND\" | \"VUV\" | \"WST\" | \"XAF\" | \"XCD\" | \"XOF\" | \"XPF\" | \"ZAR\" | \"ZMW\" | \"ZWL\"; }; admissionId?: string; sectionId?: string; admission?: { name: string; capacity: number; limit: number; order: number; entryStartsAt: string; entryEndsAt: string; saleStartsAt: string; saleEndsAt: string; saleEndsBehavior: \"SALE_ENDED\" | \"SOLD_OUT\" | \"DOOR\"; price: { base: number; booking: number; currency: \"AUD\" | \"AED\" | \"ALL\" | \"AMD\" | \"ANG\" | \"AOA\" | \"ARS\" | \"AWG\" | \"AZN\" | \"BAM\" | \"BBD\" | \"BDT\" | \"BGN\" | \"BHD\" | \"BIF\" | \"BMD\" | \"BND\" | \"BOB\" | \"BRL\" | \"BSD\" | \"BTN\" | \"BWP\" | \"BZD\" | \"CAD\" | \"CHF\" | \"CLP\" | \"CNY\" | \"COP\" | \"CRC\" | \"CVE\" | \"CZK\" | \"DJF\" | \"DKK\" | \"DOP\" | \"DZD\" | \"EGP\" | \"ERN\" | \"ETB\" | \"EUR\" | \"FJD\" | \"FKP\" | \"GBP\" | \"GEL\" | \"GHS\" | \"GIP\" | \"GMD\" | \"GNF\" | \"GTQ\" | \"GYD\" | \"HKD\" | \"HNL\" | \"HUF\" | \"IDR\" | \"ILS\" | \"INR\" | \"ISK\" | \"JMD\" | \"JOD\" | \"JPY\" | \"KES\" | \"KGS\" | \"KHR\" | \"KMF\" | \"KRW\" | \"KWD\" | \"KYD\" | \"KZT\" | \"LAK\" | \"LBP\" | \"LKR\" | \"LRD\" | \"LSL\" | \"LYD\" | \"MAD\" | \"MDL\" | \"MGA\" | \"MKD\" | \"MNT\" | \"MOP\" | \"MUR\" | \"MVR\" | \"MWK\" | \"MXN\" | \"MYR\" | \"NAD\" | \"NGN\" | \"NIO\" | \"NOK\" | \"NPR\" | \"NZD\" | \"OMR\" | \"PAB\" | \"PEN\" | \"PGK\" | \"PHP\" | \"PKR\" | \"PLN\" | \"PYG\" | \"QAR\" | \"RON\" | \"RSD\" | \"RWF\" | \"SAR\" | \"SBD\" | \"SCR\" | \"SEK\" | \"SGD\" | \"SHP\" | \"SLE\" | \"SRD\" | \"SVC\" | \"SZL\" | \"THB\" | \"TJS\" | \"TMT\" | \"TND\" | \"TOP\" | \"TRY\" | \"TTD\" | \"TWD\" | \"TZS\" | \"UAH\" | \"UGX\" | \"USD\" | \"UYU\" | \"UZS\" | \"VND\" | \"VUV\" | \"WST\" | \"XAF\" | \"XCD\" | \"XOF\" | \"XPF\" | \"ZAR\" | \"ZMW\" | \"ZWL\"; override?: { booking: number; }; }; visibility: \"ALWAYS\" | \"HIDDEN\" | \"AFTER_ADMISSION\"; teamId: string; promoterId: string; eventId: string; eventSlug: string; id?: string; subtitle?: string; description?: string; available?: number; sold?: number; reserved?: number; createdAt?: string; updatedAt?: string; visibleAfterAdmissionId?: string; sectionId?: string; }; section?: { name: string; capacity: number; limit: number; order: number; visibility: \"ALWAYS\" | \"HIDDEN\" | \"STACKED\"; location: { createdAt: string; updatedAt: string; name: string; address: string; country: string; latitude: number; longitude: number; timeZone: string; id?: string; googlePlaceId?: string; city?: string; state?: string; postcode?: string; types?: string[]; description?: string; image?: { src: string; alt: string; width: number; height: number; }; venueId?: string; }; teamId: string; promoterId: string; eventId: string; eventSlug: string; id?: string; createdAt?: string; updatedAt?: string; available?: number; sold?: number; reserved?: number; }; }[]; price: { net: number; total: number; gross: number; base: number; booking: number; shipping: number; sms: number; refunded: number; discount: number; gateway: number; dispute: number; currency: \"AUD\" | \"AED\" | \"ALL\" | \"AMD\" | \"ANG\" | \"AOA\" | \"ARS\" | \"AWG\" | \"AZN\" | \"BAM\" | \"BBD\" | \"BDT\" | \"BGN\" | \"BHD\" | \"BIF\" | \"BMD\" | \"BND\" | \"BOB\" | \"BRL\" | \"BSD\" | \"BTN\" | \"BWP\" | \"BZD\" | \"CAD\" | \"CHF\" | \"CLP\" | \"CNY\" | \"COP\" | \"CRC\" | \"CVE\" | \"CZK\" | \"DJF\" | \"DKK\" | \"DOP\" | \"DZD\" | \"EGP\" | \"ERN\" | \"ETB\" | \"EUR\" | \"FJD\" | \"FKP\" | \"GBP\" | \"GEL\" | \"GHS\" | \"GIP\" | \"GMD\" | \"GNF\" | \"GTQ\" | \"GYD\" | \"HKD\" | \"HNL\" | \"HUF\" | \"IDR\" | \"ILS\" | \"INR\" | \"ISK\" | \"JMD\" | \"JOD\" | \"JPY\" | \"KES\" | \"KGS\" | \"KHR\" | \"KMF\" | \"KRW\" | \"KWD\" | \"KYD\" | \"KZT\" | \"LAK\" | \"LBP\" | \"LKR\" | \"LRD\" | \"LSL\" | \"LYD\" | \"MAD\" | \"MDL\" | \"MGA\" | \"MKD\" | \"MNT\" | \"MOP\" | \"MUR\" | \"MVR\" | \"MWK\" | \"MXN\" | \"MYR\" | \"NAD\" | \"NGN\" | \"NIO\" | \"NOK\" | \"NPR\" | \"NZD\" | \"OMR\" | \"PAB\" | \"PEN\" | \"PGK\" | \"PHP\" | \"PKR\" | \"PLN\" | \"PYG\" | \"QAR\" | \"RON\" | \"RSD\" | \"RWF\" | \"SAR\" | \"SBD\" | \"SCR\" | \"SEK\" | \"SGD\" | \"SHP\" | \"SLE\" | \"SRD\" | \"SVC\" | \"SZL\" | \"THB\" | \"TJS\" | \"TMT\" | \"TND\" | \"TOP\" | \"TRY\" | \"TTD\" | \"TWD\" | \"TZS\" | \"UAH\" | \"UGX\" | \"USD\" | \"UYU\" | \"UZS\" | \"VND\" | \"VUV\" | \"WST\" | \"XAF\" | \"XCD\" | \"XOF\" | \"XPF\" | \"ZAR\" | \"ZMW\" | \"ZWL\"; }; couponCode?: { name: string; active: boolean; couponId: string; teamId: string; id?: string; createdAt?: string; updatedAt?: string; uses?: number; }; stripeConnectAvailability?: { available: boolean; reasons: (\"FEATURE_DISABLED\" | \"UNSUPPORTED_CURRENCY\" | \"NOT_ROUTED\" | \"NO_CONNECTED_GATEWAY\" | \"CHARGES_DISABLED\" | \"INCOMPATIBLE_FEE_STRUCTURE\")[]; supportedCurrencies: (\"AUD\" | \"NZD\" | \"USD\")[]; }; }",
|
|
1456
1975
|
"references": {
|
|
1457
1976
|
"OrderQuote": {
|
|
1458
1977
|
"location": "import",
|
|
1459
1978
|
"path": "@session-services/sdk/schemas",
|
|
1460
|
-
"id": "../../sdk/src/schemas.ts::OrderQuote"
|
|
1979
|
+
"id": "../../sdk/src/schemas.ts::OrderQuote",
|
|
1980
|
+
"referenceLocation": "OrderQuote"
|
|
1461
1981
|
}
|
|
1462
1982
|
}
|
|
1463
1983
|
},
|
|
@@ -1579,8 +2099,13 @@ export class SessionsTicketing {
|
|
|
1579
2099
|
"selectedItems": {},
|
|
1580
2100
|
"quote": {},
|
|
1581
2101
|
"previewQuote": {},
|
|
1582
|
-
"
|
|
2102
|
+
"initialLoading": {},
|
|
2103
|
+
"eventLoading": {},
|
|
2104
|
+
"retryLoading": {},
|
|
2105
|
+
"passcodeLoading": {},
|
|
1583
2106
|
"error": {},
|
|
2107
|
+
"errorKind": {},
|
|
2108
|
+
"refreshError": {},
|
|
1584
2109
|
"quoteLoading": {},
|
|
1585
2110
|
"previewLoading": {},
|
|
1586
2111
|
"quoteError": {},
|
|
@@ -1592,8 +2117,10 @@ export class SessionsTicketing {
|
|
|
1592
2117
|
"passcodeDenied": {},
|
|
1593
2118
|
"selectionPrompt": {},
|
|
1594
2119
|
"checkoutLoading": {},
|
|
2120
|
+
"checkoutError": {},
|
|
1595
2121
|
"currentTheme": {},
|
|
1596
|
-
"openModalAdmissionId": {}
|
|
2122
|
+
"openModalAdmissionId": {},
|
|
2123
|
+
"verificationRequired": {}
|
|
1597
2124
|
};
|
|
1598
2125
|
}
|
|
1599
2126
|
static get events() {
|
|
@@ -1608,8 +2135,8 @@ export class SessionsTicketing {
|
|
|
1608
2135
|
"text": ""
|
|
1609
2136
|
},
|
|
1610
2137
|
"complexType": {
|
|
1611
|
-
"original": "{\n orderId
|
|
1612
|
-
"resolved": "{ orderId
|
|
2138
|
+
"original": "{\n orderId?: string;\n checkoutUrl?: string;\n }",
|
|
2139
|
+
"resolved": "{ orderId?: string; checkoutUrl?: string; }",
|
|
1613
2140
|
"references": {}
|
|
1614
2141
|
}
|
|
1615
2142
|
}, {
|
|
@@ -1624,12 +2151,13 @@ export class SessionsTicketing {
|
|
|
1624
2151
|
},
|
|
1625
2152
|
"complexType": {
|
|
1626
2153
|
"original": "OrderQuote",
|
|
1627
|
-
"resolved": "{ items: { id: string; kind: \"ADMISSION\" | \"ADDON\"; quantity: number; price: { net: number; total: number; gross: number; base: number; booking: number; refunded: number; discount: number; currency: \"AUD\" | \"AED\" | \"ALL\" | \"AMD\" | \"ANG\" | \"AOA\" | \"ARS\" | \"AWG\" | \"AZN\" | \"BAM\" | \"BBD\" | \"BDT\" | \"BGN\" | \"BHD\" | \"BIF\" | \"BMD\" | \"BND\" | \"BOB\" | \"BRL\" | \"BSD\" | \"BTN\" | \"BWP\" | \"BZD\" | \"CAD\" | \"CHF\" | \"CLP\" | \"CNY\" | \"COP\" | \"CRC\" | \"CVE\" | \"CZK\" | \"DJF\" | \"DKK\" | \"DOP\" | \"DZD\" | \"EGP\" | \"ERN\" | \"ETB\" | \"EUR\" | \"FJD\" | \"FKP\" | \"GBP\" | \"GEL\" | \"GHS\" | \"GIP\" | \"GMD\" | \"GNF\" | \"GTQ\" | \"GYD\" | \"HKD\" | \"HNL\" | \"HUF\" | \"IDR\" | \"ILS\" | \"INR\" | \"ISK\" | \"JMD\" | \"JOD\" | \"JPY\" | \"KES\" | \"KGS\" | \"KHR\" | \"KMF\" | \"KRW\" | \"KWD\" | \"KYD\" | \"KZT\" | \"LAK\" | \"LBP\" | \"LKR\" | \"LRD\" | \"LSL\" | \"LYD\" | \"MAD\" | \"MDL\" | \"MGA\" | \"MKD\" | \"MNT\" | \"MOP\" | \"MUR\" | \"MVR\" | \"MWK\" | \"MXN\" | \"MYR\" | \"NAD\" | \"NGN\" | \"NIO\" | \"NOK\" | \"NPR\" | \"NZD\" | \"OMR\" | \"PAB\" | \"PEN\" | \"PGK\" | \"PHP\" | \"PKR\" | \"PLN\" | \"PYG\" | \"QAR\" | \"RON\" | \"RSD\" | \"RWF\" | \"SAR\" | \"SBD\" | \"SCR\" | \"SEK\" | \"SGD\" | \"SHP\" | \"SLE\" | \"SRD\" | \"SVC\" | \"SZL\" | \"THB\" | \"TJS\" | \"TMT\" | \"TND\" | \"TOP\" | \"TRY\" | \"TTD\" | \"TWD\" | \"TZS\" | \"UAH\" | \"UGX\" | \"USD\" | \"UYU\" | \"UZS\" | \"VND\" | \"VUV\" | \"WST\" | \"XAF\" | \"XCD\" | \"XOF\" | \"XPF\" | \"ZAR\" | \"ZMW\" | \"ZWL\"; }; admissionId?: string; sectionId?: string; admission?: { name: string; capacity: number; limit: number; order: number; entryStartsAt: string; entryEndsAt: string; saleStartsAt: string; saleEndsAt: string; saleEndsBehavior: \"SALE_ENDED\" | \"SOLD_OUT\" | \"DOOR\"; price: { base: number; booking: number; currency: \"AUD\" | \"AED\" | \"ALL\" | \"AMD\" | \"ANG\" | \"AOA\" | \"ARS\" | \"AWG\" | \"AZN\" | \"BAM\" | \"BBD\" | \"BDT\" | \"BGN\" | \"BHD\" | \"BIF\" | \"BMD\" | \"BND\" | \"BOB\" | \"BRL\" | \"BSD\" | \"BTN\" | \"BWP\" | \"BZD\" | \"CAD\" | \"CHF\" | \"CLP\" | \"CNY\" | \"COP\" | \"CRC\" | \"CVE\" | \"CZK\" | \"DJF\" | \"DKK\" | \"DOP\" | \"DZD\" | \"EGP\" | \"ERN\" | \"ETB\" | \"EUR\" | \"FJD\" | \"FKP\" | \"GBP\" | \"GEL\" | \"GHS\" | \"GIP\" | \"GMD\" | \"GNF\" | \"GTQ\" | \"GYD\" | \"HKD\" | \"HNL\" | \"HUF\" | \"IDR\" | \"ILS\" | \"INR\" | \"ISK\" | \"JMD\" | \"JOD\" | \"JPY\" | \"KES\" | \"KGS\" | \"KHR\" | \"KMF\" | \"KRW\" | \"KWD\" | \"KYD\" | \"KZT\" | \"LAK\" | \"LBP\" | \"LKR\" | \"LRD\" | \"LSL\" | \"LYD\" | \"MAD\" | \"MDL\" | \"MGA\" | \"MKD\" | \"MNT\" | \"MOP\" | \"MUR\" | \"MVR\" | \"MWK\" | \"MXN\" | \"MYR\" | \"NAD\" | \"NGN\" | \"NIO\" | \"NOK\" | \"NPR\" | \"NZD\" | \"OMR\" | \"PAB\" | \"PEN\" | \"PGK\" | \"PHP\" | \"PKR\" | \"PLN\" | \"PYG\" | \"QAR\" | \"RON\" | \"RSD\" | \"RWF\" | \"SAR\" | \"SBD\" | \"SCR\" | \"SEK\" | \"SGD\" | \"SHP\" | \"SLE\" | \"SRD\" | \"SVC\" | \"SZL\" | \"THB\" | \"TJS\" | \"TMT\" | \"TND\" | \"TOP\" | \"TRY\" | \"TTD\" | \"TWD\" | \"TZS\" | \"UAH\" | \"UGX\" | \"USD\" | \"UYU\" | \"UZS\" | \"VND\" | \"VUV\" | \"WST\" | \"XAF\" | \"XCD\" | \"XOF\" | \"XPF\" | \"ZAR\" | \"ZMW\" | \"ZWL\"; }; visibility: \"ALWAYS\" | \"HIDDEN\"; teamId: string; promoterId: string; eventId: string; eventSlug: string; id?: string; subtitle?: string; description?: string; available?: number; sold?: number; reserved?: number; createdAt?: string; updatedAt?: string; sectionId?: string; }; section?: { name: string; capacity: number; limit: number; order: number; visibility: \"ALWAYS\" | \"HIDDEN\" | \"STACKED\"; location: { createdAt: string; updatedAt: string; name: string; address: string; country: string; latitude: number; longitude: number; timeZone: string; id?: string; googlePlaceId?: string; city?: string; state?: string; postcode?: string; types?: string[]; description?: string; image?: { src: string; alt: string; width: number; height: number; }; venueId?: string; }; teamId: string; promoterId: string; eventId: string; eventSlug: string; id?: string; createdAt?: string; updatedAt?: string; available?: number; sold?: number; reserved?: number; }; }[]; price: { net: number; total: number; gross: number; base: number; booking: number; shipping: number; sms: number; refunded: number; discount: number; gateway: number; dispute: number; currency: \"AUD\" | \"AED\" | \"ALL\" | \"AMD\" | \"ANG\" | \"AOA\" | \"ARS\" | \"AWG\" | \"AZN\" | \"BAM\" | \"BBD\" | \"BDT\" | \"BGN\" | \"BHD\" | \"BIF\" | \"BMD\" | \"BND\" | \"BOB\" | \"BRL\" | \"BSD\" | \"BTN\" | \"BWP\" | \"BZD\" | \"CAD\" | \"CHF\" | \"CLP\" | \"CNY\" | \"COP\" | \"CRC\" | \"CVE\" | \"CZK\" | \"DJF\" | \"DKK\" | \"DOP\" | \"DZD\" | \"EGP\" | \"ERN\" | \"ETB\" | \"EUR\" | \"FJD\" | \"FKP\" | \"GBP\" | \"GEL\" | \"GHS\" | \"GIP\" | \"GMD\" | \"GNF\" | \"GTQ\" | \"GYD\" | \"HKD\" | \"HNL\" | \"HUF\" | \"IDR\" | \"ILS\" | \"INR\" | \"ISK\" | \"JMD\" | \"JOD\" | \"JPY\" | \"KES\" | \"KGS\" | \"KHR\" | \"KMF\" | \"KRW\" | \"KWD\" | \"KYD\" | \"KZT\" | \"LAK\" | \"LBP\" | \"LKR\" | \"LRD\" | \"LSL\" | \"LYD\" | \"MAD\" | \"MDL\" | \"MGA\" | \"MKD\" | \"MNT\" | \"MOP\" | \"MUR\" | \"MVR\" | \"MWK\" | \"MXN\" | \"MYR\" | \"NAD\" | \"NGN\" | \"NIO\" | \"NOK\" | \"NPR\" | \"NZD\" | \"OMR\" | \"PAB\" | \"PEN\" | \"PGK\" | \"PHP\" | \"PKR\" | \"PLN\" | \"PYG\" | \"QAR\" | \"RON\" | \"RSD\" | \"RWF\" | \"SAR\" | \"SBD\" | \"SCR\" | \"SEK\" | \"SGD\" | \"SHP\" | \"SLE\" | \"SRD\" | \"SVC\" | \"SZL\" | \"THB\" | \"TJS\" | \"TMT\" | \"TND\" | \"TOP\" | \"TRY\" | \"TTD\" | \"TWD\" | \"TZS\" | \"UAH\" | \"UGX\" | \"USD\" | \"UYU\" | \"UZS\" | \"VND\" | \"VUV\" | \"WST\" | \"XAF\" | \"XCD\" | \"XOF\" | \"XPF\" | \"ZAR\" | \"ZMW\" | \"ZWL\"; }; couponCode?: { name: string; active: boolean; couponId: string; teamId: string; id?: string; createdAt?: string; updatedAt?: string; uses?: number; }; }",
|
|
2154
|
+
"resolved": "{ items: { id: string; kind: \"ADMISSION\" | \"ADDON\"; quantity: number; price: { net: number; total: number; gross: number; base: number; booking: number; refunded: number; discount: number; currency: \"AUD\" | \"AED\" | \"ALL\" | \"AMD\" | \"ANG\" | \"AOA\" | \"ARS\" | \"AWG\" | \"AZN\" | \"BAM\" | \"BBD\" | \"BDT\" | \"BGN\" | \"BHD\" | \"BIF\" | \"BMD\" | \"BND\" | \"BOB\" | \"BRL\" | \"BSD\" | \"BTN\" | \"BWP\" | \"BZD\" | \"CAD\" | \"CHF\" | \"CLP\" | \"CNY\" | \"COP\" | \"CRC\" | \"CVE\" | \"CZK\" | \"DJF\" | \"DKK\" | \"DOP\" | \"DZD\" | \"EGP\" | \"ERN\" | \"ETB\" | \"EUR\" | \"FJD\" | \"FKP\" | \"GBP\" | \"GEL\" | \"GHS\" | \"GIP\" | \"GMD\" | \"GNF\" | \"GTQ\" | \"GYD\" | \"HKD\" | \"HNL\" | \"HUF\" | \"IDR\" | \"ILS\" | \"INR\" | \"ISK\" | \"JMD\" | \"JOD\" | \"JPY\" | \"KES\" | \"KGS\" | \"KHR\" | \"KMF\" | \"KRW\" | \"KWD\" | \"KYD\" | \"KZT\" | \"LAK\" | \"LBP\" | \"LKR\" | \"LRD\" | \"LSL\" | \"LYD\" | \"MAD\" | \"MDL\" | \"MGA\" | \"MKD\" | \"MNT\" | \"MOP\" | \"MUR\" | \"MVR\" | \"MWK\" | \"MXN\" | \"MYR\" | \"NAD\" | \"NGN\" | \"NIO\" | \"NOK\" | \"NPR\" | \"NZD\" | \"OMR\" | \"PAB\" | \"PEN\" | \"PGK\" | \"PHP\" | \"PKR\" | \"PLN\" | \"PYG\" | \"QAR\" | \"RON\" | \"RSD\" | \"RWF\" | \"SAR\" | \"SBD\" | \"SCR\" | \"SEK\" | \"SGD\" | \"SHP\" | \"SLE\" | \"SRD\" | \"SVC\" | \"SZL\" | \"THB\" | \"TJS\" | \"TMT\" | \"TND\" | \"TOP\" | \"TRY\" | \"TTD\" | \"TWD\" | \"TZS\" | \"UAH\" | \"UGX\" | \"USD\" | \"UYU\" | \"UZS\" | \"VND\" | \"VUV\" | \"WST\" | \"XAF\" | \"XCD\" | \"XOF\" | \"XPF\" | \"ZAR\" | \"ZMW\" | \"ZWL\"; }; admissionId?: string; sectionId?: string; admission?: { name: string; capacity: number; limit: number; order: number; entryStartsAt: string; entryEndsAt: string; saleStartsAt: string; saleEndsAt: string; saleEndsBehavior: \"SALE_ENDED\" | \"SOLD_OUT\" | \"DOOR\"; price: { base: number; booking: number; currency: \"AUD\" | \"AED\" | \"ALL\" | \"AMD\" | \"ANG\" | \"AOA\" | \"ARS\" | \"AWG\" | \"AZN\" | \"BAM\" | \"BBD\" | \"BDT\" | \"BGN\" | \"BHD\" | \"BIF\" | \"BMD\" | \"BND\" | \"BOB\" | \"BRL\" | \"BSD\" | \"BTN\" | \"BWP\" | \"BZD\" | \"CAD\" | \"CHF\" | \"CLP\" | \"CNY\" | \"COP\" | \"CRC\" | \"CVE\" | \"CZK\" | \"DJF\" | \"DKK\" | \"DOP\" | \"DZD\" | \"EGP\" | \"ERN\" | \"ETB\" | \"EUR\" | \"FJD\" | \"FKP\" | \"GBP\" | \"GEL\" | \"GHS\" | \"GIP\" | \"GMD\" | \"GNF\" | \"GTQ\" | \"GYD\" | \"HKD\" | \"HNL\" | \"HUF\" | \"IDR\" | \"ILS\" | \"INR\" | \"ISK\" | \"JMD\" | \"JOD\" | \"JPY\" | \"KES\" | \"KGS\" | \"KHR\" | \"KMF\" | \"KRW\" | \"KWD\" | \"KYD\" | \"KZT\" | \"LAK\" | \"LBP\" | \"LKR\" | \"LRD\" | \"LSL\" | \"LYD\" | \"MAD\" | \"MDL\" | \"MGA\" | \"MKD\" | \"MNT\" | \"MOP\" | \"MUR\" | \"MVR\" | \"MWK\" | \"MXN\" | \"MYR\" | \"NAD\" | \"NGN\" | \"NIO\" | \"NOK\" | \"NPR\" | \"NZD\" | \"OMR\" | \"PAB\" | \"PEN\" | \"PGK\" | \"PHP\" | \"PKR\" | \"PLN\" | \"PYG\" | \"QAR\" | \"RON\" | \"RSD\" | \"RWF\" | \"SAR\" | \"SBD\" | \"SCR\" | \"SEK\" | \"SGD\" | \"SHP\" | \"SLE\" | \"SRD\" | \"SVC\" | \"SZL\" | \"THB\" | \"TJS\" | \"TMT\" | \"TND\" | \"TOP\" | \"TRY\" | \"TTD\" | \"TWD\" | \"TZS\" | \"UAH\" | \"UGX\" | \"USD\" | \"UYU\" | \"UZS\" | \"VND\" | \"VUV\" | \"WST\" | \"XAF\" | \"XCD\" | \"XOF\" | \"XPF\" | \"ZAR\" | \"ZMW\" | \"ZWL\"; override?: { booking: number; }; }; visibility: \"ALWAYS\" | \"HIDDEN\" | \"AFTER_ADMISSION\"; teamId: string; promoterId: string; eventId: string; eventSlug: string; id?: string; subtitle?: string; description?: string; available?: number; sold?: number; reserved?: number; createdAt?: string; updatedAt?: string; visibleAfterAdmissionId?: string; sectionId?: string; }; section?: { name: string; capacity: number; limit: number; order: number; visibility: \"ALWAYS\" | \"HIDDEN\" | \"STACKED\"; location: { createdAt: string; updatedAt: string; name: string; address: string; country: string; latitude: number; longitude: number; timeZone: string; id?: string; googlePlaceId?: string; city?: string; state?: string; postcode?: string; types?: string[]; description?: string; image?: { src: string; alt: string; width: number; height: number; }; venueId?: string; }; teamId: string; promoterId: string; eventId: string; eventSlug: string; id?: string; createdAt?: string; updatedAt?: string; available?: number; sold?: number; reserved?: number; }; }[]; price: { net: number; total: number; gross: number; base: number; booking: number; shipping: number; sms: number; refunded: number; discount: number; gateway: number; dispute: number; currency: \"AUD\" | \"AED\" | \"ALL\" | \"AMD\" | \"ANG\" | \"AOA\" | \"ARS\" | \"AWG\" | \"AZN\" | \"BAM\" | \"BBD\" | \"BDT\" | \"BGN\" | \"BHD\" | \"BIF\" | \"BMD\" | \"BND\" | \"BOB\" | \"BRL\" | \"BSD\" | \"BTN\" | \"BWP\" | \"BZD\" | \"CAD\" | \"CHF\" | \"CLP\" | \"CNY\" | \"COP\" | \"CRC\" | \"CVE\" | \"CZK\" | \"DJF\" | \"DKK\" | \"DOP\" | \"DZD\" | \"EGP\" | \"ERN\" | \"ETB\" | \"EUR\" | \"FJD\" | \"FKP\" | \"GBP\" | \"GEL\" | \"GHS\" | \"GIP\" | \"GMD\" | \"GNF\" | \"GTQ\" | \"GYD\" | \"HKD\" | \"HNL\" | \"HUF\" | \"IDR\" | \"ILS\" | \"INR\" | \"ISK\" | \"JMD\" | \"JOD\" | \"JPY\" | \"KES\" | \"KGS\" | \"KHR\" | \"KMF\" | \"KRW\" | \"KWD\" | \"KYD\" | \"KZT\" | \"LAK\" | \"LBP\" | \"LKR\" | \"LRD\" | \"LSL\" | \"LYD\" | \"MAD\" | \"MDL\" | \"MGA\" | \"MKD\" | \"MNT\" | \"MOP\" | \"MUR\" | \"MVR\" | \"MWK\" | \"MXN\" | \"MYR\" | \"NAD\" | \"NGN\" | \"NIO\" | \"NOK\" | \"NPR\" | \"NZD\" | \"OMR\" | \"PAB\" | \"PEN\" | \"PGK\" | \"PHP\" | \"PKR\" | \"PLN\" | \"PYG\" | \"QAR\" | \"RON\" | \"RSD\" | \"RWF\" | \"SAR\" | \"SBD\" | \"SCR\" | \"SEK\" | \"SGD\" | \"SHP\" | \"SLE\" | \"SRD\" | \"SVC\" | \"SZL\" | \"THB\" | \"TJS\" | \"TMT\" | \"TND\" | \"TOP\" | \"TRY\" | \"TTD\" | \"TWD\" | \"TZS\" | \"UAH\" | \"UGX\" | \"USD\" | \"UYU\" | \"UZS\" | \"VND\" | \"VUV\" | \"WST\" | \"XAF\" | \"XCD\" | \"XOF\" | \"XPF\" | \"ZAR\" | \"ZMW\" | \"ZWL\"; }; couponCode?: { name: string; active: boolean; couponId: string; teamId: string; id?: string; createdAt?: string; updatedAt?: string; uses?: number; }; stripeConnectAvailability?: { available: boolean; reasons: (\"FEATURE_DISABLED\" | \"UNSUPPORTED_CURRENCY\" | \"NOT_ROUTED\" | \"NO_CONNECTED_GATEWAY\" | \"CHARGES_DISABLED\" | \"INCOMPATIBLE_FEE_STRUCTURE\")[]; supportedCurrencies: (\"AUD\" | \"NZD\" | \"USD\")[]; }; }",
|
|
1628
2155
|
"references": {
|
|
1629
2156
|
"OrderQuote": {
|
|
1630
2157
|
"location": "import",
|
|
1631
2158
|
"path": "@session-services/sdk/schemas",
|
|
1632
|
-
"id": "../../sdk/src/schemas.ts::OrderQuote"
|
|
2159
|
+
"id": "../../sdk/src/schemas.ts::OrderQuote",
|
|
2160
|
+
"referenceLocation": "OrderQuote"
|
|
1633
2161
|
}
|
|
1634
2162
|
}
|
|
1635
2163
|
}
|
|
@@ -1648,6 +2176,27 @@ export class SessionsTicketing {
|
|
|
1648
2176
|
"resolved": "{ error: string; }",
|
|
1649
2177
|
"references": {}
|
|
1650
2178
|
}
|
|
2179
|
+
}, {
|
|
2180
|
+
"method": "analyticsEventSkipped",
|
|
2181
|
+
"name": "analyticsEventSkipped",
|
|
2182
|
+
"bubbles": true,
|
|
2183
|
+
"cancelable": true,
|
|
2184
|
+
"composed": true,
|
|
2185
|
+
"docs": {
|
|
2186
|
+
"tags": [],
|
|
2187
|
+
"text": ""
|
|
2188
|
+
},
|
|
2189
|
+
"complexType": {
|
|
2190
|
+
"original": "AnalyticsEventSkipped",
|
|
2191
|
+
"resolved": "{ eventType: string; eventId: string; reason: AnalyticsSkipReason; promoterId?: string; teamId?: string; }",
|
|
2192
|
+
"references": {
|
|
2193
|
+
"AnalyticsEventSkipped": {
|
|
2194
|
+
"location": "local",
|
|
2195
|
+
"path": "/Users/j/Dev/sessions-repo/packages/elements/web/src/components/session-services-ticketing/session-services-ticketing.tsx",
|
|
2196
|
+
"id": "src/components/session-services-ticketing/session-services-ticketing.tsx::AnalyticsEventSkipped"
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
}
|
|
1651
2200
|
}];
|
|
1652
2201
|
}
|
|
1653
2202
|
static get elementRef() { return "host"; }
|