@bigz-app/booking-widget 0.1.25 → 0.2.1
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 +454 -273
- package/dist/booking-widget.js.map +1 -1
- package/dist/components/BookingForm.d.ts.map +1 -1
- package/dist/components/BookingSuccessModal.d.ts +3 -4
- package/dist/components/BookingSuccessModal.d.ts.map +1 -1
- package/dist/components/PaymentForm.d.ts.map +1 -1
- package/dist/components/UniversalBookingWidget.d.ts.map +1 -1
- package/dist/index.cjs +454 -273
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +454 -273
- package/dist/index.esm.js.map +1 -1
- package/dist/styles/StyleProvider.d.ts.map +1 -1
- package/dist/utils.d.ts +6 -0
- package/dist/utils.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -571,6 +571,13 @@ const StyleProvider = ({ config, children, }) => {
|
|
|
571
571
|
direction: ltr;
|
|
572
572
|
isolation: isolate;
|
|
573
573
|
}
|
|
574
|
+
.print-only {
|
|
575
|
+
display: none;
|
|
576
|
+
}
|
|
577
|
+
.print-hidden {
|
|
578
|
+
display: block;
|
|
579
|
+
}
|
|
580
|
+
@media print {
|
|
574
581
|
`;
|
|
575
582
|
// Inject CSS reset styles
|
|
576
583
|
useEffect(() => {
|
|
@@ -916,6 +923,26 @@ const createRequestBody = (config, additionalData) => {
|
|
|
916
923
|
organizationId: config.organizationId,
|
|
917
924
|
};
|
|
918
925
|
};
|
|
926
|
+
// Helper function to detect Stripe return parameters in URL
|
|
927
|
+
const detectStripeReturn = () => {
|
|
928
|
+
if (typeof window === "undefined") {
|
|
929
|
+
return null;
|
|
930
|
+
}
|
|
931
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
932
|
+
// Check for Stripe return parameters
|
|
933
|
+
const paymentIntent = urlParams.get("payment_intent");
|
|
934
|
+
const paymentIntentClientSecret = urlParams.get("payment_intent_client_secret");
|
|
935
|
+
const redirectStatus = urlParams.get("redirect_status");
|
|
936
|
+
if (paymentIntent && paymentIntentClientSecret && redirectStatus) {
|
|
937
|
+
return {
|
|
938
|
+
isStripeReturn: true,
|
|
939
|
+
paymentIntent,
|
|
940
|
+
paymentIntentClientSecret,
|
|
941
|
+
redirectStatus,
|
|
942
|
+
};
|
|
943
|
+
}
|
|
944
|
+
return null;
|
|
945
|
+
};
|
|
919
946
|
|
|
920
947
|
var isCheckBoxInput = (element) => element.type === 'checkbox';
|
|
921
948
|
|
|
@@ -9098,7 +9125,7 @@ const spinner = (borderColor) => (jsx("div", { style: {
|
|
|
9098
9125
|
borderRadius: "50%",
|
|
9099
9126
|
} }) }));
|
|
9100
9127
|
// Inner component that uses the Stripe hooks
|
|
9101
|
-
function PaymentFormInner({ config, eventDetails, formData, totalAmount, discountCode, onSuccess, onError,
|
|
9128
|
+
function PaymentFormInner({ config, eventDetails, formData, totalAmount, discountCode, onSuccess, onError, }) {
|
|
9102
9129
|
const stripe = reactStripe_umdExports.useStripe();
|
|
9103
9130
|
const elements = reactStripe_umdExports.useElements();
|
|
9104
9131
|
const [isLoading, setIsLoading] = useState(false);
|
|
@@ -9124,26 +9151,12 @@ function PaymentFormInner({ config, eventDetails, formData, totalAmount, discoun
|
|
|
9124
9151
|
return;
|
|
9125
9152
|
}
|
|
9126
9153
|
// First, confirm the payment with Stripe
|
|
9154
|
+
// Build return URL for Stripe redirect
|
|
9155
|
+
const baseUrl = window !== undefined ? window.location.href : `${config.bookingSystemUrl}/booking-success`;
|
|
9156
|
+
const returnUrl = new URL(baseUrl);
|
|
9127
9157
|
const confirmParams = {
|
|
9128
|
-
return_url:
|
|
9158
|
+
return_url: returnUrl.toString(),
|
|
9129
9159
|
};
|
|
9130
|
-
// Ensure return_url is properly formatted and doesn't contain fragment identifiers
|
|
9131
|
-
try {
|
|
9132
|
-
const url = new URL(confirmParams.return_url);
|
|
9133
|
-
// Remove any fragment identifiers that might cause issues
|
|
9134
|
-
url.hash = "";
|
|
9135
|
-
confirmParams.return_url = url.toString();
|
|
9136
|
-
}
|
|
9137
|
-
catch (e) {
|
|
9138
|
-
console.warn("[PAYMENT_FORM] Invalid return_url, using fallback:", confirmParams.return_url);
|
|
9139
|
-
// Fallback to current origin if URL parsing fails
|
|
9140
|
-
confirmParams.return_url = window.location.origin + window.location.pathname;
|
|
9141
|
-
}
|
|
9142
|
-
console.log("[PAYMENT_FORM] Confirming payment with params:", {
|
|
9143
|
-
paymentIntentId: clientSecret.split("_secret_")[0],
|
|
9144
|
-
return_url: confirmParams.return_url,
|
|
9145
|
-
redirect: "if_required",
|
|
9146
|
-
});
|
|
9147
9160
|
const { error, paymentIntent } = await stripe.confirmPayment({
|
|
9148
9161
|
elements,
|
|
9149
9162
|
confirmParams,
|
|
@@ -9161,91 +9174,15 @@ function PaymentFormInner({ config, eventDetails, formData, totalAmount, discoun
|
|
|
9161
9174
|
setPaymentError(error.message || "Zahlungsfehler");
|
|
9162
9175
|
}
|
|
9163
9176
|
else {
|
|
9164
|
-
setPaymentError("Ein unerwarteter Fehler ist aufgetreten.");
|
|
9177
|
+
setPaymentError("Ein unerwarteter Fehler ist aufgetreten. Bitte versuche es nochmal.");
|
|
9165
9178
|
}
|
|
9166
9179
|
return;
|
|
9167
9180
|
}
|
|
9168
9181
|
// Payment succeeded, now create the booking
|
|
9169
9182
|
if (paymentIntent && paymentIntent.status === "succeeded") {
|
|
9170
|
-
// Check if we have system configuration
|
|
9171
|
-
if (!systemConfig) {
|
|
9172
|
-
throw new Error("System-Konfiguration nicht verfügbar. Bitte lade die Seite neu.");
|
|
9173
|
-
}
|
|
9174
|
-
// Determine which endpoint to use based on system mode
|
|
9175
|
-
const isConnectMode = systemConfig.systemMode === "connect";
|
|
9176
|
-
const endpoint = isConnectMode
|
|
9177
|
-
? "/booking/create-from-payment"
|
|
9178
|
-
: "/booking-proxy/create-booking";
|
|
9179
|
-
// Calculate if this is a deposit payment
|
|
9180
|
-
const fullAmount = eventDetails.price * formData.participants.filter((p) => p.name.trim()).length;
|
|
9181
|
-
const isDepositPayment = eventDetails.deposit > 0;
|
|
9182
|
-
// Build request body based on mode
|
|
9183
|
-
const requestData = {
|
|
9184
|
-
// Payment info
|
|
9185
|
-
paymentIntentId: paymentIntent.id,
|
|
9186
|
-
paymentMethod: "card",
|
|
9187
|
-
paymentStatus: isDepositPayment ? "deposit_paid" : "paid",
|
|
9188
|
-
totalAmount,
|
|
9189
|
-
depositAmount: isDepositPayment ? totalAmount : undefined,
|
|
9190
|
-
fullAmount: fullAmount,
|
|
9191
|
-
// Customer info
|
|
9192
|
-
customerEmail: formData.customerEmail,
|
|
9193
|
-
customerName: formData.customerName,
|
|
9194
|
-
customerPhone: formData.customerPhone,
|
|
9195
|
-
// Booking info
|
|
9196
|
-
participants: formData.participants.filter((p) => p.name.trim()),
|
|
9197
|
-
eventInstanceId: config.eventInstanceId || eventDetails.id,
|
|
9198
|
-
organizationId: config.organizationId, // Ensure organization ID is always included
|
|
9199
|
-
discountCode: discountCode?.code,
|
|
9200
|
-
notes: "",
|
|
9201
|
-
};
|
|
9202
|
-
// Add mode-specific fields
|
|
9203
|
-
if (isConnectMode) {
|
|
9204
|
-
Object.assign(requestData, {
|
|
9205
|
-
source: "connect",
|
|
9206
|
-
stripeAccountType: "connect",
|
|
9207
|
-
});
|
|
9208
|
-
}
|
|
9209
|
-
else {
|
|
9210
|
-
// ApiKey mode - include required proxy fields
|
|
9211
|
-
Object.assign(requestData, {
|
|
9212
|
-
bookingSystemApiUrl: config.apiBaseUrl,
|
|
9213
|
-
// apiKey would be added here if required
|
|
9214
|
-
});
|
|
9215
|
-
}
|
|
9216
|
-
console.log(`[PAYMENT_FORM] Attempting booking creation via ${endpoint}`, {
|
|
9217
|
-
mode: isConnectMode ? "connect" : "apikey",
|
|
9218
|
-
paymentIntentId: paymentIntent.id,
|
|
9219
|
-
eventInstanceId: requestData.eventInstanceId,
|
|
9220
|
-
organizationId: requestData.organizationId,
|
|
9221
|
-
participantCount: requestData.participants.length,
|
|
9222
|
-
});
|
|
9223
|
-
const bookingResponse = await fetch(getApiUrl(config.apiBaseUrl, endpoint), {
|
|
9224
|
-
method: "POST",
|
|
9225
|
-
headers: createApiHeaders(config),
|
|
9226
|
-
body: JSON.stringify(createRequestBody(config, requestData)),
|
|
9227
|
-
});
|
|
9228
|
-
const bookingData = await bookingResponse.json();
|
|
9229
|
-
if (!bookingResponse.ok) {
|
|
9230
|
-
console.error(`[PAYMENT_FORM] Booking creation failed:`, {
|
|
9231
|
-
status: bookingResponse.status,
|
|
9232
|
-
error: bookingData.error,
|
|
9233
|
-
details: bookingData.details,
|
|
9234
|
-
paymentIntentId: paymentIntent.id,
|
|
9235
|
-
});
|
|
9236
|
-
throw new Error(bookingData.error || "Fehler beim Erstellen der Buchung");
|
|
9237
|
-
}
|
|
9238
|
-
console.log(`[PAYMENT_FORM] Booking created successfully:`, {
|
|
9239
|
-
bookingId: bookingData.booking?.id,
|
|
9240
|
-
orderId: bookingData.order?.id,
|
|
9241
|
-
paymentIntentId: paymentIntent.id,
|
|
9242
|
-
});
|
|
9243
9183
|
// Booking created successfully
|
|
9244
9184
|
onSuccess({
|
|
9245
|
-
booking: bookingData.booking,
|
|
9246
|
-
payment: "succeeded",
|
|
9247
9185
|
paymentIntent: paymentIntent,
|
|
9248
|
-
formData: formData,
|
|
9249
9186
|
});
|
|
9250
9187
|
}
|
|
9251
9188
|
else {
|
|
@@ -9321,6 +9258,7 @@ function PaymentFormInner({ config, eventDetails, formData, totalAmount, discoun
|
|
|
9321
9258
|
// Main PaymentForm component that handles payment intent creation and Elements wrapper
|
|
9322
9259
|
function PaymentForm({ config, eventDetails, formData, totalAmount, discountCode, onSuccess, onError, systemConfig, stripePromise, stripeAppearance, }) {
|
|
9323
9260
|
const [clientSecret, setClientSecret] = useState(null);
|
|
9261
|
+
const [paymentIntentId, setPaymentIntentId] = useState(null);
|
|
9324
9262
|
const [isCreatingPaymentIntent, setIsCreatingPaymentIntent] = useState(false);
|
|
9325
9263
|
const [paymentError, setPaymentError] = useState(null);
|
|
9326
9264
|
// Create payment intent when component mounts or when relevant data changes
|
|
@@ -9348,11 +9286,6 @@ function PaymentForm({ config, eventDetails, formData, totalAmount, discountCode
|
|
|
9348
9286
|
setIsCreatingPaymentIntent(true);
|
|
9349
9287
|
setPaymentError(null);
|
|
9350
9288
|
try {
|
|
9351
|
-
// Determine endpoint based on system mode
|
|
9352
|
-
const isConnectMode = systemConfig.systemMode === "connect";
|
|
9353
|
-
const endpoint = isConnectMode
|
|
9354
|
-
? "/booking/create-payment-intent"
|
|
9355
|
-
: "/booking-proxy/create-payment-intent";
|
|
9356
9289
|
// Build request data with validation
|
|
9357
9290
|
const requestData = {
|
|
9358
9291
|
eventInstanceId: config.eventInstanceId || eventDetails.id,
|
|
@@ -9361,7 +9294,11 @@ function PaymentForm({ config, eventDetails, formData, totalAmount, discountCode
|
|
|
9361
9294
|
currency: "eur",
|
|
9362
9295
|
participants: formData.participants.filter((p) => p.name?.trim()),
|
|
9363
9296
|
discountCode: discountCode?.code,
|
|
9297
|
+
customerName: formData.customerName?.trim(),
|
|
9364
9298
|
customerEmail: formData.customerEmail?.trim(),
|
|
9299
|
+
customerPhone: formData.customerPhone?.trim(),
|
|
9300
|
+
comment: formData.comment?.trim(),
|
|
9301
|
+
...(paymentIntentId && { paymentIntentId }), // Include existing payment intent ID if available
|
|
9365
9302
|
};
|
|
9366
9303
|
// Validate required fields
|
|
9367
9304
|
if (!requestData.eventInstanceId) {
|
|
@@ -9379,35 +9316,15 @@ function PaymentForm({ config, eventDetails, formData, totalAmount, discountCode
|
|
|
9379
9316
|
if (!requestData.customerEmail) {
|
|
9380
9317
|
throw new Error("Customer email is required");
|
|
9381
9318
|
}
|
|
9382
|
-
|
|
9383
|
-
endpoint,
|
|
9384
|
-
mode: isConnectMode ? "connect" : "apikey",
|
|
9385
|
-
amount: requestData.amount,
|
|
9386
|
-
currency: requestData.currency,
|
|
9387
|
-
participantCount: requestData.participants.length,
|
|
9388
|
-
organizationId: requestData.organizationId,
|
|
9389
|
-
eventInstanceId: requestData.eventInstanceId,
|
|
9390
|
-
});
|
|
9391
|
-
// Add mode-specific fields
|
|
9392
|
-
if (!isConnectMode) {
|
|
9393
|
-
// ApiKey mode needs additional fields
|
|
9394
|
-
Object.assign(requestData, {
|
|
9395
|
-
bookingSystemApiUrl: config.apiBaseUrl,
|
|
9396
|
-
// apiKey would be added here if required
|
|
9397
|
-
});
|
|
9398
|
-
}
|
|
9399
|
-
const response = await fetch(getApiUrl(config.apiBaseUrl, endpoint), {
|
|
9319
|
+
const response = await fetch(getApiUrl(config.apiBaseUrl, "/booking/create-payment-intent"), {
|
|
9400
9320
|
method: "POST",
|
|
9401
9321
|
headers: createApiHeaders(config),
|
|
9402
9322
|
body: JSON.stringify(createRequestBody(config, requestData)),
|
|
9403
9323
|
});
|
|
9404
9324
|
const data = await response.json();
|
|
9405
9325
|
if (response.ok) {
|
|
9406
|
-
console.log("[PAYMENT_FORM] Payment intent created successfully:", {
|
|
9407
|
-
hasClientSecret: !!data.clientSecret,
|
|
9408
|
-
clientSecretPrefix: `${data.clientSecret?.substring(0, 20)}...`,
|
|
9409
|
-
});
|
|
9410
9326
|
setClientSecret(data.clientSecret);
|
|
9327
|
+
setPaymentIntentId(data.paymentIntentId); // Save payment intent ID for future updates
|
|
9411
9328
|
}
|
|
9412
9329
|
else {
|
|
9413
9330
|
console.error("[PAYMENT_FORM] Payment intent creation failed:", {
|
|
@@ -9683,6 +9600,7 @@ const bookingFormSchema = objectType({
|
|
|
9683
9600
|
customerPhone: stringType().optional(),
|
|
9684
9601
|
participants: arrayType(participantSchema).min(1, "Mindestens ein Teilnehmer erforderlich"),
|
|
9685
9602
|
discountCode: stringType().optional(),
|
|
9603
|
+
comment: stringType().optional(),
|
|
9686
9604
|
acceptTerms: booleanType()
|
|
9687
9605
|
.refine((val) => val === true, "Bitte akzeptiere die Allgemeinen Geschäftsbedingungen"),
|
|
9688
9606
|
});
|
|
@@ -9698,6 +9616,7 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
|
|
|
9698
9616
|
defaultValues: {
|
|
9699
9617
|
participants: [{ name: "", age: undefined }],
|
|
9700
9618
|
discountCode: "",
|
|
9619
|
+
comment: "",
|
|
9701
9620
|
acceptTerms: false,
|
|
9702
9621
|
},
|
|
9703
9622
|
});
|
|
@@ -10084,6 +10003,36 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
|
|
|
10084
10003
|
backdropFilter: "blur(4px)",
|
|
10085
10004
|
borderRadius: "var(--bw-border-radius)",
|
|
10086
10005
|
padding: "var(--bw-spacing)",
|
|
10006
|
+
}, children: [jsx("label", { htmlFor: "booking-comment", style: {
|
|
10007
|
+
fontSize: "var(--bw-font-size)",
|
|
10008
|
+
fontWeight: "500",
|
|
10009
|
+
color: "var(--bw-text-color)",
|
|
10010
|
+
fontFamily: "var(--bw-font-family)",
|
|
10011
|
+
display: "block",
|
|
10012
|
+
marginBottom: "8px",
|
|
10013
|
+
}, children: "Kommentar (optional)" }), jsx("textarea", { id: "booking-comment", ...form.register("comment"), placeholder: "Zus\u00E4tzliche Anmerkungen zu Ihrer Buchung...", rows: 3, style: {
|
|
10014
|
+
width: "100%",
|
|
10015
|
+
padding: "12px",
|
|
10016
|
+
border: `1px solid var(--bw-border-color)`,
|
|
10017
|
+
borderRadius: "var(--bw-border-radius)",
|
|
10018
|
+
fontSize: "var(--bw-font-size)",
|
|
10019
|
+
fontFamily: "var(--bw-font-family)",
|
|
10020
|
+
backgroundColor: "var(--bw-input-bg)",
|
|
10021
|
+
color: "var(--bw-text-color)",
|
|
10022
|
+
resize: "vertical",
|
|
10023
|
+
minHeight: "80px",
|
|
10024
|
+
outline: "none",
|
|
10025
|
+
transition: "border-color 0.2s ease",
|
|
10026
|
+
}, onFocus: (e) => {
|
|
10027
|
+
e.target.style.borderColor = "var(--bw-highlight-color)";
|
|
10028
|
+
}, onBlur: (e) => {
|
|
10029
|
+
e.target.style.borderColor = "var(--bw-border-color)";
|
|
10030
|
+
} })] }), jsxs("div", { style: {
|
|
10031
|
+
backgroundColor: "var(--bw-surface-color)",
|
|
10032
|
+
border: `1px solid var(--bw-border-color)`,
|
|
10033
|
+
backdropFilter: "blur(4px)",
|
|
10034
|
+
borderRadius: "var(--bw-border-radius)",
|
|
10035
|
+
padding: "var(--bw-spacing)",
|
|
10087
10036
|
}, children: [jsxs("div", { style: { display: "flex", alignItems: "center", gap: "12px" }, children: [jsx("input", { id: "acceptTerms", ...form.register("acceptTerms"), type: "checkbox", style: {
|
|
10088
10037
|
marginTop: "4px",
|
|
10089
10038
|
width: "20px",
|
|
@@ -10256,162 +10205,339 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
|
|
|
10256
10205
|
` })] }) }));
|
|
10257
10206
|
}
|
|
10258
10207
|
|
|
10259
|
-
const BookingSuccessModal = ({ isOpen, onClose,
|
|
10260
|
-
|
|
10208
|
+
const BookingSuccessModal = ({ isOpen, onClose, config, onError, paymentIntentId, }) => {
|
|
10209
|
+
const [bookingData, setBookingData] = useState(null);
|
|
10210
|
+
const [eventDetails, setEventDetails] = useState(null);
|
|
10211
|
+
const [formData, setFormData] = useState(null);
|
|
10212
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
10213
|
+
const [paymentStatus, setPaymentStatus] = useState(null);
|
|
10214
|
+
const fetchBookingData = async (intentId) => {
|
|
10215
|
+
const targetPaymentIntentId = paymentIntentId;
|
|
10216
|
+
// If we have payment intent ID, fetch from API
|
|
10217
|
+
if (targetPaymentIntentId) {
|
|
10218
|
+
setIsLoading(true);
|
|
10219
|
+
try {
|
|
10220
|
+
const response = await fetch(getApiUrl(config.apiBaseUrl, "/booking/get-booking-by-payment-intent"), {
|
|
10221
|
+
method: "POST",
|
|
10222
|
+
headers: createApiHeaders(config),
|
|
10223
|
+
body: JSON.stringify(createRequestBody(config, {
|
|
10224
|
+
paymentIntentId: targetPaymentIntentId,
|
|
10225
|
+
})),
|
|
10226
|
+
});
|
|
10227
|
+
const data = await response.json();
|
|
10228
|
+
if (response.ok) {
|
|
10229
|
+
setBookingData({
|
|
10230
|
+
booking: data.booking,
|
|
10231
|
+
order: data.order,
|
|
10232
|
+
payments: data.payments,
|
|
10233
|
+
orderItems: data.orderItems,
|
|
10234
|
+
stripePaymentIntent: data.stripePaymentIntent,
|
|
10235
|
+
});
|
|
10236
|
+
setEventDetails({
|
|
10237
|
+
id: data.booking.eventInstance.id,
|
|
10238
|
+
name: data.booking.eventInstance.eventType.name,
|
|
10239
|
+
description: data.booking.eventInstance.eventType.description,
|
|
10240
|
+
startTime: data.booking.eventInstance.startTime,
|
|
10241
|
+
endTime: data.booking.eventInstance.endTime,
|
|
10242
|
+
price: data.order.total / data.booking.participantCount,
|
|
10243
|
+
});
|
|
10244
|
+
setFormData({
|
|
10245
|
+
customerEmail: data.booking.customerEmail,
|
|
10246
|
+
customerName: data.booking.customerName,
|
|
10247
|
+
customerPhone: data.booking.customerPhone,
|
|
10248
|
+
participants: data.booking.participants || [],
|
|
10249
|
+
});
|
|
10250
|
+
// Set payment status from Stripe data or order status
|
|
10251
|
+
setPaymentStatus(data.stripePaymentIntent?.status || data.order.status);
|
|
10252
|
+
}
|
|
10253
|
+
else {
|
|
10254
|
+
onError?.(data.error || "Fehler beim Abrufen der Buchungsdaten");
|
|
10255
|
+
}
|
|
10256
|
+
}
|
|
10257
|
+
catch (err) {
|
|
10258
|
+
console.error("[BookingSuccessModal] Error fetching booking data:", err);
|
|
10259
|
+
onError?.("Ein Fehler ist bei der Verarbeitung aufgetreten.");
|
|
10260
|
+
}
|
|
10261
|
+
finally {
|
|
10262
|
+
setIsLoading(false);
|
|
10263
|
+
}
|
|
10264
|
+
return;
|
|
10265
|
+
}
|
|
10266
|
+
};
|
|
10267
|
+
useEffect(() => {
|
|
10268
|
+
if (isOpen) {
|
|
10269
|
+
fetchBookingData();
|
|
10270
|
+
}
|
|
10271
|
+
}, [isOpen, paymentIntentId, config, onError]);
|
|
10272
|
+
if (!isOpen)
|
|
10261
10273
|
return null;
|
|
10274
|
+
// Show loading state while fetching data
|
|
10275
|
+
if (isLoading || !bookingData) {
|
|
10276
|
+
return (jsx(DialogWrapper, { isOpen: isOpen, onClose: onClose, maxWidth: "700px", children: jsx("div", { style: {
|
|
10277
|
+
padding: "var(--bw-spacing-large)",
|
|
10278
|
+
textAlign: "center",
|
|
10279
|
+
minHeight: "200px",
|
|
10280
|
+
display: "flex",
|
|
10281
|
+
alignItems: "center",
|
|
10282
|
+
justifyContent: "center",
|
|
10283
|
+
}, children: jsx("div", { style: {
|
|
10284
|
+
color: "var(--bw-text-muted)",
|
|
10285
|
+
fontFamily: "var(--bw-font-family)",
|
|
10286
|
+
fontSize: "var(--bw-font-size-large)",
|
|
10287
|
+
}, children: "Buchungsdaten werden geladen..." }) }) }));
|
|
10288
|
+
}
|
|
10262
10289
|
const booking = bookingData.booking;
|
|
10263
|
-
|
|
10264
|
-
|
|
10265
|
-
|
|
10266
|
-
|
|
10267
|
-
|
|
10268
|
-
|
|
10269
|
-
|
|
10270
|
-
|
|
10271
|
-
|
|
10272
|
-
|
|
10273
|
-
|
|
10274
|
-
|
|
10275
|
-
|
|
10276
|
-
|
|
10277
|
-
|
|
10278
|
-
|
|
10279
|
-
fontWeight: "700",
|
|
10280
|
-
color: "var(--bw-text-color)",
|
|
10281
|
-
margin: "0 0 var(--bw-spacing-small) 0",
|
|
10282
|
-
fontFamily: "var(--bw-font-family)",
|
|
10283
|
-
}, children: "Buchung erfolgreich!" }), jsx("p", { style: {
|
|
10284
|
-
color: "var(--bw-text-muted)",
|
|
10285
|
-
fontFamily: "var(--bw-font-family)",
|
|
10286
|
-
margin: 0,
|
|
10287
|
-
}, children: "Deine Buchung wurde erfolgreich abgeschlossen." })] }), jsxs("div", { style: {
|
|
10288
|
-
backgroundColor: "var(--bw-surface-color)",
|
|
10289
|
-
border: `1px solid var(--bw-border-color)`,
|
|
10290
|
-
borderRadius: "var(--bw-border-radius)",
|
|
10291
|
-
padding: "var(--bw-spacing)",
|
|
10290
|
+
new Date(eventDetails.startTime);
|
|
10291
|
+
new Date(eventDetails.endTime);
|
|
10292
|
+
const handlePrint = () => {
|
|
10293
|
+
window.print();
|
|
10294
|
+
};
|
|
10295
|
+
const formatTime12 = (dateString) => {
|
|
10296
|
+
return formatTime(dateString, "Europe/Berlin", "de");
|
|
10297
|
+
};
|
|
10298
|
+
const formatDate12 = (dateString) => {
|
|
10299
|
+
return formatEventDate(dateString);
|
|
10300
|
+
};
|
|
10301
|
+
return (jsx(DialogWrapper, { isOpen: isOpen, onClose: onClose, maxWidth: "700px", children: jsxs("div", { style: {
|
|
10302
|
+
fontFamily: "var(--bw-font-family)",
|
|
10303
|
+
padding: "var(--bw-spacing-large)",
|
|
10304
|
+
maxWidth: "100%",
|
|
10305
|
+
}, children: [jsxs("div", { className: "flex justify-between items-center print-hidden", style: {
|
|
10292
10306
|
marginBottom: "var(--bw-spacing-large)",
|
|
10293
|
-
|
|
10294
|
-
|
|
10295
|
-
|
|
10307
|
+
display: "flex",
|
|
10308
|
+
alignItems: "center",
|
|
10309
|
+
justifyContent: "space-between",
|
|
10310
|
+
}, children: [jsxs("h1", { className: "font-bold text-3xl flex items-center gap-2", style: {
|
|
10296
10311
|
color: "var(--bw-text-color)",
|
|
10297
|
-
margin: "0 0 var(--bw-spacing) 0",
|
|
10298
10312
|
fontFamily: "var(--bw-font-family)",
|
|
10299
|
-
|
|
10300
|
-
|
|
10301
|
-
|
|
10302
|
-
|
|
10303
|
-
|
|
10304
|
-
|
|
10305
|
-
|
|
10306
|
-
|
|
10307
|
-
|
|
10308
|
-
color: "var(--bw-text-color)",
|
|
10309
|
-
fontWeight: "500",
|
|
10310
|
-
fontFamily: "var(--bw-font-family)",
|
|
10311
|
-
textAlign: "right",
|
|
10312
|
-
maxWidth: "60%",
|
|
10313
|
-
}, children: eventDetails.name })] }), jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsx("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: "Datum:" }), jsx("span", { style: {
|
|
10314
|
-
color: "var(--bw-text-color)",
|
|
10315
|
-
fontWeight: "500",
|
|
10316
|
-
fontFamily: "var(--bw-font-family)",
|
|
10317
|
-
textAlign: "right",
|
|
10318
|
-
maxWidth: "60%",
|
|
10319
|
-
}, children: formatEventDate(eventDetails.startTime) })] }), jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsx("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: "Uhrzeit:" }), jsx("span", { style: {
|
|
10320
|
-
color: "var(--bw-text-color)",
|
|
10321
|
-
fontWeight: "500",
|
|
10322
|
-
fontFamily: "var(--bw-font-family)",
|
|
10323
|
-
textAlign: "right",
|
|
10324
|
-
maxWidth: "60%",
|
|
10325
|
-
}, children: formatTime(eventDetails.startTime, "Europe/Berlin", "de") })] }), jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsx("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: "Teilnehmer:" }), jsx("span", { style: {
|
|
10326
|
-
color: "var(--bw-text-color)",
|
|
10327
|
-
fontWeight: "500",
|
|
10328
|
-
fontFamily: "var(--bw-font-family)",
|
|
10329
|
-
}, children: booking.participantCount })] }), jsxs("div", { style: {
|
|
10313
|
+
marginBottom: "var(--bw-spacing-large)",
|
|
10314
|
+
display: "flex",
|
|
10315
|
+
alignItems: "center",
|
|
10316
|
+
gap: "var(--bw-spacing-small)",
|
|
10317
|
+
}, children: [jsx("div", { style: {
|
|
10318
|
+
width: "32px",
|
|
10319
|
+
height: "32px",
|
|
10320
|
+
backgroundColor: "var(--bw-highlight-color, #10B981)",
|
|
10321
|
+
borderRadius: "50%",
|
|
10330
10322
|
display: "flex",
|
|
10331
|
-
justifyContent: "space-between",
|
|
10332
10323
|
alignItems: "center",
|
|
10333
|
-
|
|
10334
|
-
|
|
10335
|
-
|
|
10336
|
-
|
|
10337
|
-
|
|
10338
|
-
|
|
10339
|
-
|
|
10340
|
-
|
|
10341
|
-
|
|
10342
|
-
|
|
10343
|
-
fontSize: "var(--bw-font-size-large)",
|
|
10344
|
-
fontFamily: "var(--bw-font-family)",
|
|
10345
|
-
}, children: formatCurrency(booking.total) })] })] })] }), formData.participants && formData.participants.length > 0 && (jsxs("div", { style: {
|
|
10346
|
-
border: `1px solid var(--bw-border-color)`,
|
|
10347
|
-
borderRadius: "var(--bw-border-radius)",
|
|
10348
|
-
padding: "var(--bw-spacing)",
|
|
10349
|
-
marginBottom: "var(--bw-spacing-large)",
|
|
10350
|
-
}, children: [jsx("h3", { style: {
|
|
10351
|
-
fontSize: "var(--bw-font-size-large)",
|
|
10352
|
-
fontWeight: "600",
|
|
10324
|
+
justifyContent: "center",
|
|
10325
|
+
color: "white",
|
|
10326
|
+
}, children: "\u2713" }), jsx("p", { style: {
|
|
10327
|
+
fontSize: "var(--bw-font-size-large)",
|
|
10328
|
+
fontWeight: "600",
|
|
10329
|
+
color: "var(--bw-highlight-color)",
|
|
10330
|
+
margin: "0px 10px",
|
|
10331
|
+
}, children: "Buchung erfolgreich erstellt!" })] }), jsx("button", { onClick: handlePrint, style: {
|
|
10332
|
+
backgroundColor: "transparent",
|
|
10333
|
+
border: `1px solid var(--bw-border-color)`,
|
|
10353
10334
|
color: "var(--bw-text-color)",
|
|
10354
|
-
|
|
10335
|
+
padding: "8px 16px",
|
|
10336
|
+
borderRadius: "var(--bw-border-radius)",
|
|
10337
|
+
cursor: "pointer",
|
|
10355
10338
|
fontFamily: "var(--bw-font-family)",
|
|
10356
|
-
|
|
10357
|
-
|
|
10358
|
-
|
|
10359
|
-
|
|
10360
|
-
|
|
10361
|
-
|
|
10362
|
-
|
|
10363
|
-
|
|
10364
|
-
|
|
10339
|
+
fontSize: "var(--bw-font-size-small)",
|
|
10340
|
+
}, children: "Drucken" })] }), jsxs("div", { className: "print-only print-booking-header", children: [jsx("h1", { children: "Buchungsbest\u00E4tigung" }), jsx("div", { className: "subtitle", children: "Vielen Dank f\u00FCr deine Buchung! Hier sind deine Buchungsdetails." })] }), jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "var(--bw-spacing-large)" }, children: [jsxs("div", { className: "print-booking-card", style: {
|
|
10341
|
+
backgroundColor: "var(--bw-surface-color)",
|
|
10342
|
+
border: `1px solid var(--bw-border-color)`,
|
|
10343
|
+
borderRadius: "var(--bw-border-radius)",
|
|
10344
|
+
padding: "var(--bw-spacing)",
|
|
10345
|
+
marginBottom: "var(--bw-spacing-large)",
|
|
10346
|
+
}, children: [jsx("div", { className: "print-hidden", style: { marginBottom: "var(--bw-spacing)" }, children: jsx("h3", { style: {
|
|
10347
|
+
fontSize: "var(--bw-font-size-large)",
|
|
10348
|
+
fontWeight: "600",
|
|
10365
10349
|
color: "var(--bw-text-color)",
|
|
10350
|
+
margin: "0",
|
|
10366
10351
|
fontFamily: "var(--bw-font-family)",
|
|
10367
|
-
}, children:
|
|
10368
|
-
|
|
10369
|
-
|
|
10352
|
+
}, children: "Buchungsdetails" }) }), jsx("div", { className: "print-only", children: jsx("div", { className: "print-section-title", children: "Buchungsdetails" }) }), jsxs("div", { className: "space-y-4 print-only:space-y-2 print-only:p-0", children: [jsxs("div", { className: "gap-4 grid grid-cols-2 print-detail-grid", style: {
|
|
10353
|
+
display: "grid",
|
|
10354
|
+
gridTemplateColumns: "1fr 1fr",
|
|
10355
|
+
gap: "var(--bw-spacing)",
|
|
10356
|
+
}, children: [jsxs("div", { className: "print-detail-item", style: { marginBottom: "span 2" }, children: [jsx("div", { className: "font-medium text-muted-foreground text-sm print-detail-label", style: {
|
|
10357
|
+
color: "var(--bw-text-muted)",
|
|
10358
|
+
fontSize: "var(--bw-font-size-small)",
|
|
10359
|
+
fontFamily: "var(--bw-font-family)",
|
|
10360
|
+
}, children: "Buchungs-ID" }), jsx("p", { className: "font-semibold print-detail-value", style: {
|
|
10361
|
+
fontWeight: "600",
|
|
10362
|
+
color: "var(--bw-text-color)",
|
|
10363
|
+
fontFamily: "var(--bw-font-family)",
|
|
10364
|
+
fontSize: "var(--bw-font-size-medium)",
|
|
10365
|
+
margin: "0px 0px 6px 0",
|
|
10366
|
+
}, children: booking.bookingHash })] }), jsxs("div", { className: "print-detail-item", children: [jsx("div", { className: "font-medium text-muted-foreground text-sm print-detail-label", style: {
|
|
10367
|
+
color: "var(--bw-text-muted)",
|
|
10368
|
+
fontSize: "var(--bw-font-size-small)",
|
|
10369
|
+
fontFamily: "var(--bw-font-family)",
|
|
10370
|
+
}, children: "Bezahl-Status" }), jsxs("div", { children: [jsx("span", { className: "print-hidden", style: {
|
|
10371
|
+
backgroundColor: "var(--bw-success-color, #10B981)",
|
|
10372
|
+
color: "white",
|
|
10373
|
+
padding: "2px 8px",
|
|
10374
|
+
borderRadius: "var(--bw-border-radius-small)",
|
|
10375
|
+
fontSize: "var(--bw-font-size-small)",
|
|
10376
|
+
fontFamily: "var(--bw-font-family)",
|
|
10377
|
+
width: "fit-content",
|
|
10378
|
+
}, children: paymentStatus === "succeeded"
|
|
10379
|
+
? "erfolgreich"
|
|
10380
|
+
: paymentStatus === "canceled" || paymentStatus === "failed"
|
|
10381
|
+
? "fehlgeschlagen"
|
|
10382
|
+
: "in Bearbeitung" }), jsx("span", { className: "print-only print-status-badge print-status-paid", children: "Bezahlt" })] })] })] }), jsxs("div", { className: "print-detail-item print-only:col-span-2", children: [jsx("div", { className: "font-medium text-muted-foreground text-sm print-detail-label", style: {
|
|
10383
|
+
color: "var(--bw-text-muted)",
|
|
10384
|
+
fontSize: "var(--bw-font-size-small)",
|
|
10385
|
+
fontFamily: "var(--bw-font-family)",
|
|
10386
|
+
}, children: "Event" }), jsx("p", { className: "font-semibold print-detail-value", style: {
|
|
10387
|
+
fontWeight: "600",
|
|
10388
|
+
color: "var(--bw-text-color)",
|
|
10389
|
+
fontFamily: "var(--bw-font-family)",
|
|
10390
|
+
fontSize: "var(--bw-font-size-large)",
|
|
10391
|
+
margin: "0 0 6px 0",
|
|
10392
|
+
}, children: eventDetails.name })] }), jsxs("div", { className: "gap-4 grid grid-cols-2 print-detail-grid", style: {
|
|
10393
|
+
display: "grid",
|
|
10394
|
+
gridTemplateColumns: "1fr 1fr",
|
|
10395
|
+
gap: "var(--bw-spacing)",
|
|
10396
|
+
}, children: [jsxs("div", { className: "print-detail-item", children: [jsx("div", { className: "font-medium text-muted-foreground text-sm print-detail-label", style: {
|
|
10397
|
+
color: "var(--bw-text-muted)",
|
|
10398
|
+
fontSize: "var(--bw-font-size-small)",
|
|
10399
|
+
fontFamily: "var(--bw-font-family)",
|
|
10400
|
+
}, children: "Datum" }), jsx("p", { className: "print-detail-value", style: {
|
|
10401
|
+
fontWeight: "600",
|
|
10402
|
+
color: "var(--bw-text-color)",
|
|
10403
|
+
fontFamily: "var(--bw-font-family)",
|
|
10404
|
+
fontSize: "var(--bw-font-size-large)",
|
|
10405
|
+
margin: "0 0 6px 0",
|
|
10406
|
+
}, children: formatDate12(eventDetails.startTime) })] }), jsxs("div", { className: "print-detail-item", children: [jsx("div", { className: "font-medium text-muted-foreground text-sm print-detail-label", style: {
|
|
10407
|
+
color: "var(--bw-text-muted)",
|
|
10408
|
+
fontSize: "var(--bw-font-size-small)",
|
|
10409
|
+
fontFamily: "var(--bw-font-family)",
|
|
10410
|
+
}, children: "Zeit" }), jsxs("p", { className: "print-detail-value", style: {
|
|
10411
|
+
fontWeight: "600",
|
|
10412
|
+
color: "var(--bw-text-color)",
|
|
10413
|
+
fontFamily: "var(--bw-font-family)",
|
|
10414
|
+
fontSize: "var(--bw-font-size-large)",
|
|
10415
|
+
margin: "0 0 6px 0",
|
|
10416
|
+
}, children: [formatTime12(eventDetails.startTime), " - ", formatTime12(eventDetails.endTime)] })] })] })] })] }), formData.participants && formData.participants.length > 0 && (jsxs("div", { className: "print-booking-card", style: {
|
|
10417
|
+
border: `1px solid var(--bw-border-color)`,
|
|
10418
|
+
borderRadius: "var(--bw-border-radius)",
|
|
10419
|
+
padding: "var(--bw-spacing)",
|
|
10420
|
+
marginBottom: "var(--bw-spacing-large)",
|
|
10421
|
+
}, children: [jsx("div", { className: "print-hidden", style: { marginBottom: "var(--bw-spacing)" }, children: jsxs("h3", { style: {
|
|
10422
|
+
fontSize: "var(--bw-font-size-large)",
|
|
10423
|
+
fontWeight: "600",
|
|
10424
|
+
color: "var(--bw-text-color)",
|
|
10425
|
+
margin: "0",
|
|
10370
10426
|
fontFamily: "var(--bw-font-family)",
|
|
10371
|
-
}, children: [
|
|
10372
|
-
|
|
10373
|
-
|
|
10374
|
-
|
|
10375
|
-
|
|
10376
|
-
|
|
10377
|
-
|
|
10378
|
-
|
|
10379
|
-
|
|
10380
|
-
|
|
10381
|
-
|
|
10382
|
-
|
|
10383
|
-
|
|
10384
|
-
|
|
10385
|
-
|
|
10386
|
-
|
|
10387
|
-
|
|
10388
|
-
|
|
10389
|
-
|
|
10390
|
-
|
|
10391
|
-
|
|
10392
|
-
|
|
10393
|
-
|
|
10394
|
-
|
|
10395
|
-
|
|
10396
|
-
|
|
10397
|
-
|
|
10398
|
-
|
|
10399
|
-
|
|
10400
|
-
|
|
10401
|
-
|
|
10402
|
-
|
|
10403
|
-
|
|
10404
|
-
|
|
10405
|
-
|
|
10406
|
-
|
|
10407
|
-
|
|
10408
|
-
|
|
10409
|
-
|
|
10410
|
-
|
|
10411
|
-
|
|
10412
|
-
|
|
10413
|
-
|
|
10414
|
-
|
|
10427
|
+
}, children: ["Teilnehmer (", formData.participants.length, ")"] }) }), jsx("div", { className: "print-only", children: jsxs("div", { className: "print-section-title", children: ["Teilnehmer (", formData.participants.length, ")"] }) }), jsx("div", { className: "print-only:p-0", children: jsx("div", { className: "space-y-3 print-only:space-y-1", style: {
|
|
10428
|
+
display: "flex",
|
|
10429
|
+
flexDirection: "column",
|
|
10430
|
+
gap: "var(--bw-spacing-small)",
|
|
10431
|
+
}, children: formData.participants
|
|
10432
|
+
.filter((p) => p.name.trim())
|
|
10433
|
+
.map((participant, index) => (jsx("div", { className: "flex justify-between items-center bg-muted p-3 rounded-lg print-participant", style: {
|
|
10434
|
+
display: "flex",
|
|
10435
|
+
justifyContent: "space-between",
|
|
10436
|
+
alignItems: "center",
|
|
10437
|
+
backgroundColor: "var(--bw-surface-color, #f9fafb)",
|
|
10438
|
+
padding: "var(--bw-spacing-small)",
|
|
10439
|
+
borderRadius: "var(--bw-border-radius-small)",
|
|
10440
|
+
}, children: jsxs("div", { className: "print-participant-info", children: [jsx("div", { className: "print-participant-name", style: {
|
|
10441
|
+
color: "var(--bw-text-color)",
|
|
10442
|
+
fontFamily: "var(--bw-font-family)",
|
|
10443
|
+
}, children: participant.name }), participant.age && (jsxs("div", { className: "text-muted-foreground text-sm print-participant-age", style: {
|
|
10444
|
+
color: "var(--bw-text-muted)",
|
|
10445
|
+
fontSize: "var(--bw-font-size-small)",
|
|
10446
|
+
fontFamily: "var(--bw-font-family)",
|
|
10447
|
+
}, children: [participant.age, " Jahre"] }))] }) }, index))) }) })] })), jsxs("div", { className: "print-booking-card", style: {
|
|
10448
|
+
backgroundColor: "var(--bw-surface-color)",
|
|
10449
|
+
border: `1px solid var(--bw-border-color)`,
|
|
10450
|
+
borderRadius: "var(--bw-border-radius)",
|
|
10451
|
+
padding: "var(--bw-spacing)",
|
|
10452
|
+
marginBottom: "var(--bw-spacing-large)",
|
|
10453
|
+
}, children: [jsx("div", { className: "print-hidden", style: { marginBottom: "var(--bw-spacing)" }, children: jsx("h3", { style: {
|
|
10454
|
+
fontSize: "var(--bw-font-size-large)",
|
|
10455
|
+
fontWeight: "600",
|
|
10456
|
+
color: "var(--bw-text-color)",
|
|
10457
|
+
margin: "0",
|
|
10458
|
+
fontFamily: "var(--bw-font-family)",
|
|
10459
|
+
}, children: "Zahlungs\u00FCbersicht" }) }), jsx("div", { className: "print-only", children: jsx("div", { className: "print-section-title", children: "Zahlungs\u00FCbersicht" }) }), jsxs("div", { className: "space-y-2 print-only:p-0 print-only:space-y-1", children: [jsxs("div", { className: "print-payment-summary print-only", children: [jsxs("div", { className: "print-payment-row", children: [jsx("span", { children: "Gesamtbetrag" }), jsx("span", { children: formatCurrency(booking.total) })] }), jsxs("div", { className: "print-payment-row", children: [jsx("span", { children: "Bezahlt" }), jsx("span", { children: formatCurrency(booking.total) })] })] }), jsxs("div", { className: "print-hidden space-y-2", style: { display: "flex", flexDirection: "column", gap: "var(--bw-spacing-small)" }, children: [jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsx("span", { style: { color: "var(--bw-text-color)", fontFamily: "var(--bw-font-family)" }, children: "Gesamtbetrag" }), jsx("span", { style: { color: "var(--bw-text-color)", fontFamily: "var(--bw-font-family)" }, children: formatCurrency(booking.total) })] }), jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsx("span", { style: { color: "var(--bw-text-color)", fontFamily: "var(--bw-font-family)" }, children: "Bezahlt" }), jsx("span", { style: { color: "var(--bw-text-color)", fontFamily: "var(--bw-font-family)" }, children: formatCurrency(booking.total) })] })] })] })] }), jsxs("div", { className: "print-booking-card", style: {
|
|
10460
|
+
backgroundColor: "var(--bw-surface-color)",
|
|
10461
|
+
border: `1px solid var(--bw-border-color)`,
|
|
10462
|
+
borderRadius: "var(--bw-border-radius)",
|
|
10463
|
+
padding: "var(--bw-spacing)",
|
|
10464
|
+
marginBottom: "var(--bw-spacing-large)",
|
|
10465
|
+
}, children: [jsx("div", { className: "print-hidden", style: { marginBottom: "var(--bw-spacing)" }, children: jsx("h3", { style: {
|
|
10466
|
+
fontSize: "var(--bw-font-size-large)",
|
|
10467
|
+
fontWeight: "600",
|
|
10468
|
+
color: "var(--bw-text-color)",
|
|
10469
|
+
margin: "0",
|
|
10470
|
+
fontFamily: "var(--bw-font-family)",
|
|
10471
|
+
}, children: "Kontaktdaten" }) }), jsx("div", { className: "print-only", children: jsx("div", { className: "print-section-title", children: "Kontaktdaten" }) }), jsxs("div", { className: "space-y-2 print-only:p-0 print-only:space-y-1", style: { display: "flex", flexDirection: "column", gap: "var(--bw-spacing-small)" }, children: [jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsx("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: "Name:" }), jsx("span", { style: { color: "var(--bw-text-color)", fontFamily: "var(--bw-font-family)" }, children: formData.customerName })] }), jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsx("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: "E-Mail:" }), jsx("span", { style: { color: "var(--bw-text-color)", fontFamily: "var(--bw-font-family)" }, children: formData.customerEmail })] }), formData.customerPhone && (jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsx("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: "Telefon:" }), jsx("span", { style: { color: "var(--bw-text-color)", fontFamily: "var(--bw-font-family)" }, children: formData.customerPhone })] }))] })] }), jsx("div", { className: "print-booking-card", style: {
|
|
10472
|
+
backgroundColor: "var(--bw-surface-color)",
|
|
10473
|
+
border: `1px solid var(--bw-border-color)`,
|
|
10474
|
+
borderRadius: "var(--bw-border-radius)",
|
|
10475
|
+
padding: "var(--bw-spacing)",
|
|
10476
|
+
marginBottom: "var(--bw-spacing-large)",
|
|
10477
|
+
textAlign: "center",
|
|
10478
|
+
}, children: jsxs("p", { style: {
|
|
10479
|
+
color: "var(--bw-text-muted)",
|
|
10480
|
+
margin: 0,
|
|
10481
|
+
fontFamily: "var(--bw-font-family)",
|
|
10482
|
+
fontSize: "var(--bw-font-size-small)",
|
|
10483
|
+
textAlign: "center",
|
|
10484
|
+
}, children: ["Eine Best\u00E4tigungs-E-Mail wird in K\u00FCrze an ", formData.customerEmail, " gesendet."] }) }), paymentStatus && paymentStatus !== "succeeded" && (jsxs("div", { style: {
|
|
10485
|
+
backgroundColor: "var(--bw-warning-bg, #FEF3C7)",
|
|
10486
|
+
border: "1px solid var(--bw-warning-border, #F59E0B)",
|
|
10487
|
+
borderRadius: "var(--bw-border-radius)",
|
|
10488
|
+
padding: "var(--bw-spacing)",
|
|
10489
|
+
marginBottom: "var(--bw-spacing-large)",
|
|
10490
|
+
textAlign: "center",
|
|
10491
|
+
}, children: [jsx("p", { style: {
|
|
10492
|
+
color: "var(--bw-warning-text, #92400E)",
|
|
10493
|
+
margin: "0 0 var(--bw-spacing) 0",
|
|
10494
|
+
fontFamily: "var(--bw-font-family)",
|
|
10495
|
+
fontWeight: "600",
|
|
10496
|
+
}, children: "Zahlung wird noch verarbeitet" }), jsxs("p", { style: {
|
|
10497
|
+
color: "var(--bw-warning-text, #92400E)",
|
|
10498
|
+
margin: "0 0 var(--bw-spacing) 0",
|
|
10499
|
+
fontFamily: "var(--bw-font-family)",
|
|
10500
|
+
fontSize: "var(--bw-font-size-small)",
|
|
10501
|
+
}, children: ["Status: ", paymentStatus] }), jsx("button", { onClick: () => fetchBookingData(), disabled: isLoading, style: {
|
|
10502
|
+
backgroundColor: "var(--bw-warning-text, #92400E)",
|
|
10503
|
+
color: "white",
|
|
10504
|
+
padding: "8px 16px",
|
|
10505
|
+
border: "none",
|
|
10506
|
+
borderRadius: "var(--bw-border-radius)",
|
|
10507
|
+
fontSize: "var(--bw-font-size-small)",
|
|
10508
|
+
fontWeight: "600",
|
|
10509
|
+
cursor: isLoading ? "not-allowed" : "pointer",
|
|
10510
|
+
fontFamily: "var(--bw-font-family)",
|
|
10511
|
+
opacity: isLoading ? 0.6 : 1,
|
|
10512
|
+
transition: "all 0.2s ease",
|
|
10513
|
+
}, children: isLoading ? "Aktualisiere..." : "Status aktualisieren" })] })), jsx("div", { style: {
|
|
10514
|
+
textAlign: "center",
|
|
10515
|
+
marginTop: "var(--bw-spacing-large)",
|
|
10516
|
+
paddingTop: "var(--bw-spacing)",
|
|
10517
|
+
borderTop: `1px solid var(--bw-border-color)`,
|
|
10518
|
+
}, children: jsx("button", { onClick: onClose, style: {
|
|
10519
|
+
backgroundColor: "var(--bw-highlight-color)",
|
|
10520
|
+
color: "white",
|
|
10521
|
+
padding: "12px 32px",
|
|
10522
|
+
border: "none",
|
|
10523
|
+
borderRadius: "var(--bw-border-radius)",
|
|
10524
|
+
fontSize: "var(--bw-font-size)",
|
|
10525
|
+
fontWeight: "600",
|
|
10526
|
+
cursor: "pointer",
|
|
10527
|
+
fontFamily: "var(--bw-font-family)",
|
|
10528
|
+
transition: "all 0.2s ease",
|
|
10529
|
+
}, onMouseEnter: (e) => {
|
|
10530
|
+
e.currentTarget.style.opacity = "0.9";
|
|
10531
|
+
}, onMouseLeave: (e) => {
|
|
10532
|
+
e.currentTarget.style.opacity = "1";
|
|
10533
|
+
}, children: "Schlie\u00DFen" }) }), jsxs("div", { className: "print-only print-footer", children: [jsxs("p", { children: ["Diese Buchungsbest\u00E4tigung wurde am", " ", new Date().toLocaleString("de-DE", {
|
|
10534
|
+
day: "2-digit",
|
|
10535
|
+
month: "2-digit",
|
|
10536
|
+
year: "numeric",
|
|
10537
|
+
hour: "2-digit",
|
|
10538
|
+
minute: "2-digit",
|
|
10539
|
+
timeZone: "Europe/Berlin",
|
|
10540
|
+
}), " ", "erstellt."] }), jsx("p", { children: "Bei Fragen zu deiner Buchung kontaktiere uns gerne." })] })] })] }) }));
|
|
10415
10541
|
};
|
|
10416
10542
|
|
|
10417
10543
|
const months = [
|
|
@@ -11527,7 +11653,7 @@ function UniversalBookingWidget({ config: baseConfig }) {
|
|
|
11527
11653
|
const [isLoadingShowAll, setIsLoadingShowAll] = useState(false); // For "show all events" operation
|
|
11528
11654
|
const [error, setError] = useState(null);
|
|
11529
11655
|
const [isSuccess, setIsSuccess] = useState(false);
|
|
11530
|
-
const [
|
|
11656
|
+
const [successPaymentIntentId, setSuccessPaymentIntentId] = useState(null);
|
|
11531
11657
|
const [systemConfig, setSystemConfig] = useState(null);
|
|
11532
11658
|
// PERFORMANCE OPTIMIZATION: Lazy component loading
|
|
11533
11659
|
const [shouldRenderInstanceSelection, setShouldRenderInstanceSelection] = useState(false);
|
|
@@ -11574,6 +11700,29 @@ function UniversalBookingWidget({ config: baseConfig }) {
|
|
|
11574
11700
|
initializeWidget();
|
|
11575
11701
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
11576
11702
|
}, [config]);
|
|
11703
|
+
// Handle Stripe payment return
|
|
11704
|
+
useEffect(() => {
|
|
11705
|
+
const handleStripeReturn = () => {
|
|
11706
|
+
const stripeReturn = detectStripeReturn();
|
|
11707
|
+
if (stripeReturn) {
|
|
11708
|
+
if (stripeReturn.redirectStatus === "succeeded") {
|
|
11709
|
+
// Store payment intent ID and show success modal
|
|
11710
|
+
setSuccessPaymentIntentId(stripeReturn.paymentIntent);
|
|
11711
|
+
setIsSuccess(true);
|
|
11712
|
+
}
|
|
11713
|
+
else if (stripeReturn.redirectStatus === "failed") {
|
|
11714
|
+
setError("Die Zahlung war nicht erfolgreich. Bitte versuche es erneut.");
|
|
11715
|
+
}
|
|
11716
|
+
else {
|
|
11717
|
+
setError("Die Zahlung konnte nicht abgeschlossen werden. Bitte versuche es erneut.");
|
|
11718
|
+
}
|
|
11719
|
+
}
|
|
11720
|
+
};
|
|
11721
|
+
// Only run on mount to avoid running multiple times
|
|
11722
|
+
if (!isLoading) {
|
|
11723
|
+
handleStripeReturn();
|
|
11724
|
+
}
|
|
11725
|
+
}, [isLoading]); // Only depend on isLoading to run after initial load
|
|
11577
11726
|
// PERFORMANCE OPTIMIZATION: Lazy load components when needed
|
|
11578
11727
|
useEffect(() => {
|
|
11579
11728
|
if (currentStep === "eventInstances" && !shouldRenderInstanceSelection) {
|
|
@@ -11816,7 +11965,7 @@ function UniversalBookingWidget({ config: baseConfig }) {
|
|
|
11816
11965
|
};
|
|
11817
11966
|
const handleBookingSuccess = (result) => {
|
|
11818
11967
|
setIsSuccess(true);
|
|
11819
|
-
|
|
11968
|
+
setSuccessPaymentIntentId(result.paymentIntent.id);
|
|
11820
11969
|
config.onSuccess?.(result);
|
|
11821
11970
|
};
|
|
11822
11971
|
const handleBookingError = (errorMessage) => {
|
|
@@ -11999,10 +12148,18 @@ function UniversalBookingWidget({ config: baseConfig }) {
|
|
|
11999
12148
|
setIsSuccess(false);
|
|
12000
12149
|
setCurrentStep("eventTypes");
|
|
12001
12150
|
setShowingPreview(true);
|
|
12151
|
+
// Reset state
|
|
12152
|
+
setSuccessPaymentIntentId(null);
|
|
12002
12153
|
// Reset lazy loading flags
|
|
12003
12154
|
setShouldRenderInstanceSelection(false);
|
|
12004
12155
|
setShouldRenderBookingForm(false);
|
|
12005
|
-
|
|
12156
|
+
// Clean up URL to remove Stripe parameters
|
|
12157
|
+
const url = new URL(window.location.href);
|
|
12158
|
+
url.searchParams.delete("payment_intent");
|
|
12159
|
+
url.searchParams.delete("payment_intent_client_secret");
|
|
12160
|
+
url.searchParams.delete("redirect_status");
|
|
12161
|
+
window.history.replaceState({}, "", url.toString());
|
|
12162
|
+
}, config: config, onError: setError, paymentIntentId: successPaymentIntentId })] }));
|
|
12006
12163
|
}
|
|
12007
12164
|
if (viewMode === "next-events" && !showingPreview && currentStep === "eventInstances") {
|
|
12008
12165
|
// Show all events for the single event type
|
|
@@ -12016,10 +12173,18 @@ function UniversalBookingWidget({ config: baseConfig }) {
|
|
|
12016
12173
|
setIsSuccess(false);
|
|
12017
12174
|
setCurrentStep("eventTypes");
|
|
12018
12175
|
setShowingPreview(true);
|
|
12176
|
+
// Reset state
|
|
12177
|
+
setSuccessPaymentIntentId(null);
|
|
12019
12178
|
// Reset lazy loading flags
|
|
12020
12179
|
setShouldRenderInstanceSelection(false);
|
|
12021
12180
|
setShouldRenderBookingForm(false);
|
|
12022
|
-
|
|
12181
|
+
// Clean up URL to remove Stripe parameters
|
|
12182
|
+
const url = new URL(window.location.href);
|
|
12183
|
+
url.searchParams.delete("payment_intent");
|
|
12184
|
+
url.searchParams.delete("payment_intent_client_secret");
|
|
12185
|
+
url.searchParams.delete("redirect_status");
|
|
12186
|
+
window.history.replaceState({}, "", url.toString());
|
|
12187
|
+
}, config: config, onError: setError, paymentIntentId: successPaymentIntentId })] }));
|
|
12023
12188
|
}
|
|
12024
12189
|
if (viewMode === "button" && (isSingleEventTypeMode || isDirectInstanceMode)) {
|
|
12025
12190
|
// Button mode - show button that opens sidebar/booking directly
|
|
@@ -12053,10 +12218,18 @@ function UniversalBookingWidget({ config: baseConfig }) {
|
|
|
12053
12218
|
setIsSuccess(false);
|
|
12054
12219
|
setCurrentStep("eventTypes");
|
|
12055
12220
|
setSidebarOpen(false);
|
|
12221
|
+
// Reset state
|
|
12222
|
+
setSuccessPaymentIntentId(null);
|
|
12056
12223
|
// Reset lazy loading flags
|
|
12057
12224
|
setShouldRenderInstanceSelection(false);
|
|
12058
12225
|
setShouldRenderBookingForm(false);
|
|
12059
|
-
|
|
12226
|
+
// Clean up URL to remove Stripe parameters
|
|
12227
|
+
const url = new URL(window.location.href);
|
|
12228
|
+
url.searchParams.delete("payment_intent");
|
|
12229
|
+
url.searchParams.delete("payment_intent_client_secret");
|
|
12230
|
+
url.searchParams.delete("redirect_status");
|
|
12231
|
+
window.history.replaceState({}, "", url.toString());
|
|
12232
|
+
}, config: config, onError: setError, paymentIntentId: successPaymentIntentId })] }) }));
|
|
12060
12233
|
}
|
|
12061
12234
|
// Cards mode (default) - show event type selection
|
|
12062
12235
|
const cardsView = (jsx(EventTypeSelection, { eventTypes: eventTypes, onEventTypeSelect: handleEventTypeSelect, isLoading: isLoading, skeletonCount: getSkeletonCount() }));
|
|
@@ -12092,10 +12265,18 @@ function UniversalBookingWidget({ config: baseConfig }) {
|
|
|
12092
12265
|
return (jsxs(StyleProvider, { config: config, children: [cardsView, shouldRenderInstanceSelection && (jsx(EventInstanceSelection, { eventInstances: eventInstances, selectedEventType: selectedEventType, onEventInstanceSelect: handleEventInstanceSelect, onBackToEventTypes: handleBackToEventTypes, isOpen: currentStep === "eventInstances", onClose: handleBackToEventTypes, isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails })), shouldRenderBookingForm && eventDetails && (jsx(BookingForm, { config: config, eventDetails: eventDetails, stripePromise: stripePromise, onSuccess: handleBookingSuccess, onError: handleBookingError, onBackToEventInstances: backHandlers.onBackToEventInstances, onBackToEventTypes: backHandlers.onBackToEventTypes, selectedEventType: selectedEventType, selectedEventInstance: selectedEventInstance, isOpen: currentStep === "booking" && !!eventDetails, onClose: backHandlers.onClose, systemConfig: systemConfig })), jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
|
|
12093
12266
|
setIsSuccess(false);
|
|
12094
12267
|
setCurrentStep("eventTypes");
|
|
12268
|
+
// Reset state
|
|
12269
|
+
setSuccessPaymentIntentId(null);
|
|
12095
12270
|
// Reset lazy loading flags
|
|
12096
12271
|
setShouldRenderInstanceSelection(false);
|
|
12097
12272
|
setShouldRenderBookingForm(false);
|
|
12098
|
-
|
|
12273
|
+
// Clean up URL to remove Stripe parameters
|
|
12274
|
+
const url = new URL(window.location.href);
|
|
12275
|
+
url.searchParams.delete("payment_intent");
|
|
12276
|
+
url.searchParams.delete("payment_intent_client_secret");
|
|
12277
|
+
url.searchParams.delete("redirect_status");
|
|
12278
|
+
window.history.replaceState({}, "", url.toString());
|
|
12279
|
+
}, config: config, onError: setError, paymentIntentId: successPaymentIntentId })] }));
|
|
12099
12280
|
}
|
|
12100
12281
|
|
|
12101
12282
|
// Export init function for vanilla JS usage
|