@riverbankcms/sdk 0.90.1 → 0.92.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{PreviewEditorSidebar-FNFRVSIM.mjs → PreviewEditorSidebar-3CI5MKV3.mjs} +3 -3
- package/dist/{PreviewEditorUI-3WXJFQXG.mjs → PreviewEditorUI-DKEP636I.mjs} +3 -3
- package/dist/SdkPreviewModeRuntime-BRGRDQFH.mjs +8 -0
- package/dist/_dts/api/src/bookingConfig.d.ts +13 -1
- package/dist/_dts/api/src/bookingOperations.d.ts +1 -0
- package/dist/_dts/api/src/bookingRefundOutcomes.d.ts +6 -6
- package/dist/_dts/api/src/customerMembershipOutcomes.d.ts +4 -4
- package/dist/_dts/api/src/publicExperienceEndpoints.d.ts +6 -0
- package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +32 -0
- package/dist/_dts/blocks/src/system/blocks/courses/shared/pricing.d.ts +12 -1
- package/dist/_dts/blocks/src/system/blocks/courses/shared/schemas.d.ts +12 -0
- package/dist/_dts/blocks/src/system/blocks/courses/shared/types.d.ts +4 -1
- package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +44 -0
- package/dist/_dts/blocks/src/system/manifest/fieldValidation/index.d.ts +24 -0
- package/dist/_dts/blocks/src/system/runtime/api/types.d.ts +8 -1
- package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessBookingFlow.d.ts +8 -1
- package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessBookingFlow.state.d.ts +1 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.headless.state.d.ts +4 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.interactive.d.ts +40 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.reserved-fields.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.state.d.ts +29 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/booking-runtime-sources.d.ts +1 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/components.d.ts +6 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/useCourseRegistrationWizard.d.ts +8 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/TicketSelectionStep.d.ts +8 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/hooks.d.ts +1 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.d.ts +1 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +9 -0
- package/dist/_dts/content-model/src/entry-slots/types.d.ts +110 -2
- package/dist/_dts/core/src/branded.d.ts +3 -0
- package/dist/_dts/core/src/event-pricing.d.ts +18 -1
- package/dist/_dts/core/src/money-input.d.ts +34 -4
- package/dist/_dts/core/src/string.d.ts +12 -0
- package/dist/_dts/db/src/generated/supabase/database.types.d.ts +70 -0
- package/dist/_dts/media-core/src/fileAssetCompatibility.d.ts +1 -1
- package/dist/_dts/media-core/src/filePersistence.d.ts +5 -1
- package/dist/_dts/media-core/src/fileStorage.d.ts +1 -0
- package/dist/_dts/media-core/src/videoPrep.d.ts +15 -6
- package/dist/_dts/media-core/src/videoSlotPolicy.d.ts +5 -5
- package/dist/_dts/sdk/src/cli/commands/push/execute/diff.d.ts +2 -0
- package/dist/_dts/sdk/src/cli/commands/push/execute/localMediaReporting.d.ts +23 -0
- package/dist/_dts/sdk/src/cli/commands/push/scopes/commandBackedDatedOfferingScope.d.ts +54 -0
- package/dist/_dts/sdk/src/cli/commands/push/scopes/mediaPrep.d.ts +7 -2
- package/dist/_dts/sdk/src/cli/commands/push/scopes/types.d.ts +6 -0
- package/dist/_dts/sdk/src/cli/media/local-sync.d.ts +35 -0
- package/dist/_dts/sdk/src/cli/sync/validation.d.ts +2 -2
- package/dist/_dts/sdk/src/rendering/islands/types.d.ts +23 -1
- package/dist/_dts/sdk/src/version.d.ts +1 -1
- package/dist/{chunk-SYYJZPKU.mjs → chunk-6D7PLF4M.mjs} +2 -2
- package/dist/{chunk-CR2VX432.mjs → chunk-I6EOKV6B.mjs} +568 -76
- package/dist/{chunk-FA6LVZ7C.mjs → chunk-LERKJM3E.mjs} +7 -7
- package/dist/{chunk-UG7I7S7W.mjs → chunk-U5YM4AWE.mjs} +1 -1
- package/dist/{chunk-H6TT5ZXI.mjs → chunk-UOMTCHZD.mjs} +1 -1
- package/dist/{chunk-BOQXMCSP.mjs → chunk-ZA2S7H34.mjs} +3 -3
- package/dist/cli/index.mjs +755 -414
- package/dist/cli/init-docs/content/workflow-add-block.md +48 -0
- package/dist/cli/init-docs/content/workflow-custom-block.md +10 -0
- package/dist/client/{accordion-4K7VGZ3I.mjs → accordion-BUDH2G3S.mjs} +2 -2
- package/dist/client/{bookingForm-3QXA3CIS.mjs → bookingForm-NQMCELVB.mjs} +90 -15
- package/dist/client/bookings.mjs +259 -32
- package/dist/client/{carousel-BEJKNGQ7.mjs → carousel-ONCEW6IJ.mjs} +3 -3
- package/dist/client/{cart-44BBM6XG.mjs → cart-V2TCK2GI.mjs} +7 -7
- package/dist/client/{checkout-THMHEYKF.mjs → checkout-ZI7SWNCS.mjs} +7 -7
- package/dist/client/{chunk-PEDNDLPB.mjs → chunk-AUMRQ242.mjs} +52 -5
- package/dist/client/{chunk-EJBHK74Y.mjs → chunk-B5UC2D6X.mjs} +7 -6
- package/dist/client/{chunk-DQIRKNZE.mjs → chunk-ERQDHUS2.mjs} +1 -1
- package/dist/client/{chunk-3H5CLFKT.mjs → chunk-GH6IIOOE.mjs} +39 -10
- package/dist/client/{chunk-ZIAF2DA4.mjs → chunk-HQWIJLYN.mjs} +1 -1
- package/dist/client/{chunk-4COPESPO.mjs → chunk-JXY6NHG6.mjs} +6 -6
- package/dist/client/{chunk-JV7ZNAOU.mjs → chunk-KXYEKEV6.mjs} +155 -17
- package/dist/client/{chunk-HIHOQGIP.mjs → chunk-LJCX6V7Q.mjs} +9 -9
- package/dist/client/{chunk-5AJIMWKS.mjs → chunk-N2WJPTF7.mjs} +3 -3
- package/dist/client/{chunk-KNTLBQ3N.mjs → chunk-QQNVQ62W.mjs} +1 -1
- package/dist/client/{chunk-B4H6QMPY.mjs → chunk-R3CZQLXF.mjs} +73 -8
- package/dist/client/{chunk-WHZQDPBZ.mjs → chunk-TNGL2WJF.mjs} +1 -0
- package/dist/client/{chunk-SLY6UDAS.mjs → chunk-ZJDBOLX7.mjs} +3 -3
- package/dist/client/client.mjs +548 -68
- package/dist/client/{courseRegistration-URX7RCCK.mjs → courseRegistration-JPWAQ6KM.mjs} +112 -12
- package/dist/client/{eventCalendar-GTENOQCE.mjs → eventCalendar-QDOCHBBV.mjs} +10 -10
- package/dist/client/{eventCombined-EZVB72MF.mjs → eventCombined-ZS2CXSIE.mjs} +10 -10
- package/dist/client/{eventDetails-CH4BJR5Z.mjs → eventDetails-5LOBMPLN.mjs} +10 -10
- package/dist/client/{eventListing-4BVOI5HS.mjs → eventListing-SBGY4I3L.mjs} +10 -10
- package/dist/client/{eventRegistration-37LPIKIE.mjs → eventRegistration-XGPIU3Z2.mjs} +10 -10
- package/dist/client/{form-FX3Y54YK.mjs → form-R7D4LZWW.mjs} +4 -4
- package/dist/client/{headerSection-UOZZGVYL.mjs → headerSection-RRLYUCGC.mjs} +3 -3
- package/dist/client/hooks.mjs +29 -9
- package/dist/client/{locationMap-VSIPKV35.mjs → locationMap-35ZJMRBZ.mjs} +3 -3
- package/dist/client/{newsletterForm-6FRJKNAF.mjs → newsletterForm-MJ2VCFUT.mjs} +4 -4
- package/dist/client/{productDetail-6AHMLXCO.mjs → productDetail-2O7YQNBX.mjs} +7 -7
- package/dist/client/{productList-M2CYIZVH.mjs → productList-FDP5BH7W.mjs} +7 -7
- package/dist/client/rendering/client.mjs +526 -64
- package/dist/client/rendering/islands.mjs +19 -19
- package/dist/client/rendering.mjs +547 -67
- package/dist/client/{shop-AUOT6GEX.mjs → shop-BGYJ3LDT.mjs} +7 -7
- package/dist/client/spam-protection.mjs +10 -10
- package/dist/preview-next/client/runtime.mjs +5 -5
- package/dist/{sdk-runtime-6GPJNLU6.mjs → sdk-runtime-B3TFXRXZ.mjs} +6 -6
- package/dist/server/components.mjs +179 -18
- package/dist/server/config-validation.mjs +30 -9
- package/dist/server/config.mjs +30 -9
- package/dist/server/data.mjs +29 -9
- package/dist/server/index.mjs +1 -1
- package/dist/server/navigation.mjs +2 -2
- package/dist/server/next.mjs +180 -19
- package/dist/server/page-converter.mjs +24 -7
- package/dist/server/prebuild.mjs +1 -1
- package/dist/server/rendering/server.mjs +179 -18
- package/dist/server/rendering.mjs +179 -18
- package/dist/server/routing.mjs +43 -19
- package/dist/server/server.mjs +30 -10
- package/package.json +1 -1
- package/dist/SdkPreviewModeRuntime-2UCIMKUB.mjs +0 -8
|
@@ -117,12 +117,13 @@ var init_result = __esm({
|
|
|
117
117
|
});
|
|
118
118
|
|
|
119
119
|
// ../core/src/branded.ts
|
|
120
|
-
var unsafeAsMediaAssetId, unsafeAsStorageBucketName, unsafeAsPositiveByteCount, unsafeAsPositiveSeconds, unsafeAsFormId, unsafeAsPassId, unsafeAsCustomerPassId, unsafeAsAppointmentServiceId, unsafeAsAppointmentResourceId;
|
|
120
|
+
var unsafeAsMediaAssetId, unsafeAsStorageBucketName, unsafeAsStoragePath, unsafeAsPositiveByteCount, unsafeAsPositiveSeconds, unsafeAsFormId, unsafeAsPassId, unsafeAsCustomerPassId, unsafeAsAppointmentServiceId, unsafeAsAppointmentResourceId;
|
|
121
121
|
var init_branded = __esm({
|
|
122
122
|
"../core/src/branded.ts"() {
|
|
123
123
|
"use strict";
|
|
124
124
|
unsafeAsMediaAssetId = (id) => id;
|
|
125
125
|
unsafeAsStorageBucketName = (value) => value;
|
|
126
|
+
unsafeAsStoragePath = (value) => value;
|
|
126
127
|
unsafeAsPositiveByteCount = (value) => value;
|
|
127
128
|
unsafeAsPositiveSeconds = (value) => value;
|
|
128
129
|
unsafeAsFormId = (id) => id;
|
|
@@ -268,6 +269,7 @@ function publicEventPricingType(pricing) {
|
|
|
268
269
|
return "free";
|
|
269
270
|
case "single_paid":
|
|
270
271
|
case "ticket_types":
|
|
272
|
+
case "sliding_scale":
|
|
271
273
|
case "course":
|
|
272
274
|
return isFreePublicEventPriceDisplay(pricing.display) ? "free" : "paid";
|
|
273
275
|
case "external":
|
|
@@ -280,6 +282,7 @@ function publicEventPricingCurrency(pricing) {
|
|
|
280
282
|
case "free_registration":
|
|
281
283
|
case "single_paid":
|
|
282
284
|
case "ticket_types":
|
|
285
|
+
case "sliding_scale":
|
|
283
286
|
return pricing.currency;
|
|
284
287
|
case "course":
|
|
285
288
|
return pricing.display.display.currency;
|
|
@@ -297,6 +300,8 @@ function publicEventPricingMode(pricing) {
|
|
|
297
300
|
return "single";
|
|
298
301
|
case "ticket_types":
|
|
299
302
|
return "ticket_types";
|
|
303
|
+
case "sliding_scale":
|
|
304
|
+
return "sliding_scale";
|
|
300
305
|
case "drop_in":
|
|
301
306
|
case "course":
|
|
302
307
|
case "external":
|
|
@@ -330,6 +335,8 @@ function formatCoursePriceDisplayLabel(display, options) {
|
|
|
330
335
|
return `Course (${formatCurrencyAmount(display.amount, display.currency, options)})`;
|
|
331
336
|
case "from":
|
|
332
337
|
return `Course (From ${formatCurrencyAmount(display.amount, display.currency, options)})`;
|
|
338
|
+
case "range":
|
|
339
|
+
return `Course (${formatCurrencyAmount(display.minAmount, display.currency, options)} - ${formatCurrencyAmount(display.maxAmount, display.currency, options)})`;
|
|
333
340
|
default:
|
|
334
341
|
return assertNever(display);
|
|
335
342
|
}
|
|
@@ -473,10 +480,11 @@ function omitZeroAmountFutureRows(rows) {
|
|
|
473
480
|
if (rows.length <= 1) {
|
|
474
481
|
return rows;
|
|
475
482
|
}
|
|
476
|
-
const
|
|
477
|
-
if (
|
|
483
|
+
const firstRow = rows[0];
|
|
484
|
+
if (firstRow === void 0) {
|
|
478
485
|
return [];
|
|
479
486
|
}
|
|
487
|
+
const futureRows = rows.slice(1);
|
|
480
488
|
return [
|
|
481
489
|
firstRow,
|
|
482
490
|
...futureRows.filter((row) => row.amountCents > 0)
|
|
@@ -521,11 +529,11 @@ function isValidTimeZone(timeZone) {
|
|
|
521
529
|
}
|
|
522
530
|
function getSafeTimeZone(timeZone) {
|
|
523
531
|
const normalized = typeof timeZone === "string" ? timeZone.trim() : "";
|
|
524
|
-
return normalized && isValidTimeZone(normalized) ? normalized : FALLBACK_TIMEZONE;
|
|
532
|
+
return normalized.length > 0 && isValidTimeZone(normalized) ? normalized : FALLBACK_TIMEZONE;
|
|
525
533
|
}
|
|
526
534
|
function parseStrictBookingTimeZone(timeZone) {
|
|
527
535
|
const normalized = timeZone.trim();
|
|
528
|
-
if (
|
|
536
|
+
if (normalized.length === 0 || !isValidTimeZone(normalized)) {
|
|
529
537
|
return null;
|
|
530
538
|
}
|
|
531
539
|
return normalized;
|
|
@@ -611,7 +619,7 @@ function parseScheduledBookingDateTime(input) {
|
|
|
611
619
|
try {
|
|
612
620
|
const startsAt = toUtcIsoDateTimeString(input.startsAt);
|
|
613
621
|
const timeZone = parseStrictBookingTimeZone(input.timeZone);
|
|
614
|
-
if (
|
|
622
|
+
if (timeZone === null) {
|
|
615
623
|
return {
|
|
616
624
|
ok: false,
|
|
617
625
|
field: "timeZone",
|
|
@@ -750,7 +758,7 @@ function getBookingLocalDateKey(input) {
|
|
|
750
758
|
}
|
|
751
759
|
function parseBookingLocalDate(value) {
|
|
752
760
|
const match = LOCAL_DATE_PATTERN.exec(value.trim());
|
|
753
|
-
if (
|
|
761
|
+
if (match === null || match.groups === void 0) {
|
|
754
762
|
throw new Error(`Invalid booking date format: "${value}" (expected YYYY-MM-DD)`);
|
|
755
763
|
}
|
|
756
764
|
const year = Number(match.groups.year);
|
|
@@ -809,10 +817,10 @@ function normalizeLocationAddressText(value) {
|
|
|
809
817
|
return null;
|
|
810
818
|
}
|
|
811
819
|
const trimmed = value.trim();
|
|
812
|
-
return trimmed ? trimmed : null;
|
|
820
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
813
821
|
}
|
|
814
822
|
function hasLocationCoordinates(value) {
|
|
815
|
-
return typeof value
|
|
823
|
+
return value != null && typeof value.lat === "number" && typeof value.lng === "number";
|
|
816
824
|
}
|
|
817
825
|
function toLocationCoordinates(value) {
|
|
818
826
|
if (!hasLocationCoordinates(value)) {
|
|
@@ -829,6 +837,13 @@ var init_location = __esm({
|
|
|
829
837
|
}
|
|
830
838
|
});
|
|
831
839
|
|
|
840
|
+
// ../core/src/string.ts
|
|
841
|
+
var init_string = __esm({
|
|
842
|
+
"../core/src/string.ts"() {
|
|
843
|
+
"use strict";
|
|
844
|
+
}
|
|
845
|
+
});
|
|
846
|
+
|
|
832
847
|
// ../core/src/business-address.ts
|
|
833
848
|
var init_business_address = __esm({
|
|
834
849
|
"../core/src/business-address.ts"() {
|
|
@@ -969,13 +984,6 @@ var init_slug = __esm({
|
|
|
969
984
|
}
|
|
970
985
|
});
|
|
971
986
|
|
|
972
|
-
// ../core/src/string.ts
|
|
973
|
-
var init_string = __esm({
|
|
974
|
-
"../core/src/string.ts"() {
|
|
975
|
-
"use strict";
|
|
976
|
-
}
|
|
977
|
-
});
|
|
978
|
-
|
|
979
987
|
// ../core/src/uuid.ts
|
|
980
988
|
var init_uuid = __esm({
|
|
981
989
|
"../core/src/uuid.ts"() {
|
|
@@ -1073,9 +1081,20 @@ var init_src = __esm({
|
|
|
1073
1081
|
});
|
|
1074
1082
|
|
|
1075
1083
|
// ../media-core/src/fileSafety.ts
|
|
1084
|
+
function containsUnsafePathSegmentCharacter(value) {
|
|
1085
|
+
return value.includes("/") || value.includes("\\") || CONTROL_CHARACTER_PATTERN.test(value);
|
|
1086
|
+
}
|
|
1087
|
+
function isReservedPathSegment(value) {
|
|
1088
|
+
return value === "." || value === "..";
|
|
1089
|
+
}
|
|
1090
|
+
function isUnsafePathSegment(segment) {
|
|
1091
|
+
return segment.trim().length === 0 || segment !== segment.trim() || isReservedPathSegment(segment) || containsUnsafePathSegmentCharacter(segment);
|
|
1092
|
+
}
|
|
1093
|
+
var CONTROL_CHARACTER_PATTERN;
|
|
1076
1094
|
var init_fileSafety = __esm({
|
|
1077
1095
|
"../media-core/src/fileSafety.ts"() {
|
|
1078
1096
|
"use strict";
|
|
1097
|
+
CONTROL_CHARACTER_PATTERN = /[\u0000-\u001f\u007f]/u;
|
|
1079
1098
|
}
|
|
1080
1099
|
});
|
|
1081
1100
|
|
|
@@ -1115,11 +1134,21 @@ var init_fileDomain = __esm({
|
|
|
1115
1134
|
});
|
|
1116
1135
|
|
|
1117
1136
|
// ../media-core/src/fileStorage.ts
|
|
1137
|
+
function parseStoragePath(value) {
|
|
1138
|
+
return joinStoragePathSegments(value.split("/"));
|
|
1139
|
+
}
|
|
1140
|
+
function joinStoragePathSegments(segments) {
|
|
1141
|
+
if (segments.some(isUnsafePathSegment)) {
|
|
1142
|
+
return err("unsafe-path-segment");
|
|
1143
|
+
}
|
|
1144
|
+
return ok(unsafeAsStoragePath(segments.join("/")));
|
|
1145
|
+
}
|
|
1118
1146
|
var FILE_STORAGE_BUCKETS, PUBLIC_SITE_FILE_STORAGE_BUCKETS, PRIVATE_SITE_FILE_BUCKET_MIME_TYPES, TEMP_UPLOAD_BUCKET_MIME_TYPES;
|
|
1119
1147
|
var init_fileStorage = __esm({
|
|
1120
1148
|
"../media-core/src/fileStorage.ts"() {
|
|
1121
1149
|
"use strict";
|
|
1122
1150
|
init_src();
|
|
1151
|
+
init_fileSafety();
|
|
1123
1152
|
FILE_STORAGE_BUCKETS = {
|
|
1124
1153
|
publicSite: unsafeAsStorageBucketName("media"),
|
|
1125
1154
|
privateSite: unsafeAsStorageBucketName("site-files-private"),
|
|
@@ -1305,14 +1334,18 @@ var init_uploadVerificationContract = __esm({
|
|
|
1305
1334
|
});
|
|
1306
1335
|
|
|
1307
1336
|
// ../media-core/src/videoPrep.ts
|
|
1337
|
+
function unsafeAsPositiveVideoDurationSeconds(value) {
|
|
1338
|
+
return value;
|
|
1339
|
+
}
|
|
1308
1340
|
var VIDEO_PREP_LIMITS;
|
|
1309
1341
|
var init_videoPrep = __esm({
|
|
1310
1342
|
"../media-core/src/videoPrep.ts"() {
|
|
1311
1343
|
"use strict";
|
|
1344
|
+
init_src();
|
|
1312
1345
|
VIDEO_PREP_LIMITS = {
|
|
1313
|
-
maxRawByteCount: 500 * 1024 * 1024,
|
|
1314
|
-
inlineContentMaxDurationSeconds: 60,
|
|
1315
|
-
backgroundVideoMaxDurationSeconds: 30,
|
|
1346
|
+
maxRawByteCount: unsafeAsPositiveByteCount(500 * 1024 * 1024),
|
|
1347
|
+
inlineContentMaxDurationSeconds: unsafeAsPositiveVideoDurationSeconds(60),
|
|
1348
|
+
backgroundVideoMaxDurationSeconds: unsafeAsPositiveVideoDurationSeconds(30),
|
|
1316
1349
|
targetMaxDimensionPixels: 1080
|
|
1317
1350
|
};
|
|
1318
1351
|
}
|
|
@@ -1383,10 +1416,10 @@ var init_identifiers = __esm({
|
|
|
1383
1416
|
|
|
1384
1417
|
// ../media-core/src/url.ts
|
|
1385
1418
|
function isRelativeDirectImageStoragePath(storagePath) {
|
|
1386
|
-
return RELATIVE_STORAGE_PATH_PREFIXES.some((prefix) => storagePath.startsWith(prefix));
|
|
1419
|
+
return RELATIVE_STORAGE_PATH_PREFIXES.some((prefix) => storagePath.startsWith(prefix)) && parseStoragePath(storagePath).ok;
|
|
1387
1420
|
}
|
|
1388
1421
|
function isSiteScopedDirectImageStoragePath(storagePath) {
|
|
1389
|
-
return storagePath.startsWith("sites/");
|
|
1422
|
+
return storagePath.startsWith("sites/") && parseStoragePath(storagePath).ok;
|
|
1390
1423
|
}
|
|
1391
1424
|
function encodeStoragePath(storagePath) {
|
|
1392
1425
|
return storagePath.split("/").map((segment) => encodeURIComponent(segment)).join("/");
|
|
@@ -1467,6 +1500,7 @@ var DEFAULT_BASE_PATH, RELATIVE_STORAGE_PATH_PREFIXES, formatNumber, ORDER, getI
|
|
|
1467
1500
|
var init_url = __esm({
|
|
1468
1501
|
"../media-core/src/url.ts"() {
|
|
1469
1502
|
"use strict";
|
|
1503
|
+
init_fileStorage();
|
|
1470
1504
|
DEFAULT_BASE_PATH = "/api/img";
|
|
1471
1505
|
RELATIVE_STORAGE_PATH_PREFIXES = [
|
|
1472
1506
|
"originals/",
|
|
@@ -2050,9 +2084,12 @@ var init_schemas = __esm({
|
|
|
2050
2084
|
});
|
|
2051
2085
|
coursePricingSchema = z5.object({
|
|
2052
2086
|
bookingRequirement: z5.enum(["none", "required"]),
|
|
2053
|
-
pricingStrategy: z5.enum(["free", "single", "tiered"]),
|
|
2087
|
+
pricingStrategy: z5.enum(["free", "single", "tiered", "sliding_scale"]),
|
|
2054
2088
|
currency: z5.string(),
|
|
2055
2089
|
singlePriceAmount: z5.number().nullable(),
|
|
2090
|
+
slidingMinAmount: z5.number().nullable().optional(),
|
|
2091
|
+
slidingMaxAmount: z5.number().nullable().optional(),
|
|
2092
|
+
slidingSuggestedAmount: z5.number().nullable().optional(),
|
|
2056
2093
|
paymentTerms: blockBookingPaymentTermsSchema,
|
|
2057
2094
|
options: z5.array(coursePricingOptionSchema)
|
|
2058
2095
|
});
|
|
@@ -2217,6 +2254,19 @@ var init_schemas2 = __esm({
|
|
|
2217
2254
|
ticketTypes: z6.array(publicEventTicketTypeSchema),
|
|
2218
2255
|
display: publicEventTicketTypePriceDisplaySchema
|
|
2219
2256
|
}),
|
|
2257
|
+
z6.object({
|
|
2258
|
+
kind: z6.literal("sliding_scale"),
|
|
2259
|
+
minAmount: z6.number(),
|
|
2260
|
+
maxAmount: z6.number(),
|
|
2261
|
+
suggestedAmount: z6.number().nullable(),
|
|
2262
|
+
currency: z6.string(),
|
|
2263
|
+
display: z6.object({
|
|
2264
|
+
kind: z6.literal("range"),
|
|
2265
|
+
minAmount: z6.number(),
|
|
2266
|
+
maxAmount: z6.number(),
|
|
2267
|
+
currency: z6.string()
|
|
2268
|
+
})
|
|
2269
|
+
}),
|
|
2220
2270
|
z6.object({
|
|
2221
2271
|
kind: z6.literal("course"),
|
|
2222
2272
|
display: z6.object({ kind: z6.literal("course"), display: publicCoursePriceDisplaySchema })
|
|
@@ -23337,6 +23387,7 @@ var init_booking_form_reserved_fields = __esm({
|
|
|
23337
23387
|
"selectedDate",
|
|
23338
23388
|
"selectedSlot",
|
|
23339
23389
|
"discountCode",
|
|
23390
|
+
"selectedSlidingAmountInput",
|
|
23340
23391
|
"selectedCollectionOptionKind",
|
|
23341
23392
|
"selectedAppointmentPackageId"
|
|
23342
23393
|
];
|
|
@@ -23622,6 +23673,32 @@ function readOptionalString(value) {
|
|
|
23622
23673
|
function readOptionalNumber(value) {
|
|
23623
23674
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
23624
23675
|
}
|
|
23676
|
+
function getBookingServiceSlidingScale(service) {
|
|
23677
|
+
const pricing = service?.pricing;
|
|
23678
|
+
if (!pricing || pricing.pricingStrategy !== "sliding_scale" || pricing.slidingMinAmount === null || pricing.slidingMinAmount === void 0 || pricing.slidingMaxAmount === null || pricing.slidingMaxAmount === void 0) {
|
|
23679
|
+
return null;
|
|
23680
|
+
}
|
|
23681
|
+
return {
|
|
23682
|
+
minAmount: pricing.slidingMinAmount,
|
|
23683
|
+
maxAmount: pricing.slidingMaxAmount,
|
|
23684
|
+
suggestedAmount: pricing.slidingSuggestedAmount ?? null,
|
|
23685
|
+
currency: pricing.currency
|
|
23686
|
+
};
|
|
23687
|
+
}
|
|
23688
|
+
function parseBookingCurrencyInputToCents(value) {
|
|
23689
|
+
const trimmed = value?.trim() ?? "";
|
|
23690
|
+
if (!trimmed) return null;
|
|
23691
|
+
if (!/^(?:\d+(?:\.\d{0,2})?|\.\d{1,2})$/.test(trimmed)) return null;
|
|
23692
|
+
const parsed = Number(trimmed);
|
|
23693
|
+
if (!Number.isFinite(parsed) || parsed < 0) return null;
|
|
23694
|
+
return Math.round(parsed * 100);
|
|
23695
|
+
}
|
|
23696
|
+
function formatBookingCentsAsCurrencyInput(amount) {
|
|
23697
|
+
return amount % 100 === 0 ? String(amount / 100) : (amount / 100).toFixed(2);
|
|
23698
|
+
}
|
|
23699
|
+
function isBookingServiceSlidingAmountInRange(slidingScale, selectedAmount) {
|
|
23700
|
+
return selectedAmount !== null && selectedAmount >= slidingScale.minAmount && selectedAmount <= slidingScale.maxAmount;
|
|
23701
|
+
}
|
|
23625
23702
|
function readStringArray(value) {
|
|
23626
23703
|
if (!Array.isArray(value)) return void 0;
|
|
23627
23704
|
const strings = value.filter((item) => typeof item === "string");
|
|
@@ -23810,6 +23887,20 @@ function prepareBookingSubmission(input) {
|
|
|
23810
23887
|
};
|
|
23811
23888
|
}
|
|
23812
23889
|
const paymentSelectionMode = getBookingServicePaymentSelectionMode(selectedService);
|
|
23890
|
+
const slidingScale = getBookingServiceSlidingScale(selectedService);
|
|
23891
|
+
const selectedSlidingAmount = parseBookingCurrencyInputToCents(
|
|
23892
|
+
input.data.selectedSlidingAmountInput
|
|
23893
|
+
);
|
|
23894
|
+
if (slidingScale && !isBookingServiceSlidingAmountInRange(slidingScale, selectedSlidingAmount)) {
|
|
23895
|
+
return {
|
|
23896
|
+
ok: false,
|
|
23897
|
+
error: {
|
|
23898
|
+
tag: selectedSlidingAmount === null ? "sliding-amount-required" : "sliding-amount-out-of-range",
|
|
23899
|
+
serviceId,
|
|
23900
|
+
serviceTitle: selectedService.title || serviceId
|
|
23901
|
+
}
|
|
23902
|
+
};
|
|
23903
|
+
}
|
|
23813
23904
|
if (paymentSelectionMode === "choice_required" && !toSelectedCollectionOptionKind(input.data.selectedCollectionOptionKind)) {
|
|
23814
23905
|
return {
|
|
23815
23906
|
ok: false,
|
|
@@ -23837,6 +23928,7 @@ function prepareBookingSubmission(input) {
|
|
|
23837
23928
|
...common,
|
|
23838
23929
|
kind: "standard",
|
|
23839
23930
|
...discountCode ? { discountCode } : {},
|
|
23931
|
+
...slidingScale && selectedSlidingAmount !== null ? { selectedSlidingAmount } : {},
|
|
23840
23932
|
...selectedCollectionOptionKind ? { selectedCollectionOptionKind } : {},
|
|
23841
23933
|
altchaSolution: input.altchaSolution ?? null
|
|
23842
23934
|
}
|
|
@@ -23850,6 +23942,10 @@ function formatBookingSubmissionPreparationError(error) {
|
|
|
23850
23942
|
return `Service not found: ${error.serviceId}`;
|
|
23851
23943
|
case "payment-option-required":
|
|
23852
23944
|
return `Please choose how you want to pay for "${error.serviceTitle}".`;
|
|
23945
|
+
case "sliding-amount-required":
|
|
23946
|
+
return `Please choose an amount for "${error.serviceTitle}".`;
|
|
23947
|
+
case "sliding-amount-out-of-range":
|
|
23948
|
+
return `Please choose an amount within the sliding scale for "${error.serviceTitle}".`;
|
|
23853
23949
|
case "payment-option-unsupported":
|
|
23854
23950
|
return `Service "${error.serviceTitle}" has a payment option that is not supported yet.`;
|
|
23855
23951
|
case "service-missing-duration":
|
|
@@ -24000,6 +24096,7 @@ var init_booking_form_interactive = __esm({
|
|
|
24000
24096
|
title: z36.string(),
|
|
24001
24097
|
description: z36.string().nullable().optional().transform((value) => value ?? void 0),
|
|
24002
24098
|
durationMinutes: z36.number().optional(),
|
|
24099
|
+
pricing: z36.custom().optional(),
|
|
24003
24100
|
priceAmount: z36.number().nullable().optional(),
|
|
24004
24101
|
priceCurrency: z36.string().nullable().optional(),
|
|
24005
24102
|
paymentTerms: blockBookingPaymentTermsSchema.optional(),
|
|
@@ -24439,7 +24536,7 @@ function formatCalendarTitle(viewDate, view, days, monthNames = MONTH_NAMES) {
|
|
|
24439
24536
|
if (view === "week") {
|
|
24440
24537
|
const weekStart = days[0];
|
|
24441
24538
|
const weekEnd = days[6];
|
|
24442
|
-
if (
|
|
24539
|
+
if (weekStart === void 0 || weekEnd === void 0) {
|
|
24443
24540
|
return `${monthNames[viewDate.getMonth()] ?? ""} ${viewDate.getFullYear()}`;
|
|
24444
24541
|
}
|
|
24445
24542
|
const startMonth = monthNames[weekStart.getMonth()] ?? "";
|
|
@@ -24571,7 +24668,9 @@ function getLocalDateKey(isoTimestamp, timeZone) {
|
|
|
24571
24668
|
const year = parts.find((part) => part.type === "year")?.value;
|
|
24572
24669
|
const month = parts.find((part) => part.type === "month")?.value;
|
|
24573
24670
|
const day = parts.find((part) => part.type === "day")?.value;
|
|
24574
|
-
if (
|
|
24671
|
+
if (year === void 0 || year.length === 0) return null;
|
|
24672
|
+
if (month === void 0 || month.length === 0) return null;
|
|
24673
|
+
if (day === void 0 || day.length === 0) return null;
|
|
24575
24674
|
return `${year}-${month}-${day}`;
|
|
24576
24675
|
}
|
|
24577
24676
|
function isValidTimeZone2(timeZone) {
|
|
@@ -24828,7 +24927,7 @@ function enumerateDateKeys(startDateKey, endDateKey) {
|
|
|
24828
24927
|
}
|
|
24829
24928
|
function parseDateKey(dateKey) {
|
|
24830
24929
|
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(dateKey);
|
|
24831
|
-
if (
|
|
24930
|
+
if (match === null) {
|
|
24832
24931
|
throw new Error(`Invalid timetable date key: ${dateKey}`);
|
|
24833
24932
|
}
|
|
24834
24933
|
const [, year, month, day] = match;
|
|
@@ -24864,7 +24963,7 @@ function groupItemsByDate(items, accessors) {
|
|
|
24864
24963
|
const dateKey = getLocalDateKey(startsAt, timeZone);
|
|
24865
24964
|
if (dateKey == null) continue;
|
|
24866
24965
|
const existing = grouped.get(dateKey);
|
|
24867
|
-
if (existing) {
|
|
24966
|
+
if (existing !== void 0) {
|
|
24868
24967
|
existing.push(item);
|
|
24869
24968
|
} else {
|
|
24870
24969
|
grouped.set(dateKey, [item]);
|
|
@@ -24986,7 +25085,7 @@ function isRecord6(value) {
|
|
|
24986
25085
|
}
|
|
24987
25086
|
function isPublicEventPricing(value) {
|
|
24988
25087
|
if (!isRecord6(value) || typeof value.kind !== "string") return false;
|
|
24989
|
-
return value.kind === "drop_in" || value.kind === "free_registration" || value.kind === "single_paid" || value.kind === "ticket_types" || value.kind === "course" || value.kind === "external";
|
|
25088
|
+
return value.kind === "drop_in" || value.kind === "free_registration" || value.kind === "single_paid" || value.kind === "sliding_scale" || value.kind === "ticket_types" || value.kind === "course" || value.kind === "external";
|
|
24990
25089
|
}
|
|
24991
25090
|
function isPublicEventTicketType(value) {
|
|
24992
25091
|
return isRecord6(value) && typeof value.id === "string";
|
|
@@ -33590,12 +33689,13 @@ var init_carousel_client = __esm({
|
|
|
33590
33689
|
]
|
|
33591
33690
|
);
|
|
33592
33691
|
const resolvedSlides = resolveSlidesToShowMobile(normalized.slidesToShow);
|
|
33692
|
+
const canAutoplay = normalized.autoplay && slides.length > 1;
|
|
33593
33693
|
const cssVars = React5.useMemo(
|
|
33594
33694
|
() => getCarouselSlidesToShowCssVars(normalized.slidesToShow),
|
|
33595
33695
|
[normalized.slidesToShow]
|
|
33596
33696
|
);
|
|
33597
33697
|
const plugins = React5.useMemo(() => {
|
|
33598
|
-
if (!
|
|
33698
|
+
if (!canAutoplay) return void 0;
|
|
33599
33699
|
return [
|
|
33600
33700
|
Autoplay({
|
|
33601
33701
|
delay: normalized.autoplayDelay,
|
|
@@ -33605,7 +33705,7 @@ var init_carousel_client = __esm({
|
|
|
33605
33705
|
// Continue after manual navigation
|
|
33606
33706
|
})
|
|
33607
33707
|
];
|
|
33608
|
-
}, [
|
|
33708
|
+
}, [canAutoplay, normalized.autoplayDelay]);
|
|
33609
33709
|
const [viewportRef, api] = useEmblaCarousel(
|
|
33610
33710
|
{
|
|
33611
33711
|
align: "start",
|
|
@@ -33644,7 +33744,7 @@ var init_carousel_client = __esm({
|
|
|
33644
33744
|
};
|
|
33645
33745
|
}, [api]);
|
|
33646
33746
|
React5.useEffect(() => {
|
|
33647
|
-
if (!api || !
|
|
33747
|
+
if (!api || !canAutoplay) return;
|
|
33648
33748
|
const autoplayPlugin = api.plugins()?.autoplay;
|
|
33649
33749
|
if (!autoplayPlugin) return;
|
|
33650
33750
|
const handleVisibility = () => {
|
|
@@ -33653,7 +33753,7 @@ var init_carousel_client = __esm({
|
|
|
33653
33753
|
};
|
|
33654
33754
|
document.addEventListener("visibilitychange", handleVisibility);
|
|
33655
33755
|
return () => document.removeEventListener("visibilitychange", handleVisibility);
|
|
33656
|
-
}, [api,
|
|
33756
|
+
}, [api, canAutoplay]);
|
|
33657
33757
|
const inner = /* @__PURE__ */ jsxs13(Fragment3, { children: [
|
|
33658
33758
|
/* @__PURE__ */ jsx15("div", { className: "carousel-frame rb-overflow-hidden rb-w-full", children: /* @__PURE__ */ jsx15(
|
|
33659
33759
|
"div",
|
|
@@ -33704,7 +33804,7 @@ var init_carousel_client = __esm({
|
|
|
33704
33804
|
"data-show-controls": normalized.showControls ? "true" : "false",
|
|
33705
33805
|
"data-show-dots": normalized.showDots ? "true" : "false",
|
|
33706
33806
|
"data-arrow-visibility": normalized.arrowVisibility,
|
|
33707
|
-
"data-autoplay":
|
|
33807
|
+
"data-autoplay": canAutoplay ? "true" : "false",
|
|
33708
33808
|
"data-loop": normalized.loop ? "true" : "false",
|
|
33709
33809
|
children: inner
|
|
33710
33810
|
}
|
|
@@ -34707,6 +34807,7 @@ function createBlockApi(config) {
|
|
|
34707
34807
|
body: {
|
|
34708
34808
|
courseId: data.courseId,
|
|
34709
34809
|
...data.pricingOptionId ? { pricingOptionId: data.pricingOptionId } : {},
|
|
34810
|
+
...data.selectedSlidingAmount !== void 0 ? { selectedSlidingAmount: data.selectedSlidingAmount } : {},
|
|
34710
34811
|
email: data.email,
|
|
34711
34812
|
name: data.name,
|
|
34712
34813
|
phone: data.phone,
|
|
@@ -37887,22 +37988,22 @@ function AltchaWidget({
|
|
|
37887
37988
|
if (typeof window === "undefined") return;
|
|
37888
37989
|
let widget = null;
|
|
37889
37990
|
Promise.resolve().then(() => (init_altcha(), altcha_exports)).then(() => {
|
|
37890
|
-
if (
|
|
37991
|
+
if (containerRef.current === null) return;
|
|
37891
37992
|
widget = document.createElement("altcha-widget");
|
|
37892
37993
|
widget.setAttribute("challengeurl", challengeUrl);
|
|
37893
|
-
if (auto) {
|
|
37994
|
+
if (auto === true) {
|
|
37894
37995
|
widget.setAttribute("auto", "onload");
|
|
37895
37996
|
}
|
|
37896
|
-
if (hidelogo) {
|
|
37997
|
+
if (hidelogo === true) {
|
|
37897
37998
|
widget.setAttribute("hidelogo", "true");
|
|
37898
37999
|
}
|
|
37899
38000
|
widget.setAttribute("hidefooter", "true");
|
|
37900
|
-
if (className) {
|
|
38001
|
+
if (className !== void 0 && className.length > 0) {
|
|
37901
38002
|
widget.className = className;
|
|
37902
38003
|
}
|
|
37903
38004
|
widget.addEventListener("statechange", ((event) => {
|
|
37904
38005
|
const { state, payload } = event.detail;
|
|
37905
|
-
if (state === "verified" && payload) {
|
|
38006
|
+
if (state === "verified" && payload !== void 0 && payload.length > 0) {
|
|
37906
38007
|
onSolutionChange?.(payload);
|
|
37907
38008
|
} else if (state === "error" || state === "expired") {
|
|
37908
38009
|
onSolutionChange?.(null);
|
|
@@ -37913,7 +38014,7 @@ function AltchaWidget({
|
|
|
37913
38014
|
console.error("Failed to load ALTCHA widget:", err4);
|
|
37914
38015
|
});
|
|
37915
38016
|
return () => {
|
|
37916
|
-
if (widget && containerRef.current) {
|
|
38017
|
+
if (widget !== null && containerRef.current !== null) {
|
|
37917
38018
|
containerRef.current.removeChild(widget);
|
|
37918
38019
|
}
|
|
37919
38020
|
};
|
|
@@ -37959,15 +38060,15 @@ var init_dist2 = __esm({
|
|
|
37959
38060
|
// ../altcha/src/index.ts
|
|
37960
38061
|
function getCmsApiUrl() {
|
|
37961
38062
|
const env = process.env.RIVERBANK_ENV;
|
|
37962
|
-
if (env) {
|
|
38063
|
+
if (env !== void 0 && env.length > 0) {
|
|
37963
38064
|
const envKey = `RIVERBANK_${env.toUpperCase()}_DASHBOARD_URL`;
|
|
37964
38065
|
const dashboardUrl2 = process.env[envKey];
|
|
37965
|
-
if (dashboardUrl2) {
|
|
38066
|
+
if (dashboardUrl2 !== void 0 && dashboardUrl2.length > 0) {
|
|
37966
38067
|
return `${dashboardUrl2.replace(/\/$/, "")}/api`;
|
|
37967
38068
|
}
|
|
37968
38069
|
}
|
|
37969
38070
|
const dashboardUrl = process.env.NEXT_PUBLIC_DASHBOARD_URL;
|
|
37970
|
-
if (dashboardUrl) {
|
|
38071
|
+
if (dashboardUrl !== void 0 && dashboardUrl.length > 0) {
|
|
37971
38072
|
return `${dashboardUrl.replace(/\/$/, "")}/api`;
|
|
37972
38073
|
}
|
|
37973
38074
|
throw new Error("Dashboard URL not configured. Set NEXT_PUBLIC_DASHBOARD_URL");
|
|
@@ -38944,6 +39045,7 @@ function useBookingSubmission(_siteId) {
|
|
|
38944
39045
|
customFields: data.customFields,
|
|
38945
39046
|
timezone: data.timezone,
|
|
38946
39047
|
discountCode: data.discountCode,
|
|
39048
|
+
selectedSlidingAmount: data.selectedSlidingAmount,
|
|
38947
39049
|
selectedCollectionOptionKind: data.selectedCollectionOptionKind,
|
|
38948
39050
|
altchaSolution: data.altchaSolution ?? null,
|
|
38949
39051
|
successUrl: data.successUrl,
|
|
@@ -39472,6 +39574,9 @@ function createInitialBookingFlowReducerState(input) {
|
|
|
39472
39574
|
fieldValues: collectInitialFieldValues(initialData),
|
|
39473
39575
|
touchedFields: {},
|
|
39474
39576
|
discountCode: toOptionalString(initialData.discountCode) ?? "",
|
|
39577
|
+
selectedSlidingAmountInput: toOptionalString(
|
|
39578
|
+
initialData.selectedSlidingAmountInput
|
|
39579
|
+
) ?? "",
|
|
39475
39580
|
selectedCollectionOptionKind: toSelectedCollectionOptionKind(
|
|
39476
39581
|
initialData.selectedCollectionOptionKind
|
|
39477
39582
|
),
|
|
@@ -39524,6 +39629,7 @@ function bookingFlowReducer(state, event) {
|
|
|
39524
39629
|
selectedDate: void 0,
|
|
39525
39630
|
selectedSlot: null,
|
|
39526
39631
|
selectedAppointmentPackageId: void 0,
|
|
39632
|
+
selectedSlidingAmountInput: "",
|
|
39527
39633
|
selectedCollectionOptionKind: void 0,
|
|
39528
39634
|
validationErrors: clearBookingFormError(state.validationErrors)
|
|
39529
39635
|
};
|
|
@@ -39577,6 +39683,13 @@ function bookingFlowReducer(state, event) {
|
|
|
39577
39683
|
selectedAppointmentPackageId: void 0,
|
|
39578
39684
|
validationErrors: clearBookingFormError(state.validationErrors)
|
|
39579
39685
|
};
|
|
39686
|
+
case "sliding-amount-changed":
|
|
39687
|
+
return {
|
|
39688
|
+
...state,
|
|
39689
|
+
selectedSlidingAmountInput: event.value,
|
|
39690
|
+
selectedAppointmentPackageId: void 0,
|
|
39691
|
+
validationErrors: clearBookingFormError(state.validationErrors)
|
|
39692
|
+
};
|
|
39580
39693
|
case "appointment-package-selected":
|
|
39581
39694
|
return {
|
|
39582
39695
|
...state,
|
|
@@ -39679,6 +39792,7 @@ function toBookingFormData(state) {
|
|
|
39679
39792
|
selectedDate: state.selectedDate,
|
|
39680
39793
|
selectedSlot: state.selectedSlot?.startAt,
|
|
39681
39794
|
discountCode: state.discountCode || void 0,
|
|
39795
|
+
selectedSlidingAmountInput: state.selectedSlidingAmountInput || void 0,
|
|
39682
39796
|
selectedCollectionOptionKind: state.selectedCollectionOptionKind,
|
|
39683
39797
|
selectedAppointmentPackageId: state.selectedAppointmentPackageId
|
|
39684
39798
|
};
|
|
@@ -39696,7 +39810,8 @@ function buildBookingStepResolution(input) {
|
|
|
39696
39810
|
input.form.settings?.serviceIds && input.form.settings.serviceIds.length > 1
|
|
39697
39811
|
);
|
|
39698
39812
|
const selectedService = paymentResolution.service;
|
|
39699
|
-
const
|
|
39813
|
+
const selectedServiceSlidingScale = getBookingServiceSlidingScale(selectedService);
|
|
39814
|
+
const needsPayment = Boolean(selectedServiceSlidingScale) || paymentResolution.mode !== "hidden" || Boolean(
|
|
39700
39815
|
input.enableAppointmentPackages && selectedService && (selectedService.priceAmount ?? 0) > 0
|
|
39701
39816
|
);
|
|
39702
39817
|
const hasFields = Boolean(input.form.schema?.fields.length);
|
|
@@ -39740,6 +39855,18 @@ function validateBookingStep(input) {
|
|
|
39740
39855
|
services: input.services,
|
|
39741
39856
|
defaultServiceId: input.defaultServiceId
|
|
39742
39857
|
});
|
|
39858
|
+
const slidingScale = getBookingServiceSlidingScale(resolution.service);
|
|
39859
|
+
if (slidingScale && !isBookingServiceSlidingAmountInRange(
|
|
39860
|
+
slidingScale,
|
|
39861
|
+
parseBookingCurrencyInputToCents(input.data.selectedSlidingAmountInput)
|
|
39862
|
+
)) {
|
|
39863
|
+
return {
|
|
39864
|
+
ok: false,
|
|
39865
|
+
errors: createFormBookingValidationError(
|
|
39866
|
+
"Please choose an amount within the sliding scale"
|
|
39867
|
+
)
|
|
39868
|
+
};
|
|
39869
|
+
}
|
|
39743
39870
|
if (resolution.mode === "hidden" || resolution.mode === "disclosure_only") {
|
|
39744
39871
|
return { ok: true };
|
|
39745
39872
|
}
|
|
@@ -40138,6 +40265,7 @@ var init_useHeadlessBookingFlow_state = __esm({
|
|
|
40138
40265
|
"../blocks/src/system/runtime/hooks/useHeadlessBookingFlow.state.ts"() {
|
|
40139
40266
|
"use strict";
|
|
40140
40267
|
init_booking_form_headless_state();
|
|
40268
|
+
init_booking_form_state();
|
|
40141
40269
|
}
|
|
40142
40270
|
});
|
|
40143
40271
|
|
|
@@ -40177,11 +40305,27 @@ function useHeadlessBookingFlow(options) {
|
|
|
40177
40305
|
const selectedServiceId = state.selectedServiceId ?? defaultServiceId;
|
|
40178
40306
|
const selectedResourceId = state.selectedResourceId ?? defaultResourceId;
|
|
40179
40307
|
const selectedService = options.services.find((service) => service.id === selectedServiceId) ?? null;
|
|
40308
|
+
const lastSlidingServiceIdRef = useRef9(null);
|
|
40309
|
+
useEffect8(() => {
|
|
40310
|
+
const selectedId = selectedService?.id ?? null;
|
|
40311
|
+
if (lastSlidingServiceIdRef.current === selectedId) return;
|
|
40312
|
+
lastSlidingServiceIdRef.current = selectedId;
|
|
40313
|
+
const slidingScale = getBookingServiceSlidingScale(selectedService);
|
|
40314
|
+
dispatch({
|
|
40315
|
+
type: "sliding-amount-changed",
|
|
40316
|
+
value: slidingScale?.suggestedAmount !== null && slidingScale?.suggestedAmount !== void 0 ? formatBookingCentsAsCurrencyInput(slidingScale.suggestedAmount) : ""
|
|
40317
|
+
});
|
|
40318
|
+
}, [selectedService]);
|
|
40180
40319
|
const hasPortalBearerAuth = (api.config.authOverrides?.portal ?? api.config.auth).type === "bearer";
|
|
40320
|
+
const selectedServiceSlidingScale = getBookingServiceSlidingScale(selectedService);
|
|
40321
|
+
const selectedSlidingAmount = parseBookingCurrencyInputToCents(
|
|
40322
|
+
state.selectedSlidingAmountInput
|
|
40323
|
+
);
|
|
40324
|
+
const selectedAppointmentPriceAmount = selectedServiceSlidingScale && selectedSlidingAmount !== null ? selectedSlidingAmount : selectedService?.priceAmount ?? 0;
|
|
40181
40325
|
const canLoadAppointmentPackages = Boolean(
|
|
40182
|
-
options.enableAppointmentPackages && hasPortalBearerAuth && selectedService && (selectedService.priceAmount ?? 0) > 0
|
|
40326
|
+
options.enableAppointmentPackages && hasPortalBearerAuth && selectedService && !selectedServiceSlidingScale && (selectedService.priceAmount ?? 0) > 0
|
|
40183
40327
|
);
|
|
40184
|
-
const appointmentPackagesUnavailableReason = !options.enableAppointmentPackages ? "disabled" : !selectedService || (selectedService.priceAmount ?? 0) <= 0 ? "missing-priced-service" : !hasPortalBearerAuth ? "missing-portal-auth" : null;
|
|
40328
|
+
const appointmentPackagesUnavailableReason = !options.enableAppointmentPackages ? "disabled" : !selectedService || selectedServiceSlidingScale || (selectedService.priceAmount ?? 0) <= 0 ? "missing-priced-service" : !hasPortalBearerAuth ? "missing-portal-auth" : null;
|
|
40185
40329
|
const data = useMemo6(() => toBookingFormData(state), [state]);
|
|
40186
40330
|
const availabilityDatesQuery = useMemo6(
|
|
40187
40331
|
() => buildBookingAvailabilityQuery({
|
|
@@ -40411,13 +40555,13 @@ function useHeadlessBookingFlow(options) {
|
|
|
40411
40555
|
state.selectedSlot
|
|
40412
40556
|
]);
|
|
40413
40557
|
const appointmentDiscountContext = useMemo6(
|
|
40414
|
-
() => selectedService &&
|
|
40415
|
-
[
|
|
40558
|
+
() => selectedService && selectedAppointmentPriceAmount > 0 ? { type: "appointment", serviceId: selectedService.id } : null,
|
|
40559
|
+
[selectedAppointmentPriceAmount, selectedService?.id]
|
|
40416
40560
|
);
|
|
40417
40561
|
const discountUi = useDiscountCodeUi({
|
|
40418
40562
|
api,
|
|
40419
40563
|
discountContext: appointmentDiscountContext,
|
|
40420
|
-
subtotalCents:
|
|
40564
|
+
subtotalCents: selectedAppointmentPriceAmount
|
|
40421
40565
|
});
|
|
40422
40566
|
const { submit, clearFeedback } = useBookingSubmission(options.siteId);
|
|
40423
40567
|
const submittingRef = useRef9(false);
|
|
@@ -40560,6 +40704,7 @@ function useHeadlessBookingFlow(options) {
|
|
|
40560
40704
|
type: "appointment-package-selected",
|
|
40561
40705
|
packageId: packageId ? unsafeAsCustomerPassId(packageId) : null
|
|
40562
40706
|
}),
|
|
40707
|
+
setSlidingAmountInput: (value) => dispatch({ type: "sliding-amount-changed", value }),
|
|
40563
40708
|
setDiscountCode: (code) => {
|
|
40564
40709
|
dispatch({ type: "discount-code-changed", code });
|
|
40565
40710
|
latestRef.current.setDiscountCode(code);
|
|
@@ -40630,11 +40775,11 @@ function useHeadlessBookingFlow(options) {
|
|
|
40630
40775
|
() => selectedService && paymentResolution.mode !== "unsupported" ? buildBookingPaymentSelectionViewModel({
|
|
40631
40776
|
serviceTitle: selectedService.title,
|
|
40632
40777
|
paymentTerms: selectedService.paymentTerms,
|
|
40633
|
-
priceAmount:
|
|
40778
|
+
priceAmount: selectedAppointmentPriceAmount,
|
|
40634
40779
|
priceCurrency: selectedService.priceCurrency,
|
|
40635
40780
|
bookingStartAt: state.selectedSlot?.startAt
|
|
40636
40781
|
}) : null,
|
|
40637
|
-
[paymentResolution.mode, selectedService, state.selectedSlot?.startAt]
|
|
40782
|
+
[paymentResolution.mode, selectedAppointmentPriceAmount, selectedService, state.selectedSlot?.startAt]
|
|
40638
40783
|
);
|
|
40639
40784
|
const appointmentPackageItems = appointmentPackages.tag === "loaded" ? appointmentPackages.value : [];
|
|
40640
40785
|
const selectedAppointmentPackage = appointmentPackageItems.find(
|
|
@@ -40663,6 +40808,9 @@ function useHeadlessBookingFlow(options) {
|
|
|
40663
40808
|
selection: null,
|
|
40664
40809
|
selectedCollectionOptionKind: state.selectedCollectionOptionKind,
|
|
40665
40810
|
selectedAppointmentPackageId: state.selectedAppointmentPackageId,
|
|
40811
|
+
selectedSlidingAmountInput: state.selectedSlidingAmountInput,
|
|
40812
|
+
selectedSlidingAmount,
|
|
40813
|
+
slidingScale: selectedServiceSlidingScale,
|
|
40666
40814
|
appointmentPackages: appointmentPackagesModel,
|
|
40667
40815
|
errorMessage: paymentResolution.errorMessage ?? "This service cannot be booked right now."
|
|
40668
40816
|
} : {
|
|
@@ -40671,6 +40819,9 @@ function useHeadlessBookingFlow(options) {
|
|
|
40671
40819
|
selection: paymentSelection,
|
|
40672
40820
|
selectedCollectionOptionKind: state.selectedCollectionOptionKind,
|
|
40673
40821
|
selectedAppointmentPackageId: state.selectedAppointmentPackageId,
|
|
40822
|
+
selectedSlidingAmountInput: state.selectedSlidingAmountInput,
|
|
40823
|
+
selectedSlidingAmount,
|
|
40824
|
+
slidingScale: selectedServiceSlidingScale,
|
|
40674
40825
|
appointmentPackages: appointmentPackagesModel
|
|
40675
40826
|
};
|
|
40676
40827
|
return {
|
|
@@ -41365,6 +41516,9 @@ var init_FieldValidationMessage = __esm({
|
|
|
41365
41516
|
|
|
41366
41517
|
// ../blocks/src/system/runtime/nodes/booking-form.default-ui.tsx
|
|
41367
41518
|
import { Fragment as Fragment5, jsx as jsx27, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
41519
|
+
function formatBookingAmount(amount, currency) {
|
|
41520
|
+
return formatCurrencyAmount(amount, currency, { decimals: "auto" });
|
|
41521
|
+
}
|
|
41368
41522
|
function HeadlessBookingDefaultForm({
|
|
41369
41523
|
booking,
|
|
41370
41524
|
onSubmit
|
|
@@ -41641,6 +41795,7 @@ function HeadlessBookingPaymentSelectionStep({
|
|
|
41641
41795
|
}
|
|
41642
41796
|
const packageOptions = booking.payment.appointmentPackages.items;
|
|
41643
41797
|
const hasPackageOptions = packageOptions.length > 0;
|
|
41798
|
+
const slidingScale = booking.payment.slidingScale;
|
|
41644
41799
|
return /* @__PURE__ */ jsxs21("div", { className: "ab-stack", children: [
|
|
41645
41800
|
/* @__PURE__ */ jsxs21("div", { className: "ab-info-box", children: [
|
|
41646
41801
|
/* @__PURE__ */ jsx27("h3", { className: "ab-subtitle", children: viewModel.sectionTitle }),
|
|
@@ -41651,6 +41806,28 @@ function HeadlessBookingPaymentSelectionStep({
|
|
|
41651
41806
|
booking.payment.appointmentPackages.state.message,
|
|
41652
41807
|
" You can continue with the normal payment option."
|
|
41653
41808
|
] }) : null,
|
|
41809
|
+
slidingScale ? /* @__PURE__ */ jsxs21("div", { className: "rb-space-y-2", children: [
|
|
41810
|
+
/* @__PURE__ */ jsx27("label", { htmlFor: "appointment-sliding-amount", className: "form-label", children: "Choose your price" }),
|
|
41811
|
+
/* @__PURE__ */ jsxs21("p", { className: "rb-caption status-muted", children: [
|
|
41812
|
+
formatBookingAmount(slidingScale.minAmount, slidingScale.currency),
|
|
41813
|
+
" to ",
|
|
41814
|
+
formatBookingAmount(slidingScale.maxAmount, slidingScale.currency),
|
|
41815
|
+
slidingScale.suggestedAmount !== null ? `, suggested ${formatBookingAmount(slidingScale.suggestedAmount, slidingScale.currency)}` : ""
|
|
41816
|
+
] }),
|
|
41817
|
+
/* @__PURE__ */ jsx27(
|
|
41818
|
+
"input",
|
|
41819
|
+
{
|
|
41820
|
+
id: "appointment-sliding-amount",
|
|
41821
|
+
type: "number",
|
|
41822
|
+
className: "form-input",
|
|
41823
|
+
min: slidingScale.minAmount / 100,
|
|
41824
|
+
max: slidingScale.maxAmount / 100,
|
|
41825
|
+
step: "0.01",
|
|
41826
|
+
value: booking.payment.selectedSlidingAmountInput,
|
|
41827
|
+
onChange: (event) => booking.actions.setSlidingAmountInput(event.target.value)
|
|
41828
|
+
}
|
|
41829
|
+
)
|
|
41830
|
+
] }) : null,
|
|
41654
41831
|
/* @__PURE__ */ jsxs21("div", { className: "ab-stack", role: "list", "aria-label": "Payment options", children: [
|
|
41655
41832
|
packageOptions.map((appointmentPackage) => {
|
|
41656
41833
|
const isSelected = booking.payment.selectedAppointmentPackageId === appointmentPackage.customerPassId;
|
|
@@ -43497,6 +43674,7 @@ function useEligibility(params) {
|
|
|
43497
43674
|
occurrenceId: params.occurrenceId,
|
|
43498
43675
|
attendanceMode: params.attendanceMode ?? void 0,
|
|
43499
43676
|
ticketTypeId: params.ticketTypeId ?? void 0,
|
|
43677
|
+
selectedSlidingAmount: params.selectedSlidingAmount ?? void 0,
|
|
43500
43678
|
email: params.email.trim().toLowerCase(),
|
|
43501
43679
|
ticketsCount: params.ticketsCount
|
|
43502
43680
|
});
|
|
@@ -43517,7 +43695,7 @@ function useEligibility(params) {
|
|
|
43517
43695
|
return () => {
|
|
43518
43696
|
cancelled = true;
|
|
43519
43697
|
};
|
|
43520
|
-
}, [api, params.enabled, params.occurrenceId, params.attendanceMode, params.ticketTypeId, params.email, params.ticketsCount]);
|
|
43698
|
+
}, [api, params.enabled, params.occurrenceId, params.attendanceMode, params.ticketTypeId, params.selectedSlidingAmount, params.email, params.ticketsCount]);
|
|
43521
43699
|
return {
|
|
43522
43700
|
state,
|
|
43523
43701
|
eligibility: state.eligibility,
|
|
@@ -43868,6 +44046,41 @@ function TicketCounterLimit(props2) {
|
|
|
43868
44046
|
] }) : null
|
|
43869
44047
|
] });
|
|
43870
44048
|
}
|
|
44049
|
+
function formatCurrencyInputAmount(amount) {
|
|
44050
|
+
const major = amount / 100;
|
|
44051
|
+
return Number.isInteger(major) ? String(major) : major.toFixed(2);
|
|
44052
|
+
}
|
|
44053
|
+
function SlidingScaleAmountField(props2) {
|
|
44054
|
+
const minLabel = formatPrice(props2.slidingScale.minAmount, props2.currency);
|
|
44055
|
+
const maxLabel = formatPrice(props2.slidingScale.maxAmount, props2.currency);
|
|
44056
|
+
const suggestedLabel = props2.slidingScale.suggestedAmount !== null ? formatPrice(props2.slidingScale.suggestedAmount, props2.currency) : null;
|
|
44057
|
+
return /* @__PURE__ */ jsxs28("div", { className: "er-field", children: [
|
|
44058
|
+
/* @__PURE__ */ jsx42("label", { htmlFor: "er-sliding-amount", className: "er-label", children: "Amount" }),
|
|
44059
|
+
/* @__PURE__ */ jsx42(
|
|
44060
|
+
"input",
|
|
44061
|
+
{
|
|
44062
|
+
id: "er-sliding-amount",
|
|
44063
|
+
type: "number",
|
|
44064
|
+
min: formatCurrencyInputAmount(props2.slidingScale.minAmount),
|
|
44065
|
+
max: formatCurrencyInputAmount(props2.slidingScale.maxAmount),
|
|
44066
|
+
step: "0.01",
|
|
44067
|
+
inputMode: "decimal",
|
|
44068
|
+
className: "er-input",
|
|
44069
|
+
value: props2.value,
|
|
44070
|
+
onChange: (event) => props2.onChange?.(event.target.value)
|
|
44071
|
+
}
|
|
44072
|
+
),
|
|
44073
|
+
/* @__PURE__ */ jsxs28("p", { className: "er-text er-text--muted", children: [
|
|
44074
|
+
"Choose between ",
|
|
44075
|
+
minLabel,
|
|
44076
|
+
" and ",
|
|
44077
|
+
maxLabel,
|
|
44078
|
+
suggestedLabel ? `; suggested ${suggestedLabel}` : "",
|
|
44079
|
+
"."
|
|
44080
|
+
] }),
|
|
44081
|
+
props2.message ? /* @__PURE__ */ jsx42("p", { className: "er-text er-text--muted", children: props2.message }) : null
|
|
44082
|
+
] });
|
|
44083
|
+
}
|
|
43871
44084
|
function getTicketTypeCounterAvailabilityLabel(input) {
|
|
43872
44085
|
if (input.selectedRemainingCapacity !== null) {
|
|
43873
44086
|
return `${input.selectedRemainingCapacity} remaining for this ticket type`;
|
|
@@ -43939,6 +44152,10 @@ var init_TicketSelectionStep = __esm({
|
|
|
43939
44152
|
maxTickets,
|
|
43940
44153
|
selectedTicketTypeId = null,
|
|
43941
44154
|
onTicketTypeChange,
|
|
44155
|
+
slidingScale = null,
|
|
44156
|
+
selectedSlidingAmountInput = "",
|
|
44157
|
+
slidingScaleSelectionMessage = null,
|
|
44158
|
+
onSlidingAmountChange,
|
|
43942
44159
|
onTicketsChange
|
|
43943
44160
|
}) => {
|
|
43944
44161
|
const deliveryMode = event?.deliveryMode ?? "in_person";
|
|
@@ -44054,6 +44271,16 @@ var init_TicketSelectionStep = __esm({
|
|
|
44054
44271
|
] })
|
|
44055
44272
|
] })
|
|
44056
44273
|
] }) : /* @__PURE__ */ jsxs28(Fragment8, { children: [
|
|
44274
|
+
slidingScale ? /* @__PURE__ */ jsx42(
|
|
44275
|
+
SlidingScaleAmountField,
|
|
44276
|
+
{
|
|
44277
|
+
slidingScale,
|
|
44278
|
+
currency: eventPricingCurrency ?? DEFAULT_EVENT_CURRENCY2,
|
|
44279
|
+
value: selectedSlidingAmountInput,
|
|
44280
|
+
message: slidingScaleSelectionMessage,
|
|
44281
|
+
onChange: onSlidingAmountChange
|
|
44282
|
+
}
|
|
44283
|
+
) : null,
|
|
44057
44284
|
/* @__PURE__ */ jsx42("h3", { className: "er-title", children: canJoinWaitlist ? "How many waitlist spots?" : "How many tickets?" }),
|
|
44058
44285
|
/* @__PURE__ */ jsxs28("div", { className: "er-ticket-counter-group", children: [
|
|
44059
44286
|
/* @__PURE__ */ jsx42(
|
|
@@ -45068,6 +45295,10 @@ function EventRegistrationWizardContent(props2) {
|
|
|
45068
45295
|
maxTickets: wizard.maxTicketsNum,
|
|
45069
45296
|
selectedTicketTypeId: wizard.selectedTicketTypeId,
|
|
45070
45297
|
onTicketTypeChange: wizard.setSelectedTicketTypeId,
|
|
45298
|
+
slidingScale: wizard.selectedEventSlidingScale,
|
|
45299
|
+
selectedSlidingAmountInput: wizard.selectedSlidingAmountInput,
|
|
45300
|
+
slidingScaleSelectionMessage: wizard.slidingScaleSelectionMessage,
|
|
45301
|
+
onSlidingAmountChange: wizard.setSelectedSlidingAmountInput,
|
|
45071
45302
|
onTicketsChange: wizard.setTicketsCount
|
|
45072
45303
|
}
|
|
45073
45304
|
)
|
|
@@ -45284,7 +45515,7 @@ function EventRegistrationSummaryBar(props2) {
|
|
|
45284
45515
|
const summaryTimeZone = wizard.occurrenceContext?.timeZone ?? summaryEvent?.timeZone ?? null;
|
|
45285
45516
|
const occurrenceOverrideTitle = wizard.occurrenceContext?.overrides?.title;
|
|
45286
45517
|
const summaryTitle = occurrenceOverrideTitle ?? summaryEvent?.title ?? "";
|
|
45287
|
-
const summaryPrice = wizard.selectedTicketType?.priceAmount ?? wizard.eligibility?.price ?? (summaryEvent ? publicEventScalarPrice(summaryEvent.pricing) : null) ?? 0;
|
|
45518
|
+
const summaryPrice = wizard.selectedTicketType?.priceAmount ?? wizard.eligibility?.price ?? (wizard.selectedEventSlidingScale ? wizard.selectedSlidingAmount : null) ?? (summaryEvent ? publicEventScalarPrice(summaryEvent.pricing) : null) ?? 0;
|
|
45288
45519
|
const summaryCurrency = (summaryEvent ? publicEventPricingCurrency(summaryEvent.pricing) : null) ?? DEFAULT_EVENT_CURRENCY2;
|
|
45289
45520
|
const teamMemberNames = (summaryEvent?.teamMembers ?? []).map((teamMember) => teamMember.name).filter(Boolean);
|
|
45290
45521
|
const subtotalCents = Math.max(0, summaryPrice * wizard.ticketsCount);
|
|
@@ -45735,6 +45966,7 @@ function useEventRegistrationSubmit(options) {
|
|
|
45735
45966
|
occurrenceId: submitOccurrenceId,
|
|
45736
45967
|
attendanceMode: options.selectedAttendanceMode ?? void 0,
|
|
45737
45968
|
ticketTypeId: options.selectedTicketTypeId ?? void 0,
|
|
45969
|
+
selectedSlidingAmount: options.selectedSlidingAmount ?? void 0,
|
|
45738
45970
|
email: options.formData.email.trim().toLowerCase(),
|
|
45739
45971
|
name: options.formData.name.trim(),
|
|
45740
45972
|
ticketsCount: options.ticketsCount,
|
|
@@ -45844,6 +46076,35 @@ var init_useEventRegistrationSubmit = __esm({
|
|
|
45844
46076
|
|
|
45845
46077
|
// ../blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.ts
|
|
45846
46078
|
import { useCallback as useCallback8, useEffect as useEffect15, useMemo as useMemo10, useReducer as useReducer10, useState as useState7 } from "react";
|
|
46079
|
+
function parseCurrencyInputToCents(value) {
|
|
46080
|
+
const trimmed = value.trim();
|
|
46081
|
+
if (!trimmed) return null;
|
|
46082
|
+
const amount = Number(trimmed);
|
|
46083
|
+
if (!Number.isFinite(amount) || amount < 0) return null;
|
|
46084
|
+
return Math.round(amount * 100);
|
|
46085
|
+
}
|
|
46086
|
+
function formatCentsAsCurrencyInput(amount) {
|
|
46087
|
+
const major = amount / 100;
|
|
46088
|
+
return Number.isInteger(major) ? String(major) : major.toFixed(2);
|
|
46089
|
+
}
|
|
46090
|
+
function getSlidingScaleForEvent(event) {
|
|
46091
|
+
const pricing = event ? resolveRuntimeEventPricing(event) : null;
|
|
46092
|
+
return pricing?.kind === "sliding_scale" ? {
|
|
46093
|
+
minAmount: pricing.minAmount,
|
|
46094
|
+
maxAmount: pricing.maxAmount,
|
|
46095
|
+
suggestedAmount: pricing.suggestedAmount
|
|
46096
|
+
} : null;
|
|
46097
|
+
}
|
|
46098
|
+
function getSlidingScaleSelectionMessage(input) {
|
|
46099
|
+
if (!input.slidingScale) return null;
|
|
46100
|
+
if (input.selectedAmount === null) {
|
|
46101
|
+
return "Choose an amount to continue.";
|
|
46102
|
+
}
|
|
46103
|
+
if (input.selectedAmount < input.slidingScale.minAmount || input.selectedAmount > input.slidingScale.maxAmount) {
|
|
46104
|
+
return "Choose an amount within the sliding scale.";
|
|
46105
|
+
}
|
|
46106
|
+
return null;
|
|
46107
|
+
}
|
|
45847
46108
|
function useEventRegistrationWizard(options) {
|
|
45848
46109
|
const api = useBlockApi();
|
|
45849
46110
|
const registrationEvents = useMemo10(
|
|
@@ -45888,6 +46149,10 @@ function useEventRegistrationWizard(options) {
|
|
|
45888
46149
|
preSelectedEvent?.deliveryMode === "online" ? "online" : preSelectedEvent?.deliveryMode === "in_person" ? "in_person" : null
|
|
45889
46150
|
);
|
|
45890
46151
|
const [selectedTicketTypeId, setSelectedTicketTypeId] = useState7(null);
|
|
46152
|
+
const [selectedSlidingAmountInput, setSelectedSlidingAmountInput] = useState7(() => {
|
|
46153
|
+
const slidingScale = getSlidingScaleForEvent(preSelectedEvent ?? null);
|
|
46154
|
+
return slidingScale?.suggestedAmount !== null && slidingScale?.suggestedAmount !== void 0 ? formatCentsAsCurrencyInput(slidingScale.suggestedAmount) : "";
|
|
46155
|
+
});
|
|
45891
46156
|
const [registrationResult, setRegistrationResult] = useState7(null);
|
|
45892
46157
|
const [errorMessage, setErrorMessage] = useState7("");
|
|
45893
46158
|
const [altchaSolution, setAltchaSolution] = useState7(null);
|
|
@@ -45924,6 +46189,7 @@ function useEventRegistrationWizard(options) {
|
|
|
45924
46189
|
occurrenceId,
|
|
45925
46190
|
attendanceMode: selectedAttendanceMode,
|
|
45926
46191
|
ticketTypeId: selectedTicketTypeId,
|
|
46192
|
+
selectedSlidingAmount: parseCurrencyInputToCents(selectedSlidingAmountInput),
|
|
45927
46193
|
email: formData.email,
|
|
45928
46194
|
ticketsCount
|
|
45929
46195
|
});
|
|
@@ -46059,6 +46325,18 @@ function useEventRegistrationWizard(options) {
|
|
|
46059
46325
|
}),
|
|
46060
46326
|
[selectedAttendanceMode, selectedEvent, preSelectedEvent, eligibility, selectedTicketTypeId]
|
|
46061
46327
|
);
|
|
46328
|
+
const selectedSlidingAmount = useMemo10(
|
|
46329
|
+
() => parseCurrencyInputToCents(selectedSlidingAmountInput),
|
|
46330
|
+
[selectedSlidingAmountInput]
|
|
46331
|
+
);
|
|
46332
|
+
const selectedEventSlidingScale = useMemo10(
|
|
46333
|
+
() => getSlidingScaleForEvent(selectedEvent ?? preSelectedEvent),
|
|
46334
|
+
[selectedEvent, preSelectedEvent]
|
|
46335
|
+
);
|
|
46336
|
+
const slidingScaleSelectionMessage = getSlidingScaleSelectionMessage({
|
|
46337
|
+
slidingScale: selectedEventSlidingScale,
|
|
46338
|
+
selectedAmount: selectedSlidingAmount
|
|
46339
|
+
});
|
|
46062
46340
|
const ticketTypeSelectionRequired = useMemo10(() => {
|
|
46063
46341
|
const event = selectedEvent ?? preSelectedEvent;
|
|
46064
46342
|
if (!event || publicEventPricingMode(resolveRuntimeEventPricing(event)) !== "ticket_types") {
|
|
@@ -46127,12 +46405,24 @@ function useEventRegistrationWizard(options) {
|
|
|
46127
46405
|
setGuestSectionShake(false);
|
|
46128
46406
|
};
|
|
46129
46407
|
const eventRequiresPayment = useMemo10(
|
|
46130
|
-
() =>
|
|
46408
|
+
() => {
|
|
46409
|
+
if (selectedEventSlidingScale) {
|
|
46410
|
+
return (selectedSlidingAmount ?? 0) > 0;
|
|
46411
|
+
}
|
|
46412
|
+
return resolveEventRequiresPayment({
|
|
46413
|
+
eligibility,
|
|
46414
|
+
selectedTicketType,
|
|
46415
|
+
event: selectedEvent ?? preSelectedEvent
|
|
46416
|
+
});
|
|
46417
|
+
},
|
|
46418
|
+
[
|
|
46131
46419
|
eligibility,
|
|
46132
46420
|
selectedTicketType,
|
|
46133
|
-
|
|
46134
|
-
|
|
46135
|
-
|
|
46421
|
+
selectedEvent,
|
|
46422
|
+
preSelectedEvent,
|
|
46423
|
+
selectedEventSlidingScale,
|
|
46424
|
+
selectedSlidingAmount
|
|
46425
|
+
]
|
|
46136
46426
|
);
|
|
46137
46427
|
const handleDetailsComplete = async () => {
|
|
46138
46428
|
if (ticketTypeSelectionRequired && !hasValidSelectedTicketType) {
|
|
@@ -46141,6 +46431,11 @@ function useEventRegistrationWizard(options) {
|
|
|
46141
46431
|
setStep("error");
|
|
46142
46432
|
return { ok: false, reason: "blocked", message };
|
|
46143
46433
|
}
|
|
46434
|
+
if (slidingScaleSelectionMessage) {
|
|
46435
|
+
setErrorMessage(slidingScaleSelectionMessage);
|
|
46436
|
+
setStep("error");
|
|
46437
|
+
return { ok: false, reason: "blocked", message: slidingScaleSelectionMessage };
|
|
46438
|
+
}
|
|
46144
46439
|
if (!validateForm()) {
|
|
46145
46440
|
setGuestSectionShake(true);
|
|
46146
46441
|
return {
|
|
@@ -46225,9 +46520,18 @@ function useEventRegistrationWizard(options) {
|
|
|
46225
46520
|
const discountSubtotalCents = useMemo10(() => {
|
|
46226
46521
|
if (discountContext?.type !== "event") return void 0;
|
|
46227
46522
|
const event = selectedEvent ?? preSelectedEvent;
|
|
46228
|
-
const eventPriceCents = selectedTicketType?.priceAmount ?? eligibility?.price ?? (event ? publicEventScalarPrice(resolveRuntimeEventPricing(event)) : null) ?? 0;
|
|
46523
|
+
const eventPriceCents = selectedTicketType?.priceAmount ?? eligibility?.price ?? (selectedEventSlidingScale ? selectedSlidingAmount : null) ?? (event ? publicEventScalarPrice(resolveRuntimeEventPricing(event)) : null) ?? 0;
|
|
46229
46524
|
return Math.max(0, eventPriceCents * ticketsCount);
|
|
46230
|
-
}, [
|
|
46525
|
+
}, [
|
|
46526
|
+
discountContext,
|
|
46527
|
+
selectedTicketType,
|
|
46528
|
+
eligibility,
|
|
46529
|
+
selectedEvent,
|
|
46530
|
+
preSelectedEvent,
|
|
46531
|
+
selectedEventSlidingScale,
|
|
46532
|
+
selectedSlidingAmount,
|
|
46533
|
+
ticketsCount
|
|
46534
|
+
]);
|
|
46231
46535
|
const discountUi = useDiscountCodeUi({ api, discountContext, subtotalCents: discountSubtotalCents });
|
|
46232
46536
|
const selectionMethod = paymentSelection.method;
|
|
46233
46537
|
const shouldShowDiscountToggle = discountContext !== null && discountUi.manualCodeEntryAllowed && (selectionMethod === "stripe" || selectionMethod === "pass_bundle" || selectionMethod === "membership_bundle");
|
|
@@ -46236,6 +46540,7 @@ function useEventRegistrationWizard(options) {
|
|
|
46236
46540
|
registrationTarget,
|
|
46237
46541
|
selectedAttendanceMode,
|
|
46238
46542
|
selectedTicketTypeId,
|
|
46543
|
+
selectedSlidingAmount,
|
|
46239
46544
|
ticketsCount,
|
|
46240
46545
|
formData,
|
|
46241
46546
|
altchaSolution,
|
|
@@ -46250,6 +46555,10 @@ function useEventRegistrationWizard(options) {
|
|
|
46250
46555
|
});
|
|
46251
46556
|
const handleEventSelect = (event) => {
|
|
46252
46557
|
setSelectedEvent(event);
|
|
46558
|
+
const slidingScale = getSlidingScaleForEvent(event);
|
|
46559
|
+
setSelectedSlidingAmountInput(
|
|
46560
|
+
slidingScale?.suggestedAmount !== null && slidingScale?.suggestedAmount !== void 0 ? formatCentsAsCurrencyInput(slidingScale.suggestedAmount) : ""
|
|
46561
|
+
);
|
|
46253
46562
|
setSelectedAttendanceMode(
|
|
46254
46563
|
(event.deliveryMode ?? "in_person") === "hybrid" ? null : (event.deliveryMode ?? "in_person") === "online" ? "online" : "in_person"
|
|
46255
46564
|
);
|
|
@@ -46259,6 +46568,7 @@ function useEventRegistrationWizard(options) {
|
|
|
46259
46568
|
const handleRetry = () => {
|
|
46260
46569
|
dispatchFlow({ type: "reset", hasPreSelectedContext });
|
|
46261
46570
|
setSelectedTicketTypeId(null);
|
|
46571
|
+
setSelectedSlidingAmountInput("");
|
|
46262
46572
|
setSelectedAttendanceMode(
|
|
46263
46573
|
preSelectedEvent?.deliveryMode === "online" ? "online" : preSelectedEvent?.deliveryMode === "in_person" ? "in_person" : null
|
|
46264
46574
|
);
|
|
@@ -46295,6 +46605,11 @@ function useEventRegistrationWizard(options) {
|
|
|
46295
46605
|
setSelectedAttendanceMode,
|
|
46296
46606
|
selectedTicketTypeId,
|
|
46297
46607
|
setSelectedTicketTypeId,
|
|
46608
|
+
selectedSlidingAmountInput,
|
|
46609
|
+
setSelectedSlidingAmountInput,
|
|
46610
|
+
selectedSlidingAmount,
|
|
46611
|
+
selectedEventSlidingScale,
|
|
46612
|
+
slidingScaleSelectionMessage,
|
|
46298
46613
|
selectedTicketType,
|
|
46299
46614
|
visibleTicketTypes,
|
|
46300
46615
|
ticketTypeSelectionRequired,
|
|
@@ -47252,7 +47567,9 @@ function getSelectableCoursePricingOptionsForNow(course, now) {
|
|
|
47252
47567
|
return left.name.localeCompare(right.name);
|
|
47253
47568
|
});
|
|
47254
47569
|
}
|
|
47255
|
-
function resolveCoursePricingState(course, selectedPricingOptionId, nowInput = {}) {
|
|
47570
|
+
function resolveCoursePricingState(course, selectedPricingOptionId, selectedSlidingAmountOrNowInput, nowInput = {}) {
|
|
47571
|
+
const selectedSlidingAmount = typeof selectedSlidingAmountOrNowInput === "number" || selectedSlidingAmountOrNowInput === null ? selectedSlidingAmountOrNowInput : null;
|
|
47572
|
+
const effectiveNowInput = typeof selectedSlidingAmountOrNowInput === "object" && selectedSlidingAmountOrNowInput !== null ? selectedSlidingAmountOrNowInput : nowInput;
|
|
47256
47573
|
const currency = course.pricing?.currency ?? course.currency;
|
|
47257
47574
|
if (!course.pricing) {
|
|
47258
47575
|
const legacyAmount = course.priceCents ?? 0;
|
|
@@ -47262,6 +47579,8 @@ function resolveCoursePricingState(course, selectedPricingOptionId, nowInput = {
|
|
|
47262
47579
|
selectableOptions: [],
|
|
47263
47580
|
requiresSelection: false,
|
|
47264
47581
|
selectedOption: null,
|
|
47582
|
+
slidingScale: null,
|
|
47583
|
+
selectedSlidingAmount: null,
|
|
47265
47584
|
selectedPriceAmount: legacyAmount,
|
|
47266
47585
|
selectedRequiresPayment: legacyAmount > 0,
|
|
47267
47586
|
hasPaidSelection: legacyAmount > 0,
|
|
@@ -47276,6 +47595,8 @@ function resolveCoursePricingState(course, selectedPricingOptionId, nowInput = {
|
|
|
47276
47595
|
selectableOptions: [],
|
|
47277
47596
|
requiresSelection: false,
|
|
47278
47597
|
selectedOption: null,
|
|
47598
|
+
slidingScale: null,
|
|
47599
|
+
selectedSlidingAmount: null,
|
|
47279
47600
|
selectedPriceAmount: 0,
|
|
47280
47601
|
selectedRequiresPayment: false,
|
|
47281
47602
|
hasPaidSelection: false,
|
|
@@ -47289,6 +47610,8 @@ function resolveCoursePricingState(course, selectedPricingOptionId, nowInput = {
|
|
|
47289
47610
|
selectableOptions: [],
|
|
47290
47611
|
requiresSelection: false,
|
|
47291
47612
|
selectedOption: null,
|
|
47613
|
+
slidingScale: null,
|
|
47614
|
+
selectedSlidingAmount: null,
|
|
47292
47615
|
selectedPriceAmount: amount,
|
|
47293
47616
|
selectedRequiresPayment: amount > 0,
|
|
47294
47617
|
hasPaidSelection: amount > 0,
|
|
@@ -47298,7 +47621,7 @@ function resolveCoursePricingState(course, selectedPricingOptionId, nowInput = {
|
|
|
47298
47621
|
case "tiered": {
|
|
47299
47622
|
const selectableOptions = getSelectableCoursePricingOptionsForNow(
|
|
47300
47623
|
course,
|
|
47301
|
-
resolvePlanningDateInput(
|
|
47624
|
+
resolvePlanningDateInput(effectiveNowInput)
|
|
47302
47625
|
);
|
|
47303
47626
|
const selectedOption = (selectedPricingOptionId ? selectableOptions.find((option) => option.id === selectedPricingOptionId) : null) ?? (selectableOptions.length === 1 ? selectableOptions[0] ?? null : null);
|
|
47304
47627
|
const lowestAmount = selectableOptions.reduce((lowest, option) => {
|
|
@@ -47314,12 +47637,51 @@ function resolveCoursePricingState(course, selectedPricingOptionId, nowInput = {
|
|
|
47314
47637
|
selectableOptions,
|
|
47315
47638
|
requiresSelection: selectableOptions.length > 1,
|
|
47316
47639
|
selectedOption,
|
|
47640
|
+
slidingScale: null,
|
|
47641
|
+
selectedSlidingAmount: null,
|
|
47317
47642
|
selectedPriceAmount: selectedOption?.priceAmount ?? null,
|
|
47318
47643
|
selectedRequiresPayment: (selectedOption?.priceAmount ?? 0) > 0,
|
|
47319
47644
|
hasPaidSelection: selectableOptions.some((option) => option.priceAmount > 0),
|
|
47320
47645
|
hasFreeSelection: selectableOptions.some((option) => option.priceAmount === 0)
|
|
47321
47646
|
};
|
|
47322
47647
|
}
|
|
47648
|
+
case "sliding_scale": {
|
|
47649
|
+
const minAmount = course.pricing.slidingMinAmount ?? null;
|
|
47650
|
+
const maxAmount = course.pricing.slidingMaxAmount ?? null;
|
|
47651
|
+
if (minAmount === null || maxAmount === null || minAmount < 0 || maxAmount < minAmount) {
|
|
47652
|
+
return {
|
|
47653
|
+
currency,
|
|
47654
|
+
display: { kind: "unavailable", currency },
|
|
47655
|
+
selectableOptions: [],
|
|
47656
|
+
requiresSelection: true,
|
|
47657
|
+
selectedOption: null,
|
|
47658
|
+
slidingScale: null,
|
|
47659
|
+
selectedSlidingAmount: null,
|
|
47660
|
+
selectedPriceAmount: null,
|
|
47661
|
+
selectedRequiresPayment: false,
|
|
47662
|
+
hasPaidSelection: false,
|
|
47663
|
+
hasFreeSelection: false
|
|
47664
|
+
};
|
|
47665
|
+
}
|
|
47666
|
+
const normalizedSelectedAmount = typeof selectedSlidingAmount === "number" && Number.isFinite(selectedSlidingAmount) ? selectedSlidingAmount : null;
|
|
47667
|
+
return {
|
|
47668
|
+
currency,
|
|
47669
|
+
display: { kind: "range", minAmount, maxAmount, currency },
|
|
47670
|
+
selectableOptions: [],
|
|
47671
|
+
requiresSelection: normalizedSelectedAmount === null,
|
|
47672
|
+
selectedOption: null,
|
|
47673
|
+
slidingScale: {
|
|
47674
|
+
minAmount,
|
|
47675
|
+
maxAmount,
|
|
47676
|
+
suggestedAmount: course.pricing.slidingSuggestedAmount ?? null
|
|
47677
|
+
},
|
|
47678
|
+
selectedSlidingAmount: normalizedSelectedAmount,
|
|
47679
|
+
selectedPriceAmount: normalizedSelectedAmount,
|
|
47680
|
+
selectedRequiresPayment: (normalizedSelectedAmount ?? 0) > 0,
|
|
47681
|
+
hasPaidSelection: maxAmount > 0,
|
|
47682
|
+
hasFreeSelection: minAmount === 0
|
|
47683
|
+
};
|
|
47684
|
+
}
|
|
47323
47685
|
}
|
|
47324
47686
|
}
|
|
47325
47687
|
function formatCoursePriceDisplay(display, locale) {
|
|
@@ -51511,6 +51873,44 @@ function CoursePricingSelector({
|
|
|
51511
51873
|
)
|
|
51512
51874
|
] });
|
|
51513
51875
|
}
|
|
51876
|
+
function CourseSlidingScaleInput({
|
|
51877
|
+
pricing,
|
|
51878
|
+
value,
|
|
51879
|
+
onChange
|
|
51880
|
+
}) {
|
|
51881
|
+
const slidingScale = pricing.slidingScale;
|
|
51882
|
+
if (!slidingScale) {
|
|
51883
|
+
return null;
|
|
51884
|
+
}
|
|
51885
|
+
const minLabel = formatCoursePriceAmount(slidingScale.minAmount, pricing.currency);
|
|
51886
|
+
const maxLabel = formatCoursePriceAmount(slidingScale.maxAmount, pricing.currency);
|
|
51887
|
+
const suggestedLabel = slidingScale.suggestedAmount !== null ? formatCoursePriceAmount(slidingScale.suggestedAmount, pricing.currency) : null;
|
|
51888
|
+
return /* @__PURE__ */ jsxs65("div", { className: "cr-form__field", children: [
|
|
51889
|
+
/* @__PURE__ */ jsx95("label", { htmlFor: "cr-sliding-amount", className: "cr-form__label", children: "Amount" }),
|
|
51890
|
+
/* @__PURE__ */ jsx95(
|
|
51891
|
+
"input",
|
|
51892
|
+
{
|
|
51893
|
+
id: "cr-sliding-amount",
|
|
51894
|
+
type: "number",
|
|
51895
|
+
min: slidingScale.minAmount / 100,
|
|
51896
|
+
max: slidingScale.maxAmount / 100,
|
|
51897
|
+
step: "0.01",
|
|
51898
|
+
inputMode: "decimal",
|
|
51899
|
+
className: "cr-form__input",
|
|
51900
|
+
value,
|
|
51901
|
+
onChange: (event) => onChange(event.target.value)
|
|
51902
|
+
}
|
|
51903
|
+
),
|
|
51904
|
+
/* @__PURE__ */ jsxs65("p", { className: "cr-text cr-text--muted", children: [
|
|
51905
|
+
"Choose between ",
|
|
51906
|
+
minLabel,
|
|
51907
|
+
" and ",
|
|
51908
|
+
maxLabel,
|
|
51909
|
+
suggestedLabel ? `; suggested ${suggestedLabel}` : "",
|
|
51910
|
+
"."
|
|
51911
|
+
] })
|
|
51912
|
+
] });
|
|
51913
|
+
}
|
|
51514
51914
|
function EnrollmentForm({ formData, errors, onChange, isEmailLocked, isLoading, onLogout }) {
|
|
51515
51915
|
const nameErrorId = "cr-name-error";
|
|
51516
51916
|
const emailErrorId = "cr-email-error";
|
|
@@ -51606,6 +52006,17 @@ var init_components2 = __esm({
|
|
|
51606
52006
|
|
|
51607
52007
|
// ../blocks/src/system/runtime/nodes/course-registration/useCourseRegistrationWizard.ts
|
|
51608
52008
|
import { useEffect as useEffect25, useMemo as useMemo19, useState as useState18 } from "react";
|
|
52009
|
+
function parseCurrencyInputToCents2(value) {
|
|
52010
|
+
const trimmed = value.trim();
|
|
52011
|
+
if (!trimmed) return null;
|
|
52012
|
+
const amount = Number(trimmed);
|
|
52013
|
+
if (!Number.isFinite(amount) || amount < 0) return null;
|
|
52014
|
+
return Math.round(amount * 100);
|
|
52015
|
+
}
|
|
52016
|
+
function formatCentsAsCurrencyInput2(amount) {
|
|
52017
|
+
const major = amount / 100;
|
|
52018
|
+
return Number.isInteger(major) ? String(major) : major.toFixed(2);
|
|
52019
|
+
}
|
|
51609
52020
|
function shouldFetchCourseEligibility(course, hasPaidSelection, portalAuthState, hasWaitlistClaimToken) {
|
|
51610
52021
|
if (!course || portalAuthState === "checking") return false;
|
|
51611
52022
|
if (hasWaitlistClaimToken) return false;
|
|
@@ -51623,12 +52034,27 @@ function getSessionIdFromUrl() {
|
|
|
51623
52034
|
}
|
|
51624
52035
|
function getMissingCoursePricingSelectionMessage(pricing) {
|
|
51625
52036
|
if (pricing?.requiresSelection && !pricing.selectedOption) {
|
|
52037
|
+
if (pricing.slidingScale) {
|
|
52038
|
+
return "Choose an amount to continue.";
|
|
52039
|
+
}
|
|
51626
52040
|
return "Choose a pricing option to continue.";
|
|
51627
52041
|
}
|
|
52042
|
+
if (pricing?.slidingScale && pricing.selectedSlidingAmount !== null && pricing.selectedSlidingAmount < pricing.slidingScale.minAmount) {
|
|
52043
|
+
return "Choose an amount within the sliding scale.";
|
|
52044
|
+
}
|
|
52045
|
+
if (pricing?.slidingScale && pricing.selectedSlidingAmount !== null && pricing.selectedSlidingAmount > pricing.slidingScale.maxAmount) {
|
|
52046
|
+
return "Choose an amount within the sliding scale.";
|
|
52047
|
+
}
|
|
51628
52048
|
return null;
|
|
51629
52049
|
}
|
|
51630
52050
|
function buildCoursePricingOptionPayload(pricing) {
|
|
51631
|
-
|
|
52051
|
+
if (pricing?.selectedOption) {
|
|
52052
|
+
return { pricingOptionId: pricing.selectedOption.id };
|
|
52053
|
+
}
|
|
52054
|
+
if (pricing?.slidingScale && pricing.selectedSlidingAmount !== null) {
|
|
52055
|
+
return { selectedSlidingAmount: pricing.selectedSlidingAmount };
|
|
52056
|
+
}
|
|
52057
|
+
return {};
|
|
51632
52058
|
}
|
|
51633
52059
|
function resolveHasCoursePayment(pricing) {
|
|
51634
52060
|
if (!pricing) {
|
|
@@ -51669,6 +52095,7 @@ function useCourseRegistrationWizard(props2) {
|
|
|
51669
52095
|
scopedCourses.length === 1 ? scopedCourses[0] ?? null : null
|
|
51670
52096
|
);
|
|
51671
52097
|
const [selectedPricingOptionId, setSelectedPricingOptionId] = useState18(null);
|
|
52098
|
+
const [selectedSlidingAmountInput, setSelectedSlidingAmountInput] = useState18("");
|
|
51672
52099
|
const [formData, setFormData] = useState18({
|
|
51673
52100
|
name: "",
|
|
51674
52101
|
email: "",
|
|
@@ -51690,8 +52117,12 @@ function useCourseRegistrationWizard(props2) {
|
|
|
51690
52117
|
const [bookingMode, setBookingMode] = useState18(null);
|
|
51691
52118
|
const waitlistClaim = useWaitlistClaim();
|
|
51692
52119
|
const selectedCoursePricing = useMemo19(
|
|
51693
|
-
() => selectedCourse ? resolveCoursePricingState(
|
|
51694
|
-
|
|
52120
|
+
() => selectedCourse ? resolveCoursePricingState(
|
|
52121
|
+
selectedCourse,
|
|
52122
|
+
selectedPricingOptionId,
|
|
52123
|
+
parseCurrencyInputToCents2(selectedSlidingAmountInput)
|
|
52124
|
+
) : null,
|
|
52125
|
+
[selectedCourse, selectedPricingOptionId, selectedSlidingAmountInput]
|
|
51695
52126
|
);
|
|
51696
52127
|
const missingPricingSelectionMessage = getMissingCoursePricingSelectionMessage(
|
|
51697
52128
|
selectedCoursePricing
|
|
@@ -51764,9 +52195,13 @@ function useCourseRegistrationWizard(props2) {
|
|
|
51764
52195
|
useEffect25(() => {
|
|
51765
52196
|
if (!selectedCourse) {
|
|
51766
52197
|
setSelectedPricingOptionId(null);
|
|
52198
|
+
setSelectedSlidingAmountInput("");
|
|
51767
52199
|
return;
|
|
51768
52200
|
}
|
|
51769
52201
|
const defaultPricing = resolveCoursePricingState(selectedCourse, null);
|
|
52202
|
+
setSelectedSlidingAmountInput(
|
|
52203
|
+
defaultPricing.slidingScale?.suggestedAmount !== null && defaultPricing.slidingScale?.suggestedAmount !== void 0 ? formatCentsAsCurrencyInput2(defaultPricing.slidingScale.suggestedAmount) : ""
|
|
52204
|
+
);
|
|
51770
52205
|
setSelectedPricingOptionId((previous) => {
|
|
51771
52206
|
if (previous && defaultPricing.selectableOptions.some((option) => option.id === previous)) {
|
|
51772
52207
|
return previous;
|
|
@@ -52141,6 +52576,8 @@ function useCourseRegistrationWizard(props2) {
|
|
|
52141
52576
|
selectedCourse,
|
|
52142
52577
|
selectedPricingOptionId,
|
|
52143
52578
|
setSelectedPricingOptionId,
|
|
52579
|
+
selectedSlidingAmountInput,
|
|
52580
|
+
setSelectedSlidingAmountInput,
|
|
52144
52581
|
selectedCoursePricing,
|
|
52145
52582
|
setSelectedCourse,
|
|
52146
52583
|
formData,
|
|
@@ -52206,6 +52643,19 @@ var init_useCourseRegistrationWizard = __esm({
|
|
|
52206
52643
|
|
|
52207
52644
|
// ../blocks/src/system/runtime/nodes/course-registration/CourseRegistrationWizard.tsx
|
|
52208
52645
|
import { Fragment as Fragment23, jsx as jsx96, jsxs as jsxs66 } from "react/jsx-runtime";
|
|
52646
|
+
function getCourseSlidingScaleMessage(pricing) {
|
|
52647
|
+
if (!pricing.slidingScale) {
|
|
52648
|
+
return null;
|
|
52649
|
+
}
|
|
52650
|
+
const selectedAmount = pricing.selectedSlidingAmount;
|
|
52651
|
+
if (selectedAmount === null) {
|
|
52652
|
+
return "Choose an amount to continue.";
|
|
52653
|
+
}
|
|
52654
|
+
if (selectedAmount < pricing.slidingScale.minAmount || selectedAmount > pricing.slidingScale.maxAmount) {
|
|
52655
|
+
return "Choose an amount within the sliding scale.";
|
|
52656
|
+
}
|
|
52657
|
+
return null;
|
|
52658
|
+
}
|
|
52209
52659
|
function CourseRegistrationWizard(props2) {
|
|
52210
52660
|
const {
|
|
52211
52661
|
showSessions = true,
|
|
@@ -52227,6 +52677,8 @@ function CourseRegistrationWizard(props2) {
|
|
|
52227
52677
|
selectedCourse,
|
|
52228
52678
|
selectedPricingOptionId,
|
|
52229
52679
|
setSelectedPricingOptionId,
|
|
52680
|
+
selectedSlidingAmountInput,
|
|
52681
|
+
setSelectedSlidingAmountInput,
|
|
52230
52682
|
selectedCoursePricing,
|
|
52231
52683
|
formData,
|
|
52232
52684
|
setFormData,
|
|
@@ -52301,7 +52753,8 @@ function CourseRegistrationWizard(props2) {
|
|
|
52301
52753
|
const canShowDiscountUi = !discountsAvailableLoading && paymentChoice === "checkout" && discountsAvailable && manualCodeEntryAllowed;
|
|
52302
52754
|
const courseSoldOut = waitlistClaim.claim === null && courseEligibility?.isFull === true && courseEligibility.canJoinWaitlist !== true;
|
|
52303
52755
|
const detailsSubmitLabel = courseEligibility?.canJoinWaitlist ? "Join waitlist" : buttonText;
|
|
52304
|
-
const pricingSelectionMissing = selectedCoursePricing?.requiresSelection === true && !selectedCoursePricing.selectedOption;
|
|
52756
|
+
const pricingSelectionMissing = selectedCoursePricing?.requiresSelection === true && !selectedCoursePricing.selectedOption && !selectedCoursePricing.slidingScale;
|
|
52757
|
+
const slidingScaleMessage = selectedCoursePricing ? getCourseSlidingScaleMessage(selectedCoursePricing) : null;
|
|
52305
52758
|
const pricingUnavailable = selectedCoursePricing?.display.kind === "unavailable";
|
|
52306
52759
|
const selectedCourseWithPricing = selectedCourse && selectedCoursePricing ? {
|
|
52307
52760
|
course: selectedCourse,
|
|
@@ -52394,6 +52847,14 @@ function CourseRegistrationWizard(props2) {
|
|
|
52394
52847
|
onSelect: setSelectedPricingOptionId
|
|
52395
52848
|
}
|
|
52396
52849
|
),
|
|
52850
|
+
/* @__PURE__ */ jsx96(
|
|
52851
|
+
CourseSlidingScaleInput,
|
|
52852
|
+
{
|
|
52853
|
+
pricing: selectedCourseWithPricing.pricing,
|
|
52854
|
+
value: selectedSlidingAmountInput,
|
|
52855
|
+
onChange: setSelectedSlidingAmountInput
|
|
52856
|
+
}
|
|
52857
|
+
),
|
|
52397
52858
|
showSpamProtection && /* @__PURE__ */ jsx96("div", { className: "cr-altcha", children: /* @__PURE__ */ jsx96(
|
|
52398
52859
|
AltchaWidget,
|
|
52399
52860
|
{
|
|
@@ -52431,7 +52892,7 @@ function CourseRegistrationWizard(props2) {
|
|
|
52431
52892
|
{
|
|
52432
52893
|
type: "submit",
|
|
52433
52894
|
className: buttonClass,
|
|
52434
|
-
disabled: courseSoldOut || eligibilityLoading || pricingSelectionMissing || pricingUnavailable,
|
|
52895
|
+
disabled: courseSoldOut || eligibilityLoading || pricingSelectionMissing || slidingScaleMessage !== null || pricingUnavailable,
|
|
52435
52896
|
children: eligibilityLoading ? "Checking availability\u2026" : courseSoldOut ? "Sold out" : detailsSubmitLabel
|
|
52436
52897
|
}
|
|
52437
52898
|
)
|
|
@@ -52441,6 +52902,7 @@ function CourseRegistrationWizard(props2) {
|
|
|
52441
52902
|
),
|
|
52442
52903
|
courseSoldOut && /* @__PURE__ */ jsx96("p", { className: "cr-text cr-text--muted", children: "This course is fully booked and there is no waitlist available right now." }),
|
|
52443
52904
|
pricingSelectionMissing && /* @__PURE__ */ jsx96("p", { className: "cr-text cr-text--muted", children: "Choose a pricing option to continue." }),
|
|
52905
|
+
slidingScaleMessage && /* @__PURE__ */ jsx96("p", { className: "cr-text cr-text--muted", children: slidingScaleMessage }),
|
|
52444
52906
|
pricingUnavailable && /* @__PURE__ */ jsx96("p", { className: "cr-text cr-text--muted", children: "Pricing is not available for this course right now." }),
|
|
52445
52907
|
eligibilityError && /* @__PURE__ */ jsx96("p", { className: "cr-text cr-text--error", children: eligibilityError })
|
|
52446
52908
|
] })
|
|
@@ -56751,6 +57213,21 @@ function fieldPlanToZod(plan, options = {}) {
|
|
|
56751
57213
|
}
|
|
56752
57214
|
});
|
|
56753
57215
|
}
|
|
57216
|
+
function fieldPresenceForPlan(plan) {
|
|
57217
|
+
return plan.required ? { kind: "required" } : { kind: "optional" };
|
|
57218
|
+
}
|
|
57219
|
+
function fieldPlanToObjectPropertyZod(plan, options = {}) {
|
|
57220
|
+
const schema = fieldPlanToZod(plan, options);
|
|
57221
|
+
const presence = fieldPresenceForPlan(plan);
|
|
57222
|
+
switch (presence.kind) {
|
|
57223
|
+
case "required":
|
|
57224
|
+
return schema;
|
|
57225
|
+
case "optional":
|
|
57226
|
+
return schema.optional();
|
|
57227
|
+
default:
|
|
57228
|
+
return assertNever7(presence);
|
|
57229
|
+
}
|
|
57230
|
+
}
|
|
56754
57231
|
function addFieldIssueToZodContext(zodCtx, validationIssue, rootPath) {
|
|
56755
57232
|
const message = fieldIssueToMessage(validationIssue);
|
|
56756
57233
|
const path = relativeZodIssuePath(validationIssue.path, rootPath);
|
|
@@ -56963,7 +57440,7 @@ function createManifestValidator(manifestOrFields, options = {}) {
|
|
|
56963
57440
|
function deriveContentZodFromPlans(plans, options) {
|
|
56964
57441
|
const shape = {};
|
|
56965
57442
|
for (const plan of plans) {
|
|
56966
|
-
shape[plan.fieldId] =
|
|
57443
|
+
shape[plan.fieldId] = fieldPlanToObjectPropertyZod(plan, options);
|
|
56967
57444
|
}
|
|
56968
57445
|
return z54.object(shape).catchall(z54.unknown()).passthrough();
|
|
56969
57446
|
}
|
|
@@ -69057,11 +69534,11 @@ function extractRouteUpdatedAt(candidate) {
|
|
|
69057
69534
|
}
|
|
69058
69535
|
function resolveRouteTargetForStage(routeIdValue, routes, stageInput) {
|
|
69059
69536
|
const routeId = typeof routeIdValue === "string" ? routeIdValue : null;
|
|
69060
|
-
if (
|
|
69537
|
+
if (routeId === null || routeId.length === 0 || routes === void 0) return null;
|
|
69061
69538
|
const routeEntry = routes[routeId];
|
|
69062
69539
|
if (!isRouteVisibleInStage(routeEntry, stageInput)) return null;
|
|
69063
69540
|
const href = extractRouteHref(routeEntry, stageInput);
|
|
69064
|
-
if (
|
|
69541
|
+
if (href === null) return null;
|
|
69065
69542
|
return {
|
|
69066
69543
|
routeId,
|
|
69067
69544
|
href,
|
|
@@ -97874,6 +98351,7 @@ var CANONICAL_REFUND_CONFLICT_CODES = [
|
|
|
97874
98351
|
];
|
|
97875
98352
|
var CANONICAL_REFUND_PLANNER_ERROR_CODES = [
|
|
97876
98353
|
...CANONICAL_REFUND_CONFLICT_CODES,
|
|
98354
|
+
"invalid_amount",
|
|
97877
98355
|
"amount_exceeds_remaining",
|
|
97878
98356
|
"pass_revoke_requires_full_refund",
|
|
97879
98357
|
"refund_failed"
|
|
@@ -97900,6 +98378,7 @@ var CUSTOMER_MEMBERSHIP_PAYMENT_REFUND_FAILED_CODES = [
|
|
|
97900
98378
|
// ../api/src/bookingRefundOutcomes.ts
|
|
97901
98379
|
var STANDARD_LINE_ITEM_REFUND_INVALID_CODES = [
|
|
97902
98380
|
"missing_amount",
|
|
98381
|
+
"invalid_amount",
|
|
97903
98382
|
"amount_exceeds_remaining",
|
|
97904
98383
|
"credit_refunds_disabled",
|
|
97905
98384
|
"missing_credit_customer",
|
|
@@ -97914,6 +98393,7 @@ var EVENT_ATTENDEE_REFUND_INVALID_CODES = [
|
|
|
97914
98393
|
var MANAGED_PRODUCT_REFUND_INVALID_CODES = [
|
|
97915
98394
|
"credit_refunds_disabled",
|
|
97916
98395
|
"not_refundable",
|
|
98396
|
+
"invalid_amount",
|
|
97917
98397
|
"amount_exceeds_remaining"
|
|
97918
98398
|
];
|
|
97919
98399
|
var CUSTOMER_PASS_REFUND_INVALID_CODES = [
|