@propeller-commerce/propeller-v2-react-ui 0.4.6

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/pure.js ADDED
@@ -0,0 +1,938 @@
1
+ import { buildClusterJsonLd, safeJsonStringify, buildItemListJsonLd, buildProductJsonLd, getLabel, isContentHidden, formatPrice, getCountryName } from '@propeller-commerce/propeller-v2-core-ui';
2
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
3
+ import * as React from 'react';
4
+ import { OrderDiscountType, YesNo } from '@propeller-commerce/propeller-sdk-v2';
5
+
6
+ // src/components/Breadcrumbs.tsx
7
+ function Breadcrumbs(props) {
8
+ const lang = props.language || "NL";
9
+ const path = props.categoryPath || [];
10
+ const baseId = props.configuration?.baseCategoryId;
11
+ const filtered = baseId ? path.filter((cat) => cat.categoryId !== baseId) : path;
12
+ let items = filtered;
13
+ if (props.currentCategory) {
14
+ const last = filtered[filtered.length - 1];
15
+ if (!last || last.categoryId !== props.currentCategory.categoryId) {
16
+ items = [...filtered, props.currentCategory];
17
+ }
18
+ }
19
+ const displayItems = props.showCurrent === false && items.length > 0 ? items.slice(0, items.length - 1) : items;
20
+ function getCategoryName(cat) {
21
+ const match = cat.name?.find((n) => n.language === lang);
22
+ return match?.value || cat.name?.[0]?.value || "";
23
+ }
24
+ function getCategoryUrl(cat, index) {
25
+ if (props.getUrl) return props.getUrl(cat, index);
26
+ const urls = props.configuration?.urls;
27
+ if (urls && typeof urls.getCategoryUrl === "function") {
28
+ return urls.getCategoryUrl(cat, props.language);
29
+ }
30
+ const slug = cat.slug?.find((s) => s.language === lang)?.value || cat.slug?.[0]?.value || "";
31
+ return `/category/${cat.categoryId}/${slug}`;
32
+ }
33
+ function isCurrentItem(index) {
34
+ if (props.showCurrent === false) return false;
35
+ if (props.currentLabel) return false;
36
+ return index === displayItems.length - 1;
37
+ }
38
+ const showSeparatorBefore = (index) => props.showHome !== false || index > 0;
39
+ return /* @__PURE__ */ jsx("nav", { "aria-label": getLabel(props.labels, "breadcrumbAriaLabel", "Breadcrumb"), className: `propeller-breadcrumbs ${props.className || ""}`, children: /* @__PURE__ */ jsxs("ol", { className: "propeller-breadcrumbs__list flex flex-wrap items-center text-sm text-muted-foreground", children: [
40
+ props.showHome !== false ? /* @__PURE__ */ jsx("li", { className: "propeller-breadcrumbs__item flex items-center", "data-home": "true", children: /* @__PURE__ */ jsx(
41
+ "a",
42
+ {
43
+ className: "propeller-breadcrumbs__link hover:text-foreground transition-colors",
44
+ href: props.homeUrl || "/",
45
+ children: getLabel(props.labels, "home", "Home")
46
+ }
47
+ ) }) : null,
48
+ displayItems.map((cat, index) => /* @__PURE__ */ jsxs(
49
+ "li",
50
+ {
51
+ className: "propeller-breadcrumbs__item flex items-center",
52
+ "data-current": isCurrentItem(index) ? "true" : "false",
53
+ children: [
54
+ showSeparatorBefore(index) ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "propeller-breadcrumbs__separator mx-2 select-none text-muted-foreground/40", children: getLabel(props.labels, "separator", "/") }) : null,
55
+ isCurrentItem(index) ? /* @__PURE__ */ jsx(
56
+ "span",
57
+ {
58
+ "aria-current": "page",
59
+ className: "propeller-breadcrumbs__link propeller-breadcrumbs__link--current text-foreground",
60
+ children: getCategoryName(cat)
61
+ }
62
+ ) : null,
63
+ !isCurrentItem(index) ? /* @__PURE__ */ jsx(
64
+ "a",
65
+ {
66
+ className: "propeller-breadcrumbs__link hover:text-foreground transition-colors",
67
+ href: getCategoryUrl(cat, index),
68
+ children: getCategoryName(cat)
69
+ }
70
+ ) : null
71
+ ]
72
+ },
73
+ cat.categoryId || index
74
+ )),
75
+ props.currentLabel ? /* @__PURE__ */ jsxs(
76
+ "li",
77
+ {
78
+ className: "propeller-breadcrumbs__item flex items-center",
79
+ "data-current": "true",
80
+ children: [
81
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "propeller-breadcrumbs__separator mx-2 select-none text-muted-foreground/40", children: getLabel(props.labels, "separator", "/") }),
82
+ props.currentUrl ? /* @__PURE__ */ jsx(
83
+ "a",
84
+ {
85
+ "aria-current": "page",
86
+ className: "propeller-breadcrumbs__link propeller-breadcrumbs__link--current text-foreground",
87
+ href: props.currentUrl,
88
+ children: props.currentLabel
89
+ }
90
+ ) : /* @__PURE__ */ jsx(
91
+ "span",
92
+ {
93
+ "aria-current": "page",
94
+ className: "propeller-breadcrumbs__link propeller-breadcrumbs__link--current text-foreground",
95
+ children: props.currentLabel
96
+ }
97
+ )
98
+ ]
99
+ }
100
+ ) : null
101
+ ] }) });
102
+ }
103
+ var Breadcrumbs_default = Breadcrumbs;
104
+ function ClusterJsonLd(props) {
105
+ const data = buildClusterJsonLd(props.cluster, props.context);
106
+ if (!data) return null;
107
+ return /* @__PURE__ */ jsx(
108
+ "script",
109
+ {
110
+ type: "application/ld+json",
111
+ dangerouslySetInnerHTML: { __html: safeJsonStringify(data) }
112
+ }
113
+ );
114
+ }
115
+ var ClusterJsonLd_default = React.memo(ClusterJsonLd);
116
+ function ItemListJsonLd(props) {
117
+ const data = buildItemListJsonLd(props.products, props.context);
118
+ if (!data) return null;
119
+ return /* @__PURE__ */ jsx(
120
+ "script",
121
+ {
122
+ type: "application/ld+json",
123
+ dangerouslySetInnerHTML: { __html: safeJsonStringify(data) }
124
+ }
125
+ );
126
+ }
127
+ var ItemListJsonLd_default = React.memo(ItemListJsonLd);
128
+ function ProductJsonLd(props) {
129
+ const data = buildProductJsonLd(props.product, props.context);
130
+ if (!data) return null;
131
+ return /* @__PURE__ */ jsx(
132
+ "script",
133
+ {
134
+ type: "application/ld+json",
135
+ dangerouslySetInnerHTML: { __html: safeJsonStringify(data) }
136
+ }
137
+ );
138
+ }
139
+ var ProductJsonLd_default = React.memo(ProductJsonLd);
140
+ function CategoryShortDescription(props) {
141
+ const match = props.category?.shortDescription?.find(
142
+ (d) => d.language === props.language
143
+ );
144
+ const html = match?.value || "";
145
+ return /* @__PURE__ */ jsx(Fragment, { children: !!html ? /* @__PURE__ */ jsx("div", { className: `propeller-category-short-description mb-6 ${props.className || ""}`, children: /* @__PURE__ */ jsx(
146
+ "div",
147
+ {
148
+ className: "propeller-category-short-description__content prose prose-slate max-w-none text-muted-foreground",
149
+ dangerouslySetInnerHTML: { __html: html }
150
+ }
151
+ ) }) : null });
152
+ }
153
+ var CategoryShortDescription_default = CategoryShortDescription;
154
+ function GridTitle(props) {
155
+ return /* @__PURE__ */ jsx("div", { className: `propeller-grid-title mb-8 ${props.className || ""}`, children: /* @__PURE__ */ jsxs("div", { className: "propeller-grid-title__row flex items-baseline gap-3 mb-3", children: [
156
+ props.headingLevel === "h2" ? /* @__PURE__ */ jsx("h2", { className: "propeller-grid-title__heading text-3xl sm:text-4xl font-bold tracking-tight", children: props.title }) : null,
157
+ props.headingLevel !== "h2" ? /* @__PURE__ */ jsx("h1", { className: "propeller-grid-title__heading text-3xl sm:text-4xl font-bold tracking-tight", children: props.title }) : null
158
+ ] }) });
159
+ }
160
+ var GridTitle_default = GridTitle;
161
+ function ItemStock(props) {
162
+ function getTotalQuantity() {
163
+ const qty = props.inventory?.totalQuantity;
164
+ return qty !== void 0 && qty !== null ? qty : -1;
165
+ }
166
+ function isAvailable() {
167
+ return getTotalQuantity() > 0;
168
+ }
169
+ function getStockStatusLabel() {
170
+ const qty = getTotalQuantity();
171
+ if (qty < 0) return "";
172
+ if (qty === 0) return getLabel(props.labels, "outOfStock", "Out of stock");
173
+ if (qty <= 5) return getLabel(props.labels, "lowStock", "Low stock");
174
+ return getLabel(props.labels, "inStock", "In stock");
175
+ }
176
+ function getStockStatusClass() {
177
+ const qty = getTotalQuantity();
178
+ if (qty <= 0) return "text-destructive bg-destructive/10 border-destructive/20";
179
+ if (qty <= 5) return "text-warning bg-warning/10 border-warning/20";
180
+ return "text-success bg-success/10 border-success/20";
181
+ }
182
+ function getStockStatusData() {
183
+ const qty = getTotalQuantity();
184
+ if (qty <= 0) return "out";
185
+ if (qty <= 5) return "low";
186
+ return "in";
187
+ }
188
+ function getAvailabilityLabel() {
189
+ return isAvailable() ? getLabel(props.labels, "available", "Available") : getLabel(props.labels, "notAvailable", "Not available");
190
+ }
191
+ function getAvailabilityClass() {
192
+ return isAvailable() ? "text-success bg-success/10 border-success/20" : "text-destructive bg-destructive/10 border-destructive/20";
193
+ }
194
+ function getAvailabilityDotClass() {
195
+ return isAvailable() ? "bg-success" : "bg-destructive";
196
+ }
197
+ function hasInventory() {
198
+ return !!props.inventory && getTotalQuantity() >= 0;
199
+ }
200
+ return /* @__PURE__ */ jsx(Fragment, { children: hasInventory() ? /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(
201
+ "div",
202
+ {
203
+ className: `propeller-item-stock flex flex-wrap items-center gap-1.5 ${props.className || ""}`,
204
+ "data-available": isAvailable() ? "true" : "false",
205
+ "data-stock": getStockStatusData(),
206
+ children: [
207
+ props.showAvailability !== false ? /* @__PURE__ */ jsxs(
208
+ "span",
209
+ {
210
+ className: `propeller-item-stock__availability inline-flex items-center gap-1 whitespace-nowrap rounded-full border px-2 py-0.5 text-[11px] font-medium ${getAvailabilityClass()}`,
211
+ children: [
212
+ /* @__PURE__ */ jsx(
213
+ "span",
214
+ {
215
+ className: `propeller-item-stock__availability-dot h-1.5 w-1.5 flex-shrink-0 rounded-full ${getAvailabilityDotClass()}`
216
+ }
217
+ ),
218
+ getAvailabilityLabel()
219
+ ]
220
+ }
221
+ ) : null,
222
+ props.showStock !== false && !!getStockStatusLabel() ? /* @__PURE__ */ jsxs(
223
+ "span",
224
+ {
225
+ className: `propeller-item-stock__status inline-flex items-center gap-1 whitespace-nowrap rounded-full border px-2 py-0.5 text-[11px] font-medium ${getStockStatusClass()}`,
226
+ children: [
227
+ getStockStatusLabel(),
228
+ getTotalQuantity() > 0 ? /* @__PURE__ */ jsxs("span", { className: "propeller-item-stock__count opacity-70", children: [
229
+ "(",
230
+ getTotalQuantity(),
231
+ getLabel(props.labels, "pieces", "pcs"),
232
+ ")"
233
+ ] }) : null
234
+ ]
235
+ }
236
+ ) : null
237
+ ]
238
+ }
239
+ ) }) : null });
240
+ }
241
+ var ItemStock_default = React.memo(ItemStock);
242
+ function getProductName(orderItem) {
243
+ return orderItem?.product?.names?.[0]?.value || orderItem?.name || "Unknown Product";
244
+ }
245
+ function getClusterUrl(orderItem) {
246
+ const cluster = orderItem?.product?.cluster;
247
+ if (!cluster) return "";
248
+ const id = cluster.clusterId;
249
+ const slug = cluster.slugs?.[0]?.value || "";
250
+ if (!id || !slug) return "";
251
+ return `/cluster/${id}/${slug}`;
252
+ }
253
+ function getProductUrl(orderItem) {
254
+ const cu = getClusterUrl(orderItem);
255
+ if (cu) return cu;
256
+ const id = orderItem?.product?.productId;
257
+ const slug = orderItem?.product?.slugs?.[0]?.value || "";
258
+ if (id && slug) return `/product/${id}/${slug}`;
259
+ return "";
260
+ }
261
+ function OrderItemCard(props) {
262
+ const item = props.orderItem;
263
+ const isChildItem = props.isChildItem || false;
264
+ const titleLinkable = props.titleLinkable !== void 0 ? props.titleLinkable : true;
265
+ const showImage = isChildItem ? false : props.showImage !== void 0 ? props.showImage : true;
266
+ const showSku = isChildItem ? false : props.showSku !== void 0 ? props.showSku : true;
267
+ const showQuantity = props.showQuantity !== void 0 ? props.showQuantity : true;
268
+ const showPrice = props.showPrice !== void 0 ? props.showPrice : true;
269
+ const showDiscount = props.showDiscount !== void 0 ? props.showDiscount : false;
270
+ const showStockComponent = props.showStockComponent !== void 0 ? props.showStockComponent : false;
271
+ const showItemNotes = props.showItemNotes !== void 0 ? props.showItemNotes : false;
272
+ const productName = getProductName(item);
273
+ const productSku = item?.product?.sku || item?.sku || "";
274
+ const productImage = item?.product?.media?.images?.items?.[0]?.imageVariants?.[0]?.url || "";
275
+ const productUrl = getProductUrl(item);
276
+ const quantity = item?.quantity || 0;
277
+ const priceTotal = item?.priceTotal || 0;
278
+ const discount = item?.discount || 0;
279
+ const originalPrice = item?.originalPrice || 0;
280
+ const discountPercentage = originalPrice > 0 && discount > 0 ? discount / originalPrice * 100 : 0;
281
+ const notes = item?.notes || "";
282
+ const hasChildren = (props.childItems || []).length > 0;
283
+ function formatItemPrice(price) {
284
+ if (props.formatPrice) {
285
+ return props.formatPrice(price);
286
+ }
287
+ if (!price && price !== 0) return "-";
288
+ return formatPrice(price, { symbol: props.currency ?? "\u20AC" });
289
+ }
290
+ const discountDisplay = discountPercentage > 0 ? `${formatItemPrice(discount)} (${discountPercentage.toFixed(2).replace(".", ",")}%)` : formatItemPrice(discount);
291
+ return /* @__PURE__ */ jsxs("tbody", { className: "propeller-order-item-card", children: [
292
+ /* @__PURE__ */ jsxs(
293
+ "tr",
294
+ {
295
+ className: `propeller-order-item-card__row ${isChildItem ? "border-0" : "hover:bg-surface-hover transition"}`,
296
+ "data-child": isChildItem ? "true" : "false",
297
+ children: [
298
+ /* @__PURE__ */ jsx(
299
+ "td",
300
+ {
301
+ className: `propeller-order-item-card__cell propeller-order-item-card__cell--product ${isChildItem ? "px-6 py-2 pl-28" : "px-6 py-4"}`,
302
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
303
+ showImage ? productImage ? /* @__PURE__ */ jsx("div", { className: "propeller-order-item-card__media relative w-16 h-16 flex-shrink-0 rounded overflow-hidden", children: /* @__PURE__ */ jsx(
304
+ "img",
305
+ {
306
+ className: "propeller-order-item-card__image object-cover w-full h-full",
307
+ src: productImage,
308
+ alt: productName
309
+ }
310
+ ) }) : /* @__PURE__ */ jsx("div", { className: "propeller-order-item-card__image-placeholder w-16 h-16 bg-surface-hover rounded flex items-center justify-center text-foreground-subtle text-xs", children: getLabel(props.labels, "noImage", "No Img") }) : null,
311
+ /* @__PURE__ */ jsxs("div", { children: [
312
+ titleLinkable && productUrl && !isChildItem ? /* @__PURE__ */ jsx(
313
+ "a",
314
+ {
315
+ className: "propeller-order-item-card__title font-medium text-foreground hover:text-primary hover:underline",
316
+ href: productUrl,
317
+ children: productName
318
+ }
319
+ ) : /* @__PURE__ */ jsx(
320
+ "span",
321
+ {
322
+ className: `propeller-order-item-card__title ${isChildItem ? "text-sm text-muted-foreground" : "font-medium"}`,
323
+ children: productName
324
+ }
325
+ ),
326
+ showSku && productSku ? /* @__PURE__ */ jsxs("p", { className: "propeller-order-item-card__sku text-sm text-muted-foreground mt-1", children: [
327
+ "SKU: ",
328
+ productSku
329
+ ] }) : null,
330
+ showItemNotes && notes ? /* @__PURE__ */ jsx("p", { className: "propeller-order-item-card__notes text-sm text-foreground-subtle mt-1 italic", children: notes }) : null,
331
+ showStockComponent && item?.product?.inventory ? (() => {
332
+ const StockImpl = props.stockComponent ?? ItemStock_default;
333
+ return /* @__PURE__ */ jsx(
334
+ StockImpl,
335
+ {
336
+ inventory: item.product.inventory,
337
+ showStock: true,
338
+ showAvailability: true,
339
+ labels: props.labels
340
+ }
341
+ );
342
+ })() : null
343
+ ] })
344
+ ] })
345
+ }
346
+ ),
347
+ showQuantity ? /* @__PURE__ */ jsx(
348
+ "td",
349
+ {
350
+ className: isChildItem ? "propeller-order-item-card__cell propeller-order-item-card__cell--quantity px-6 py-2 text-center text-sm text-muted-foreground" : "propeller-order-item-card__cell propeller-order-item-card__cell--quantity px-6 py-4 text-center",
351
+ children: quantity
352
+ }
353
+ ) : null,
354
+ showDiscount ? /* @__PURE__ */ jsx(
355
+ "td",
356
+ {
357
+ className: isChildItem ? "propeller-order-item-card__cell propeller-order-item-card__cell--discount px-6 py-2 text-right text-sm text-muted-foreground" : "propeller-order-item-card__cell propeller-order-item-card__cell--discount px-6 py-4 text-right whitespace-nowrap text-warning",
358
+ children: discount > 0 ? /* @__PURE__ */ jsx(Fragment, { children: discountDisplay }) : null
359
+ }
360
+ ) : null,
361
+ showPrice ? /* @__PURE__ */ jsx(
362
+ "td",
363
+ {
364
+ className: isChildItem ? "propeller-order-item-card__cell propeller-order-item-card__cell--price px-6 py-2 text-right whitespace-nowrap text-sm text-muted-foreground" : "propeller-order-item-card__cell propeller-order-item-card__cell--price px-6 py-4 text-right whitespace-nowrap",
365
+ children: (() => {
366
+ const PriceImpl = props.priceComponent;
367
+ if (PriceImpl) {
368
+ return /* @__PURE__ */ jsx(
369
+ PriceImpl,
370
+ {
371
+ price: item?.product?.price,
372
+ currency: props.currency,
373
+ labels: props.labels
374
+ }
375
+ );
376
+ }
377
+ return formatItemPrice(priceTotal);
378
+ })()
379
+ }
380
+ ) : null
381
+ ]
382
+ }
383
+ ),
384
+ hasChildren ? /* @__PURE__ */ jsx(Fragment, { children: (props.childItems || []).map((child) => /* @__PURE__ */ jsxs(
385
+ "tr",
386
+ {
387
+ className: "propeller-order-item-card__child-row border-0",
388
+ "data-child": "true",
389
+ children: [
390
+ /* @__PURE__ */ jsx("td", { className: "propeller-order-item-card__cell propeller-order-item-card__cell--product px-6 py-2 pl-28", children: /* @__PURE__ */ jsx("span", { className: "propeller-order-item-card__child-title text-sm text-muted-foreground", children: child.product?.names?.[0]?.value || child.name || "Unknown" }) }),
391
+ showQuantity ? /* @__PURE__ */ jsx("td", { className: "propeller-order-item-card__cell propeller-order-item-card__cell--quantity px-6 py-2 text-center text-sm text-muted-foreground", children: child.quantity || 0 }) : null,
392
+ showDiscount ? /* @__PURE__ */ jsx("td", { className: "propeller-order-item-card__cell propeller-order-item-card__cell--discount px-6 py-2 text-right text-sm text-muted-foreground" }) : null,
393
+ showPrice ? /* @__PURE__ */ jsx("td", { className: "propeller-order-item-card__cell propeller-order-item-card__cell--price px-6 py-2 text-right whitespace-nowrap text-sm text-muted-foreground", children: formatItemPrice(child.priceTotal || 0) }) : null
394
+ ]
395
+ },
396
+ child.id || child.uuid
397
+ )) }) : null
398
+ ] });
399
+ }
400
+ var OrderItemCard_default = OrderItemCard;
401
+ function OrderSummary(props) {
402
+ const order = props.order;
403
+ const containerClass = props.orderSummaryContainerClass || "order-summary";
404
+ const showOrderNumber = props.showOrderNumber !== void 0 ? props.showOrderNumber : true;
405
+ const showOrderDate = props.showOrderDate !== void 0 ? props.showOrderDate : true;
406
+ const showOrderStatus = props.showOrderStatus !== void 0 ? props.showOrderStatus : true;
407
+ const showInvoiceAddress = props.showInvoiceAddress !== void 0 ? props.showInvoiceAddress : true;
408
+ const showDeliveryAddress = props.showDeliveryAddress !== void 0 ? props.showDeliveryAddress : true;
409
+ const showOrderTotal = props.showOrderTotal !== void 0 ? props.showOrderTotal : true;
410
+ const showDeliveryInfo = props.showDeliveryInfo !== void 0 ? props.showDeliveryInfo : true;
411
+ const showRemarks = props.showRemarks !== void 0 ? props.showRemarks : true;
412
+ const orderNumber = order?.id || "";
413
+ const orderDate = order?.createdAt || "";
414
+ const orderStatus = order?.status || "";
415
+ const orderTotal = Number(order?.total?.net || 0);
416
+ const orderReference = order?.reference || "";
417
+ const orderRemarks = order?.remarks || "";
418
+ const paymentMethod = order?.paymentData?.method || "";
419
+ const carrierName = order?.postageData?.carrier || "";
420
+ const addresses = order?.addresses || [];
421
+ const invoiceAddress = addresses.find((a) => a.type === "invoice") || null;
422
+ const deliveryAddress = addresses.find((a) => a.type === "delivery") || null;
423
+ function formatItemPrice(price) {
424
+ if (props.formatPrice) {
425
+ return props.formatPrice(price);
426
+ }
427
+ return formatPrice(price || 0, { symbol: props.currency ?? "\u20AC" });
428
+ }
429
+ function formatOrderDate(dateString) {
430
+ if (props.formatDate) {
431
+ return props.formatDate(dateString);
432
+ }
433
+ try {
434
+ return new Date(dateString).toLocaleDateString("en-US");
435
+ } catch {
436
+ return dateString;
437
+ }
438
+ }
439
+ const requestDateRaw = order?.postageData?.requestDate;
440
+ let requestDate = "";
441
+ if (requestDateRaw) {
442
+ if (props.formatDate) {
443
+ requestDate = props.formatDate(requestDateRaw);
444
+ } else {
445
+ try {
446
+ requestDate = new Date(requestDateRaw).toLocaleDateString("en-US");
447
+ } catch {
448
+ requestDate = requestDateRaw;
449
+ }
450
+ }
451
+ }
452
+ const getCountryName$1 = (code) => getCountryName(code, props.countries);
453
+ return /* @__PURE__ */ jsxs("div", { className: `propeller-order-summary ${containerClass}`, children: [
454
+ props.title ? /* @__PURE__ */ jsx("h2", { className: "propeller-order-summary__title text-xl font-bold mb-4", children: props.title }) : null,
455
+ /* @__PURE__ */ jsxs("div", { className: "propeller-order-summary__meta grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 pb-5 border-b border-border mb-5", children: [
456
+ showOrderNumber && orderNumber ? /* @__PURE__ */ jsxs("div", { className: "propeller-order-summary__meta-item", "data-meta": "order-number", children: [
457
+ /* @__PURE__ */ jsx("p", { className: "propeller-order-summary__meta-label text-sm text-muted-foreground mb-1", children: getLabel(props.labels, "orderNumber", "Order Number") }),
458
+ /* @__PURE__ */ jsx("p", { className: "propeller-order-summary__meta-value font-semibold", children: orderNumber })
459
+ ] }) : null,
460
+ showOrderDate && orderDate ? /* @__PURE__ */ jsxs("div", { className: "propeller-order-summary__meta-item", "data-meta": "order-date", children: [
461
+ /* @__PURE__ */ jsx("p", { className: "propeller-order-summary__meta-label text-sm text-muted-foreground mb-1", children: getLabel(props.labels, "orderDate", "Order Date") }),
462
+ /* @__PURE__ */ jsx("p", { className: "propeller-order-summary__meta-value font-semibold", children: formatOrderDate(orderDate) })
463
+ ] }) : null,
464
+ showOrderStatus && orderStatus ? /* @__PURE__ */ jsxs("div", { className: "propeller-order-summary__meta-item", "data-meta": "status", children: [
465
+ /* @__PURE__ */ jsx("p", { className: "propeller-order-summary__meta-label text-sm text-muted-foreground mb-1", children: getLabel(props.labels, "status", "Status") }),
466
+ /* @__PURE__ */ jsx("span", { className: "propeller-order-summary__status inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-secondary/10 text-secondary", children: orderStatus })
467
+ ] }) : null,
468
+ showOrderTotal ? /* @__PURE__ */ jsxs("div", { className: "propeller-order-summary__meta-item", "data-meta": "total", children: [
469
+ /* @__PURE__ */ jsx("p", { className: "propeller-order-summary__meta-label text-sm text-muted-foreground mb-1", children: getLabel(props.labels, "total", "Total") }),
470
+ /* @__PURE__ */ jsx("p", { className: "propeller-order-summary__total font-bold text-lg", children: formatItemPrice(orderTotal) })
471
+ ] }) : null
472
+ ] }),
473
+ /* @__PURE__ */ jsxs("div", { className: "propeller-order-summary__addresses grid grid-cols-1 md:grid-cols-2 gap-6 pb-5", children: [
474
+ showInvoiceAddress ? /* @__PURE__ */ jsxs("div", { className: "propeller-order-summary__address space-y-2", "data-address": "invoice", children: [
475
+ /* @__PURE__ */ jsx("h3", { className: "propeller-order-summary__address-title text-sm font-semibold text-muted-foreground uppercase tracking-wide", children: getLabel(props.labels, "invoiceAddress", "Invoice Address") }),
476
+ invoiceAddress && invoiceAddress.street ? /* @__PURE__ */ jsxs("div", { className: "text-sm space-y-1", children: [
477
+ invoiceAddress.company ? /* @__PURE__ */ jsx("p", { className: "font-medium", children: invoiceAddress.company }) : null,
478
+ /* @__PURE__ */ jsx("p", { children: [invoiceAddress.firstName, invoiceAddress.middleName, invoiceAddress.lastName].filter(Boolean).join(" ") }),
479
+ /* @__PURE__ */ jsx("p", { children: [invoiceAddress.street, invoiceAddress.number, invoiceAddress.numberExtension].filter(Boolean).join(" ") }),
480
+ /* @__PURE__ */ jsx("p", { children: [invoiceAddress.postalCode, invoiceAddress.city].filter(Boolean).join(" ") }),
481
+ invoiceAddress.country ? /* @__PURE__ */ jsx("p", { children: getCountryName$1(invoiceAddress.country) }) : null,
482
+ invoiceAddress.email ? /* @__PURE__ */ jsx("p", { className: "propeller-order-summary__address-email text-muted-foreground", children: invoiceAddress.email }) : null
483
+ ] }) : null
484
+ ] }) : null,
485
+ showDeliveryAddress ? /* @__PURE__ */ jsxs("div", { className: "propeller-order-summary__address space-y-2", "data-address": "delivery", children: [
486
+ /* @__PURE__ */ jsx("h3", { className: "propeller-order-summary__address-title text-sm font-semibold text-muted-foreground uppercase tracking-wide", children: getLabel(props.labels, "deliveryAddress", "Delivery Address") }),
487
+ deliveryAddress && deliveryAddress.street ? /* @__PURE__ */ jsxs("div", { className: "text-sm space-y-1", children: [
488
+ deliveryAddress.company ? /* @__PURE__ */ jsx("p", { className: "font-medium", children: deliveryAddress.company }) : null,
489
+ /* @__PURE__ */ jsx("p", { children: [deliveryAddress.firstName, deliveryAddress.middleName, deliveryAddress.lastName].filter(Boolean).join(" ") }),
490
+ /* @__PURE__ */ jsx("p", { children: [deliveryAddress.street, deliveryAddress.number, deliveryAddress.numberExtension].filter(Boolean).join(" ") }),
491
+ /* @__PURE__ */ jsx("p", { children: [deliveryAddress.postalCode, deliveryAddress.city].filter(Boolean).join(" ") }),
492
+ deliveryAddress.country ? /* @__PURE__ */ jsx("p", { children: getCountryName$1(deliveryAddress.country) }) : null,
493
+ deliveryAddress.email ? /* @__PURE__ */ jsx("p", { className: "propeller-order-summary__address-email text-muted-foreground", children: deliveryAddress.email }) : null
494
+ ] }) : null
495
+ ] }) : null
496
+ ] }),
497
+ showDeliveryInfo && (paymentMethod || carrierName || requestDate) ? /* @__PURE__ */ jsxs("div", { className: "propeller-order-summary__info-panel bg-surface-hover p-4 rounded-control border border-border space-y-2 text-sm", children: [
498
+ paymentMethod ? /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
499
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: getLabel(props.labels, "payment", "Payment:") }),
500
+ /* @__PURE__ */ jsx("span", { children: paymentMethod })
501
+ ] }) : null,
502
+ carrierName ? /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
503
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: getLabel(props.labels, "carrier", "Carrier:") }),
504
+ /* @__PURE__ */ jsx("span", { children: carrierName })
505
+ ] }) : null,
506
+ requestDate ? /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
507
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: getLabel(props.labels, "deliveryDate", "Delivery Date:") }),
508
+ /* @__PURE__ */ jsx("span", { children: requestDate })
509
+ ] }) : null
510
+ ] }) : null,
511
+ showRemarks && (orderReference || orderRemarks) ? /* @__PURE__ */ jsxs("div", { className: "propeller-order-summary__remarks-panel bg-surface-hover p-4 rounded-control border border-border space-y-2 text-sm mt-4", children: [
512
+ orderReference ? /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
513
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: getLabel(props.labels, "reference", "Reference:") }),
514
+ /* @__PURE__ */ jsx("span", { children: orderReference })
515
+ ] }) : null,
516
+ orderRemarks ? /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
517
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: getLabel(props.labels, "remarks", "Remarks:") }),
518
+ /* @__PURE__ */ jsx("span", { children: orderRemarks })
519
+ ] }) : null
520
+ ] }) : null
521
+ ] });
522
+ }
523
+ var OrderSummary_default = OrderSummary;
524
+ function OrderTotals(props) {
525
+ const showSubtotal = props.showSubtotal !== false;
526
+ const showDiscount = props.showDiscount !== false;
527
+ const showShippingCosts = props.showShippingCosts !== false;
528
+ const showVATs = props.showVATs !== false;
529
+ const showTotalExclVat = props.showTotalExclVat !== false;
530
+ const showTotalVat = props.showTotalVat !== false;
531
+ const total = props.order?.total;
532
+ const paymentData = props.order?.paymentData;
533
+ const postageData = props.order?.postageData;
534
+ function formatItemPrice(price) {
535
+ if (props.formatPrice) return props.formatPrice(price);
536
+ return formatPrice(price || 0, { symbol: props.currency ?? "\u20AC" });
537
+ }
538
+ const subtotal = total?.gross || 0;
539
+ const hasDiscount = !!total && total.discountType !== OrderDiscountType.N && total.discountValue > 0;
540
+ function discountDisplay() {
541
+ if (!total) return "";
542
+ if (total.discountType === OrderDiscountType.A) {
543
+ return "-" + formatItemPrice(total.discountValue);
544
+ }
545
+ if (total.discountType === OrderDiscountType.P) {
546
+ return "- " + total.discountValue + "%";
547
+ }
548
+ return "-" + formatItemPrice(total.discountValue);
549
+ }
550
+ const subtotalWithDiscount = (total?.gross || 0) - (total?.discountValue || 0);
551
+ const hasTransactionCosts = (paymentData?.gross ?? 0) > 0;
552
+ const transactionCosts = Number(paymentData?.gross || 0);
553
+ const hasShippingCosts = (postageData?.gross ?? 0) > 0;
554
+ const shippingCosts = Number(postageData?.gross || 0);
555
+ const totalExclVat = total?.gross || 0;
556
+ const taxPercentages = (total?.taxPercentages || []).filter((tax) => tax.percentage > 0 && tax.total > 0);
557
+ const totalInclVat = total?.net || 0;
558
+ const totalVat = taxPercentages.reduce((sum, t) => sum + Number(t.total || 0), 0);
559
+ return /* @__PURE__ */ jsxs("div", { className: "propeller-order-totals w-full md:w-80 bg-card p-6 rounded-container shadow space-y-3", children: [
560
+ showSubtotal ? /* @__PURE__ */ jsxs("div", { className: "propeller-order-totals__row flex justify-between text-muted-foreground", "data-row": "subtotal", children: [
561
+ /* @__PURE__ */ jsx("span", { className: "propeller-order-totals__label", children: getLabel(props.labels, "subtotal", "Subtotal:") }),
562
+ /* @__PURE__ */ jsx("span", { className: "propeller-order-totals__value", children: formatItemPrice(subtotal) })
563
+ ] }) : null,
564
+ showDiscount && hasDiscount ? /* @__PURE__ */ jsxs(Fragment, { children: [
565
+ /* @__PURE__ */ jsxs("div", { className: "propeller-order-totals__row flex justify-between text-secondary", "data-row": "discount", children: [
566
+ /* @__PURE__ */ jsx("span", { className: "propeller-order-totals__label", children: getLabel(props.labels, "discount", "Discount:") }),
567
+ /* @__PURE__ */ jsx("span", { className: "propeller-order-totals__value", children: discountDisplay() })
568
+ ] }),
569
+ /* @__PURE__ */ jsxs("div", { className: "propeller-order-totals__row flex justify-between text-muted-foreground border-t pt-2 border-dashed", "data-row": "subtotal-with-discount", children: [
570
+ /* @__PURE__ */ jsx("span", { className: "propeller-order-totals__label", children: getLabel(props.labels, "subtotalWithDiscount", "Subtotal with discount:") }),
571
+ /* @__PURE__ */ jsx("span", { className: "propeller-order-totals__value", children: formatItemPrice(subtotalWithDiscount) })
572
+ ] })
573
+ ] }) : null,
574
+ hasTransactionCosts ? /* @__PURE__ */ jsxs("div", { className: "propeller-order-totals__row flex justify-between text-muted-foreground", "data-row": "transaction-costs", children: [
575
+ /* @__PURE__ */ jsx("span", { className: "propeller-order-totals__label", children: getLabel(props.labels, "transactionCosts", "Transaction costs:") }),
576
+ /* @__PURE__ */ jsx("span", { className: "propeller-order-totals__value", children: formatItemPrice(transactionCosts) })
577
+ ] }) : null,
578
+ showShippingCosts && hasShippingCosts ? /* @__PURE__ */ jsxs("div", { className: "propeller-order-totals__row flex justify-between text-muted-foreground", "data-row": "shipping-costs", children: [
579
+ /* @__PURE__ */ jsx("span", { className: "propeller-order-totals__label", children: getLabel(props.labels, "shippingCosts", "Shipping costs:") }),
580
+ /* @__PURE__ */ jsx("span", { className: "propeller-order-totals__value", children: formatItemPrice(shippingCosts) })
581
+ ] }) : null,
582
+ showTotalExclVat ? /* @__PURE__ */ jsxs("div", { className: "propeller-order-totals__row flex justify-between text-muted-foreground pt-2 border-t", "data-row": "total-excl-vat", children: [
583
+ /* @__PURE__ */ jsx("span", { className: "propeller-order-totals__label", children: getLabel(props.labels, "totalExclVat", "Total excl. VAT:") }),
584
+ /* @__PURE__ */ jsx("span", { className: "propeller-order-totals__value", children: formatItemPrice(totalExclVat) })
585
+ ] }) : null,
586
+ showVATs && taxPercentages.length > 0 ? /* @__PURE__ */ jsx(Fragment, { children: taxPercentages.map((tax, index) => /* @__PURE__ */ jsxs("div", { className: "propeller-order-totals__row flex justify-between text-muted-foreground text-sm", "data-row": "vat-line", children: [
587
+ /* @__PURE__ */ jsxs("span", { className: "propeller-order-totals__label", children: [
588
+ tax.percentage,
589
+ "% ",
590
+ getLabel(props.labels, "vat", "VAT"),
591
+ ":"
592
+ ] }),
593
+ /* @__PURE__ */ jsx("span", { className: "propeller-order-totals__value", children: formatItemPrice(Number(tax.total)) })
594
+ ] }, index)) }) : null,
595
+ showTotalVat ? /* @__PURE__ */ jsxs("div", { className: "propeller-order-totals__row flex justify-between text-muted-foreground text-sm", "data-row": "total-vat", children: [
596
+ /* @__PURE__ */ jsx("span", { className: "propeller-order-totals__label", children: getLabel(props.labels, "totalVat", "Total VAT:") }),
597
+ /* @__PURE__ */ jsx("span", { className: "propeller-order-totals__value", children: formatItemPrice(totalVat) })
598
+ ] }) : null,
599
+ /* @__PURE__ */ jsxs("div", { className: "propeller-order-totals__row propeller-order-totals__row--total flex justify-between text-xl font-bold pt-4 border-t text-foreground mt-2", "data-row": "total", children: [
600
+ /* @__PURE__ */ jsx("span", { className: "propeller-order-totals__label", children: getLabel(props.labels, "total", "Total:") }),
601
+ /* @__PURE__ */ jsx("span", { className: "propeller-order-totals__value", children: formatItemPrice(totalInclVat) })
602
+ ] })
603
+ ] });
604
+ }
605
+ var OrderTotals_default = OrderTotals;
606
+ function ProductBulkPrices(props) {
607
+ const includeTax = !!props.includeTax;
608
+ const isHidden = isContentHidden(props.portalMode, props.user);
609
+ function getTierQuantity(tier) {
610
+ const discount = tier.discount;
611
+ return discount?.quantityFrom ?? tier.quantity ?? null;
612
+ }
613
+ function getBulkPrices() {
614
+ const rawAll = props.bulkPrices || [];
615
+ const all = rawAll.filter((tier) => {
616
+ const t = tier;
617
+ const priceType = t.type ?? t.discount?.type;
618
+ const discountType = t.discountType ?? t.discount?.discountType;
619
+ return !(priceType === "PRICESHEET" && discountType === "LIST_PRICE_MIN");
620
+ });
621
+ if (all.length === 0) return [];
622
+ const now = /* @__PURE__ */ new Date();
623
+ const groups = /* @__PURE__ */ new Map();
624
+ for (const tier of all) {
625
+ const qty = getTierQuantity(tier);
626
+ if (qty === null) continue;
627
+ const list = groups.get(qty) || [];
628
+ list.push(tier);
629
+ groups.set(qty, list);
630
+ }
631
+ const filtered = [];
632
+ for (const [, prices] of groups) {
633
+ const validDated = [];
634
+ const nullDated = [];
635
+ for (const tier of prices) {
636
+ const discount = tier.discount;
637
+ if (!discount) {
638
+ filtered.push(tier);
639
+ continue;
640
+ }
641
+ const validFrom = discount.validFrom ?? null;
642
+ const validTo = discount.validTo ?? null;
643
+ if (validFrom === null && validTo === null) {
644
+ nullDated.push(tier);
645
+ continue;
646
+ }
647
+ let isValid = true;
648
+ if (validFrom !== null && now < new Date(validFrom)) isValid = false;
649
+ if (isValid && validTo !== null && now > new Date(validTo)) isValid = false;
650
+ if (isValid) validDated.push(tier);
651
+ }
652
+ if (validDated.length > 0) filtered.push(validDated[0]);
653
+ else if (nullDated.length > 0) filtered.push(nullDated[0]);
654
+ }
655
+ filtered.sort((a, b) => (getTierQuantity(a) ?? 0) - (getTierQuantity(b) ?? 0));
656
+ if (filtered.length === 1 && getTierQuantity(filtered[0]) === 1) return [];
657
+ return filtered;
658
+ }
659
+ const bulkPrices = getBulkPrices();
660
+ const hasItems = bulkPrices.length > 0;
661
+ function getPrice(tier) {
662
+ const value = includeTax ? tier.net : tier.gross;
663
+ if (value === null || value === void 0) return "";
664
+ return formatPrice(value, { symbol: props.currency ?? "\u20AC" });
665
+ }
666
+ function getQuantityLabel(tier, index) {
667
+ const discount = tier.discount;
668
+ const qty = discount?.quantityFrom || tier.quantity || 1;
669
+ const nextTier = bulkPrices[index + 1];
670
+ const nextDiscount = nextTier?.discount;
671
+ const nextQty = nextDiscount?.quantityFrom || nextTier?.quantity;
672
+ if (nextQty) return `${qty}\u2013${nextQty - 1}`;
673
+ return `${qty}+`;
674
+ }
675
+ return /* @__PURE__ */ jsx(Fragment, { children: !isHidden && hasItems ? /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(
676
+ "div",
677
+ {
678
+ className: `propeller-product-bulk-prices ${props.className || ""}`,
679
+ "data-include-tax": includeTax ? "true" : "false",
680
+ children: [
681
+ getLabel(props.labels, "title", "Volume pricing") ? /* @__PURE__ */ jsx("h3", { className: "propeller-product-bulk-prices__title text-base font-semibold text-foreground mb-3", children: getLabel(props.labels, "title", "Volume pricing") }) : null,
682
+ /* @__PURE__ */ jsx("div", { className: "propeller-product-bulk-prices__table-wrapper overflow-hidden rounded-container border border-border", children: /* @__PURE__ */ jsxs("table", { className: "propeller-product-bulk-prices__table w-full text-sm", children: [
683
+ /* @__PURE__ */ jsx("thead", { className: "propeller-product-bulk-prices__thead bg-muted/50", children: /* @__PURE__ */ jsxs("tr", { children: [
684
+ /* @__PURE__ */ jsx("th", { className: "propeller-product-bulk-prices__th propeller-product-bulk-prices__th--quantity px-4 py-2 text-left font-medium text-muted-foreground", children: getLabel(props.labels, "quantityFrom", "Qty from") }),
685
+ /* @__PURE__ */ jsxs("th", { className: "propeller-product-bulk-prices__th propeller-product-bulk-prices__th--price px-4 py-2 text-right font-medium text-muted-foreground", children: [
686
+ getLabel(props.labels, "price", "Price"),
687
+ /* @__PURE__ */ jsxs("span", { className: "propeller-product-bulk-prices__tax-label font-normal text-xs", children: [
688
+ "(",
689
+ includeTax ? getLabel(props.labels, "inclTax", "incl. VAT") : getLabel(props.labels, "exclTax", "excl. VAT"),
690
+ ")"
691
+ ] })
692
+ ] })
693
+ ] }) }),
694
+ /* @__PURE__ */ jsx("tbody", { className: "propeller-product-bulk-prices__tbody divide-y divide-border", children: bulkPrices.map((tier, index) => /* @__PURE__ */ jsxs("tr", { className: "propeller-product-bulk-prices__row bg-card hover:bg-muted/20 transition-colors", children: [
695
+ /* @__PURE__ */ jsx("td", { className: "propeller-product-bulk-prices__cell propeller-product-bulk-prices__cell--quantity px-4 py-2 text-foreground font-medium", children: getQuantityLabel(tier, index) }),
696
+ /* @__PURE__ */ jsx("td", { className: "propeller-product-bulk-prices__cell propeller-product-bulk-prices__cell--price px-4 py-2 text-right text-foreground font-semibold", children: getPrice(tier) })
697
+ ] }, index)) })
698
+ ] }) })
699
+ ]
700
+ }
701
+ ) }) : null });
702
+ }
703
+ var ProductBulkPrices_default = ProductBulkPrices;
704
+ function ProductDownloads(props) {
705
+ const items = props.downloads?.items || [];
706
+ const hasItems = items.length > 0;
707
+ const lang = props.language || "NL";
708
+ function getDocumentUrl(doc) {
709
+ const docs = doc.documents || [];
710
+ const match = docs.find((d) => d.language === lang);
711
+ return match?.originalUrl || docs?.[0]?.originalUrl || "";
712
+ }
713
+ function getDocumentName(doc) {
714
+ const alts = doc.alt || [];
715
+ const match = alts.find((a) => a.language === lang);
716
+ return match?.value || alts?.[0]?.value || "Download";
717
+ }
718
+ return /* @__PURE__ */ jsxs("div", { className: `propeller-product-downloads ${props.className || ""}`, children: [
719
+ hasItems ? /* @__PURE__ */ jsx("h3", { className: "propeller-product-downloads__title text-base font-semibold text-foreground mb-3", children: getLabel(props.labels, "title", "Downloads") }) : null,
720
+ hasItems ? /* @__PURE__ */ jsx("ul", { className: "propeller-product-downloads__list space-y-2", children: items.map((doc, index) => /* @__PURE__ */ jsx("li", { className: "propeller-product-downloads__item", children: !!getDocumentUrl(doc) ? /* @__PURE__ */ jsxs(
721
+ "a",
722
+ {
723
+ target: "_blank",
724
+ className: "propeller-product-downloads__link flex items-center gap-3 rounded-container border border-border bg-card px-4 py-3 text-sm text-foreground hover:bg-muted/30 hover:border-primary/40 transition-colors group",
725
+ href: getDocumentUrl(doc),
726
+ download: true,
727
+ children: [
728
+ /* @__PURE__ */ jsx(
729
+ "svg",
730
+ {
731
+ fill: "none",
732
+ stroke: "currentColor",
733
+ viewBox: "0 0 24 24",
734
+ className: "h-5 w-5 flex-shrink-0 text-muted-foreground group-hover:text-primary transition-colors",
735
+ children: /* @__PURE__ */ jsx(
736
+ "path",
737
+ {
738
+ strokeLinecap: "round",
739
+ strokeLinejoin: "round",
740
+ d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z",
741
+ strokeWidth: 1.5
742
+ }
743
+ )
744
+ }
745
+ ),
746
+ /* @__PURE__ */ jsx("span", { className: "flex-1 min-w-0 truncate", children: getDocumentName(doc) }),
747
+ /* @__PURE__ */ jsx(
748
+ "svg",
749
+ {
750
+ fill: "none",
751
+ stroke: "currentColor",
752
+ viewBox: "0 0 24 24",
753
+ className: "h-4 w-4 flex-shrink-0 text-muted-foreground group-hover:text-primary transition-colors",
754
+ children: /* @__PURE__ */ jsx(
755
+ "path",
756
+ {
757
+ strokeLinecap: "round",
758
+ strokeLinejoin: "round",
759
+ d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4",
760
+ strokeWidth: 2
761
+ }
762
+ )
763
+ }
764
+ )
765
+ ]
766
+ }
767
+ ) : null }, index)) }) : null,
768
+ !hasItems ? /* @__PURE__ */ jsx("p", { className: "propeller-product-downloads__empty text-sm text-muted-foreground", children: getLabel(props.labels, "empty", "No downloads") }) : null
769
+ ] });
770
+ }
771
+ var ProductDownloads_default = ProductDownloads;
772
+ function ProductPriceDisplay(props) {
773
+ function isHidden() {
774
+ return isContentHidden(props.portalMode, props.user);
775
+ }
776
+ function formatPrice5(value) {
777
+ if (value === null || value === void 0) return "";
778
+ return formatPrice(value, { symbol: props.currency ?? "\u20AC" });
779
+ }
780
+ function getOptionsTotal(useNet) {
781
+ const options = props.options || [];
782
+ const selected = props.selectedOptionProducts || [];
783
+ let total = 0;
784
+ options.forEach((option) => {
785
+ if (option.hidden === YesNo.Y) return;
786
+ const selectedProduct = selected.find(
787
+ (p) => (option.products || []).some((op) => op.productId === p.productId)
788
+ );
789
+ if (selectedProduct) {
790
+ total += useNet ? selectedProduct.price?.net || 0 : selectedProduct.price?.gross || 0;
791
+ } else if (option.isRequired === YesNo.Y && option.defaultProduct) {
792
+ const defaultId = option.defaultProduct.productId;
793
+ const fullDefault = (option.products || []).find((p) => p.productId === defaultId) || option.defaultProduct;
794
+ total += useNet ? fullDefault.price?.net || 0 : fullDefault.price?.gross || 0;
795
+ }
796
+ });
797
+ return total;
798
+ }
799
+ function getLeadingPrice() {
800
+ const price = props.price;
801
+ if (!price) return "";
802
+ const useNet = !!props.includeTax;
803
+ const base = useNet ? price.net : price.gross;
804
+ if (base === null || base === void 0) return "";
805
+ return formatPrice5(base + getOptionsTotal(useNet));
806
+ }
807
+ function getSecondaryPrice() {
808
+ const price = props.price;
809
+ if (!price) return "";
810
+ const useNet = !props.includeTax;
811
+ const base = useNet ? price.net : price.gross;
812
+ if (base === null || base === void 0) return "";
813
+ return formatPrice5(base + getOptionsTotal(useNet));
814
+ }
815
+ function getTaxLabel() {
816
+ return props.includeTax ? getLabel(props.labels, "inclTax", "incl. VAT") : getLabel(props.labels, "exclTax", "excl. VAT");
817
+ }
818
+ function getSecondaryTaxLabel() {
819
+ return props.includeTax ? getLabel(props.labels, "exclTax", "excl. VAT") : getLabel(props.labels, "inclTax", "incl. VAT");
820
+ }
821
+ return /* @__PURE__ */ jsxs("div", { className: `propeller-product-price ${props.className || ""}`, "data-hidden": isHidden() ? "true" : "false", children: [
822
+ isHidden() ? /* @__PURE__ */ jsx("p", { className: "propeller-product-price__login-prompt text-sm text-muted-foreground italic", children: getLabel(props.labels, "loginToSeePrices", "Log in to see prices") }) : null,
823
+ !isHidden() && !!getLeadingPrice() ? /* @__PURE__ */ jsxs("div", { className: "propeller-product-price__content flex flex-col gap-0.5", children: [
824
+ /* @__PURE__ */ jsxs("div", { className: "propeller-product-price__primary flex items-baseline gap-2", children: [
825
+ /* @__PURE__ */ jsx(
826
+ "span",
827
+ {
828
+ className: `propeller-product-price__amount ${props.priceSize || "text-3xl"} font-bold text-foreground`,
829
+ children: getLeadingPrice()
830
+ }
831
+ ),
832
+ /* @__PURE__ */ jsx("span", { className: "propeller-product-price__tax-label text-sm text-muted-foreground", children: getTaxLabel() })
833
+ ] }),
834
+ !!getSecondaryPrice() ? /* @__PURE__ */ jsxs("div", { className: "propeller-product-price__secondary text-sm text-muted-foreground flex items-baseline gap-1", children: [
835
+ /* @__PURE__ */ jsx("span", { className: "propeller-product-price-secondary__amount", children: getSecondaryPrice() }),
836
+ /* @__PURE__ */ jsx("span", { className: "propeller-product-price-secondary__tax-label", children: getSecondaryTaxLabel() })
837
+ ] }) : null
838
+ ] }) : null
839
+ ] });
840
+ }
841
+ var ProductPrice_default = ProductPriceDisplay;
842
+ function ProductShortDescription(props) {
843
+ function getShortDescription() {
844
+ const product = props.product;
845
+ if (!product?.shortDescriptions) return "";
846
+ const lang = props.language || "NL";
847
+ const match = product.shortDescriptions.find((d) => d.language === lang);
848
+ return match?.value || product.shortDescriptions?.[0]?.value || "";
849
+ }
850
+ const html = getShortDescription();
851
+ return /* @__PURE__ */ jsx(Fragment, { children: !!html ? /* @__PURE__ */ jsx(
852
+ "div",
853
+ {
854
+ dangerouslySetInnerHTML: { __html: html },
855
+ className: `propeller-product-short-description prose prose-slate max-w-none text-muted-foreground ${props.className || ""}`
856
+ }
857
+ ) : null });
858
+ }
859
+ var ProductShortDescription_default = ProductShortDescription;
860
+ function ProductVideos(props) {
861
+ const items = props.videos?.items || [];
862
+ const hasItems = items.length > 0;
863
+ const lang = props.language || "NL";
864
+ function getVideoUri(video) {
865
+ const vids = video.videos || [];
866
+ const match = vids.find((v) => v.language === lang);
867
+ return match?.uri || vids?.[0]?.uri || "";
868
+ }
869
+ function getVideoTitle(video) {
870
+ const alts = video.alt || [];
871
+ const match = alts.find((a) => a.language === lang);
872
+ return match?.value || alts?.[0]?.value || "Video";
873
+ }
874
+ function isEmbeddable(uri) {
875
+ return uri.includes("youtube.com") || uri.includes("youtu.be") || uri.includes("vimeo.com");
876
+ }
877
+ function getEmbedUrl(uri) {
878
+ if (uri.includes("youtube.com/embed/") || uri.includes("player.vimeo.com/video/")) {
879
+ return uri;
880
+ }
881
+ if (uri.includes("youtube.com/watch")) {
882
+ const url = new URL(uri);
883
+ const videoId = url.searchParams.get("v") || "";
884
+ return `https://www.youtube.com/embed/${videoId}`;
885
+ }
886
+ if (uri.includes("youtu.be/")) {
887
+ const videoId = uri.split("youtu.be/")[1]?.split("?")[0] || "";
888
+ return `https://www.youtube.com/embed/${videoId}`;
889
+ }
890
+ if (uri.includes("vimeo.com/")) {
891
+ const parts = uri.split("vimeo.com/")[1]?.split("?")[0]?.split("/") || [];
892
+ const videoId = parts[0] || "";
893
+ const hash = parts[1] || "";
894
+ return hash ? `https://player.vimeo.com/video/${videoId}?h=${hash}` : `https://player.vimeo.com/video/${videoId}`;
895
+ }
896
+ return uri;
897
+ }
898
+ return /* @__PURE__ */ jsxs("div", { className: `propeller-product-videos ${props.className || ""}`, children: [
899
+ hasItems ? /* @__PURE__ */ jsx("h3", { className: "propeller-product-videos__title text-base font-semibold text-foreground mb-3", children: getLabel(props.labels, "title", "Videos") }) : null,
900
+ hasItems ? /* @__PURE__ */ jsx("div", { className: "propeller-product-videos__list space-y-4", children: items.map((video, index) => /* @__PURE__ */ jsx(
901
+ "div",
902
+ {
903
+ className: "propeller-product-videos__item rounded-container overflow-hidden border border-border bg-foreground",
904
+ "data-embedded": !!getVideoUri(video) && isEmbeddable(getVideoUri(video)) ? "true" : "false",
905
+ children: !!getVideoUri(video) ? /* @__PURE__ */ jsxs(Fragment, { children: [
906
+ isEmbeddable(getVideoUri(video)) ? /* @__PURE__ */ jsx(
907
+ "div",
908
+ {
909
+ className: "propeller-product-videos__embed relative w-full",
910
+ style: {
911
+ paddingBottom: "56.25%"
912
+ },
913
+ children: /* @__PURE__ */ jsx(
914
+ "iframe",
915
+ {
916
+ loading: "lazy",
917
+ allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
918
+ className: "propeller-product-videos__iframe absolute inset-0 w-full h-full",
919
+ src: getEmbedUrl(getVideoUri(video)),
920
+ title: getVideoTitle(video),
921
+ allowFullScreen: true
922
+ }
923
+ )
924
+ }
925
+ ) : null,
926
+ !isEmbeddable(getVideoUri(video)) ? /* @__PURE__ */ jsx("video", { preload: "metadata", className: "propeller-product-videos__video w-full", controls: true, children: /* @__PURE__ */ jsx("source", { src: getVideoUri(video) }) }) : null
927
+ ] }) : null
928
+ },
929
+ index
930
+ )) }) : null,
931
+ !hasItems ? /* @__PURE__ */ jsx("p", { className: "propeller-product-videos__empty text-sm text-muted-foreground", children: getLabel(props.labels, "empty", "No videos") }) : null
932
+ ] });
933
+ }
934
+ var ProductVideos_default = ProductVideos;
935
+
936
+ export { Breadcrumbs_default as Breadcrumbs, CategoryShortDescription_default as CategoryShortDescription, ClusterJsonLd_default as ClusterJsonLd, GridTitle_default as GridTitle, ItemListJsonLd_default as ItemListJsonLd, ItemStock_default as ItemStock, OrderItemCard_default as OrderItemCard, OrderSummary_default as OrderSummary, OrderTotals_default as OrderTotals, ProductBulkPrices_default as ProductBulkPrices, ProductDownloads_default as ProductDownloads, ProductJsonLd_default as ProductJsonLd, ProductPrice_default as ProductPrice, ProductShortDescription_default as ProductShortDescription, ProductVideos_default as ProductVideos };
937
+ //# sourceMappingURL=pure.js.map
938
+ //# sourceMappingURL=pure.js.map