@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
package/dist/client/client.mjs
CHANGED
|
@@ -23,12 +23,13 @@ var init_result = __esm({
|
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
// ../core/src/branded.ts
|
|
26
|
-
var unsafeAsMediaAssetId, unsafeAsStorageBucketName, unsafeAsPositiveByteCount, unsafeAsPositiveSeconds, unsafeAsFormId, unsafeAsPassId, unsafeAsCustomerPassId, unsafeAsAppointmentServiceId, unsafeAsAppointmentResourceId;
|
|
26
|
+
var unsafeAsMediaAssetId, unsafeAsStorageBucketName, unsafeAsStoragePath, unsafeAsPositiveByteCount, unsafeAsPositiveSeconds, unsafeAsFormId, unsafeAsPassId, unsafeAsCustomerPassId, unsafeAsAppointmentServiceId, unsafeAsAppointmentResourceId;
|
|
27
27
|
var init_branded = __esm({
|
|
28
28
|
"../core/src/branded.ts"() {
|
|
29
29
|
"use strict";
|
|
30
30
|
unsafeAsMediaAssetId = (id) => id;
|
|
31
31
|
unsafeAsStorageBucketName = (value) => value;
|
|
32
|
+
unsafeAsStoragePath = (value) => value;
|
|
32
33
|
unsafeAsPositiveByteCount = (value) => value;
|
|
33
34
|
unsafeAsPositiveSeconds = (value) => value;
|
|
34
35
|
unsafeAsFormId = (id) => id;
|
|
@@ -174,6 +175,7 @@ function publicEventPricingType(pricing) {
|
|
|
174
175
|
return "free";
|
|
175
176
|
case "single_paid":
|
|
176
177
|
case "ticket_types":
|
|
178
|
+
case "sliding_scale":
|
|
177
179
|
case "course":
|
|
178
180
|
return isFreePublicEventPriceDisplay(pricing.display) ? "free" : "paid";
|
|
179
181
|
case "external":
|
|
@@ -186,6 +188,7 @@ function publicEventPricingCurrency(pricing) {
|
|
|
186
188
|
case "free_registration":
|
|
187
189
|
case "single_paid":
|
|
188
190
|
case "ticket_types":
|
|
191
|
+
case "sliding_scale":
|
|
189
192
|
return pricing.currency;
|
|
190
193
|
case "course":
|
|
191
194
|
return pricing.display.display.currency;
|
|
@@ -203,6 +206,8 @@ function publicEventPricingMode(pricing) {
|
|
|
203
206
|
return "single";
|
|
204
207
|
case "ticket_types":
|
|
205
208
|
return "ticket_types";
|
|
209
|
+
case "sliding_scale":
|
|
210
|
+
return "sliding_scale";
|
|
206
211
|
case "drop_in":
|
|
207
212
|
case "course":
|
|
208
213
|
case "external":
|
|
@@ -236,6 +241,8 @@ function formatCoursePriceDisplayLabel(display, options) {
|
|
|
236
241
|
return `Course (${formatCurrencyAmount(display.amount, display.currency, options)})`;
|
|
237
242
|
case "from":
|
|
238
243
|
return `Course (From ${formatCurrencyAmount(display.amount, display.currency, options)})`;
|
|
244
|
+
case "range":
|
|
245
|
+
return `Course (${formatCurrencyAmount(display.minAmount, display.currency, options)} - ${formatCurrencyAmount(display.maxAmount, display.currency, options)})`;
|
|
239
246
|
default:
|
|
240
247
|
return assertNever(display);
|
|
241
248
|
}
|
|
@@ -379,10 +386,11 @@ function omitZeroAmountFutureRows(rows) {
|
|
|
379
386
|
if (rows.length <= 1) {
|
|
380
387
|
return rows;
|
|
381
388
|
}
|
|
382
|
-
const
|
|
383
|
-
if (
|
|
389
|
+
const firstRow = rows[0];
|
|
390
|
+
if (firstRow === void 0) {
|
|
384
391
|
return [];
|
|
385
392
|
}
|
|
393
|
+
const futureRows = rows.slice(1);
|
|
386
394
|
return [
|
|
387
395
|
firstRow,
|
|
388
396
|
...futureRows.filter((row) => row.amountCents > 0)
|
|
@@ -427,11 +435,11 @@ function isValidTimeZone(timeZone) {
|
|
|
427
435
|
}
|
|
428
436
|
function getSafeTimeZone(timeZone) {
|
|
429
437
|
const normalized = typeof timeZone === "string" ? timeZone.trim() : "";
|
|
430
|
-
return normalized && isValidTimeZone(normalized) ? normalized : FALLBACK_TIMEZONE;
|
|
438
|
+
return normalized.length > 0 && isValidTimeZone(normalized) ? normalized : FALLBACK_TIMEZONE;
|
|
431
439
|
}
|
|
432
440
|
function parseStrictBookingTimeZone(timeZone) {
|
|
433
441
|
const normalized = timeZone.trim();
|
|
434
|
-
if (
|
|
442
|
+
if (normalized.length === 0 || !isValidTimeZone(normalized)) {
|
|
435
443
|
return null;
|
|
436
444
|
}
|
|
437
445
|
return normalized;
|
|
@@ -517,7 +525,7 @@ function parseScheduledBookingDateTime(input) {
|
|
|
517
525
|
try {
|
|
518
526
|
const startsAt = toUtcIsoDateTimeString(input.startsAt);
|
|
519
527
|
const timeZone = parseStrictBookingTimeZone(input.timeZone);
|
|
520
|
-
if (
|
|
528
|
+
if (timeZone === null) {
|
|
521
529
|
return {
|
|
522
530
|
ok: false,
|
|
523
531
|
field: "timeZone",
|
|
@@ -656,7 +664,7 @@ function getBookingLocalDateKey(input) {
|
|
|
656
664
|
}
|
|
657
665
|
function parseBookingLocalDate(value) {
|
|
658
666
|
const match = LOCAL_DATE_PATTERN.exec(value.trim());
|
|
659
|
-
if (
|
|
667
|
+
if (match === null || match.groups === void 0) {
|
|
660
668
|
throw new Error(`Invalid booking date format: "${value}" (expected YYYY-MM-DD)`);
|
|
661
669
|
}
|
|
662
670
|
const year = Number(match.groups.year);
|
|
@@ -715,10 +723,10 @@ function normalizeLocationAddressText(value) {
|
|
|
715
723
|
return null;
|
|
716
724
|
}
|
|
717
725
|
const trimmed = value.trim();
|
|
718
|
-
return trimmed ? trimmed : null;
|
|
726
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
719
727
|
}
|
|
720
728
|
function hasLocationCoordinates(value) {
|
|
721
|
-
return typeof value
|
|
729
|
+
return value != null && typeof value.lat === "number" && typeof value.lng === "number";
|
|
722
730
|
}
|
|
723
731
|
function toLocationCoordinates(value) {
|
|
724
732
|
if (!hasLocationCoordinates(value)) {
|
|
@@ -735,6 +743,13 @@ var init_location = __esm({
|
|
|
735
743
|
}
|
|
736
744
|
});
|
|
737
745
|
|
|
746
|
+
// ../core/src/string.ts
|
|
747
|
+
var init_string = __esm({
|
|
748
|
+
"../core/src/string.ts"() {
|
|
749
|
+
"use strict";
|
|
750
|
+
}
|
|
751
|
+
});
|
|
752
|
+
|
|
738
753
|
// ../core/src/business-address.ts
|
|
739
754
|
var init_business_address = __esm({
|
|
740
755
|
"../core/src/business-address.ts"() {
|
|
@@ -875,13 +890,6 @@ var init_slug = __esm({
|
|
|
875
890
|
}
|
|
876
891
|
});
|
|
877
892
|
|
|
878
|
-
// ../core/src/string.ts
|
|
879
|
-
var init_string = __esm({
|
|
880
|
-
"../core/src/string.ts"() {
|
|
881
|
-
"use strict";
|
|
882
|
-
}
|
|
883
|
-
});
|
|
884
|
-
|
|
885
893
|
// ../core/src/uuid.ts
|
|
886
894
|
var init_uuid = __esm({
|
|
887
895
|
"../core/src/uuid.ts"() {
|
|
@@ -1038,9 +1046,20 @@ var init_types = __esm({
|
|
|
1038
1046
|
});
|
|
1039
1047
|
|
|
1040
1048
|
// ../media-core/src/fileSafety.ts
|
|
1049
|
+
function containsUnsafePathSegmentCharacter(value) {
|
|
1050
|
+
return value.includes("/") || value.includes("\\") || CONTROL_CHARACTER_PATTERN.test(value);
|
|
1051
|
+
}
|
|
1052
|
+
function isReservedPathSegment(value) {
|
|
1053
|
+
return value === "." || value === "..";
|
|
1054
|
+
}
|
|
1055
|
+
function isUnsafePathSegment(segment) {
|
|
1056
|
+
return segment.trim().length === 0 || segment !== segment.trim() || isReservedPathSegment(segment) || containsUnsafePathSegmentCharacter(segment);
|
|
1057
|
+
}
|
|
1058
|
+
var CONTROL_CHARACTER_PATTERN;
|
|
1041
1059
|
var init_fileSafety = __esm({
|
|
1042
1060
|
"../media-core/src/fileSafety.ts"() {
|
|
1043
1061
|
"use strict";
|
|
1062
|
+
CONTROL_CHARACTER_PATTERN = /[\u0000-\u001f\u007f]/u;
|
|
1044
1063
|
}
|
|
1045
1064
|
});
|
|
1046
1065
|
|
|
@@ -1080,11 +1099,21 @@ var init_fileDomain = __esm({
|
|
|
1080
1099
|
});
|
|
1081
1100
|
|
|
1082
1101
|
// ../media-core/src/fileStorage.ts
|
|
1102
|
+
function parseStoragePath(value) {
|
|
1103
|
+
return joinStoragePathSegments(value.split("/"));
|
|
1104
|
+
}
|
|
1105
|
+
function joinStoragePathSegments(segments) {
|
|
1106
|
+
if (segments.some(isUnsafePathSegment)) {
|
|
1107
|
+
return err("unsafe-path-segment");
|
|
1108
|
+
}
|
|
1109
|
+
return ok(unsafeAsStoragePath(segments.join("/")));
|
|
1110
|
+
}
|
|
1083
1111
|
var FILE_STORAGE_BUCKETS, PUBLIC_SITE_FILE_STORAGE_BUCKETS, PRIVATE_SITE_FILE_BUCKET_MIME_TYPES, TEMP_UPLOAD_BUCKET_MIME_TYPES;
|
|
1084
1112
|
var init_fileStorage = __esm({
|
|
1085
1113
|
"../media-core/src/fileStorage.ts"() {
|
|
1086
1114
|
"use strict";
|
|
1087
1115
|
init_src();
|
|
1116
|
+
init_fileSafety();
|
|
1088
1117
|
FILE_STORAGE_BUCKETS = {
|
|
1089
1118
|
publicSite: unsafeAsStorageBucketName("media"),
|
|
1090
1119
|
privateSite: unsafeAsStorageBucketName("site-files-private"),
|
|
@@ -1270,14 +1299,18 @@ var init_uploadVerificationContract = __esm({
|
|
|
1270
1299
|
});
|
|
1271
1300
|
|
|
1272
1301
|
// ../media-core/src/videoPrep.ts
|
|
1302
|
+
function unsafeAsPositiveVideoDurationSeconds(value) {
|
|
1303
|
+
return value;
|
|
1304
|
+
}
|
|
1273
1305
|
var VIDEO_PREP_LIMITS;
|
|
1274
1306
|
var init_videoPrep = __esm({
|
|
1275
1307
|
"../media-core/src/videoPrep.ts"() {
|
|
1276
1308
|
"use strict";
|
|
1309
|
+
init_src();
|
|
1277
1310
|
VIDEO_PREP_LIMITS = {
|
|
1278
|
-
maxRawByteCount: 500 * 1024 * 1024,
|
|
1279
|
-
inlineContentMaxDurationSeconds: 60,
|
|
1280
|
-
backgroundVideoMaxDurationSeconds: 30,
|
|
1311
|
+
maxRawByteCount: unsafeAsPositiveByteCount(500 * 1024 * 1024),
|
|
1312
|
+
inlineContentMaxDurationSeconds: unsafeAsPositiveVideoDurationSeconds(60),
|
|
1313
|
+
backgroundVideoMaxDurationSeconds: unsafeAsPositiveVideoDurationSeconds(30),
|
|
1281
1314
|
targetMaxDimensionPixels: 1080
|
|
1282
1315
|
};
|
|
1283
1316
|
}
|
|
@@ -1348,10 +1381,10 @@ var init_identifiers = __esm({
|
|
|
1348
1381
|
|
|
1349
1382
|
// ../media-core/src/url.ts
|
|
1350
1383
|
function isRelativeDirectImageStoragePath(storagePath) {
|
|
1351
|
-
return RELATIVE_STORAGE_PATH_PREFIXES.some((prefix) => storagePath.startsWith(prefix));
|
|
1384
|
+
return RELATIVE_STORAGE_PATH_PREFIXES.some((prefix) => storagePath.startsWith(prefix)) && parseStoragePath(storagePath).ok;
|
|
1352
1385
|
}
|
|
1353
1386
|
function isSiteScopedDirectImageStoragePath(storagePath) {
|
|
1354
|
-
return storagePath.startsWith("sites/");
|
|
1387
|
+
return storagePath.startsWith("sites/") && parseStoragePath(storagePath).ok;
|
|
1355
1388
|
}
|
|
1356
1389
|
function encodeStoragePath(storagePath) {
|
|
1357
1390
|
return storagePath.split("/").map((segment) => encodeURIComponent(segment)).join("/");
|
|
@@ -1432,6 +1465,7 @@ var DEFAULT_BASE_PATH, RELATIVE_STORAGE_PATH_PREFIXES, formatNumber, ORDER, getI
|
|
|
1432
1465
|
var init_url = __esm({
|
|
1433
1466
|
"../media-core/src/url.ts"() {
|
|
1434
1467
|
"use strict";
|
|
1468
|
+
init_fileStorage();
|
|
1435
1469
|
DEFAULT_BASE_PATH = "/api/img";
|
|
1436
1470
|
RELATIVE_STORAGE_PATH_PREFIXES = [
|
|
1437
1471
|
"originals/",
|
|
@@ -22918,9 +22952,12 @@ var init_schemas = __esm({
|
|
|
22918
22952
|
});
|
|
22919
22953
|
coursePricingSchema = z45.object({
|
|
22920
22954
|
bookingRequirement: z45.enum(["none", "required"]),
|
|
22921
|
-
pricingStrategy: z45.enum(["free", "single", "tiered"]),
|
|
22955
|
+
pricingStrategy: z45.enum(["free", "single", "tiered", "sliding_scale"]),
|
|
22922
22956
|
currency: z45.string(),
|
|
22923
22957
|
singlePriceAmount: z45.number().nullable(),
|
|
22958
|
+
slidingMinAmount: z45.number().nullable().optional(),
|
|
22959
|
+
slidingMaxAmount: z45.number().nullable().optional(),
|
|
22960
|
+
slidingSuggestedAmount: z45.number().nullable().optional(),
|
|
22924
22961
|
paymentTerms: blockBookingPaymentTermsSchema,
|
|
22925
22962
|
options: z45.array(coursePricingOptionSchema)
|
|
22926
22963
|
});
|
|
@@ -23085,6 +23122,19 @@ var init_schemas2 = __esm({
|
|
|
23085
23122
|
ticketTypes: z46.array(publicEventTicketTypeSchema),
|
|
23086
23123
|
display: publicEventTicketTypePriceDisplaySchema
|
|
23087
23124
|
}),
|
|
23125
|
+
z46.object({
|
|
23126
|
+
kind: z46.literal("sliding_scale"),
|
|
23127
|
+
minAmount: z46.number(),
|
|
23128
|
+
maxAmount: z46.number(),
|
|
23129
|
+
suggestedAmount: z46.number().nullable(),
|
|
23130
|
+
currency: z46.string(),
|
|
23131
|
+
display: z46.object({
|
|
23132
|
+
kind: z46.literal("range"),
|
|
23133
|
+
minAmount: z46.number(),
|
|
23134
|
+
maxAmount: z46.number(),
|
|
23135
|
+
currency: z46.string()
|
|
23136
|
+
})
|
|
23137
|
+
}),
|
|
23088
23138
|
z46.object({
|
|
23089
23139
|
kind: z46.literal("course"),
|
|
23090
23140
|
display: z46.object({ kind: z46.literal("course"), display: publicCoursePriceDisplaySchema })
|
|
@@ -23553,7 +23603,7 @@ function isRecord6(value) {
|
|
|
23553
23603
|
}
|
|
23554
23604
|
function isPublicEventPricing(value) {
|
|
23555
23605
|
if (!isRecord6(value) || typeof value.kind !== "string") return false;
|
|
23556
|
-
return value.kind === "drop_in" || value.kind === "free_registration" || value.kind === "single_paid" || value.kind === "ticket_types" || value.kind === "course" || value.kind === "external";
|
|
23606
|
+
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";
|
|
23557
23607
|
}
|
|
23558
23608
|
function isPublicEventTicketType(value) {
|
|
23559
23609
|
return isRecord6(value) && typeof value.id === "string";
|
|
@@ -24066,7 +24116,9 @@ function getSelectableCoursePricingOptionsForNow(course, now) {
|
|
|
24066
24116
|
return left.name.localeCompare(right.name);
|
|
24067
24117
|
});
|
|
24068
24118
|
}
|
|
24069
|
-
function resolveCoursePricingState(course, selectedPricingOptionId, nowInput = {}) {
|
|
24119
|
+
function resolveCoursePricingState(course, selectedPricingOptionId, selectedSlidingAmountOrNowInput, nowInput = {}) {
|
|
24120
|
+
const selectedSlidingAmount = typeof selectedSlidingAmountOrNowInput === "number" || selectedSlidingAmountOrNowInput === null ? selectedSlidingAmountOrNowInput : null;
|
|
24121
|
+
const effectiveNowInput = typeof selectedSlidingAmountOrNowInput === "object" && selectedSlidingAmountOrNowInput !== null ? selectedSlidingAmountOrNowInput : nowInput;
|
|
24070
24122
|
const currency = course.pricing?.currency ?? course.currency;
|
|
24071
24123
|
if (!course.pricing) {
|
|
24072
24124
|
const legacyAmount = course.priceCents ?? 0;
|
|
@@ -24076,6 +24128,8 @@ function resolveCoursePricingState(course, selectedPricingOptionId, nowInput = {
|
|
|
24076
24128
|
selectableOptions: [],
|
|
24077
24129
|
requiresSelection: false,
|
|
24078
24130
|
selectedOption: null,
|
|
24131
|
+
slidingScale: null,
|
|
24132
|
+
selectedSlidingAmount: null,
|
|
24079
24133
|
selectedPriceAmount: legacyAmount,
|
|
24080
24134
|
selectedRequiresPayment: legacyAmount > 0,
|
|
24081
24135
|
hasPaidSelection: legacyAmount > 0,
|
|
@@ -24090,6 +24144,8 @@ function resolveCoursePricingState(course, selectedPricingOptionId, nowInput = {
|
|
|
24090
24144
|
selectableOptions: [],
|
|
24091
24145
|
requiresSelection: false,
|
|
24092
24146
|
selectedOption: null,
|
|
24147
|
+
slidingScale: null,
|
|
24148
|
+
selectedSlidingAmount: null,
|
|
24093
24149
|
selectedPriceAmount: 0,
|
|
24094
24150
|
selectedRequiresPayment: false,
|
|
24095
24151
|
hasPaidSelection: false,
|
|
@@ -24103,6 +24159,8 @@ function resolveCoursePricingState(course, selectedPricingOptionId, nowInput = {
|
|
|
24103
24159
|
selectableOptions: [],
|
|
24104
24160
|
requiresSelection: false,
|
|
24105
24161
|
selectedOption: null,
|
|
24162
|
+
slidingScale: null,
|
|
24163
|
+
selectedSlidingAmount: null,
|
|
24106
24164
|
selectedPriceAmount: amount,
|
|
24107
24165
|
selectedRequiresPayment: amount > 0,
|
|
24108
24166
|
hasPaidSelection: amount > 0,
|
|
@@ -24112,7 +24170,7 @@ function resolveCoursePricingState(course, selectedPricingOptionId, nowInput = {
|
|
|
24112
24170
|
case "tiered": {
|
|
24113
24171
|
const selectableOptions = getSelectableCoursePricingOptionsForNow(
|
|
24114
24172
|
course,
|
|
24115
|
-
resolvePlanningDateInput(
|
|
24173
|
+
resolvePlanningDateInput(effectiveNowInput)
|
|
24116
24174
|
);
|
|
24117
24175
|
const selectedOption = (selectedPricingOptionId ? selectableOptions.find((option) => option.id === selectedPricingOptionId) : null) ?? (selectableOptions.length === 1 ? selectableOptions[0] ?? null : null);
|
|
24118
24176
|
const lowestAmount = selectableOptions.reduce((lowest, option) => {
|
|
@@ -24128,12 +24186,51 @@ function resolveCoursePricingState(course, selectedPricingOptionId, nowInput = {
|
|
|
24128
24186
|
selectableOptions,
|
|
24129
24187
|
requiresSelection: selectableOptions.length > 1,
|
|
24130
24188
|
selectedOption,
|
|
24189
|
+
slidingScale: null,
|
|
24190
|
+
selectedSlidingAmount: null,
|
|
24131
24191
|
selectedPriceAmount: selectedOption?.priceAmount ?? null,
|
|
24132
24192
|
selectedRequiresPayment: (selectedOption?.priceAmount ?? 0) > 0,
|
|
24133
24193
|
hasPaidSelection: selectableOptions.some((option) => option.priceAmount > 0),
|
|
24134
24194
|
hasFreeSelection: selectableOptions.some((option) => option.priceAmount === 0)
|
|
24135
24195
|
};
|
|
24136
24196
|
}
|
|
24197
|
+
case "sliding_scale": {
|
|
24198
|
+
const minAmount = course.pricing.slidingMinAmount ?? null;
|
|
24199
|
+
const maxAmount = course.pricing.slidingMaxAmount ?? null;
|
|
24200
|
+
if (minAmount === null || maxAmount === null || minAmount < 0 || maxAmount < minAmount) {
|
|
24201
|
+
return {
|
|
24202
|
+
currency,
|
|
24203
|
+
display: { kind: "unavailable", currency },
|
|
24204
|
+
selectableOptions: [],
|
|
24205
|
+
requiresSelection: true,
|
|
24206
|
+
selectedOption: null,
|
|
24207
|
+
slidingScale: null,
|
|
24208
|
+
selectedSlidingAmount: null,
|
|
24209
|
+
selectedPriceAmount: null,
|
|
24210
|
+
selectedRequiresPayment: false,
|
|
24211
|
+
hasPaidSelection: false,
|
|
24212
|
+
hasFreeSelection: false
|
|
24213
|
+
};
|
|
24214
|
+
}
|
|
24215
|
+
const normalizedSelectedAmount = typeof selectedSlidingAmount === "number" && Number.isFinite(selectedSlidingAmount) ? selectedSlidingAmount : null;
|
|
24216
|
+
return {
|
|
24217
|
+
currency,
|
|
24218
|
+
display: { kind: "range", minAmount, maxAmount, currency },
|
|
24219
|
+
selectableOptions: [],
|
|
24220
|
+
requiresSelection: normalizedSelectedAmount === null,
|
|
24221
|
+
selectedOption: null,
|
|
24222
|
+
slidingScale: {
|
|
24223
|
+
minAmount,
|
|
24224
|
+
maxAmount,
|
|
24225
|
+
suggestedAmount: course.pricing.slidingSuggestedAmount ?? null
|
|
24226
|
+
},
|
|
24227
|
+
selectedSlidingAmount: normalizedSelectedAmount,
|
|
24228
|
+
selectedPriceAmount: normalizedSelectedAmount,
|
|
24229
|
+
selectedRequiresPayment: (normalizedSelectedAmount ?? 0) > 0,
|
|
24230
|
+
hasPaidSelection: maxAmount > 0,
|
|
24231
|
+
hasFreeSelection: minAmount === 0
|
|
24232
|
+
};
|
|
24233
|
+
}
|
|
24137
24234
|
}
|
|
24138
24235
|
}
|
|
24139
24236
|
function formatCoursePriceDisplay(display, locale) {
|
|
@@ -24607,7 +24704,7 @@ function formatCalendarTitle(viewDate, view, days, monthNames = MONTH_NAMES) {
|
|
|
24607
24704
|
if (view === "week") {
|
|
24608
24705
|
const weekStart = days[0];
|
|
24609
24706
|
const weekEnd = days[6];
|
|
24610
|
-
if (
|
|
24707
|
+
if (weekStart === void 0 || weekEnd === void 0) {
|
|
24611
24708
|
return `${monthNames[viewDate.getMonth()] ?? ""} ${viewDate.getFullYear()}`;
|
|
24612
24709
|
}
|
|
24613
24710
|
const startMonth = monthNames[weekStart.getMonth()] ?? "";
|
|
@@ -24739,7 +24836,9 @@ function getLocalDateKey(isoTimestamp, timeZone) {
|
|
|
24739
24836
|
const year = parts.find((part) => part.type === "year")?.value;
|
|
24740
24837
|
const month = parts.find((part) => part.type === "month")?.value;
|
|
24741
24838
|
const day = parts.find((part) => part.type === "day")?.value;
|
|
24742
|
-
if (
|
|
24839
|
+
if (year === void 0 || year.length === 0) return null;
|
|
24840
|
+
if (month === void 0 || month.length === 0) return null;
|
|
24841
|
+
if (day === void 0 || day.length === 0) return null;
|
|
24743
24842
|
return `${year}-${month}-${day}`;
|
|
24744
24843
|
}
|
|
24745
24844
|
function isValidTimeZone2(timeZone) {
|
|
@@ -24996,7 +25095,7 @@ function enumerateDateKeys(startDateKey, endDateKey) {
|
|
|
24996
25095
|
}
|
|
24997
25096
|
function parseDateKey(dateKey) {
|
|
24998
25097
|
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(dateKey);
|
|
24999
|
-
if (
|
|
25098
|
+
if (match === null) {
|
|
25000
25099
|
throw new Error(`Invalid timetable date key: ${dateKey}`);
|
|
25001
25100
|
}
|
|
25002
25101
|
const [, year, month, day] = match;
|
|
@@ -25032,7 +25131,7 @@ function groupItemsByDate(items, accessors) {
|
|
|
25032
25131
|
const dateKey = getLocalDateKey(startsAt, timeZone);
|
|
25033
25132
|
if (dateKey == null) continue;
|
|
25034
25133
|
const existing = grouped.get(dateKey);
|
|
25035
|
-
if (existing) {
|
|
25134
|
+
if (existing !== void 0) {
|
|
25036
25135
|
existing.push(item);
|
|
25037
25136
|
} else {
|
|
25038
25137
|
grouped.set(dateKey, [item]);
|
|
@@ -29379,6 +29478,7 @@ var init_booking_form_reserved_fields = __esm({
|
|
|
29379
29478
|
"selectedDate",
|
|
29380
29479
|
"selectedSlot",
|
|
29381
29480
|
"discountCode",
|
|
29481
|
+
"selectedSlidingAmountInput",
|
|
29382
29482
|
"selectedCollectionOptionKind",
|
|
29383
29483
|
"selectedAppointmentPackageId"
|
|
29384
29484
|
];
|
|
@@ -29664,6 +29764,32 @@ function readOptionalString(value) {
|
|
|
29664
29764
|
function readOptionalNumber(value) {
|
|
29665
29765
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
29666
29766
|
}
|
|
29767
|
+
function getBookingServiceSlidingScale(service) {
|
|
29768
|
+
const pricing = service?.pricing;
|
|
29769
|
+
if (!pricing || pricing.pricingStrategy !== "sliding_scale" || pricing.slidingMinAmount === null || pricing.slidingMinAmount === void 0 || pricing.slidingMaxAmount === null || pricing.slidingMaxAmount === void 0) {
|
|
29770
|
+
return null;
|
|
29771
|
+
}
|
|
29772
|
+
return {
|
|
29773
|
+
minAmount: pricing.slidingMinAmount,
|
|
29774
|
+
maxAmount: pricing.slidingMaxAmount,
|
|
29775
|
+
suggestedAmount: pricing.slidingSuggestedAmount ?? null,
|
|
29776
|
+
currency: pricing.currency
|
|
29777
|
+
};
|
|
29778
|
+
}
|
|
29779
|
+
function parseBookingCurrencyInputToCents(value) {
|
|
29780
|
+
const trimmed = value?.trim() ?? "";
|
|
29781
|
+
if (!trimmed) return null;
|
|
29782
|
+
if (!/^(?:\d+(?:\.\d{0,2})?|\.\d{1,2})$/.test(trimmed)) return null;
|
|
29783
|
+
const parsed = Number(trimmed);
|
|
29784
|
+
if (!Number.isFinite(parsed) || parsed < 0) return null;
|
|
29785
|
+
return Math.round(parsed * 100);
|
|
29786
|
+
}
|
|
29787
|
+
function formatBookingCentsAsCurrencyInput(amount) {
|
|
29788
|
+
return amount % 100 === 0 ? String(amount / 100) : (amount / 100).toFixed(2);
|
|
29789
|
+
}
|
|
29790
|
+
function isBookingServiceSlidingAmountInRange(slidingScale, selectedAmount) {
|
|
29791
|
+
return selectedAmount !== null && selectedAmount >= slidingScale.minAmount && selectedAmount <= slidingScale.maxAmount;
|
|
29792
|
+
}
|
|
29667
29793
|
function readStringArray(value) {
|
|
29668
29794
|
if (!Array.isArray(value)) return void 0;
|
|
29669
29795
|
const strings = value.filter((item) => typeof item === "string");
|
|
@@ -29852,6 +29978,20 @@ function prepareBookingSubmission(input) {
|
|
|
29852
29978
|
};
|
|
29853
29979
|
}
|
|
29854
29980
|
const paymentSelectionMode = getBookingServicePaymentSelectionMode(selectedService);
|
|
29981
|
+
const slidingScale = getBookingServiceSlidingScale(selectedService);
|
|
29982
|
+
const selectedSlidingAmount = parseBookingCurrencyInputToCents(
|
|
29983
|
+
input.data.selectedSlidingAmountInput
|
|
29984
|
+
);
|
|
29985
|
+
if (slidingScale && !isBookingServiceSlidingAmountInRange(slidingScale, selectedSlidingAmount)) {
|
|
29986
|
+
return {
|
|
29987
|
+
ok: false,
|
|
29988
|
+
error: {
|
|
29989
|
+
tag: selectedSlidingAmount === null ? "sliding-amount-required" : "sliding-amount-out-of-range",
|
|
29990
|
+
serviceId,
|
|
29991
|
+
serviceTitle: selectedService.title || serviceId
|
|
29992
|
+
}
|
|
29993
|
+
};
|
|
29994
|
+
}
|
|
29855
29995
|
if (paymentSelectionMode === "choice_required" && !toSelectedCollectionOptionKind(input.data.selectedCollectionOptionKind)) {
|
|
29856
29996
|
return {
|
|
29857
29997
|
ok: false,
|
|
@@ -29879,6 +30019,7 @@ function prepareBookingSubmission(input) {
|
|
|
29879
30019
|
...common,
|
|
29880
30020
|
kind: "standard",
|
|
29881
30021
|
...discountCode ? { discountCode } : {},
|
|
30022
|
+
...slidingScale && selectedSlidingAmount !== null ? { selectedSlidingAmount } : {},
|
|
29882
30023
|
...selectedCollectionOptionKind ? { selectedCollectionOptionKind } : {},
|
|
29883
30024
|
altchaSolution: input.altchaSolution ?? null
|
|
29884
30025
|
}
|
|
@@ -29892,6 +30033,10 @@ function formatBookingSubmissionPreparationError(error) {
|
|
|
29892
30033
|
return `Service not found: ${error.serviceId}`;
|
|
29893
30034
|
case "payment-option-required":
|
|
29894
30035
|
return `Please choose how you want to pay for "${error.serviceTitle}".`;
|
|
30036
|
+
case "sliding-amount-required":
|
|
30037
|
+
return `Please choose an amount for "${error.serviceTitle}".`;
|
|
30038
|
+
case "sliding-amount-out-of-range":
|
|
30039
|
+
return `Please choose an amount within the sliding scale for "${error.serviceTitle}".`;
|
|
29895
30040
|
case "payment-option-unsupported":
|
|
29896
30041
|
return `Service "${error.serviceTitle}" has a payment option that is not supported yet.`;
|
|
29897
30042
|
case "service-missing-duration":
|
|
@@ -30042,6 +30187,7 @@ var init_booking_form_interactive = __esm({
|
|
|
30042
30187
|
title: z66.string(),
|
|
30043
30188
|
description: z66.string().nullable().optional().transform((value) => value ?? void 0),
|
|
30044
30189
|
durationMinutes: z66.number().optional(),
|
|
30190
|
+
pricing: z66.custom().optional(),
|
|
30045
30191
|
priceAmount: z66.number().nullable().optional(),
|
|
30046
30192
|
priceCurrency: z66.string().nullable().optional(),
|
|
30047
30193
|
paymentTerms: blockBookingPaymentTermsSchema.optional(),
|
|
@@ -34960,12 +35106,13 @@ var init_carousel_client = __esm({
|
|
|
34960
35106
|
]
|
|
34961
35107
|
);
|
|
34962
35108
|
const resolvedSlides = resolveSlidesToShowMobile(normalized.slidesToShow);
|
|
35109
|
+
const canAutoplay = normalized.autoplay && slides.length > 1;
|
|
34963
35110
|
const cssVars = React12.useMemo(
|
|
34964
35111
|
() => getCarouselSlidesToShowCssVars(normalized.slidesToShow),
|
|
34965
35112
|
[normalized.slidesToShow]
|
|
34966
35113
|
);
|
|
34967
35114
|
const plugins = React12.useMemo(() => {
|
|
34968
|
-
if (!
|
|
35115
|
+
if (!canAutoplay) return void 0;
|
|
34969
35116
|
return [
|
|
34970
35117
|
Autoplay({
|
|
34971
35118
|
delay: normalized.autoplayDelay,
|
|
@@ -34975,7 +35122,7 @@ var init_carousel_client = __esm({
|
|
|
34975
35122
|
// Continue after manual navigation
|
|
34976
35123
|
})
|
|
34977
35124
|
];
|
|
34978
|
-
}, [
|
|
35125
|
+
}, [canAutoplay, normalized.autoplayDelay]);
|
|
34979
35126
|
const [viewportRef, api] = useEmblaCarousel(
|
|
34980
35127
|
{
|
|
34981
35128
|
align: "start",
|
|
@@ -35014,7 +35161,7 @@ var init_carousel_client = __esm({
|
|
|
35014
35161
|
};
|
|
35015
35162
|
}, [api]);
|
|
35016
35163
|
React12.useEffect(() => {
|
|
35017
|
-
if (!api || !
|
|
35164
|
+
if (!api || !canAutoplay) return;
|
|
35018
35165
|
const autoplayPlugin = api.plugins()?.autoplay;
|
|
35019
35166
|
if (!autoplayPlugin) return;
|
|
35020
35167
|
const handleVisibility = () => {
|
|
@@ -35023,7 +35170,7 @@ var init_carousel_client = __esm({
|
|
|
35023
35170
|
};
|
|
35024
35171
|
document.addEventListener("visibilitychange", handleVisibility);
|
|
35025
35172
|
return () => document.removeEventListener("visibilitychange", handleVisibility);
|
|
35026
|
-
}, [api,
|
|
35173
|
+
}, [api, canAutoplay]);
|
|
35027
35174
|
const inner = /* @__PURE__ */ jsxs53(Fragment13, { children: [
|
|
35028
35175
|
/* @__PURE__ */ jsx68("div", { className: "carousel-frame rb-overflow-hidden rb-w-full", children: /* @__PURE__ */ jsx68(
|
|
35029
35176
|
"div",
|
|
@@ -35074,7 +35221,7 @@ var init_carousel_client = __esm({
|
|
|
35074
35221
|
"data-show-controls": normalized.showControls ? "true" : "false",
|
|
35075
35222
|
"data-show-dots": normalized.showDots ? "true" : "false",
|
|
35076
35223
|
"data-arrow-visibility": normalized.arrowVisibility,
|
|
35077
|
-
"data-autoplay":
|
|
35224
|
+
"data-autoplay": canAutoplay ? "true" : "false",
|
|
35078
35225
|
"data-loop": normalized.loop ? "true" : "false",
|
|
35079
35226
|
children: inner
|
|
35080
35227
|
}
|
|
@@ -36077,6 +36224,7 @@ function createBlockApi(config) {
|
|
|
36077
36224
|
body: {
|
|
36078
36225
|
courseId: data.courseId,
|
|
36079
36226
|
...data.pricingOptionId ? { pricingOptionId: data.pricingOptionId } : {},
|
|
36227
|
+
...data.selectedSlidingAmount !== void 0 ? { selectedSlidingAmount: data.selectedSlidingAmount } : {},
|
|
36080
36228
|
email: data.email,
|
|
36081
36229
|
name: data.name,
|
|
36082
36230
|
phone: data.phone,
|
|
@@ -39257,22 +39405,22 @@ function AltchaWidget({
|
|
|
39257
39405
|
if (typeof window === "undefined") return;
|
|
39258
39406
|
let widget = null;
|
|
39259
39407
|
Promise.resolve().then(() => (init_altcha(), altcha_exports)).then(() => {
|
|
39260
|
-
if (
|
|
39408
|
+
if (containerRef.current === null) return;
|
|
39261
39409
|
widget = document.createElement("altcha-widget");
|
|
39262
39410
|
widget.setAttribute("challengeurl", challengeUrl);
|
|
39263
|
-
if (auto) {
|
|
39411
|
+
if (auto === true) {
|
|
39264
39412
|
widget.setAttribute("auto", "onload");
|
|
39265
39413
|
}
|
|
39266
|
-
if (hidelogo) {
|
|
39414
|
+
if (hidelogo === true) {
|
|
39267
39415
|
widget.setAttribute("hidelogo", "true");
|
|
39268
39416
|
}
|
|
39269
39417
|
widget.setAttribute("hidefooter", "true");
|
|
39270
|
-
if (className) {
|
|
39418
|
+
if (className !== void 0 && className.length > 0) {
|
|
39271
39419
|
widget.className = className;
|
|
39272
39420
|
}
|
|
39273
39421
|
widget.addEventListener("statechange", ((event) => {
|
|
39274
39422
|
const { state, payload } = event.detail;
|
|
39275
|
-
if (state === "verified" && payload) {
|
|
39423
|
+
if (state === "verified" && payload !== void 0 && payload.length > 0) {
|
|
39276
39424
|
onSolutionChange?.(payload);
|
|
39277
39425
|
} else if (state === "error" || state === "expired") {
|
|
39278
39426
|
onSolutionChange?.(null);
|
|
@@ -39283,7 +39431,7 @@ function AltchaWidget({
|
|
|
39283
39431
|
console.error("Failed to load ALTCHA widget:", err3);
|
|
39284
39432
|
});
|
|
39285
39433
|
return () => {
|
|
39286
|
-
if (widget && containerRef.current) {
|
|
39434
|
+
if (widget !== null && containerRef.current !== null) {
|
|
39287
39435
|
containerRef.current.removeChild(widget);
|
|
39288
39436
|
}
|
|
39289
39437
|
};
|
|
@@ -39329,15 +39477,15 @@ var init_dist2 = __esm({
|
|
|
39329
39477
|
// ../altcha/src/index.ts
|
|
39330
39478
|
function getCmsApiUrl2() {
|
|
39331
39479
|
const env = process.env.RIVERBANK_ENV;
|
|
39332
|
-
if (env) {
|
|
39480
|
+
if (env !== void 0 && env.length > 0) {
|
|
39333
39481
|
const envKey = `RIVERBANK_${env.toUpperCase()}_DASHBOARD_URL`;
|
|
39334
39482
|
const dashboardUrl2 = process.env[envKey];
|
|
39335
|
-
if (dashboardUrl2) {
|
|
39483
|
+
if (dashboardUrl2 !== void 0 && dashboardUrl2.length > 0) {
|
|
39336
39484
|
return `${dashboardUrl2.replace(/\/$/, "")}/api`;
|
|
39337
39485
|
}
|
|
39338
39486
|
}
|
|
39339
39487
|
const dashboardUrl = process.env.NEXT_PUBLIC_DASHBOARD_URL;
|
|
39340
|
-
if (dashboardUrl) {
|
|
39488
|
+
if (dashboardUrl !== void 0 && dashboardUrl.length > 0) {
|
|
39341
39489
|
return `${dashboardUrl.replace(/\/$/, "")}/api`;
|
|
39342
39490
|
}
|
|
39343
39491
|
throw new Error("Dashboard URL not configured. Set NEXT_PUBLIC_DASHBOARD_URL");
|
|
@@ -40277,6 +40425,7 @@ function useBookingSubmission(_siteId) {
|
|
|
40277
40425
|
customFields: data.customFields,
|
|
40278
40426
|
timezone: data.timezone,
|
|
40279
40427
|
discountCode: data.discountCode,
|
|
40428
|
+
selectedSlidingAmount: data.selectedSlidingAmount,
|
|
40280
40429
|
selectedCollectionOptionKind: data.selectedCollectionOptionKind,
|
|
40281
40430
|
altchaSolution: data.altchaSolution ?? null,
|
|
40282
40431
|
successUrl: data.successUrl,
|
|
@@ -40805,6 +40954,9 @@ function createInitialBookingFlowReducerState(input) {
|
|
|
40805
40954
|
fieldValues: collectInitialFieldValues(initialData),
|
|
40806
40955
|
touchedFields: {},
|
|
40807
40956
|
discountCode: toOptionalString(initialData.discountCode) ?? "",
|
|
40957
|
+
selectedSlidingAmountInput: toOptionalString(
|
|
40958
|
+
initialData.selectedSlidingAmountInput
|
|
40959
|
+
) ?? "",
|
|
40808
40960
|
selectedCollectionOptionKind: toSelectedCollectionOptionKind(
|
|
40809
40961
|
initialData.selectedCollectionOptionKind
|
|
40810
40962
|
),
|
|
@@ -40857,6 +41009,7 @@ function bookingFlowReducer(state, event) {
|
|
|
40857
41009
|
selectedDate: void 0,
|
|
40858
41010
|
selectedSlot: null,
|
|
40859
41011
|
selectedAppointmentPackageId: void 0,
|
|
41012
|
+
selectedSlidingAmountInput: "",
|
|
40860
41013
|
selectedCollectionOptionKind: void 0,
|
|
40861
41014
|
validationErrors: clearBookingFormError(state.validationErrors)
|
|
40862
41015
|
};
|
|
@@ -40910,6 +41063,13 @@ function bookingFlowReducer(state, event) {
|
|
|
40910
41063
|
selectedAppointmentPackageId: void 0,
|
|
40911
41064
|
validationErrors: clearBookingFormError(state.validationErrors)
|
|
40912
41065
|
};
|
|
41066
|
+
case "sliding-amount-changed":
|
|
41067
|
+
return {
|
|
41068
|
+
...state,
|
|
41069
|
+
selectedSlidingAmountInput: event.value,
|
|
41070
|
+
selectedAppointmentPackageId: void 0,
|
|
41071
|
+
validationErrors: clearBookingFormError(state.validationErrors)
|
|
41072
|
+
};
|
|
40913
41073
|
case "appointment-package-selected":
|
|
40914
41074
|
return {
|
|
40915
41075
|
...state,
|
|
@@ -41012,6 +41172,7 @@ function toBookingFormData(state) {
|
|
|
41012
41172
|
selectedDate: state.selectedDate,
|
|
41013
41173
|
selectedSlot: state.selectedSlot?.startAt,
|
|
41014
41174
|
discountCode: state.discountCode || void 0,
|
|
41175
|
+
selectedSlidingAmountInput: state.selectedSlidingAmountInput || void 0,
|
|
41015
41176
|
selectedCollectionOptionKind: state.selectedCollectionOptionKind,
|
|
41016
41177
|
selectedAppointmentPackageId: state.selectedAppointmentPackageId
|
|
41017
41178
|
};
|
|
@@ -41029,7 +41190,8 @@ function buildBookingStepResolution(input) {
|
|
|
41029
41190
|
input.form.settings?.serviceIds && input.form.settings.serviceIds.length > 1
|
|
41030
41191
|
);
|
|
41031
41192
|
const selectedService = paymentResolution.service;
|
|
41032
|
-
const
|
|
41193
|
+
const selectedServiceSlidingScale = getBookingServiceSlidingScale(selectedService);
|
|
41194
|
+
const needsPayment = Boolean(selectedServiceSlidingScale) || paymentResolution.mode !== "hidden" || Boolean(
|
|
41033
41195
|
input.enableAppointmentPackages && selectedService && (selectedService.priceAmount ?? 0) > 0
|
|
41034
41196
|
);
|
|
41035
41197
|
const hasFields = Boolean(input.form.schema?.fields.length);
|
|
@@ -41073,6 +41235,18 @@ function validateBookingStep(input) {
|
|
|
41073
41235
|
services: input.services,
|
|
41074
41236
|
defaultServiceId: input.defaultServiceId
|
|
41075
41237
|
});
|
|
41238
|
+
const slidingScale = getBookingServiceSlidingScale(resolution.service);
|
|
41239
|
+
if (slidingScale && !isBookingServiceSlidingAmountInRange(
|
|
41240
|
+
slidingScale,
|
|
41241
|
+
parseBookingCurrencyInputToCents(input.data.selectedSlidingAmountInput)
|
|
41242
|
+
)) {
|
|
41243
|
+
return {
|
|
41244
|
+
ok: false,
|
|
41245
|
+
errors: createFormBookingValidationError(
|
|
41246
|
+
"Please choose an amount within the sliding scale"
|
|
41247
|
+
)
|
|
41248
|
+
};
|
|
41249
|
+
}
|
|
41076
41250
|
if (resolution.mode === "hidden" || resolution.mode === "disclosure_only") {
|
|
41077
41251
|
return { ok: true };
|
|
41078
41252
|
}
|
|
@@ -41471,6 +41645,7 @@ var init_useHeadlessBookingFlow_state = __esm({
|
|
|
41471
41645
|
"../blocks/src/system/runtime/hooks/useHeadlessBookingFlow.state.ts"() {
|
|
41472
41646
|
"use strict";
|
|
41473
41647
|
init_booking_form_headless_state();
|
|
41648
|
+
init_booking_form_state();
|
|
41474
41649
|
}
|
|
41475
41650
|
});
|
|
41476
41651
|
|
|
@@ -41510,11 +41685,27 @@ function useHeadlessBookingFlow(options) {
|
|
|
41510
41685
|
const selectedServiceId = state.selectedServiceId ?? defaultServiceId;
|
|
41511
41686
|
const selectedResourceId = state.selectedResourceId ?? defaultResourceId;
|
|
41512
41687
|
const selectedService = options.services.find((service) => service.id === selectedServiceId) ?? null;
|
|
41688
|
+
const lastSlidingServiceIdRef = useRef9(null);
|
|
41689
|
+
useEffect10(() => {
|
|
41690
|
+
const selectedId = selectedService?.id ?? null;
|
|
41691
|
+
if (lastSlidingServiceIdRef.current === selectedId) return;
|
|
41692
|
+
lastSlidingServiceIdRef.current = selectedId;
|
|
41693
|
+
const slidingScale = getBookingServiceSlidingScale(selectedService);
|
|
41694
|
+
dispatch({
|
|
41695
|
+
type: "sliding-amount-changed",
|
|
41696
|
+
value: slidingScale?.suggestedAmount !== null && slidingScale?.suggestedAmount !== void 0 ? formatBookingCentsAsCurrencyInput(slidingScale.suggestedAmount) : ""
|
|
41697
|
+
});
|
|
41698
|
+
}, [selectedService]);
|
|
41513
41699
|
const hasPortalBearerAuth = (api.config.authOverrides?.portal ?? api.config.auth).type === "bearer";
|
|
41700
|
+
const selectedServiceSlidingScale = getBookingServiceSlidingScale(selectedService);
|
|
41701
|
+
const selectedSlidingAmount = parseBookingCurrencyInputToCents(
|
|
41702
|
+
state.selectedSlidingAmountInput
|
|
41703
|
+
);
|
|
41704
|
+
const selectedAppointmentPriceAmount = selectedServiceSlidingScale && selectedSlidingAmount !== null ? selectedSlidingAmount : selectedService?.priceAmount ?? 0;
|
|
41514
41705
|
const canLoadAppointmentPackages = Boolean(
|
|
41515
|
-
options.enableAppointmentPackages && hasPortalBearerAuth && selectedService && (selectedService.priceAmount ?? 0) > 0
|
|
41706
|
+
options.enableAppointmentPackages && hasPortalBearerAuth && selectedService && !selectedServiceSlidingScale && (selectedService.priceAmount ?? 0) > 0
|
|
41516
41707
|
);
|
|
41517
|
-
const appointmentPackagesUnavailableReason = !options.enableAppointmentPackages ? "disabled" : !selectedService || (selectedService.priceAmount ?? 0) <= 0 ? "missing-priced-service" : !hasPortalBearerAuth ? "missing-portal-auth" : null;
|
|
41708
|
+
const appointmentPackagesUnavailableReason = !options.enableAppointmentPackages ? "disabled" : !selectedService || selectedServiceSlidingScale || (selectedService.priceAmount ?? 0) <= 0 ? "missing-priced-service" : !hasPortalBearerAuth ? "missing-portal-auth" : null;
|
|
41518
41709
|
const data = useMemo8(() => toBookingFormData(state), [state]);
|
|
41519
41710
|
const availabilityDatesQuery = useMemo8(
|
|
41520
41711
|
() => buildBookingAvailabilityQuery({
|
|
@@ -41744,13 +41935,13 @@ function useHeadlessBookingFlow(options) {
|
|
|
41744
41935
|
state.selectedSlot
|
|
41745
41936
|
]);
|
|
41746
41937
|
const appointmentDiscountContext = useMemo8(
|
|
41747
|
-
() => selectedService &&
|
|
41748
|
-
[
|
|
41938
|
+
() => selectedService && selectedAppointmentPriceAmount > 0 ? { type: "appointment", serviceId: selectedService.id } : null,
|
|
41939
|
+
[selectedAppointmentPriceAmount, selectedService?.id]
|
|
41749
41940
|
);
|
|
41750
41941
|
const discountUi = useDiscountCodeUi({
|
|
41751
41942
|
api,
|
|
41752
41943
|
discountContext: appointmentDiscountContext,
|
|
41753
|
-
subtotalCents:
|
|
41944
|
+
subtotalCents: selectedAppointmentPriceAmount
|
|
41754
41945
|
});
|
|
41755
41946
|
const { submit, clearFeedback } = useBookingSubmission(options.siteId);
|
|
41756
41947
|
const submittingRef = useRef9(false);
|
|
@@ -41893,6 +42084,7 @@ function useHeadlessBookingFlow(options) {
|
|
|
41893
42084
|
type: "appointment-package-selected",
|
|
41894
42085
|
packageId: packageId ? unsafeAsCustomerPassId(packageId) : null
|
|
41895
42086
|
}),
|
|
42087
|
+
setSlidingAmountInput: (value) => dispatch({ type: "sliding-amount-changed", value }),
|
|
41896
42088
|
setDiscountCode: (code) => {
|
|
41897
42089
|
dispatch({ type: "discount-code-changed", code });
|
|
41898
42090
|
latestRef.current.setDiscountCode(code);
|
|
@@ -41963,11 +42155,11 @@ function useHeadlessBookingFlow(options) {
|
|
|
41963
42155
|
() => selectedService && paymentResolution.mode !== "unsupported" ? buildBookingPaymentSelectionViewModel({
|
|
41964
42156
|
serviceTitle: selectedService.title,
|
|
41965
42157
|
paymentTerms: selectedService.paymentTerms,
|
|
41966
|
-
priceAmount:
|
|
42158
|
+
priceAmount: selectedAppointmentPriceAmount,
|
|
41967
42159
|
priceCurrency: selectedService.priceCurrency,
|
|
41968
42160
|
bookingStartAt: state.selectedSlot?.startAt
|
|
41969
42161
|
}) : null,
|
|
41970
|
-
[paymentResolution.mode, selectedService, state.selectedSlot?.startAt]
|
|
42162
|
+
[paymentResolution.mode, selectedAppointmentPriceAmount, selectedService, state.selectedSlot?.startAt]
|
|
41971
42163
|
);
|
|
41972
42164
|
const appointmentPackageItems = appointmentPackages.tag === "loaded" ? appointmentPackages.value : [];
|
|
41973
42165
|
const selectedAppointmentPackage = appointmentPackageItems.find(
|
|
@@ -41996,6 +42188,9 @@ function useHeadlessBookingFlow(options) {
|
|
|
41996
42188
|
selection: null,
|
|
41997
42189
|
selectedCollectionOptionKind: state.selectedCollectionOptionKind,
|
|
41998
42190
|
selectedAppointmentPackageId: state.selectedAppointmentPackageId,
|
|
42191
|
+
selectedSlidingAmountInput: state.selectedSlidingAmountInput,
|
|
42192
|
+
selectedSlidingAmount,
|
|
42193
|
+
slidingScale: selectedServiceSlidingScale,
|
|
41999
42194
|
appointmentPackages: appointmentPackagesModel,
|
|
42000
42195
|
errorMessage: paymentResolution.errorMessage ?? "This service cannot be booked right now."
|
|
42001
42196
|
} : {
|
|
@@ -42004,6 +42199,9 @@ function useHeadlessBookingFlow(options) {
|
|
|
42004
42199
|
selection: paymentSelection,
|
|
42005
42200
|
selectedCollectionOptionKind: state.selectedCollectionOptionKind,
|
|
42006
42201
|
selectedAppointmentPackageId: state.selectedAppointmentPackageId,
|
|
42202
|
+
selectedSlidingAmountInput: state.selectedSlidingAmountInput,
|
|
42203
|
+
selectedSlidingAmount,
|
|
42204
|
+
slidingScale: selectedServiceSlidingScale,
|
|
42007
42205
|
appointmentPackages: appointmentPackagesModel
|
|
42008
42206
|
};
|
|
42009
42207
|
return {
|
|
@@ -42618,6 +42816,9 @@ var init_FieldValidationMessage = __esm({
|
|
|
42618
42816
|
|
|
42619
42817
|
// ../blocks/src/system/runtime/nodes/booking-form.default-ui.tsx
|
|
42620
42818
|
import { Fragment as Fragment15, jsx as jsx78, jsxs as jsxs59 } from "react/jsx-runtime";
|
|
42819
|
+
function formatBookingAmount(amount, currency) {
|
|
42820
|
+
return formatCurrencyAmount(amount, currency, { decimals: "auto" });
|
|
42821
|
+
}
|
|
42621
42822
|
function HeadlessBookingDefaultForm({
|
|
42622
42823
|
booking,
|
|
42623
42824
|
onSubmit
|
|
@@ -42894,6 +43095,7 @@ function HeadlessBookingPaymentSelectionStep({
|
|
|
42894
43095
|
}
|
|
42895
43096
|
const packageOptions = booking.payment.appointmentPackages.items;
|
|
42896
43097
|
const hasPackageOptions = packageOptions.length > 0;
|
|
43098
|
+
const slidingScale = booking.payment.slidingScale;
|
|
42897
43099
|
return /* @__PURE__ */ jsxs59("div", { className: "ab-stack", children: [
|
|
42898
43100
|
/* @__PURE__ */ jsxs59("div", { className: "ab-info-box", children: [
|
|
42899
43101
|
/* @__PURE__ */ jsx78("h3", { className: "ab-subtitle", children: viewModel.sectionTitle }),
|
|
@@ -42904,6 +43106,28 @@ function HeadlessBookingPaymentSelectionStep({
|
|
|
42904
43106
|
booking.payment.appointmentPackages.state.message,
|
|
42905
43107
|
" You can continue with the normal payment option."
|
|
42906
43108
|
] }) : null,
|
|
43109
|
+
slidingScale ? /* @__PURE__ */ jsxs59("div", { className: "rb-space-y-2", children: [
|
|
43110
|
+
/* @__PURE__ */ jsx78("label", { htmlFor: "appointment-sliding-amount", className: "form-label", children: "Choose your price" }),
|
|
43111
|
+
/* @__PURE__ */ jsxs59("p", { className: "rb-caption status-muted", children: [
|
|
43112
|
+
formatBookingAmount(slidingScale.minAmount, slidingScale.currency),
|
|
43113
|
+
" to ",
|
|
43114
|
+
formatBookingAmount(slidingScale.maxAmount, slidingScale.currency),
|
|
43115
|
+
slidingScale.suggestedAmount !== null ? `, suggested ${formatBookingAmount(slidingScale.suggestedAmount, slidingScale.currency)}` : ""
|
|
43116
|
+
] }),
|
|
43117
|
+
/* @__PURE__ */ jsx78(
|
|
43118
|
+
"input",
|
|
43119
|
+
{
|
|
43120
|
+
id: "appointment-sliding-amount",
|
|
43121
|
+
type: "number",
|
|
43122
|
+
className: "form-input",
|
|
43123
|
+
min: slidingScale.minAmount / 100,
|
|
43124
|
+
max: slidingScale.maxAmount / 100,
|
|
43125
|
+
step: "0.01",
|
|
43126
|
+
value: booking.payment.selectedSlidingAmountInput,
|
|
43127
|
+
onChange: (event) => booking.actions.setSlidingAmountInput(event.target.value)
|
|
43128
|
+
}
|
|
43129
|
+
)
|
|
43130
|
+
] }) : null,
|
|
42907
43131
|
/* @__PURE__ */ jsxs59("div", { className: "ab-stack", role: "list", "aria-label": "Payment options", children: [
|
|
42908
43132
|
packageOptions.map((appointmentPackage) => {
|
|
42909
43133
|
const isSelected = booking.payment.selectedAppointmentPackageId === appointmentPackage.customerPassId;
|
|
@@ -44750,6 +44974,7 @@ function useEligibility(params) {
|
|
|
44750
44974
|
occurrenceId: params.occurrenceId,
|
|
44751
44975
|
attendanceMode: params.attendanceMode ?? void 0,
|
|
44752
44976
|
ticketTypeId: params.ticketTypeId ?? void 0,
|
|
44977
|
+
selectedSlidingAmount: params.selectedSlidingAmount ?? void 0,
|
|
44753
44978
|
email: params.email.trim().toLowerCase(),
|
|
44754
44979
|
ticketsCount: params.ticketsCount
|
|
44755
44980
|
});
|
|
@@ -44770,7 +44995,7 @@ function useEligibility(params) {
|
|
|
44770
44995
|
return () => {
|
|
44771
44996
|
cancelled = true;
|
|
44772
44997
|
};
|
|
44773
|
-
}, [api, params.enabled, params.occurrenceId, params.attendanceMode, params.ticketTypeId, params.email, params.ticketsCount]);
|
|
44998
|
+
}, [api, params.enabled, params.occurrenceId, params.attendanceMode, params.ticketTypeId, params.selectedSlidingAmount, params.email, params.ticketsCount]);
|
|
44774
44999
|
return {
|
|
44775
45000
|
state,
|
|
44776
45001
|
eligibility: state.eligibility,
|
|
@@ -45121,6 +45346,41 @@ function TicketCounterLimit(props2) {
|
|
|
45121
45346
|
] }) : null
|
|
45122
45347
|
] });
|
|
45123
45348
|
}
|
|
45349
|
+
function formatCurrencyInputAmount(amount) {
|
|
45350
|
+
const major = amount / 100;
|
|
45351
|
+
return Number.isInteger(major) ? String(major) : major.toFixed(2);
|
|
45352
|
+
}
|
|
45353
|
+
function SlidingScaleAmountField(props2) {
|
|
45354
|
+
const minLabel = formatPrice(props2.slidingScale.minAmount, props2.currency);
|
|
45355
|
+
const maxLabel = formatPrice(props2.slidingScale.maxAmount, props2.currency);
|
|
45356
|
+
const suggestedLabel = props2.slidingScale.suggestedAmount !== null ? formatPrice(props2.slidingScale.suggestedAmount, props2.currency) : null;
|
|
45357
|
+
return /* @__PURE__ */ jsxs66("div", { className: "er-field", children: [
|
|
45358
|
+
/* @__PURE__ */ jsx93("label", { htmlFor: "er-sliding-amount", className: "er-label", children: "Amount" }),
|
|
45359
|
+
/* @__PURE__ */ jsx93(
|
|
45360
|
+
"input",
|
|
45361
|
+
{
|
|
45362
|
+
id: "er-sliding-amount",
|
|
45363
|
+
type: "number",
|
|
45364
|
+
min: formatCurrencyInputAmount(props2.slidingScale.minAmount),
|
|
45365
|
+
max: formatCurrencyInputAmount(props2.slidingScale.maxAmount),
|
|
45366
|
+
step: "0.01",
|
|
45367
|
+
inputMode: "decimal",
|
|
45368
|
+
className: "er-input",
|
|
45369
|
+
value: props2.value,
|
|
45370
|
+
onChange: (event) => props2.onChange?.(event.target.value)
|
|
45371
|
+
}
|
|
45372
|
+
),
|
|
45373
|
+
/* @__PURE__ */ jsxs66("p", { className: "er-text er-text--muted", children: [
|
|
45374
|
+
"Choose between ",
|
|
45375
|
+
minLabel,
|
|
45376
|
+
" and ",
|
|
45377
|
+
maxLabel,
|
|
45378
|
+
suggestedLabel ? `; suggested ${suggestedLabel}` : "",
|
|
45379
|
+
"."
|
|
45380
|
+
] }),
|
|
45381
|
+
props2.message ? /* @__PURE__ */ jsx93("p", { className: "er-text er-text--muted", children: props2.message }) : null
|
|
45382
|
+
] });
|
|
45383
|
+
}
|
|
45124
45384
|
function getTicketTypeCounterAvailabilityLabel(input) {
|
|
45125
45385
|
if (input.selectedRemainingCapacity !== null) {
|
|
45126
45386
|
return `${input.selectedRemainingCapacity} remaining for this ticket type`;
|
|
@@ -45192,6 +45452,10 @@ var init_TicketSelectionStep = __esm({
|
|
|
45192
45452
|
maxTickets,
|
|
45193
45453
|
selectedTicketTypeId = null,
|
|
45194
45454
|
onTicketTypeChange,
|
|
45455
|
+
slidingScale = null,
|
|
45456
|
+
selectedSlidingAmountInput = "",
|
|
45457
|
+
slidingScaleSelectionMessage = null,
|
|
45458
|
+
onSlidingAmountChange,
|
|
45195
45459
|
onTicketsChange
|
|
45196
45460
|
}) => {
|
|
45197
45461
|
const deliveryMode = event?.deliveryMode ?? "in_person";
|
|
@@ -45307,6 +45571,16 @@ var init_TicketSelectionStep = __esm({
|
|
|
45307
45571
|
] })
|
|
45308
45572
|
] })
|
|
45309
45573
|
] }) : /* @__PURE__ */ jsxs66(Fragment18, { children: [
|
|
45574
|
+
slidingScale ? /* @__PURE__ */ jsx93(
|
|
45575
|
+
SlidingScaleAmountField,
|
|
45576
|
+
{
|
|
45577
|
+
slidingScale,
|
|
45578
|
+
currency: eventPricingCurrency ?? DEFAULT_EVENT_CURRENCY2,
|
|
45579
|
+
value: selectedSlidingAmountInput,
|
|
45580
|
+
message: slidingScaleSelectionMessage,
|
|
45581
|
+
onChange: onSlidingAmountChange
|
|
45582
|
+
}
|
|
45583
|
+
) : null,
|
|
45310
45584
|
/* @__PURE__ */ jsx93("h3", { className: "er-title", children: canJoinWaitlist ? "How many waitlist spots?" : "How many tickets?" }),
|
|
45311
45585
|
/* @__PURE__ */ jsxs66("div", { className: "er-ticket-counter-group", children: [
|
|
45312
45586
|
/* @__PURE__ */ jsx93(
|
|
@@ -46321,6 +46595,10 @@ function EventRegistrationWizardContent(props2) {
|
|
|
46321
46595
|
maxTickets: wizard.maxTicketsNum,
|
|
46322
46596
|
selectedTicketTypeId: wizard.selectedTicketTypeId,
|
|
46323
46597
|
onTicketTypeChange: wizard.setSelectedTicketTypeId,
|
|
46598
|
+
slidingScale: wizard.selectedEventSlidingScale,
|
|
46599
|
+
selectedSlidingAmountInput: wizard.selectedSlidingAmountInput,
|
|
46600
|
+
slidingScaleSelectionMessage: wizard.slidingScaleSelectionMessage,
|
|
46601
|
+
onSlidingAmountChange: wizard.setSelectedSlidingAmountInput,
|
|
46324
46602
|
onTicketsChange: wizard.setTicketsCount
|
|
46325
46603
|
}
|
|
46326
46604
|
)
|
|
@@ -46537,7 +46815,7 @@ function EventRegistrationSummaryBar(props2) {
|
|
|
46537
46815
|
const summaryTimeZone = wizard.occurrenceContext?.timeZone ?? summaryEvent?.timeZone ?? null;
|
|
46538
46816
|
const occurrenceOverrideTitle = wizard.occurrenceContext?.overrides?.title;
|
|
46539
46817
|
const summaryTitle = occurrenceOverrideTitle ?? summaryEvent?.title ?? "";
|
|
46540
|
-
const summaryPrice = wizard.selectedTicketType?.priceAmount ?? wizard.eligibility?.price ?? (summaryEvent ? publicEventScalarPrice(summaryEvent.pricing) : null) ?? 0;
|
|
46818
|
+
const summaryPrice = wizard.selectedTicketType?.priceAmount ?? wizard.eligibility?.price ?? (wizard.selectedEventSlidingScale ? wizard.selectedSlidingAmount : null) ?? (summaryEvent ? publicEventScalarPrice(summaryEvent.pricing) : null) ?? 0;
|
|
46541
46819
|
const summaryCurrency = (summaryEvent ? publicEventPricingCurrency(summaryEvent.pricing) : null) ?? DEFAULT_EVENT_CURRENCY2;
|
|
46542
46820
|
const teamMemberNames = (summaryEvent?.teamMembers ?? []).map((teamMember) => teamMember.name).filter(Boolean);
|
|
46543
46821
|
const subtotalCents = Math.max(0, summaryPrice * wizard.ticketsCount);
|
|
@@ -46988,6 +47266,7 @@ function useEventRegistrationSubmit(options) {
|
|
|
46988
47266
|
occurrenceId: submitOccurrenceId,
|
|
46989
47267
|
attendanceMode: options.selectedAttendanceMode ?? void 0,
|
|
46990
47268
|
ticketTypeId: options.selectedTicketTypeId ?? void 0,
|
|
47269
|
+
selectedSlidingAmount: options.selectedSlidingAmount ?? void 0,
|
|
46991
47270
|
email: options.formData.email.trim().toLowerCase(),
|
|
46992
47271
|
name: options.formData.name.trim(),
|
|
46993
47272
|
ticketsCount: options.ticketsCount,
|
|
@@ -47097,6 +47376,35 @@ var init_useEventRegistrationSubmit = __esm({
|
|
|
47097
47376
|
|
|
47098
47377
|
// ../blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.ts
|
|
47099
47378
|
import { useCallback as useCallback8, useEffect as useEffect17, useMemo as useMemo12, useReducer as useReducer10, useState as useState9 } from "react";
|
|
47379
|
+
function parseCurrencyInputToCents(value) {
|
|
47380
|
+
const trimmed = value.trim();
|
|
47381
|
+
if (!trimmed) return null;
|
|
47382
|
+
const amount = Number(trimmed);
|
|
47383
|
+
if (!Number.isFinite(amount) || amount < 0) return null;
|
|
47384
|
+
return Math.round(amount * 100);
|
|
47385
|
+
}
|
|
47386
|
+
function formatCentsAsCurrencyInput(amount) {
|
|
47387
|
+
const major = amount / 100;
|
|
47388
|
+
return Number.isInteger(major) ? String(major) : major.toFixed(2);
|
|
47389
|
+
}
|
|
47390
|
+
function getSlidingScaleForEvent(event) {
|
|
47391
|
+
const pricing = event ? resolveRuntimeEventPricing(event) : null;
|
|
47392
|
+
return pricing?.kind === "sliding_scale" ? {
|
|
47393
|
+
minAmount: pricing.minAmount,
|
|
47394
|
+
maxAmount: pricing.maxAmount,
|
|
47395
|
+
suggestedAmount: pricing.suggestedAmount
|
|
47396
|
+
} : null;
|
|
47397
|
+
}
|
|
47398
|
+
function getSlidingScaleSelectionMessage(input) {
|
|
47399
|
+
if (!input.slidingScale) return null;
|
|
47400
|
+
if (input.selectedAmount === null) {
|
|
47401
|
+
return "Choose an amount to continue.";
|
|
47402
|
+
}
|
|
47403
|
+
if (input.selectedAmount < input.slidingScale.minAmount || input.selectedAmount > input.slidingScale.maxAmount) {
|
|
47404
|
+
return "Choose an amount within the sliding scale.";
|
|
47405
|
+
}
|
|
47406
|
+
return null;
|
|
47407
|
+
}
|
|
47100
47408
|
function useEventRegistrationWizard(options) {
|
|
47101
47409
|
const api = useBlockApi();
|
|
47102
47410
|
const registrationEvents = useMemo12(
|
|
@@ -47141,6 +47449,10 @@ function useEventRegistrationWizard(options) {
|
|
|
47141
47449
|
preSelectedEvent?.deliveryMode === "online" ? "online" : preSelectedEvent?.deliveryMode === "in_person" ? "in_person" : null
|
|
47142
47450
|
);
|
|
47143
47451
|
const [selectedTicketTypeId, setSelectedTicketTypeId] = useState9(null);
|
|
47452
|
+
const [selectedSlidingAmountInput, setSelectedSlidingAmountInput] = useState9(() => {
|
|
47453
|
+
const slidingScale = getSlidingScaleForEvent(preSelectedEvent ?? null);
|
|
47454
|
+
return slidingScale?.suggestedAmount !== null && slidingScale?.suggestedAmount !== void 0 ? formatCentsAsCurrencyInput(slidingScale.suggestedAmount) : "";
|
|
47455
|
+
});
|
|
47144
47456
|
const [registrationResult, setRegistrationResult] = useState9(null);
|
|
47145
47457
|
const [errorMessage, setErrorMessage] = useState9("");
|
|
47146
47458
|
const [altchaSolution, setAltchaSolution] = useState9(null);
|
|
@@ -47177,6 +47489,7 @@ function useEventRegistrationWizard(options) {
|
|
|
47177
47489
|
occurrenceId,
|
|
47178
47490
|
attendanceMode: selectedAttendanceMode,
|
|
47179
47491
|
ticketTypeId: selectedTicketTypeId,
|
|
47492
|
+
selectedSlidingAmount: parseCurrencyInputToCents(selectedSlidingAmountInput),
|
|
47180
47493
|
email: formData.email,
|
|
47181
47494
|
ticketsCount
|
|
47182
47495
|
});
|
|
@@ -47312,6 +47625,18 @@ function useEventRegistrationWizard(options) {
|
|
|
47312
47625
|
}),
|
|
47313
47626
|
[selectedAttendanceMode, selectedEvent, preSelectedEvent, eligibility, selectedTicketTypeId]
|
|
47314
47627
|
);
|
|
47628
|
+
const selectedSlidingAmount = useMemo12(
|
|
47629
|
+
() => parseCurrencyInputToCents(selectedSlidingAmountInput),
|
|
47630
|
+
[selectedSlidingAmountInput]
|
|
47631
|
+
);
|
|
47632
|
+
const selectedEventSlidingScale = useMemo12(
|
|
47633
|
+
() => getSlidingScaleForEvent(selectedEvent ?? preSelectedEvent),
|
|
47634
|
+
[selectedEvent, preSelectedEvent]
|
|
47635
|
+
);
|
|
47636
|
+
const slidingScaleSelectionMessage = getSlidingScaleSelectionMessage({
|
|
47637
|
+
slidingScale: selectedEventSlidingScale,
|
|
47638
|
+
selectedAmount: selectedSlidingAmount
|
|
47639
|
+
});
|
|
47315
47640
|
const ticketTypeSelectionRequired = useMemo12(() => {
|
|
47316
47641
|
const event = selectedEvent ?? preSelectedEvent;
|
|
47317
47642
|
if (!event || publicEventPricingMode(resolveRuntimeEventPricing(event)) !== "ticket_types") {
|
|
@@ -47380,12 +47705,24 @@ function useEventRegistrationWizard(options) {
|
|
|
47380
47705
|
setGuestSectionShake(false);
|
|
47381
47706
|
};
|
|
47382
47707
|
const eventRequiresPayment = useMemo12(
|
|
47383
|
-
() =>
|
|
47708
|
+
() => {
|
|
47709
|
+
if (selectedEventSlidingScale) {
|
|
47710
|
+
return (selectedSlidingAmount ?? 0) > 0;
|
|
47711
|
+
}
|
|
47712
|
+
return resolveEventRequiresPayment({
|
|
47713
|
+
eligibility,
|
|
47714
|
+
selectedTicketType,
|
|
47715
|
+
event: selectedEvent ?? preSelectedEvent
|
|
47716
|
+
});
|
|
47717
|
+
},
|
|
47718
|
+
[
|
|
47384
47719
|
eligibility,
|
|
47385
47720
|
selectedTicketType,
|
|
47386
|
-
|
|
47387
|
-
|
|
47388
|
-
|
|
47721
|
+
selectedEvent,
|
|
47722
|
+
preSelectedEvent,
|
|
47723
|
+
selectedEventSlidingScale,
|
|
47724
|
+
selectedSlidingAmount
|
|
47725
|
+
]
|
|
47389
47726
|
);
|
|
47390
47727
|
const handleDetailsComplete = async () => {
|
|
47391
47728
|
if (ticketTypeSelectionRequired && !hasValidSelectedTicketType) {
|
|
@@ -47394,6 +47731,11 @@ function useEventRegistrationWizard(options) {
|
|
|
47394
47731
|
setStep("error");
|
|
47395
47732
|
return { ok: false, reason: "blocked", message };
|
|
47396
47733
|
}
|
|
47734
|
+
if (slidingScaleSelectionMessage) {
|
|
47735
|
+
setErrorMessage(slidingScaleSelectionMessage);
|
|
47736
|
+
setStep("error");
|
|
47737
|
+
return { ok: false, reason: "blocked", message: slidingScaleSelectionMessage };
|
|
47738
|
+
}
|
|
47397
47739
|
if (!validateForm()) {
|
|
47398
47740
|
setGuestSectionShake(true);
|
|
47399
47741
|
return {
|
|
@@ -47478,9 +47820,18 @@ function useEventRegistrationWizard(options) {
|
|
|
47478
47820
|
const discountSubtotalCents = useMemo12(() => {
|
|
47479
47821
|
if (discountContext?.type !== "event") return void 0;
|
|
47480
47822
|
const event = selectedEvent ?? preSelectedEvent;
|
|
47481
|
-
const eventPriceCents = selectedTicketType?.priceAmount ?? eligibility?.price ?? (event ? publicEventScalarPrice(resolveRuntimeEventPricing(event)) : null) ?? 0;
|
|
47823
|
+
const eventPriceCents = selectedTicketType?.priceAmount ?? eligibility?.price ?? (selectedEventSlidingScale ? selectedSlidingAmount : null) ?? (event ? publicEventScalarPrice(resolveRuntimeEventPricing(event)) : null) ?? 0;
|
|
47482
47824
|
return Math.max(0, eventPriceCents * ticketsCount);
|
|
47483
|
-
}, [
|
|
47825
|
+
}, [
|
|
47826
|
+
discountContext,
|
|
47827
|
+
selectedTicketType,
|
|
47828
|
+
eligibility,
|
|
47829
|
+
selectedEvent,
|
|
47830
|
+
preSelectedEvent,
|
|
47831
|
+
selectedEventSlidingScale,
|
|
47832
|
+
selectedSlidingAmount,
|
|
47833
|
+
ticketsCount
|
|
47834
|
+
]);
|
|
47484
47835
|
const discountUi = useDiscountCodeUi({ api, discountContext, subtotalCents: discountSubtotalCents });
|
|
47485
47836
|
const selectionMethod = paymentSelection.method;
|
|
47486
47837
|
const shouldShowDiscountToggle = discountContext !== null && discountUi.manualCodeEntryAllowed && (selectionMethod === "stripe" || selectionMethod === "pass_bundle" || selectionMethod === "membership_bundle");
|
|
@@ -47489,6 +47840,7 @@ function useEventRegistrationWizard(options) {
|
|
|
47489
47840
|
registrationTarget,
|
|
47490
47841
|
selectedAttendanceMode,
|
|
47491
47842
|
selectedTicketTypeId,
|
|
47843
|
+
selectedSlidingAmount,
|
|
47492
47844
|
ticketsCount,
|
|
47493
47845
|
formData,
|
|
47494
47846
|
altchaSolution,
|
|
@@ -47503,6 +47855,10 @@ function useEventRegistrationWizard(options) {
|
|
|
47503
47855
|
});
|
|
47504
47856
|
const handleEventSelect = (event) => {
|
|
47505
47857
|
setSelectedEvent(event);
|
|
47858
|
+
const slidingScale = getSlidingScaleForEvent(event);
|
|
47859
|
+
setSelectedSlidingAmountInput(
|
|
47860
|
+
slidingScale?.suggestedAmount !== null && slidingScale?.suggestedAmount !== void 0 ? formatCentsAsCurrencyInput(slidingScale.suggestedAmount) : ""
|
|
47861
|
+
);
|
|
47506
47862
|
setSelectedAttendanceMode(
|
|
47507
47863
|
(event.deliveryMode ?? "in_person") === "hybrid" ? null : (event.deliveryMode ?? "in_person") === "online" ? "online" : "in_person"
|
|
47508
47864
|
);
|
|
@@ -47512,6 +47868,7 @@ function useEventRegistrationWizard(options) {
|
|
|
47512
47868
|
const handleRetry = () => {
|
|
47513
47869
|
dispatchFlow({ type: "reset", hasPreSelectedContext });
|
|
47514
47870
|
setSelectedTicketTypeId(null);
|
|
47871
|
+
setSelectedSlidingAmountInput("");
|
|
47515
47872
|
setSelectedAttendanceMode(
|
|
47516
47873
|
preSelectedEvent?.deliveryMode === "online" ? "online" : preSelectedEvent?.deliveryMode === "in_person" ? "in_person" : null
|
|
47517
47874
|
);
|
|
@@ -47548,6 +47905,11 @@ function useEventRegistrationWizard(options) {
|
|
|
47548
47905
|
setSelectedAttendanceMode,
|
|
47549
47906
|
selectedTicketTypeId,
|
|
47550
47907
|
setSelectedTicketTypeId,
|
|
47908
|
+
selectedSlidingAmountInput,
|
|
47909
|
+
setSelectedSlidingAmountInput,
|
|
47910
|
+
selectedSlidingAmount,
|
|
47911
|
+
selectedEventSlidingScale,
|
|
47912
|
+
slidingScaleSelectionMessage,
|
|
47551
47913
|
selectedTicketType,
|
|
47552
47914
|
visibleTicketTypes,
|
|
47553
47915
|
ticketTypeSelectionRequired,
|
|
@@ -51866,6 +52228,44 @@ function CoursePricingSelector({
|
|
|
51866
52228
|
)
|
|
51867
52229
|
] });
|
|
51868
52230
|
}
|
|
52231
|
+
function CourseSlidingScaleInput({
|
|
52232
|
+
pricing,
|
|
52233
|
+
value,
|
|
52234
|
+
onChange
|
|
52235
|
+
}) {
|
|
52236
|
+
const slidingScale = pricing.slidingScale;
|
|
52237
|
+
if (!slidingScale) {
|
|
52238
|
+
return null;
|
|
52239
|
+
}
|
|
52240
|
+
const minLabel = formatCoursePriceAmount(slidingScale.minAmount, pricing.currency);
|
|
52241
|
+
const maxLabel = formatCoursePriceAmount(slidingScale.maxAmount, pricing.currency);
|
|
52242
|
+
const suggestedLabel = slidingScale.suggestedAmount !== null ? formatCoursePriceAmount(slidingScale.suggestedAmount, pricing.currency) : null;
|
|
52243
|
+
return /* @__PURE__ */ jsxs97("div", { className: "cr-form__field", children: [
|
|
52244
|
+
/* @__PURE__ */ jsx140("label", { htmlFor: "cr-sliding-amount", className: "cr-form__label", children: "Amount" }),
|
|
52245
|
+
/* @__PURE__ */ jsx140(
|
|
52246
|
+
"input",
|
|
52247
|
+
{
|
|
52248
|
+
id: "cr-sliding-amount",
|
|
52249
|
+
type: "number",
|
|
52250
|
+
min: slidingScale.minAmount / 100,
|
|
52251
|
+
max: slidingScale.maxAmount / 100,
|
|
52252
|
+
step: "0.01",
|
|
52253
|
+
inputMode: "decimal",
|
|
52254
|
+
className: "cr-form__input",
|
|
52255
|
+
value,
|
|
52256
|
+
onChange: (event) => onChange(event.target.value)
|
|
52257
|
+
}
|
|
52258
|
+
),
|
|
52259
|
+
/* @__PURE__ */ jsxs97("p", { className: "cr-text cr-text--muted", children: [
|
|
52260
|
+
"Choose between ",
|
|
52261
|
+
minLabel,
|
|
52262
|
+
" and ",
|
|
52263
|
+
maxLabel,
|
|
52264
|
+
suggestedLabel ? `; suggested ${suggestedLabel}` : "",
|
|
52265
|
+
"."
|
|
52266
|
+
] })
|
|
52267
|
+
] });
|
|
52268
|
+
}
|
|
51869
52269
|
function EnrollmentForm({ formData, errors, onChange, isEmailLocked, isLoading, onLogout }) {
|
|
51870
52270
|
const nameErrorId = "cr-name-error";
|
|
51871
52271
|
const emailErrorId = "cr-email-error";
|
|
@@ -51961,6 +52361,17 @@ var init_components2 = __esm({
|
|
|
51961
52361
|
|
|
51962
52362
|
// ../blocks/src/system/runtime/nodes/course-registration/useCourseRegistrationWizard.ts
|
|
51963
52363
|
import { useEffect as useEffect27, useMemo as useMemo21, useState as useState20 } from "react";
|
|
52364
|
+
function parseCurrencyInputToCents2(value) {
|
|
52365
|
+
const trimmed = value.trim();
|
|
52366
|
+
if (!trimmed) return null;
|
|
52367
|
+
const amount = Number(trimmed);
|
|
52368
|
+
if (!Number.isFinite(amount) || amount < 0) return null;
|
|
52369
|
+
return Math.round(amount * 100);
|
|
52370
|
+
}
|
|
52371
|
+
function formatCentsAsCurrencyInput2(amount) {
|
|
52372
|
+
const major = amount / 100;
|
|
52373
|
+
return Number.isInteger(major) ? String(major) : major.toFixed(2);
|
|
52374
|
+
}
|
|
51964
52375
|
function shouldFetchCourseEligibility(course, hasPaidSelection, portalAuthState, hasWaitlistClaimToken) {
|
|
51965
52376
|
if (!course || portalAuthState === "checking") return false;
|
|
51966
52377
|
if (hasWaitlistClaimToken) return false;
|
|
@@ -51978,12 +52389,27 @@ function getSessionIdFromUrl() {
|
|
|
51978
52389
|
}
|
|
51979
52390
|
function getMissingCoursePricingSelectionMessage(pricing) {
|
|
51980
52391
|
if (pricing?.requiresSelection && !pricing.selectedOption) {
|
|
52392
|
+
if (pricing.slidingScale) {
|
|
52393
|
+
return "Choose an amount to continue.";
|
|
52394
|
+
}
|
|
51981
52395
|
return "Choose a pricing option to continue.";
|
|
51982
52396
|
}
|
|
52397
|
+
if (pricing?.slidingScale && pricing.selectedSlidingAmount !== null && pricing.selectedSlidingAmount < pricing.slidingScale.minAmount) {
|
|
52398
|
+
return "Choose an amount within the sliding scale.";
|
|
52399
|
+
}
|
|
52400
|
+
if (pricing?.slidingScale && pricing.selectedSlidingAmount !== null && pricing.selectedSlidingAmount > pricing.slidingScale.maxAmount) {
|
|
52401
|
+
return "Choose an amount within the sliding scale.";
|
|
52402
|
+
}
|
|
51983
52403
|
return null;
|
|
51984
52404
|
}
|
|
51985
52405
|
function buildCoursePricingOptionPayload(pricing) {
|
|
51986
|
-
|
|
52406
|
+
if (pricing?.selectedOption) {
|
|
52407
|
+
return { pricingOptionId: pricing.selectedOption.id };
|
|
52408
|
+
}
|
|
52409
|
+
if (pricing?.slidingScale && pricing.selectedSlidingAmount !== null) {
|
|
52410
|
+
return { selectedSlidingAmount: pricing.selectedSlidingAmount };
|
|
52411
|
+
}
|
|
52412
|
+
return {};
|
|
51987
52413
|
}
|
|
51988
52414
|
function resolveHasCoursePayment(pricing) {
|
|
51989
52415
|
if (!pricing) {
|
|
@@ -52024,6 +52450,7 @@ function useCourseRegistrationWizard(props2) {
|
|
|
52024
52450
|
scopedCourses.length === 1 ? scopedCourses[0] ?? null : null
|
|
52025
52451
|
);
|
|
52026
52452
|
const [selectedPricingOptionId, setSelectedPricingOptionId] = useState20(null);
|
|
52453
|
+
const [selectedSlidingAmountInput, setSelectedSlidingAmountInput] = useState20("");
|
|
52027
52454
|
const [formData, setFormData] = useState20({
|
|
52028
52455
|
name: "",
|
|
52029
52456
|
email: "",
|
|
@@ -52045,8 +52472,12 @@ function useCourseRegistrationWizard(props2) {
|
|
|
52045
52472
|
const [bookingMode, setBookingMode] = useState20(null);
|
|
52046
52473
|
const waitlistClaim = useWaitlistClaim();
|
|
52047
52474
|
const selectedCoursePricing = useMemo21(
|
|
52048
|
-
() => selectedCourse ? resolveCoursePricingState(
|
|
52049
|
-
|
|
52475
|
+
() => selectedCourse ? resolveCoursePricingState(
|
|
52476
|
+
selectedCourse,
|
|
52477
|
+
selectedPricingOptionId,
|
|
52478
|
+
parseCurrencyInputToCents2(selectedSlidingAmountInput)
|
|
52479
|
+
) : null,
|
|
52480
|
+
[selectedCourse, selectedPricingOptionId, selectedSlidingAmountInput]
|
|
52050
52481
|
);
|
|
52051
52482
|
const missingPricingSelectionMessage = getMissingCoursePricingSelectionMessage(
|
|
52052
52483
|
selectedCoursePricing
|
|
@@ -52119,9 +52550,13 @@ function useCourseRegistrationWizard(props2) {
|
|
|
52119
52550
|
useEffect27(() => {
|
|
52120
52551
|
if (!selectedCourse) {
|
|
52121
52552
|
setSelectedPricingOptionId(null);
|
|
52553
|
+
setSelectedSlidingAmountInput("");
|
|
52122
52554
|
return;
|
|
52123
52555
|
}
|
|
52124
52556
|
const defaultPricing = resolveCoursePricingState(selectedCourse, null);
|
|
52557
|
+
setSelectedSlidingAmountInput(
|
|
52558
|
+
defaultPricing.slidingScale?.suggestedAmount !== null && defaultPricing.slidingScale?.suggestedAmount !== void 0 ? formatCentsAsCurrencyInput2(defaultPricing.slidingScale.suggestedAmount) : ""
|
|
52559
|
+
);
|
|
52125
52560
|
setSelectedPricingOptionId((previous) => {
|
|
52126
52561
|
if (previous && defaultPricing.selectableOptions.some((option) => option.id === previous)) {
|
|
52127
52562
|
return previous;
|
|
@@ -52496,6 +52931,8 @@ function useCourseRegistrationWizard(props2) {
|
|
|
52496
52931
|
selectedCourse,
|
|
52497
52932
|
selectedPricingOptionId,
|
|
52498
52933
|
setSelectedPricingOptionId,
|
|
52934
|
+
selectedSlidingAmountInput,
|
|
52935
|
+
setSelectedSlidingAmountInput,
|
|
52499
52936
|
selectedCoursePricing,
|
|
52500
52937
|
setSelectedCourse,
|
|
52501
52938
|
formData,
|
|
@@ -52561,6 +52998,19 @@ var init_useCourseRegistrationWizard = __esm({
|
|
|
52561
52998
|
|
|
52562
52999
|
// ../blocks/src/system/runtime/nodes/course-registration/CourseRegistrationWizard.tsx
|
|
52563
53000
|
import { Fragment as Fragment31, jsx as jsx141, jsxs as jsxs98 } from "react/jsx-runtime";
|
|
53001
|
+
function getCourseSlidingScaleMessage(pricing) {
|
|
53002
|
+
if (!pricing.slidingScale) {
|
|
53003
|
+
return null;
|
|
53004
|
+
}
|
|
53005
|
+
const selectedAmount = pricing.selectedSlidingAmount;
|
|
53006
|
+
if (selectedAmount === null) {
|
|
53007
|
+
return "Choose an amount to continue.";
|
|
53008
|
+
}
|
|
53009
|
+
if (selectedAmount < pricing.slidingScale.minAmount || selectedAmount > pricing.slidingScale.maxAmount) {
|
|
53010
|
+
return "Choose an amount within the sliding scale.";
|
|
53011
|
+
}
|
|
53012
|
+
return null;
|
|
53013
|
+
}
|
|
52564
53014
|
function CourseRegistrationWizard(props2) {
|
|
52565
53015
|
const {
|
|
52566
53016
|
showSessions = true,
|
|
@@ -52582,6 +53032,8 @@ function CourseRegistrationWizard(props2) {
|
|
|
52582
53032
|
selectedCourse,
|
|
52583
53033
|
selectedPricingOptionId,
|
|
52584
53034
|
setSelectedPricingOptionId,
|
|
53035
|
+
selectedSlidingAmountInput,
|
|
53036
|
+
setSelectedSlidingAmountInput,
|
|
52585
53037
|
selectedCoursePricing,
|
|
52586
53038
|
formData,
|
|
52587
53039
|
setFormData,
|
|
@@ -52656,7 +53108,8 @@ function CourseRegistrationWizard(props2) {
|
|
|
52656
53108
|
const canShowDiscountUi = !discountsAvailableLoading && paymentChoice === "checkout" && discountsAvailable && manualCodeEntryAllowed;
|
|
52657
53109
|
const courseSoldOut = waitlistClaim.claim === null && courseEligibility?.isFull === true && courseEligibility.canJoinWaitlist !== true;
|
|
52658
53110
|
const detailsSubmitLabel = courseEligibility?.canJoinWaitlist ? "Join waitlist" : buttonText;
|
|
52659
|
-
const pricingSelectionMissing = selectedCoursePricing?.requiresSelection === true && !selectedCoursePricing.selectedOption;
|
|
53111
|
+
const pricingSelectionMissing = selectedCoursePricing?.requiresSelection === true && !selectedCoursePricing.selectedOption && !selectedCoursePricing.slidingScale;
|
|
53112
|
+
const slidingScaleMessage = selectedCoursePricing ? getCourseSlidingScaleMessage(selectedCoursePricing) : null;
|
|
52660
53113
|
const pricingUnavailable = selectedCoursePricing?.display.kind === "unavailable";
|
|
52661
53114
|
const selectedCourseWithPricing = selectedCourse && selectedCoursePricing ? {
|
|
52662
53115
|
course: selectedCourse,
|
|
@@ -52749,6 +53202,14 @@ function CourseRegistrationWizard(props2) {
|
|
|
52749
53202
|
onSelect: setSelectedPricingOptionId
|
|
52750
53203
|
}
|
|
52751
53204
|
),
|
|
53205
|
+
/* @__PURE__ */ jsx141(
|
|
53206
|
+
CourseSlidingScaleInput,
|
|
53207
|
+
{
|
|
53208
|
+
pricing: selectedCourseWithPricing.pricing,
|
|
53209
|
+
value: selectedSlidingAmountInput,
|
|
53210
|
+
onChange: setSelectedSlidingAmountInput
|
|
53211
|
+
}
|
|
53212
|
+
),
|
|
52752
53213
|
showSpamProtection && /* @__PURE__ */ jsx141("div", { className: "cr-altcha", children: /* @__PURE__ */ jsx141(
|
|
52753
53214
|
AltchaWidget,
|
|
52754
53215
|
{
|
|
@@ -52786,7 +53247,7 @@ function CourseRegistrationWizard(props2) {
|
|
|
52786
53247
|
{
|
|
52787
53248
|
type: "submit",
|
|
52788
53249
|
className: buttonClass,
|
|
52789
|
-
disabled: courseSoldOut || eligibilityLoading || pricingSelectionMissing || pricingUnavailable,
|
|
53250
|
+
disabled: courseSoldOut || eligibilityLoading || pricingSelectionMissing || slidingScaleMessage !== null || pricingUnavailable,
|
|
52790
53251
|
children: eligibilityLoading ? "Checking availability\u2026" : courseSoldOut ? "Sold out" : detailsSubmitLabel
|
|
52791
53252
|
}
|
|
52792
53253
|
)
|
|
@@ -52796,6 +53257,7 @@ function CourseRegistrationWizard(props2) {
|
|
|
52796
53257
|
),
|
|
52797
53258
|
courseSoldOut && /* @__PURE__ */ jsx141("p", { className: "cr-text cr-text--muted", children: "This course is fully booked and there is no waitlist available right now." }),
|
|
52798
53259
|
pricingSelectionMissing && /* @__PURE__ */ jsx141("p", { className: "cr-text cr-text--muted", children: "Choose a pricing option to continue." }),
|
|
53260
|
+
slidingScaleMessage && /* @__PURE__ */ jsx141("p", { className: "cr-text cr-text--muted", children: slidingScaleMessage }),
|
|
52799
53261
|
pricingUnavailable && /* @__PURE__ */ jsx141("p", { className: "cr-text cr-text--muted", children: "Pricing is not available for this course right now." }),
|
|
52800
53262
|
eligibilityError && /* @__PURE__ */ jsx141("p", { className: "cr-text cr-text--error", children: eligibilityError })
|
|
52801
53263
|
] })
|
|
@@ -62949,6 +63411,21 @@ function fieldPlanToZod(plan, options = {}) {
|
|
|
62949
63411
|
}
|
|
62950
63412
|
});
|
|
62951
63413
|
}
|
|
63414
|
+
function fieldPresenceForPlan(plan) {
|
|
63415
|
+
return plan.required ? { kind: "required" } : { kind: "optional" };
|
|
63416
|
+
}
|
|
63417
|
+
function fieldPlanToObjectPropertyZod(plan, options = {}) {
|
|
63418
|
+
const schema = fieldPlanToZod(plan, options);
|
|
63419
|
+
const presence = fieldPresenceForPlan(plan);
|
|
63420
|
+
switch (presence.kind) {
|
|
63421
|
+
case "required":
|
|
63422
|
+
return schema;
|
|
63423
|
+
case "optional":
|
|
63424
|
+
return schema.optional();
|
|
63425
|
+
default:
|
|
63426
|
+
return assertNever4(presence);
|
|
63427
|
+
}
|
|
63428
|
+
}
|
|
62952
63429
|
function addFieldIssueToZodContext(zodCtx, validationIssue, rootPath) {
|
|
62953
63430
|
const message = fieldIssueToMessage(validationIssue);
|
|
62954
63431
|
const path = relativeZodIssuePath(validationIssue.path, rootPath);
|
|
@@ -63161,7 +63638,7 @@ function createManifestValidator(manifestOrFields, options = {}) {
|
|
|
63161
63638
|
function deriveContentZodFromPlans(plans, options) {
|
|
63162
63639
|
const shape = {};
|
|
63163
63640
|
for (const plan of plans) {
|
|
63164
|
-
shape[plan.fieldId] =
|
|
63641
|
+
shape[plan.fieldId] = fieldPlanToObjectPropertyZod(plan, options);
|
|
63165
63642
|
}
|
|
63166
63643
|
return z7.object(shape).catchall(z7.unknown()).passthrough();
|
|
63167
63644
|
}
|
|
@@ -75254,11 +75731,11 @@ function extractRouteUpdatedAt(candidate) {
|
|
|
75254
75731
|
}
|
|
75255
75732
|
function resolveRouteTargetForStage(routeIdValue, routes, stageInput) {
|
|
75256
75733
|
const routeId = typeof routeIdValue === "string" ? routeIdValue : null;
|
|
75257
|
-
if (
|
|
75734
|
+
if (routeId === null || routeId.length === 0 || routes === void 0) return null;
|
|
75258
75735
|
const routeEntry = routes[routeId];
|
|
75259
75736
|
if (!isRouteVisibleInStage(routeEntry, stageInput)) return null;
|
|
75260
75737
|
const href = extractRouteHref(routeEntry, stageInput);
|
|
75261
|
-
if (
|
|
75738
|
+
if (href === null) return null;
|
|
75262
75739
|
return {
|
|
75263
75740
|
routeId,
|
|
75264
75741
|
href,
|
|
@@ -97083,6 +97560,7 @@ var CANONICAL_REFUND_CONFLICT_CODES = [
|
|
|
97083
97560
|
];
|
|
97084
97561
|
var CANONICAL_REFUND_PLANNER_ERROR_CODES = [
|
|
97085
97562
|
...CANONICAL_REFUND_CONFLICT_CODES,
|
|
97563
|
+
"invalid_amount",
|
|
97086
97564
|
"amount_exceeds_remaining",
|
|
97087
97565
|
"pass_revoke_requires_full_refund",
|
|
97088
97566
|
"refund_failed"
|
|
@@ -97109,6 +97587,7 @@ var CUSTOMER_MEMBERSHIP_PAYMENT_REFUND_FAILED_CODES = [
|
|
|
97109
97587
|
// ../api/src/bookingRefundOutcomes.ts
|
|
97110
97588
|
var STANDARD_LINE_ITEM_REFUND_INVALID_CODES = [
|
|
97111
97589
|
"missing_amount",
|
|
97590
|
+
"invalid_amount",
|
|
97112
97591
|
"amount_exceeds_remaining",
|
|
97113
97592
|
"credit_refunds_disabled",
|
|
97114
97593
|
"missing_credit_customer",
|
|
@@ -97123,6 +97602,7 @@ var EVENT_ATTENDEE_REFUND_INVALID_CODES = [
|
|
|
97123
97602
|
var MANAGED_PRODUCT_REFUND_INVALID_CODES = [
|
|
97124
97603
|
"credit_refunds_disabled",
|
|
97125
97604
|
"not_refundable",
|
|
97605
|
+
"invalid_amount",
|
|
97126
97606
|
"amount_exceeds_remaining"
|
|
97127
97607
|
];
|
|
97128
97608
|
var CUSTOMER_PASS_REFUND_INVALID_CODES = [
|
|
@@ -99095,7 +99575,7 @@ var SimpleCache = class {
|
|
|
99095
99575
|
};
|
|
99096
99576
|
|
|
99097
99577
|
// src/version.ts
|
|
99098
|
-
var SDK_VERSION = "0.
|
|
99578
|
+
var SDK_VERSION = "0.92.0";
|
|
99099
99579
|
|
|
99100
99580
|
// src/client/error.ts
|
|
99101
99581
|
var RiverbankApiError = class _RiverbankApiError extends Error {
|