@bigz-app/booking-widget 0.3.5 → 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 +636 -211
- 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 +637 -212
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +638 -213
- package/dist/index.esm.js.map +1 -1
- package/package.json +75 -71
package/dist/index.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React__default from 'react';
|
|
2
|
-
import React__default__default, { createContext, useState, useEffect, useMemo, useContext, useRef } from 'react';
|
|
2
|
+
import React__default__default, { createContext, useState, useEffect, useMemo, useContext, useRef, useCallback, Fragment as Fragment$1 } from 'react';
|
|
3
3
|
import { createRoot } from 'react-dom/client';
|
|
4
4
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
5
5
|
import ReactDOM, { createPortal } from 'react-dom';
|
|
@@ -6888,7 +6888,7 @@ const preprocessMarkdown$1 = (markdown) => {
|
|
|
6888
6888
|
// Convert double underscores to HTML underline tags for React Markdown
|
|
6889
6889
|
return markdown.replace(/__([^_]+)__/g, "<u>$1</u>");
|
|
6890
6890
|
};
|
|
6891
|
-
const IconCheck$
|
|
6891
|
+
const IconCheck$2 = ({ size = 16, color = "#10b981" }) => (jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsx("polyline", { points: "20 6 9 17 4 12" }) }));
|
|
6892
6892
|
const IconWave$1 = ({ size = 20, color = "#0ea5e9" }) => (jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsx("path", { d: "M2 18c2-2 6-2 8 0s6 2 8 0 6-2 8 0" }), jsx("path", { d: "M2 12c2-2 6-2 8 0s6 2 8 0 6-2 8 0" }), jsx("path", { d: "M2 6c2-2 6-2 8 0s6 2 8 0 6-2 8 0" })] }));
|
|
6893
6893
|
function EventTypeDetailsDialog({ isOpen, onClose, eventType, onEventTypeSelect, }) {
|
|
6894
6894
|
if (!isOpen || !eventType)
|
|
@@ -6935,7 +6935,7 @@ function EventTypeDetailsDialog({ isOpen, onClose, eventType, onEventTypeSelect,
|
|
|
6935
6935
|
fontSize: "16px",
|
|
6936
6936
|
lineHeight: "1.6",
|
|
6937
6937
|
color: "var(--bw-text-color)",
|
|
6938
|
-
}, children: [jsx("div", { style: { marginTop: "4px", flexShrink: 0 }, children: jsx(IconCheck$
|
|
6938
|
+
}, children: [jsx("div", { style: { marginTop: "4px", flexShrink: 0 }, children: jsx(IconCheck$2, { size: 16, color: "var(--bw-success-color)" }) }), jsx("span", { children: highlight.trim() })] }, index))) }) }) }))] }), eventType.description && (jsxs("div", { style: {
|
|
6939
6939
|
marginBottom: "24px",
|
|
6940
6940
|
color: "var(--bw-text-muted)",
|
|
6941
6941
|
fontSize: "16px",
|
|
@@ -7244,7 +7244,7 @@ const preprocessMarkdown = (markdown) => {
|
|
|
7244
7244
|
// Custom minimal SVG icons (Lucide-style)
|
|
7245
7245
|
const IconClock = ({ size = 16, color = "#10b981" }) => (jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsx("circle", { cx: "12", cy: "12", r: "10" }), jsx("polyline", { points: "12 6 12 12 16 14" })] }));
|
|
7246
7246
|
const IconCalendar = ({ size = 16, color = "#3b82f6" }) => (jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsx("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2" }), jsx("line", { x1: "16", y1: "2", x2: "16", y2: "6" }), jsx("line", { x1: "8", y1: "2", x2: "8", y2: "6" }), jsx("line", { x1: "3", y1: "10", x2: "21", y2: "10" })] }));
|
|
7247
|
-
const IconCheck = ({ size = 16, color = "#10b981" }) => (jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsx("polyline", { points: "20 6 9 17 4 12" }) }));
|
|
7247
|
+
const IconCheck$1 = ({ size = 16, color = "#10b981" }) => (jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsx("polyline", { points: "20 6 9 17 4 12" }) }));
|
|
7248
7248
|
// Wave icon for booking action
|
|
7249
7249
|
const IconWave = ({ size = 20, color = "#0ea5e9" }) => (jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsx("path", { d: "M2 18c2-2 6-2 8 0s6 2 8 0 6-2 8 0" }), jsx("path", { d: "M2 12c2-2 6-2 8 0s6 2 8 0 6-2 8 0" }), jsx("path", { d: "M2 6c2-2 6-2 8 0s6 2 8 0 6-2 8 0" })] }));
|
|
7250
7250
|
// Loading skeleton component that matches the actual design
|
|
@@ -7708,7 +7708,7 @@ function EventTypeSelection({ eventTypes, onEventTypeSelect, isLoading = false,
|
|
|
7708
7708
|
color: "var(--bw-text-muted)",
|
|
7709
7709
|
position: "relative",
|
|
7710
7710
|
maxWidth: "100%",
|
|
7711
|
-
}, children: [jsx("div", { style: { marginTop: "4px", flexShrink: 0 }, children: jsx(IconCheck, { size: 16, color: "var(--bw-success-color)" }) }), jsx("span", { style: {
|
|
7711
|
+
}, children: [jsx("div", { style: { marginTop: "4px", flexShrink: 0 }, children: jsx(IconCheck$1, { size: 16, color: "var(--bw-success-color)" }) }), jsx("span", { style: {
|
|
7712
7712
|
textOverflow: "ellipsis",
|
|
7713
7713
|
overflow: "hidden",
|
|
7714
7714
|
whiteSpace: "nowrap",
|
|
@@ -9111,6 +9111,110 @@ var reactStripe_umd = {exports: {}};
|
|
|
9111
9111
|
|
|
9112
9112
|
var reactStripe_umdExports = reactStripe_umd.exports;
|
|
9113
9113
|
|
|
9114
|
+
// Component for bookings fully covered by gift cards (no Stripe payment needed)
|
|
9115
|
+
function GiftCardOnlyBooking({ config, eventDetails, formData, discountCode, giftCards, onSuccess, onError, }) {
|
|
9116
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
9117
|
+
const [error, setError] = useState(null);
|
|
9118
|
+
const handleBooking = async () => {
|
|
9119
|
+
setIsLoading(true);
|
|
9120
|
+
setError(null);
|
|
9121
|
+
try {
|
|
9122
|
+
// Create booking directly without Stripe payment
|
|
9123
|
+
const requestData = {
|
|
9124
|
+
eventInstanceId: config.eventInstanceId || eventDetails.id,
|
|
9125
|
+
organizationId: config.organizationId,
|
|
9126
|
+
participants: formData.participants.filter((p) => p.name?.trim()),
|
|
9127
|
+
discountCode: discountCode?.code,
|
|
9128
|
+
giftCardCodes: giftCards.map((gc) => gc.code),
|
|
9129
|
+
customerName: formData.customerName?.trim(),
|
|
9130
|
+
customerEmail: formData.customerEmail?.trim(),
|
|
9131
|
+
customerPhone: formData.customerPhone?.trim(),
|
|
9132
|
+
comment: formData.comment?.trim(),
|
|
9133
|
+
paymentMethod: "gift_card",
|
|
9134
|
+
};
|
|
9135
|
+
const response = await fetch(getApiUrl(config.apiBaseUrl, "/booking/create-gift-card-booking"), {
|
|
9136
|
+
method: "POST",
|
|
9137
|
+
headers: createApiHeaders(config),
|
|
9138
|
+
body: JSON.stringify(createRequestBody(config, requestData)),
|
|
9139
|
+
});
|
|
9140
|
+
const data = await response.json();
|
|
9141
|
+
if (response.ok) {
|
|
9142
|
+
onSuccess({
|
|
9143
|
+
booking: data.booking,
|
|
9144
|
+
order: data.order,
|
|
9145
|
+
giftCardRedemptions: data.giftCardRedemptions,
|
|
9146
|
+
});
|
|
9147
|
+
}
|
|
9148
|
+
else {
|
|
9149
|
+
setError(data.error || "Fehler beim Erstellen der Buchung");
|
|
9150
|
+
onError(data.error || "Fehler beim Erstellen der Buchung");
|
|
9151
|
+
}
|
|
9152
|
+
}
|
|
9153
|
+
catch (err) {
|
|
9154
|
+
setError(err.message || "Fehler beim Erstellen der Buchung");
|
|
9155
|
+
onError(err.message || "Fehler beim Erstellen der Buchung");
|
|
9156
|
+
}
|
|
9157
|
+
finally {
|
|
9158
|
+
setIsLoading(false);
|
|
9159
|
+
}
|
|
9160
|
+
};
|
|
9161
|
+
const totalGiftCardAmount = giftCards.reduce((sum, gc) => sum + (gc.balanceToUse || gc.discountAmount || 0), 0);
|
|
9162
|
+
return (jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "var(--bw-spacing)" }, children: [jsxs("div", { style: {
|
|
9163
|
+
backgroundColor: "var(--bw-success-color)15",
|
|
9164
|
+
border: "1px solid var(--bw-success-color)40",
|
|
9165
|
+
borderRadius: "var(--bw-border-radius)",
|
|
9166
|
+
padding: "var(--bw-spacing)",
|
|
9167
|
+
}, children: [jsx("div", { style: {
|
|
9168
|
+
display: "flex",
|
|
9169
|
+
alignItems: "center",
|
|
9170
|
+
gap: "8px",
|
|
9171
|
+
marginBottom: "8px",
|
|
9172
|
+
color: "var(--bw-success-color)",
|
|
9173
|
+
fontFamily: "var(--bw-font-family)",
|
|
9174
|
+
fontWeight: "600",
|
|
9175
|
+
}, children: "\uD83C\uDF81 Vollst\u00E4ndig durch Gutschein(e) gedeckt" }), jsxs("div", { style: {
|
|
9176
|
+
fontSize: "var(--bw-font-size)",
|
|
9177
|
+
color: "var(--bw-text-muted)",
|
|
9178
|
+
fontFamily: "var(--bw-font-family)",
|
|
9179
|
+
}, children: ["Gutschein-Guthaben: ", formatCurrency(totalGiftCardAmount)] })] }), error && (jsxs("div", { style: {
|
|
9180
|
+
backgroundColor: "var(--bw-error-color)15",
|
|
9181
|
+
border: "1px solid var(--bw-error-color)40",
|
|
9182
|
+
borderRadius: "var(--bw-border-radius)",
|
|
9183
|
+
padding: "var(--bw-spacing)",
|
|
9184
|
+
color: "var(--bw-error-color)",
|
|
9185
|
+
fontSize: "var(--bw-font-size)",
|
|
9186
|
+
fontFamily: "var(--bw-font-family)",
|
|
9187
|
+
}, children: ["\u26A0\uFE0F ", error] })), jsx("button", { type: "button", onClick: handleBooking, disabled: isLoading, style: {
|
|
9188
|
+
width: "100%",
|
|
9189
|
+
padding: "12px 24px",
|
|
9190
|
+
backgroundColor: "var(--bw-highlight-color)",
|
|
9191
|
+
color: "#fff",
|
|
9192
|
+
border: "none",
|
|
9193
|
+
borderRadius: "var(--bw-border-radius)",
|
|
9194
|
+
fontSize: "var(--bw-font-size)",
|
|
9195
|
+
fontWeight: "600",
|
|
9196
|
+
cursor: isLoading ? "not-allowed" : "pointer",
|
|
9197
|
+
opacity: isLoading ? 0.6 : 1,
|
|
9198
|
+
transition: "all 0.2s ease",
|
|
9199
|
+
fontFamily: "var(--bw-font-family)",
|
|
9200
|
+
display: "flex",
|
|
9201
|
+
alignItems: "center",
|
|
9202
|
+
justifyContent: "center",
|
|
9203
|
+
gap: "8px",
|
|
9204
|
+
}, children: isLoading ? (jsxs(Fragment, { children: [jsx("div", { style: {
|
|
9205
|
+
width: "16px",
|
|
9206
|
+
height: "16px",
|
|
9207
|
+
border: "2px solid #fff",
|
|
9208
|
+
borderTopColor: "transparent",
|
|
9209
|
+
borderRadius: "50%",
|
|
9210
|
+
animation: "spin 1s linear infinite",
|
|
9211
|
+
} }), "Buchung wird erstellt..."] })) : ("Mit Gutschein buchen") }), jsx("style", { children: `
|
|
9212
|
+
@keyframes spin {
|
|
9213
|
+
from { transform: rotate(0deg); }
|
|
9214
|
+
to { transform: rotate(360deg); }
|
|
9215
|
+
}
|
|
9216
|
+
` })] }));
|
|
9217
|
+
}
|
|
9114
9218
|
const spinner$1 = (borderColor) => (jsx("div", { style: {
|
|
9115
9219
|
width: "auto",
|
|
9116
9220
|
height: "auto",
|
|
@@ -9127,7 +9231,7 @@ const spinner$1 = (borderColor) => (jsx("div", { style: {
|
|
|
9127
9231
|
borderRadius: "50%",
|
|
9128
9232
|
} }) }));
|
|
9129
9233
|
// Inner component that uses the Stripe hooks
|
|
9130
|
-
function PaymentFormInner({ config, eventDetails, formData, totalAmount, discountCode, onSuccess, onError, }) {
|
|
9234
|
+
function PaymentFormInner({ config, eventDetails, formData, totalAmount, discountCode, giftCards, onSuccess, onError, }) {
|
|
9131
9235
|
const stripe = reactStripe_umdExports.useStripe();
|
|
9132
9236
|
const elements = reactStripe_umdExports.useElements();
|
|
9133
9237
|
const [isLoading, setIsLoading] = useState(false);
|
|
@@ -9258,7 +9362,7 @@ function PaymentFormInner({ config, eventDetails, formData, totalAmount, discoun
|
|
|
9258
9362
|
` })] }));
|
|
9259
9363
|
}
|
|
9260
9364
|
// Main PaymentForm component that handles payment intent creation and Elements wrapper
|
|
9261
|
-
function PaymentForm({ config, eventDetails, formData, totalAmount, discountCode, onSuccess, onError, systemConfig, stripePromise, stripeAppearance, }) {
|
|
9365
|
+
function PaymentForm({ config, eventDetails, formData, totalAmount, discountCode, giftCards, onSuccess, onError, systemConfig, stripePromise, stripeAppearance, }) {
|
|
9262
9366
|
const [clientSecret, setClientSecret] = useState(null);
|
|
9263
9367
|
const [paymentIntentId, setPaymentIntentId] = useState(null);
|
|
9264
9368
|
const [isCreatingPaymentIntent, setIsCreatingPaymentIntent] = useState(false);
|
|
@@ -9354,6 +9458,7 @@ function PaymentForm({ config, eventDetails, formData, totalAmount, discountCode
|
|
|
9354
9458
|
currency: "eur",
|
|
9355
9459
|
participants: formData.participants.filter((p) => p.name?.trim()),
|
|
9356
9460
|
discountCode: discountCode?.code,
|
|
9461
|
+
giftCardCodes: giftCards?.map((gc) => gc.code) || [],
|
|
9357
9462
|
customerName: formData.customerName?.trim(),
|
|
9358
9463
|
customerEmail: formData.customerEmail?.trim(),
|
|
9359
9464
|
customerPhone: formData.customerPhone?.trim(),
|
|
@@ -9415,8 +9520,21 @@ function PaymentForm({ config, eventDetails, formData, totalAmount, discountCode
|
|
|
9415
9520
|
formData.customerName,
|
|
9416
9521
|
totalAmount,
|
|
9417
9522
|
discountCode,
|
|
9523
|
+
giftCards,
|
|
9418
9524
|
config,
|
|
9419
9525
|
]);
|
|
9526
|
+
// Calculate total gift card coverage
|
|
9527
|
+
const totalGiftCardAmount = giftCards?.reduce((sum, gc) => sum + (gc.balanceToUse || gc.discountAmount || 0), 0) || 0;
|
|
9528
|
+
const baseTotal = eventDetails?.price
|
|
9529
|
+
? eventDetails.price * (formData.participants?.filter((p) => p.name?.trim()).length || 0)
|
|
9530
|
+
: 0;
|
|
9531
|
+
const discountAmount = discountCode?.discountAmount || 0;
|
|
9532
|
+
const amountAfterDiscount = Math.max(0, baseTotal - discountAmount);
|
|
9533
|
+
const isFullyCoveredByGiftCards = totalGiftCardAmount >= amountAfterDiscount && amountAfterDiscount > 0;
|
|
9534
|
+
// If gift cards fully cover the payment, show a simplified booking button
|
|
9535
|
+
if (isFullyCoveredByGiftCards && totalAmount <= 0) {
|
|
9536
|
+
return (jsx(GiftCardOnlyBooking, { config: config, eventDetails: eventDetails, formData: formData, discountCode: discountCode, giftCards: giftCards || [], onSuccess: onSuccess, onError: onError }));
|
|
9537
|
+
}
|
|
9420
9538
|
// Show loading state while creating payment intent
|
|
9421
9539
|
if (isCreatingPaymentIntent || !clientSecret) {
|
|
9422
9540
|
return (jsxs("div", { style: {
|
|
@@ -9450,7 +9568,7 @@ function PaymentForm({ config, eventDetails, formData, totalAmount, discountCode
|
|
|
9450
9568
|
clientSecret,
|
|
9451
9569
|
appearance: stripeAppearance || { theme: "stripe" },
|
|
9452
9570
|
locale: config.locale || "de",
|
|
9453
|
-
}, children: jsx(PaymentFormInner, { config: config, eventDetails: eventDetails, formData: formData, totalAmount: totalAmount, discountCode: discountCode, onSuccess: (result) => {
|
|
9571
|
+
}, children: jsx(PaymentFormInner, { config: config, eventDetails: eventDetails, formData: formData, totalAmount: totalAmount, discountCode: discountCode, giftCards: giftCards, onSuccess: (result) => {
|
|
9454
9572
|
// Clear persisted PI data on successful payment
|
|
9455
9573
|
clearPersistedPaymentIntent();
|
|
9456
9574
|
setPaymentIntentId(null);
|
|
@@ -9655,6 +9773,222 @@ function Accordion({ title, priceInfo, children, isOpen, onToggle }) {
|
|
|
9655
9773
|
}, children: children }))] }));
|
|
9656
9774
|
}
|
|
9657
9775
|
|
|
9776
|
+
// Icons
|
|
9777
|
+
const IconTicket = ({ size = 20, color = "currentColor" }) => (jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsx("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" }), jsx("path", { d: "M13 5v2" }), jsx("path", { d: "M13 17v2" }), jsx("path", { d: "M13 11v2" })] }));
|
|
9778
|
+
const IconGift = ({ size = 20, color = "currentColor" }) => (jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsx("rect", { x: "3", y: "8", width: "18", height: "4", rx: "1" }), jsx("path", { d: "M12 8v13" }), jsx("path", { d: "M19 12v7a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-7" }), jsx("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" })] }));
|
|
9779
|
+
const IconCheck = ({ size = 16, color = "currentColor" }) => (jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsx("polyline", { points: "20 6 9 17 4 12" }) }));
|
|
9780
|
+
const IconX = ({ size = 16, color = "currentColor" }) => (jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }));
|
|
9781
|
+
const IconSpinner = ({ size = 16, color = "currentColor" }) => (jsx("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: jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }) }));
|
|
9782
|
+
function VoucherInput({ config, orderValue, eventInstanceId, customerEmail, onVoucherValidated, appliedVouchers, onRemoveVoucher, disabled = false, }) {
|
|
9783
|
+
const [inputValue, setInputValue] = useState("");
|
|
9784
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
9785
|
+
const [error, setError] = useState(null);
|
|
9786
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
9787
|
+
// Check if a discount code is already applied (only one allowed)
|
|
9788
|
+
const hasDiscountCode = appliedVouchers.some((v) => v.type === "discount");
|
|
9789
|
+
const validateVoucher = useCallback(async (code) => {
|
|
9790
|
+
if (!code.trim()) {
|
|
9791
|
+
setError(null);
|
|
9792
|
+
return;
|
|
9793
|
+
}
|
|
9794
|
+
// Check if code is already applied
|
|
9795
|
+
if (appliedVouchers.some((v) => v.code.toUpperCase() === code.toUpperCase())) {
|
|
9796
|
+
setError("Dieser Code wurde bereits angewendet");
|
|
9797
|
+
return;
|
|
9798
|
+
}
|
|
9799
|
+
setIsLoading(true);
|
|
9800
|
+
setError(null);
|
|
9801
|
+
try {
|
|
9802
|
+
const response = await fetch(getApiUrl(config.apiBaseUrl, "/booking/validate-voucher"), {
|
|
9803
|
+
method: "POST",
|
|
9804
|
+
headers: createApiHeaders(config),
|
|
9805
|
+
body: JSON.stringify(createRequestBody(config, {
|
|
9806
|
+
code: code.trim(),
|
|
9807
|
+
orderValue: orderValue,
|
|
9808
|
+
eventInstanceId: eventInstanceId,
|
|
9809
|
+
customerEmail: customerEmail,
|
|
9810
|
+
})),
|
|
9811
|
+
});
|
|
9812
|
+
const data = await response.json();
|
|
9813
|
+
if (data.valid && data.voucher) {
|
|
9814
|
+
// Check if trying to add a second discount code
|
|
9815
|
+
if (data.voucher.type === "discount" && hasDiscountCode) {
|
|
9816
|
+
setError("Es kann nur ein Rabattcode verwendet werden");
|
|
9817
|
+
onVoucherValidated(null, "Es kann nur ein Rabattcode verwendet werden");
|
|
9818
|
+
return;
|
|
9819
|
+
}
|
|
9820
|
+
onVoucherValidated(data.voucher);
|
|
9821
|
+
setInputValue("");
|
|
9822
|
+
setError(null);
|
|
9823
|
+
}
|
|
9824
|
+
else {
|
|
9825
|
+
setError(data.error || "Code nicht gefunden oder ungültig");
|
|
9826
|
+
onVoucherValidated(null, data.error);
|
|
9827
|
+
}
|
|
9828
|
+
}
|
|
9829
|
+
catch (err) {
|
|
9830
|
+
const errorMsg = "Fehler beim Validieren des Codes";
|
|
9831
|
+
setError(errorMsg);
|
|
9832
|
+
onVoucherValidated(null, errorMsg);
|
|
9833
|
+
}
|
|
9834
|
+
finally {
|
|
9835
|
+
setIsLoading(false);
|
|
9836
|
+
}
|
|
9837
|
+
}, [
|
|
9838
|
+
config,
|
|
9839
|
+
orderValue,
|
|
9840
|
+
eventInstanceId,
|
|
9841
|
+
customerEmail,
|
|
9842
|
+
appliedVouchers,
|
|
9843
|
+
hasDiscountCode,
|
|
9844
|
+
onVoucherValidated,
|
|
9845
|
+
]);
|
|
9846
|
+
const handleSubmit = () => {
|
|
9847
|
+
if (inputValue.trim() && !isLoading && !disabled) {
|
|
9848
|
+
validateVoucher(inputValue);
|
|
9849
|
+
}
|
|
9850
|
+
};
|
|
9851
|
+
const handleKeyDown = (e) => {
|
|
9852
|
+
if (e.key === "Enter") {
|
|
9853
|
+
e.preventDefault();
|
|
9854
|
+
if (inputValue.trim() && !isLoading && !disabled) {
|
|
9855
|
+
validateVoucher(inputValue);
|
|
9856
|
+
}
|
|
9857
|
+
}
|
|
9858
|
+
};
|
|
9859
|
+
const inputStyle = {
|
|
9860
|
+
flex: 1,
|
|
9861
|
+
padding: "10px 12px",
|
|
9862
|
+
backgroundColor: "var(--bw-background-color)",
|
|
9863
|
+
border: "1px solid var(--bw-border-color)",
|
|
9864
|
+
borderRadius: "var(--bw-border-radius)",
|
|
9865
|
+
color: "var(--bw-text-color)",
|
|
9866
|
+
fontSize: "var(--bw-font-size)",
|
|
9867
|
+
fontFamily: "var(--bw-font-family)",
|
|
9868
|
+
outline: "none",
|
|
9869
|
+
transition: "all 0.2s ease",
|
|
9870
|
+
textTransform: "uppercase",
|
|
9871
|
+
};
|
|
9872
|
+
const buttonStyle = {
|
|
9873
|
+
padding: "10px 16px",
|
|
9874
|
+
backgroundColor: "var(--bw-highlight-color)",
|
|
9875
|
+
border: "none",
|
|
9876
|
+
borderRadius: "var(--bw-border-radius)",
|
|
9877
|
+
color: "#fff",
|
|
9878
|
+
fontSize: "var(--bw-font-size)",
|
|
9879
|
+
fontFamily: "var(--bw-font-family)",
|
|
9880
|
+
fontWeight: "600",
|
|
9881
|
+
cursor: disabled || isLoading ? "not-allowed" : "pointer",
|
|
9882
|
+
opacity: disabled || isLoading ? 0.6 : 1,
|
|
9883
|
+
transition: "all 0.2s ease",
|
|
9884
|
+
display: "flex",
|
|
9885
|
+
alignItems: "center",
|
|
9886
|
+
justifyContent: "center",
|
|
9887
|
+
gap: "6px",
|
|
9888
|
+
minWidth: "100px",
|
|
9889
|
+
};
|
|
9890
|
+
const appliedVoucherStyle = {
|
|
9891
|
+
display: "flex",
|
|
9892
|
+
alignItems: "center",
|
|
9893
|
+
justifyContent: "space-between",
|
|
9894
|
+
padding: "10px 12px",
|
|
9895
|
+
backgroundColor: "var(--bw-surface-color)",
|
|
9896
|
+
border: "1px solid var(--bw-border-color)",
|
|
9897
|
+
borderRadius: "var(--bw-border-radius)",
|
|
9898
|
+
marginBottom: "8px",
|
|
9899
|
+
};
|
|
9900
|
+
const removeButtonStyle = {
|
|
9901
|
+
background: "none",
|
|
9902
|
+
border: "none",
|
|
9903
|
+
padding: "4px",
|
|
9904
|
+
cursor: "pointer",
|
|
9905
|
+
color: "var(--bw-error-color)",
|
|
9906
|
+
display: "flex",
|
|
9907
|
+
alignItems: "center",
|
|
9908
|
+
justifyContent: "center",
|
|
9909
|
+
borderRadius: "50%",
|
|
9910
|
+
transition: "background-color 0.2s ease",
|
|
9911
|
+
};
|
|
9912
|
+
return (jsxs("div", { style: {
|
|
9913
|
+
backgroundColor: "var(--bw-surface-color)",
|
|
9914
|
+
border: "1px solid var(--bw-border-color)",
|
|
9915
|
+
borderRadius: "var(--bw-border-radius)",
|
|
9916
|
+
overflow: "hidden",
|
|
9917
|
+
}, children: [jsxs("button", { type: "button", onClick: () => setIsExpanded(!isExpanded), style: {
|
|
9918
|
+
width: "100%",
|
|
9919
|
+
padding: "var(--bw-spacing)",
|
|
9920
|
+
backgroundColor: "transparent",
|
|
9921
|
+
border: "none",
|
|
9922
|
+
cursor: "pointer",
|
|
9923
|
+
display: "flex",
|
|
9924
|
+
alignItems: "center",
|
|
9925
|
+
justifyContent: "space-between",
|
|
9926
|
+
color: "var(--bw-text-color)",
|
|
9927
|
+
fontFamily: "var(--bw-font-family)",
|
|
9928
|
+
fontSize: "var(--bw-font-size)",
|
|
9929
|
+
fontWeight: "500",
|
|
9930
|
+
}, children: [jsxs("span", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [jsx(IconTicket, { size: 18, color: "var(--bw-highlight-color)" }), "Rabattcode oder Gutschein", appliedVouchers.length > 0 && (jsx("span", { style: {
|
|
9931
|
+
backgroundColor: "var(--bw-highlight-color)",
|
|
9932
|
+
color: "#fff",
|
|
9933
|
+
padding: "2px 8px",
|
|
9934
|
+
borderRadius: "12px",
|
|
9935
|
+
fontSize: "12px",
|
|
9936
|
+
fontWeight: "600",
|
|
9937
|
+
}, children: appliedVouchers.length }))] }), jsx("span", { style: {
|
|
9938
|
+
transform: isExpanded ? "rotate(180deg)" : "rotate(0deg)",
|
|
9939
|
+
transition: "transform 0.2s ease",
|
|
9940
|
+
}, children: "\u25BC" })] }), isExpanded && (jsxs("div", { style: { padding: "0 var(--bw-spacing) var(--bw-spacing)" }, children: [appliedVouchers.length > 0 && (jsx("div", { style: { marginBottom: "12px" }, children: appliedVouchers.map((voucher) => (jsxs("div", { style: appliedVoucherStyle, children: [jsxs("div", { style: { display: "flex", alignItems: "center", gap: "10px" }, children: [voucher.type === "discount" ? (jsx(IconTicket, { size: 18, color: "var(--bw-success-color)" })) : (jsx(IconGift, { size: 18, color: "var(--bw-success-color)" })), jsxs("div", { children: [jsxs("div", { style: {
|
|
9941
|
+
fontFamily: "var(--bw-font-family)",
|
|
9942
|
+
fontSize: "var(--bw-font-size)",
|
|
9943
|
+
fontWeight: "600",
|
|
9944
|
+
color: "var(--bw-text-color)",
|
|
9945
|
+
display: "flex",
|
|
9946
|
+
alignItems: "center",
|
|
9947
|
+
gap: "6px",
|
|
9948
|
+
}, children: [jsx("span", { style: { fontFamily: "monospace" }, children: voucher.code }), jsx(IconCheck, { size: 14, color: "var(--bw-success-color)" })] }), jsxs("div", { style: {
|
|
9949
|
+
fontFamily: "var(--bw-font-family)",
|
|
9950
|
+
fontSize: "12px",
|
|
9951
|
+
color: "var(--bw-success-color)",
|
|
9952
|
+
}, children: [voucher.type === "discount"
|
|
9953
|
+
? `−${formatCurrency(voucher.discountAmount)} Rabatt`
|
|
9954
|
+
: `−${formatCurrency(voucher.balanceToUse || voucher.discountAmount)} Gutschein`, voucher.type === "giftCard" &&
|
|
9955
|
+
voucher.remainingBalance !== undefined &&
|
|
9956
|
+
voucher.remainingBalance > 0 && (jsxs("span", { style: { color: "var(--bw-text-muted)", marginLeft: "8px" }, children: ["(Rest: ", formatCurrency(voucher.remainingBalance), ")"] }))] })] })] }), jsx("button", { type: "button", onClick: () => onRemoveVoucher(voucher.code), style: removeButtonStyle, title: "Entfernen", children: jsx(IconX, { size: 16 }) })] }, voucher.code))) })), jsxs("div", { style: { display: "flex", gap: "8px" }, children: [jsx("input", { type: "text", value: inputValue, onChange: (e) => {
|
|
9957
|
+
setInputValue(e.target.value.toUpperCase());
|
|
9958
|
+
setError(null);
|
|
9959
|
+
}, onKeyDown: handleKeyDown, placeholder: hasDiscountCode
|
|
9960
|
+
? "Gutscheincode eingeben..."
|
|
9961
|
+
: "Rabatt- oder Gutscheincode eingeben...", style: inputStyle, disabled: disabled || isLoading, onFocus: (e) => {
|
|
9962
|
+
e.target.style.borderColor = "var(--bw-highlight-color)";
|
|
9963
|
+
e.target.style.boxShadow = "0 0 0 2px var(--bw-highlight-color)33";
|
|
9964
|
+
}, onBlur: (e) => {
|
|
9965
|
+
e.target.style.borderColor = "var(--bw-border-color)";
|
|
9966
|
+
e.target.style.boxShadow = "none";
|
|
9967
|
+
} }), jsx("button", { type: "button", onClick: handleSubmit, style: buttonStyle, disabled: disabled || isLoading || !inputValue.trim(), children: isLoading ? (jsx(IconSpinner, { size: 16, color: "#fff" })) : (jsxs(Fragment, { children: [jsx(IconCheck, { size: 16 }), "Einl\u00F6sen"] })) })] }), error && (jsxs("div", { style: {
|
|
9968
|
+
marginTop: "8px",
|
|
9969
|
+
padding: "8px 12px",
|
|
9970
|
+
backgroundColor: "var(--bw-error-color)15",
|
|
9971
|
+
border: "1px solid var(--bw-error-color)40",
|
|
9972
|
+
borderRadius: "var(--bw-border-radius)",
|
|
9973
|
+
color: "var(--bw-error-color)",
|
|
9974
|
+
fontSize: "var(--bw-font-size)",
|
|
9975
|
+
fontFamily: "var(--bw-font-family)",
|
|
9976
|
+
display: "flex",
|
|
9977
|
+
alignItems: "center",
|
|
9978
|
+
gap: "8px",
|
|
9979
|
+
}, children: [jsx(IconX, { size: 16 }), error] })), hasDiscountCode && (jsx("div", { style: {
|
|
9980
|
+
marginTop: "8px",
|
|
9981
|
+
fontSize: "12px",
|
|
9982
|
+
color: "var(--bw-text-muted)",
|
|
9983
|
+
fontFamily: "var(--bw-font-family)",
|
|
9984
|
+
}, children: "\uD83D\uDCA1 Es wurde bereits ein Rabattcode angewendet. Du kannst weitere Gutscheine hinzuf\u00FCgen." }))] })), jsx("style", { children: `
|
|
9985
|
+
@keyframes spin {
|
|
9986
|
+
from { transform: rotate(0deg); }
|
|
9987
|
+
to { transform: rotate(360deg); }
|
|
9988
|
+
}
|
|
9989
|
+
` })] }));
|
|
9990
|
+
}
|
|
9991
|
+
|
|
9658
9992
|
// Form schemas
|
|
9659
9993
|
const participantSchema = objectType({
|
|
9660
9994
|
name: stringType().min(1, "Name ist erforderlich"),
|
|
@@ -9674,6 +10008,10 @@ const bookingFormSchema = objectType({
|
|
|
9674
10008
|
const IconWarning = ({ size = 48, color = "var(--bw-error-color)" }) => (jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsx("circle", { cx: "12", cy: "12", r: "10" }), jsx("line", { x1: "12", y1: "8", x2: "12", y2: "12" }), jsx("circle", { cx: "12", cy: "16", r: "1" })] }));
|
|
9675
10009
|
const IconMoney = ({ size = 20, color = "var(--bw-text-muted)" }) => (jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsx("rect", { x: "2", y: "6", width: "20", height: "12", rx: "2" }), jsx("circle", { cx: "12", cy: "12", r: "4" }), jsx("line", { x1: "2", y1: "10", x2: "2", y2: "14" }), jsx("line", { x1: "22", y1: "10", x2: "22", y2: "14" })] }));
|
|
9676
10010
|
function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError, onBackToEventInstances, onBackToEventTypes, selectedEventType, selectedEventInstance, isOpen, onClose, systemConfig, }) {
|
|
10011
|
+
// New voucher system - supports multiple gift cards + one discount code
|
|
10012
|
+
const [appliedVouchers, setAppliedVouchers] = useState([]);
|
|
10013
|
+
const [voucherError, setVoucherError] = useState(null);
|
|
10014
|
+
// Legacy state for backward compatibility
|
|
9677
10015
|
const [discountCode, setDiscountCode] = useState(null);
|
|
9678
10016
|
const [discountLoading, setDiscountLoading] = useState(false);
|
|
9679
10017
|
const [discountError, setDiscountError] = useState(null);
|
|
@@ -9687,28 +10025,66 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
|
|
|
9687
10025
|
},
|
|
9688
10026
|
});
|
|
9689
10027
|
const watchedParticipants = form.watch("participants");
|
|
9690
|
-
|
|
10028
|
+
form.watch("discountCode");
|
|
9691
10029
|
const watchedCustomerName = form.watch("customerName");
|
|
9692
10030
|
const watchedCustomerEmail = form.watch("customerEmail");
|
|
9693
10031
|
const customerNameError = form.formState.errors.customerName;
|
|
9694
10032
|
const customerEmailError = form.formState.errors.customerEmail;
|
|
9695
10033
|
const watchedAcceptTerms = form.watch("acceptTerms");
|
|
9696
|
-
// Calculate total
|
|
9697
|
-
const
|
|
10034
|
+
// Calculate base total before any discounts
|
|
10035
|
+
const calculateBaseTotal = useCallback(() => {
|
|
9698
10036
|
if (!eventDetails)
|
|
9699
10037
|
return 0;
|
|
9700
|
-
|
|
9701
|
-
|
|
9702
|
-
|
|
10038
|
+
return eventDetails.price * watchedParticipants.filter((p) => p.name.trim()).length;
|
|
10039
|
+
}, [eventDetails, watchedParticipants]);
|
|
10040
|
+
// Calculate total discount from all applied vouchers
|
|
10041
|
+
const calculateTotalDiscount = useCallback(() => {
|
|
10042
|
+
return appliedVouchers.reduce((total, voucher) => {
|
|
10043
|
+
if (voucher.type === "discount") {
|
|
10044
|
+
return total + voucher.discountAmount;
|
|
10045
|
+
}
|
|
10046
|
+
else if (voucher.type === "giftCard") {
|
|
10047
|
+
return total + (voucher.balanceToUse || voucher.discountAmount);
|
|
10048
|
+
}
|
|
10049
|
+
return total;
|
|
10050
|
+
}, 0);
|
|
10051
|
+
}, [appliedVouchers]);
|
|
10052
|
+
// Calculate total amount after discounts
|
|
10053
|
+
const calculateTotal = useCallback(() => {
|
|
10054
|
+
const baseTotal = calculateBaseTotal();
|
|
10055
|
+
const totalDiscount = calculateTotalDiscount();
|
|
10056
|
+
return Math.max(0, baseTotal - totalDiscount);
|
|
10057
|
+
}, [calculateBaseTotal, calculateTotalDiscount]);
|
|
9703
10058
|
const calculateDeposit = () => {
|
|
9704
10059
|
if (!eventDetails || !eventDetails.deposit)
|
|
9705
10060
|
return 0;
|
|
9706
10061
|
const participantCount = watchedParticipants.filter((p) => p.name.trim()).length;
|
|
9707
10062
|
return eventDetails.deposit * participantCount;
|
|
9708
10063
|
};
|
|
10064
|
+
const baseTotal = calculateBaseTotal();
|
|
10065
|
+
const totalDiscount = calculateTotalDiscount();
|
|
9709
10066
|
const totalAmount = calculateTotal();
|
|
9710
10067
|
const depositAmount = calculateDeposit();
|
|
9711
|
-
|
|
10068
|
+
// If there's a deposit, we pay the deposit; otherwise we pay the total after discounts
|
|
10069
|
+
const paymentAmount = depositAmount > 0 ? Math.max(0, depositAmount - totalDiscount) : totalAmount;
|
|
10070
|
+
// Get discount code for legacy compatibility
|
|
10071
|
+
const appliedDiscountCode = appliedVouchers.find((v) => v.type === "discount");
|
|
10072
|
+
// Get gift cards
|
|
10073
|
+
const appliedGiftCards = appliedVouchers.filter((v) => v.type === "giftCard");
|
|
10074
|
+
// Voucher handlers
|
|
10075
|
+
const handleVoucherValidated = useCallback((voucher, error) => {
|
|
10076
|
+
if (error) {
|
|
10077
|
+
setVoucherError(error);
|
|
10078
|
+
return;
|
|
10079
|
+
}
|
|
10080
|
+
if (voucher) {
|
|
10081
|
+
setAppliedVouchers((prev) => [...prev, voucher]);
|
|
10082
|
+
setVoucherError(null);
|
|
10083
|
+
}
|
|
10084
|
+
}, []);
|
|
10085
|
+
const handleRemoveVoucher = useCallback((code) => {
|
|
10086
|
+
setAppliedVouchers((prev) => prev.filter((v) => v.code !== code));
|
|
10087
|
+
}, []);
|
|
9712
10088
|
// Form validation helper
|
|
9713
10089
|
const isFormValid = () => {
|
|
9714
10090
|
const participantCount = watchedParticipants.filter((p) => p.name.trim()).length;
|
|
@@ -9722,48 +10098,51 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
|
|
|
9722
10098
|
const hasAcceptedTerms = watchedAcceptTerms === true;
|
|
9723
10099
|
return validParticipants && participantsWithinLimit && hasName && hasEmail && hasAcceptedTerms;
|
|
9724
10100
|
};
|
|
9725
|
-
//
|
|
10101
|
+
// Re-validate vouchers when participant count changes (affects order value)
|
|
9726
10102
|
useEffect(() => {
|
|
9727
|
-
|
|
9728
|
-
|
|
9729
|
-
|
|
9730
|
-
|
|
9731
|
-
|
|
9732
|
-
|
|
9733
|
-
|
|
9734
|
-
|
|
9735
|
-
|
|
9736
|
-
|
|
9737
|
-
|
|
9738
|
-
|
|
9739
|
-
|
|
9740
|
-
|
|
9741
|
-
|
|
9742
|
-
|
|
9743
|
-
|
|
9744
|
-
|
|
9745
|
-
|
|
9746
|
-
|
|
9747
|
-
|
|
10103
|
+
// When participants change, we need to recalculate voucher amounts
|
|
10104
|
+
// For now, we'll clear vouchers if the order value changes significantly
|
|
10105
|
+
// In a production app, you might want to re-validate each voucher
|
|
10106
|
+
if (appliedVouchers.length > 0) {
|
|
10107
|
+
// Recalculate discount amounts based on new order value
|
|
10108
|
+
const newBaseTotal = eventDetails?.price
|
|
10109
|
+
? eventDetails.price * watchedParticipants.filter((p) => p.name.trim()).length
|
|
10110
|
+
: 0;
|
|
10111
|
+
// Update voucher amounts (simplified - in production, re-validate via API)
|
|
10112
|
+
setAppliedVouchers((prev) => prev.map((voucher) => {
|
|
10113
|
+
if (voucher.type === "discount") {
|
|
10114
|
+
let newDiscountAmount = 0;
|
|
10115
|
+
if (voucher.discountType === "percentage") {
|
|
10116
|
+
newDiscountAmount = Math.round((newBaseTotal * (voucher.discountValue || 0)) / 10000);
|
|
10117
|
+
}
|
|
10118
|
+
else {
|
|
10119
|
+
newDiscountAmount = voucher.discountValue || 0;
|
|
10120
|
+
}
|
|
10121
|
+
newDiscountAmount = Math.min(newDiscountAmount, newBaseTotal);
|
|
10122
|
+
return {
|
|
10123
|
+
...voucher,
|
|
10124
|
+
discountAmount: newDiscountAmount,
|
|
10125
|
+
newTotal: newBaseTotal - newDiscountAmount,
|
|
10126
|
+
};
|
|
9748
10127
|
}
|
|
9749
|
-
else {
|
|
9750
|
-
|
|
9751
|
-
|
|
10128
|
+
else if (voucher.type === "giftCard") {
|
|
10129
|
+
// Gift card balance stays the same, but amount to use might change
|
|
10130
|
+
const remainingAfterDiscount = newBaseTotal -
|
|
10131
|
+
prev
|
|
10132
|
+
.filter((v) => v.type === "discount")
|
|
10133
|
+
.reduce((sum, v) => sum + v.discountAmount, 0);
|
|
10134
|
+
const balanceToUse = Math.min(voucher.currentBalance || 0, Math.max(0, remainingAfterDiscount));
|
|
10135
|
+
return {
|
|
10136
|
+
...voucher,
|
|
10137
|
+
balanceToUse,
|
|
10138
|
+
remainingBalance: (voucher.currentBalance || 0) - balanceToUse,
|
|
10139
|
+
discountAmount: balanceToUse,
|
|
10140
|
+
};
|
|
9752
10141
|
}
|
|
9753
|
-
|
|
9754
|
-
|
|
9755
|
-
|
|
9756
|
-
|
|
9757
|
-
}
|
|
9758
|
-
finally {
|
|
9759
|
-
setDiscountLoading(false);
|
|
9760
|
-
}
|
|
9761
|
-
};
|
|
9762
|
-
const timer = setTimeout(() => {
|
|
9763
|
-
validateDiscountCode(watchedDiscountCode || "");
|
|
9764
|
-
}, 500);
|
|
9765
|
-
return () => clearTimeout(timer);
|
|
9766
|
-
}, [watchedDiscountCode, watchedParticipants, eventDetails, config]);
|
|
10142
|
+
return voucher;
|
|
10143
|
+
}));
|
|
10144
|
+
}
|
|
10145
|
+
}, [watchedParticipants, eventDetails]);
|
|
9767
10146
|
// Helper functions
|
|
9768
10147
|
const addParticipant = () => {
|
|
9769
10148
|
const currentParticipants = form.getValues("participants");
|
|
@@ -9918,7 +10297,7 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
|
|
|
9918
10297
|
color: "var(--bw-text-color)",
|
|
9919
10298
|
fontWeight: "500",
|
|
9920
10299
|
fontFamily: "var(--bw-font-family)",
|
|
9921
|
-
}, children: [formatCurrency(eventDetails.price), " pro Person"] })] })] })] }), jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "var(--bw-spacing-large)" }, children: [jsxs("
|
|
10300
|
+
}, children: [formatCurrency(eventDetails.price), " pro Person"] })] })] })] }), jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "var(--bw-spacing-large)" }, children: [jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "var(--bw-spacing-large)" }, children: [jsxs("div", { style: {
|
|
9922
10301
|
backgroundColor: "var(--bw-surface-color)",
|
|
9923
10302
|
border: `1px solid var(--bw-border-color)`,
|
|
9924
10303
|
backdropFilter: "blur(4px)",
|
|
@@ -10063,7 +10442,7 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
|
|
|
10063
10442
|
color: "var(--bw-error-color)",
|
|
10064
10443
|
fontSize: "var(--bw-font-size)",
|
|
10065
10444
|
fontFamily: "var(--bw-font-family)",
|
|
10066
|
-
}, children: ["Maximal ", eventDetails.availableSpots, " Pl\u00E4tze verf\u00FCgbar."] }))] })] }), jsxs("div", { style: {
|
|
10445
|
+
}, children: ["Maximal ", eventDetails.availableSpots, " Pl\u00E4tze verf\u00FCgbar."] }))] })] }), jsx(VoucherInput, { config: config, orderValue: baseTotal, eventInstanceId: eventDetails?.id, customerEmail: watchedCustomerEmail, onVoucherValidated: handleVoucherValidated, appliedVouchers: appliedVouchers, onRemoveVoucher: handleRemoveVoucher, disabled: !eventDetails }), jsxs("div", { style: {
|
|
10067
10446
|
backgroundColor: "var(--bw-surface-color)",
|
|
10068
10447
|
border: `1px solid var(--bw-border-color)`,
|
|
10069
10448
|
backdropFilter: "blur(4px)",
|
|
@@ -10162,7 +10541,7 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
|
|
|
10162
10541
|
color: "var(--bw-text-color)",
|
|
10163
10542
|
fontWeight: "500",
|
|
10164
10543
|
fontFamily: "var(--bw-font-family)",
|
|
10165
|
-
}, children: formatCurrency(eventDetails.deposit || 0) })] })),
|
|
10544
|
+
}, children: formatCurrency(eventDetails.deposit || 0) })] })), appliedVouchers.length > 0 && (jsxs(Fragment, { children: [jsxs("div", { style: {
|
|
10166
10545
|
display: "flex",
|
|
10167
10546
|
justifyContent: "space-between",
|
|
10168
10547
|
alignItems: "center",
|
|
@@ -10171,20 +10550,31 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
|
|
|
10171
10550
|
fontFamily: "var(--bw-font-family)",
|
|
10172
10551
|
}, children: "Zwischensumme:" }), jsx("span", { style: {
|
|
10173
10552
|
color: "var(--bw-text-muted)",
|
|
10174
|
-
textDecoration: "line-through",
|
|
10553
|
+
textDecoration: totalDiscount > 0 ? "line-through" : "none",
|
|
10175
10554
|
fontFamily: "var(--bw-font-family)",
|
|
10176
|
-
}, children: formatCurrency(
|
|
10177
|
-
watchedParticipants.filter((p) => p.name.trim()).length) })] }), jsxs("div", { style: {
|
|
10555
|
+
}, children: formatCurrency(baseTotal) })] }), appliedDiscountCode && (jsxs("div", { style: {
|
|
10178
10556
|
display: "flex",
|
|
10179
10557
|
justifyContent: "space-between",
|
|
10180
10558
|
alignItems: "center",
|
|
10181
|
-
}, children: [
|
|
10559
|
+
}, children: [jsxs("span", { style: {
|
|
10560
|
+
color: "var(--bw-success-color)",
|
|
10561
|
+
fontFamily: "var(--bw-font-family)",
|
|
10562
|
+
fontSize: "var(--bw-font-size)",
|
|
10563
|
+
}, children: ["Rabatt (", appliedDiscountCode.code, "):"] }), jsxs("span", { style: {
|
|
10182
10564
|
color: "var(--bw-success-color)",
|
|
10183
10565
|
fontFamily: "var(--bw-font-family)",
|
|
10184
|
-
}, children: "
|
|
10566
|
+
}, children: ["-", formatCurrency(appliedDiscountCode.discountAmount)] })] })), appliedGiftCards.map((giftCard) => (jsxs("div", { style: {
|
|
10567
|
+
display: "flex",
|
|
10568
|
+
justifyContent: "space-between",
|
|
10569
|
+
alignItems: "center",
|
|
10570
|
+
}, children: [jsxs("span", { style: {
|
|
10185
10571
|
color: "var(--bw-success-color)",
|
|
10186
10572
|
fontFamily: "var(--bw-font-family)",
|
|
10187
|
-
|
|
10573
|
+
fontSize: "var(--bw-font-size)",
|
|
10574
|
+
}, children: ["Gutschein (", giftCard.code, "):"] }), jsxs("span", { style: {
|
|
10575
|
+
color: "var(--bw-success-color)",
|
|
10576
|
+
fontFamily: "var(--bw-font-family)",
|
|
10577
|
+
}, children: ["-", formatCurrency(giftCard.balanceToUse || giftCard.discountAmount)] })] }, giftCard.code)))] })), jsxs("div", { style: {
|
|
10188
10578
|
borderTop: `1px solid var(--bw-border-color)`,
|
|
10189
10579
|
paddingTop: "12px",
|
|
10190
10580
|
}, children: [depositAmount > 0 && (jsxs("div", { style: {
|
|
@@ -10257,7 +10647,15 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
|
|
|
10257
10647
|
fontFamily: "var(--bw-font-family)",
|
|
10258
10648
|
borderBottom: "2px solid var(--bw-highlight-color)",
|
|
10259
10649
|
paddingBottom: 4,
|
|
10260
|
-
}, children: "Zahlung" }), jsx(PaymentForm, { config: config, eventDetails: eventDetails, formData: form.getValues(), totalAmount: paymentAmount, discountCode:
|
|
10650
|
+
}, children: "Zahlung" }), jsx(PaymentForm, { config: config, eventDetails: eventDetails, formData: form.getValues(), totalAmount: paymentAmount, discountCode: appliedDiscountCode ? {
|
|
10651
|
+
id: appliedDiscountCode.id,
|
|
10652
|
+
code: appliedDiscountCode.code,
|
|
10653
|
+
description: appliedDiscountCode.description || undefined,
|
|
10654
|
+
type: appliedDiscountCode.discountType || "percentage",
|
|
10655
|
+
value: appliedDiscountCode.discountValue || 0,
|
|
10656
|
+
discountAmount: appliedDiscountCode.discountAmount,
|
|
10657
|
+
newTotal: appliedDiscountCode.newTotal,
|
|
10658
|
+
} : null, giftCards: appliedGiftCards, onSuccess: onSuccess, onError: onError, systemConfig: systemConfig, stripePromise: stripePromise, stripeAppearance: stripeAppearance })] }));
|
|
10261
10659
|
})()] })] }), jsx("style", { children: `
|
|
10262
10660
|
.booking-widget-container *,
|
|
10263
10661
|
.booking-widget-container *::before,
|
|
@@ -10908,16 +11306,7 @@ const spinner = (borderColor) => (jsx("div", { style: {
|
|
|
10908
11306
|
} }) }));
|
|
10909
11307
|
function EventInstanceSelection({ eventInstances, selectedEventType, onEventInstanceSelect, onBackToEventTypes, isOpen, onClose, isLoadingEventInstances = false, isLoadingEventDetails = false, }) {
|
|
10910
11308
|
const [selectedEventInstanceId, setSelectedEventInstanceId] = useState(null);
|
|
10911
|
-
const [
|
|
10912
|
-
const getEventsForMonth = (monthIndex) => {
|
|
10913
|
-
return eventInstances.filter((instance) => new Date(instance.startTime).getMonth() === monthIndex);
|
|
10914
|
-
};
|
|
10915
|
-
const getMinPriceForMonth = (monthIndex) => {
|
|
10916
|
-
const monthEvents = getEventsForMonth(monthIndex);
|
|
10917
|
-
if (monthEvents.length === 0)
|
|
10918
|
-
return 0;
|
|
10919
|
-
return Math.min(...monthEvents.map((event) => event.price));
|
|
10920
|
-
};
|
|
11309
|
+
const [openGroups, setOpenGroups] = useState(new Set());
|
|
10921
11310
|
const getMonthPriceDisplayInfo = (minPrice) => {
|
|
10922
11311
|
return getPriceDisplayInfo(minPrice, yearPrices);
|
|
10923
11312
|
};
|
|
@@ -10927,27 +11316,48 @@ function EventInstanceSelection({ eventInstances, selectedEventType, onEventInst
|
|
|
10927
11316
|
.filter((instance) => new Date(instance.startTime).getFullYear() === currentYear)
|
|
10928
11317
|
.map((instance) => instance.price);
|
|
10929
11318
|
const today = new Date();
|
|
10930
|
-
//
|
|
10931
|
-
const
|
|
10932
|
-
|
|
10933
|
-
|
|
10934
|
-
|
|
10935
|
-
|
|
10936
|
-
|
|
10937
|
-
|
|
10938
|
-
|
|
11319
|
+
// Group events by month and year, then sort chronologically (e.g., Aug 2025 before Apr 2026)
|
|
11320
|
+
const monthYearGroups = (() => {
|
|
11321
|
+
const groupsMap = new Map();
|
|
11322
|
+
for (const instance of eventInstances) {
|
|
11323
|
+
const date = new Date(instance.startTime);
|
|
11324
|
+
const year = date.getFullYear();
|
|
11325
|
+
const monthIndex = date.getMonth();
|
|
11326
|
+
const key = `${year}-${monthIndex}`;
|
|
11327
|
+
if (!groupsMap.has(key)) {
|
|
11328
|
+
groupsMap.set(key, {
|
|
11329
|
+
key,
|
|
11330
|
+
year,
|
|
11331
|
+
monthIndex,
|
|
11332
|
+
label: `${months[monthIndex]} ${year}`,
|
|
11333
|
+
events: [],
|
|
11334
|
+
minPrice: Number.POSITIVE_INFINITY,
|
|
11335
|
+
});
|
|
11336
|
+
}
|
|
11337
|
+
const group = groupsMap.get(key);
|
|
11338
|
+
group.events.push(instance);
|
|
11339
|
+
if (instance.price < group.minPrice)
|
|
11340
|
+
group.minPrice = instance.price;
|
|
11341
|
+
}
|
|
11342
|
+
return Array.from(groupsMap.values())
|
|
11343
|
+
.map((group) => ({
|
|
11344
|
+
...group,
|
|
11345
|
+
events: group.events.sort((a, b) => new Date(a.startTime).getTime() - new Date(b.startTime).getTime()),
|
|
11346
|
+
}))
|
|
11347
|
+
.sort((a, b) => (a.year === b.year ? a.monthIndex - b.monthIndex : a.year - b.year));
|
|
11348
|
+
})();
|
|
10939
11349
|
const handleEventInstanceSelect = (eventInstance) => {
|
|
10940
11350
|
setSelectedEventInstanceId(eventInstance.id);
|
|
10941
11351
|
onEventInstanceSelect(eventInstance);
|
|
10942
11352
|
};
|
|
10943
|
-
const
|
|
10944
|
-
if (
|
|
11353
|
+
const toggleGroup = (key) => {
|
|
11354
|
+
if (openGroups.has(key)) {
|
|
10945
11355
|
// Close if already open
|
|
10946
|
-
|
|
11356
|
+
setOpenGroups(new Set());
|
|
10947
11357
|
}
|
|
10948
11358
|
else {
|
|
10949
11359
|
// Open only this one, close others
|
|
10950
|
-
|
|
11360
|
+
setOpenGroups(new Set([key]));
|
|
10951
11361
|
}
|
|
10952
11362
|
};
|
|
10953
11363
|
const handleClose = () => {
|
|
@@ -11204,10 +11614,7 @@ function EventInstanceSelection({ eventInstances, selectedEventType, onEventInst
|
|
|
11204
11614
|
minHeight: "400px",
|
|
11205
11615
|
textAlign: "center",
|
|
11206
11616
|
padding: "var(--bw-spacing)",
|
|
11207
|
-
}, children: jsxs("div", { children: [jsx("
|
|
11208
|
-
margin: "0 auto 16px",
|
|
11209
|
-
fontSize: "48px",
|
|
11210
|
-
}, children: "\uD83D\uDCC5" }), jsx("h3", { style: {
|
|
11617
|
+
}, children: jsxs("div", { children: [jsx("h3", { style: {
|
|
11211
11618
|
marginBottom: "8px",
|
|
11212
11619
|
fontWeight: "600",
|
|
11213
11620
|
fontSize: "var(--bw-font-size-large)",
|
|
@@ -11275,136 +11682,154 @@ function EventInstanceSelection({ eventInstances, selectedEventType, onEventInst
|
|
|
11275
11682
|
font-size: 1.1rem !important;
|
|
11276
11683
|
}
|
|
11277
11684
|
}
|
|
11278
|
-
` }), jsx(Sidebar, { isOpen: isOpen, onClose: handleClose, title:
|
|
11685
|
+
` }), jsx(Sidebar, { isOpen: isOpen, onClose: handleClose, title: `${selectedEventType?.name}`, children: jsx("div", { className: "bw-event-instance-list", style: { padding: "24px" }, children: jsx("div", { style: {
|
|
11279
11686
|
display: "flex",
|
|
11280
11687
|
flexDirection: "column",
|
|
11281
11688
|
gap: "20px",
|
|
11282
|
-
}, children:
|
|
11689
|
+
}, children: monthYearGroups.map(({ key, label, events, minPrice, year }, idx) => {
|
|
11283
11690
|
const monthPriceDisplayInfo = getMonthPriceDisplayInfo(minPrice);
|
|
11284
|
-
return (
|
|
11285
|
-
|
|
11286
|
-
|
|
11287
|
-
|
|
11288
|
-
|
|
11289
|
-
|
|
11290
|
-
|
|
11291
|
-
|
|
11292
|
-
|
|
11293
|
-
|
|
11294
|
-
|
|
11295
|
-
|
|
11296
|
-
|
|
11297
|
-
|
|
11298
|
-
|
|
11299
|
-
|
|
11300
|
-
|
|
11301
|
-
|
|
11302
|
-
|
|
11303
|
-
|
|
11304
|
-
|
|
11305
|
-
|
|
11306
|
-
|
|
11307
|
-
|
|
11308
|
-
|
|
11309
|
-
|
|
11310
|
-
|
|
11311
|
-
|
|
11312
|
-
|
|
11313
|
-
|
|
11314
|
-
|
|
11315
|
-
|
|
11316
|
-
|
|
11317
|
-
|
|
11318
|
-
|
|
11319
|
-
|
|
11320
|
-
|
|
11321
|
-
}, onClick: () => {
|
|
11322
|
-
if (!isFullyBooked && !isPastEvent && event.bookingOpen) {
|
|
11323
|
-
handleEventInstanceSelect(event);
|
|
11324
|
-
}
|
|
11325
|
-
}, onMouseEnter: (e) => {
|
|
11326
|
-
if (!isFullyBooked && !isPastEvent && event.bookingOpen) {
|
|
11327
|
-
e.currentTarget.style.transform = "scale(1.02)";
|
|
11328
|
-
e.currentTarget.style.backgroundColor =
|
|
11329
|
-
"var(--bw-surface-muted, rgba(59, 130, 246, 0.1))";
|
|
11330
|
-
}
|
|
11331
|
-
}, onMouseLeave: (e) => {
|
|
11332
|
-
if (!isFullyBooked && !isPastEvent && event.bookingOpen) {
|
|
11333
|
-
e.currentTarget.style.transform = "scale(1)";
|
|
11334
|
-
e.currentTarget.style.backgroundColor = "var(--bw-surface-color)";
|
|
11335
|
-
}
|
|
11336
|
-
}, children: [selectedEventInstanceId === event.id && isLoadingEventDetails && (jsx("div", { style: {
|
|
11337
|
-
position: "absolute",
|
|
11338
|
-
top: 0,
|
|
11339
|
-
left: 0,
|
|
11340
|
-
width: "100%",
|
|
11341
|
-
height: "100%",
|
|
11342
|
-
backgroundColor: "var(--bw-overlay-color, rgba(15, 23, 42, 0.8))",
|
|
11691
|
+
return (jsxs(Fragment$1, { children: [idx > 0 && monthYearGroups[idx - 1].year !== year && (jsx("div", { style: {
|
|
11692
|
+
height: 1,
|
|
11693
|
+
backgroundColor: "var(--bw-border-color)",
|
|
11694
|
+
margin: "4px 0",
|
|
11695
|
+
} })), jsx(Accordion, { title: label, priceInfo: jsx("div", { style: {
|
|
11696
|
+
fontSize: "1rem",
|
|
11697
|
+
backgroundColor: monthPriceDisplayInfo
|
|
11698
|
+
? monthPriceDisplayInfo.backgroundColor
|
|
11699
|
+
: "#14532d",
|
|
11700
|
+
color: monthPriceDisplayInfo
|
|
11701
|
+
? monthPriceDisplayInfo.textColor
|
|
11702
|
+
: "#4ade80",
|
|
11703
|
+
fontWeight: 500,
|
|
11704
|
+
marginLeft: "auto",
|
|
11705
|
+
padding: "4px 8px",
|
|
11706
|
+
borderRadius: "var(--bw-border-radius-small)",
|
|
11707
|
+
border: monthPriceDisplayInfo ? "none" : undefined,
|
|
11708
|
+
boxShadow: monthPriceDisplayInfo
|
|
11709
|
+
? "0 2px 4px rgba(0, 0, 0, 0.2)"
|
|
11710
|
+
: undefined,
|
|
11711
|
+
}, children: `ab ${formatCurrency(minPrice)}` }), isOpen: openGroups.has(key), onToggle: () => toggleGroup(key), children: jsx("div", { style: {
|
|
11712
|
+
display: "flex",
|
|
11713
|
+
flexDirection: "column",
|
|
11714
|
+
gap: "12px",
|
|
11715
|
+
paddingTop: "12px",
|
|
11716
|
+
}, children: events.map((event) => {
|
|
11717
|
+
const availableSpots = event.maxParticipants - event.participantCount;
|
|
11718
|
+
const isFullyBooked = availableSpots === 0;
|
|
11719
|
+
const startDate = new Date(event.startTime);
|
|
11720
|
+
const isPastEvent = today.toISOString() >= startDate.toISOString();
|
|
11721
|
+
return (jsxs("div", { className: "bw-event-instance-card", style: {
|
|
11722
|
+
position: "relative",
|
|
11723
|
+
cursor: !isFullyBooked && !isPastEvent && event.bookingOpen
|
|
11724
|
+
? "pointer"
|
|
11725
|
+
: "not-allowed",
|
|
11726
|
+
border: "1px solid var(--bw-border-color)",
|
|
11727
|
+
backgroundColor: "var(--bw-surface-color)",
|
|
11343
11728
|
borderRadius: "var(--bw-border-radius)",
|
|
11344
|
-
|
|
11345
|
-
|
|
11346
|
-
|
|
11347
|
-
|
|
11348
|
-
|
|
11349
|
-
|
|
11350
|
-
|
|
11351
|
-
|
|
11352
|
-
|
|
11353
|
-
|
|
11354
|
-
|
|
11355
|
-
|
|
11356
|
-
|
|
11357
|
-
|
|
11358
|
-
|
|
11359
|
-
|
|
11360
|
-
|
|
11361
|
-
|
|
11362
|
-
|
|
11363
|
-
|
|
11364
|
-
|
|
11365
|
-
|
|
11366
|
-
|
|
11367
|
-
|
|
11368
|
-
|
|
11369
|
-
|
|
11370
|
-
|
|
11371
|
-
|
|
11372
|
-
|
|
11373
|
-
|
|
11374
|
-
|
|
11375
|
-
|
|
11376
|
-
|
|
11729
|
+
padding: "16px 20px",
|
|
11730
|
+
transition: "all 0.2s ease",
|
|
11731
|
+
opacity: isFullyBooked || isPastEvent ? 0.3 : 1,
|
|
11732
|
+
filter: isFullyBooked || isPastEvent ? "grayscale(40%)" : "none",
|
|
11733
|
+
fontFamily: "var(--bw-font-family)",
|
|
11734
|
+
}, onClick: () => {
|
|
11735
|
+
if (!isFullyBooked && !isPastEvent && event.bookingOpen) {
|
|
11736
|
+
handleEventInstanceSelect(event);
|
|
11737
|
+
}
|
|
11738
|
+
}, onMouseEnter: (e) => {
|
|
11739
|
+
if (!isFullyBooked && !isPastEvent && event.bookingOpen) {
|
|
11740
|
+
e.currentTarget.style.transform = "scale(1.02)";
|
|
11741
|
+
e.currentTarget.style.backgroundColor =
|
|
11742
|
+
"var(--bw-surface-muted, rgba(59, 130, 246, 0.1))";
|
|
11743
|
+
}
|
|
11744
|
+
}, onMouseLeave: (e) => {
|
|
11745
|
+
if (!isFullyBooked && !isPastEvent && event.bookingOpen) {
|
|
11746
|
+
e.currentTarget.style.transform = "scale(1)";
|
|
11747
|
+
e.currentTarget.style.backgroundColor = "var(--bw-surface-color)";
|
|
11748
|
+
}
|
|
11749
|
+
}, children: [selectedEventInstanceId === event.id && isLoadingEventDetails && (jsx("div", { style: {
|
|
11750
|
+
position: "absolute",
|
|
11751
|
+
top: 0,
|
|
11752
|
+
left: 0,
|
|
11753
|
+
width: "100%",
|
|
11754
|
+
height: "100%",
|
|
11755
|
+
backgroundColor: "var(--bw-overlay-color, rgba(15, 23, 42, 0.8))",
|
|
11756
|
+
borderRadius: "var(--bw-border-radius)",
|
|
11757
|
+
display: "flex",
|
|
11758
|
+
alignItems: "center",
|
|
11759
|
+
justifyContent: "center",
|
|
11760
|
+
}, children: jsx("div", { style: {
|
|
11761
|
+
width: "32px",
|
|
11762
|
+
height: "32px",
|
|
11763
|
+
color: "var(--bw-highlight-color-muted, rgba(59, 130, 246, 0.8))",
|
|
11764
|
+
animation: "spin 1s linear infinite",
|
|
11765
|
+
fontSize: "32px",
|
|
11766
|
+
}, children: spinner() }) })), jsx(SpecialPriceBadge, { price: event.price, yearPrices: yearPrices }), jsx(AllocationBadge, { availableSpots: availableSpots, maxParticipants: event.maxParticipants }), jsxs("div", { style: {
|
|
11767
|
+
display: "flex",
|
|
11768
|
+
justifyContent: "space-between",
|
|
11769
|
+
width: "100%",
|
|
11770
|
+
alignItems: "start",
|
|
11771
|
+
gap: "12px",
|
|
11772
|
+
marginBottom: "4px",
|
|
11773
|
+
}, children: [jsxs("div", { style: { display: "flex", alignItems: "start", gap: "12px" }, children: [jsx("div", { className: "bw-event-instance-datebox", style: {
|
|
11774
|
+
fontSize: "var(--bw-font-size)",
|
|
11775
|
+
transition: "all 0.2s ease",
|
|
11776
|
+
borderRadius: "var(--bw-border-radius-small)",
|
|
11777
|
+
borderTop: `4px solid var(--bw-border-color)`,
|
|
11778
|
+
border: "1px solid var(--bw-border-color)",
|
|
11779
|
+
width: "40px",
|
|
11780
|
+
height: "40px",
|
|
11781
|
+
display: "flex",
|
|
11782
|
+
alignItems: "center",
|
|
11783
|
+
justifyContent: "center",
|
|
11784
|
+
fontWeight: "bold",
|
|
11785
|
+
color: "var(--bw-text-color)",
|
|
11786
|
+
backgroundColor: "var(--bw-background-color)",
|
|
11787
|
+
}, children: startDate.getDate() }), jsxs("div", { style: {
|
|
11788
|
+
fontSize: "var(--bw-font-size)",
|
|
11789
|
+
color: "var(--bw-text-color)",
|
|
11790
|
+
display: "flex",
|
|
11791
|
+
flexDirection: "column",
|
|
11792
|
+
alignItems: "start",
|
|
11793
|
+
justifyContent: "start",
|
|
11794
|
+
lineHeight: "1.2",
|
|
11795
|
+
}, children: [jsxs("div", { children: [jsx("span", { className: "bw-event-instance-title", style: { fontWeight: "600", marginBottom: "2px" }, children: formatWeekday(event.startTime) }), formatWeekday(event.startTime) !==
|
|
11796
|
+
formatWeekday(event.endTime) && (jsxs(Fragment, { children: [jsx("span", { style: {
|
|
11797
|
+
color: "var(--bw-text-muted)",
|
|
11798
|
+
fontSize: "14px",
|
|
11799
|
+
}, children: " - " }), jsx("span", { className: "bw-event-instance-title", style: { fontWeight: "600", marginBottom: "2px" }, children: formatWeekday(event.endTime) })] }))] }), jsx("div", { children: formatWeekday(event.startTime) ===
|
|
11800
|
+
formatWeekday(event.endTime) ? (jsxs(Fragment, { children: [jsx("span", { style: {
|
|
11801
|
+
color: "var(--bw-text-muted)",
|
|
11802
|
+
fontSize: "14px",
|
|
11803
|
+
}, children: formatTime(event.startTime) }), jsx("span", { style: {
|
|
11804
|
+
color: "var(--bw-text-muted)",
|
|
11805
|
+
fontSize: "14px",
|
|
11806
|
+
}, children: " - " }), jsx("span", { style: {
|
|
11807
|
+
color: "var(--bw-text-muted)",
|
|
11808
|
+
fontSize: "14px",
|
|
11809
|
+
}, children: formatTime(event.endTime) })] })) : (jsxs("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: [formatTime(event.startTime), " Uhr"] })) })] }), jsxs("span", { style: {
|
|
11810
|
+
fontSize: "12px",
|
|
11811
|
+
fontWeight: 400,
|
|
11812
|
+
color: "var(--bw-text-muted)",
|
|
11813
|
+
marginLeft: "6px",
|
|
11814
|
+
background: "var(--bw-background-muted)",
|
|
11815
|
+
whiteSpace: "nowrap",
|
|
11816
|
+
}, children: [event.durationDays, " Tag", event.durationDays > 1 ? "e" : ""] })] }), jsx("div", { className: "bw-event-instance-price", style: {
|
|
11817
|
+
textAlign: "right",
|
|
11377
11818
|
display: "flex",
|
|
11378
11819
|
flexDirection: "column",
|
|
11379
|
-
alignItems: "
|
|
11380
|
-
|
|
11381
|
-
|
|
11382
|
-
|
|
11383
|
-
|
|
11384
|
-
|
|
11385
|
-
|
|
11386
|
-
fontWeight: 400,
|
|
11387
|
-
color: "var(--bw-text-muted)",
|
|
11388
|
-
marginLeft: "6px",
|
|
11389
|
-
background: "var(--bw-background-muted)",
|
|
11390
|
-
whiteSpace: "nowrap",
|
|
11391
|
-
}, children: [event.durationDays, " Tag", event.durationDays > 1 ? "e" : ""] })] }), jsx("div", { className: "bw-event-instance-price", style: {
|
|
11392
|
-
textAlign: "right",
|
|
11820
|
+
alignItems: "end",
|
|
11821
|
+
}, children: jsx(PriceDisplay, { price: event.price, yearPrices: yearPrices }) })] }), event.name !== selectedEventType?.name && (jsx("h4", { className: "bw-event-instance-title", style: {
|
|
11822
|
+
fontSize: "var(--bw-font-size)",
|
|
11823
|
+
fontWeight: "600",
|
|
11824
|
+
color: "var(--bw-text-color)",
|
|
11825
|
+
lineHeight: "1.25",
|
|
11826
|
+
margin: "0 0 2px 0",
|
|
11393
11827
|
display: "flex",
|
|
11394
|
-
|
|
11395
|
-
|
|
11396
|
-
|
|
11397
|
-
|
|
11398
|
-
|
|
11399
|
-
color: "var(--bw-text-color)",
|
|
11400
|
-
lineHeight: "1.25",
|
|
11401
|
-
margin: "0 0 2px 0",
|
|
11402
|
-
display: "flex",
|
|
11403
|
-
alignItems: "center",
|
|
11404
|
-
gap: "8px",
|
|
11405
|
-
maxWidth: "230px",
|
|
11406
|
-
}, children: event.name }))] }, event.id));
|
|
11407
|
-
}) }) }, month));
|
|
11828
|
+
alignItems: "center",
|
|
11829
|
+
gap: "8px",
|
|
11830
|
+
maxWidth: "230px",
|
|
11831
|
+
}, children: event.name }))] }, event.id));
|
|
11832
|
+
}) }) })] }, key));
|
|
11408
11833
|
}) }) }) })] }));
|
|
11409
11834
|
}
|
|
11410
11835
|
|