@ticketlayer/elements 0.2.0
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/LICENSE +21 -0
- package/README.md +55 -0
- package/dist/cjs/index-DfzcrE9-.js +3598 -0
- package/dist/cjs/index.cjs.js +16 -0
- package/dist/cjs/loader.cjs.js +12 -0
- package/dist/cjs/order-summary-ZMkJ5bez.js +116 -0
- package/dist/cjs/sdk-connector-ClDF3013.js +108 -0
- package/dist/cjs/ticketlayer-elements.cjs.js +24 -0
- package/dist/cjs/tl-buy-modal.cjs.entry.js +127 -0
- package/dist/cjs/tl-buy-tickets-button.cjs.entry.js +131 -0
- package/dist/cjs/tl-buy-tickets-wrapper.cjs.entry.js +58 -0
- package/dist/cjs/tl-cart-badge.cjs.entry.js +109 -0
- package/dist/cjs/tl-cart-drawer.cjs.entry.js +67 -0
- package/dist/cjs/tl-cart.cjs.entry.js +148 -0
- package/dist/cjs/tl-checkout-wrapper.cjs.entry.js +57 -0
- package/dist/cjs/tl-event-card.cjs.entry.js +140 -0
- package/dist/cjs/tl-event-list.cjs.entry.js +80 -0
- package/dist/cjs/tl-login.cjs.entry.js +184 -0
- package/dist/cjs/tl-my-orders.cjs.entry.js +123 -0
- package/dist/cjs/tl-occurrence-selector_2.cjs.entry.js +754 -0
- package/dist/cjs/tl-order-confirmation.cjs.entry.js +146 -0
- package/dist/cjs/tl-order-tickets_2.cjs.entry.js +3198 -0
- package/dist/cjs/tl-promo-code.cjs.entry.js +75 -0
- package/dist/cjs/tl-seat-map.cjs.entry.js +147 -0
- package/dist/collection/collection-manifest.json +29 -0
- package/dist/collection/components/tl-buy-modal/tl-buy-modal.css +264 -0
- package/dist/collection/components/tl-buy-modal/tl-buy-modal.js +249 -0
- package/dist/collection/components/tl-buy-tickets-button/tl-buy-tickets-button.css +120 -0
- package/dist/collection/components/tl-buy-tickets-button/tl-buy-tickets-button.js +412 -0
- package/dist/collection/components/tl-buy-tickets-wrapper/tl-buy-tickets-wrapper.css +23 -0
- package/dist/collection/components/tl-buy-tickets-wrapper/tl-buy-tickets-wrapper.js +192 -0
- package/dist/collection/components/tl-cart/tl-cart.css +251 -0
- package/dist/collection/components/tl-cart/tl-cart.js +314 -0
- package/dist/collection/components/tl-cart-badge/tl-cart-badge.css +138 -0
- package/dist/collection/components/tl-cart-badge/tl-cart-badge.js +217 -0
- package/dist/collection/components/tl-cart-drawer/tl-cart-drawer.css +98 -0
- package/dist/collection/components/tl-cart-drawer/tl-cart-drawer.js +185 -0
- package/dist/collection/components/tl-checkout-wrapper/tl-checkout-wrapper.css +23 -0
- package/dist/collection/components/tl-checkout-wrapper/tl-checkout-wrapper.js +148 -0
- package/dist/collection/components/tl-event-card/event-card-adapter.js +23 -0
- package/dist/collection/components/tl-event-card/tl-event-card.css +175 -0
- package/dist/collection/components/tl-event-card/tl-event-card.js +205 -0
- package/dist/collection/components/tl-event-list/tl-event-list.css +134 -0
- package/dist/collection/components/tl-event-list/tl-event-list.js +171 -0
- package/dist/collection/components/tl-login/tl-login.css +133 -0
- package/dist/collection/components/tl-login/tl-login.js +309 -0
- package/dist/collection/components/tl-my-orders/tl-my-orders.css +204 -0
- package/dist/collection/components/tl-my-orders/tl-my-orders.js +221 -0
- package/dist/collection/components/tl-occurrence-selector/tl-occurrence-selector.css +658 -0
- package/dist/collection/components/tl-occurrence-selector/tl-occurrence-selector.js +707 -0
- package/dist/collection/components/tl-order-confirmation/tl-order-confirmation.css +176 -0
- package/dist/collection/components/tl-order-confirmation/tl-order-confirmation.js +298 -0
- package/dist/collection/components/tl-order-tickets/tl-order-tickets.css +30 -0
- package/dist/collection/components/tl-order-tickets/tl-order-tickets.js +122 -0
- package/dist/collection/components/tl-promo-code/tl-promo-code.css +106 -0
- package/dist/collection/components/tl-promo-code/tl-promo-code.js +181 -0
- package/dist/collection/components/tl-seat-map/tl-seat-map.css +85 -0
- package/dist/collection/components/tl-seat-map/tl-seat-map.js +366 -0
- package/dist/collection/components/tl-ticket/tl-ticket.css +90 -0
- package/dist/collection/components/tl-ticket/tl-ticket.js +129 -0
- package/dist/collection/components/tl-ticket-selector/tl-ticket-selector.css +205 -0
- package/dist/collection/components/tl-ticket-selector/tl-ticket-selector.js +332 -0
- package/dist/collection/index.js +10 -0
- package/dist/collection/utils/order-summary.js +101 -0
- package/dist/collection/utils/sdk-connector.js +100 -0
- package/dist/collection/utils/testing/mock-sdk.js +95 -0
- package/dist/components/index.d.ts +35 -0
- package/dist/components/index.js +1 -0
- package/dist/components/order-summary.js +1 -0
- package/dist/components/sdk-connector.js +1 -0
- package/dist/components/tl-buy-modal.d.ts +11 -0
- package/dist/components/tl-buy-modal.js +1 -0
- package/dist/components/tl-buy-tickets-button.d.ts +11 -0
- package/dist/components/tl-buy-tickets-button.js +1 -0
- package/dist/components/tl-buy-tickets-wrapper.d.ts +11 -0
- package/dist/components/tl-buy-tickets-wrapper.js +1 -0
- package/dist/components/tl-buy-tickets-wrapper2.js +1 -0
- package/dist/components/tl-cart-badge.d.ts +11 -0
- package/dist/components/tl-cart-badge.js +1 -0
- package/dist/components/tl-cart-drawer.d.ts +11 -0
- package/dist/components/tl-cart-drawer.js +1 -0
- package/dist/components/tl-cart.d.ts +11 -0
- package/dist/components/tl-cart.js +1 -0
- package/dist/components/tl-cart2.js +1 -0
- package/dist/components/tl-checkout-wrapper.d.ts +11 -0
- package/dist/components/tl-checkout-wrapper.js +1 -0
- package/dist/components/tl-checkout-wrapper2.js +1 -0
- package/dist/components/tl-event-card.d.ts +11 -0
- package/dist/components/tl-event-card.js +1 -0
- package/dist/components/tl-event-card2.js +1 -0
- package/dist/components/tl-event-list.d.ts +11 -0
- package/dist/components/tl-event-list.js +1 -0
- package/dist/components/tl-login.d.ts +11 -0
- package/dist/components/tl-login.js +1 -0
- package/dist/components/tl-login2.js +1 -0
- package/dist/components/tl-my-orders.d.ts +11 -0
- package/dist/components/tl-my-orders.js +1 -0
- package/dist/components/tl-occurrence-selector.d.ts +11 -0
- package/dist/components/tl-occurrence-selector.js +1 -0
- package/dist/components/tl-occurrence-selector2.js +1 -0
- package/dist/components/tl-order-confirmation.d.ts +11 -0
- package/dist/components/tl-order-confirmation.js +1 -0
- package/dist/components/tl-order-tickets.d.ts +11 -0
- package/dist/components/tl-order-tickets.js +1 -0
- package/dist/components/tl-order-tickets2.js +1 -0
- package/dist/components/tl-promo-code.d.ts +11 -0
- package/dist/components/tl-promo-code.js +1 -0
- package/dist/components/tl-seat-map.d.ts +11 -0
- package/dist/components/tl-seat-map.js +1 -0
- package/dist/components/tl-ticket-selector.d.ts +11 -0
- package/dist/components/tl-ticket-selector.js +1 -0
- package/dist/components/tl-ticket-selector2.js +1 -0
- package/dist/components/tl-ticket.d.ts +11 -0
- package/dist/components/tl-ticket.js +1 -0
- package/dist/components/tl-ticket2.js +1 -0
- package/dist/elements.docs.d.ts +454 -0
- package/dist/elements.docs.json +3008 -0
- package/dist/esm/index-Ba-RZTFI.js +3588 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/loader.js +10 -0
- package/dist/esm/order-summary-BGekdjN9.js +103 -0
- package/dist/esm/sdk-connector-CqhvfyKV.js +102 -0
- package/dist/esm/ticketlayer-elements.js +20 -0
- package/dist/esm/tl-buy-modal.entry.js +125 -0
- package/dist/esm/tl-buy-tickets-button.entry.js +129 -0
- package/dist/esm/tl-buy-tickets-wrapper.entry.js +56 -0
- package/dist/esm/tl-cart-badge.entry.js +107 -0
- package/dist/esm/tl-cart-drawer.entry.js +65 -0
- package/dist/esm/tl-cart.entry.js +146 -0
- package/dist/esm/tl-checkout-wrapper.entry.js +55 -0
- package/dist/esm/tl-event-card.entry.js +138 -0
- package/dist/esm/tl-event-list.entry.js +78 -0
- package/dist/esm/tl-login.entry.js +182 -0
- package/dist/esm/tl-my-orders.entry.js +121 -0
- package/dist/esm/tl-occurrence-selector_2.entry.js +751 -0
- package/dist/esm/tl-order-confirmation.entry.js +144 -0
- package/dist/esm/tl-order-tickets_2.entry.js +3195 -0
- package/dist/esm/tl-promo-code.entry.js +73 -0
- package/dist/esm/tl-seat-map.entry.js +145 -0
- package/dist/index.cjs.js +1 -0
- package/dist/index.js +1 -0
- package/dist/ticketlayer-elements/index.esm.js +1 -0
- package/dist/ticketlayer-elements/p-0291df4c.entry.js +1 -0
- package/dist/ticketlayer-elements/p-10f01a1f.entry.js +1 -0
- package/dist/ticketlayer-elements/p-11273f8f.entry.js +1 -0
- package/dist/ticketlayer-elements/p-340ab4f5.entry.js +1 -0
- package/dist/ticketlayer-elements/p-41d22d7c.entry.js +1 -0
- package/dist/ticketlayer-elements/p-82752e3b.entry.js +1 -0
- package/dist/ticketlayer-elements/p-976770f3.entry.js +1 -0
- package/dist/ticketlayer-elements/p-9a903ff6.entry.js +1 -0
- package/dist/ticketlayer-elements/p-9c9072c8.entry.js +1 -0
- package/dist/ticketlayer-elements/p-9d8163d6.entry.js +1 -0
- package/dist/ticketlayer-elements/p-BGekdjN9.js +1 -0
- package/dist/ticketlayer-elements/p-Ba-RZTFI.js +2 -0
- package/dist/ticketlayer-elements/p-CqhvfyKV.js +1 -0
- package/dist/ticketlayer-elements/p-a5c90b68.entry.js +1 -0
- package/dist/ticketlayer-elements/p-b6d479ad.entry.js +1 -0
- package/dist/ticketlayer-elements/p-dd43f015.entry.js +1 -0
- package/dist/ticketlayer-elements/p-eb640760.entry.js +1 -0
- package/dist/ticketlayer-elements/p-ee3aa227.entry.js +1 -0
- package/dist/ticketlayer-elements/p-fb9444c4.entry.js +1 -0
- package/dist/ticketlayer-elements/ticketlayer-elements.css +1 -0
- package/dist/ticketlayer-elements/ticketlayer-elements.esm.js +1 -0
- package/dist/types/components/tl-buy-modal/tl-buy-modal.d.ts +54 -0
- package/dist/types/components/tl-buy-tickets-button/tl-buy-tickets-button.d.ts +61 -0
- package/dist/types/components/tl-buy-tickets-wrapper/tl-buy-tickets-wrapper.d.ts +52 -0
- package/dist/types/components/tl-cart/tl-cart.d.ts +80 -0
- package/dist/types/components/tl-cart-badge/tl-cart-badge.d.ts +36 -0
- package/dist/types/components/tl-cart-drawer/tl-cart-drawer.d.ts +35 -0
- package/dist/types/components/tl-checkout-wrapper/tl-checkout-wrapper.d.ts +39 -0
- package/dist/types/components/tl-event-card/event-card-adapter.d.ts +23 -0
- package/dist/types/components/tl-event-card/tl-event-card.d.ts +55 -0
- package/dist/types/components/tl-event-list/tl-event-list.d.ts +30 -0
- package/dist/types/components/tl-login/tl-login.d.ts +59 -0
- package/dist/types/components/tl-my-orders/tl-my-orders.d.ts +39 -0
- package/dist/types/components/tl-occurrence-selector/tl-occurrence-selector.d.ts +208 -0
- package/dist/types/components/tl-order-confirmation/tl-order-confirmation.d.ts +54 -0
- package/dist/types/components/tl-order-tickets/tl-order-tickets.d.ts +21 -0
- package/dist/types/components/tl-promo-code/tl-promo-code.d.ts +39 -0
- package/dist/types/components/tl-seat-map/tl-seat-map.d.ts +68 -0
- package/dist/types/components/tl-ticket/tl-ticket.d.ts +28 -0
- package/dist/types/components/tl-ticket-selector/tl-ticket-selector.d.ts +78 -0
- package/dist/types/components.d.ts +1629 -0
- package/dist/types/index.d.ts +14 -0
- package/dist/types/stencil-public-runtime.d.ts +1839 -0
- package/dist/types/utils/order-summary.d.ts +67 -0
- package/dist/types/utils/sdk-connector.d.ts +113 -0
- package/dist/types/utils/testing/mock-sdk.d.ts +36 -0
- package/elements.catalogue.json +968 -0
- package/loader/cdn.js +1 -0
- package/loader/index.cjs.js +1 -0
- package/loader/index.d.ts +24 -0
- package/loader/index.es2017.js +1 -0
- package/loader/index.js +2 -0
- package/package.json +101 -0
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { g as getSDK, h as hasSDK, o as onSDKEvent, s as setSDK, w as whenSDK } from './sdk-connector-CqhvfyKV.js';
|
|
2
|
+
export { tl_buy_tickets_wrapper as TlBuyTicketsWrapper } from './tl-buy-tickets-wrapper.entry.js';
|
|
3
|
+
export { tl_checkout_wrapper as TlCheckoutWrapper } from './tl-checkout-wrapper.entry.js';
|
|
4
|
+
import './index-Ba-RZTFI.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { g as globalScripts, b as bootstrapLazy } from './index-Ba-RZTFI.js';
|
|
2
|
+
export { s as setNonce } from './index-Ba-RZTFI.js';
|
|
3
|
+
|
|
4
|
+
const defineCustomElements = async (win, options) => {
|
|
5
|
+
if (typeof window === 'undefined') return undefined;
|
|
6
|
+
await globalScripts();
|
|
7
|
+
return bootstrapLazy([["tl-my-orders",[[1,"tl-my-orders",{"emptyMessage":[1,"empty-message"],"columns":[2],"orders":[32],"authenticated":[32],"loading":[32],"error":[32],"expandedId":[32]}]]],["tl-buy-modal",[[1,"tl-buy-modal",{"eventId":[1,"event-id"],"occurrenceId":[1,"occurrence-id"],"step":[32],"eventName":[32],"imageUrl":[32],"venueLabel":[32],"dateSummary":[32],"selectedOccurrenceId":[32],"occurrenceCount":[32],"occurrenceLabel":[32],"error":[32]}]]],["tl-order-confirmation",[[1,"tl-order-confirmation",{"orderId":[1,"order-id"],"customerEmail":[1,"customer-email"],"showTickets":[4,"show-tickets"],"columns":[2],"order":[32],"resolvedOrderId":[32],"loading":[32],"error":[32],"paymentFailed":[32],"occurrence":[32],"signedInCustomer":[32]},null,{"orderId":[{"watchOrderId":0}]}]]],["tl-cart-drawer",[[1,"tl-cart-drawer",{"side":[1],"heading":[1],"open":[1028],"visible":[32]},null,{"open":[{"onOpenProp":0}]}]]],["tl-event-list",[[1,"tl-event-list",{"limit":[2],"category":[1],"columns":[2],"events":[32],"loading":[32],"error":[32]},null,{"limit":[{"watchFiltersChange":0}],"category":[{"watchFiltersChange":0}]}]]],["tl-buy-tickets-button",[[1,"tl-buy-tickets-button",{"eventId":[1,"event-id"],"occurrenceId":[1,"occurrence-id"],"state":[1],"label":[1],"variant":[1],"size":[1],"fullWidth":[4,"full-width"],"price":[2],"currency":[1],"pricePrefix":[1,"price-prefix"],"disabled":[4],"isHovered":[32]}]]],["tl-buy-tickets-wrapper",[[260,"tl-buy-tickets-wrapper",{"eventId":[1,"event-id"],"occurrenceId":[1,"occurrence-id"],"disabled":[4]}]]],["tl-cart-badge",[[1,"tl-cart-badge",{"showEmpty":[4,"show-empty"],"icon":[1],"size":[1],"badgeOnly":[4,"badge-only"],"itemCount":[32]}]]],["tl-checkout-wrapper",[[260,"tl-checkout-wrapper",{"disabled":[4]}]]],["tl-promo-code",[[1,"tl-promo-code",{"placeholder":[1],"buttonLabel":[1,"button-label"],"code":[32],"applying":[32],"applied":[32],"error":[32]}]]],["tl-seat-map",[[1,"tl-seat-map",{"occurrenceId":[1,"occurrence-id"],"hboUrl":[1,"hbo-url"],"apiUrl":[1,"api-url"],"height":[1],"width":[1],"isReady":[32],"isLoading":[32],"error":[32],"seatsInCart":[32]},null,{"occurrenceId":[{"watchOccurrenceId":0}]}]]],["tl-cart",[[1,"tl-cart",{"showCheckoutButton":[4,"show-checkout-button"],"checkoutLabel":[1,"checkout-label"],"showRemoveButtons":[4,"show-remove-buttons"],"compact":[4],"cart":[32],"loading":[32],"error":[32],"removingItemId":[32]}]]],["tl-event-card",[[1,"tl-event-card",{"event":[16],"eventId":[1,"event-id"],"loadedEvent":[32],"loading":[32],"error":[32]},null,{"eventId":[{"watchEventId":0}]}]]],["tl-login",[[1,"tl-login",{"heading":[1],"allowCodeEntry":[4,"allow-code-entry"],"phase":[32],"email":[32],"code":[32],"busy":[32],"error":[32],"notice":[32],"customer":[32]}]]],["tl-occurrence-selector_2",[[1,"tl-occurrence-selector",{"eventId":[1,"event-id"],"displayMode":[1,"display-mode"],"orientation":[1],"theme":[16],"loading":[32],"error":[32],"occurrences":[32],"currentMonth":[32],"selectedDate":[32],"computedDisplayMode":[32],"containerWidth":[32]},null,{"eventId":[{"onEventIdChange":0}]}],[1,"tl-ticket-selector",{"eventId":[1,"event-id"],"occurrenceId":[1,"occurrence-id"],"showButton":[4,"show-button"],"buttonLabel":[1,"button-label"],"ticketTypes":[32],"quantities":[32],"loading":[32],"error":[32],"adding":[32],"addSuccess":[32]},null,{"eventId":[{"watchPropsChange":0}],"occurrenceId":[{"watchPropsChange":0}]}]]],["tl-order-tickets_2",[[1,"tl-order-tickets",{"orderId":[1,"order-id"],"columns":[2],"tickets":[32],"loading":[32],"error":[32]},null,{"orderId":[{"watchOrder":0}]}],[1,"tl-ticket",{"ticket":[16],"orderId":[1,"order-id"],"qrSvg":[32],"downloading":[32]},null,{"ticket":[{"generateQr":0}]}]]]], options);
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export { defineCustomElements };
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/** Money arrives as minor-unit integers or decimal strings ("50.00"). */
|
|
2
|
+
function formatPrice(value, currency = 'GBP') {
|
|
3
|
+
if (value === null || value === undefined || value === '')
|
|
4
|
+
return '';
|
|
5
|
+
const fmt = new Intl.NumberFormat('en-GB', { style: 'currency', currency });
|
|
6
|
+
if (typeof value === 'number')
|
|
7
|
+
return fmt.format(value / 100);
|
|
8
|
+
const n = Number(value);
|
|
9
|
+
return Number.isNaN(n) ? String(value) : fmt.format(n);
|
|
10
|
+
}
|
|
11
|
+
function formatDateTime(iso) {
|
|
12
|
+
return new Date(iso).toLocaleDateString('en-GB', {
|
|
13
|
+
weekday: 'short',
|
|
14
|
+
day: 'numeric',
|
|
15
|
+
month: 'short',
|
|
16
|
+
year: 'numeric',
|
|
17
|
+
hour: '2-digit',
|
|
18
|
+
minute: '2-digit',
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function formatDate(iso) {
|
|
22
|
+
return new Date(iso).toLocaleDateString('en-GB', {
|
|
23
|
+
day: 'numeric',
|
|
24
|
+
month: 'short',
|
|
25
|
+
year: 'numeric',
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/** Line items that are tickets (fees, taxes and discounts have their own type). */
|
|
29
|
+
function ticketItems(order) {
|
|
30
|
+
return (order.items ?? []).filter((i) => !i.type || i.type === 'ticket');
|
|
31
|
+
}
|
|
32
|
+
function ticketCount(order) {
|
|
33
|
+
const fromItems = ticketItems(order).reduce((sum, i) => sum + (Number(i.quantity) || 0), 0);
|
|
34
|
+
return fromItems || order.tickets?.length || 0;
|
|
35
|
+
}
|
|
36
|
+
/** Event name as the order view exposes it: the first ticket line's name. */
|
|
37
|
+
function orderEventName(order) {
|
|
38
|
+
return order.eventName || ticketItems(order)[0]?.name || order.items?.[0]?.name || null;
|
|
39
|
+
}
|
|
40
|
+
function orderCustomerEmail(order, customer) {
|
|
41
|
+
const fromOrder = order?.customerEmail || order?.customer?.email;
|
|
42
|
+
if (fromOrder)
|
|
43
|
+
return fromOrder;
|
|
44
|
+
const c = customer;
|
|
45
|
+
return c?.email || null;
|
|
46
|
+
}
|
|
47
|
+
function statusLabel(status) {
|
|
48
|
+
if (!status)
|
|
49
|
+
return '';
|
|
50
|
+
return status.replace(/_/g, ' ').replace(/^\w/, (m) => m.toUpperCase());
|
|
51
|
+
}
|
|
52
|
+
function statusTone(status) {
|
|
53
|
+
switch (status) {
|
|
54
|
+
case 'confirmed':
|
|
55
|
+
return 'success';
|
|
56
|
+
case 'completed':
|
|
57
|
+
case 'fulfilled':
|
|
58
|
+
return 'info';
|
|
59
|
+
case 'pending':
|
|
60
|
+
case 'processing':
|
|
61
|
+
return 'warning';
|
|
62
|
+
case 'cancelled':
|
|
63
|
+
case 'expired':
|
|
64
|
+
case 'failed':
|
|
65
|
+
return 'error';
|
|
66
|
+
default:
|
|
67
|
+
return 'muted';
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function errorMessage(err, fallback) {
|
|
71
|
+
return err instanceof Error && err.message ? err.message : fallback;
|
|
72
|
+
}
|
|
73
|
+
/** True for the "not signed in" family of API errors (401/403, NO_SESSION, NOT_AUTHENTICATED). */
|
|
74
|
+
function isAuthError(err) {
|
|
75
|
+
const e = err;
|
|
76
|
+
if (!e || typeof e !== 'object')
|
|
77
|
+
return false;
|
|
78
|
+
return e.status === 401 || e.status === 403 || e.code === 'NO_SESSION' || e.code === 'NOT_AUTHENTICATED';
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Find the event and start time for an occurrence id. The order view only
|
|
82
|
+
* carries the occurrence id, so this walks the channel's listings (cached by
|
|
83
|
+
* live-api) until one owns the occurrence. Best effort: null when not found.
|
|
84
|
+
*/
|
|
85
|
+
async function resolveOccurrence(sdk, occurrenceId, maxEvents = 12) {
|
|
86
|
+
const events = sdk.getEventsManager();
|
|
87
|
+
const listing = await events.list({ limit: maxEvents });
|
|
88
|
+
const candidates = listing.items.slice(0, maxEvents);
|
|
89
|
+
for (const candidate of candidates) {
|
|
90
|
+
const detail = (await events.get(candidate.id).catch(() => null));
|
|
91
|
+
const occ = detail?.occurrences?.find((o) => o.id === occurrenceId);
|
|
92
|
+
if (occ) {
|
|
93
|
+
return {
|
|
94
|
+
eventId: detail?.id ?? candidate.id,
|
|
95
|
+
eventName: detail?.name ?? candidate.name ?? '',
|
|
96
|
+
startsAt: occ.startsAt ?? null,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export { formatPrice as a, statusLabel as b, formatDateTime as c, orderCustomerEmail as d, errorMessage as e, formatDate as f, ticketItems as g, isAuthError as i, orderEventName as o, resolveOccurrence as r, statusTone as s, ticketCount as t };
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK Connector
|
|
3
|
+
*
|
|
4
|
+
* Utility to connect external SDK instances to Elements components.
|
|
5
|
+
*/
|
|
6
|
+
// The SDK is shared between bundles via the `window.Ticketlayer` registry that
|
|
7
|
+
// @ticketlayer/live publishes (createLiveClient → publishClient). Elements never
|
|
8
|
+
// import the SDK; they read this global and bind to its connector view.
|
|
9
|
+
const READY_EVENT = 'ticketlayer:ready';
|
|
10
|
+
// Back-compat slot for hosts that install a connector manually via setSDK().
|
|
11
|
+
const MANUAL_SLOT = '__TICKETLAYER_SDK__';
|
|
12
|
+
function readGlobalSDK() {
|
|
13
|
+
if (typeof window === 'undefined')
|
|
14
|
+
return null;
|
|
15
|
+
const win = window;
|
|
16
|
+
const reg = win.Ticketlayer;
|
|
17
|
+
return (reg?.getSDK?.() ?? reg?.sdk ?? win[MANUAL_SLOT]) || null;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Manually install an SDK/connector instance (escape hatch). The normal path is
|
|
21
|
+
* for the host to call createLiveClient(), which auto-publishes on the registry.
|
|
22
|
+
*/
|
|
23
|
+
function setSDK(sdk) {
|
|
24
|
+
if (typeof window === 'undefined')
|
|
25
|
+
return;
|
|
26
|
+
window[MANUAL_SLOT] = sdk;
|
|
27
|
+
// Wake any components already awaiting whenSDK().
|
|
28
|
+
window.dispatchEvent(new CustomEvent(READY_EVENT, { detail: sdk }));
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get the SDK instance synchronously. Throws if not yet available - prefer
|
|
32
|
+
* whenSDK() in lifecycle methods so mounting before Live is ready isn't an error.
|
|
33
|
+
*/
|
|
34
|
+
function getSDK() {
|
|
35
|
+
const sdk = readGlobalSDK();
|
|
36
|
+
if (!sdk) {
|
|
37
|
+
throw new Error('[Ticketlayer Elements] SDK not ready. Create a Live client (createLiveClient) ' +
|
|
38
|
+
'or await whenSDK() before using Elements.');
|
|
39
|
+
}
|
|
40
|
+
return sdk;
|
|
41
|
+
}
|
|
42
|
+
/** True if a client is currently registered. */
|
|
43
|
+
function hasSDK() {
|
|
44
|
+
return readGlobalSDK() !== null;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Resolve when the SDK is available - immediately if Live is already up, else
|
|
48
|
+
* on the `ticketlayer:ready` event. Replaces busy-wait polling in components.
|
|
49
|
+
*/
|
|
50
|
+
function whenSDK(timeoutMs = 15000) {
|
|
51
|
+
const existing = readGlobalSDK();
|
|
52
|
+
if (existing)
|
|
53
|
+
return Promise.resolve(existing);
|
|
54
|
+
if (typeof window === 'undefined') {
|
|
55
|
+
return Promise.reject(new Error('[Ticketlayer Elements] No window; SDK unavailable.'));
|
|
56
|
+
}
|
|
57
|
+
return new Promise((resolve, reject) => {
|
|
58
|
+
let settled = false;
|
|
59
|
+
const finish = () => {
|
|
60
|
+
const sdk = readGlobalSDK();
|
|
61
|
+
if (sdk && !settled) {
|
|
62
|
+
settled = true;
|
|
63
|
+
cleanup();
|
|
64
|
+
resolve(sdk);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
const cleanup = () => {
|
|
68
|
+
window.removeEventListener(READY_EVENT, finish);
|
|
69
|
+
clearTimeout(timer);
|
|
70
|
+
};
|
|
71
|
+
const timer = setTimeout(() => {
|
|
72
|
+
if (settled)
|
|
73
|
+
return;
|
|
74
|
+
settled = true;
|
|
75
|
+
cleanup();
|
|
76
|
+
reject(new Error('[Ticketlayer Elements] SDK not initialized. Create a Live client before using Elements.'));
|
|
77
|
+
}, timeoutMs);
|
|
78
|
+
window.addEventListener(READY_EVENT, finish);
|
|
79
|
+
// Late-publish race guard: re-check once listener is attached.
|
|
80
|
+
finish();
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Subscribe to SDK events (waits for the SDK, returns an unsubscribe function).
|
|
85
|
+
*/
|
|
86
|
+
function onSDKEvent(event, callback) {
|
|
87
|
+
let off = null;
|
|
88
|
+
let cancelled = false;
|
|
89
|
+
whenSDK()
|
|
90
|
+
.then((sdk) => {
|
|
91
|
+
if (cancelled)
|
|
92
|
+
return;
|
|
93
|
+
off = sdk.on(event, callback);
|
|
94
|
+
})
|
|
95
|
+
.catch(() => undefined);
|
|
96
|
+
return () => {
|
|
97
|
+
cancelled = true;
|
|
98
|
+
off?.();
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export { getSDK as g, hasSDK as h, onSDKEvent as o, setSDK as s, whenSDK as w };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { p as promiseResolve, g as globalScripts, b as bootstrapLazy } from './index-Ba-RZTFI.js';
|
|
2
|
+
export { s as setNonce } from './index-Ba-RZTFI.js';
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
Stencil Client Patch Browser v4.41.1 | MIT Licensed | https://stenciljs.com
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
var patchBrowser = () => {
|
|
9
|
+
const importMeta = import.meta.url;
|
|
10
|
+
const opts = {};
|
|
11
|
+
if (importMeta !== "") {
|
|
12
|
+
opts.resourcesUrl = new URL(".", importMeta).href;
|
|
13
|
+
}
|
|
14
|
+
return promiseResolve(opts);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
patchBrowser().then(async (options) => {
|
|
18
|
+
await globalScripts();
|
|
19
|
+
return bootstrapLazy([["tl-my-orders",[[1,"tl-my-orders",{"emptyMessage":[1,"empty-message"],"columns":[2],"orders":[32],"authenticated":[32],"loading":[32],"error":[32],"expandedId":[32]}]]],["tl-buy-modal",[[1,"tl-buy-modal",{"eventId":[1,"event-id"],"occurrenceId":[1,"occurrence-id"],"step":[32],"eventName":[32],"imageUrl":[32],"venueLabel":[32],"dateSummary":[32],"selectedOccurrenceId":[32],"occurrenceCount":[32],"occurrenceLabel":[32],"error":[32]}]]],["tl-order-confirmation",[[1,"tl-order-confirmation",{"orderId":[1,"order-id"],"customerEmail":[1,"customer-email"],"showTickets":[4,"show-tickets"],"columns":[2],"order":[32],"resolvedOrderId":[32],"loading":[32],"error":[32],"paymentFailed":[32],"occurrence":[32],"signedInCustomer":[32]},null,{"orderId":[{"watchOrderId":0}]}]]],["tl-cart-drawer",[[1,"tl-cart-drawer",{"side":[1],"heading":[1],"open":[1028],"visible":[32]},null,{"open":[{"onOpenProp":0}]}]]],["tl-event-list",[[1,"tl-event-list",{"limit":[2],"category":[1],"columns":[2],"events":[32],"loading":[32],"error":[32]},null,{"limit":[{"watchFiltersChange":0}],"category":[{"watchFiltersChange":0}]}]]],["tl-buy-tickets-button",[[1,"tl-buy-tickets-button",{"eventId":[1,"event-id"],"occurrenceId":[1,"occurrence-id"],"state":[1],"label":[1],"variant":[1],"size":[1],"fullWidth":[4,"full-width"],"price":[2],"currency":[1],"pricePrefix":[1,"price-prefix"],"disabled":[4],"isHovered":[32]}]]],["tl-buy-tickets-wrapper",[[260,"tl-buy-tickets-wrapper",{"eventId":[1,"event-id"],"occurrenceId":[1,"occurrence-id"],"disabled":[4]}]]],["tl-cart-badge",[[1,"tl-cart-badge",{"showEmpty":[4,"show-empty"],"icon":[1],"size":[1],"badgeOnly":[4,"badge-only"],"itemCount":[32]}]]],["tl-checkout-wrapper",[[260,"tl-checkout-wrapper",{"disabled":[4]}]]],["tl-promo-code",[[1,"tl-promo-code",{"placeholder":[1],"buttonLabel":[1,"button-label"],"code":[32],"applying":[32],"applied":[32],"error":[32]}]]],["tl-seat-map",[[1,"tl-seat-map",{"occurrenceId":[1,"occurrence-id"],"hboUrl":[1,"hbo-url"],"apiUrl":[1,"api-url"],"height":[1],"width":[1],"isReady":[32],"isLoading":[32],"error":[32],"seatsInCart":[32]},null,{"occurrenceId":[{"watchOccurrenceId":0}]}]]],["tl-cart",[[1,"tl-cart",{"showCheckoutButton":[4,"show-checkout-button"],"checkoutLabel":[1,"checkout-label"],"showRemoveButtons":[4,"show-remove-buttons"],"compact":[4],"cart":[32],"loading":[32],"error":[32],"removingItemId":[32]}]]],["tl-event-card",[[1,"tl-event-card",{"event":[16],"eventId":[1,"event-id"],"loadedEvent":[32],"loading":[32],"error":[32]},null,{"eventId":[{"watchEventId":0}]}]]],["tl-login",[[1,"tl-login",{"heading":[1],"allowCodeEntry":[4,"allow-code-entry"],"phase":[32],"email":[32],"code":[32],"busy":[32],"error":[32],"notice":[32],"customer":[32]}]]],["tl-occurrence-selector_2",[[1,"tl-occurrence-selector",{"eventId":[1,"event-id"],"displayMode":[1,"display-mode"],"orientation":[1],"theme":[16],"loading":[32],"error":[32],"occurrences":[32],"currentMonth":[32],"selectedDate":[32],"computedDisplayMode":[32],"containerWidth":[32]},null,{"eventId":[{"onEventIdChange":0}]}],[1,"tl-ticket-selector",{"eventId":[1,"event-id"],"occurrenceId":[1,"occurrence-id"],"showButton":[4,"show-button"],"buttonLabel":[1,"button-label"],"ticketTypes":[32],"quantities":[32],"loading":[32],"error":[32],"adding":[32],"addSuccess":[32]},null,{"eventId":[{"watchPropsChange":0}],"occurrenceId":[{"watchPropsChange":0}]}]]],["tl-order-tickets_2",[[1,"tl-order-tickets",{"orderId":[1,"order-id"],"columns":[2],"tickets":[32],"loading":[32],"error":[32]},null,{"orderId":[{"watchOrder":0}]}],[1,"tl-ticket",{"ticket":[16],"orderId":[1,"order-id"],"qrSvg":[32],"downloading":[32]},null,{"ticket":[{"generateQr":0}]}]]]], options);
|
|
20
|
+
});
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { r as registerInstance, c as createEvent, h, H as Host } from './index-Ba-RZTFI.js';
|
|
2
|
+
import { w as whenSDK, g as getSDK } from './sdk-connector-CqhvfyKV.js';
|
|
3
|
+
|
|
4
|
+
const tlBuyModalCss = () => `:host{--_bg:var(--tl-background, #ffffff);--_fg:var(--tl-foreground, #111827);--_muted:var(--tl-muted, #f3f4f6);--_muted-fg:var(--tl-muted-foreground, #6b7280);--_border:var(--tl-border, #e5e7eb);--_primary:var(--tl-primary, #6366f1);--_primary-fg:var(--tl-primary-foreground, #ffffff);--_radius:var(--tl-radius-lg, var(--tl-radius, 0.75rem));--_font:var(--tl-font-family, system-ui, -apple-system, sans-serif);font-family:var(--_font)}.overlay{position:fixed;inset:0;z-index:2147483646;display:flex;align-items:center;justify-content:center;padding:16px;background:rgba(8, 8, 16, 0.72);backdrop-filter:blur(4px);animation:tl-fade 0.18s ease-out}.panel{width:100%;max-width:460px;max-height:90vh;display:flex;flex-direction:column;overflow:hidden;background:var(--_bg);color:var(--_fg);border:1px solid var(--_border);border-radius:var(--_radius);box-shadow:0 24px 64px rgba(0, 0, 0, 0.45);animation:tl-rise 0.22s cubic-bezier(0.16, 1, 0.3, 1);transition:max-width 0.25s cubic-bezier(0.16, 1, 0.3, 1)}.panel--wide{max-width:720px}.panel-header{display:flex;align-items:center;gap:14px;padding:16px 18px;border-bottom:1px solid var(--_border)}.event-thumb{flex:none;width:56px;height:56px;border-radius:12px;background-size:cover;background-position:center;background-color:var(--_muted);border:1px solid var(--_border)}.titles{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1}.event-meta{margin:0;font-size:0.8rem;color:var(--_muted-fg);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kicker{font-size:0.72rem;font-weight:600;letter-spacing:0.08em;text-transform:uppercase;color:var(--_primary)}.event-name{margin:0;font-size:1.18rem;font-weight:700;line-height:1.25;color:var(--_fg);overflow:hidden;text-overflow:ellipsis}.close-btn{flex:none;display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;border:0;border-radius:999px;background:var(--_muted);color:var(--_muted-fg);cursor:pointer;transition:color 0.15s, background 0.15s}.close-btn:hover{color:var(--_fg)}.close-btn svg{width:16px;height:16px}.panel-body{padding:18px 22px 22px;overflow-y:auto}.state-msg{display:flex;align-items:center;justify-content:center;gap:10px;padding:40px 0;color:var(--_muted-fg)}.state-msg.error{color:#b91c1c}.spinner{width:16px;height:16px;border:2px solid var(--_border);border-top-color:var(--_primary);border-radius:999px;animation:tl-spin 0.7s linear infinite}.tickets-step{display:flex;flex-direction:column;gap:6px}.back-link{align-self:flex-start;padding:0;border:0;background:none;color:var(--_primary);font-size:0.85rem;font-weight:500;cursor:pointer}.back-link:hover{text-decoration:underline}.occ-label{margin:2px 0 8px;font-size:0.9rem;font-weight:600;color:var(--_fg)}.done-step{display:flex;flex-direction:column;align-items:center;text-align:center;gap:6px;padding:16px 0 4px}.done-mark{font-size:2.4rem;line-height:1;margin-bottom:6px}.done-title{margin:0;font-size:1.1rem;font-weight:700;color:var(--_fg)}.done-sub{margin:0 0 14px;font-size:0.9rem;color:var(--_muted-fg)}.primary-btn{width:100%;padding:13px;border:0;border-radius:var(--tl-radius-md, 0.5rem);background:var(--_primary);color:var(--_primary-fg);font-size:0.98rem;font-weight:600;cursor:pointer;transition:opacity 0.15s}.primary-btn:hover{opacity:0.9}.ghost-btn{width:100%;margin-top:8px;padding:12px;border:1px solid var(--_border);border-radius:var(--tl-radius-md, 0.5rem);background:transparent;color:var(--_fg);font-size:0.95rem;font-weight:500;cursor:pointer;transition:background 0.15s}.ghost-btn:hover{background:var(--_muted)}@keyframes tl-fade{from{opacity:0}}@keyframes tl-rise{from{opacity:0;transform:translateY(12px) scale(0.98)}}@keyframes tl-spin{to{transform:rotate(360deg)}}`;
|
|
5
|
+
|
|
6
|
+
const TlBuyModal = class {
|
|
7
|
+
constructor(hostRef) {
|
|
8
|
+
registerInstance(this, hostRef);
|
|
9
|
+
this.tlClose = createEvent(this, "tlClose");
|
|
10
|
+
this.tlCheckout = createEvent(this, "tlCheckout");
|
|
11
|
+
this.tlError = createEvent(this, "tlError");
|
|
12
|
+
this.step = 'loading';
|
|
13
|
+
this.eventName = '';
|
|
14
|
+
this.imageUrl = '';
|
|
15
|
+
this.venueLabel = '';
|
|
16
|
+
this.dateSummary = '';
|
|
17
|
+
this.selectedOccurrenceId = null;
|
|
18
|
+
this.occurrenceCount = 0;
|
|
19
|
+
this.occurrenceLabel = '';
|
|
20
|
+
this.error = null;
|
|
21
|
+
this.handleOccurrenceSelect = (e) => {
|
|
22
|
+
const occ = e.detail.occurrence;
|
|
23
|
+
this.selectedOccurrenceId = occ.id;
|
|
24
|
+
this.occurrenceLabel = this.labelFor(occ);
|
|
25
|
+
this.step = 'tickets';
|
|
26
|
+
};
|
|
27
|
+
this.handleAdded = () => {
|
|
28
|
+
this.step = 'done';
|
|
29
|
+
};
|
|
30
|
+
this.backToDates = () => {
|
|
31
|
+
this.selectedOccurrenceId = null;
|
|
32
|
+
this.step = 'occurrence';
|
|
33
|
+
};
|
|
34
|
+
this.close = () => this.tlClose.emit();
|
|
35
|
+
this.goCheckout = () => this.tlCheckout.emit();
|
|
36
|
+
}
|
|
37
|
+
async componentWillLoad() {
|
|
38
|
+
if (!this.eventId) {
|
|
39
|
+
this.fail('No event specified');
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
await whenSDK();
|
|
44
|
+
const ev = (await getSDK().getEventsManager().get(this.eventId));
|
|
45
|
+
this.eventName = ev?.name ?? 'Tickets';
|
|
46
|
+
this.imageUrl = ev?.imageUrl || ev?.heroImageUrl || '';
|
|
47
|
+
this.venueLabel = [ev?.venueName, ev?.venueCity].filter(Boolean).join(', ');
|
|
48
|
+
const occs = ev?.occurrences ?? [];
|
|
49
|
+
this.occurrenceCount = occs.length;
|
|
50
|
+
this.dateSummary = this.summariseDates(occs);
|
|
51
|
+
// Skip the date step when one was preselected or there's only one date.
|
|
52
|
+
const initial = this.occurrenceId ?? (occs.length === 1 ? occs[0]?.id : null);
|
|
53
|
+
if (initial) {
|
|
54
|
+
this.selectedOccurrenceId = initial;
|
|
55
|
+
this.occurrenceLabel = this.labelFor(occs.find((o) => o.id === initial));
|
|
56
|
+
this.step = 'tickets';
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
this.step = 'occurrence';
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
this.fail(err instanceof Error ? err.message : 'Could not load this event');
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
fail(message) {
|
|
67
|
+
this.error = message;
|
|
68
|
+
this.step = 'error';
|
|
69
|
+
this.tlError.emit({ message });
|
|
70
|
+
}
|
|
71
|
+
/** A compact date line for the header: a single date, or a range across many. */
|
|
72
|
+
summariseDates(occs) {
|
|
73
|
+
const times = occs
|
|
74
|
+
.map((o) => o.startsAt)
|
|
75
|
+
.filter((s) => !!s)
|
|
76
|
+
.sort();
|
|
77
|
+
if (times.length === 0)
|
|
78
|
+
return '';
|
|
79
|
+
const day = (s) => new Date(s).toLocaleDateString('en-GB', { day: 'numeric', month: 'short', year: 'numeric' });
|
|
80
|
+
if (times.length === 1) {
|
|
81
|
+
return new Date(times[0]).toLocaleDateString('en-GB', {
|
|
82
|
+
weekday: 'short',
|
|
83
|
+
day: 'numeric',
|
|
84
|
+
month: 'short',
|
|
85
|
+
year: 'numeric',
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
const first = day(times[0]);
|
|
89
|
+
const last = day(times[times.length - 1]);
|
|
90
|
+
const range = first === last ? first : `${first} – ${last}`;
|
|
91
|
+
return `${range} · ${times.length} dates`;
|
|
92
|
+
}
|
|
93
|
+
labelFor(occ) {
|
|
94
|
+
if (!occ?.startsAt)
|
|
95
|
+
return '';
|
|
96
|
+
return new Date(occ.startsAt).toLocaleString('en-GB', {
|
|
97
|
+
weekday: 'short',
|
|
98
|
+
day: 'numeric',
|
|
99
|
+
month: 'short',
|
|
100
|
+
hour: '2-digit',
|
|
101
|
+
minute: '2-digit',
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
stepKicker() {
|
|
105
|
+
switch (this.step) {
|
|
106
|
+
case 'occurrence':
|
|
107
|
+
return 'Choose a date';
|
|
108
|
+
case 'tickets':
|
|
109
|
+
return 'Select tickets';
|
|
110
|
+
case 'done':
|
|
111
|
+
return 'Nice one';
|
|
112
|
+
default:
|
|
113
|
+
return 'Tickets';
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
render() {
|
|
117
|
+
return (h(Host, { key: '1245e518c2b5232f4d9dba091cf808cd3867fbef' }, h("div", { key: '4e770fccdd785444f1cc87df4adab5a5dc1bf58a', class: "overlay", onClick: (e) => {
|
|
118
|
+
if (e.target === e.currentTarget)
|
|
119
|
+
this.close();
|
|
120
|
+
} }, h("div", { key: '57b13dac690028aeebd6a601acfba07f00854c40', class: { panel: true, 'panel--wide': this.step === 'occurrence' }, role: "dialog", "aria-modal": "true", "aria-label": this.eventName }, h("header", { key: '881e9cc70a0ca25947f272b9ebcb2e6d4b4268f2', class: "panel-header" }, this.imageUrl && (h("div", { key: '753f7df1b5118dfacbbc6b89b4e5d7ba114f6cdf', class: "event-thumb", style: { backgroundImage: `url(${this.imageUrl})` } })), h("div", { key: '9aaa32d1add90fabd1b0ea0c100f198962f4e6a5', class: "titles" }, h("span", { key: '538032bdf2338206ad763417386852ff97cc472f', class: "kicker" }, this.stepKicker()), h("h2", { key: '71429804179e7fbbea1fa90a2937a065517092f5', class: "event-name" }, this.eventName), this.venueLabel && h("p", { key: 'dd968b397deab890df3a4fbdff33226e82bd9660', class: "event-meta" }, this.venueLabel), this.dateSummary && h("p", { key: 'f40e6049d09b06c9f599e7d14d6fbb43b39b22fd', class: "event-meta" }, this.dateSummary)), h("button", { key: 'dbe0908f8cd8544654b627921f68cc4961802b77', class: "close-btn", "aria-label": "Close", onClick: this.close }, h("svg", { key: '23a750830e6e16d28cbcd5025507d25848aaadf7', viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("path", { key: 'e81b8763a5c781f72c1ca8a2113482948e3ba8cc', d: "M6 6l12 12M18 6L6 18", "stroke-linecap": "round" })))), h("div", { key: 'da71e610f907cf53e78246d2065aaf526d5ceffd', class: "panel-body" }, this.step === 'loading' && (h("div", { key: '28cbb9a98c7b08fa8dcb9d8d5dfbf3bec93fe38d', class: "state-msg" }, h("span", { key: '915c8de87cbdc7da1ccf0622ce6c0f02fccf2cad', class: "spinner" }), " Loading\u2026")), this.step === 'error' && h("div", { key: '5785578bfef6f1ee81d938d91ffd3ded975f8c12', class: "state-msg error" }, this.error), this.step === 'occurrence' && (h("tl-occurrence-selector", { key: 'eeb853eab141c3c103015e82d221a140f6a3a109', eventId: this.eventId, onTlSelect: this.handleOccurrenceSelect })), this.step === 'tickets' && this.selectedOccurrenceId && (h("div", { key: 'f608f592ba651eb431375433eb4ff9393863ade5', class: "tickets-step" }, this.occurrenceCount > 1 && (h("button", { key: '84adfbdbeaceb2cf4238c6ffd09558b4499ca940', class: "back-link", onClick: this.backToDates }, "\u2190 Change date")), this.occurrenceLabel && h("p", { key: '0317e9194049608711e8c622142c3ad2c0a5dc12', class: "occ-label" }, this.occurrenceLabel), h("tl-ticket-selector", { key: '27b1e05d9d92fb8d519375e2b27d4b5ea0a4890a', eventId: this.eventId, occurrenceId: this.selectedOccurrenceId, onTlAddToCart: this.handleAdded }))), this.step === 'done' && (h("div", { key: '0853088206988c66d489f8804df7899821d49e64', class: "done-step" }, h("div", { key: 'c2955b893c4dffaadcdfd27bee96ef2724a131a6', class: "done-mark" }, "\uD83C\uDF9F\uFE0F"), h("p", { key: '370c30dfcbc0c25b4794d984dd261a3a5779a9dc', class: "done-title" }, "Added to your cart"), h("p", { key: 'c462f3c9292740e2fd2c74b173484f80a5dc1a30', class: "done-sub" }, "Held for you while you check out."), h("button", { key: '484991f79572e3213ad6413a1af87599880c3643', class: "primary-btn", onClick: this.goCheckout }, "Go to checkout"), h("button", { key: '5b4ba5a472b794e8f5af0f131dad1c8c11b869f5', class: "ghost-btn", onClick: this.close }, "Keep browsing"))))))));
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
TlBuyModal.style = tlBuyModalCss();
|
|
124
|
+
|
|
125
|
+
export { TlBuyModal as tl_buy_modal };
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { r as registerInstance, c as createEvent, h, H as Host } from './index-Ba-RZTFI.js';
|
|
2
|
+
import { h as hasSDK, g as getSDK } from './sdk-connector-CqhvfyKV.js';
|
|
3
|
+
|
|
4
|
+
const tlBuyTicketsButtonCss = () => `:host{display:inline-block;font-family:var(--tl-font-family, system-ui, -apple-system, sans-serif)}:host(.full-width){display:block;width:100%}:host(.full-width) .buy-button{width:100%}.buy-button{display:inline-flex;align-items:center;justify-content:center;gap:0.5rem;font-weight:600;border:none;cursor:pointer;text-decoration:none;outline:none;transition:all 0.2s ease;white-space:nowrap}.buy-button.variant-primary{background:var(--button-color);color:var(--button-foreground)}.buy-button.variant-secondary{background:color-mix(in srgb, var(--button-color) 15%, transparent);color:var(--button-color)}.buy-button.variant-outline{background:transparent;color:var(--button-color);border:2px solid var(--button-color)}.buy-button.size-sm{padding:0.5rem 1rem;font-size:0.875rem;border-radius:var(--tl-radius-sm, 0.375rem)}.buy-button.size-md{padding:0.75rem 1.5rem;font-size:1rem;border-radius:var(--tl-radius-md, 0.5rem)}.buy-button.size-lg{padding:1rem 2rem;font-size:1.125rem;border-radius:var(--tl-radius-lg, 0.625rem);min-height:51px}.buy-button.hovered:not(.disabled){opacity:0.9;transform:translateY(-1px)}.buy-button.hovered.variant-primary{background:var(--button-hover-color)}.buy-button.disabled{opacity:0.7;cursor:not-allowed}.icon{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}.icon svg{width:1em;height:1em}.label{flex-shrink:0}.price{display:inline-flex;align-items:center;gap:0.25rem;margin-left:0.5rem;white-space:nowrap;opacity:0.9}.price-prefix{opacity:0.7}.price-value{font-weight:700}`;
|
|
5
|
+
|
|
6
|
+
// State configurations
|
|
7
|
+
const STATE_CONFIGS = {
|
|
8
|
+
available: {
|
|
9
|
+
defaultLabel: 'Buy Tickets',
|
|
10
|
+
color: 'var(--tl-primary, #e64b12)',
|
|
11
|
+
hoverColor: 'var(--tl-primary, #d4440f)',
|
|
12
|
+
foreground: 'var(--tl-primary-foreground, #ffffff)',
|
|
13
|
+
},
|
|
14
|
+
soldOut: {
|
|
15
|
+
defaultLabel: 'Sold Out',
|
|
16
|
+
color: '#dc2626',
|
|
17
|
+
hoverColor: '#b91c1c',
|
|
18
|
+
foreground: '#ffffff',
|
|
19
|
+
},
|
|
20
|
+
waitlist: {
|
|
21
|
+
defaultLabel: 'Join Waitlist',
|
|
22
|
+
color: '#2563eb',
|
|
23
|
+
hoverColor: '#1d4ed8',
|
|
24
|
+
foreground: '#ffffff',
|
|
25
|
+
},
|
|
26
|
+
comingSoon: {
|
|
27
|
+
defaultLabel: 'On Sale Soon',
|
|
28
|
+
color: '#d97706',
|
|
29
|
+
hoverColor: '#b45309',
|
|
30
|
+
foreground: '#ffffff',
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
const TlBuyTicketsButton = class {
|
|
34
|
+
constructor(hostRef) {
|
|
35
|
+
registerInstance(this, hostRef);
|
|
36
|
+
this.tlClick = createEvent(this, "tlClick");
|
|
37
|
+
/** Button state - determines colour, label, and icon */
|
|
38
|
+
this.state = 'available';
|
|
39
|
+
/** Button variant */
|
|
40
|
+
this.variant = 'primary';
|
|
41
|
+
/** Button size */
|
|
42
|
+
this.size = 'md';
|
|
43
|
+
/** Full width button */
|
|
44
|
+
this.fullWidth = false;
|
|
45
|
+
/** Currency code for price formatting */
|
|
46
|
+
this.currency = 'GBP';
|
|
47
|
+
/** Show price prefix text */
|
|
48
|
+
this.pricePrefix = 'From';
|
|
49
|
+
/** Disabled state */
|
|
50
|
+
this.disabled = false;
|
|
51
|
+
// -------------------------------------------------------------------------
|
|
52
|
+
// State
|
|
53
|
+
// -------------------------------------------------------------------------
|
|
54
|
+
this.isHovered = false;
|
|
55
|
+
// -------------------------------------------------------------------------
|
|
56
|
+
// Methods
|
|
57
|
+
// -------------------------------------------------------------------------
|
|
58
|
+
this.handleClick = () => {
|
|
59
|
+
// Check if button should be interactive
|
|
60
|
+
if (this.disabled || this.state === 'soldOut' || this.state === 'comingSoon') {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// Emit click event
|
|
64
|
+
this.tlClick.emit({ eventId: this.eventId, occurrenceId: this.occurrenceId });
|
|
65
|
+
// Open modal via SDK if available
|
|
66
|
+
if (hasSDK()) {
|
|
67
|
+
try {
|
|
68
|
+
const sdk = getSDK();
|
|
69
|
+
sdk.event(this.eventId).openModal({
|
|
70
|
+
occurrenceId: this.occurrenceId,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
console.error('[tl-buy-tickets-button] Failed to open modal:', err);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
formatPrice(priceInMinorUnits) {
|
|
80
|
+
const amount = priceInMinorUnits / 100;
|
|
81
|
+
const hasDecimals = amount % 1 !== 0;
|
|
82
|
+
return new Intl.NumberFormat('en-GB', {
|
|
83
|
+
style: 'currency',
|
|
84
|
+
currency: this.currency,
|
|
85
|
+
minimumFractionDigits: hasDecimals ? 2 : 0,
|
|
86
|
+
maximumFractionDigits: hasDecimals ? 2 : 0,
|
|
87
|
+
}).format(amount);
|
|
88
|
+
}
|
|
89
|
+
getStateConfig() {
|
|
90
|
+
return STATE_CONFIGS[this.state];
|
|
91
|
+
}
|
|
92
|
+
isInteractive() {
|
|
93
|
+
return !this.disabled && this.state !== 'soldOut' && this.state !== 'comingSoon';
|
|
94
|
+
}
|
|
95
|
+
// -------------------------------------------------------------------------
|
|
96
|
+
// Render
|
|
97
|
+
// -------------------------------------------------------------------------
|
|
98
|
+
render() {
|
|
99
|
+
const config = this.getStateConfig();
|
|
100
|
+
const buttonLabel = this.label || config.defaultLabel;
|
|
101
|
+
const isInteractive = this.isInteractive();
|
|
102
|
+
return (h(Host, { key: '10c8c36d12223afcfd13c9807c2ef6b0f4c34266', class: { 'full-width': this.fullWidth } }, h("button", { key: 'c7f6a39a837c90ced0176b5d017687afabf99a5a', type: "button", class: {
|
|
103
|
+
'buy-button': true,
|
|
104
|
+
[`variant-${this.variant}`]: true,
|
|
105
|
+
[`size-${this.size}`]: true,
|
|
106
|
+
'disabled': !isInteractive,
|
|
107
|
+
'hovered': this.isHovered && isInteractive,
|
|
108
|
+
}, style: {
|
|
109
|
+
'--button-color': config.color,
|
|
110
|
+
'--button-hover-color': config.hoverColor,
|
|
111
|
+
'--button-foreground': config.foreground,
|
|
112
|
+
}, disabled: !isInteractive, onClick: this.handleClick, onMouseEnter: () => (this.isHovered = true), onMouseLeave: () => (this.isHovered = false) }, h("span", { key: 'e2bc1edc9fbd2a9c81da8cc3293170b1c4275125', class: "icon" }, this.state === 'soldOut' && this.renderSoldOutIcon(), this.state === 'waitlist' && this.renderWaitlistIcon(), this.state === 'comingSoon' && this.renderComingSoonIcon(), this.state === 'available' && this.renderTicketIcon()), h("span", { key: '8371c85dcc24c5ac040744edefe80618421025ef', class: "label" }, buttonLabel), this.price !== undefined && (h("span", { key: 'c02cb5b646ade8866deafb9b3e698115abec5708', class: "price" }, h("span", { key: 'cb0ab272460115a5edebd674362c83711735a70d', class: "price-prefix" }, this.pricePrefix), h("span", { key: 'e28ba56d3928076b624513de95682351f3e0d92b', class: "price-value" }, this.formatPrice(this.price)))))));
|
|
113
|
+
}
|
|
114
|
+
renderTicketIcon() {
|
|
115
|
+
return (h("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("path", { d: "M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z" }), h("path", { d: "M13 5v2" }), h("path", { d: "M13 17v2" }), h("path", { d: "M13 11v2" })));
|
|
116
|
+
}
|
|
117
|
+
renderSoldOutIcon() {
|
|
118
|
+
return (h("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("circle", { cx: "12", cy: "12", r: "10" }), h("path", { d: "m15 9-6 6" }), h("path", { d: "m9 9 6 6" })));
|
|
119
|
+
}
|
|
120
|
+
renderWaitlistIcon() {
|
|
121
|
+
return (h("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("circle", { cx: "12", cy: "12", r: "10" }), h("polyline", { points: "12 6 12 12 16 14" })));
|
|
122
|
+
}
|
|
123
|
+
renderComingSoonIcon() {
|
|
124
|
+
return (h("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("path", { d: "M12 2v4" }), h("path", { d: "m16.2 7.8 2.9-2.9" }), h("path", { d: "M18 12h4" }), h("path", { d: "m16.2 16.2 2.9 2.9" }), h("path", { d: "M12 18v4" }), h("path", { d: "m4.9 19.1 2.9-2.9" }), h("path", { d: "M2 12h4" }), h("path", { d: "m4.9 4.9 2.9 2.9" })));
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
TlBuyTicketsButton.style = tlBuyTicketsButtonCss();
|
|
128
|
+
|
|
129
|
+
export { TlBuyTicketsButton as tl_buy_tickets_button };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { r as registerInstance, c as createEvent, h, H as Host, a as getElement } from './index-Ba-RZTFI.js';
|
|
2
|
+
import { h as hasSDK, g as getSDK } from './sdk-connector-CqhvfyKV.js';
|
|
3
|
+
|
|
4
|
+
const tlBuyTicketsWrapperCss = () => `tl-buy-tickets-wrapper,.tl-buy-tickets-wrapper{display:inline-block;cursor:pointer}tl-buy-tickets-wrapper:focus,.tl-buy-tickets-wrapper:focus{outline:2px solid var(--tl-ring, #3b82f6);outline-offset:2px;border-radius:var(--tl-radius-sm, 0.25rem)}tl-buy-tickets-wrapper[disabled],tl-buy-tickets-wrapper.tl-buy-tickets-wrapper--disabled,.tl-buy-tickets-wrapper--disabled{cursor:not-allowed;opacity:0.5}`;
|
|
5
|
+
|
|
6
|
+
const TlBuyTicketsWrapper = class {
|
|
7
|
+
constructor(hostRef) {
|
|
8
|
+
registerInstance(this, hostRef);
|
|
9
|
+
this.tlComplete = createEvent(this, "tl-complete");
|
|
10
|
+
this.tlError = createEvent(this, "tl-error");
|
|
11
|
+
this.tlClose = createEvent(this, "tl-close");
|
|
12
|
+
/**
|
|
13
|
+
* Whether the wrapper is disabled
|
|
14
|
+
*/
|
|
15
|
+
this.disabled = false;
|
|
16
|
+
this.handleClick = () => {
|
|
17
|
+
if (this.disabled)
|
|
18
|
+
return;
|
|
19
|
+
if (!hasSDK()) {
|
|
20
|
+
console.error('[tl-buy-tickets-wrapper] SDK not initialized. Call setSDK(ticketlayer) first.');
|
|
21
|
+
this.tlError.emit({ message: 'SDK not initialized' });
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const sdk = getSDK();
|
|
25
|
+
// Open the modal via SDK
|
|
26
|
+
sdk.event(this.eventId).openModal({
|
|
27
|
+
occurrenceId: this.occurrenceId,
|
|
28
|
+
onComplete: (order) => {
|
|
29
|
+
this.tlComplete.emit(order);
|
|
30
|
+
},
|
|
31
|
+
onError: (err) => {
|
|
32
|
+
this.tlError.emit({ message: err.message });
|
|
33
|
+
},
|
|
34
|
+
onClose: () => {
|
|
35
|
+
this.tlClose.emit();
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
this.handleKeyDown = (e) => {
|
|
40
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
41
|
+
e.preventDefault();
|
|
42
|
+
this.handleClick();
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
render() {
|
|
47
|
+
return (h(Host, { key: 'd6ef81ac9bc1a1194eda1603cbb2a75b355a212e', class: {
|
|
48
|
+
'tl-buy-tickets-wrapper': true,
|
|
49
|
+
'tl-buy-tickets-wrapper--disabled': this.disabled,
|
|
50
|
+
}, onClick: this.handleClick, onKeyDown: this.handleKeyDown, role: "button", tabindex: this.disabled ? -1 : 0, "aria-disabled": this.disabled ? 'true' : null }, h("slot", { key: 'faef5aaad20deaf5e442d688c69105e45f9ee26f' })));
|
|
51
|
+
}
|
|
52
|
+
get el() { return getElement(this); }
|
|
53
|
+
};
|
|
54
|
+
TlBuyTicketsWrapper.style = tlBuyTicketsWrapperCss();
|
|
55
|
+
|
|
56
|
+
export { TlBuyTicketsWrapper as tl_buy_tickets_wrapper };
|