@session-services/web-elements 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/LICENSE +11 -0
  2. package/README.md +101 -0
  3. package/dist/cjs/app-globals-V2Kpy_OQ.js +5 -0
  4. package/dist/cjs/index-C6e98Atu.js +1529 -0
  5. package/dist/cjs/index.cjs.js +2 -0
  6. package/dist/cjs/loader.cjs.js +13 -0
  7. package/dist/cjs/session-services-elements.cjs.js +25 -0
  8. package/dist/cjs/session-services-ticketing.cjs.entry.js +1953 -0
  9. package/dist/collection/collection-manifest.json +12 -0
  10. package/dist/collection/components/session-services-ticketing/session-services-ticketing.css +879 -0
  11. package/dist/collection/components/session-services-ticketing/session-services-ticketing.js +708 -0
  12. package/dist/collection/index.js +11 -0
  13. package/dist/components/index.d.ts +33 -0
  14. package/dist/components/index.js +1311 -0
  15. package/dist/components/session-services-ticketing.d.ts +11 -0
  16. package/dist/components/session-services-ticketing.js +1995 -0
  17. package/dist/esm/app-globals-DQuL1Twl.js +3 -0
  18. package/dist/esm/index-CeXOR4aK.js +1521 -0
  19. package/dist/esm/index.js +1 -0
  20. package/dist/esm/loader.js +11 -0
  21. package/dist/esm/session-services-elements.js +21 -0
  22. package/dist/esm/session-services-ticketing.entry.js +1951 -0
  23. package/dist/index.cjs.js +1 -0
  24. package/dist/index.js +1 -0
  25. package/dist/session-services-elements/index.esm.js +0 -0
  26. package/dist/session-services-elements/p-9ca1f04b.entry.js +1 -0
  27. package/dist/session-services-elements/p-CeXOR4aK.js +2 -0
  28. package/dist/session-services-elements/p-DQuL1Twl.js +1 -0
  29. package/dist/session-services-elements/session-services-elements.esm.js +1 -0
  30. package/dist/sst-env.d.ts +9 -0
  31. package/dist/types/components/session-services-ticketing/session-services-ticketing.d.ts +64 -0
  32. package/dist/types/components.d.ts +111 -0
  33. package/dist/types/index.d.ts +9 -0
  34. package/dist/types/stencil-public-runtime.d.ts +1799 -0
  35. package/loader/cdn.js +1 -0
  36. package/loader/index.cjs.js +1 -0
  37. package/loader/index.d.ts +24 -0
  38. package/loader/index.es2017.js +1 -0
  39. package/loader/index.js +2 -0
  40. package/package.json +101 -0
