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