@bigz-app/booking-widget 0.3.6 → 0.3.8
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/booking-widget.js +609 -193
- package/dist/booking-widget.js.map +1 -1
- package/dist/components/BookingForm.d.ts.map +1 -1
- package/dist/components/EventInstanceSelection.d.ts.map +1 -1
- package/dist/components/PaymentForm.d.ts +3 -1
- package/dist/components/PaymentForm.d.ts.map +1 -1
- package/dist/components/VoucherInput.d.ts +29 -0
- package/dist/components/VoucherInput.d.ts.map +1 -0
- package/dist/index.cjs +610 -194
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +611 -195
- package/dist/index.esm.js.map +1 -1
- package/package.json +75 -70
package/dist/booking-widget.js
CHANGED
|
@@ -6946,7 +6946,7 @@
|
|
|
6946
6946
|
// Convert double underscores to HTML underline tags for React Markdown
|
|
6947
6947
|
return markdown.replace(/__([^_]+)__/g, "<u>$1</u>");
|
|
6948
6948
|
};
|
|
6949
|
-
const IconCheck$
|
|
6949
|
+
const IconCheck$2 = ({ size = 16, color = "#10b981" }) => (u$2("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: u$2("polyline", { points: "20 6 9 17 4 12" }) }));
|
|
6950
6950
|
const IconWave$1 = ({ size = 20, color = "#0ea5e9" }) => (u$2("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [u$2("path", { d: "M2 18c2-2 6-2 8 0s6 2 8 0 6-2 8 0" }), u$2("path", { d: "M2 12c2-2 6-2 8 0s6 2 8 0 6-2 8 0" }), u$2("path", { d: "M2 6c2-2 6-2 8 0s6 2 8 0 6-2 8 0" })] }));
|
|
6951
6951
|
function EventTypeDetailsDialog({ isOpen, onClose, eventType, onEventTypeSelect, }) {
|
|
6952
6952
|
if (!isOpen || !eventType)
|
|
@@ -6993,7 +6993,7 @@
|
|
|
6993
6993
|
fontSize: "16px",
|
|
6994
6994
|
lineHeight: "1.6",
|
|
6995
6995
|
color: "var(--bw-text-color)",
|
|
6996
|
-
}, children: [u$2("div", { style: { marginTop: "4px", flexShrink: 0 }, children: u$2(IconCheck$
|
|
6996
|
+
}, children: [u$2("div", { style: { marginTop: "4px", flexShrink: 0 }, children: u$2(IconCheck$2, { size: 16, color: "var(--bw-success-color)" }) }), u$2("span", { children: highlight.trim() })] }, index))) }) }) }))] }), eventType.description && (u$2("div", { style: {
|
|
6997
6997
|
marginBottom: "24px",
|
|
6998
6998
|
color: "var(--bw-text-muted)",
|
|
6999
6999
|
fontSize: "16px",
|
|
@@ -7302,7 +7302,7 @@
|
|
|
7302
7302
|
// Custom minimal SVG icons (Lucide-style)
|
|
7303
7303
|
const IconClock = ({ size = 16, color = "#10b981" }) => (u$2("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [u$2("circle", { cx: "12", cy: "12", r: "10" }), u$2("polyline", { points: "12 6 12 12 16 14" })] }));
|
|
7304
7304
|
const IconCalendar = ({ size = 16, color = "#3b82f6" }) => (u$2("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [u$2("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2" }), u$2("line", { x1: "16", y1: "2", x2: "16", y2: "6" }), u$2("line", { x1: "8", y1: "2", x2: "8", y2: "6" }), u$2("line", { x1: "3", y1: "10", x2: "21", y2: "10" })] }));
|
|
7305
|
-
const IconCheck = ({ size = 16, color = "#10b981" }) => (u$2("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: u$2("polyline", { points: "20 6 9 17 4 12" }) }));
|
|
7305
|
+
const IconCheck$1 = ({ size = 16, color = "#10b981" }) => (u$2("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: u$2("polyline", { points: "20 6 9 17 4 12" }) }));
|
|
7306
7306
|
// Wave icon for booking action
|
|
7307
7307
|
const IconWave = ({ size = 20, color = "#0ea5e9" }) => (u$2("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [u$2("path", { d: "M2 18c2-2 6-2 8 0s6 2 8 0 6-2 8 0" }), u$2("path", { d: "M2 12c2-2 6-2 8 0s6 2 8 0 6-2 8 0" }), u$2("path", { d: "M2 6c2-2 6-2 8 0s6 2 8 0 6-2 8 0" })] }));
|
|
7308
7308
|
// Loading skeleton component that matches the actual design
|
|
@@ -7766,7 +7766,7 @@
|
|
|
7766
7766
|
color: "var(--bw-text-muted)",
|
|
7767
7767
|
position: "relative",
|
|
7768
7768
|
maxWidth: "100%",
|
|
7769
|
-
}, children: [u$2("div", { style: { marginTop: "4px", flexShrink: 0 }, children: u$2(IconCheck, { size: 16, color: "var(--bw-success-color)" }) }), u$2("span", { style: {
|
|
7769
|
+
}, children: [u$2("div", { style: { marginTop: "4px", flexShrink: 0 }, children: u$2(IconCheck$1, { size: 16, color: "var(--bw-success-color)" }) }), u$2("span", { style: {
|
|
7770
7770
|
textOverflow: "ellipsis",
|
|
7771
7771
|
overflow: "hidden",
|
|
7772
7772
|
whiteSpace: "nowrap",
|
|
@@ -9196,6 +9196,110 @@
|
|
|
9196
9196
|
|
|
9197
9197
|
var reactStripe_umdExports = reactStripe_umd.exports;
|
|
9198
9198
|
|
|
9199
|
+
// Component for bookings fully covered by gift cards (no Stripe payment needed)
|
|
9200
|
+
function GiftCardOnlyBooking({ config, eventDetails, formData, discountCode, giftCards, onSuccess, onError, }) {
|
|
9201
|
+
const [isLoading, setIsLoading] = d$1(false);
|
|
9202
|
+
const [error, setError] = d$1(null);
|
|
9203
|
+
const handleBooking = async () => {
|
|
9204
|
+
setIsLoading(true);
|
|
9205
|
+
setError(null);
|
|
9206
|
+
try {
|
|
9207
|
+
// Create booking directly without Stripe payment
|
|
9208
|
+
const requestData = {
|
|
9209
|
+
eventInstanceId: config.eventInstanceId || eventDetails.id,
|
|
9210
|
+
organizationId: config.organizationId,
|
|
9211
|
+
participants: formData.participants.filter((p) => p.name?.trim()),
|
|
9212
|
+
discountCode: discountCode?.code,
|
|
9213
|
+
giftCardCodes: giftCards.map((gc) => gc.code),
|
|
9214
|
+
customerName: formData.customerName?.trim(),
|
|
9215
|
+
customerEmail: formData.customerEmail?.trim(),
|
|
9216
|
+
customerPhone: formData.customerPhone?.trim(),
|
|
9217
|
+
comment: formData.comment?.trim(),
|
|
9218
|
+
paymentMethod: "gift_card",
|
|
9219
|
+
};
|
|
9220
|
+
const response = await fetch(getApiUrl(config.apiBaseUrl, "/booking/create-gift-card-booking"), {
|
|
9221
|
+
method: "POST",
|
|
9222
|
+
headers: createApiHeaders(config),
|
|
9223
|
+
body: JSON.stringify(createRequestBody(config, requestData)),
|
|
9224
|
+
});
|
|
9225
|
+
const data = await response.json();
|
|
9226
|
+
if (response.ok) {
|
|
9227
|
+
onSuccess({
|
|
9228
|
+
booking: data.booking,
|
|
9229
|
+
order: data.order,
|
|
9230
|
+
giftCardRedemptions: data.giftCardRedemptions,
|
|
9231
|
+
});
|
|
9232
|
+
}
|
|
9233
|
+
else {
|
|
9234
|
+
setError(data.error || "Fehler beim Erstellen der Buchung");
|
|
9235
|
+
onError(data.error || "Fehler beim Erstellen der Buchung");
|
|
9236
|
+
}
|
|
9237
|
+
}
|
|
9238
|
+
catch (err) {
|
|
9239
|
+
setError(err.message || "Fehler beim Erstellen der Buchung");
|
|
9240
|
+
onError(err.message || "Fehler beim Erstellen der Buchung");
|
|
9241
|
+
}
|
|
9242
|
+
finally {
|
|
9243
|
+
setIsLoading(false);
|
|
9244
|
+
}
|
|
9245
|
+
};
|
|
9246
|
+
const totalGiftCardAmount = giftCards.reduce((sum, gc) => sum + (gc.balanceToUse || gc.discountAmount || 0), 0);
|
|
9247
|
+
return (u$2("div", { style: { display: "flex", flexDirection: "column", gap: "var(--bw-spacing)" }, children: [u$2("div", { style: {
|
|
9248
|
+
backgroundColor: "var(--bw-success-color)15",
|
|
9249
|
+
border: "1px solid var(--bw-success-color)40",
|
|
9250
|
+
borderRadius: "var(--bw-border-radius)",
|
|
9251
|
+
padding: "var(--bw-spacing)",
|
|
9252
|
+
}, children: [u$2("div", { style: {
|
|
9253
|
+
display: "flex",
|
|
9254
|
+
alignItems: "center",
|
|
9255
|
+
gap: "8px",
|
|
9256
|
+
marginBottom: "8px",
|
|
9257
|
+
color: "var(--bw-success-color)",
|
|
9258
|
+
fontFamily: "var(--bw-font-family)",
|
|
9259
|
+
fontWeight: "600",
|
|
9260
|
+
}, children: "\uD83C\uDF81 Vollst\u00E4ndig durch Gutschein(e) gedeckt" }), u$2("div", { style: {
|
|
9261
|
+
fontSize: "var(--bw-font-size)",
|
|
9262
|
+
color: "var(--bw-text-muted)",
|
|
9263
|
+
fontFamily: "var(--bw-font-family)",
|
|
9264
|
+
}, children: ["Gutschein-Guthaben: ", formatCurrency(totalGiftCardAmount)] })] }), error && (u$2("div", { style: {
|
|
9265
|
+
backgroundColor: "var(--bw-error-color)15",
|
|
9266
|
+
border: "1px solid var(--bw-error-color)40",
|
|
9267
|
+
borderRadius: "var(--bw-border-radius)",
|
|
9268
|
+
padding: "var(--bw-spacing)",
|
|
9269
|
+
color: "var(--bw-error-color)",
|
|
9270
|
+
fontSize: "var(--bw-font-size)",
|
|
9271
|
+
fontFamily: "var(--bw-font-family)",
|
|
9272
|
+
}, children: ["\u26A0\uFE0F ", error] })), u$2("button", { type: "button", onClick: handleBooking, disabled: isLoading, style: {
|
|
9273
|
+
width: "100%",
|
|
9274
|
+
padding: "12px 24px",
|
|
9275
|
+
backgroundColor: "var(--bw-highlight-color)",
|
|
9276
|
+
color: "#fff",
|
|
9277
|
+
border: "none",
|
|
9278
|
+
borderRadius: "var(--bw-border-radius)",
|
|
9279
|
+
fontSize: "var(--bw-font-size)",
|
|
9280
|
+
fontWeight: "600",
|
|
9281
|
+
cursor: isLoading ? "not-allowed" : "pointer",
|
|
9282
|
+
opacity: isLoading ? 0.6 : 1,
|
|
9283
|
+
transition: "all 0.2s ease",
|
|
9284
|
+
fontFamily: "var(--bw-font-family)",
|
|
9285
|
+
display: "flex",
|
|
9286
|
+
alignItems: "center",
|
|
9287
|
+
justifyContent: "center",
|
|
9288
|
+
gap: "8px",
|
|
9289
|
+
}, children: isLoading ? (u$2(k$3, { children: [u$2("div", { style: {
|
|
9290
|
+
width: "16px",
|
|
9291
|
+
height: "16px",
|
|
9292
|
+
border: "2px solid #fff",
|
|
9293
|
+
borderTopColor: "transparent",
|
|
9294
|
+
borderRadius: "50%",
|
|
9295
|
+
animation: "spin 1s linear infinite",
|
|
9296
|
+
} }), "Buchung wird erstellt..."] })) : ("Mit Gutschein buchen") }), u$2("style", { children: `
|
|
9297
|
+
@keyframes spin {
|
|
9298
|
+
from { transform: rotate(0deg); }
|
|
9299
|
+
to { transform: rotate(360deg); }
|
|
9300
|
+
}
|
|
9301
|
+
` })] }));
|
|
9302
|
+
}
|
|
9199
9303
|
const spinner$1 = (borderColor) => (u$2("div", { style: {
|
|
9200
9304
|
width: "auto",
|
|
9201
9305
|
height: "auto",
|
|
@@ -9212,7 +9316,7 @@
|
|
|
9212
9316
|
borderRadius: "50%",
|
|
9213
9317
|
} }) }));
|
|
9214
9318
|
// Inner component that uses the Stripe hooks
|
|
9215
|
-
function PaymentFormInner({ config, eventDetails, formData, totalAmount, discountCode, onSuccess, onError, }) {
|
|
9319
|
+
function PaymentFormInner({ config, eventDetails, formData, totalAmount, discountCode, giftCards, onSuccess, onError, }) {
|
|
9216
9320
|
const stripe = reactStripe_umdExports.useStripe();
|
|
9217
9321
|
const elements = reactStripe_umdExports.useElements();
|
|
9218
9322
|
const [isLoading, setIsLoading] = d$1(false);
|
|
@@ -9343,7 +9447,7 @@
|
|
|
9343
9447
|
` })] }));
|
|
9344
9448
|
}
|
|
9345
9449
|
// Main PaymentForm component that handles payment intent creation and Elements wrapper
|
|
9346
|
-
function PaymentForm({ config, eventDetails, formData, totalAmount, discountCode, onSuccess, onError, systemConfig, stripePromise, stripeAppearance, }) {
|
|
9450
|
+
function PaymentForm({ config, eventDetails, formData, totalAmount, discountCode, giftCards, onSuccess, onError, systemConfig, stripePromise, stripeAppearance, }) {
|
|
9347
9451
|
const [clientSecret, setClientSecret] = d$1(null);
|
|
9348
9452
|
const [paymentIntentId, setPaymentIntentId] = d$1(null);
|
|
9349
9453
|
const [isCreatingPaymentIntent, setIsCreatingPaymentIntent] = d$1(false);
|
|
@@ -9439,6 +9543,7 @@
|
|
|
9439
9543
|
currency: "eur",
|
|
9440
9544
|
participants: formData.participants.filter((p) => p.name?.trim()),
|
|
9441
9545
|
discountCode: discountCode?.code,
|
|
9546
|
+
giftCardCodes: giftCards?.map((gc) => gc.code) || [],
|
|
9442
9547
|
customerName: formData.customerName?.trim(),
|
|
9443
9548
|
customerEmail: formData.customerEmail?.trim(),
|
|
9444
9549
|
customerPhone: formData.customerPhone?.trim(),
|
|
@@ -9500,8 +9605,21 @@
|
|
|
9500
9605
|
formData.customerName,
|
|
9501
9606
|
totalAmount,
|
|
9502
9607
|
discountCode,
|
|
9608
|
+
giftCards,
|
|
9503
9609
|
config,
|
|
9504
9610
|
]);
|
|
9611
|
+
// Calculate total gift card coverage
|
|
9612
|
+
const totalGiftCardAmount = giftCards?.reduce((sum, gc) => sum + (gc.balanceToUse || gc.discountAmount || 0), 0) || 0;
|
|
9613
|
+
const baseTotal = eventDetails?.price
|
|
9614
|
+
? eventDetails.price * (formData.participants?.filter((p) => p.name?.trim()).length || 0)
|
|
9615
|
+
: 0;
|
|
9616
|
+
const discountAmount = discountCode?.discountAmount || 0;
|
|
9617
|
+
const amountAfterDiscount = Math.max(0, baseTotal - discountAmount);
|
|
9618
|
+
const isFullyCoveredByGiftCards = totalGiftCardAmount >= amountAfterDiscount && amountAfterDiscount > 0;
|
|
9619
|
+
// If gift cards fully cover the payment, show a simplified booking button
|
|
9620
|
+
if (isFullyCoveredByGiftCards && totalAmount <= 0) {
|
|
9621
|
+
return (u$2(GiftCardOnlyBooking, { config: config, eventDetails: eventDetails, formData: formData, discountCode: discountCode, giftCards: giftCards || [], onSuccess: onSuccess, onError: onError }));
|
|
9622
|
+
}
|
|
9505
9623
|
// Show loading state while creating payment intent
|
|
9506
9624
|
if (isCreatingPaymentIntent || !clientSecret) {
|
|
9507
9625
|
return (u$2("div", { style: {
|
|
@@ -9535,7 +9653,7 @@
|
|
|
9535
9653
|
clientSecret,
|
|
9536
9654
|
appearance: stripeAppearance || { theme: "stripe" },
|
|
9537
9655
|
locale: config.locale || "de",
|
|
9538
|
-
}, children: u$2(PaymentFormInner, { config: config, eventDetails: eventDetails, formData: formData, totalAmount: totalAmount, discountCode: discountCode, onSuccess: (result) => {
|
|
9656
|
+
}, children: u$2(PaymentFormInner, { config: config, eventDetails: eventDetails, formData: formData, totalAmount: totalAmount, discountCode: discountCode, giftCards: giftCards, onSuccess: (result) => {
|
|
9539
9657
|
// Clear persisted PI data on successful payment
|
|
9540
9658
|
clearPersistedPaymentIntent();
|
|
9541
9659
|
setPaymentIntentId(null);
|
|
@@ -9740,6 +9858,222 @@
|
|
|
9740
9858
|
}, children: children }))] }));
|
|
9741
9859
|
}
|
|
9742
9860
|
|
|
9861
|
+
// Icons
|
|
9862
|
+
const IconTicket = ({ size = 20, color = "currentColor" }) => (u$2("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [u$2("path", { d: "M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z" }), u$2("path", { d: "M13 5v2" }), u$2("path", { d: "M13 17v2" }), u$2("path", { d: "M13 11v2" })] }));
|
|
9863
|
+
const IconGift = ({ size = 20, color = "currentColor" }) => (u$2("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [u$2("rect", { x: "3", y: "8", width: "18", height: "4", rx: "1" }), u$2("path", { d: "M12 8v13" }), u$2("path", { d: "M19 12v7a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-7" }), u$2("path", { d: "M7.5 8a2.5 2.5 0 0 1 0-5A4.8 8 0 0 1 12 8a4.8 8 0 0 1 4.5-5 2.5 2.5 0 0 1 0 5" })] }));
|
|
9864
|
+
const IconCheck = ({ size = 16, color = "currentColor" }) => (u$2("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: u$2("polyline", { points: "20 6 9 17 4 12" }) }));
|
|
9865
|
+
const IconX = ({ size = 16, color = "currentColor" }) => (u$2("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [u$2("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), u$2("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }));
|
|
9866
|
+
const IconSpinner = ({ size = 16, color = "currentColor" }) => (u$2("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", style: { animation: "spin 1s linear infinite" }, children: u$2("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }) }));
|
|
9867
|
+
function VoucherInput({ config, orderValue, eventInstanceId, customerEmail, onVoucherValidated, appliedVouchers, onRemoveVoucher, disabled = false, }) {
|
|
9868
|
+
const [inputValue, setInputValue] = d$1("");
|
|
9869
|
+
const [isLoading, setIsLoading] = d$1(false);
|
|
9870
|
+
const [error, setError] = d$1(null);
|
|
9871
|
+
const [isExpanded, setIsExpanded] = d$1(false);
|
|
9872
|
+
// Check if a discount code is already applied (only one allowed)
|
|
9873
|
+
const hasDiscountCode = appliedVouchers.some((v) => v.type === "discount");
|
|
9874
|
+
const validateVoucher = q$2(async (code) => {
|
|
9875
|
+
if (!code.trim()) {
|
|
9876
|
+
setError(null);
|
|
9877
|
+
return;
|
|
9878
|
+
}
|
|
9879
|
+
// Check if code is already applied
|
|
9880
|
+
if (appliedVouchers.some((v) => v.code.toUpperCase() === code.toUpperCase())) {
|
|
9881
|
+
setError("Dieser Code wurde bereits angewendet");
|
|
9882
|
+
return;
|
|
9883
|
+
}
|
|
9884
|
+
setIsLoading(true);
|
|
9885
|
+
setError(null);
|
|
9886
|
+
try {
|
|
9887
|
+
const response = await fetch(getApiUrl(config.apiBaseUrl, "/booking/validate-voucher"), {
|
|
9888
|
+
method: "POST",
|
|
9889
|
+
headers: createApiHeaders(config),
|
|
9890
|
+
body: JSON.stringify(createRequestBody(config, {
|
|
9891
|
+
code: code.trim(),
|
|
9892
|
+
orderValue: orderValue,
|
|
9893
|
+
eventInstanceId: eventInstanceId,
|
|
9894
|
+
customerEmail: customerEmail,
|
|
9895
|
+
})),
|
|
9896
|
+
});
|
|
9897
|
+
const data = await response.json();
|
|
9898
|
+
if (data.valid && data.voucher) {
|
|
9899
|
+
// Check if trying to add a second discount code
|
|
9900
|
+
if (data.voucher.type === "discount" && hasDiscountCode) {
|
|
9901
|
+
setError("Es kann nur ein Rabattcode verwendet werden");
|
|
9902
|
+
onVoucherValidated(null, "Es kann nur ein Rabattcode verwendet werden");
|
|
9903
|
+
return;
|
|
9904
|
+
}
|
|
9905
|
+
onVoucherValidated(data.voucher);
|
|
9906
|
+
setInputValue("");
|
|
9907
|
+
setError(null);
|
|
9908
|
+
}
|
|
9909
|
+
else {
|
|
9910
|
+
setError(data.error || "Code nicht gefunden oder ungültig");
|
|
9911
|
+
onVoucherValidated(null, data.error);
|
|
9912
|
+
}
|
|
9913
|
+
}
|
|
9914
|
+
catch (err) {
|
|
9915
|
+
const errorMsg = "Fehler beim Validieren des Codes";
|
|
9916
|
+
setError(errorMsg);
|
|
9917
|
+
onVoucherValidated(null, errorMsg);
|
|
9918
|
+
}
|
|
9919
|
+
finally {
|
|
9920
|
+
setIsLoading(false);
|
|
9921
|
+
}
|
|
9922
|
+
}, [
|
|
9923
|
+
config,
|
|
9924
|
+
orderValue,
|
|
9925
|
+
eventInstanceId,
|
|
9926
|
+
customerEmail,
|
|
9927
|
+
appliedVouchers,
|
|
9928
|
+
hasDiscountCode,
|
|
9929
|
+
onVoucherValidated,
|
|
9930
|
+
]);
|
|
9931
|
+
const handleSubmit = () => {
|
|
9932
|
+
if (inputValue.trim() && !isLoading && !disabled) {
|
|
9933
|
+
validateVoucher(inputValue);
|
|
9934
|
+
}
|
|
9935
|
+
};
|
|
9936
|
+
const handleKeyDown = (e) => {
|
|
9937
|
+
if (e.key === "Enter") {
|
|
9938
|
+
e.preventDefault();
|
|
9939
|
+
if (inputValue.trim() && !isLoading && !disabled) {
|
|
9940
|
+
validateVoucher(inputValue);
|
|
9941
|
+
}
|
|
9942
|
+
}
|
|
9943
|
+
};
|
|
9944
|
+
const inputStyle = {
|
|
9945
|
+
flex: 1,
|
|
9946
|
+
padding: "10px 12px",
|
|
9947
|
+
backgroundColor: "var(--bw-background-color)",
|
|
9948
|
+
border: "1px solid var(--bw-border-color)",
|
|
9949
|
+
borderRadius: "var(--bw-border-radius)",
|
|
9950
|
+
color: "var(--bw-text-color)",
|
|
9951
|
+
fontSize: "var(--bw-font-size)",
|
|
9952
|
+
fontFamily: "var(--bw-font-family)",
|
|
9953
|
+
outline: "none",
|
|
9954
|
+
transition: "all 0.2s ease",
|
|
9955
|
+
textTransform: "uppercase",
|
|
9956
|
+
};
|
|
9957
|
+
const buttonStyle = {
|
|
9958
|
+
padding: "10px 16px",
|
|
9959
|
+
backgroundColor: "var(--bw-highlight-color)",
|
|
9960
|
+
border: "none",
|
|
9961
|
+
borderRadius: "var(--bw-border-radius)",
|
|
9962
|
+
color: "#fff",
|
|
9963
|
+
fontSize: "var(--bw-font-size)",
|
|
9964
|
+
fontFamily: "var(--bw-font-family)",
|
|
9965
|
+
fontWeight: "600",
|
|
9966
|
+
cursor: disabled || isLoading ? "not-allowed" : "pointer",
|
|
9967
|
+
opacity: disabled || isLoading ? 0.6 : 1,
|
|
9968
|
+
transition: "all 0.2s ease",
|
|
9969
|
+
display: "flex",
|
|
9970
|
+
alignItems: "center",
|
|
9971
|
+
justifyContent: "center",
|
|
9972
|
+
gap: "6px",
|
|
9973
|
+
minWidth: "100px",
|
|
9974
|
+
};
|
|
9975
|
+
const appliedVoucherStyle = {
|
|
9976
|
+
display: "flex",
|
|
9977
|
+
alignItems: "center",
|
|
9978
|
+
justifyContent: "space-between",
|
|
9979
|
+
padding: "10px 12px",
|
|
9980
|
+
backgroundColor: "var(--bw-surface-color)",
|
|
9981
|
+
border: "1px solid var(--bw-border-color)",
|
|
9982
|
+
borderRadius: "var(--bw-border-radius)",
|
|
9983
|
+
marginBottom: "8px",
|
|
9984
|
+
};
|
|
9985
|
+
const removeButtonStyle = {
|
|
9986
|
+
background: "none",
|
|
9987
|
+
border: "none",
|
|
9988
|
+
padding: "4px",
|
|
9989
|
+
cursor: "pointer",
|
|
9990
|
+
color: "var(--bw-error-color)",
|
|
9991
|
+
display: "flex",
|
|
9992
|
+
alignItems: "center",
|
|
9993
|
+
justifyContent: "center",
|
|
9994
|
+
borderRadius: "50%",
|
|
9995
|
+
transition: "background-color 0.2s ease",
|
|
9996
|
+
};
|
|
9997
|
+
return (u$2("div", { style: {
|
|
9998
|
+
backgroundColor: "var(--bw-surface-color)",
|
|
9999
|
+
border: "1px solid var(--bw-border-color)",
|
|
10000
|
+
borderRadius: "var(--bw-border-radius)",
|
|
10001
|
+
overflow: "hidden",
|
|
10002
|
+
}, children: [u$2("button", { type: "button", onClick: () => setIsExpanded(!isExpanded), style: {
|
|
10003
|
+
width: "100%",
|
|
10004
|
+
padding: "var(--bw-spacing)",
|
|
10005
|
+
backgroundColor: "transparent",
|
|
10006
|
+
border: "none",
|
|
10007
|
+
cursor: "pointer",
|
|
10008
|
+
display: "flex",
|
|
10009
|
+
alignItems: "center",
|
|
10010
|
+
justifyContent: "space-between",
|
|
10011
|
+
color: "var(--bw-text-color)",
|
|
10012
|
+
fontFamily: "var(--bw-font-family)",
|
|
10013
|
+
fontSize: "var(--bw-font-size)",
|
|
10014
|
+
fontWeight: "500",
|
|
10015
|
+
}, children: [u$2("span", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [u$2(IconTicket, { size: 18, color: "var(--bw-highlight-color)" }), "Rabattcode oder Gutschein", appliedVouchers.length > 0 && (u$2("span", { style: {
|
|
10016
|
+
backgroundColor: "var(--bw-highlight-color)",
|
|
10017
|
+
color: "#fff",
|
|
10018
|
+
padding: "2px 8px",
|
|
10019
|
+
borderRadius: "12px",
|
|
10020
|
+
fontSize: "12px",
|
|
10021
|
+
fontWeight: "600",
|
|
10022
|
+
}, children: appliedVouchers.length }))] }), u$2("span", { style: {
|
|
10023
|
+
transform: isExpanded ? "rotate(180deg)" : "rotate(0deg)",
|
|
10024
|
+
transition: "transform 0.2s ease",
|
|
10025
|
+
}, children: "\u25BC" })] }), isExpanded && (u$2("div", { style: { padding: "0 var(--bw-spacing) var(--bw-spacing)" }, children: [appliedVouchers.length > 0 && (u$2("div", { style: { marginBottom: "12px" }, children: appliedVouchers.map((voucher) => (u$2("div", { style: appliedVoucherStyle, children: [u$2("div", { style: { display: "flex", alignItems: "center", gap: "10px" }, children: [voucher.type === "discount" ? (u$2(IconTicket, { size: 18, color: "var(--bw-success-color)" })) : (u$2(IconGift, { size: 18, color: "var(--bw-success-color)" })), u$2("div", { children: [u$2("div", { style: {
|
|
10026
|
+
fontFamily: "var(--bw-font-family)",
|
|
10027
|
+
fontSize: "var(--bw-font-size)",
|
|
10028
|
+
fontWeight: "600",
|
|
10029
|
+
color: "var(--bw-text-color)",
|
|
10030
|
+
display: "flex",
|
|
10031
|
+
alignItems: "center",
|
|
10032
|
+
gap: "6px",
|
|
10033
|
+
}, children: [u$2("span", { style: { fontFamily: "monospace" }, children: voucher.code }), u$2(IconCheck, { size: 14, color: "var(--bw-success-color)" })] }), u$2("div", { style: {
|
|
10034
|
+
fontFamily: "var(--bw-font-family)",
|
|
10035
|
+
fontSize: "12px",
|
|
10036
|
+
color: "var(--bw-success-color)",
|
|
10037
|
+
}, children: [voucher.type === "discount"
|
|
10038
|
+
? `−${formatCurrency(voucher.discountAmount)} Rabatt`
|
|
10039
|
+
: `−${formatCurrency(voucher.balanceToUse || voucher.discountAmount)} Gutschein`, voucher.type === "giftCard" &&
|
|
10040
|
+
voucher.remainingBalance !== undefined &&
|
|
10041
|
+
voucher.remainingBalance > 0 && (u$2("span", { style: { color: "var(--bw-text-muted)", marginLeft: "8px" }, children: ["(Rest: ", formatCurrency(voucher.remainingBalance), ")"] }))] })] })] }), u$2("button", { type: "button", onClick: () => onRemoveVoucher(voucher.code), style: removeButtonStyle, title: "Entfernen", children: u$2(IconX, { size: 16 }) })] }, voucher.code))) })), u$2("div", { style: { display: "flex", gap: "8px" }, children: [u$2("input", { type: "text", value: inputValue, onChange: (e) => {
|
|
10042
|
+
setInputValue(e.target.value.toUpperCase());
|
|
10043
|
+
setError(null);
|
|
10044
|
+
}, onKeyDown: handleKeyDown, placeholder: hasDiscountCode
|
|
10045
|
+
? "Gutscheincode eingeben..."
|
|
10046
|
+
: "Rabatt- oder Gutscheincode eingeben...", style: inputStyle, disabled: disabled || isLoading, onFocus: (e) => {
|
|
10047
|
+
e.target.style.borderColor = "var(--bw-highlight-color)";
|
|
10048
|
+
e.target.style.boxShadow = "0 0 0 2px var(--bw-highlight-color)33";
|
|
10049
|
+
}, onBlur: (e) => {
|
|
10050
|
+
e.target.style.borderColor = "var(--bw-border-color)";
|
|
10051
|
+
e.target.style.boxShadow = "none";
|
|
10052
|
+
} }), u$2("button", { type: "button", onClick: handleSubmit, style: buttonStyle, disabled: disabled || isLoading || !inputValue.trim(), children: isLoading ? (u$2(IconSpinner, { size: 16, color: "#fff" })) : (u$2(k$3, { children: [u$2(IconCheck, { size: 16 }), "Einl\u00F6sen"] })) })] }), error && (u$2("div", { style: {
|
|
10053
|
+
marginTop: "8px",
|
|
10054
|
+
padding: "8px 12px",
|
|
10055
|
+
backgroundColor: "var(--bw-error-color)15",
|
|
10056
|
+
border: "1px solid var(--bw-error-color)40",
|
|
10057
|
+
borderRadius: "var(--bw-border-radius)",
|
|
10058
|
+
color: "var(--bw-error-color)",
|
|
10059
|
+
fontSize: "var(--bw-font-size)",
|
|
10060
|
+
fontFamily: "var(--bw-font-family)",
|
|
10061
|
+
display: "flex",
|
|
10062
|
+
alignItems: "center",
|
|
10063
|
+
gap: "8px",
|
|
10064
|
+
}, children: [u$2(IconX, { size: 16 }), error] })), hasDiscountCode && (u$2("div", { style: {
|
|
10065
|
+
marginTop: "8px",
|
|
10066
|
+
fontSize: "12px",
|
|
10067
|
+
color: "var(--bw-text-muted)",
|
|
10068
|
+
fontFamily: "var(--bw-font-family)",
|
|
10069
|
+
}, children: "\uD83D\uDCA1 Es wurde bereits ein Rabattcode angewendet. Du kannst weitere Gutscheine hinzuf\u00FCgen." }))] })), u$2("style", { children: `
|
|
10070
|
+
@keyframes spin {
|
|
10071
|
+
from { transform: rotate(0deg); }
|
|
10072
|
+
to { transform: rotate(360deg); }
|
|
10073
|
+
}
|
|
10074
|
+
` })] }));
|
|
10075
|
+
}
|
|
10076
|
+
|
|
9743
10077
|
// Form schemas
|
|
9744
10078
|
const participantSchema = objectType({
|
|
9745
10079
|
name: stringType().min(1, "Name ist erforderlich"),
|
|
@@ -9759,6 +10093,10 @@
|
|
|
9759
10093
|
const IconWarning = ({ size = 48, color = "var(--bw-error-color)" }) => (u$2("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [u$2("circle", { cx: "12", cy: "12", r: "10" }), u$2("line", { x1: "12", y1: "8", x2: "12", y2: "12" }), u$2("circle", { cx: "12", cy: "16", r: "1" })] }));
|
|
9760
10094
|
const IconMoney = ({ size = 20, color = "var(--bw-text-muted)" }) => (u$2("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [u$2("rect", { x: "2", y: "6", width: "20", height: "12", rx: "2" }), u$2("circle", { cx: "12", cy: "12", r: "4" }), u$2("line", { x1: "2", y1: "10", x2: "2", y2: "14" }), u$2("line", { x1: "22", y1: "10", x2: "22", y2: "14" })] }));
|
|
9761
10095
|
function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError, onBackToEventInstances, onBackToEventTypes, selectedEventType, selectedEventInstance, isOpen, onClose, systemConfig, }) {
|
|
10096
|
+
// New voucher system - supports multiple gift cards + one discount code
|
|
10097
|
+
const [appliedVouchers, setAppliedVouchers] = d$1([]);
|
|
10098
|
+
const [voucherError, setVoucherError] = d$1(null);
|
|
10099
|
+
// Legacy state for backward compatibility
|
|
9762
10100
|
const [discountCode, setDiscountCode] = d$1(null);
|
|
9763
10101
|
const [discountLoading, setDiscountLoading] = d$1(false);
|
|
9764
10102
|
const [discountError, setDiscountError] = d$1(null);
|
|
@@ -9772,28 +10110,66 @@
|
|
|
9772
10110
|
},
|
|
9773
10111
|
});
|
|
9774
10112
|
const watchedParticipants = form.watch("participants");
|
|
9775
|
-
|
|
10113
|
+
form.watch("discountCode");
|
|
9776
10114
|
const watchedCustomerName = form.watch("customerName");
|
|
9777
10115
|
const watchedCustomerEmail = form.watch("customerEmail");
|
|
9778
10116
|
const customerNameError = form.formState.errors.customerName;
|
|
9779
10117
|
const customerEmailError = form.formState.errors.customerEmail;
|
|
9780
10118
|
const watchedAcceptTerms = form.watch("acceptTerms");
|
|
9781
|
-
// Calculate total
|
|
9782
|
-
const
|
|
10119
|
+
// Calculate base total before any discounts
|
|
10120
|
+
const calculateBaseTotal = q$2(() => {
|
|
9783
10121
|
if (!eventDetails)
|
|
9784
10122
|
return 0;
|
|
9785
|
-
|
|
9786
|
-
|
|
9787
|
-
|
|
10123
|
+
return eventDetails.price * watchedParticipants.filter((p) => p.name.trim()).length;
|
|
10124
|
+
}, [eventDetails, watchedParticipants]);
|
|
10125
|
+
// Calculate total discount from all applied vouchers
|
|
10126
|
+
const calculateTotalDiscount = q$2(() => {
|
|
10127
|
+
return appliedVouchers.reduce((total, voucher) => {
|
|
10128
|
+
if (voucher.type === "discount") {
|
|
10129
|
+
return total + voucher.discountAmount;
|
|
10130
|
+
}
|
|
10131
|
+
else if (voucher.type === "giftCard") {
|
|
10132
|
+
return total + (voucher.balanceToUse || voucher.discountAmount);
|
|
10133
|
+
}
|
|
10134
|
+
return total;
|
|
10135
|
+
}, 0);
|
|
10136
|
+
}, [appliedVouchers]);
|
|
10137
|
+
// Calculate total amount after discounts
|
|
10138
|
+
const calculateTotal = q$2(() => {
|
|
10139
|
+
const baseTotal = calculateBaseTotal();
|
|
10140
|
+
const totalDiscount = calculateTotalDiscount();
|
|
10141
|
+
return Math.max(0, baseTotal - totalDiscount);
|
|
10142
|
+
}, [calculateBaseTotal, calculateTotalDiscount]);
|
|
9788
10143
|
const calculateDeposit = () => {
|
|
9789
10144
|
if (!eventDetails || !eventDetails.deposit)
|
|
9790
10145
|
return 0;
|
|
9791
10146
|
const participantCount = watchedParticipants.filter((p) => p.name.trim()).length;
|
|
9792
10147
|
return eventDetails.deposit * participantCount;
|
|
9793
10148
|
};
|
|
10149
|
+
const baseTotal = calculateBaseTotal();
|
|
10150
|
+
const totalDiscount = calculateTotalDiscount();
|
|
9794
10151
|
const totalAmount = calculateTotal();
|
|
9795
10152
|
const depositAmount = calculateDeposit();
|
|
9796
|
-
|
|
10153
|
+
// If there's a deposit, we pay the deposit; otherwise we pay the total after discounts
|
|
10154
|
+
const paymentAmount = depositAmount > 0 ? Math.max(0, depositAmount - totalDiscount) : totalAmount;
|
|
10155
|
+
// Get discount code for legacy compatibility
|
|
10156
|
+
const appliedDiscountCode = appliedVouchers.find((v) => v.type === "discount");
|
|
10157
|
+
// Get gift cards
|
|
10158
|
+
const appliedGiftCards = appliedVouchers.filter((v) => v.type === "giftCard");
|
|
10159
|
+
// Voucher handlers
|
|
10160
|
+
const handleVoucherValidated = q$2((voucher, error) => {
|
|
10161
|
+
if (error) {
|
|
10162
|
+
setVoucherError(error);
|
|
10163
|
+
return;
|
|
10164
|
+
}
|
|
10165
|
+
if (voucher) {
|
|
10166
|
+
setAppliedVouchers((prev) => [...prev, voucher]);
|
|
10167
|
+
setVoucherError(null);
|
|
10168
|
+
}
|
|
10169
|
+
}, []);
|
|
10170
|
+
const handleRemoveVoucher = q$2((code) => {
|
|
10171
|
+
setAppliedVouchers((prev) => prev.filter((v) => v.code !== code));
|
|
10172
|
+
}, []);
|
|
9797
10173
|
// Form validation helper
|
|
9798
10174
|
const isFormValid = () => {
|
|
9799
10175
|
const participantCount = watchedParticipants.filter((p) => p.name.trim()).length;
|
|
@@ -9807,48 +10183,51 @@
|
|
|
9807
10183
|
const hasAcceptedTerms = watchedAcceptTerms === true;
|
|
9808
10184
|
return validParticipants && participantsWithinLimit && hasName && hasEmail && hasAcceptedTerms;
|
|
9809
10185
|
};
|
|
9810
|
-
//
|
|
10186
|
+
// Re-validate vouchers when participant count changes (affects order value)
|
|
9811
10187
|
y$1(() => {
|
|
9812
|
-
|
|
9813
|
-
|
|
9814
|
-
|
|
9815
|
-
|
|
9816
|
-
|
|
9817
|
-
|
|
9818
|
-
|
|
9819
|
-
|
|
9820
|
-
|
|
9821
|
-
|
|
9822
|
-
|
|
9823
|
-
|
|
9824
|
-
|
|
9825
|
-
|
|
9826
|
-
|
|
9827
|
-
|
|
9828
|
-
|
|
9829
|
-
|
|
9830
|
-
|
|
9831
|
-
|
|
9832
|
-
|
|
10188
|
+
// When participants change, we need to recalculate voucher amounts
|
|
10189
|
+
// For now, we'll clear vouchers if the order value changes significantly
|
|
10190
|
+
// In a production app, you might want to re-validate each voucher
|
|
10191
|
+
if (appliedVouchers.length > 0) {
|
|
10192
|
+
// Recalculate discount amounts based on new order value
|
|
10193
|
+
const newBaseTotal = eventDetails?.price
|
|
10194
|
+
? eventDetails.price * watchedParticipants.filter((p) => p.name.trim()).length
|
|
10195
|
+
: 0;
|
|
10196
|
+
// Update voucher amounts (simplified - in production, re-validate via API)
|
|
10197
|
+
setAppliedVouchers((prev) => prev.map((voucher) => {
|
|
10198
|
+
if (voucher.type === "discount") {
|
|
10199
|
+
let newDiscountAmount = 0;
|
|
10200
|
+
if (voucher.discountType === "percentage") {
|
|
10201
|
+
newDiscountAmount = Math.round((newBaseTotal * (voucher.discountValue || 0)) / 10000);
|
|
10202
|
+
}
|
|
10203
|
+
else {
|
|
10204
|
+
newDiscountAmount = voucher.discountValue || 0;
|
|
10205
|
+
}
|
|
10206
|
+
newDiscountAmount = Math.min(newDiscountAmount, newBaseTotal);
|
|
10207
|
+
return {
|
|
10208
|
+
...voucher,
|
|
10209
|
+
discountAmount: newDiscountAmount,
|
|
10210
|
+
newTotal: newBaseTotal - newDiscountAmount,
|
|
10211
|
+
};
|
|
9833
10212
|
}
|
|
9834
|
-
else {
|
|
9835
|
-
|
|
9836
|
-
|
|
10213
|
+
else if (voucher.type === "giftCard") {
|
|
10214
|
+
// Gift card balance stays the same, but amount to use might change
|
|
10215
|
+
const remainingAfterDiscount = newBaseTotal -
|
|
10216
|
+
prev
|
|
10217
|
+
.filter((v) => v.type === "discount")
|
|
10218
|
+
.reduce((sum, v) => sum + v.discountAmount, 0);
|
|
10219
|
+
const balanceToUse = Math.min(voucher.currentBalance || 0, Math.max(0, remainingAfterDiscount));
|
|
10220
|
+
return {
|
|
10221
|
+
...voucher,
|
|
10222
|
+
balanceToUse,
|
|
10223
|
+
remainingBalance: (voucher.currentBalance || 0) - balanceToUse,
|
|
10224
|
+
discountAmount: balanceToUse,
|
|
10225
|
+
};
|
|
9837
10226
|
}
|
|
9838
|
-
|
|
9839
|
-
|
|
9840
|
-
|
|
9841
|
-
|
|
9842
|
-
}
|
|
9843
|
-
finally {
|
|
9844
|
-
setDiscountLoading(false);
|
|
9845
|
-
}
|
|
9846
|
-
};
|
|
9847
|
-
const timer = setTimeout(() => {
|
|
9848
|
-
validateDiscountCode(watchedDiscountCode || "");
|
|
9849
|
-
}, 500);
|
|
9850
|
-
return () => clearTimeout(timer);
|
|
9851
|
-
}, [watchedDiscountCode, watchedParticipants, eventDetails, config]);
|
|
10227
|
+
return voucher;
|
|
10228
|
+
}));
|
|
10229
|
+
}
|
|
10230
|
+
}, [watchedParticipants, eventDetails]);
|
|
9852
10231
|
// Helper functions
|
|
9853
10232
|
const addParticipant = () => {
|
|
9854
10233
|
const currentParticipants = form.getValues("participants");
|
|
@@ -10003,7 +10382,7 @@
|
|
|
10003
10382
|
color: "var(--bw-text-color)",
|
|
10004
10383
|
fontWeight: "500",
|
|
10005
10384
|
fontFamily: "var(--bw-font-family)",
|
|
10006
|
-
}, children: [formatCurrency(eventDetails.price), " pro Person"] })] })] })] }), u$2("div", { style: { display: "flex", flexDirection: "column", gap: "var(--bw-spacing-large)" }, children: [u$2("
|
|
10385
|
+
}, children: [formatCurrency(eventDetails.price), " pro Person"] })] })] })] }), u$2("div", { style: { display: "flex", flexDirection: "column", gap: "var(--bw-spacing-large)" }, children: [u$2("div", { style: { display: "flex", flexDirection: "column", gap: "var(--bw-spacing-large)" }, children: [u$2("div", { style: {
|
|
10007
10386
|
backgroundColor: "var(--bw-surface-color)",
|
|
10008
10387
|
border: `1px solid var(--bw-border-color)`,
|
|
10009
10388
|
backdropFilter: "blur(4px)",
|
|
@@ -10148,7 +10527,7 @@
|
|
|
10148
10527
|
color: "var(--bw-error-color)",
|
|
10149
10528
|
fontSize: "var(--bw-font-size)",
|
|
10150
10529
|
fontFamily: "var(--bw-font-family)",
|
|
10151
|
-
}, children: ["Maximal ", eventDetails.availableSpots, " Pl\u00E4tze verf\u00FCgbar."] }))] })] }), u$2("div", { style: {
|
|
10530
|
+
}, children: ["Maximal ", eventDetails.availableSpots, " Pl\u00E4tze verf\u00FCgbar."] }))] })] }), u$2(VoucherInput, { config: config, orderValue: baseTotal, eventInstanceId: eventDetails?.id, customerEmail: watchedCustomerEmail, onVoucherValidated: handleVoucherValidated, appliedVouchers: appliedVouchers, onRemoveVoucher: handleRemoveVoucher, disabled: !eventDetails }), u$2("div", { style: {
|
|
10152
10531
|
backgroundColor: "var(--bw-surface-color)",
|
|
10153
10532
|
border: `1px solid var(--bw-border-color)`,
|
|
10154
10533
|
backdropFilter: "blur(4px)",
|
|
@@ -10247,7 +10626,7 @@
|
|
|
10247
10626
|
color: "var(--bw-text-color)",
|
|
10248
10627
|
fontWeight: "500",
|
|
10249
10628
|
fontFamily: "var(--bw-font-family)",
|
|
10250
|
-
}, children: formatCurrency(eventDetails.deposit || 0) })] })),
|
|
10629
|
+
}, children: formatCurrency(eventDetails.deposit || 0) })] })), appliedVouchers.length > 0 && (u$2(k$3, { children: [u$2("div", { style: {
|
|
10251
10630
|
display: "flex",
|
|
10252
10631
|
justifyContent: "space-between",
|
|
10253
10632
|
alignItems: "center",
|
|
@@ -10256,20 +10635,31 @@
|
|
|
10256
10635
|
fontFamily: "var(--bw-font-family)",
|
|
10257
10636
|
}, children: "Zwischensumme:" }), u$2("span", { style: {
|
|
10258
10637
|
color: "var(--bw-text-muted)",
|
|
10259
|
-
textDecoration: "line-through",
|
|
10638
|
+
textDecoration: totalDiscount > 0 ? "line-through" : "none",
|
|
10260
10639
|
fontFamily: "var(--bw-font-family)",
|
|
10261
|
-
}, children: formatCurrency(
|
|
10262
|
-
watchedParticipants.filter((p) => p.name.trim()).length) })] }), u$2("div", { style: {
|
|
10640
|
+
}, children: formatCurrency(baseTotal) })] }), appliedDiscountCode && (u$2("div", { style: {
|
|
10263
10641
|
display: "flex",
|
|
10264
10642
|
justifyContent: "space-between",
|
|
10265
10643
|
alignItems: "center",
|
|
10266
10644
|
}, children: [u$2("span", { style: {
|
|
10267
10645
|
color: "var(--bw-success-color)",
|
|
10268
10646
|
fontFamily: "var(--bw-font-family)",
|
|
10269
|
-
|
|
10647
|
+
fontSize: "var(--bw-font-size)",
|
|
10648
|
+
}, children: ["Rabatt (", appliedDiscountCode.code, "):"] }), u$2("span", { style: {
|
|
10270
10649
|
color: "var(--bw-success-color)",
|
|
10271
10650
|
fontFamily: "var(--bw-font-family)",
|
|
10272
|
-
}, children: ["-", formatCurrency(
|
|
10651
|
+
}, children: ["-", formatCurrency(appliedDiscountCode.discountAmount)] })] })), appliedGiftCards.map((giftCard) => (u$2("div", { style: {
|
|
10652
|
+
display: "flex",
|
|
10653
|
+
justifyContent: "space-between",
|
|
10654
|
+
alignItems: "center",
|
|
10655
|
+
}, children: [u$2("span", { style: {
|
|
10656
|
+
color: "var(--bw-success-color)",
|
|
10657
|
+
fontFamily: "var(--bw-font-family)",
|
|
10658
|
+
fontSize: "var(--bw-font-size)",
|
|
10659
|
+
}, children: ["Gutschein (", giftCard.code, "):"] }), u$2("span", { style: {
|
|
10660
|
+
color: "var(--bw-success-color)",
|
|
10661
|
+
fontFamily: "var(--bw-font-family)",
|
|
10662
|
+
}, children: ["-", formatCurrency(giftCard.balanceToUse || giftCard.discountAmount)] })] }, giftCard.code)))] })), u$2("div", { style: {
|
|
10273
10663
|
borderTop: `1px solid var(--bw-border-color)`,
|
|
10274
10664
|
paddingTop: "12px",
|
|
10275
10665
|
}, children: [depositAmount > 0 && (u$2("div", { style: {
|
|
@@ -10342,7 +10732,15 @@
|
|
|
10342
10732
|
fontFamily: "var(--bw-font-family)",
|
|
10343
10733
|
borderBottom: "2px solid var(--bw-highlight-color)",
|
|
10344
10734
|
paddingBottom: 4,
|
|
10345
|
-
}, children: "Zahlung" }), u$2(PaymentForm, { config: config, eventDetails: eventDetails, formData: form.getValues(), totalAmount: paymentAmount, discountCode:
|
|
10735
|
+
}, children: "Zahlung" }), u$2(PaymentForm, { config: config, eventDetails: eventDetails, formData: form.getValues(), totalAmount: paymentAmount, discountCode: appliedDiscountCode ? {
|
|
10736
|
+
id: appliedDiscountCode.id,
|
|
10737
|
+
code: appliedDiscountCode.code,
|
|
10738
|
+
description: appliedDiscountCode.description || undefined,
|
|
10739
|
+
type: appliedDiscountCode.discountType || "percentage",
|
|
10740
|
+
value: appliedDiscountCode.discountValue || 0,
|
|
10741
|
+
discountAmount: appliedDiscountCode.discountAmount,
|
|
10742
|
+
newTotal: appliedDiscountCode.newTotal,
|
|
10743
|
+
} : null, giftCards: appliedGiftCards, onSuccess: onSuccess, onError: onError, systemConfig: systemConfig, stripePromise: stripePromise, stripeAppearance: stripeAppearance })] }));
|
|
10346
10744
|
})()] })] }), u$2("style", { children: `
|
|
10347
10745
|
.booking-widget-container *,
|
|
10348
10746
|
.booking-widget-container *::before,
|
|
@@ -11369,137 +11767,155 @@
|
|
|
11369
11767
|
font-size: 1.1rem !important;
|
|
11370
11768
|
}
|
|
11371
11769
|
}
|
|
11372
|
-
` }), u$2(Sidebar, { isOpen: isOpen, onClose: handleClose, title:
|
|
11373
|
-
|
|
11374
|
-
|
|
11375
|
-
|
|
11376
|
-
|
|
11377
|
-
|
|
11378
|
-
|
|
11379
|
-
|
|
11380
|
-
backgroundColor:
|
|
11381
|
-
|
|
11382
|
-
|
|
11383
|
-
|
|
11384
|
-
|
|
11385
|
-
|
|
11386
|
-
|
|
11387
|
-
|
|
11388
|
-
|
|
11389
|
-
|
|
11390
|
-
|
|
11391
|
-
:
|
|
11392
|
-
|
|
11393
|
-
|
|
11394
|
-
|
|
11395
|
-
|
|
11396
|
-
|
|
11397
|
-
|
|
11398
|
-
|
|
11399
|
-
|
|
11400
|
-
|
|
11401
|
-
|
|
11402
|
-
|
|
11403
|
-
|
|
11404
|
-
|
|
11405
|
-
|
|
11406
|
-
|
|
11407
|
-
|
|
11408
|
-
|
|
11409
|
-
|
|
11410
|
-
|
|
11411
|
-
|
|
11412
|
-
|
|
11413
|
-
|
|
11414
|
-
|
|
11415
|
-
|
|
11416
|
-
|
|
11417
|
-
|
|
11418
|
-
|
|
11419
|
-
|
|
11420
|
-
|
|
11421
|
-
|
|
11422
|
-
|
|
11423
|
-
|
|
11424
|
-
|
|
11425
|
-
|
|
11426
|
-
|
|
11427
|
-
|
|
11428
|
-
|
|
11429
|
-
|
|
11430
|
-
|
|
11431
|
-
|
|
11432
|
-
|
|
11433
|
-
|
|
11434
|
-
|
|
11435
|
-
|
|
11436
|
-
|
|
11437
|
-
|
|
11438
|
-
|
|
11439
|
-
|
|
11440
|
-
|
|
11441
|
-
|
|
11442
|
-
|
|
11443
|
-
|
|
11444
|
-
|
|
11445
|
-
|
|
11446
|
-
|
|
11447
|
-
}, children:
|
|
11448
|
-
|
|
11449
|
-
|
|
11450
|
-
|
|
11451
|
-
|
|
11452
|
-
|
|
11453
|
-
|
|
11454
|
-
|
|
11455
|
-
|
|
11456
|
-
|
|
11457
|
-
|
|
11458
|
-
|
|
11459
|
-
|
|
11460
|
-
|
|
11461
|
-
|
|
11462
|
-
|
|
11463
|
-
|
|
11464
|
-
|
|
11465
|
-
|
|
11466
|
-
|
|
11467
|
-
|
|
11468
|
-
|
|
11469
|
-
|
|
11470
|
-
|
|
11471
|
-
|
|
11472
|
-
|
|
11473
|
-
|
|
11474
|
-
|
|
11475
|
-
|
|
11476
|
-
|
|
11477
|
-
|
|
11478
|
-
|
|
11479
|
-
|
|
11480
|
-
|
|
11481
|
-
|
|
11482
|
-
|
|
11483
|
-
|
|
11484
|
-
|
|
11485
|
-
|
|
11486
|
-
|
|
11487
|
-
|
|
11488
|
-
|
|
11489
|
-
|
|
11490
|
-
|
|
11491
|
-
|
|
11492
|
-
|
|
11493
|
-
|
|
11494
|
-
|
|
11495
|
-
|
|
11496
|
-
|
|
11497
|
-
|
|
11498
|
-
|
|
11499
|
-
|
|
11500
|
-
|
|
11501
|
-
|
|
11502
|
-
|
|
11770
|
+
` }), u$2(Sidebar, { isOpen: isOpen, onClose: handleClose, title: `${selectedEventType?.name}`, children: u$2("div", { className: "bw-event-instance-list", style: { padding: "24px" }, children: u$2("div", { style: {
|
|
11771
|
+
display: "flex",
|
|
11772
|
+
flexDirection: "column",
|
|
11773
|
+
gap: "20px",
|
|
11774
|
+
}, children: monthYearGroups.map(({ key, label, events, minPrice, year }, idx) => {
|
|
11775
|
+
const monthPriceDisplayInfo = getMonthPriceDisplayInfo(minPrice);
|
|
11776
|
+
return (u$2(k$3, { children: [idx > 0 && monthYearGroups[idx - 1].year !== year && (u$2("div", { style: {
|
|
11777
|
+
height: 1,
|
|
11778
|
+
backgroundColor: "var(--bw-border-color)",
|
|
11779
|
+
margin: "4px 0",
|
|
11780
|
+
} })), u$2(Accordion, { title: label, priceInfo: u$2("div", { style: {
|
|
11781
|
+
fontSize: "1rem",
|
|
11782
|
+
backgroundColor: monthPriceDisplayInfo
|
|
11783
|
+
? monthPriceDisplayInfo.backgroundColor
|
|
11784
|
+
: "#14532d",
|
|
11785
|
+
color: monthPriceDisplayInfo
|
|
11786
|
+
? monthPriceDisplayInfo.textColor
|
|
11787
|
+
: "#4ade80",
|
|
11788
|
+
fontWeight: 500,
|
|
11789
|
+
marginLeft: "auto",
|
|
11790
|
+
padding: "4px 8px",
|
|
11791
|
+
borderRadius: "var(--bw-border-radius-small)",
|
|
11792
|
+
border: monthPriceDisplayInfo ? "none" : undefined,
|
|
11793
|
+
boxShadow: monthPriceDisplayInfo
|
|
11794
|
+
? "0 2px 4px rgba(0, 0, 0, 0.2)"
|
|
11795
|
+
: undefined,
|
|
11796
|
+
}, children: `ab ${formatCurrency(minPrice)}` }), isOpen: openGroups.has(key), onToggle: () => toggleGroup(key), children: u$2("div", { style: {
|
|
11797
|
+
display: "flex",
|
|
11798
|
+
flexDirection: "column",
|
|
11799
|
+
gap: "12px",
|
|
11800
|
+
paddingTop: "12px",
|
|
11801
|
+
}, children: events.map((event) => {
|
|
11802
|
+
const availableSpots = event.maxParticipants - event.participantCount;
|
|
11803
|
+
const isFullyBooked = availableSpots === 0;
|
|
11804
|
+
const startDate = new Date(event.startTime);
|
|
11805
|
+
const isPastEvent = today.toISOString() >= startDate.toISOString();
|
|
11806
|
+
return (u$2("div", { className: "bw-event-instance-card", style: {
|
|
11807
|
+
position: "relative",
|
|
11808
|
+
cursor: !isFullyBooked && !isPastEvent && event.bookingOpen
|
|
11809
|
+
? "pointer"
|
|
11810
|
+
: "not-allowed",
|
|
11811
|
+
border: "1px solid var(--bw-border-color)",
|
|
11812
|
+
backgroundColor: "var(--bw-surface-color)",
|
|
11813
|
+
borderRadius: "var(--bw-border-radius)",
|
|
11814
|
+
padding: "16px 20px",
|
|
11815
|
+
transition: "all 0.2s ease",
|
|
11816
|
+
opacity: isFullyBooked || isPastEvent ? 0.3 : 1,
|
|
11817
|
+
filter: isFullyBooked || isPastEvent ? "grayscale(40%)" : "none",
|
|
11818
|
+
fontFamily: "var(--bw-font-family)",
|
|
11819
|
+
}, onClick: () => {
|
|
11820
|
+
if (!isFullyBooked && !isPastEvent && event.bookingOpen) {
|
|
11821
|
+
handleEventInstanceSelect(event);
|
|
11822
|
+
}
|
|
11823
|
+
}, onMouseEnter: (e) => {
|
|
11824
|
+
if (!isFullyBooked && !isPastEvent && event.bookingOpen) {
|
|
11825
|
+
e.currentTarget.style.transform = "scale(1.02)";
|
|
11826
|
+
e.currentTarget.style.backgroundColor =
|
|
11827
|
+
"var(--bw-surface-muted, rgba(59, 130, 246, 0.1))";
|
|
11828
|
+
}
|
|
11829
|
+
}, onMouseLeave: (e) => {
|
|
11830
|
+
if (!isFullyBooked && !isPastEvent && event.bookingOpen) {
|
|
11831
|
+
e.currentTarget.style.transform = "scale(1)";
|
|
11832
|
+
e.currentTarget.style.backgroundColor = "var(--bw-surface-color)";
|
|
11833
|
+
}
|
|
11834
|
+
}, children: [selectedEventInstanceId === event.id && isLoadingEventDetails && (u$2("div", { style: {
|
|
11835
|
+
position: "absolute",
|
|
11836
|
+
top: 0,
|
|
11837
|
+
left: 0,
|
|
11838
|
+
width: "100%",
|
|
11839
|
+
height: "100%",
|
|
11840
|
+
backgroundColor: "var(--bw-overlay-color, rgba(15, 23, 42, 0.8))",
|
|
11841
|
+
borderRadius: "var(--bw-border-radius)",
|
|
11842
|
+
display: "flex",
|
|
11843
|
+
alignItems: "center",
|
|
11844
|
+
justifyContent: "center",
|
|
11845
|
+
}, children: u$2("div", { style: {
|
|
11846
|
+
width: "32px",
|
|
11847
|
+
height: "32px",
|
|
11848
|
+
color: "var(--bw-highlight-color-muted, rgba(59, 130, 246, 0.8))",
|
|
11849
|
+
animation: "spin 1s linear infinite",
|
|
11850
|
+
fontSize: "32px",
|
|
11851
|
+
}, children: spinner() }) })), u$2(SpecialPriceBadge, { price: event.price, yearPrices: yearPrices }), u$2(AllocationBadge, { availableSpots: availableSpots, maxParticipants: event.maxParticipants }), u$2("div", { style: {
|
|
11852
|
+
display: "flex",
|
|
11853
|
+
justifyContent: "space-between",
|
|
11854
|
+
width: "100%",
|
|
11855
|
+
alignItems: "start",
|
|
11856
|
+
gap: "12px",
|
|
11857
|
+
marginBottom: "4px",
|
|
11858
|
+
}, children: [u$2("div", { style: { display: "flex", alignItems: "start", gap: "12px" }, children: [u$2("div", { className: "bw-event-instance-datebox", style: {
|
|
11859
|
+
fontSize: "var(--bw-font-size)",
|
|
11860
|
+
transition: "all 0.2s ease",
|
|
11861
|
+
borderRadius: "var(--bw-border-radius-small)",
|
|
11862
|
+
borderTop: `4px solid var(--bw-border-color)`,
|
|
11863
|
+
border: "1px solid var(--bw-border-color)",
|
|
11864
|
+
width: "40px",
|
|
11865
|
+
height: "40px",
|
|
11866
|
+
display: "flex",
|
|
11867
|
+
alignItems: "center",
|
|
11868
|
+
justifyContent: "center",
|
|
11869
|
+
fontWeight: "bold",
|
|
11870
|
+
color: "var(--bw-text-color)",
|
|
11871
|
+
backgroundColor: "var(--bw-background-color)",
|
|
11872
|
+
}, children: startDate.getDate() }), u$2("div", { style: {
|
|
11873
|
+
fontSize: "var(--bw-font-size)",
|
|
11874
|
+
color: "var(--bw-text-color)",
|
|
11875
|
+
display: "flex",
|
|
11876
|
+
flexDirection: "column",
|
|
11877
|
+
alignItems: "start",
|
|
11878
|
+
justifyContent: "start",
|
|
11879
|
+
lineHeight: "1.2",
|
|
11880
|
+
}, children: [u$2("div", { children: [u$2("span", { className: "bw-event-instance-title", style: { fontWeight: "600", marginBottom: "2px" }, children: formatWeekday(event.startTime) }), formatWeekday(event.startTime) !==
|
|
11881
|
+
formatWeekday(event.endTime) && (u$2(k$3, { children: [u$2("span", { style: {
|
|
11882
|
+
color: "var(--bw-text-muted)",
|
|
11883
|
+
fontSize: "14px",
|
|
11884
|
+
}, children: " - " }), u$2("span", { className: "bw-event-instance-title", style: { fontWeight: "600", marginBottom: "2px" }, children: formatWeekday(event.endTime) })] }))] }), u$2("div", { children: formatWeekday(event.startTime) ===
|
|
11885
|
+
formatWeekday(event.endTime) ? (u$2(k$3, { children: [u$2("span", { style: {
|
|
11886
|
+
color: "var(--bw-text-muted)",
|
|
11887
|
+
fontSize: "14px",
|
|
11888
|
+
}, children: formatTime(event.startTime) }), u$2("span", { style: {
|
|
11889
|
+
color: "var(--bw-text-muted)",
|
|
11890
|
+
fontSize: "14px",
|
|
11891
|
+
}, children: " - " }), u$2("span", { style: {
|
|
11892
|
+
color: "var(--bw-text-muted)",
|
|
11893
|
+
fontSize: "14px",
|
|
11894
|
+
}, children: formatTime(event.endTime) })] })) : (u$2("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: [formatTime(event.startTime), " Uhr"] })) })] }), u$2("span", { style: {
|
|
11895
|
+
fontSize: "12px",
|
|
11896
|
+
fontWeight: 400,
|
|
11897
|
+
color: "var(--bw-text-muted)",
|
|
11898
|
+
marginLeft: "6px",
|
|
11899
|
+
background: "var(--bw-background-muted)",
|
|
11900
|
+
whiteSpace: "nowrap",
|
|
11901
|
+
}, children: [event.durationDays, " Tag", event.durationDays > 1 ? "e" : ""] })] }), u$2("div", { className: "bw-event-instance-price", style: {
|
|
11902
|
+
textAlign: "right",
|
|
11903
|
+
display: "flex",
|
|
11904
|
+
flexDirection: "column",
|
|
11905
|
+
alignItems: "end",
|
|
11906
|
+
}, children: u$2(PriceDisplay, { price: event.price, yearPrices: yearPrices }) })] }), event.name !== selectedEventType?.name && (u$2("h4", { className: "bw-event-instance-title", style: {
|
|
11907
|
+
fontSize: "var(--bw-font-size)",
|
|
11908
|
+
fontWeight: "600",
|
|
11909
|
+
color: "var(--bw-text-color)",
|
|
11910
|
+
lineHeight: "1.25",
|
|
11911
|
+
margin: "0 0 2px 0",
|
|
11912
|
+
display: "flex",
|
|
11913
|
+
alignItems: "center",
|
|
11914
|
+
gap: "8px",
|
|
11915
|
+
maxWidth: "230px",
|
|
11916
|
+
}, children: event.name }))] }, event.id));
|
|
11917
|
+
}) }) })] }, key));
|
|
11918
|
+
}) }) }) })] }));
|
|
11503
11919
|
}
|
|
11504
11920
|
|
|
11505
11921
|
// Loading skeleton component for NextEventsPreview
|