@@ -0,0 +1,708 @@
1
+ import { createClient } from "@session-services/sdk";
2
+ import { createAnalytics, formatPrice } from "@session-services/sdk/analytics";
3
+ import {
4
+ // biome-ignore lint/correctness/noUnusedImports: h is required by Stencil JSX transform
5
+ h, Host, } from "@stencil/core";
6
+ const CalendarIcon = () => (h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, h("path", { d: "M8 2v4" }), h("path", { d: "M16 2v4" }), h("rect", { width: "18", height: "18", x: "3", y: "4", rx: "2" }), h("path", { d: "M3 10h18" })));
7
+ const LocationIcon = () => (h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, h("path", { d: "M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0" }), h("circle", { cx: "12", cy: "10", r: "3" })));
8
+ export class SessionsTicketing {
9
+ tenantId;
10
+ eventId;
11
+ apiUrl = "https://api.session.services";
12
+ locale = "en-US";
13
+ returnUrl;
14
+ theme = "system";
15
+ enableAnalytics = true;
16
+ debugAnalytics = false;
17
+ event = null;
18
+ selectedItems = new Map();
19
+ quote = null;
20
+ loading = true;
21
+ error = null;
22
+ quoteLoading = false;
23
+ quoteError = null;
24
+ checkoutLoading = false;
25
+ currentTheme = "light";
26
+ checkoutInit;
27
+ cartUpdate;
28
+ errorOccurred;
29
+ client;
30
+ analytics;
31
+ mediaQueryList;
32
+ requestId = 0;
33
+ async componentWillLoad() {
34
+ await this.initializeComponent();
35
+ }
36
+ async propsChanged() {
37
+ await this.initializeComponent();
38
+ }
39
+ themeChanged() {
40
+ this.setupTheme();
41
+ }
42
+ disconnectedCallback() {
43
+ if (this.mediaQueryList) {
44
+ this.mediaQueryList.removeEventListener("change", this.handleSystemThemeChange);
45
+ }
46
+ }
47
+ async initializeComponent() {
48
+ this.error = null;
49
+ this.event = null;
50
+ this.selectedItems.clear();
51
+ this.quote = null;
52
+ if (!this.tenantId || !this.eventId) {
53
+ this.error = "Missing required configuration: tenantId and eventId";
54
+ this.loading = false;
55
+ return;
56
+ }
57
+ this.client = createClient({
58
+ environment: this.apiUrl,
59
+ tenantId: this.tenantId,
60
+ });
61
+ this.setupTheme();
62
+ await this.loadEventData();
63
+ }
64
+ setupTheme() {
65
+ if (this.mediaQueryList) {
66
+ this.mediaQueryList.removeEventListener("change", this.handleSystemThemeChange);
67
+ }
68
+ if (this.theme === "system") {
69
+ this.mediaQueryList = window.matchMedia("(prefers-color-scheme: dark)");
70
+ this.currentTheme = this.mediaQueryList.matches ? "dark" : "light";
71
+ this.mediaQueryList.addEventListener("change", this.handleSystemThemeChange);
72
+ }
73
+ else {
74
+ this.currentTheme = this.theme;
75
+ }
76
+ }
77
+ handleSystemThemeChange = (e) => {
78
+ if (this.theme === "system") {
79
+ this.currentTheme = e.matches ? "dark" : "light";
80
+ }
81
+ };
82
+ trackEvent(eventType, properties = {}) {
83
+ if (!this.analytics || !this.enableAnalytics)
84
+ return;
85
+ this.analytics.track(eventType, {
86
+ event_id: this.eventId,
87
+ team_id: this.event?.teamId,
88
+ promoter_id: this.event?.promoterId,
89
+ event_name: this.event?.name,
90
+ event_slug: this.event?.slug,
91
+ currency: this.event?.currency,
92
+ ...properties,
93
+ });
94
+ }
95
+ async loadEventData() {
96
+ try {
97
+ this.loading = true;
98
+ this.error = null;
99
+ const response = await this.client.event.get({ key: this.eventId });
100
+ this.event = response.event;
101
+ if (this.enableAnalytics && !this.analytics && this.event?.promoterId) {
102
+ this.analytics = createAnalytics({
103
+ client: this.client,
104
+ debug: this.debugAnalytics,
105
+ });
106
+ }
107
+ if (this.event) {
108
+ this.trackEvent("Product List Viewed", {
109
+ list_id: this.eventId,
110
+ category: "Admissions",
111
+ products: this.event.admissions.map((adm, index) => ({
112
+ product_id: adm.id,
113
+ sku: adm.id,
114
+ name: adm.name,
115
+ category: this.event?.name,
116
+ price: ((adm.price?.base || 0) + (adm.price?.booking || 0)) / 100,
117
+ quantity: 1,
118
+ position: index + 1,
119
+ admission_id: adm.id,
120
+ section_id: adm.sectionId,
121
+ price_base: adm.price?.base,
122
+ price_booking_fee: adm.price?.booking,
123
+ available: adm.available,
124
+ capacity: adm.capacity,
125
+ })),
126
+ });
127
+ }
128
+ }
129
+ catch (err) {
130
+ this.error =
131
+ err instanceof Error ? err.message : "Failed to load event data";
132
+ this.errorOccurred.emit({ error: this.error });
133
+ }
134
+ finally {
135
+ this.loading = false;
136
+ }
137
+ }
138
+ async updateQuantity(admissionId, sectionId, delta) {
139
+ const key = `${admissionId}::${sectionId || "none"}`;
140
+ const currentQuantity = this.selectedItems.get(key) || 0;
141
+ const newQuantity = Math.max(0, currentQuantity + delta);
142
+ if (newQuantity === 0) {
143
+ this.selectedItems.delete(key);
144
+ }
145
+ else {
146
+ this.selectedItems.set(key, newQuantity);
147
+ }
148
+ this.selectedItems = new Map(this.selectedItems);
149
+ const admission = this.event?.admissions.find((a) => a.id === admissionId);
150
+ const section = sectionId
151
+ ? this.event?.sections.find((s) => s.id === sectionId)
152
+ : null;
153
+ if (delta > 0 && admission) {
154
+ this.trackEvent("Product Added", {
155
+ product_id: admissionId,
156
+ sku: admissionId,
157
+ name: admission.name,
158
+ category: this.event?.name,
159
+ variant: section?.name,
160
+ price: ((admission.price?.base || 0) + (admission.price?.booking || 0)) /
161
+ 100,
162
+ quantity: Math.abs(delta),
163
+ admission_id: admissionId,
164
+ section_id: sectionId || undefined,
165
+ section_name: section?.name,
166
+ price_base: admission.price?.base,
167
+ price_booking_fee: admission.price?.booking,
168
+ });
169
+ }
170
+ else if (delta < 0 && admission) {
171
+ this.trackEvent("Product Removed", {
172
+ product_id: admissionId,
173
+ sku: admissionId,
174
+ name: admission.name,
175
+ category: this.event?.name,
176
+ variant: section?.name,
177
+ price: ((admission.price?.base || 0) + (admission.price?.booking || 0)) /
178
+ 100,
179
+ quantity: Math.abs(delta),
180
+ admission_id: admissionId,
181
+ section_id: sectionId || undefined,
182
+ section_name: section?.name,
183
+ });
184
+ }
185
+ await this.updateQuote();
186
+ }
187
+ async updateQuote() {
188
+ if (this.selectedItems.size === 0) {
189
+ this.quote = null;
190
+ this.quoteError = null;
191
+ return;
192
+ }
193
+ this.requestId++;
194
+ const currentId = this.requestId;
195
+ try {
196
+ this.quoteLoading = true;
197
+ this.quoteError = null;
198
+ const items = [];
199
+ this.selectedItems.forEach((quantity, key) => {
200
+ const [admissionId, sectionId] = key.split("::");
201
+ items.push({
202
+ quantity,
203
+ admissionId,
204
+ sectionId: sectionId !== "none" ? sectionId : undefined,
205
+ });
206
+ });
207
+ const response = await this.client.order.quote({
208
+ eventId: this.eventId,
209
+ items,
210
+ });
211
+ if (currentId === this.requestId) {
212
+ this.quote = response.quote;
213
+ this.cartUpdate.emit(this.quote);
214
+ this.trackEvent("Cart Viewed", {
215
+ products: this.quote.items.map((item) => {
216
+ const admission = this.event?.admissions.find((a) => a.id === item.admissionId);
217
+ const section = item.sectionId
218
+ ? this.event?.sections.find((s) => s.id === item.sectionId)
219
+ : null;
220
+ return {
221
+ product_id: item.admissionId,
222
+ sku: item.admissionId,
223
+ name: admission?.name,
224
+ category: this.event?.name,
225
+ variant: section?.name,
226
+ price: ((item.price?.base || 0) + (item.price?.booking || 0)) / 100,
227
+ quantity: item.quantity,
228
+ admission_id: item.admissionId,
229
+ section_id: item.sectionId,
230
+ price_base: item.price?.base,
231
+ price_booking_fee: item.price?.booking,
232
+ };
233
+ }),
234
+ value: (this.quote.price?.total || 0) / 100,
235
+ currency: this.event?.currency,
236
+ });
237
+ }
238
+ }
239
+ catch (_err) {
240
+ if (currentId === this.requestId) {
241
+ this.quoteError = "Failed to update cart. Please try again.";
242
+ this.errorOccurred.emit({ error: this.quoteError });
243
+ }
244
+ }
245
+ finally {
246
+ if (currentId === this.requestId) {
247
+ this.quoteLoading = false;
248
+ }
249
+ }
250
+ }
251
+ async initiateCheckout() {
252
+ if (!this.quote)
253
+ return;
254
+ try {
255
+ this.checkoutLoading = true;
256
+ this.quoteError = null;
257
+ this.trackEvent("Checkout Started", {
258
+ value: (this.quote.price?.total || 0) / 100,
259
+ revenue: (this.quote.price?.total || 0) / 100,
260
+ currency: this.event?.currency,
261
+ products: this.quote.items.map((item) => {
262
+ const admission = this.event?.admissions.find((a) => a.id === item.admissionId);
263
+ const section = item.sectionId
264
+ ? this.event?.sections.find((s) => s.id === item.sectionId)
265
+ : null;
266
+ return {
267
+ product_id: item.admissionId,
268
+ sku: item.admissionId,
269
+ name: admission?.name,
270
+ category: this.event?.name,
271
+ variant: section?.name,
272
+ price: ((item.price?.base || 0) + (item.price?.booking || 0)) / 100,
273
+ quantity: item.quantity,
274
+ admission_id: item.admissionId,
275
+ section_id: item.sectionId,
276
+ section_name: section?.name,
277
+ price_base: item.price?.base,
278
+ price_booking_fee: item.price?.booking,
279
+ };
280
+ }),
281
+ });
282
+ const result = await this.client.order.create({
283
+ eventId: this.eventId,
284
+ items: this.quote.items.map((item) => ({
285
+ quantity: item.quantity,
286
+ admissionId: item.admissionId,
287
+ sectionId: item.sectionId,
288
+ })),
289
+ returnUrl: this.returnUrl,
290
+ });
291
+ this.checkoutInit.emit({
292
+ orderId: result.order.id,
293
+ checkoutUrl: result.order.checkoutUrl,
294
+ });
295
+ if (result.order.checkoutUrl) {
296
+ window.location.href = result.order.checkoutUrl;
297
+ return;
298
+ }
299
+ this.checkoutLoading = false;
300
+ }
301
+ catch (_err) {
302
+ this.quoteError = "Failed to initiate checkout. Please try again.";
303
+ this.errorOccurred.emit({ error: this.quoteError });
304
+ this.checkoutLoading = false;
305
+ }
306
+ }
307
+ formatDateTimeRange(startDate, endDate) {
308
+ const formatOptions = {
309
+ weekday: "short",
310
+ day: "numeric",
311
+ month: "short",
312
+ hour: "2-digit",
313
+ minute: "2-digit",
314
+ };
315
+ const startFormatted = new Date(startDate).toLocaleString(this.locale, formatOptions);
316
+ const endFormatted = new Date(endDate).toLocaleString(this.locale, formatOptions);
317
+ return `${startFormatted} - ${endFormatted}`;
318
+ }
319
+ formatPriceValue(priceInCents) {
320
+ const currency = this.event?.currency;
321
+ if (!currency) {
322
+ return new Intl.NumberFormat(this.locale, {
323
+ style: "decimal",
324
+ minimumFractionDigits: 2,
325
+ maximumFractionDigits: 2,
326
+ }).format(priceInCents / 100);
327
+ }
328
+ try {
329
+ return formatPrice(priceInCents, currency);
330
+ }
331
+ catch (error) {
332
+ console.error("formatPrice failed, using fallback", {
333
+ error,
334
+ currency,
335
+ priceInCents,
336
+ locale: this.locale,
337
+ });
338
+ return new Intl.NumberFormat(this.locale, {
339
+ style: "currency",
340
+ currency,
341
+ }).format(priceInCents / 100);
342
+ }
343
+ }
344
+ handleQuantityDecrease = async (admissionId, sectionId) => {
345
+ await this.updateQuantity(admissionId, sectionId, -1);
346
+ };
347
+ handleQuantityIncrease = async (admissionId, sectionId) => {
348
+ await this.updateQuantity(admissionId, sectionId, 1);
349
+ };
350
+ renderQuantityControls(admission, sectionId) {
351
+ const key = `${admission.id}::${sectionId || "none"}`;
352
+ const quantity = this.selectedItems.get(key) || 0;
353
+ const isUnlimited = admission.available === -1 || admission.capacity === -1;
354
+ return (h("div", { class: "quantity-controls" }, h("button", { type: "button", class: "quantity-btn decrease", onClick: () => this.handleQuantityDecrease(admission.id, sectionId), disabled: quantity === 0, "aria-label": "Decrease quantity" }, "\u2212"), h("span", { class: "quantity-value" }, quantity), h("button", { type: "button", class: "quantity-btn increase", onClick: () => this.handleQuantityIncrease(admission.id, sectionId), disabled: !isUnlimited && quantity >= admission.available, "aria-label": "Increase quantity" }, "+")));
355
+ }
356
+ renderEventTimeAndLocation() {
357
+ if (!this.event?.entryStartsAt || !this.event?.entryEndsAt)
358
+ return null;
359
+ return (h(h.Fragment, null, h("div", { class: "admission-time" }, CalendarIcon(), this.formatDateTimeRange(this.event.entryStartsAt, this.event.entryEndsAt)), this.event.location && (h("div", { class: "admission-venue" }, LocationIcon(), this.event.location.name))));
360
+ }
361
+ renderPriceAndControls(admission, sectionId, isSoldOut) {
362
+ const basePrice = admission.price?.base || 0;
363
+ const bookingFee = admission.price?.booking || 0;
364
+ return (h("div", { class: "admission-price-info" }, h("div", { class: "admission-price-wrapper" }, h("span", { class: "admission-price" }, this.formatPriceValue(basePrice)), h("span", { class: "admission-fee" }, bookingFee > 0 ? "+ Booking fee" : "No booking fee")), !isSoldOut ? (this.renderQuantityControls(admission, sectionId)) : (h("div", { class: "sold-out-controls" }, h("span", { class: "sold-out-text" }, "Sold Out")))));
365
+ }
366
+ renderAdmission(admission, section, isSectionSoldOut = false) {
367
+ const key = `${admission.id}::${section?.id || "none"}`;
368
+ const basePrice = admission.price?.base || 0;
369
+ const isSoldOut = admission.available === 0 || isSectionSoldOut;
370
+ const sectionId = section?.id || null;
371
+ const isStandaloneAdmission = !section;
372
+ const ariaLabel = section
373
+ ? `${admission.name} in ${section.name} - ${isSoldOut ? "Sold Out" : this.formatPriceValue(basePrice)}`
374
+ : `${admission.name} - ${isSoldOut ? "Sold Out" : this.formatPriceValue(basePrice)}`;
375
+ return (h("section", { class: `admission-card ${isSoldOut ? "sold-out" : ""} ${isStandaloneAdmission ? "solo-admission" : ""}`, key: key, tabindex: isSoldOut ? -1 : 0, "aria-label": ariaLabel }, h("div", { class: "admission-content" }, h("div", { class: "admission-details" }, h("h3", { class: "admission-title" }, admission.name), isStandaloneAdmission && (h(h.Fragment, null, this.renderEventTimeAndLocation(), this.renderPriceAndControls(admission, sectionId, isSoldOut))), section &&
376
+ this.renderPriceAndControls(admission, sectionId, isSoldOut)))));
377
+ }
378
+ renderSectionHeader(section, isSectionSoldOut) {
379
+ return (h("div", { class: "section-header" }, h("h2", { class: "section-name" }, section.name, isSectionSoldOut && h("span", { class: "sold-out-badge" }, "Sold Out")), this.event?.entryStartsAt && this.event?.entryEndsAt && (h("div", { class: "section-time" }, CalendarIcon(), this.formatDateTimeRange(this.event.entryStartsAt, this.event.entryEndsAt))), this.event?.location && (h("div", { class: "section-venue" }, LocationIcon(), this.event.location.name))));
380
+ }
381
+ renderSectionWithAdmissions(section) {
382
+ const sectionAdmissions = this.event?.admissions.filter((adm) => adm.sectionId === section.id) ||
383
+ [];
384
+ if (sectionAdmissions.length === 0)
385
+ return null;
386
+ const isSectionSoldOut = section.available === 0;
387
+ return (h("div", { class: `ticket-section ${isSectionSoldOut ? "section-sold-out" : ""}`, key: section.id }, this.renderSectionHeader(section, isSectionSoldOut), h("div", { class: "admissions-list" }, sectionAdmissions
388
+ .sort((a, b) => a.order - b.order)
389
+ .map((admission) => this.renderAdmission(admission, section, isSectionSoldOut)))));
390
+ }
391
+ renderLoadingState() {
392
+ return (h(Host, { "data-theme": this.currentTheme }, h("div", { class: "loading-state" }, "Loading event details...")));
393
+ }
394
+ renderErrorState() {
395
+ return (h(Host, { "data-theme": this.currentTheme }, h("div", { class: "session-services-ticketing-container" }, h("div", { class: "error-banner" }, h("strong", null, "Unable to load event"), h("p", null, this.error), h("button", { type: "button", class: "retry-button", onClick: () => this.loadEventData() }, "Try Again")))));
396
+ }
397
+ renderNotFoundState() {
398
+ return (h(Host, { "data-theme": this.currentTheme }, h("div", { class: "session-services-ticketing-container" }, h("div", { class: "error-banner" }, h("strong", null, "Event not found"), h("p", null, "The requested event could not be found.")))));
399
+ }
400
+ renderOrderSummaryItems() {
401
+ if (!this.quote?.items?.length) {
402
+ return (h("div", { class: "empty-cart-message" }, h("span", { class: "empty-cart-text" }, "No tickets selected"), h("span", { class: "empty-cart-price" }, this.formatPriceValue(0))));
403
+ }
404
+ return (h(h.Fragment, null, this.quote.items.map((item) => {
405
+ const admission = this.event?.admissions.find((a) => a.id === item.admissionId);
406
+ const section = item.sectionId
407
+ ? this.event?.sections.find((s) => s.id === item.sectionId)
408
+ : null;
409
+ const itemTotal = item.price?.base || 0;
410
+ if (section) {
411
+ return (h("div", { class: "order-item-with-section", key: `${item.admissionId}::${item.sectionId || "none"}` }, h("div", { class: "item-section-line" }, h("div", { class: "item-section-name" }, item.quantity, " x ", section.name), h("div", { class: "item-price" }, this.formatPriceValue(itemTotal))), h("div", { class: "item-admission-name" }, admission?.name)));
412
+ }
413
+ return (h("div", { class: "order-item", key: `${item.admissionId}::${item.sectionId || "none"}` }, h("div", { class: "item-description" }, item.quantity, " x ", admission?.name), h("div", { class: "item-price" }, this.formatPriceValue(itemTotal))));
414
+ })));
415
+ }
416
+ isCheckoutDisabled() {
417
+ return (this.quoteLoading ||
418
+ this.checkoutLoading ||
419
+ !this.quote ||
420
+ !this.quote.items?.length);
421
+ }
422
+ getCheckoutButtonText() {
423
+ if (this.checkoutLoading)
424
+ return "Processing...";
425
+ if (this.quoteLoading)
426
+ return "Updating...";
427
+ return "Checkout";
428
+ }
429
+ renderOrderSummary() {
430
+ return (h("div", { class: "order-summary" }, h("h2", { class: "summary-title" }, "Order summary"), this.quoteError && h("div", { class: "error-message" }, this.quoteError), h("div", { class: "order-items" }, this.renderOrderSummaryItems()), h("div", { class: "order-fees" }, h("div", { class: "fee-row" }, h("span", null, "Booking fee"), h("span", null, this.formatPriceValue(this.quote?.price?.booking || 0)))), h("div", { class: "order-total" }, h("span", null, "Total price"), h("span", null, !this.quote
431
+ ? "N/A"
432
+ : (this.quote.price?.total || 0) === 0
433
+ ? "Free"
434
+ : this.formatPriceValue(this.quote.price?.total || 0))), h("button", { type: "button", class: "checkout-btn", onClick: () => this.initiateCheckout(), disabled: this.isCheckoutDisabled() }, this.getCheckoutButtonText())));
435
+ }
436
+ renderTicketSections() {
437
+ const generalAdmissions = this.event?.admissions.filter((adm) => !adm.sectionId) || [];
438
+ return (h("div", { class: "tickets-wrapper" }, generalAdmissions.length > 0 && (h("div", { class: "unsectioned-admissions" }, generalAdmissions
439
+ .sort((a, b) => a.order - b.order)
440
+ .map((admission) => (h("div", { class: "ticket-section" }, h("div", { class: "admissions-list" }, this.renderAdmission(admission))))))), this.event?.sections
441
+ .sort((a, b) => a.order - b.order)
442
+ .map((section) => this.renderSectionWithAdmissions(section))));
443
+ }
444
+ render() {
445
+ if (this.loading)
446
+ return this.renderLoadingState();
447
+ if (this.error && !this.event)
448
+ return this.renderErrorState();
449
+ if (!this.event)
450
+ return this.renderNotFoundState();
451
+ return (h(Host, { "data-theme": this.currentTheme }, h("div", { class: "session-services-ticketing-container" }, this.renderTicketSections(), this.renderOrderSummary())));
452
+ }
453
+ static get is() { return "session-services-ticketing"; }
454
+ static get encapsulation() { return "shadow"; }
455
+ static get originalStyleUrls() {
456
+ return {
457
+ "$": ["session-services-ticketing.css"]
458
+ };
459
+ }
460
+ static get styleUrls() {
461
+ return {
462
+ "$": ["session-services-ticketing.css"]
463
+ };
464
+ }
465
+ static get properties() {
466
+ return {
467
+ "tenantId": {
468
+ "type": "string",
469
+ "mutable": false,
470
+ "complexType": {
471
+ "original": "string",
472
+ "resolved": "string",
473
+ "references": {}
474
+ },
475
+ "required": true,
476
+ "optional": false,
477
+ "docs": {
478
+ "tags": [],
479
+ "text": ""
480
+ },
481
+ "getter": false,
482
+ "setter": false,
483
+ "reflect": false,
484
+ "attribute": "tenant-id"
485
+ },
486
+ "eventId": {
487
+ "type": "string",
488
+ "mutable": false,
489
+ "complexType": {
490
+ "original": "string",
491
+ "resolved": "string",
492
+ "references": {}
493
+ },
494
+ "required": true,
495
+ "optional": false,
496
+ "docs": {
497
+ "tags": [],
498
+ "text": ""
499
+ },
500
+ "getter": false,
501
+ "setter": false,
502
+ "reflect": false,
503
+ "attribute": "event-id"
504
+ },
505
+ "apiUrl": {
506
+ "type": "string",
507
+ "mutable": false,
508
+ "complexType": {
509
+ "original": "string",
510
+ "resolved": "string",
511
+ "references": {}
512
+ },
513
+ "required": false,
514
+ "optional": false,
515
+ "docs": {
516
+ "tags": [],
517
+ "text": ""
518
+ },
519
+ "getter": false,
520
+ "setter": false,
521
+ "reflect": false,
522
+ "attribute": "api-url",
523
+ "defaultValue": "\"https://api.session.services\""
524
+ },
525
+ "locale": {
526
+ "type": "string",
527
+ "mutable": false,
528
+ "complexType": {
529
+ "original": "string",
530
+ "resolved": "string",
531
+ "references": {}
532
+ },
533
+ "required": false,
534
+ "optional": false,
535
+ "docs": {
536
+ "tags": [],
537
+ "text": ""
538
+ },
539
+ "getter": false,
540
+ "setter": false,
541
+ "reflect": false,
542
+ "attribute": "locale",
543
+ "defaultValue": "\"en-US\""
544
+ },
545
+ "returnUrl": {
546
+ "type": "string",
547
+ "mutable": false,
548
+ "complexType": {
549
+ "original": "string",
550
+ "resolved": "string",
551
+ "references": {}
552
+ },
553
+ "required": false,
554
+ "optional": true,
555
+ "docs": {
556
+ "tags": [],
557
+ "text": ""
558
+ },
559
+ "getter": false,
560
+ "setter": false,
561
+ "reflect": false,
562
+ "attribute": "return-url"
563
+ },
564
+ "theme": {
565
+ "type": "string",
566
+ "mutable": false,
567
+ "complexType": {
568
+ "original": "\"light\" | \"dark\" | \"system\"",
569
+ "resolved": "\"dark\" | \"light\" | \"system\"",
570
+ "references": {}
571
+ },
572
+ "required": false,
573
+ "optional": false,
574
+ "docs": {
575
+ "tags": [],
576
+ "text": ""
577
+ },
578
+ "getter": false,
579
+ "setter": false,
580
+ "reflect": false,
581
+ "attribute": "theme",
582
+ "defaultValue": "\"system\""
583
+ },
584
+ "enableAnalytics": {
585
+ "type": "boolean",
586
+ "mutable": false,
587
+ "complexType": {
588
+ "original": "boolean",
589
+ "resolved": "boolean",
590
+ "references": {}
591
+ },
592
+ "required": false,
593
+ "optional": false,
594
+ "docs": {
595
+ "tags": [],
596
+ "text": ""
597
+ },
598
+ "getter": false,
599
+ "setter": false,
600
+ "reflect": false,
601
+ "attribute": "enable-analytics",
602
+ "defaultValue": "true"
603
+ },
604
+ "debugAnalytics": {
605
+ "type": "boolean",
606
+ "mutable": false,
607
+ "complexType": {
608
+ "original": "boolean",
609
+ "resolved": "boolean",
610
+ "references": {}
611
+ },
612
+ "required": false,
613
+ "optional": false,
614
+ "docs": {
615
+ "tags": [],
616
+ "text": ""
617
+ },
618
+ "getter": false,
619
+ "setter": false,
620
+ "reflect": false,
621
+ "attribute": "debug-analytics",
622
+ "defaultValue": "false"
623
+ }
624
+ };
625
+ }
626
+ static get states() {
627
+ return {
628
+ "event": {},
629
+ "selectedItems": {},
630
+ "quote": {},
631
+ "loading": {},
632
+ "error": {},
633
+ "quoteLoading": {},
634
+ "quoteError": {},
635
+ "checkoutLoading": {},
636
+ "currentTheme": {}
637
+ };
638
+ }
639
+ static get events() {
640
+ return [{
641
+ "method": "checkoutInit",
642
+ "name": "checkoutInit",
643
+ "bubbles": true,
644
+ "cancelable": true,
645
+ "composed": true,
646
+ "docs": {
647
+ "tags": [],
648
+ "text": ""
649
+ },
650
+ "complexType": {
651
+ "original": "{\n orderId: string;\n checkoutUrl: string;\n }",
652
+ "resolved": "{ orderId: string; checkoutUrl: string; }",
653
+ "references": {}
654
+ }
655
+ }, {
656
+ "method": "cartUpdate",
657
+ "name": "cartUpdate",
658
+ "bubbles": true,
659
+ "cancelable": true,
660
+ "composed": true,
661
+ "docs": {
662
+ "tags": [],
663
+ "text": ""
664
+ },
665
+ "complexType": {
666
+ "original": "OrderQuote",
667
+ "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: string; }; admissionId?: string; sectionId?: string; admission?: { name: string; capacity: number; limit: number; order: number; entryStartsAt: string; entryEndsAt: string; saleStartsAt: string; saleEndsAt: string; price: { base: number; booking: number; currency: string; }; teamId: string; promoterId: string; eventId: string; eventSlug: string; id?: string; available?: number; sold?: number; reserved?: number; createdAt?: string; updatedAt?: string; sectionId?: string; }; section?: { name: string; capacity: number; limit: number; order: number; 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; refunded: number; discount: number; gateway: number; dispute: number; currency: string; }; couponCode?: { name: string; active: boolean; couponId: string; teamId: string; id?: string; createdAt?: string; updatedAt?: string; uses?: number; }; }",
668
+ "references": {
669
+ "OrderQuote": {
670
+ "location": "import",
671
+ "path": "@session-services/sdk/schemas",
672
+ "id": "../../sdk/src/schemas.ts::OrderQuote"
673
+ }
674
+ }
675
+ }
676
+ }, {
677
+ "method": "errorOccurred",
678
+ "name": "errorOccurred",
679
+ "bubbles": true,
680
+ "cancelable": true,
681
+ "composed": true,
682
+ "docs": {
683
+ "tags": [],
684
+ "text": ""
685
+ },
686
+ "complexType": {
687
+ "original": "{ error: string }",
688
+ "resolved": "{ error: string; }",
689
+ "references": {}
690
+ }
691
+ }];
692
+ }
693
+ static get watchers() {
694
+ return [{
695
+ "propName": "tenantId",
696
+ "methodName": "propsChanged"
697
+ }, {
698
+ "propName": "eventId",
699
+ "methodName": "propsChanged"
700
+ }, {
701
+ "propName": "apiUrl",
702
+ "methodName": "propsChanged"
703
+ }, {
704
+ "propName": "theme",
705
+ "methodName": "themeChanged"
706
+ }];
707
+ }
708
+ }