summit-registration-lite 7.0.1 → 7.0.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.
- package/.github/workflows/ci.yml +54 -0
- package/dist/components/index.css +12 -27
- package/dist/components/index.css.map +1 -1
- package/dist/components/index.js +813 -264
- package/dist/components/index.js.map +1 -1
- package/dist/components/login-passwordless.css +1 -2
- package/dist/components/login-passwordless.js +21 -4
- package/dist/components/login-passwordless.js.map +1 -1
- package/dist/components/login.css +1 -2
- package/dist/components/login.js +69 -2
- package/dist/components/login.js.map +1 -1
- package/dist/components/registration-form.css +12 -26
- package/dist/components/registration-form.css.map +1 -1
- package/dist/components/registration-form.js +808 -260
- package/dist/components/registration-form.js.map +1 -1
- package/dist/components/registration-modal.css +12 -27
- package/dist/components/registration-modal.css.map +1 -1
- package/dist/components/registration-modal.js +812 -263
- package/dist/components/registration-modal.js.map +1 -1
- package/dist/index.css +12 -27
- package/dist/index.css.map +1 -1
- package/dist/index.js +812 -263
- package/dist/index.js.map +1 -1
- package/dist/utils/constants.js +11 -1
- package/dist/utils/constants.js.map +1 -1
- package/e2e/fixtures.js +84 -0
- package/e2e/promo-code-discovery.spec.js +364 -0
- package/package.json +12 -4
- package/playwright.config.js +26 -0
- package/.claude/rules/summit-registration-lite-component-props.md +0 -95
- package/.claude/rules/summit-registration-lite-i18n.md +0 -62
- package/.claude/rules/summit-registration-lite-payment-providers.md +0 -69
- package/.claude/rules/summit-registration-lite-project.md +0 -80
- package/.claude/rules/summit-registration-lite-redux-actions.md +0 -65
- package/.claude/rules/summit-registration-lite-step-flow.md +0 -77
- package/.claude/rules/summit-registration-lite-testing.md +0 -97
- package/.claude/rules/summit-registration-lite-utils.md +0 -71
- package/.claude/skills/summit-registration-lite-add-provider/SKILL.md +0 -155
- package/.claude/skills/summit-registration-lite-dev-setup/SKILL.md +0 -67
- package/.claude/skills/summit-registration-lite-publish/SKILL.md +0 -64
- package/.claude/skills/summit-registration-lite-scaffold-component/SKILL.md +0 -152
package/dist/components/index.js
CHANGED
|
@@ -25,6 +25,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
25
25
|
"t$": () => (/* binding */ CLEAR_WIDGET_STATE),
|
|
26
26
|
"rr": () => (/* binding */ CREATE_RESERVATION_SUCCESS),
|
|
27
27
|
"bz": () => (/* binding */ DELETE_RESERVATION_SUCCESS),
|
|
28
|
+
"dQ": () => (/* binding */ DISCOVER_PROMO_CODES_SUCCESS),
|
|
28
29
|
"Cw": () => (/* binding */ GET_MY_INVITATION),
|
|
29
30
|
"bx": () => (/* binding */ GET_TAX_TYPES),
|
|
30
31
|
"HC": () => (/* binding */ GET_TICKET_TYPES),
|
|
@@ -40,9 +41,14 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
40
41
|
"Vx": () => (/* binding */ START_WIDGET_LOADING),
|
|
41
42
|
"sC": () => (/* binding */ STOP_WIDGET_LOADING),
|
|
42
43
|
"VH": () => (/* binding */ UPDATE_CLOCK),
|
|
44
|
+
"j6": () => (/* binding */ VALIDATE_PROMO_CODE),
|
|
45
|
+
"o5": () => (/* binding */ VALIDATE_PROMO_CODE_ERROR),
|
|
46
|
+
"Tk": () => (/* binding */ VALIDATE_PROMO_CODE_RATE_LIMITED),
|
|
47
|
+
"w6": () => (/* binding */ VALIDATE_PROMO_CODE_SUCCESS),
|
|
43
48
|
"gs": () => (/* binding */ applyPromoCode),
|
|
44
49
|
"sz": () => (/* binding */ changeStep),
|
|
45
50
|
"YS": () => (/* binding */ clearWidgetState),
|
|
51
|
+
"kM": () => (/* binding */ discoverPromoCodes),
|
|
46
52
|
"aH": () => (/* binding */ getLoginCode),
|
|
47
53
|
"q1": () => (/* binding */ getMyInvitation),
|
|
48
54
|
"xu": () => (/* binding */ getTicketTypesAndTaxes),
|
|
@@ -61,7 +67,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
61
67
|
"jn": () => (/* binding */ validatePromoCode)
|
|
62
68
|
});
|
|
63
69
|
|
|
64
|
-
// UNUSED EXPORTS: CREATE_RESERVATION, CREATE_RESERVATION_ERROR, DELETE_RESERVATION, DELETE_RESERVATION_ERROR,
|
|
70
|
+
// UNUSED EXPORTS: CREATE_RESERVATION, CREATE_RESERVATION_ERROR, DELETE_RESERVATION, DELETE_RESERVATION_ERROR, DISCOVER_PROMO_CODES
|
|
65
71
|
|
|
66
72
|
;// CONCATENATED MODULE: external "openstack-uicore-foundation/lib/utils/actions"
|
|
67
73
|
const actions_namespaceObject = require("openstack-uicore-foundation/lib/utils/actions");
|
|
@@ -397,6 +403,11 @@ const LOAD_PROFILE_DATA = 'LOAD_PROFILE_DATA';
|
|
|
397
403
|
const SET_CURRENT_PROMO_CODE = 'SET_CURRENT_PROMO_CODE';
|
|
398
404
|
const CLEAR_CURRENT_PROMO_CODE = 'CLEAR_CURRENT_PROMO_CODE';
|
|
399
405
|
const VALIDATE_PROMO_CODE = 'VALIDATE_PROMO_CODE';
|
|
406
|
+
const VALIDATE_PROMO_CODE_SUCCESS = 'VALIDATE_PROMO_CODE_SUCCESS';
|
|
407
|
+
const VALIDATE_PROMO_CODE_ERROR = 'VALIDATE_PROMO_CODE_ERROR';
|
|
408
|
+
const VALIDATE_PROMO_CODE_RATE_LIMITED = 'VALIDATE_PROMO_CODE_RATE_LIMITED';
|
|
409
|
+
const DISCOVER_PROMO_CODES = 'DISCOVER_PROMO_CODES';
|
|
410
|
+
const DISCOVER_PROMO_CODES_SUCCESS = 'DISCOVER_PROMO_CODES_SUCCESS';
|
|
400
411
|
const startWidgetLoading = (0,actions_namespaceObject.createAction)(START_WIDGET_LOADING);
|
|
401
412
|
const stopWidgetLoading = (0,actions_namespaceObject.createAction)(STOP_WIDGET_LOADING);
|
|
402
413
|
const loadSession = settings => dispatch => {
|
|
@@ -409,6 +420,23 @@ const clearWidgetState = () => dispatch => {
|
|
|
409
420
|
dispatch((0,actions_namespaceObject.createAction)(CLEAR_WIDGET_STATE)({}));
|
|
410
421
|
};
|
|
411
422
|
|
|
423
|
+
const promoCodeErrorHandler = (err, res) => (dispatch, state) => {
|
|
424
|
+
// 404: promo code or ticket type not found
|
|
425
|
+
// 412: promo code invalid for this ticket type/qty
|
|
426
|
+
if (res && [404, 412].includes(res.statusCode)) {
|
|
427
|
+
dispatch((0,actions_namespaceObject.createAction)(VALIDATE_PROMO_CODE_ERROR)({}));
|
|
428
|
+
return;
|
|
429
|
+
} // 429: rate limited - transient, preserve current promo state
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
if (res && res.statusCode === 429) {
|
|
433
|
+
dispatch((0,actions_namespaceObject.createAction)(VALIDATE_PROMO_CODE_RATE_LIMITED)({}));
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
return (0,actions_namespaceObject.authErrorHandler)(err, res)(dispatch, state);
|
|
438
|
+
};
|
|
439
|
+
|
|
412
440
|
const customErrorHandler = (err, res) => (dispatch, state) => {
|
|
413
441
|
if (err.timeout) {
|
|
414
442
|
return err;
|
|
@@ -426,13 +454,35 @@ const customErrorHandler = (err, res) => (dispatch, state) => {
|
|
|
426
454
|
};
|
|
427
455
|
/*********************************************************************************/
|
|
428
456
|
|
|
457
|
+
/* PROMO CODE DISCOVERY */
|
|
458
|
+
|
|
459
|
+
/*********************************************************************************/
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
const discoverPromoCodes = summitId => async (dispatch, getState, {
|
|
463
|
+
apiBaseUrl,
|
|
464
|
+
getAccessToken
|
|
465
|
+
}) => {
|
|
466
|
+
try {
|
|
467
|
+
const accessToken = await getAccessToken();
|
|
468
|
+
return (0,actions_namespaceObject.getRequest)((0,actions_namespaceObject.createAction)(DISCOVER_PROMO_CODES), (0,actions_namespaceObject.createAction)(DISCOVER_PROMO_CODES_SUCCESS), `${apiBaseUrl}/api/v1/summits/${summitId}/promo-codes/all/discover`, // Discovery is non-blocking - errors silently ignored.
|
|
469
|
+
// Auth errors will surface on the next user-initiated action.
|
|
470
|
+
null)({
|
|
471
|
+
access_token: accessToken
|
|
472
|
+
})(dispatch);
|
|
473
|
+
} catch (e) {
|
|
474
|
+
console.log(e);
|
|
475
|
+
return null;
|
|
476
|
+
}
|
|
477
|
+
};
|
|
478
|
+
/*********************************************************************************/
|
|
479
|
+
|
|
429
480
|
/* TICKETS */
|
|
430
481
|
|
|
431
482
|
/*********************************************************************************/
|
|
432
483
|
// api/v1/summits/{id}/ticket-types/allowed
|
|
433
484
|
// api/v1/summits/{id}/tax-types
|
|
434
485
|
|
|
435
|
-
|
|
436
486
|
const getTicketTypesAndTaxes = summitId => async dispatch => {
|
|
437
487
|
return Promise.all([dispatch(getTicketTypes(summitId)), dispatch(getTaxesTypes(summitId))]).then(values => {
|
|
438
488
|
return values;
|
|
@@ -504,22 +554,23 @@ const getTaxesTypes = summitId => async (dispatch, getState, {
|
|
|
504
554
|
}
|
|
505
555
|
};
|
|
506
556
|
|
|
507
|
-
const applyPromoCode = currentPromoCode => (dispatch, getState) => {
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
summitId
|
|
513
|
-
}
|
|
557
|
+
const applyPromoCode = currentPromoCode => async (dispatch, getState) => {
|
|
558
|
+
const {
|
|
559
|
+
registrationLiteState: {
|
|
560
|
+
settings: {
|
|
561
|
+
summitId
|
|
514
562
|
}
|
|
515
|
-
}
|
|
563
|
+
}
|
|
564
|
+
} = getState();
|
|
516
565
|
|
|
566
|
+
try {
|
|
517
567
|
dispatch((0,actions_namespaceObject.createAction)(SET_CURRENT_PROMO_CODE)({
|
|
518
568
|
currentPromoCode
|
|
519
569
|
}));
|
|
520
|
-
dispatch(getTicketTypes(summitId));
|
|
570
|
+
await dispatch(getTicketTypes(summitId));
|
|
521
571
|
} catch (e) {
|
|
522
|
-
|
|
572
|
+
dispatch((0,actions_namespaceObject.createAction)(CLEAR_CURRENT_PROMO_CODE)({}));
|
|
573
|
+
throw e;
|
|
523
574
|
}
|
|
524
575
|
};
|
|
525
576
|
const removePromoCode = () => (dispatch, getState) => {
|
|
@@ -539,9 +590,13 @@ const removePromoCode = () => (dispatch, getState) => {
|
|
|
539
590
|
return Promise.reject(e);
|
|
540
591
|
}
|
|
541
592
|
};
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
593
|
+
/**
|
|
594
|
+
* Validates promo code for a specific ticket selection.
|
|
595
|
+
* Stores allows_to_reassign in Redux state.
|
|
596
|
+
* Returns response or throws error - caller handles UI concerns.
|
|
597
|
+
*/
|
|
598
|
+
|
|
599
|
+
const validatePromoCode = ticketData => async (dispatch, getState, {
|
|
545
600
|
apiBaseUrl,
|
|
546
601
|
getAccessToken
|
|
547
602
|
}) => {
|
|
@@ -552,61 +607,24 @@ const validatePromoCode = (ticketData, {
|
|
|
552
607
|
},
|
|
553
608
|
promoCode: currentPromoCode
|
|
554
609
|
}
|
|
555
|
-
} = getState();
|
|
556
|
-
const {
|
|
557
|
-
promoCode: formPromoCode
|
|
558
|
-
} = ticketData;
|
|
559
|
-
|
|
560
|
-
if (formPromoCode && !currentPromoCode) {
|
|
561
|
-
const defaultMessage = `You entered a promo code but it hasn't been applied. Make sure to click the 'Apply' button or remove it before continuing.`;
|
|
562
|
-
const notAppliedCodeError = {
|
|
563
|
-
body: {
|
|
564
|
-
errors: [defaultMessage]
|
|
565
|
-
}
|
|
566
|
-
};
|
|
567
|
-
return onError(null, notAppliedCodeError);
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
if (summitId && currentPromoCode) {
|
|
571
|
-
dispatch(startWidgetLoading());
|
|
572
|
-
const {
|
|
573
|
-
ticketQuantity,
|
|
574
|
-
id,
|
|
575
|
-
sub_type
|
|
576
|
-
} = ticketData;
|
|
577
|
-
const access_token = await getAccessToken();
|
|
578
|
-
let apiUrl = external_urijs_default()(`${apiBaseUrl}/api/v1/summits/${summitId}/promo-codes/${currentPromoCode}/apply`);
|
|
579
|
-
apiUrl.addQuery('access_token', access_token);
|
|
580
|
-
apiUrl.addQuery('filter[]', `ticket_type_id==${id}`);
|
|
581
|
-
apiUrl.addQuery('filter[]', `ticket_type_qty==${ticketQuantity}`);
|
|
582
|
-
apiUrl.addQuery('filter[]', `ticket_type_subtype==${sub_type}`);
|
|
583
|
-
|
|
584
|
-
const errorHandler = (err, res) => (dispatch, state) => {
|
|
585
|
-
if (res && res.statusCode === 404 && onError) return onError(err, res);
|
|
586
|
-
if (res && res.statusCode === 412 && onError) return onError(err, res);
|
|
587
|
-
if (res && res.statusCode === 429 && onError) return onError(err, res);
|
|
588
|
-
|
|
589
|
-
if (res && res.statusCode === 500) {
|
|
590
|
-
const defaultMessage = 'Server Error';
|
|
591
|
-
const msg = res?.body?.message || defaultMessage;
|
|
592
|
-
external_sweetalert2_default().fire("Server Error", msg, "error");
|
|
593
|
-
return;
|
|
594
|
-
}
|
|
610
|
+
} = getState(); // Nothing to validate if no promo code applied
|
|
595
611
|
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
return (0,actions_namespaceObject.getRequest)(null, (0,actions_namespaceObject.createAction)(VALIDATE_PROMO_CODE), `${apiUrl}`, errorHandler)({})(dispatch).then(res => {
|
|
600
|
-
dispatch(changeStep(constants.STEP_PERSONAL_INFO));
|
|
601
|
-
dispatch(stopWidgetLoading());
|
|
602
|
-
return res;
|
|
603
|
-
}).catch(error => {
|
|
604
|
-
dispatch(stopWidgetLoading());
|
|
605
|
-
return Promise.reject(error);
|
|
606
|
-
});
|
|
612
|
+
if (!summitId || !currentPromoCode) {
|
|
613
|
+
return null;
|
|
607
614
|
}
|
|
608
615
|
|
|
609
|
-
|
|
616
|
+
const {
|
|
617
|
+
ticketQuantity = 1,
|
|
618
|
+
id,
|
|
619
|
+
sub_type
|
|
620
|
+
} = ticketData;
|
|
621
|
+
const access_token = await getAccessToken();
|
|
622
|
+
let apiUrl = external_urijs_default()(`${apiBaseUrl}/api/v1/summits/${summitId}/promo-codes/${currentPromoCode}/apply`);
|
|
623
|
+
apiUrl.addQuery('access_token', access_token);
|
|
624
|
+
apiUrl.addQuery('filter[]', `ticket_type_id==${id}`);
|
|
625
|
+
apiUrl.addQuery('filter[]', `ticket_type_qty==${ticketQuantity}`);
|
|
626
|
+
apiUrl.addQuery('filter[]', `ticket_type_subtype==${sub_type}`);
|
|
627
|
+
return (0,actions_namespaceObject.getRequest)((0,actions_namespaceObject.createAction)(VALIDATE_PROMO_CODE), (0,actions_namespaceObject.createAction)(VALIDATE_PROMO_CODE_SUCCESS), `${apiUrl}`, promoCodeErrorHandler)({})(dispatch);
|
|
610
628
|
};
|
|
611
629
|
const reserveTicket = ({
|
|
612
630
|
provider,
|
|
@@ -1326,7 +1344,7 @@ LoginComponent.defaultProps = {
|
|
|
1326
1344
|
|
|
1327
1345
|
/***/ }),
|
|
1328
1346
|
|
|
1329
|
-
/***/
|
|
1347
|
+
/***/ 95:
|
|
1330
1348
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
1331
1349
|
|
|
1332
1350
|
"use strict";
|
|
@@ -1355,6 +1373,256 @@ const external_react_use_namespaceObject = require("react-use");
|
|
|
1355
1373
|
const constants_namespaceObject = require("openstack-uicore-foundation/lib/security/constants");
|
|
1356
1374
|
// EXTERNAL MODULE: ./src/actions.js + 5 modules
|
|
1357
1375
|
var actions = __webpack_require__(595);
|
|
1376
|
+
;// CONCATENATED MODULE: external "i18n-react"
|
|
1377
|
+
const external_i18n_react_namespaceObject = require("i18n-react");
|
|
1378
|
+
var external_i18n_react_default = /*#__PURE__*/__webpack_require__.n(external_i18n_react_namespaceObject);
|
|
1379
|
+
// EXTERNAL MODULE: ./src/utils/constants.js
|
|
1380
|
+
var constants = __webpack_require__(243);
|
|
1381
|
+
;// CONCATENATED MODULE: ./src/hooks/usePromoCode.js
|
|
1382
|
+
|
|
1383
|
+
|
|
1384
|
+
|
|
1385
|
+
|
|
1386
|
+
const usePromoCode = ({
|
|
1387
|
+
// Redux state
|
|
1388
|
+
discoveredPromoCodes,
|
|
1389
|
+
promoCode,
|
|
1390
|
+
promoCodeVerified,
|
|
1391
|
+
promoCodeValidating,
|
|
1392
|
+
// Redux dispatchers
|
|
1393
|
+
applyPromoCode,
|
|
1394
|
+
removePromoCode,
|
|
1395
|
+
validatePromoCode,
|
|
1396
|
+
// Form integration
|
|
1397
|
+
ticketDataLoaded = false,
|
|
1398
|
+
hasTickets = false,
|
|
1399
|
+
setFormPromoCode
|
|
1400
|
+
}) => {
|
|
1401
|
+
// Per-session lock: once the user removes (or auto-apply fails for) a
|
|
1402
|
+
// discovered code, don't re-apply it on this widget mount. Never reset.
|
|
1403
|
+
const [userRemovedAutoApply, setUserRemovedAutoApply] = (0,external_react_.useState)(false);
|
|
1404
|
+
const [isAutoApplied, setIsAutoApplied] = (0,external_react_.useState)(false);
|
|
1405
|
+
const [suggestionActive, setSuggestionActive] = (0,external_react_.useState)(false);
|
|
1406
|
+
const [suggestionDismissed, setSuggestionDismissed] = (0,external_react_.useState)(false); // Error written by handleValidationError (API) or the form (unapplied-code warning).
|
|
1407
|
+
// The user-facing `validationError` is computed below by merging this with the
|
|
1408
|
+
// status-derived INVALID message.
|
|
1409
|
+
|
|
1410
|
+
const [manualError, setManualError] = (0,external_react_.useState)(null);
|
|
1411
|
+
const [applyingCode, setApplyingCode] = (0,external_react_.useState)(false); // Pick first auto_apply code, or first code if none has auto_apply
|
|
1412
|
+
|
|
1413
|
+
const discoveredPromoCode = (0,external_react_.useMemo)(() => {
|
|
1414
|
+
if (!discoveredPromoCodes?.length) return null;
|
|
1415
|
+
return discoveredPromoCodes.find(c => c.auto_apply) || discoveredPromoCodes[0];
|
|
1416
|
+
}, [discoveredPromoCodes]);
|
|
1417
|
+
const isApplied = !!promoCode;
|
|
1418
|
+
const isDiscoveredCode = isApplied && discoveredPromoCode?.code === promoCode; // --- Status ---
|
|
1419
|
+
|
|
1420
|
+
const status = (0,external_react_.useMemo)(() => {
|
|
1421
|
+
if (isApplied) {
|
|
1422
|
+
if (promoCodeValidating) return constants.PROMO_STATUS.VALIDATING;
|
|
1423
|
+
if (promoCodeVerified === true) return constants.PROMO_STATUS.VALID;
|
|
1424
|
+
if (promoCodeVerified === false) return constants.PROMO_STATUS.INVALID; // Applied but no tickets returned and not currently applying: code is invalid
|
|
1425
|
+
|
|
1426
|
+
if (!applyingCode && ticketDataLoaded && !hasTickets) return constants.PROMO_STATUS.INVALID;
|
|
1427
|
+
return constants.PROMO_STATUS.APPLYING;
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
if (suggestionActive && !suggestionDismissed) return constants.PROMO_STATUS.SUGGESTED;
|
|
1431
|
+
return constants.PROMO_STATUS.IDLE;
|
|
1432
|
+
}, [isApplied, promoCodeVerified, promoCodeValidating, suggestionActive, suggestionDismissed, applyingCode, ticketDataLoaded, hasTickets]); // Hook's own validation error. Composed from the in-flight API error (if any)
|
|
1433
|
+
// and the status-derived "invalid code" message when status is INVALID.
|
|
1434
|
+
// Consumers may layer their own warning on top before display.
|
|
1435
|
+
|
|
1436
|
+
const validationError = manualError ?? (status === constants.PROMO_STATUS.INVALID ? external_i18n_react_default().translate('promo_code.invalid_code') : null); // --- Derived values ---
|
|
1437
|
+
|
|
1438
|
+
const suggestedCode = discoveredPromoCode?.code || null;
|
|
1439
|
+
const activeDiscoveredCode = status === constants.PROMO_STATUS.VALID && isDiscoveredCode ? discoveredPromoCode : null;
|
|
1440
|
+
const perAccountLimit = activeDiscoveredCode?.quantity_per_account > 0 ? activeDiscoveredCode.remaining_quantity_per_account : null; // Tightest promo-code-level quantity cap for the stepper (discovered codes only).
|
|
1441
|
+
// Both cap sources use `!= null` so a value of 0 (sold-out / no remaining) caps the
|
|
1442
|
+
// stepper at 0 instead of being silently ignored.
|
|
1443
|
+
|
|
1444
|
+
const maxQuantityFromPromo = (0,external_react_.useMemo)(() => {
|
|
1445
|
+
if (!activeDiscoveredCode) return null;
|
|
1446
|
+
const caps = [];
|
|
1447
|
+
if (activeDiscoveredCode.remaining_quantity_per_account != null) caps.push(activeDiscoveredCode.remaining_quantity_per_account);
|
|
1448
|
+
if (activeDiscoveredCode.quantity_available != null) caps.push(activeDiscoveredCode.quantity_available);
|
|
1449
|
+
return caps.length > 0 ? Math.min(...caps) : null;
|
|
1450
|
+
}, [activeDiscoveredCode]); // True when the user can safely advance from the ticket step
|
|
1451
|
+
// (no in-flight promo apply/validate and no INVALID state to block on).
|
|
1452
|
+
|
|
1453
|
+
const isReady = status === constants.PROMO_STATUS.IDLE || status === constants.PROMO_STATUS.SUGGESTED || status === constants.PROMO_STATUS.VALID; // --- Discovery: ticket qualification ---
|
|
1454
|
+
|
|
1455
|
+
const isCodeValidForTicket = (0,external_react_.useCallback)(ticket => {
|
|
1456
|
+
if (!discoveredPromoCode || !ticket) return false;
|
|
1457
|
+
const allowed = discoveredPromoCode.allowed_ticket_types || [];
|
|
1458
|
+
if (allowed.length === 0) return true;
|
|
1459
|
+
return allowed.some(tt => (typeof tt === 'object' ? tt.id : tt) === ticket.id);
|
|
1460
|
+
}, [discoveredPromoCode]); // --- Helpers ---
|
|
1461
|
+
|
|
1462
|
+
const handleValidationError = (0,external_react_.useCallback)(e => {
|
|
1463
|
+
if (e?.res?.body) {
|
|
1464
|
+
const errors = e.res.body.errors || [e.res.body.message || external_i18n_react_default().translate('promo_code.validation_error')];
|
|
1465
|
+
const first = errors[0];
|
|
1466
|
+
const firstStr = typeof first === 'string' ? first : first?.message ?? String(first);
|
|
1467
|
+
const msg = /is not a valid code/i.test(firstStr) ? external_i18n_react_default().translate('promo_code.invalid_code') : firstStr;
|
|
1468
|
+
setManualError(msg);
|
|
1469
|
+
} else {
|
|
1470
|
+
setManualError(external_i18n_react_default().translate('promo_code.validation_error'));
|
|
1471
|
+
}
|
|
1472
|
+
}, []); // --- Actions ---
|
|
1473
|
+
|
|
1474
|
+
const onRevalidate = (0,external_react_.useCallback)(async (ticket, quantity) => {
|
|
1475
|
+
setManualError(null);
|
|
1476
|
+
|
|
1477
|
+
try {
|
|
1478
|
+
await validatePromoCode({
|
|
1479
|
+
id: ticket.id,
|
|
1480
|
+
ticketQuantity: quantity,
|
|
1481
|
+
sub_type: ticket.sub_type
|
|
1482
|
+
});
|
|
1483
|
+
return true;
|
|
1484
|
+
} catch (e) {
|
|
1485
|
+
handleValidationError(e);
|
|
1486
|
+
return false;
|
|
1487
|
+
}
|
|
1488
|
+
}, [validatePromoCode, handleValidationError]); // Shared auto-apply flow. Caller is responsible for the gating conditions
|
|
1489
|
+
// (auto_apply / single code / not already applied / not user-removed) so each
|
|
1490
|
+
// call site keeps its own trigger logic. Returns true if the code was applied
|
|
1491
|
+
// and (if a ticket was passed) successfully revalidated.
|
|
1492
|
+
//
|
|
1493
|
+
// Note on concurrency: the two call sites (early-auto-apply effect and
|
|
1494
|
+
// onTicketSelected's auto-apply branch) operate on disjoint states by design
|
|
1495
|
+
// (the effect requires `!hasTickets`, the branch requires a selected ticket),
|
|
1496
|
+
// so a true concurrent invocation is unreachable in practice. If a future
|
|
1497
|
+
// change makes that overlap possible, gate this body with a ref-tracked
|
|
1498
|
+
// in-flight flag rather than `applyingCode` (which is captured stale here).
|
|
1499
|
+
|
|
1500
|
+
const tryAutoApply = (0,external_react_.useCallback)(async ticket => {
|
|
1501
|
+
setIsAutoApplied(true);
|
|
1502
|
+
setApplyingCode(true);
|
|
1503
|
+
|
|
1504
|
+
try {
|
|
1505
|
+
await applyPromoCode(discoveredPromoCode.code);
|
|
1506
|
+
|
|
1507
|
+
if (ticket) {
|
|
1508
|
+
const valid = await onRevalidate(ticket, 1);
|
|
1509
|
+
|
|
1510
|
+
if (!valid) {
|
|
1511
|
+
setIsAutoApplied(false);
|
|
1512
|
+
return false;
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1516
|
+
return true;
|
|
1517
|
+
} catch (e) {
|
|
1518
|
+
setIsAutoApplied(false);
|
|
1519
|
+
handleValidationError(e);
|
|
1520
|
+
return false;
|
|
1521
|
+
} finally {
|
|
1522
|
+
setApplyingCode(false);
|
|
1523
|
+
}
|
|
1524
|
+
}, [discoveredPromoCode, applyPromoCode, onRevalidate, handleValidationError]);
|
|
1525
|
+
const onTicketSelected = (0,external_react_.useCallback)(async ticket => {
|
|
1526
|
+
const qualifies = discoveredPromoCode && isCodeValidForTicket(ticket);
|
|
1527
|
+
setSuggestionActive(qualifies);
|
|
1528
|
+
setSuggestionDismissed(false);
|
|
1529
|
+
setManualError(null); // Manual (non-discovered) code is applied: re-validate for new ticket
|
|
1530
|
+
|
|
1531
|
+
if (isApplied && !isDiscoveredCode) {
|
|
1532
|
+
await onRevalidate(ticket, 1);
|
|
1533
|
+
return;
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
if (!discoveredPromoCode) return; // Discovered code is currently applied
|
|
1537
|
+
|
|
1538
|
+
if (isDiscoveredCode) {
|
|
1539
|
+
if (!qualifies) {
|
|
1540
|
+
setIsAutoApplied(false);
|
|
1541
|
+
removePromoCode();
|
|
1542
|
+
} else {
|
|
1543
|
+
const valid = await onRevalidate(ticket, 1);
|
|
1544
|
+
if (!valid) setIsAutoApplied(false);
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1547
|
+
return;
|
|
1548
|
+
} // No code applied, ticket qualifies, auto-apply configured, single code only
|
|
1549
|
+
|
|
1550
|
+
|
|
1551
|
+
if (!isApplied && qualifies && discoveredPromoCode.auto_apply && !userRemovedAutoApply && discoveredPromoCodes.length === 1) {
|
|
1552
|
+
await tryAutoApply(ticket);
|
|
1553
|
+
}
|
|
1554
|
+
}, [discoveredPromoCode, isApplied, isDiscoveredCode, userRemovedAutoApply, discoveredPromoCodes, isCodeValidForTicket, removePromoCode, onRevalidate, tryAutoApply]); // Early auto-apply: when no tickets are available and a single auto_apply code
|
|
1555
|
+
// was discovered, apply it so the API returns WithPromoCode ticket types.
|
|
1556
|
+
// On failure, mark as removed to prevent re-fire loops.
|
|
1557
|
+
|
|
1558
|
+
(0,external_react_.useEffect)(() => {
|
|
1559
|
+
if (userRemovedAutoApply || isApplied) return;
|
|
1560
|
+
if (!ticketDataLoaded || hasTickets) return;
|
|
1561
|
+
if (!discoveredPromoCode?.auto_apply) return;
|
|
1562
|
+
if (discoveredPromoCodes.length !== 1) return;
|
|
1563
|
+
tryAutoApply(null).then(success => {
|
|
1564
|
+
if (!success) setUserRemovedAutoApply(true);
|
|
1565
|
+
});
|
|
1566
|
+
}, [userRemovedAutoApply, ticketDataLoaded, hasTickets, discoveredPromoCode, discoveredPromoCodes, isApplied, tryAutoApply]);
|
|
1567
|
+
const onApply = (0,external_react_.useCallback)(async (code, ticket, quantity) => {
|
|
1568
|
+
setManualError(null);
|
|
1569
|
+
setApplyingCode(true);
|
|
1570
|
+
|
|
1571
|
+
try {
|
|
1572
|
+
await applyPromoCode(code);
|
|
1573
|
+
} catch (e) {
|
|
1574
|
+
handleValidationError(e);
|
|
1575
|
+
setApplyingCode(false);
|
|
1576
|
+
return;
|
|
1577
|
+
}
|
|
1578
|
+
|
|
1579
|
+
if (ticket) {
|
|
1580
|
+
await onRevalidate(ticket, quantity);
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
setApplyingCode(false);
|
|
1584
|
+
}, [applyPromoCode, onRevalidate, handleValidationError]);
|
|
1585
|
+
const onRemove = (0,external_react_.useCallback)(() => {
|
|
1586
|
+
if (isAutoApplied || isDiscoveredCode) setUserRemovedAutoApply(true);
|
|
1587
|
+
setIsAutoApplied(false);
|
|
1588
|
+
setManualError(null);
|
|
1589
|
+
setSuggestionDismissed(false);
|
|
1590
|
+
if (discoveredPromoCode) setSuggestionActive(true);
|
|
1591
|
+
setFormPromoCode('');
|
|
1592
|
+
removePromoCode();
|
|
1593
|
+
}, [isAutoApplied, isDiscoveredCode, discoveredPromoCode, removePromoCode, setFormPromoCode]);
|
|
1594
|
+
const onInputChange = (0,external_react_.useCallback)(value => {
|
|
1595
|
+
setManualError(null);
|
|
1596
|
+
setSuggestionDismissed(value !== discoveredPromoCode?.code);
|
|
1597
|
+
setFormPromoCode(value);
|
|
1598
|
+
}, [discoveredPromoCode, setFormPromoCode]);
|
|
1599
|
+
return {
|
|
1600
|
+
state: {
|
|
1601
|
+
// Status (what's happening with the applied/suggested code)
|
|
1602
|
+
status,
|
|
1603
|
+
isReady,
|
|
1604
|
+
validationError,
|
|
1605
|
+
// Applied code origin
|
|
1606
|
+
isDiscoveredCode,
|
|
1607
|
+
isAutoApplied,
|
|
1608
|
+
// Discovery / suggestion
|
|
1609
|
+
suggestedCode,
|
|
1610
|
+
// Quantity caps from the active discovered code
|
|
1611
|
+
maxQuantityFromPromo,
|
|
1612
|
+
perAccountLimit
|
|
1613
|
+
},
|
|
1614
|
+
actions: {
|
|
1615
|
+
// Ordered by lifecycle: input → apply → ticket change → revalidate → remove
|
|
1616
|
+
onInputChange,
|
|
1617
|
+
onApply,
|
|
1618
|
+
onTicketSelected,
|
|
1619
|
+
onRevalidate,
|
|
1620
|
+
onRemove
|
|
1621
|
+
}
|
|
1622
|
+
};
|
|
1623
|
+
};
|
|
1624
|
+
|
|
1625
|
+
/* harmony default export */ const hooks_usePromoCode = (usePromoCode);
|
|
1358
1626
|
;// CONCATENATED MODULE: external "openstack-uicore-foundation/lib/components/ajaxloader"
|
|
1359
1627
|
const ajaxloader_namespaceObject = require("openstack-uicore-foundation/lib/components/ajaxloader");
|
|
1360
1628
|
var ajaxloader_default = /*#__PURE__*/__webpack_require__.n(ajaxloader_namespaceObject);
|
|
@@ -1376,8 +1644,6 @@ const methods_namespaceObject = require("openstack-uicore-foundation/lib/utils/m
|
|
|
1376
1644
|
;// CONCATENATED MODULE: ./src/components/lawpay-form/index.module.scss
|
|
1377
1645
|
// extracted by mini-css-extract-plugin
|
|
1378
1646
|
/* harmony default export */ const lawpay_form_index_module = ({"form":"form___zXb7s","fieldWrapper":"fieldWrapper___G4Wqw","inputWrapper":"inputWrapper___Yz5zB","fieldRow":"fieldRow___NfZdJ","addressField":"addressField___vmAQh","lawpayWrapper":"lawpayWrapper___hpUBf","dateWrapper":"dateWrapper___XDfqs","dropdown":"dropdown___l3_bk","fieldError":"fieldError___Igq3U"});
|
|
1379
|
-
// EXTERNAL MODULE: ./src/utils/constants.js
|
|
1380
|
-
var constants = __webpack_require__(243);
|
|
1381
1647
|
;// CONCATENATED MODULE: ./src/components/lawpay-form/index.js
|
|
1382
1648
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
1383
1649
|
|
|
@@ -2122,7 +2388,7 @@ var company_input_v2_default = /*#__PURE__*/__webpack_require__.n(company_input_
|
|
|
2122
2388
|
var helpers = __webpack_require__(499);
|
|
2123
2389
|
;// CONCATENATED MODULE: ./src/components/personal-information/index.module.scss
|
|
2124
2390
|
// extracted by mini-css-extract-plugin
|
|
2125
|
-
/* harmony default export */ const personal_information_index_module = ({"title":"title___ECoNz","form":"form___lDFka","fieldWrapper":"fieldWrapper___Mi_nL","fieldWrapperRadio":"fieldWrapperRadio___x18VG","inputWrapper":"inputWrapper___PEQFR","readOnly":"readOnly___WRazF","fieldError":"fieldError___ksJVe","moreInfo":"moreInfo___cQYdZ","moreInfoTooltip":"moreInfoTooltip___lslgT","ticketQuantityNotice":"ticketQuantityNotice___L6gis","formErrors":"formErrors___dQQMe"});
|
|
2391
|
+
/* harmony default export */ const personal_information_index_module = ({"title":"title___ECoNz","form":"form___lDFka","fieldWrapper":"fieldWrapper___Mi_nL","fieldWrapperRadio":"fieldWrapperRadio___x18VG","form-check-label":"form-check-label___MgGSC","inputWrapper":"inputWrapper___PEQFR","readOnly":"readOnly___WRazF","fieldError":"fieldError___ksJVe","moreInfo":"moreInfo___cQYdZ","moreInfoTooltip":"moreInfoTooltip___lslgT","ticketQuantityNotice":"ticketQuantityNotice___L6gis","formErrors":"formErrors___dQQMe"});
|
|
2126
2392
|
;// CONCATENATED MODULE: ./src/components/personal-information/index.js
|
|
2127
2393
|
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
2128
2394
|
|
|
@@ -2163,20 +2429,27 @@ const PersonalInfoComponent = ({
|
|
|
2163
2429
|
summitId,
|
|
2164
2430
|
handleCompanyError,
|
|
2165
2431
|
formValues,
|
|
2166
|
-
formErrors =
|
|
2432
|
+
formErrors = [],
|
|
2167
2433
|
invitation,
|
|
2168
2434
|
showCompanyInput = true,
|
|
2169
2435
|
companyDDLPlaceholder,
|
|
2170
2436
|
showCompanyInputDefaultOptions,
|
|
2171
|
-
companyDDLOptions2Show
|
|
2437
|
+
companyDDLOptions2Show,
|
|
2438
|
+
promoCodeAllowsReassign = true
|
|
2172
2439
|
}) => {
|
|
2173
2440
|
const initialFirstName = userProfile.given_name || (invitation ? invitation.first_name : '');
|
|
2174
2441
|
const initialLastName = userProfile.family_name || (invitation ? invitation.last_name : '');
|
|
2175
2442
|
const [ticketOwnerOption, setTicketOwnerOption] = (0,external_react_.useState)('');
|
|
2176
|
-
const [ticketOwnerError, setTicketOwnerError] = (0,external_react_.useState)(false); // if there's only one ticket on the order and there is no invitation available,
|
|
2443
|
+
const [ticketOwnerError, setTicketOwnerError] = (0,external_react_.useState)(false); // if there's only one ticket on the order and there is no invitation available, handle ticket assignment
|
|
2444
|
+
|
|
2445
|
+
const isSingleTicketOrder = formValues.ticketQuantity === 1 && !invitation && !(0,utils/* isPrePaidTicketType */.B6)(formValues.ticketType); // check if reassignment is allowed by both promo code AND ticket type
|
|
2177
2446
|
|
|
2178
|
-
const
|
|
2447
|
+
const ticketTypeAllowsReassign = formValues.ticketType?.allows_to_reassign !== false;
|
|
2448
|
+
const canReassign = promoCodeAllowsReassign && ticketTypeAllowsReassign; // show radio options only if reassignment is allowed by both sources
|
|
2179
2449
|
|
|
2450
|
+
const shouldDisplayTicketAssignment = isSingleTicketOrder && canReassign; // show notice when ticket is non-transferable (either promo code or ticket type disallows)
|
|
2451
|
+
|
|
2452
|
+
const isNonTransferable = isSingleTicketOrder && !canReassign;
|
|
2180
2453
|
const radioListOptions = [{
|
|
2181
2454
|
label: "Myself",
|
|
2182
2455
|
value: constants.TICKET_OWNER_MYSELF
|
|
@@ -2219,7 +2492,7 @@ const PersonalInfoComponent = ({
|
|
|
2219
2492
|
email: reservation.owner_email ? reservation.owner_email : personalInfo.email,
|
|
2220
2493
|
company: {
|
|
2221
2494
|
id: null,
|
|
2222
|
-
name: reservation.owner_company
|
|
2495
|
+
name: reservation.owner_company || personalInfo.company?.name || ''
|
|
2223
2496
|
}
|
|
2224
2497
|
});
|
|
2225
2498
|
}
|
|
@@ -2235,12 +2508,21 @@ const PersonalInfoComponent = ({
|
|
|
2235
2508
|
};
|
|
2236
2509
|
|
|
2237
2510
|
const onSubmit = data => {
|
|
2238
|
-
if (!personalInfo.company
|
|
2511
|
+
if (!personalInfo.company?.name && showCompanyInput) {
|
|
2239
2512
|
setCompanyError(true);
|
|
2240
2513
|
return;
|
|
2241
2514
|
}
|
|
2242
2515
|
|
|
2243
|
-
if (
|
|
2516
|
+
if (isNonTransferable) {
|
|
2517
|
+
// auto-assign to purchaser when ticket is non-transferable
|
|
2518
|
+
data = personal_information_objectSpread(personal_information_objectSpread({}, data), {}, {
|
|
2519
|
+
attendee: {
|
|
2520
|
+
firstName: data.firstName,
|
|
2521
|
+
lastName: data.lastName,
|
|
2522
|
+
email: data.email
|
|
2523
|
+
}
|
|
2524
|
+
});
|
|
2525
|
+
} else if (shouldDisplayTicketAssignment) {
|
|
2244
2526
|
if (!ticketOwnerOption) {
|
|
2245
2527
|
setTicketOwnerError(true);
|
|
2246
2528
|
return;
|
|
@@ -2337,7 +2619,7 @@ const PersonalInfoComponent = ({
|
|
|
2337
2619
|
className: personal_information_index_module.title
|
|
2338
2620
|
}, /*#__PURE__*/external_react_default().createElement("span", null, "Purchaser Information"), !isActive && /*#__PURE__*/external_react_default().createElement("div", {
|
|
2339
2621
|
"data-testid": "personal-info"
|
|
2340
|
-
}, /*#__PURE__*/external_react_default().createElement("span", null, `${personalInfo.firstName} ${personalInfo.lastName}${personalInfo.company
|
|
2622
|
+
}, /*#__PURE__*/external_react_default().createElement("span", null, `${personalInfo.firstName} ${personalInfo.lastName}${personalInfo.company?.name ? ` - ${personalInfo.company.name}` : ''}`), /*#__PURE__*/external_react_default().createElement("br", null), /*#__PURE__*/external_react_default().createElement("span", null, personalInfo.email))), /*#__PURE__*/external_react_default().createElement(external_react_spring_namespaceObject.animated.div, {
|
|
2341
2623
|
style: personal_information_objectSpread({
|
|
2342
2624
|
overflow: `${isActive ? '' : 'hidden'}`
|
|
2343
2625
|
}, toggleAnimation)
|
|
@@ -2432,7 +2714,7 @@ const PersonalInfoComponent = ({
|
|
|
2432
2714
|
}), companyError && /*#__PURE__*/external_react_default().createElement("div", {
|
|
2433
2715
|
className: personal_information_index_module.fieldError,
|
|
2434
2716
|
"data-testid": "company-error"
|
|
2435
|
-
}, "This field is required."))), shouldDisplayTicketAssignment
|
|
2717
|
+
}, "This field is required."))), shouldDisplayTicketAssignment && /*#__PURE__*/external_react_default().createElement((external_react_default()).Fragment, null, /*#__PURE__*/external_react_default().createElement("div", {
|
|
2436
2718
|
className: personal_information_index_module.fieldWrapperRadio
|
|
2437
2719
|
}, /*#__PURE__*/external_react_default().createElement("label", null, "Ticket is for:"), /*#__PURE__*/external_react_default().createElement(components_namespaceObject.RadioList, {
|
|
2438
2720
|
id: `ticket-self-radio`,
|
|
@@ -2500,12 +2782,9 @@ const PersonalInfoComponent = ({
|
|
|
2500
2782
|
;// CONCATENATED MODULE: external "openstack-uicore-foundation/lib/components/raw-html"
|
|
2501
2783
|
const raw_html_namespaceObject = require("openstack-uicore-foundation/lib/components/raw-html");
|
|
2502
2784
|
var raw_html_default = /*#__PURE__*/__webpack_require__.n(raw_html_namespaceObject);
|
|
2503
|
-
;// CONCATENATED MODULE: external "i18n-react"
|
|
2504
|
-
const external_i18n_react_namespaceObject = require("i18n-react");
|
|
2505
|
-
var external_i18n_react_default = /*#__PURE__*/__webpack_require__.n(external_i18n_react_namespaceObject);
|
|
2506
2785
|
;// CONCATENATED MODULE: ./src/components/ticket-type/index.module.scss
|
|
2507
2786
|
// extracted by mini-css-extract-plugin
|
|
2508
|
-
/* harmony default export */ const ticket_type_index_module = ({"title":"title___DNZyl","summary":"summary___quWdZ","promoCode":"promoCode___bqTCw","crossOut":"crossOut___QZ7dy","discount":"discount___sEK_Q","
|
|
2787
|
+
/* harmony default export */ const ticket_type_index_module = ({"title":"title___DNZyl","summary":"summary___quWdZ","promoCode":"promoCode___bqTCw","crossOut":"crossOut___QZ7dy","discount":"discount___sEK_Q","taxes":"taxes___fe8oJ","promo":"promo___F8lPO","form":"form___aoo7w","dropdown":"dropdown____HWg0","quantity":"quantity___SIEQZ","soldOut":"soldOut___Hatfr","moreInfo":"moreInfo___LmwOe","moreInfoTooltip":"moreInfoTooltip___nOBf1","inPersonDisclaimer":"inPersonDisclaimer___PXGTz"});
|
|
2509
2788
|
;// CONCATENATED MODULE: external "lodash/isEqual"
|
|
2510
2789
|
const isEqual_namespaceObject = require("lodash/isEqual");
|
|
2511
2790
|
var isEqual_default = /*#__PURE__*/__webpack_require__.n(isEqual_namespaceObject);
|
|
@@ -2550,7 +2829,7 @@ const TicketDropdownComponent = ({
|
|
|
2550
2829
|
(0,external_react_.useEffect)(() => {
|
|
2551
2830
|
const prevTicketTypes = prevTicketTypesRef.current;
|
|
2552
2831
|
|
|
2553
|
-
if (!isEqual_default()(
|
|
2832
|
+
if (!isEqual_default()(prevTicketTypes, ticketTypes)) {
|
|
2554
2833
|
setCurrentTicketTypes(ticketTypes);
|
|
2555
2834
|
}
|
|
2556
2835
|
|
|
@@ -2593,12 +2872,9 @@ const TicketDropdownComponent = ({
|
|
|
2593
2872
|
;// CONCATENATED MODULE: external "react-tooltip"
|
|
2594
2873
|
const external_react_tooltip_namespaceObject = require("react-tooltip");
|
|
2595
2874
|
var external_react_tooltip_default = /*#__PURE__*/__webpack_require__.n(external_react_tooltip_namespaceObject);
|
|
2596
|
-
// EXTERNAL MODULE: ./src/assets/icon-check-circle.svg
|
|
2597
|
-
var icon_check_circle = __webpack_require__(60);
|
|
2598
|
-
var icon_check_circle_default = /*#__PURE__*/__webpack_require__.n(icon_check_circle);
|
|
2599
2875
|
;// CONCATENATED MODULE: ./src/components/promocode-input/index.module.scss
|
|
2600
2876
|
// extracted by mini-css-extract-plugin
|
|
2601
|
-
/* harmony default export */ const promocode_input_index_module = ({"promoCodeWrapper":"promoCodeWrapper___aw3Zx","promoCodeInput":"promoCodeInput___rDiET","promoCodeActive":"promoCodeActive___j7xnn","codeButtonWrapper":"codeButtonWrapper___jVZh5","noCode":"noCode___YUmVy","
|
|
2877
|
+
/* harmony default export */ const promocode_input_index_module = ({"promoCodeWrapper":"promoCodeWrapper___aw3Zx","promoCodeInput":"promoCodeInput___rDiET","promoCodeActive":"promoCodeActive___j7xnn","codeButtonWrapper":"codeButtonWrapper___jVZh5","noCode":"noCode___YUmVy","statusIcon":"statusIcon___l1uV0","valid":"valid___pDUq_","invalid":"invalid___UO9dX","spinner":"spinner___SKEJg","spin":"spin___wP5uK","moreInfo":"moreInfo___Ru3Rv","moreInfoTooltip":"moreInfoTooltip___eaYWm"});
|
|
2602
2878
|
;// CONCATENATED MODULE: ./src/components/promocode-input/index.js
|
|
2603
2879
|
/**
|
|
2604
2880
|
* Copyright 2020 OpenStack Foundation
|
|
@@ -2620,56 +2896,101 @@ var icon_check_circle_default = /*#__PURE__*/__webpack_require__.n(icon_check_ci
|
|
|
2620
2896
|
|
|
2621
2897
|
|
|
2622
2898
|
const PromoCodeInput = ({
|
|
2623
|
-
|
|
2899
|
+
promoStatus,
|
|
2624
2900
|
promoCode,
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2901
|
+
suggestedCode,
|
|
2902
|
+
isAutoApplied,
|
|
2903
|
+
onApply,
|
|
2904
|
+
onRemove,
|
|
2905
|
+
onInputChange,
|
|
2906
|
+
showMultipleTicketTexts
|
|
2628
2907
|
}) => {
|
|
2629
|
-
const [
|
|
2908
|
+
const [userTypedValue, setUserTypedValue] = (0,external_react_.useState)('');
|
|
2909
|
+
(0,external_react_.useEffect)(() => {
|
|
2910
|
+
if (!promoCode) setUserTypedValue('');
|
|
2911
|
+
}, [promoCode]); // Lock the input + show Remove (instead of Apply) whenever a code is in flight
|
|
2912
|
+
// or has settled (valid or invalid). The user must explicitly Remove to edit again.
|
|
2913
|
+
|
|
2914
|
+
const isLocked = promoStatus === constants.PROMO_STATUS.APPLYING || promoStatus === constants.PROMO_STATUS.VALIDATING || promoStatus === constants.PROMO_STATUS.VALID || promoStatus === constants.PROMO_STATUS.INVALID;
|
|
2915
|
+
const inputValue = (0,external_react_.useMemo)(() => {
|
|
2916
|
+
if (promoCode) return promoCode;
|
|
2917
|
+
if (promoStatus === constants.PROMO_STATUS.SUGGESTED) return suggestedCode || '';
|
|
2918
|
+
return userTypedValue;
|
|
2919
|
+
}, [promoCode, promoStatus, suggestedCode, userTypedValue]);
|
|
2920
|
+
const label = (0,external_react_.useMemo)(() => {
|
|
2921
|
+
switch (promoStatus) {
|
|
2922
|
+
case constants.PROMO_STATUS.VALID:
|
|
2923
|
+
if (isAutoApplied) return external_i18n_react_default().translate('promo_code.auto_applied_label');
|
|
2924
|
+
return external_i18n_react_default().translate('promo_code.applied_label');
|
|
2925
|
+
|
|
2926
|
+
case constants.PROMO_STATUS.APPLYING:
|
|
2927
|
+
case constants.PROMO_STATUS.VALIDATING:
|
|
2928
|
+
if (isAutoApplied) return external_i18n_react_default().translate('promo_code.auto_applied_label');
|
|
2929
|
+
return external_i18n_react_default().translate('promo_code.applying_label');
|
|
2930
|
+
|
|
2931
|
+
case constants.PROMO_STATUS.INVALID:
|
|
2932
|
+
return undefined;
|
|
2933
|
+
|
|
2934
|
+
case constants.PROMO_STATUS.SUGGESTED:
|
|
2935
|
+
return external_i18n_react_default().translate('promo_code.suggestion_label');
|
|
2936
|
+
|
|
2937
|
+
default:
|
|
2938
|
+
return undefined;
|
|
2939
|
+
}
|
|
2940
|
+
}, [promoStatus, isAutoApplied]);
|
|
2941
|
+
const canApply = !isLocked && !!inputValue;
|
|
2630
2942
|
|
|
2631
|
-
const
|
|
2632
|
-
|
|
2633
|
-
|
|
2943
|
+
const handleInputChange = value => {
|
|
2944
|
+
setUserTypedValue(value);
|
|
2945
|
+
onInputChange(value);
|
|
2634
2946
|
};
|
|
2635
2947
|
|
|
2636
|
-
(0,external_react_.useEffect)(() => {
|
|
2637
|
-
if ((0,utils/* isEmptyString */.ke)(promoCode)) handlePromoCodeChange(promoCode);
|
|
2638
|
-
}, [promoCode]);
|
|
2639
2948
|
return /*#__PURE__*/external_react_default().createElement((external_react_default()).Fragment, null, /*#__PURE__*/external_react_default().createElement("div", {
|
|
2640
2949
|
className: promocode_input_index_module.promoCodeWrapper
|
|
2641
|
-
}, /*#__PURE__*/external_react_default().createElement("span",
|
|
2950
|
+
}, /*#__PURE__*/external_react_default().createElement("span", {
|
|
2951
|
+
style: {
|
|
2952
|
+
display: 'flex',
|
|
2953
|
+
justifyContent: 'space-between',
|
|
2954
|
+
alignItems: 'center'
|
|
2955
|
+
}
|
|
2956
|
+
}, /*#__PURE__*/external_react_default().createElement("span", null, label || external_i18n_react_default().translate('promo_code.default_label')), showMultipleTicketTexts && /*#__PURE__*/external_react_default().createElement("a", {
|
|
2957
|
+
"data-tip": true,
|
|
2958
|
+
"data-for": "promo-code-info",
|
|
2959
|
+
className: promocode_input_index_module.moreInfo,
|
|
2960
|
+
style: {
|
|
2961
|
+
margin: 0
|
|
2962
|
+
}
|
|
2963
|
+
}, /*#__PURE__*/external_react_default().createElement("i", {
|
|
2964
|
+
className: "glyphicon glyphicon-info-sign",
|
|
2965
|
+
"aria-hidden": "true"
|
|
2966
|
+
}), ` `, "Have multiple promo codes?")), /*#__PURE__*/external_react_default().createElement("div", {
|
|
2642
2967
|
className: promocode_input_index_module.promoCodeInput
|
|
2643
2968
|
}, /*#__PURE__*/external_react_default().createElement("input", {
|
|
2644
|
-
className: `${
|
|
2969
|
+
className: `${isLocked ? promocode_input_index_module.promoCodeActive : ''}`,
|
|
2645
2970
|
type: "text",
|
|
2646
|
-
value:
|
|
2647
|
-
onChange: ev =>
|
|
2971
|
+
value: inputValue,
|
|
2972
|
+
onChange: ev => handleInputChange(ev.target.value),
|
|
2648
2973
|
placeholder: "Enter your promo code",
|
|
2649
2974
|
onKeyDown: e => {
|
|
2650
|
-
if (e.key === "Enter")
|
|
2975
|
+
if (e.key === "Enter" && canApply) onApply(inputValue);
|
|
2651
2976
|
},
|
|
2652
|
-
readOnly:
|
|
2653
|
-
}),
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2977
|
+
readOnly: isLocked
|
|
2978
|
+
}), (promoStatus === constants.PROMO_STATUS.VALIDATING || promoStatus === constants.PROMO_STATUS.APPLYING) && /*#__PURE__*/external_react_default().createElement("span", {
|
|
2979
|
+
className: `${promocode_input_index_module.statusIcon} ${promocode_input_index_module.spinner}`
|
|
2980
|
+
}), promoStatus === constants.PROMO_STATUS.VALID && /*#__PURE__*/external_react_default().createElement("span", {
|
|
2981
|
+
className: `${promocode_input_index_module.statusIcon} ${promocode_input_index_module.valid}`
|
|
2982
|
+
}, "\u2713"), promoStatus === constants.PROMO_STATUS.INVALID && /*#__PURE__*/external_react_default().createElement("span", {
|
|
2983
|
+
className: `${promocode_input_index_module.statusIcon} ${promocode_input_index_module.invalid}`
|
|
2984
|
+
}, "\u2715"), /*#__PURE__*/external_react_default().createElement("div", {
|
|
2985
|
+
className: `${promocode_input_index_module.codeButtonWrapper} ${inputValue ? '' : promocode_input_index_module.noCode}`
|
|
2986
|
+
}, isLocked ? /*#__PURE__*/external_react_default().createElement("button", {
|
|
2987
|
+
onClick: onRemove
|
|
2660
2988
|
}, "Remove") : /*#__PURE__*/external_react_default().createElement("button", {
|
|
2661
|
-
disabled: !
|
|
2662
|
-
onClick: () =>
|
|
2663
|
-
}, "Apply"))),
|
|
2664
|
-
className: promocode_input_index_module.moreInfo
|
|
2665
|
-
}, /*#__PURE__*/external_react_default().createElement("a", {
|
|
2666
|
-
"data-tip": true,
|
|
2667
|
-
"data-for": "promo-code-info"
|
|
2668
|
-
}, /*#__PURE__*/external_react_default().createElement("i", {
|
|
2669
|
-
className: "glyphicon glyphicon-info-sign",
|
|
2670
|
-
"aria-hidden": "true"
|
|
2671
|
-
}), ` `, "Have multiple promo codes?"))), /*#__PURE__*/external_react_default().createElement((external_react_tooltip_default()), {
|
|
2989
|
+
disabled: !canApply,
|
|
2990
|
+
onClick: () => onApply(inputValue)
|
|
2991
|
+
}, "Apply")))), /*#__PURE__*/external_react_default().createElement((external_react_tooltip_default()), {
|
|
2672
2992
|
id: "promo-code-info",
|
|
2993
|
+
place: "bottom",
|
|
2673
2994
|
overridePosition: utils/* avoidTooltipOverflow */.kb
|
|
2674
2995
|
}, /*#__PURE__*/external_react_default().createElement("div", {
|
|
2675
2996
|
className: promocode_input_index_module.moreInfoTooltip
|
|
@@ -2677,6 +2998,32 @@ const PromoCodeInput = ({
|
|
|
2677
2998
|
};
|
|
2678
2999
|
|
|
2679
3000
|
/* harmony default export */ const promocode_input = (PromoCodeInput);
|
|
3001
|
+
;// CONCATENATED MODULE: ./src/components/ticket-notice/index.module.scss
|
|
3002
|
+
// extracted by mini-css-extract-plugin
|
|
3003
|
+
/* harmony default export */ const ticket_notice_index_module = ({"notice":"notice____Pa2z","error":"error___WzZms","info":"info___WFfzs","icon":"icon___YWZms"});
|
|
3004
|
+
;// CONCATENATED MODULE: ./src/components/ticket-notice/index.js
|
|
3005
|
+
|
|
3006
|
+
// `message` is either a single string or an array of strings. Arrays render
|
|
3007
|
+
// stacked consecutively inside the same notice box. Returns null when the
|
|
3008
|
+
// message is empty/unset so callers can pass conditional arrays without an
|
|
3009
|
+
// outer guard.
|
|
3010
|
+
|
|
3011
|
+
const TicketNotice = ({
|
|
3012
|
+
message,
|
|
3013
|
+
variant = 'info'
|
|
3014
|
+
}) => {
|
|
3015
|
+
const items = Array.isArray(message) ? message : message ? [message] : [];
|
|
3016
|
+
if (items.length === 0) return null;
|
|
3017
|
+
return /*#__PURE__*/external_react_default().createElement("div", {
|
|
3018
|
+
className: `${ticket_notice_index_module.notice} ${ticket_notice_index_module[variant]}`
|
|
3019
|
+
}, variant === 'error' && /*#__PURE__*/external_react_default().createElement("span", {
|
|
3020
|
+
className: ticket_notice_index_module.icon
|
|
3021
|
+
}, "\u26A0"), items.map((m, i) => /*#__PURE__*/external_react_default().createElement("div", {
|
|
3022
|
+
key: i
|
|
3023
|
+
}, m)));
|
|
3024
|
+
};
|
|
3025
|
+
|
|
3026
|
+
/* harmony default export */ const ticket_notice = (TicketNotice);
|
|
2680
3027
|
;// CONCATENATED MODULE: ./src/components/ticket-type/index.js
|
|
2681
3028
|
function ticket_type_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
2682
3029
|
|
|
@@ -2711,6 +3058,7 @@ function ticket_type_defineProperty(obj, key, value) { if (key in obj) { Object.
|
|
|
2711
3058
|
|
|
2712
3059
|
|
|
2713
3060
|
|
|
3061
|
+
|
|
2714
3062
|
const TicketTypeComponent = ({
|
|
2715
3063
|
allowedTicketTypes,
|
|
2716
3064
|
originalTicketTypes,
|
|
@@ -2718,20 +3066,35 @@ const TicketTypeComponent = ({
|
|
|
2718
3066
|
taxTypes,
|
|
2719
3067
|
isActive,
|
|
2720
3068
|
changeForm,
|
|
2721
|
-
formErrors,
|
|
2722
3069
|
reservation,
|
|
2723
3070
|
inPersonDisclaimer,
|
|
2724
3071
|
showMultipleTicketTexts,
|
|
2725
3072
|
allowPromoCodes,
|
|
2726
|
-
|
|
2727
|
-
|
|
3073
|
+
promo = {},
|
|
3074
|
+
validationError,
|
|
2728
3075
|
promoCode,
|
|
2729
|
-
|
|
3076
|
+
promoCodeAllowsReassign = true,
|
|
3077
|
+
trackViewItem,
|
|
3078
|
+
noTicketsAvailableMessage
|
|
2730
3079
|
}) => {
|
|
3080
|
+
const {
|
|
3081
|
+
state: promoState = {},
|
|
3082
|
+
actions: promoActions = {}
|
|
3083
|
+
} = promo;
|
|
2731
3084
|
const [ticket, setTicket] = (0,external_react_.useState)(null);
|
|
2732
3085
|
const [quantity, setQuantity] = (0,external_react_.useState)(1);
|
|
2733
3086
|
const minQuantity = 1;
|
|
2734
|
-
const maxQuantity = (0,helpers/* getTicketMaxQuantity */.UE)(ticket);
|
|
3087
|
+
const maxQuantity = (0,helpers/* getTicketMaxQuantity */.UE)(ticket, promoState.maxQuantityFromPromo); // Clamp quantity when max changes (e.g. per-account limit kicks in after auto-apply).
|
|
3088
|
+
// If the cap drops below minQuantity (e.g. cap of 0), use the cap directly rather
|
|
3089
|
+
// than flooring at minQuantity, otherwise quantity would end up above the cap.
|
|
3090
|
+
|
|
3091
|
+
(0,external_react_.useEffect)(() => {
|
|
3092
|
+
if (!ticket) return;
|
|
3093
|
+
|
|
3094
|
+
if (quantity > maxQuantity) {
|
|
3095
|
+
setQuantity(maxQuantity < minQuantity ? 0 : maxQuantity);
|
|
3096
|
+
}
|
|
3097
|
+
}, [maxQuantity, quantity, ticket]);
|
|
2735
3098
|
const [ref, {
|
|
2736
3099
|
height
|
|
2737
3100
|
}] = (0,external_react_use_namespaceObject.useMeasure)();
|
|
@@ -2755,17 +3118,25 @@ const TicketTypeComponent = ({
|
|
|
2755
3118
|
}
|
|
2756
3119
|
}, []);
|
|
2757
3120
|
(0,external_react_.useEffect)(() => {
|
|
3121
|
+
const ticketSelectionValid = !!ticket && quantity >= minQuantity && quantity <= maxQuantity;
|
|
2758
3122
|
changeForm({
|
|
2759
3123
|
ticketType: ticket,
|
|
2760
|
-
ticketQuantity: quantity
|
|
3124
|
+
ticketQuantity: quantity,
|
|
3125
|
+
ticketSelectionValid
|
|
2761
3126
|
});
|
|
2762
|
-
}, [ticket, quantity]);
|
|
3127
|
+
}, [ticket, quantity, maxQuantity]);
|
|
2763
3128
|
(0,external_react_.useEffect)(() => {
|
|
2764
|
-
//
|
|
2765
|
-
//
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
3129
|
+
// When promo code changes, the API returns updated ticket types with/without discount.
|
|
3130
|
+
// Sync the selected ticket with the refreshed data.
|
|
3131
|
+
if (!ticket) {
|
|
3132
|
+
// Auto-select if only one ticket type available after promo code applied
|
|
3133
|
+
if (promoCode && originalTicketTypes.length === 1) {
|
|
3134
|
+
handleTicketChange(originalTicketTypes[0]);
|
|
3135
|
+
}
|
|
3136
|
+
|
|
3137
|
+
return;
|
|
3138
|
+
}
|
|
3139
|
+
|
|
2769
3140
|
const updatedCurrentTicket = originalTicketTypes.find(t => t?.id === ticket.id);
|
|
2770
3141
|
|
|
2771
3142
|
if (updatedCurrentTicket) {
|
|
@@ -2773,35 +3144,62 @@ const TicketTypeComponent = ({
|
|
|
2773
3144
|
ticketType: updatedCurrentTicket
|
|
2774
3145
|
});
|
|
2775
3146
|
setTicket(updatedCurrentTicket);
|
|
3147
|
+
} else {
|
|
3148
|
+
setTicket(null);
|
|
3149
|
+
setQuantity(minQuantity);
|
|
2776
3150
|
}
|
|
2777
|
-
|
|
2778
|
-
if (!promoCode) changeForm({
|
|
2779
|
-
promoCode: ''
|
|
2780
|
-
});
|
|
2781
3151
|
}, [promoCode, originalTicketTypes]);
|
|
2782
|
-
const
|
|
3152
|
+
const showTicketSelector = allowedTicketTypes.length > 0;
|
|
3153
|
+
const isPrePaidReservation = (0,external_react_.useMemo)(() => reservation ? (0,utils/* isPrePaidOrder */.xm)(reservation) : false, [reservation]); // check if reassignment is allowed by both promo code AND ticket type
|
|
3154
|
+
|
|
3155
|
+
const ticketTypeAllowsReassign = ticket?.allows_to_reassign !== false;
|
|
3156
|
+
const canReassign = promoCodeAllowsReassign && ticketTypeAllowsReassign; // Per-order cap is interesting only when it's tighter than what inventory
|
|
3157
|
+
// would otherwise allow (i.e. the binding constraint on the stepper).
|
|
3158
|
+
|
|
3159
|
+
const ticketPerOrderLimit = (0,external_react_.useMemo)(() => {
|
|
3160
|
+
if (!ticket) return null;
|
|
3161
|
+
const cap = ticket.max_quantity_per_order;
|
|
3162
|
+
const inventory = (ticket.quantity_2_sell ?? Number.MAX_SAFE_INTEGER) - (ticket.quantity_sold ?? 0);
|
|
3163
|
+
return cap != null && cap > 0 && cap < inventory ? cap : null;
|
|
3164
|
+
}, [ticket]); // Messages composed for the info notice (stacked in display order):
|
|
3165
|
+
// (1) promo per-account cap, (2) ticket-type per-order cap, (3) non-transferable.
|
|
3166
|
+
|
|
3167
|
+
const infoMessage = (0,external_react_.useMemo)(() => {
|
|
3168
|
+
if (!ticket) return [];
|
|
3169
|
+
const lines = [];
|
|
3170
|
+
|
|
3171
|
+
if (promoState.perAccountLimit != null) {
|
|
3172
|
+
lines.push(external_i18n_react_default().translate(promoState.perAccountLimit === 1 ? 'promo_code.per_account_limit_one' : 'promo_code.per_account_limit_other', {
|
|
3173
|
+
limit: promoState.perAccountLimit
|
|
3174
|
+
}));
|
|
3175
|
+
}
|
|
3176
|
+
|
|
3177
|
+
if (ticketPerOrderLimit != null) {
|
|
3178
|
+
lines.push(external_i18n_react_default().translate(ticketPerOrderLimit === 1 ? 'ticket_type.max_per_order_one' : 'ticket_type.max_per_order_other', {
|
|
3179
|
+
limit: ticketPerOrderLimit
|
|
3180
|
+
}));
|
|
3181
|
+
}
|
|
3182
|
+
|
|
3183
|
+
if (!canReassign) {
|
|
3184
|
+
lines.push(external_i18n_react_default().translate('promo_code.non_transferable'));
|
|
3185
|
+
}
|
|
2783
3186
|
|
|
2784
|
-
|
|
3187
|
+
return lines;
|
|
3188
|
+
}, [ticket, promoState.perAccountLimit, ticketPerOrderLimit, canReassign]);
|
|
3189
|
+
|
|
3190
|
+
const handleTicketChange = async t => {
|
|
2785
3191
|
setTicket(t);
|
|
2786
3192
|
setQuantity(minQuantity);
|
|
2787
3193
|
trackViewItem(t);
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
const handlePromoCodeChange = code => {
|
|
2791
|
-
changeForm({
|
|
2792
|
-
promoCode: code
|
|
2793
|
-
});
|
|
3194
|
+
await promoActions.onTicketSelected(t);
|
|
2794
3195
|
};
|
|
2795
3196
|
|
|
2796
3197
|
const incrementQuantity = () => setQuantity(quantity + 1);
|
|
2797
3198
|
|
|
2798
3199
|
const decrementQuantity = () => setQuantity(quantity - 1);
|
|
2799
3200
|
|
|
2800
|
-
const
|
|
2801
|
-
|
|
2802
|
-
const handleRemovePromoCode = () => {
|
|
2803
|
-
setTicket(null);
|
|
2804
|
-
removePromoCode();
|
|
3201
|
+
const handleApplyPromoCode = async code => {
|
|
3202
|
+
await promoActions.onApply(code, ticket, quantity);
|
|
2805
3203
|
};
|
|
2806
3204
|
|
|
2807
3205
|
return /*#__PURE__*/external_react_default().createElement("div", {
|
|
@@ -2810,9 +3208,26 @@ const TicketTypeComponent = ({
|
|
|
2810
3208
|
className: ticket_type_index_module.innerWrapper
|
|
2811
3209
|
}, /*#__PURE__*/external_react_default().createElement("div", {
|
|
2812
3210
|
className: ticket_type_index_module.title
|
|
2813
|
-
}, /*#__PURE__*/external_react_default().createElement("span",
|
|
3211
|
+
}, /*#__PURE__*/external_react_default().createElement("span", {
|
|
3212
|
+
style: isActive ? {
|
|
3213
|
+
display: 'flex',
|
|
3214
|
+
justifyContent: 'space-between',
|
|
3215
|
+
alignItems: 'center',
|
|
3216
|
+
width: '100%'
|
|
3217
|
+
} : {}
|
|
3218
|
+
}, /*#__PURE__*/external_react_default().createElement("span", null, "Ticket"), isActive && showMultipleTicketTexts && /*#__PURE__*/external_react_default().createElement("a", {
|
|
3219
|
+
className: ticket_type_index_module.moreInfo,
|
|
3220
|
+
"data-tip": true,
|
|
3221
|
+
"data-for": "ticket-quantity-info",
|
|
3222
|
+
style: {
|
|
3223
|
+
margin: 0
|
|
3224
|
+
}
|
|
3225
|
+
}, /*#__PURE__*/external_react_default().createElement("i", {
|
|
3226
|
+
className: "glyphicon glyphicon-info-sign",
|
|
3227
|
+
"aria-hidden": "true"
|
|
3228
|
+
}), ` `, "Need multiple ticket types?")), /*#__PURE__*/external_react_default().createElement("div", {
|
|
2814
3229
|
className: ticket_type_index_module.summary
|
|
2815
|
-
}, /*#__PURE__*/external_react_default().createElement("span", null, ticket && /*#__PURE__*/external_react_default().createElement((external_react_default()).Fragment, null, `${ticket.name} (${quantity}): `, /*#__PURE__*/external_react_default().createElement((external_react_default()).Fragment, null, (0,utils/* getTicketCost */.fX)(ticket, quantity)), `${(0,utils/* getTicketTaxes */.h5)(ticket, taxTypes)}`, !isActive && reservation?.discount_amount > 0 && /*#__PURE__*/external_react_default().createElement((external_react_default()).Fragment, null, /*#__PURE__*/external_react_default().createElement("br", null), /*#__PURE__*/external_react_default().createElement("span", {
|
|
3230
|
+
}, /*#__PURE__*/external_react_default().createElement("span", null, !isActive && ticket && /*#__PURE__*/external_react_default().createElement((external_react_default()).Fragment, null, `${ticket.name} (${quantity}): `, /*#__PURE__*/external_react_default().createElement((external_react_default()).Fragment, null, (0,utils/* getTicketCost */.fX)(ticket, quantity)), `${(0,utils/* getTicketTaxes */.h5)(ticket, taxTypes)}`, !isActive && reservation?.discount_amount > 0 && /*#__PURE__*/external_react_default().createElement((external_react_default()).Fragment, null, /*#__PURE__*/external_react_default().createElement("br", null), /*#__PURE__*/external_react_default().createElement("span", {
|
|
2816
3231
|
className: ticket_type_index_module.promoCode
|
|
2817
3232
|
}, "Promo code\xA0", /*#__PURE__*/external_react_default().createElement("abbr", {
|
|
2818
3233
|
title: reservation.promo_code
|
|
@@ -2834,13 +3249,13 @@ const TicketTypeComponent = ({
|
|
|
2834
3249
|
})} ${ticket.currency}`), /*#__PURE__*/external_react_default().createElement("br", null));
|
|
2835
3250
|
})), !isActive && reservation && !isPrePaidReservation && /*#__PURE__*/external_react_default().createElement((external_react_default()).Fragment, null, /*#__PURE__*/external_react_default().createElement("br", null), "Total: ", `${(0,helpers/* formatCurrency */.xG)(reservation.amount, {
|
|
2836
3251
|
currency: ticket.currency
|
|
2837
|
-
})} ${ticket.currency}`))
|
|
3252
|
+
})} ${ticket.currency}`))))), /*#__PURE__*/external_react_default().createElement(external_react_spring_namespaceObject.animated.div, {
|
|
2838
3253
|
style: ticket_type_objectSpread({
|
|
2839
3254
|
overflow: 'hidden'
|
|
2840
3255
|
}, toggleAnimation)
|
|
2841
3256
|
}, /*#__PURE__*/external_react_default().createElement("div", {
|
|
2842
3257
|
ref: ref
|
|
2843
|
-
}, /*#__PURE__*/external_react_default().createElement("div", {
|
|
3258
|
+
}, showTicketSelector && /*#__PURE__*/external_react_default().createElement("div", {
|
|
2844
3259
|
className: ticket_type_index_module.form
|
|
2845
3260
|
}, /*#__PURE__*/external_react_default().createElement("div", {
|
|
2846
3261
|
className: ticket_type_index_module.dropdown
|
|
@@ -2879,28 +3294,31 @@ const TicketTypeComponent = ({
|
|
|
2879
3294
|
disabled: maxQuantity === 0 || quantity >= maxQuantity
|
|
2880
3295
|
}, /*#__PURE__*/external_react_default().createElement("i", {
|
|
2881
3296
|
className: "fa fa-plus"
|
|
2882
|
-
}))))))),
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
removePromoCode: handleRemovePromoCode,
|
|
2887
|
-
onPromoCodeChange: handlePromoCodeChange
|
|
2888
|
-
}), promoCodeError && Object.values(promoCodeError).map((er, index) => /*#__PURE__*/external_react_default().createElement("div", {
|
|
2889
|
-
key: `error-${index}`,
|
|
2890
|
-
className: `${ticket_type_index_module.promocodeError} alert alert-danger`
|
|
2891
|
-
}, er))), showMultipleTicketTexts && /*#__PURE__*/external_react_default().createElement("a", {
|
|
2892
|
-
className: ticket_type_index_module.moreInfo,
|
|
2893
|
-
"data-tip": true,
|
|
2894
|
-
"data-for": "ticket-quantity-info"
|
|
2895
|
-
}, /*#__PURE__*/external_react_default().createElement("i", {
|
|
2896
|
-
className: "glyphicon glyphicon-info-sign",
|
|
2897
|
-
"aria-hidden": "true"
|
|
2898
|
-
}), ` `, "Need multiple ticket types?"), /*#__PURE__*/external_react_default().createElement((external_react_tooltip_default()), {
|
|
3297
|
+
}))))))), !showTicketSelector && /*#__PURE__*/external_react_default().createElement(ticket_notice, {
|
|
3298
|
+
message: noTicketsAvailableMessage || external_i18n_react_default().translate("ticket_type.no_tickets_available"),
|
|
3299
|
+
variant: "info"
|
|
3300
|
+
}), /*#__PURE__*/external_react_default().createElement((external_react_tooltip_default()), {
|
|
2899
3301
|
id: "ticket-quantity-info",
|
|
3302
|
+
place: "bottom",
|
|
2900
3303
|
overridePosition: utils/* avoidTooltipOverflow */.kb
|
|
2901
3304
|
}, /*#__PURE__*/external_react_default().createElement("div", {
|
|
2902
3305
|
className: ticket_type_index_module.moreInfoTooltip
|
|
2903
|
-
}, external_i18n_react_default().translate("ticket_type.ticket_quantity_tooltip")))
|
|
3306
|
+
}, external_i18n_react_default().translate("ticket_type.ticket_quantity_tooltip"))), allowPromoCodes && /*#__PURE__*/external_react_default().createElement((external_react_default()).Fragment, null, /*#__PURE__*/external_react_default().createElement(promocode_input, {
|
|
3307
|
+
promoStatus: promoState.status,
|
|
3308
|
+
promoCode: promoCode,
|
|
3309
|
+
suggestedCode: promoState.suggestedCode,
|
|
3310
|
+
isAutoApplied: promoState.isAutoApplied,
|
|
3311
|
+
onInputChange: promoActions.onInputChange,
|
|
3312
|
+
onApply: handleApplyPromoCode,
|
|
3313
|
+
onRemove: promoActions.onRemove,
|
|
3314
|
+
showMultipleTicketTexts: showMultipleTicketTexts
|
|
3315
|
+
})), /*#__PURE__*/external_react_default().createElement(ticket_notice, {
|
|
3316
|
+
message: validationError,
|
|
3317
|
+
variant: "error"
|
|
3318
|
+
}), /*#__PURE__*/external_react_default().createElement(ticket_notice, {
|
|
3319
|
+
message: infoMessage,
|
|
3320
|
+
variant: "info"
|
|
3321
|
+
}))), inPersonDisclaimer && ticket && (0,actions/* isInPersonTicketType */.Qc)(ticket) && /*#__PURE__*/external_react_default().createElement("div", {
|
|
2904
3322
|
className: ticket_type_index_module.inPersonDisclaimer
|
|
2905
3323
|
}, /*#__PURE__*/external_react_default().createElement((raw_html_default()), null, inPersonDisclaimer)))));
|
|
2906
3324
|
};
|
|
@@ -2936,16 +3354,16 @@ function button_bar_defineProperty(obj, key, value) { if (key in obj) { Object.d
|
|
|
2936
3354
|
const ButtonBarComponent = ({
|
|
2937
3355
|
step,
|
|
2938
3356
|
changeStep,
|
|
2939
|
-
|
|
2940
|
-
onValidateError,
|
|
3357
|
+
onNextStep,
|
|
2941
3358
|
formValues,
|
|
2942
3359
|
removeReservedTicket,
|
|
2943
|
-
inPersonDisclaimer
|
|
3360
|
+
inPersonDisclaimer,
|
|
3361
|
+
promoIsReady
|
|
2944
3362
|
}) => {
|
|
2945
3363
|
const {
|
|
2946
3364
|
ticketType,
|
|
2947
3365
|
ticketQuantity,
|
|
2948
|
-
|
|
3366
|
+
ticketSelectionValid
|
|
2949
3367
|
} = formValues || {};
|
|
2950
3368
|
const nextButtonText = inPersonDisclaimer && ticketType && (0,actions/* isInPersonTicketType */.Qc)(ticketType) ? 'Accept' : 'Next';
|
|
2951
3369
|
return /*#__PURE__*/external_react_default().createElement("div", {
|
|
@@ -2963,12 +3381,11 @@ const ButtonBarComponent = ({
|
|
|
2963
3381
|
className: `${button_bar_index_module.button} button`,
|
|
2964
3382
|
onClick: () => removeReservedTicket()
|
|
2965
3383
|
}, "< Back"), step === constants.STEP_SELECT_TICKET_TYPE && /*#__PURE__*/external_react_default().createElement("button", {
|
|
2966
|
-
disabled: !
|
|
3384
|
+
disabled: !ticketSelectionValid || !promoIsReady,
|
|
2967
3385
|
className: `${button_bar_index_module.button} button`,
|
|
2968
|
-
onClick: () =>
|
|
2969
|
-
ticketQuantity
|
|
2970
|
-
|
|
2971
|
-
}), onValidateError)
|
|
3386
|
+
onClick: () => onNextStep(button_bar_objectSpread(button_bar_objectSpread({}, ticketType), {}, {
|
|
3387
|
+
ticketQuantity
|
|
3388
|
+
}))
|
|
2972
3389
|
}, nextButtonText), step === constants.STEP_PERSONAL_INFO && ticketType?.cost === 0 && /*#__PURE__*/external_react_default().createElement("button", {
|
|
2973
3390
|
className: `${button_bar_index_module.button} button`,
|
|
2974
3391
|
type: "submit",
|
|
@@ -3234,10 +3651,10 @@ const TicketOwnedComponent = ({
|
|
|
3234
3651
|
const NoAllowedTickets = ({
|
|
3235
3652
|
noAllowedTicketsMessage
|
|
3236
3653
|
}) => {
|
|
3237
|
-
return /*#__PURE__*/
|
|
3238
|
-
className:
|
|
3239
|
-
}, /*#__PURE__*/
|
|
3240
|
-
className: `${
|
|
3654
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
3655
|
+
className: styles.noAllowedWrapper
|
|
3656
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
3657
|
+
className: `${styles.alert} alert alert-warning`,
|
|
3241
3658
|
role: "alert",
|
|
3242
3659
|
dangerouslySetInnerHTML: {
|
|
3243
3660
|
__html: noAllowedTicketsMessage
|
|
@@ -3245,7 +3662,7 @@ const NoAllowedTickets = ({
|
|
|
3245
3662
|
}));
|
|
3246
3663
|
};
|
|
3247
3664
|
|
|
3248
|
-
/* harmony default export */ const no_allowed_tickets = (NoAllowedTickets);
|
|
3665
|
+
/* harmony default export */ const no_allowed_tickets = ((/* unused pure expression or super */ null && (NoAllowedTickets)));
|
|
3249
3666
|
;// CONCATENATED MODULE: ./src/components/ticket-taxes-error/index.module.scss
|
|
3250
3667
|
// extracted by mini-css-extract-plugin
|
|
3251
3668
|
/* harmony default export */ const ticket_taxes_error_index_module = ({"ticketTaxesErrorWrapper":"ticketTaxesErrorWrapper___ldztd","alert":"alert___AM17V"});
|
|
@@ -3285,7 +3702,7 @@ const TicketTaxesError = ({
|
|
|
3285
3702
|
|
|
3286
3703
|
/* harmony default export */ const ticket_taxes_error = (TicketTaxesError);
|
|
3287
3704
|
;// CONCATENATED MODULE: ./src/components/registration-form/index.js
|
|
3288
|
-
const registration_form_excluded = ["loadSession", "setMarketingSettings", "changeStep", "removeReservedTicket", "reserveTicket", "payTicketWithProvider", "trackEvent", "onPurchaseComplete", "getTicketTypesAndTaxes", "getLoginCode", "passwordlessLogin", "goToLogin", "loginOptions", "allowsNativeAuth", "allowsOtpAuth", "reservation", "checkout", "ticketTypes", "taxTypes", "step", "passwordlessCodeSent", "passwordlessEmail", "passwordlessCode", "passwordlessCodeLifeTime", "getPasswordlessCode", "passwordlessCodeError", "loginWithCode", "goToExtraQuestions", "goToMyOrders", "goToEvent", "profileData", "summitData", "supportEmail", "ticketOwned", "ownedTickets", "widgetLoading", "loading", "inPersonDisclaimer", "userProfile", "handleCompanyError", "providerOptions", "invitation", "loginInitialEmailInputValue", "getMyInvitation", "showMultipleTicketTexts", "noAllowedTicketsMessage", "ticketTaxesErrorMessage", "authErrorCallback", "clearWidgetState", "allowPromoCodes", "showCompanyInput", "companyDDLPlaceholder", "nowUtc", "updateClock", "completedExtraQuestions", "loadProfileData", "closeWidget", "hasVirtualAccessLevel", "hidePostalCode", "onError", "successfulPaymentReturnUrl", "idpLogoLight", "idpLogoDark", "idpLogoAlt", "showCompanyInputDefaultOptions", "companyDDLOptions2Show", "promoCode", "hasDiscount", "getTicketDiscount", "removePromoCode", "applyPromoCode", "validatePromoCode", "closeHandlerRef"];
|
|
3705
|
+
const registration_form_excluded = ["loadSession", "setMarketingSettings", "changeStep", "removeReservedTicket", "reserveTicket", "payTicketWithProvider", "trackEvent", "onPurchaseComplete", "getTicketTypesAndTaxes", "getLoginCode", "passwordlessLogin", "goToLogin", "loginOptions", "allowsNativeAuth", "allowsOtpAuth", "reservation", "checkout", "ticketTypes", "taxTypes", "step", "passwordlessCodeSent", "passwordlessEmail", "passwordlessCode", "passwordlessCodeLifeTime", "getPasswordlessCode", "passwordlessCodeError", "loginWithCode", "goToExtraQuestions", "goToMyOrders", "goToEvent", "profileData", "summitData", "supportEmail", "ticketOwned", "ownedTickets", "widgetLoading", "loading", "inPersonDisclaimer", "userProfile", "handleCompanyError", "providerOptions", "invitation", "loginInitialEmailInputValue", "getMyInvitation", "showMultipleTicketTexts", "noAllowedTicketsMessage", "noTicketsAvailableMessage", "ticketTaxesErrorMessage", "authErrorCallback", "clearWidgetState", "allowPromoCodes", "showCompanyInput", "companyDDLPlaceholder", "nowUtc", "updateClock", "completedExtraQuestions", "loadProfileData", "closeWidget", "hasVirtualAccessLevel", "hidePostalCode", "onError", "successfulPaymentReturnUrl", "idpLogoLight", "idpLogoDark", "idpLogoAlt", "showCompanyInputDefaultOptions", "companyDDLOptions2Show", "promoCode", "promoCodeVerified", "promoCodeValidating", "promoCodeAllowsReassign", "discoveredPromoCodes", "hasDiscount", "getTicketDiscount", "removePromoCode", "applyPromoCode", "validatePromoCode", "discoverPromoCodes", "startWidgetLoading", "stopWidgetLoading", "closeHandlerRef"];
|
|
3289
3706
|
|
|
3290
3707
|
function registration_form_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
3291
3708
|
|
|
@@ -3334,6 +3751,7 @@ function registration_form_objectWithoutPropertiesLoose(source, excluded) { if (
|
|
|
3334
3751
|
|
|
3335
3752
|
|
|
3336
3753
|
|
|
3754
|
+
|
|
3337
3755
|
|
|
3338
3756
|
|
|
3339
3757
|
let language = (0,utils/* getCurrentUserLanguage */.AS)();
|
|
@@ -3397,6 +3815,7 @@ const RegistrationFormContent = _ref => {
|
|
|
3397
3815
|
getMyInvitation,
|
|
3398
3816
|
showMultipleTicketTexts,
|
|
3399
3817
|
noAllowedTicketsMessage,
|
|
3818
|
+
noTicketsAvailableMessage,
|
|
3400
3819
|
ticketTaxesErrorMessage,
|
|
3401
3820
|
authErrorCallback,
|
|
3402
3821
|
clearWidgetState,
|
|
@@ -3418,11 +3837,18 @@ const RegistrationFormContent = _ref => {
|
|
|
3418
3837
|
showCompanyInputDefaultOptions,
|
|
3419
3838
|
companyDDLOptions2Show,
|
|
3420
3839
|
promoCode,
|
|
3840
|
+
promoCodeVerified,
|
|
3841
|
+
promoCodeValidating,
|
|
3842
|
+
promoCodeAllowsReassign,
|
|
3843
|
+
discoveredPromoCodes,
|
|
3421
3844
|
hasDiscount,
|
|
3422
3845
|
getTicketDiscount,
|
|
3423
3846
|
removePromoCode,
|
|
3424
3847
|
applyPromoCode,
|
|
3425
3848
|
validatePromoCode,
|
|
3849
|
+
discoverPromoCodes,
|
|
3850
|
+
startWidgetLoading,
|
|
3851
|
+
stopWidgetLoading,
|
|
3426
3852
|
closeHandlerRef
|
|
3427
3853
|
} = _ref,
|
|
3428
3854
|
rest = registration_form_objectWithoutProperties(_ref, registration_form_excluded);
|
|
@@ -3437,31 +3863,32 @@ const RegistrationFormContent = _ref => {
|
|
|
3437
3863
|
},
|
|
3438
3864
|
errors: []
|
|
3439
3865
|
});
|
|
3866
|
+
const [hasTicketData, setHasTicketData] = (0,external_react_.useState)(false);
|
|
3440
3867
|
const [ticketDataError, setTicketDataError] = (0,external_react_.useState)(false);
|
|
3441
|
-
const [
|
|
3868
|
+
const [unappliedCodeWarning, setUnappliedCodeWarning] = (0,external_react_.useState)(null);
|
|
3869
|
+
const isAuthenticated = !!profileData;
|
|
3870
|
+
const summitId = summitData?.id;
|
|
3871
|
+
const userId = profileData?.id;
|
|
3442
3872
|
const {
|
|
3443
3873
|
values: formValues,
|
|
3444
3874
|
errors: formErrors
|
|
3445
3875
|
} = registrationForm;
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
})
|
|
3450
|
-
|
|
3451
|
-
const setFormErrors = errors => setRegistrationForm(registration_form_objectSpread(registration_form_objectSpread({}, registrationForm), {}, {
|
|
3876
|
+
const mergeFormValues = (0,external_react_.useCallback)(partial => setRegistrationForm(prev => registration_form_objectSpread(registration_form_objectSpread({}, prev), {}, {
|
|
3877
|
+
values: registration_form_objectSpread(registration_form_objectSpread({}, prev.values), partial)
|
|
3878
|
+
})), []);
|
|
3879
|
+
const setFormErrors = (0,external_react_.useCallback)(errors => setRegistrationForm(prev => registration_form_objectSpread(registration_form_objectSpread({}, prev), {}, {
|
|
3452
3880
|
errors
|
|
3453
|
-
}));
|
|
3454
|
-
|
|
3881
|
+
})), []);
|
|
3455
3882
|
const {
|
|
3456
3883
|
publicKey,
|
|
3457
3884
|
provider
|
|
3458
3885
|
} = (0,utils/* getCurrentProvider */.U5)(summitData);
|
|
3459
|
-
const allowedTicketTypes =
|
|
3460
|
-
const noAvailableTickets = (0,external_react_.useMemo)(() =>
|
|
3461
|
-
const alreadyOwnedTickets = (0,external_react_.useMemo)(() =>
|
|
3886
|
+
const allowedTicketTypes = (0,external_react_.useMemo)(() => hasTicketData ? ticketTypes.filter(tt => tt.sub_type === constants.TICKET_TYPE_SUBTYPE_PREPAID || tt.sales_start_date === null && tt.sales_end_date === null || nowUtc >= tt.sales_start_date && nowUtc <= tt.sales_end_date) : [], [hasTicketData, ticketTypes, nowUtc]);
|
|
3887
|
+
const noAvailableTickets = (0,external_react_.useMemo)(() => isAuthenticated && hasTicketData && !ticketDataError && allowedTicketTypes.length === 0 && step !== constants.STEP_COMPLETE, [isAuthenticated, hasTicketData, ticketDataError, allowedTicketTypes, step]);
|
|
3888
|
+
const alreadyOwnedTickets = (0,external_react_.useMemo)(() => isAuthenticated && hasTicketData && !ticketDataError && allowedTicketTypes.length > 0 && ownedTickets.length > 0, [isAuthenticated, hasTicketData, ticketDataError, allowedTicketTypes, ownedTickets]);
|
|
3462
3889
|
(0,external_react_.useEffect)(() => {
|
|
3463
3890
|
if (profileData) loadProfileData(profileData);
|
|
3464
|
-
}, [
|
|
3891
|
+
}, [userId]);
|
|
3465
3892
|
(0,external_react_.useEffect)(() => {
|
|
3466
3893
|
loadSession(registration_form_objectSpread(registration_form_objectSpread({}, rest), {}, {
|
|
3467
3894
|
summitData,
|
|
@@ -3473,12 +3900,12 @@ const RegistrationFormContent = _ref => {
|
|
|
3473
3900
|
}
|
|
3474
3901
|
}, []);
|
|
3475
3902
|
(0,external_react_.useEffect)(() => {
|
|
3476
|
-
if (
|
|
3477
|
-
const ensureInvitation = () => summitData.invite_only_registration ? getMyInvitation(
|
|
3903
|
+
if (summitId && isAuthenticated) {
|
|
3904
|
+
const ensureInvitation = () => summitData.invite_only_registration ? getMyInvitation(summitId) : Promise.resolve();
|
|
3478
3905
|
|
|
3479
|
-
ensureInvitation().catch(e => console.log(e)).finally(() => handleGetTicketTypesAndTaxes(
|
|
3906
|
+
ensureInvitation().catch(e => console.log(e)).finally(() => handleGetTicketTypesAndTaxes(summitId));
|
|
3480
3907
|
}
|
|
3481
|
-
}, [
|
|
3908
|
+
}, [summitId, isAuthenticated]);
|
|
3482
3909
|
(0,external_react_.useEffect)(() => {
|
|
3483
3910
|
if (step > constants.STEP_SELECT_TICKET_TYPE && !registrationForm.values?.ticketType && !reservation) {
|
|
3484
3911
|
changeStep(constants.STEP_SELECT_TICKET_TYPE);
|
|
@@ -3486,7 +3913,43 @@ const RegistrationFormContent = _ref => {
|
|
|
3486
3913
|
}, [registrationForm.values, step]);
|
|
3487
3914
|
(0,external_react_.useEffect)(() => {
|
|
3488
3915
|
setFormErrors([]);
|
|
3489
|
-
}, [step]);
|
|
3916
|
+
}, [step]); // Discovery: fetch qualifying promo codes after auth
|
|
3917
|
+
|
|
3918
|
+
(0,external_react_.useEffect)(() => {
|
|
3919
|
+
if (isAuthenticated && summitId) {
|
|
3920
|
+
discoverPromoCodes(summitId);
|
|
3921
|
+
}
|
|
3922
|
+
}, [isAuthenticated, summitId]);
|
|
3923
|
+
const handleFormPromoCodeChange = (0,external_react_.useCallback)(code => mergeFormValues({
|
|
3924
|
+
promoCode: code
|
|
3925
|
+
}), [mergeFormValues]);
|
|
3926
|
+
const promo = hooks_usePromoCode({
|
|
3927
|
+
discoveredPromoCodes,
|
|
3928
|
+
promoCode,
|
|
3929
|
+
promoCodeVerified,
|
|
3930
|
+
promoCodeValidating,
|
|
3931
|
+
applyPromoCode,
|
|
3932
|
+
removePromoCode,
|
|
3933
|
+
validatePromoCode,
|
|
3934
|
+
setFormPromoCode: handleFormPromoCodeChange,
|
|
3935
|
+
ticketDataLoaded: hasTicketData && !ticketDataError,
|
|
3936
|
+
hasTickets: allowedTicketTypes.length > 0
|
|
3937
|
+
}); // Local destructure for readability at call sites.
|
|
3938
|
+
|
|
3939
|
+
const {
|
|
3940
|
+
state: promoState,
|
|
3941
|
+
actions: promoActions
|
|
3942
|
+
} = promo; // Error rendered in the promo notice slot — form-level warning layered on top
|
|
3943
|
+
// of the hook's own validation error (API rejection or status-derived).
|
|
3944
|
+
|
|
3945
|
+
const ticketStepError = unappliedCodeWarning ?? promoState.validationError; // Clear the unapplied-code warning once the condition that would have raised it
|
|
3946
|
+
// no longer holds (input cleared, code applied, or a suggestion is showing).
|
|
3947
|
+
|
|
3948
|
+
(0,external_react_.useEffect)(() => {
|
|
3949
|
+
if (!formValues?.promoCode || promoCode || promoState.status === constants.PROMO_STATUS.SUGGESTED) {
|
|
3950
|
+
setUnappliedCodeWarning(null);
|
|
3951
|
+
}
|
|
3952
|
+
}, [formValues?.promoCode, promoCode, promoState.status]);
|
|
3490
3953
|
const [ref, {
|
|
3491
3954
|
height
|
|
3492
3955
|
}] = (0,external_react_use_namespaceObject.useMeasure)();
|
|
@@ -3528,8 +3991,9 @@ const RegistrationFormContent = _ref => {
|
|
|
3528
3991
|
|
|
3529
3992
|
const handleGetTicketTypesAndTaxes = summitId => {
|
|
3530
3993
|
setTicketDataError(false);
|
|
3531
|
-
|
|
3532
|
-
|
|
3994
|
+
getTicketTypesAndTaxes(summitId).then(() => {
|
|
3995
|
+
setHasTicketData(true);
|
|
3996
|
+
}).catch(error => {
|
|
3533
3997
|
let {
|
|
3534
3998
|
message
|
|
3535
3999
|
} = error;
|
|
@@ -3540,17 +4004,31 @@ const RegistrationFormContent = _ref => {
|
|
|
3540
4004
|
}
|
|
3541
4005
|
|
|
3542
4006
|
setTicketDataError(true);
|
|
3543
|
-
}).finally(() => {
|
|
3544
|
-
setTicketDataLoaded(true);
|
|
3545
4007
|
});
|
|
3546
4008
|
};
|
|
3547
4009
|
|
|
3548
|
-
const
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
4010
|
+
const handleAdvanceFromTicketStep = async data => {
|
|
4011
|
+
if (formValues?.promoCode && !promoCode && promoState.status !== constants.PROMO_STATUS.SUGGESTED) {
|
|
4012
|
+
setUnappliedCodeWarning(external_i18n_react_default().translate('promo_code.unapplied_code_warning'));
|
|
4013
|
+
return;
|
|
4014
|
+
} // Re-validate manual codes with final quantity before advancing
|
|
4015
|
+
|
|
4016
|
+
|
|
4017
|
+
if (promoCode && !promoState.isDiscoveredCode) {
|
|
4018
|
+
startWidgetLoading();
|
|
4019
|
+
let valid = false;
|
|
4020
|
+
|
|
4021
|
+
try {
|
|
4022
|
+
valid = await promoActions.onRevalidate(formValues.ticketType, data.ticketQuantity);
|
|
4023
|
+
} finally {
|
|
4024
|
+
stopWidgetLoading();
|
|
4025
|
+
}
|
|
4026
|
+
|
|
4027
|
+
if (!valid) return;
|
|
4028
|
+
}
|
|
4029
|
+
|
|
4030
|
+
trackAddToCart(data);
|
|
4031
|
+
changeStep(constants.STEP_PERSONAL_INFO);
|
|
3554
4032
|
};
|
|
3555
4033
|
|
|
3556
4034
|
const trackViewItem = data => {
|
|
@@ -3573,12 +4051,11 @@ const RegistrationFormContent = _ref => {
|
|
|
3573
4051
|
trackEvent(constants.PURCHASE_COMPLETE, {
|
|
3574
4052
|
order
|
|
3575
4053
|
});
|
|
3576
|
-
}; //
|
|
3577
|
-
//
|
|
3578
|
-
// race conditions with redux-persist rehydration.
|
|
4054
|
+
}; // Authenticated first-load: wait until ticket data is in before rendering
|
|
4055
|
+
// to avoid a flash of empty/wrong state.
|
|
3579
4056
|
|
|
3580
4057
|
|
|
3581
|
-
if (
|
|
4058
|
+
if (isAuthenticated && !hasTicketData && !ticketDataError) return null;
|
|
3582
4059
|
return /*#__PURE__*/external_react_default().createElement("div", {
|
|
3583
4060
|
className: "summit-registration-lite"
|
|
3584
4061
|
}, /*#__PURE__*/external_react_default().createElement((ajaxloader_default()), {
|
|
@@ -3592,8 +4069,6 @@ const RegistrationFormContent = _ref => {
|
|
|
3592
4069
|
}), profileData && ticketDataError && /*#__PURE__*/external_react_default().createElement(ticket_taxes_error, {
|
|
3593
4070
|
ticketTaxesErrorMessage: ticketTaxesErrorMessage,
|
|
3594
4071
|
retryTicketTaxes: () => handleGetTicketTypesAndTaxes(summitData?.id)
|
|
3595
|
-
}), noAvailableTickets && /*#__PURE__*/external_react_default().createElement(no_allowed_tickets, {
|
|
3596
|
-
noAllowedTicketsMessage: noAllowedTicketsMessage
|
|
3597
4072
|
}), !ticketDataError && /*#__PURE__*/external_react_default().createElement((external_react_default()).Fragment, null, !profileData && !passwordlessCodeSent && /*#__PURE__*/external_react_default().createElement(login["default"], {
|
|
3598
4073
|
summitData: summitData,
|
|
3599
4074
|
loginOptions: loginOptions,
|
|
@@ -3626,19 +4101,14 @@ const RegistrationFormContent = _ref => {
|
|
|
3626
4101
|
reservation: reservation,
|
|
3627
4102
|
isActive: step === constants.STEP_SELECT_TICKET_TYPE,
|
|
3628
4103
|
allowPromoCodes: allowPromoCodes,
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
setFormErrors({});
|
|
3632
|
-
setFormValues(registration_form_objectSpread(registration_form_objectSpread({}, formValues), {}, {
|
|
3633
|
-
promoCode: ""
|
|
3634
|
-
}));
|
|
3635
|
-
removePromoCode();
|
|
3636
|
-
},
|
|
4104
|
+
promo: promo,
|
|
4105
|
+
validationError: ticketStepError,
|
|
3637
4106
|
promoCode: promoCode,
|
|
3638
|
-
|
|
3639
|
-
changeForm:
|
|
4107
|
+
promoCodeAllowsReassign: promoCodeAllowsReassign,
|
|
4108
|
+
changeForm: mergeFormValues,
|
|
3640
4109
|
trackViewItem: trackViewItem,
|
|
3641
|
-
showMultipleTicketTexts: showMultipleTicketTexts
|
|
4110
|
+
showMultipleTicketTexts: showMultipleTicketTexts,
|
|
4111
|
+
noTicketsAvailableMessage: noTicketsAvailableMessage
|
|
3642
4112
|
}), /*#__PURE__*/external_react_default().createElement(personal_information, {
|
|
3643
4113
|
isActive: step === constants.STEP_PERSONAL_INFO,
|
|
3644
4114
|
reservation: reservation,
|
|
@@ -3646,9 +4116,9 @@ const RegistrationFormContent = _ref => {
|
|
|
3646
4116
|
invitation: invitation,
|
|
3647
4117
|
summitId: summitData.id,
|
|
3648
4118
|
changeForm: personalInformation => {
|
|
3649
|
-
|
|
4119
|
+
mergeFormValues({
|
|
3650
4120
|
personalInformation
|
|
3651
|
-
})
|
|
4121
|
+
});
|
|
3652
4122
|
reserveTicket({
|
|
3653
4123
|
provider,
|
|
3654
4124
|
personalInformation: personalInformation,
|
|
@@ -3676,7 +4146,8 @@ const RegistrationFormContent = _ref => {
|
|
|
3676
4146
|
showCompanyInput: showCompanyInput,
|
|
3677
4147
|
companyDDLPlaceholder: companyDDLPlaceholder,
|
|
3678
4148
|
showCompanyInputDefaultOptions: showCompanyInputDefaultOptions,
|
|
3679
|
-
companyDDLOptions2Show: companyDDLOptions2Show
|
|
4149
|
+
companyDDLOptions2Show: companyDDLOptions2Show,
|
|
4150
|
+
promoCodeAllowsReassign: promoCodeAllowsReassign
|
|
3680
4151
|
}), /*#__PURE__*/external_react_default().createElement(external_react_spring_namespaceObject.animated.div, {
|
|
3681
4152
|
style: registration_form_objectSpread({}, toggleAnimation)
|
|
3682
4153
|
}, /*#__PURE__*/external_react_default().createElement("div", {
|
|
@@ -3697,11 +4168,9 @@ const RegistrationFormContent = _ref => {
|
|
|
3697
4168
|
step: step,
|
|
3698
4169
|
inPersonDisclaimer: inPersonDisclaimer,
|
|
3699
4170
|
formValues: formValues,
|
|
4171
|
+
promoIsReady: promoState.isReady,
|
|
3700
4172
|
removeReservedTicket: removeReservedTicket,
|
|
3701
|
-
|
|
3702
|
-
onValidateError: {
|
|
3703
|
-
onError: (err, res) => setFormErrors(res.body.errors)
|
|
3704
|
-
},
|
|
4173
|
+
onNextStep: handleAdvanceFromTicketStep,
|
|
3705
4174
|
changeStep: changeStep
|
|
3706
4175
|
})), profileData && step === constants.STEP_COMPLETE && /*#__PURE__*/external_react_default().createElement(purchase_complete, {
|
|
3707
4176
|
checkout: checkout,
|
|
@@ -3744,7 +4213,11 @@ const mapStateToProps = ({
|
|
|
3744
4213
|
passwordlessCodeSent: registrationLiteState.passwordless.code_sent,
|
|
3745
4214
|
passwordlessCodeError: registrationLiteState.passwordless.error,
|
|
3746
4215
|
nowUtc: registrationLiteState.nowUtc,
|
|
3747
|
-
promoCode: registrationLiteState.promoCode
|
|
4216
|
+
promoCode: registrationLiteState.promoCode,
|
|
4217
|
+
promoCodeVerified: registrationLiteState.promoCodeVerified,
|
|
4218
|
+
promoCodeValidating: registrationLiteState.promoCodeValidating,
|
|
4219
|
+
promoCodeAllowsReassign: registrationLiteState.promoCodeAllowsReassign,
|
|
4220
|
+
discoveredPromoCodes: registrationLiteState.discoveredPromoCodes
|
|
3748
4221
|
});
|
|
3749
4222
|
|
|
3750
4223
|
const RegistrationForm = (0,external_react_redux_.connect)(mapStateToProps, {
|
|
@@ -3763,7 +4236,10 @@ const RegistrationForm = (0,external_react_redux_.connect)(mapStateToProps, {
|
|
|
3763
4236
|
loadProfileData: actions/* loadProfileData */.Bi,
|
|
3764
4237
|
applyPromoCode: actions/* applyPromoCode */.gs,
|
|
3765
4238
|
removePromoCode: actions/* removePromoCode */.$r,
|
|
3766
|
-
validatePromoCode: actions/* validatePromoCode */.jn
|
|
4239
|
+
validatePromoCode: actions/* validatePromoCode */.jn,
|
|
4240
|
+
discoverPromoCodes: actions/* discoverPromoCodes */.kM,
|
|
4241
|
+
startWidgetLoading: actions/* startWidgetLoading */.Bq,
|
|
4242
|
+
stopWidgetLoading: actions/* stopWidgetLoading */.Rs
|
|
3767
4243
|
})(RegistrationFormContent);
|
|
3768
4244
|
RegistrationForm.defaultProps = {
|
|
3769
4245
|
loginInitialEmailInputValue: '',
|
|
@@ -3836,8 +4312,8 @@ var external_react_default = /*#__PURE__*/__webpack_require__.n(external_react_)
|
|
|
3836
4312
|
// EXTERNAL MODULE: external "prop-types"
|
|
3837
4313
|
var external_prop_types_ = __webpack_require__(580);
|
|
3838
4314
|
var external_prop_types_default = /*#__PURE__*/__webpack_require__.n(external_prop_types_);
|
|
3839
|
-
// EXTERNAL MODULE: ./src/components/registration-form/index.js +
|
|
3840
|
-
var registration_form = __webpack_require__(
|
|
4315
|
+
// EXTERNAL MODULE: ./src/components/registration-form/index.js + 46 modules
|
|
4316
|
+
var registration_form = __webpack_require__(95);
|
|
3841
4317
|
// EXTERNAL MODULE: ./src/utils/withReduxProvider.js + 9 modules
|
|
3842
4318
|
var withReduxProvider = __webpack_require__(974);
|
|
3843
4319
|
;// CONCATENATED MODULE: ./src/styles/general.module.scss
|
|
@@ -3952,6 +4428,7 @@ RegistrationModal.propTypes = {
|
|
|
3952
4428
|
initialOrderComplete1stParagraph: (external_prop_types_default()).string,
|
|
3953
4429
|
initialOrderComplete2ndParagraph: (external_prop_types_default()).string,
|
|
3954
4430
|
initialOrderCompleteButton: (external_prop_types_default()).string,
|
|
4431
|
+
noTicketsAvailableMessage: (external_prop_types_default()).string,
|
|
3955
4432
|
orderCompleteTitle: (external_prop_types_default()).string,
|
|
3956
4433
|
orderComplete1stParagraph: (external_prop_types_default()).string,
|
|
3957
4434
|
orderComplete2ndParagraph: (external_prop_types_default()).string,
|
|
@@ -4044,10 +4521,16 @@ var formatErrorMessage = __webpack_require__(104);
|
|
|
4044
4521
|
var utils = __webpack_require__(452);
|
|
4045
4522
|
;// CONCATENATED MODULE: ./src/helpers/getTicketMaxQuantity.js
|
|
4046
4523
|
|
|
4047
|
-
const getTicketMaxQuantity = ticket => {
|
|
4524
|
+
const getTicketMaxQuantity = (ticket, remainingQuantityPerAccount) => {
|
|
4048
4525
|
if (!ticket) return 0;
|
|
4049
4526
|
if ((0,utils/* isPrePaidTicketType */.B6)(ticket)) return 1;
|
|
4050
|
-
|
|
4527
|
+
let max = Math.min((ticket.quantity_2_sell ?? Number.MAX_SAFE_INTEGER) - ticket.quantity_sold, ticket.max_quantity_per_order ?? Number.MAX_SAFE_INTEGER);
|
|
4528
|
+
|
|
4529
|
+
if (remainingQuantityPerAccount != null) {
|
|
4530
|
+
max = Math.min(max, remainingQuantityPerAccount);
|
|
4531
|
+
}
|
|
4532
|
+
|
|
4533
|
+
return max;
|
|
4051
4534
|
};
|
|
4052
4535
|
;// CONCATENATED MODULE: ./src/helpers/index.js
|
|
4053
4536
|
|
|
@@ -4075,6 +4558,7 @@ const getTicketMaxQuantity = ticket => {
|
|
|
4075
4558
|
/* harmony export */ "ORDER_STATUS_PAID": () => (/* binding */ ORDER_STATUS_PAID),
|
|
4076
4559
|
/* harmony export */ "PAYMENT_PROVIDER_LAWPAY": () => (/* binding */ PAYMENT_PROVIDER_LAWPAY),
|
|
4077
4560
|
/* harmony export */ "PAYMENT_PROVIDER_STRIPE": () => (/* binding */ PAYMENT_PROVIDER_STRIPE),
|
|
4561
|
+
/* harmony export */ "PROMO_STATUS": () => (/* binding */ PROMO_STATUS),
|
|
4078
4562
|
/* harmony export */ "PURCHASE_COMPLETE": () => (/* binding */ PURCHASE_COMPLETE),
|
|
4079
4563
|
/* harmony export */ "RESEND_TIME": () => (/* binding */ RESEND_TIME),
|
|
4080
4564
|
/* harmony export */ "STEP_COMPLETE": () => (/* binding */ STEP_COMPLETE),
|
|
@@ -4128,7 +4612,16 @@ const PURCHASE_COMPLETE = 'purchase_complete'; // ERRORS
|
|
|
4128
4612
|
|
|
4129
4613
|
const ERROR_TYPE_ERROR = 'error_type_error';
|
|
4130
4614
|
const ERROR_TYPE_VALIDATION = 'error_type_validation';
|
|
4131
|
-
const ERROR_TYPE_PAYMENT = 'error_type_payment'; //
|
|
4615
|
+
const ERROR_TYPE_PAYMENT = 'error_type_payment'; // PROMO CODE STATUS
|
|
4616
|
+
|
|
4617
|
+
const PROMO_STATUS = {
|
|
4618
|
+
IDLE: 'idle',
|
|
4619
|
+
SUGGESTED: 'suggested',
|
|
4620
|
+
APPLYING: 'applying',
|
|
4621
|
+
VALIDATING: 'validating',
|
|
4622
|
+
VALID: 'valid',
|
|
4623
|
+
INVALID: 'invalid'
|
|
4624
|
+
}; // PROVIDERS
|
|
4132
4625
|
|
|
4133
4626
|
const PAYMENT_PROVIDER_STRIPE = 'Stripe';
|
|
4134
4627
|
const PAYMENT_PROVIDER_LAWPAY = 'LawPay';
|
|
@@ -4392,7 +4885,11 @@ const DEFAULT_STATE = {
|
|
|
4392
4885
|
userProfile: null
|
|
4393
4886
|
},
|
|
4394
4887
|
nowUtc: localNowUtc,
|
|
4395
|
-
promoCode: ''
|
|
4888
|
+
promoCode: '',
|
|
4889
|
+
promoCodeVerified: null,
|
|
4890
|
+
promoCodeValidating: false,
|
|
4891
|
+
promoCodeAllowsReassign: true,
|
|
4892
|
+
discoveredPromoCodes: []
|
|
4396
4893
|
};
|
|
4397
4894
|
|
|
4398
4895
|
const RegistrationLiteReducer = (state = DEFAULT_STATE, action) => {
|
|
@@ -4400,7 +4897,6 @@ const RegistrationLiteReducer = (state = DEFAULT_STATE, action) => {
|
|
|
4400
4897
|
type,
|
|
4401
4898
|
payload
|
|
4402
4899
|
} = action;
|
|
4403
|
-
console.log(action);
|
|
4404
4900
|
|
|
4405
4901
|
switch (type) {
|
|
4406
4902
|
case actions/* CLEAR_WIDGET_STATE */.t$:
|
|
@@ -4443,6 +4939,10 @@ const RegistrationLiteReducer = (state = DEFAULT_STATE, action) => {
|
|
|
4443
4939
|
requestedTicketTypes: false,
|
|
4444
4940
|
taxTypes: [],
|
|
4445
4941
|
invitation: null,
|
|
4942
|
+
promoCode: '',
|
|
4943
|
+
promoCodeVerified: null,
|
|
4944
|
+
promoCodeAllowsReassign: true,
|
|
4945
|
+
discoveredPromoCodes: [],
|
|
4446
4946
|
passwordless: _objectSpread({}, DEFAULT_STATE.passwordless),
|
|
4447
4947
|
settings: _objectSpread(_objectSpread({}, DEFAULT_STATE.settings), {}, {
|
|
4448
4948
|
summitId: summitData.id,
|
|
@@ -4547,7 +5047,11 @@ const RegistrationLiteReducer = (state = DEFAULT_STATE, action) => {
|
|
|
4547
5047
|
{
|
|
4548
5048
|
return _objectSpread(_objectSpread({}, state), {}, {
|
|
4549
5049
|
reservation: null,
|
|
4550
|
-
promoCode: ''
|
|
5050
|
+
promoCode: '',
|
|
5051
|
+
promoCodeVerified: null,
|
|
5052
|
+
promoCodeValidating: false,
|
|
5053
|
+
promoCodeAllowsReassign: true,
|
|
5054
|
+
discoveredPromoCodes: []
|
|
4551
5055
|
});
|
|
4552
5056
|
}
|
|
4553
5057
|
|
|
@@ -4558,7 +5062,11 @@ const RegistrationLiteReducer = (state = DEFAULT_STATE, action) => {
|
|
|
4558
5062
|
reservation: null,
|
|
4559
5063
|
userProfile: null,
|
|
4560
5064
|
invitation: null,
|
|
4561
|
-
promoCode: ''
|
|
5065
|
+
promoCode: '',
|
|
5066
|
+
promoCodeVerified: null,
|
|
5067
|
+
promoCodeValidating: false,
|
|
5068
|
+
promoCodeAllowsReassign: true,
|
|
5069
|
+
discoveredPromoCodes: []
|
|
4562
5070
|
});
|
|
4563
5071
|
}
|
|
4564
5072
|
|
|
@@ -4589,7 +5097,10 @@ const RegistrationLiteReducer = (state = DEFAULT_STATE, action) => {
|
|
|
4589
5097
|
case actions/* CLEAR_CURRENT_PROMO_CODE */.ZD:
|
|
4590
5098
|
{
|
|
4591
5099
|
return _objectSpread(_objectSpread({}, state), {}, {
|
|
4592
|
-
promoCode: ''
|
|
5100
|
+
promoCode: '',
|
|
5101
|
+
promoCodeVerified: null,
|
|
5102
|
+
promoCodeValidating: false,
|
|
5103
|
+
promoCodeAllowsReassign: true
|
|
4593
5104
|
});
|
|
4594
5105
|
}
|
|
4595
5106
|
|
|
@@ -4599,7 +5110,52 @@ const RegistrationLiteReducer = (state = DEFAULT_STATE, action) => {
|
|
|
4599
5110
|
currentPromoCode
|
|
4600
5111
|
} = payload;
|
|
4601
5112
|
return _objectSpread(_objectSpread({}, state), {}, {
|
|
4602
|
-
promoCode: currentPromoCode
|
|
5113
|
+
promoCode: currentPromoCode,
|
|
5114
|
+
promoCodeVerified: null,
|
|
5115
|
+
promoCodeValidating: false,
|
|
5116
|
+
promoCodeAllowsReassign: true
|
|
5117
|
+
});
|
|
5118
|
+
}
|
|
5119
|
+
|
|
5120
|
+
case actions/* VALIDATE_PROMO_CODE */.j6:
|
|
5121
|
+
{
|
|
5122
|
+
return _objectSpread(_objectSpread({}, state), {}, {
|
|
5123
|
+
promoCodeValidating: true
|
|
5124
|
+
});
|
|
5125
|
+
}
|
|
5126
|
+
|
|
5127
|
+
case actions/* VALIDATE_PROMO_CODE_SUCCESS */.w6:
|
|
5128
|
+
{
|
|
5129
|
+
const {
|
|
5130
|
+
allows_to_reassign
|
|
5131
|
+
} = payload.response;
|
|
5132
|
+
return _objectSpread(_objectSpread({}, state), {}, {
|
|
5133
|
+
promoCodeVerified: true,
|
|
5134
|
+
promoCodeValidating: false,
|
|
5135
|
+
promoCodeAllowsReassign: allows_to_reassign ?? true
|
|
5136
|
+
});
|
|
5137
|
+
}
|
|
5138
|
+
|
|
5139
|
+
case actions/* VALIDATE_PROMO_CODE_ERROR */.o5:
|
|
5140
|
+
{
|
|
5141
|
+
return _objectSpread(_objectSpread({}, state), {}, {
|
|
5142
|
+
promoCodeVerified: false,
|
|
5143
|
+
promoCodeValidating: false,
|
|
5144
|
+
promoCodeAllowsReassign: true
|
|
5145
|
+
});
|
|
5146
|
+
}
|
|
5147
|
+
|
|
5148
|
+
case actions/* VALIDATE_PROMO_CODE_RATE_LIMITED */.Tk:
|
|
5149
|
+
{
|
|
5150
|
+
return _objectSpread(_objectSpread({}, state), {}, {
|
|
5151
|
+
promoCodeValidating: false
|
|
5152
|
+
});
|
|
5153
|
+
}
|
|
5154
|
+
|
|
5155
|
+
case actions/* DISCOVER_PROMO_CODES_SUCCESS */.dQ:
|
|
5156
|
+
{
|
|
5157
|
+
return _objectSpread(_objectSpread({}, state), {}, {
|
|
5158
|
+
discoveredPromoCodes: payload.response?.data || []
|
|
4603
5159
|
});
|
|
4604
5160
|
}
|
|
4605
5161
|
|
|
@@ -4717,13 +5273,6 @@ module.exports = "data:image/svg+xml,%3c!-- Generator: Adobe Illustrator 25.4.1,
|
|
|
4717
5273
|
|
|
4718
5274
|
/***/ }),
|
|
4719
5275
|
|
|
4720
|
-
/***/ 60:
|
|
4721
|
-
/***/ ((module) => {
|
|
4722
|
-
|
|
4723
|
-
module.exports = "data:image/svg+xml,%3csvg width='20' height='20' viewBox='0 0 20 20' fill='none' xmlns='http://www.w3.org/2000/svg'%3e %3cpath d='M8.11475 2.60519C9.64837 2.25868 11.2529 2.41721 12.6891 3.05713C13.0978 3.23923 13.5767 3.05555 13.7588 2.64686C13.9409 2.23817 13.7572 1.75925 13.3485 1.57714C11.5932 0.795024 9.6321 0.601267 7.75767 1.02477C5.88325 1.44827 4.19593 2.46634 2.94738 3.92714C1.69883 5.38795 0.955938 7.21321 0.829498 9.13072C0.703058 11.0482 1.19985 12.9552 2.24577 14.5673C3.2917 16.1794 4.83072 17.4103 6.6333 18.0762C8.43589 18.7422 10.4055 18.8076 12.2483 18.2627C14.0911 17.7179 15.7084 16.5919 16.859 15.0528C18.0096 13.5137 18.6319 11.6438 18.633 9.72216V8.97638C18.633 8.52896 18.2703 8.16625 17.8228 8.16625C17.3754 8.16625 17.0127 8.52896 17.0127 8.97638V9.72123C17.0118 11.2935 16.5027 12.8234 15.5613 14.0827C14.6199 15.342 13.2966 16.2632 11.7889 16.709C10.2811 17.1548 8.66965 17.1012 7.19481 16.5564C5.71996 16.0115 4.46077 15.0045 3.60501 13.6855C2.74925 12.3665 2.34279 10.8062 2.44624 9.23733C2.54969 7.66846 3.15751 6.17506 4.17905 4.97986C5.2006 3.78465 6.58112 2.95169 8.11475 2.60519Z' fill='%2392CD76'/%3e %3cpath d='M18.396 3.81325C18.7122 3.49672 18.7119 2.98378 18.3954 2.66756C18.0789 2.35134 17.5659 2.3516 17.2497 2.66813L9.72129 10.2041L7.86404 8.34683C7.54767 8.03046 7.03472 8.03046 6.71835 8.34683C6.40197 8.66321 6.40197 9.17615 6.71835 9.49253L9.14873 11.9229C9.30071 12.0749 9.50685 12.1602 9.72178 12.1602C9.93671 12.1601 10.1428 12.0747 10.2947 11.9226L18.396 3.81325Z' fill='%2392CD76'/%3e %3c/svg%3e"
|
|
4724
|
-
|
|
4725
|
-
/***/ }),
|
|
4726
|
-
|
|
4727
5276
|
/***/ 267:
|
|
4728
5277
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
4729
5278
|
|
|
@@ -4789,7 +5338,7 @@ module.exports = require("sweetalert2");
|
|
|
4789
5338
|
/***/ ((module) => {
|
|
4790
5339
|
|
|
4791
5340
|
"use strict";
|
|
4792
|
-
module.exports = JSON.parse('{"purchase_complete_step":{"title":" Your order is complete","initial_order_complete_1st_paragraph_label":"A ticket has been assigned to {attendee}. To complete {adv} additional ticket details, please click the \\"{button}\\" button.","initial_order_complete_button":"Finish Now","order_complete_1st_paragraph_label":"You may visit the \\"My Orders/Tickets\\" tab in the top right-hand corner of the navigation bar to\\n assign/reassign tickets or to complete any required ticket details.","order_complete_button":"View My Orders/Tickets","access_event_button":"Access Event Now","initial_order_footer_label":"If you wish to transfer your assigned ticket, close this window and visit the \\"My Orders/Tickets\\" tab in the top navigation bar. ","footer_assistance_text":"For further assistance, please email <a href=\\"mailto:{supportEmail}\\">{supportEmail}</a>","event_will_start_text":"The event will start on {date} at {time} {time_zone_label}"},"ticket_type":{"ticket_quantity_tooltip":"Only one ticket type can be selected per order. To purchase multiple ticket types, please place a separate registration order for each ticket type."},"promo_code":{"promo_code_tooltip":"Only one promo code can be used per order; the code will be applied to all tickets in this order. If you\'d like to use multiple promo codes, please place a separate registration order for each promo code."}}');
|
|
5341
|
+
module.exports = JSON.parse('{"purchase_complete_step":{"title":" Your order is complete","initial_order_complete_1st_paragraph_label":"A ticket has been assigned to {attendee}. To complete {adv} additional ticket details, please click the \\"{button}\\" button.","initial_order_complete_button":"Finish Now","order_complete_1st_paragraph_label":"You may visit the \\"My Orders/Tickets\\" tab in the top right-hand corner of the navigation bar to\\n assign/reassign tickets or to complete any required ticket details.","order_complete_button":"View My Orders/Tickets","access_event_button":"Access Event Now","initial_order_footer_label":"If you wish to transfer your assigned ticket, close this window and visit the \\"My Orders/Tickets\\" tab in the top navigation bar. ","footer_assistance_text":"For further assistance, please email <a href=\\"mailto:{supportEmail}\\">{supportEmail}</a>","event_will_start_text":"The event will start on {date} at {time} {time_zone_label}"},"ticket_type":{"ticket_quantity_tooltip":"Only one ticket type can be selected per order. To purchase multiple ticket types, please place a separate registration order for each ticket type.","no_tickets_available":"There are no tickets currently available for purchase. If you have a promo code, enter it below to check for eligible tickets.","max_per_order_one":"This ticket type is limited to 1 per order.","max_per_order_other":"This ticket type is limited to {limit} per order."},"promo_code":{"promo_code_tooltip":"Only one promo code can be used per order; the code will be applied to all tickets in this order. If you\'d like to use multiple promo codes, please place a separate registration order for each promo code.","default_label":"Do you have a promo code?","auto_applied_label":"Following promo code was automatically applied:","applied_label":"Applied promo code:","applying_label":"Applying promo code...","suggestion_label":"You qualify for the following promo code:","per_account_limit_one":"Promo code limits {limit} ticket per account.","per_account_limit_other":"Promo code limits {limit} tickets per account.","non_transferable":"This ticket will be automatically assigned to you and cannot be reassigned.","unapplied_code_warning":"You entered a promo code but it hasn\'t been applied. Make sure to click the \'Apply\' button or remove it before continuing.","invalid_code":"Promo code entered is not valid.","validation_error":"An error occurred while validating the promo code."}}');
|
|
4793
5342
|
|
|
4794
5343
|
/***/ })
|
|
4795
5344
|
|
|
@@ -4876,7 +5425,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
4876
5425
|
/* harmony import */ var _login__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(462);
|
|
4877
5426
|
/* harmony import */ var _login_passwordless__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(590);
|
|
4878
5427
|
/* harmony import */ var _registration_modal__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(889);
|
|
4879
|
-
/* harmony import */ var _registration_form__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(
|
|
5428
|
+
/* harmony import */ var _registration_form__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(95);
|
|
4880
5429
|
/**
|
|
4881
5430
|
* Copyright 2026 OpenStack Foundation
|
|
4882
5431
|
* Licensed under the Apache License, Version 2.0 (the "License");
|