@cimplify/sdk 0.24.1 → 0.25.0

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.
Files changed (42) hide show
  1. package/dist/advanced.d.mts +2 -2
  2. package/dist/advanced.d.ts +2 -2
  3. package/dist/{chunk-H34GSEGR.mjs → chunk-JMNMSVDQ.mjs} +24 -1
  4. package/dist/{chunk-IYQGGFVQ.js → chunk-WMQXSDRC.js} +26 -0
  5. package/dist/{index-DCoxHrmr.d.mts → index-2JxW7TuQ.d.mts} +2 -2
  6. package/dist/{index-DIHoZUz_.d.mts → index-7mX_cUpQ.d.mts} +1 -1
  7. package/dist/{index-DT0Mzy8v.d.ts → index-DBM89ktY.d.ts} +2 -2
  8. package/dist/{index-CJZMsbDi.d.ts → index-DEx3GwlW.d.ts} +1 -1
  9. package/dist/index.d.mts +5 -5
  10. package/dist/index.d.ts +5 -5
  11. package/dist/index.js +18 -6
  12. package/dist/index.mjs +1 -1
  13. package/dist/{payment-DqiwuLma.d.mts → payment-5a21yzi7.d.mts} +22 -1
  14. package/dist/{payment-DqiwuLma.d.ts → payment-5a21yzi7.d.ts} +22 -1
  15. package/dist/{price-BZlddg1A.d.ts → price-BS0Z5Oi9.d.ts} +1 -1
  16. package/dist/{price-DVQrpE7j.d.mts → price-CGPMlQUk.d.mts} +1 -1
  17. package/dist/react.d.mts +104 -11
  18. package/dist/react.d.ts +104 -11
  19. package/dist/react.js +895 -99
  20. package/dist/react.mjs +876 -97
  21. package/dist/styles.css +1 -1
  22. package/dist/utils.d.mts +3 -3
  23. package/dist/utils.d.ts +3 -3
  24. package/package.json +1 -1
  25. package/registry/accommodation-card.json +17 -0
  26. package/registry/compact-service-card.json +16 -0
  27. package/registry/digital-product-card.json +16 -0
  28. package/registry/food-product-card.json +16 -0
  29. package/registry/food-product-layout.json +1 -1
  30. package/registry/index.json +113 -0
  31. package/registry/lease-service-card.json +17 -0
  32. package/registry/price-range.json +1 -1
  33. package/registry/price.json +1 -1
  34. package/registry/product-card.json +1 -1
  35. package/registry/product-customizer.json +1 -1
  36. package/registry/product-page.json +1 -1
  37. package/registry/rental-service-card.json +16 -0
  38. package/registry/retail-product-card.json +16 -0
  39. package/registry/schedule-service-card.json +16 -0
  40. package/registry/standard-service-card.json +16 -0
  41. package/registry/subscription-card.json +16 -0
  42. package/registry/wholesale-product-card.json +17 -0
package/dist/react.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var chunkIYQGGFVQ_js = require('./chunk-IYQGGFVQ.js');
4
+ var chunkWMQXSDRC_js = require('./chunk-WMQXSDRC.js');
5
5
  var chunkI4F4Y3D4_js = require('./chunk-I4F4Y3D4.js');
6
6
  var chunkPEDLCL72_js = require('./chunk-PEDLCL72.js');
7
7
  var React3 = require('react');
@@ -1036,7 +1036,7 @@ function useCart(options = {}) {
1036
1036
  () => snapshot.items.reduce((sum, item) => sum + item.quantity, 0),
1037
1037
  [snapshot.items]
1038
1038
  );
1039
- return {
1039
+ return React3.useMemo(() => ({
1040
1040
  items: snapshot.items,
1041
1041
  itemCount,
1042
1042
  subtotal: snapshot.subtotal,
@@ -1051,7 +1051,7 @@ function useCart(options = {}) {
1051
1051
  clearCart,
1052
1052
  sync,
1053
1053
  reorder
1054
- };
1054
+ }), [snapshot.items, itemCount, snapshot.subtotal, snapshot.tax, snapshot.total, snapshot.currency, snapshot.isLoading, addItem, removeItem, updateQuantity, clearCart, sync, reorder]);
1055
1055
  }
1056
1056
  var LOCATION_STORAGE_KEY = "cimplify_location_id";
1057
1057
  var DISPLAY_CURRENCY_STORAGE_KEY = "cimplify_display_currency";
@@ -1061,7 +1061,7 @@ var DEFAULT_COUNTRY = "US";
1061
1061
  function createDefaultClient() {
1062
1062
  const processRef = globalThis.process;
1063
1063
  const envPublicKey = processRef?.env?.NEXT_PUBLIC_CIMPLIFY_PUBLIC_KEY || "";
1064
- return chunkIYQGGFVQ_js.createCimplifyClient({ publicKey: envPublicKey });
1064
+ return chunkWMQXSDRC_js.createCimplifyClient({ publicKey: envPublicKey });
1065
1065
  }
1066
1066
  function getStoredLocationId() {
1067
1067
  if (typeof window === "undefined" || !window.localStorage) {
@@ -1702,11 +1702,14 @@ function CimplifyCheckout({
1702
1702
  errorMessage && /* @__PURE__ */ jsxRuntime.jsx("p", { "data-cimplify-error": "", style: { marginTop: SPACE.sm, fontSize: 13, color: colors.error }, children: errorMessage })
1703
1703
  ] });
1704
1704
  }
1705
- function Price({ amount, className, prefix }) {
1706
- const { displayCurrency, convertPrice } = useCimplify();
1705
+ function Price({ amount, currency, className, prefix }) {
1706
+ const context = useOptionalCimplify();
1707
+ const resolvedCurrency = currency ?? context?.displayCurrency ?? "USD";
1708
+ const convertedAmount = !currency && context?.convertPrice ? context.convertPrice(amount) : amount;
1709
+ const resolvedAmount = typeof convertedAmount === "string" ? parseFloat(convertedAmount) || 0 : convertedAmount;
1707
1710
  return /* @__PURE__ */ jsxRuntime.jsxs("span", { className, children: [
1708
1711
  prefix,
1709
- chunkPEDLCL72_js.formatPrice(convertPrice(amount), displayCurrency)
1712
+ chunkPEDLCL72_js.formatPrice(resolvedAmount, resolvedCurrency)
1710
1713
  ] });
1711
1714
  }
1712
1715
  function createCachedQuery(config) {
@@ -3562,7 +3565,7 @@ function VariantSelector({
3562
3565
  {
3563
3566
  "data-cimplify-variant-name": true,
3564
3567
  className: cn("flex-1 min-w-0 text-sm", classNames?.name),
3565
- children: chunkIYQGGFVQ_js.getVariantDisplayName(variant, productName)
3568
+ children: chunkWMQXSDRC_js.getVariantDisplayName(variant, productName)
3566
3569
  }
3567
3570
  ),
3568
3571
  /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-variant-pricing": true, className: cn("text-sm text-muted-foreground", classNames?.pricing), children: [
@@ -4806,7 +4809,9 @@ function ProductCustomizer({
4806
4809
  },
4807
4810
  []
4808
4811
  );
4809
- const handleAddToCart = async () => {
4812
+ const addedTimerRef = React3.useRef(void 0);
4813
+ React3.useEffect(() => () => clearTimeout(addedTimerRef.current), []);
4814
+ const handleAddToCart = React3.useCallback(async () => {
4810
4815
  if (isSubmitting) return;
4811
4816
  setIsSubmitting(true);
4812
4817
  const options = {
@@ -4832,15 +4837,16 @@ function ProductCustomizer({
4832
4837
  await cart.addItem(product, quantity, options);
4833
4838
  }
4834
4839
  setIsAdded(true);
4835
- setTimeout(() => {
4840
+ clearTimeout(addedTimerRef.current);
4841
+ addedTimerRef.current = setTimeout(() => {
4836
4842
  setIsAdded(false);
4837
- setQuantity(1);
4843
+ setQuantity(product.min_order_quantity ?? 1);
4838
4844
  }, 2e3);
4839
4845
  } catch {
4840
4846
  } finally {
4841
4847
  setIsSubmitting(false);
4842
4848
  }
4843
- };
4849
+ }, [product, quantity, selectedVariantId, selectedVariant, quoteId, normalizedAddOnOptionIds, selectedAddOnOptions, isComposite, compositeSelections, isBundle, bundleSelections, selectedBillingPlan, specialInstructions, isSubmitting, onAddToCart, cart]);
4844
4850
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-customizer": true, className: cn("space-y-6", className, classNames?.root), children: [
4845
4851
  isComposite && product.groups && product.composite_id && /* @__PURE__ */ jsxRuntime.jsx(
4846
4852
  CompositeSelector,
@@ -5095,7 +5101,7 @@ function CartLineItemRow({
5095
5101
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-item": true, className: classNames?.item, children: [
5096
5102
  /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-item-info": true, children: [
5097
5103
  /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-name": true, className: classNames?.itemName, children: item.product.name }),
5098
- item.variant && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-variant": true, children: chunkIYQGGFVQ_js.getVariantDisplayName(item.variant, item.product.name) }),
5104
+ item.variant && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-variant": true, children: chunkWMQXSDRC_js.getVariantDisplayName(item.variant, item.product.name) }),
5099
5105
  item.addOnOptions && item.addOnOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-cart-item-addons": true, children: [
5100
5106
  "+ ",
5101
5107
  item.addOnOptions.map((opt) => opt.name).join(", ")
@@ -5492,19 +5498,832 @@ function ProductSheet({
5492
5498
  }
5493
5499
  );
5494
5500
  }
5501
+ function CardImage({
5502
+ src,
5503
+ alt,
5504
+ aspectRatio = "square",
5505
+ renderImage,
5506
+ className,
5507
+ children
5508
+ }) {
5509
+ const aspectClass = {
5510
+ square: "aspect-square",
5511
+ "3/4": "aspect-[3/4]",
5512
+ "4/3": "aspect-[4/3]",
5513
+ "16/9": "aspect-[16/9]"
5514
+ }[aspectRatio];
5515
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-card-image": true, className: cn("relative overflow-hidden bg-muted", aspectClass, className), children: [
5516
+ renderImage ? renderImage({ src, alt, className: "w-full h-full object-cover transition-transform duration-700 ease-out group-hover:scale-[1.04]" }) : /* @__PURE__ */ jsxRuntime.jsx(
5517
+ "img",
5518
+ {
5519
+ src,
5520
+ alt,
5521
+ className: "w-full h-full object-cover transition-transform duration-700 ease-out group-hover:scale-[1.04]"
5522
+ }
5523
+ ),
5524
+ children
5525
+ ] });
5526
+ }
5527
+ function QuickAddButton({
5528
+ onClick,
5529
+ className
5530
+ }) {
5531
+ return /* @__PURE__ */ jsxRuntime.jsx(
5532
+ "button",
5533
+ {
5534
+ "data-cimplify-card-quick-add": true,
5535
+ onClick: (e) => {
5536
+ e.stopPropagation();
5537
+ onClick?.();
5538
+ },
5539
+ className: cn(
5540
+ "w-9 h-9 rounded-full bg-background text-foreground flex items-center justify-center",
5541
+ "shadow-[0_1px_4px_rgba(0,0,0,0.10),0_4px_12px_rgba(0,0,0,0.08)]",
5542
+ "transition-all duration-200 ease-out",
5543
+ "opacity-0 group-hover:opacity-100 translate-y-1 group-hover:translate-y-0",
5544
+ "hover:!bg-foreground hover:!text-background hover:!scale-110",
5545
+ className
5546
+ ),
5547
+ children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: [
5548
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "8", y1: "3", x2: "8", y2: "13" }),
5549
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "3", y1: "8", x2: "13", y2: "8" })
5550
+ ] })
5551
+ }
5552
+ );
5553
+ }
5554
+ function WishlistButton({
5555
+ filled = false,
5556
+ onClick,
5557
+ className
5558
+ }) {
5559
+ return /* @__PURE__ */ jsxRuntime.jsx(
5560
+ "button",
5561
+ {
5562
+ "data-cimplify-card-wishlist": true,
5563
+ onClick: (e) => {
5564
+ e.stopPropagation();
5565
+ onClick?.();
5566
+ },
5567
+ className: cn(
5568
+ "w-8 h-8 rounded-full bg-background/90 backdrop-blur flex items-center justify-center",
5569
+ "transition-all duration-200 ease-out hover:scale-110 hover:bg-background",
5570
+ filled ? "text-destructive" : "text-muted-foreground hover:text-destructive",
5571
+ className
5572
+ ),
5573
+ children: /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-4 h-4", fill: filled ? "currentColor" : "none", stroke: "currentColor", strokeWidth: "1.5", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12z" }) })
5574
+ }
5575
+ );
5576
+ }
5577
+ function SoldOutOverlay() {
5578
+ return /* @__PURE__ */ jsxRuntime.jsx(
5579
+ "div",
5580
+ {
5581
+ "data-cimplify-card-sold-out": true,
5582
+ className: "absolute inset-0 bg-background/50 backdrop-blur-[1px] flex items-center justify-center z-10 rounded-[inherit]",
5583
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "bg-background/90 text-foreground text-xs font-bold px-4 py-2 uppercase tracking-wider", children: "Sold Out" })
5584
+ }
5585
+ );
5586
+ }
5587
+ function SaleBadge2({ product }) {
5588
+ if (!chunkPEDLCL72_js.isOnSale(product)) return null;
5589
+ const pct = chunkPEDLCL72_js.getDiscountPercentage(product);
5590
+ if (!pct || pct <= 0) return null;
5591
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-card-sale-badge": true, className: "inline-flex items-center text-[11px] font-semibold tracking-wide bg-destructive text-destructive-foreground px-2 py-0.5 rounded-md", children: [
5592
+ "-",
5593
+ pct,
5594
+ "%"
5595
+ ] });
5596
+ }
5597
+ function CardShell({
5598
+ product,
5599
+ renderLink,
5600
+ disabled = false,
5601
+ className,
5602
+ children
5603
+ }) {
5604
+ const href = `/products/${product.slug}`;
5605
+ const shellClass = cn(
5606
+ "group block text-left cursor-pointer bg-card rounded-[14px] overflow-hidden",
5607
+ "shadow-[0_1px_3px_rgba(0,0,0,0.04),0_6px_24px_rgba(0,0,0,0.06)]",
5608
+ "transition-all duration-300 ease-[cubic-bezier(0.19,1,0.22,1)]",
5609
+ !disabled && "hover:-translate-y-1 hover:shadow-[0_2px_6px_rgba(0,0,0,0.04),0_12px_40px_rgba(0,0,0,0.10)]",
5610
+ disabled && "opacity-60 cursor-default",
5611
+ className
5612
+ );
5613
+ if (renderLink) {
5614
+ return renderLink({ href, className: shellClass, children: /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children }) });
5615
+ }
5616
+ return /* @__PURE__ */ jsxRuntime.jsx("a", { href, className: shellClass, "data-cimplify-card": true, children });
5617
+ }
5618
+ function FoodProductCard({
5619
+ product,
5620
+ onQuickAdd,
5621
+ renderImage,
5622
+ renderLink,
5623
+ className
5624
+ }) {
5625
+ const image = product.image_url || product.images?.[0] || "";
5626
+ const tags = product.tags || [];
5627
+ const isSignature = product.metadata?.is_signature === true;
5628
+ const isNew = product.metadata?.is_new === true;
5629
+ const isComposite = product.type === chunkWMQXSDRC_js.PRODUCT_TYPE.Composite;
5630
+ return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, className, children: [
5631
+ /* @__PURE__ */ jsxRuntime.jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "square", renderImage, children: [
5632
+ isSignature && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute top-3 left-3 inline-flex items-center gap-1 text-[11px] font-semibold tracking-wide bg-amber-50 text-amber-700 border border-amber-200/60 px-2 py-0.5 rounded-md", children: [
5633
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-3 h-3 opacity-70", fill: "currentColor", viewBox: "0 0 16 16", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 .75l1.85 4.95L15 6.2l-3.7 3.2 1.1 5.1L8 12.15 3.6 14.5l1.1-5.1L1 6.2l5.15-.5z" }) }),
5634
+ "Signature"
5635
+ ] }),
5636
+ isNew && !isSignature && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute top-3 left-3 text-[11px] font-semibold tracking-wide bg-emerald-50 text-emerald-700 border border-emerald-200/60 px-2 py-0.5 rounded-md", children: "New" }),
5637
+ isComposite && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute top-3 left-3 text-[11px] font-semibold tracking-wide bg-violet-50 text-violet-700 border border-violet-200/60 px-2 py-0.5 rounded-md", children: "Customizable" }),
5638
+ /* @__PURE__ */ jsxRuntime.jsx(
5639
+ QuickAddButton,
5640
+ {
5641
+ onClick: () => onQuickAdd?.(product),
5642
+ className: "absolute bottom-3 right-3"
5643
+ }
5644
+ )
5645
+ ] }),
5646
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-3.5", children: [
5647
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[14.5px] font-semibold text-foreground leading-snug tracking-tight truncate", children: product.name }),
5648
+ product.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[12.5px] text-muted-foreground mt-1 leading-relaxed line-clamp-2", children: product.description }),
5649
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mt-3", children: [
5650
+ isComposite ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm font-bold", children: [
5651
+ "From ",
5652
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price })
5653
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price, className: "text-sm font-bold" }),
5654
+ tags.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-1", children: tags.slice(0, 2).map((tag) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium text-muted-foreground px-1.5 py-0.5 bg-muted rounded", children: tag }, tag)) })
5655
+ ] })
5656
+ ] })
5657
+ ] });
5658
+ }
5659
+ function getColorSwatches(product) {
5660
+ const variants = product.variants;
5661
+ if (!variants || variants.length === 0) return [];
5662
+ const seen = /* @__PURE__ */ new Set();
5663
+ for (const v of variants) {
5664
+ if (v.display_attributes) {
5665
+ for (const attr of v.display_attributes) {
5666
+ if (attr.axis_name.toLowerCase() === "color" && !seen.has(attr.value_name)) {
5667
+ seen.add(attr.value_name);
5668
+ }
5669
+ }
5670
+ }
5671
+ }
5672
+ return Array.from(seen).slice(0, 5);
5673
+ }
5674
+ function RetailProductCard({
5675
+ product,
5676
+ renderImage,
5677
+ renderLink,
5678
+ className
5679
+ }) {
5680
+ const image = product.image_url || product.images?.[0] || "";
5681
+ const outOfStock = product.inventory_status?.in_stock === false;
5682
+ const onSale = chunkPEDLCL72_js.isOnSale(product);
5683
+ const swatches = getColorSwatches(product);
5684
+ return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, disabled: outOfStock, className, children: [
5685
+ outOfStock && /* @__PURE__ */ jsxRuntime.jsx(SoldOutOverlay, {}),
5686
+ /* @__PURE__ */ jsxRuntime.jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "3/4", renderImage, children: [
5687
+ onSale && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-3 left-3", children: /* @__PURE__ */ jsxRuntime.jsx(SaleBadge2, { product }) }),
5688
+ /* @__PURE__ */ jsxRuntime.jsx(WishlistButton, { className: "absolute top-3 right-3" }),
5689
+ product.inventory_status?.low_stock && product.inventory_status?.stock_level && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute bottom-3 left-3 text-[11px] font-semibold bg-amber-50 text-amber-700 border border-amber-200/60 px-2 py-0.5 rounded-md", children: [
5690
+ "Only ",
5691
+ product.inventory_status.stock_level,
5692
+ " left"
5693
+ ] })
5694
+ ] }),
5695
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-3.5", children: [
5696
+ product.vendor && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] font-semibold text-muted-foreground uppercase tracking-widest", children: product.vendor }),
5697
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[14.5px] font-semibold text-foreground leading-snug tracking-tight mt-1 truncate", children: product.name }),
5698
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mt-2", children: [
5699
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price, className: "text-sm font-bold" }),
5700
+ onSale && /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: chunkPEDLCL72_js.getBasePrice(product), className: "text-xs text-muted-foreground line-through" })
5701
+ ] }),
5702
+ swatches.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-1.5 mt-2.5", children: swatches.map((name) => /* @__PURE__ */ jsxRuntime.jsx(
5703
+ "span",
5704
+ {
5705
+ title: name,
5706
+ className: "text-[9px] font-medium text-muted-foreground px-1.5 py-0.5 bg-muted rounded",
5707
+ children: name
5708
+ },
5709
+ name
5710
+ )) })
5711
+ ] })
5712
+ ] });
5713
+ }
5714
+ function PriceRange({ product, currency, className }) {
5715
+ const context = useOptionalCimplify();
5716
+ const resolvedCurrency = currency ?? context?.displayCurrency ?? "USD";
5717
+ const range = chunkPEDLCL72_js.getPriceRange(product);
5718
+ if (!range) return null;
5719
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-price-range": true, className, children: chunkPEDLCL72_js.formatPriceRange(range.min, range.max, resolvedCurrency) });
5720
+ }
5721
+ function WholesaleProductCard({
5722
+ product,
5723
+ onQuickAdd,
5724
+ renderImage,
5725
+ renderLink,
5726
+ className
5727
+ }) {
5728
+ const image = product.image_url || product.images?.[0] || "";
5729
+ const hasTiers = product.quantity_pricing && product.quantity_pricing.length > 1;
5730
+ const status = product.inventory_status;
5731
+ return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, className, children: [
5732
+ /* @__PURE__ */ jsxRuntime.jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "square", renderImage, children: [
5733
+ product.min_order_quantity != null && product.min_order_quantity > 1 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute top-3 left-3 text-[11px] font-semibold tracking-wide bg-zinc-800 text-white px-2 py-0.5 rounded-md", children: [
5734
+ "MOQ: ",
5735
+ product.min_order_quantity
5736
+ ] }),
5737
+ /* @__PURE__ */ jsxRuntime.jsx(
5738
+ QuickAddButton,
5739
+ {
5740
+ onClick: () => onQuickAdd?.(product),
5741
+ className: "absolute bottom-3 right-3"
5742
+ }
5743
+ )
5744
+ ] }),
5745
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-3.5", children: [
5746
+ product.sku && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] text-muted-foreground font-mono", children: product.sku }),
5747
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[14.5px] font-semibold text-foreground leading-snug tracking-tight mt-1 truncate", children: product.name }),
5748
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2", children: hasTiers ? /* @__PURE__ */ jsxRuntime.jsx(PriceRange, { product, className: "text-sm font-bold" }) : /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price, className: "text-sm font-bold" }) }),
5749
+ status && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 mt-2", children: [
5750
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
5751
+ "w-[7px] h-[7px] rounded-full shrink-0",
5752
+ status.in_stock ? status.low_stock ? "bg-amber-500" : "bg-emerald-500" : "bg-red-500"
5753
+ ) }),
5754
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
5755
+ "text-[10.5px] font-medium",
5756
+ status.in_stock ? status.low_stock ? "text-amber-600" : "text-emerald-600" : "text-red-600"
5757
+ ), children: !status.in_stock ? "Out of stock" : status.stock_level != null ? `${status.stock_level.toLocaleString()} in stock` : "In stock" })
5758
+ ] })
5759
+ ] })
5760
+ ] });
5761
+ }
5762
+ var TYPE_BADGES = {
5763
+ download: { label: "Download", color: "bg-sky-50 text-sky-700 border-sky-200/60" },
5764
+ license: { label: "License", color: "bg-blue-50 text-blue-700 border-blue-200/60" },
5765
+ event_ticket: { label: "Event", color: "bg-violet-50 text-violet-700 border-violet-200/60" },
5766
+ access_pass: { label: "Access", color: "bg-emerald-50 text-emerald-700 border-emerald-200/60" },
5767
+ gift_card: { label: "Gift Card", color: "bg-amber-50 text-amber-700 border-amber-200/60" }
5768
+ };
5769
+ function DigitalProductCard({
5770
+ product,
5771
+ renderImage,
5772
+ renderLink,
5773
+ className
5774
+ }) {
5775
+ const image = product.image_url || product.images?.[0] || "";
5776
+ const typeBadge = product.digital_type ? TYPE_BADGES[product.digital_type] : null;
5777
+ const isTicket = product.digital_type === "event_ticket";
5778
+ return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, className, children: [
5779
+ /* @__PURE__ */ jsxRuntime.jsx(CardImage, { src: image, alt: product.name, aspectRatio: "4/3", renderImage, children: typeBadge && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `absolute top-3 left-3 text-[11px] font-semibold tracking-wide border px-2 py-0.5 rounded-md ${typeBadge.color}`, children: typeBadge.label }) }),
5780
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-3.5", children: [
5781
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[14.5px] font-semibold text-foreground leading-snug tracking-tight truncate", children: product.name }),
5782
+ isTicket && (product.event_date || product.venue) && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-[12px] text-muted-foreground mt-1 truncate", children: [
5783
+ product.event_date && new Date(product.event_date).toLocaleDateString(void 0, { month: "short", day: "numeric" }),
5784
+ product.event_date && product.venue && " \xB7 ",
5785
+ product.venue
5786
+ ] }),
5787
+ !isTicket && product.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[12px] text-muted-foreground mt-1 line-clamp-1", children: product.description }),
5788
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mt-2.5", children: [
5789
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price, className: "text-sm font-bold" }),
5790
+ product.file_type && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] text-muted-foreground bg-muted px-1.5 py-0.5 rounded", children: [
5791
+ product.file_type.toUpperCase(),
5792
+ product.file_size_mb != null && ` \xB7 ${product.file_size_mb >= 1024 ? `${(product.file_size_mb / 1024).toFixed(1)}GB` : `${product.file_size_mb}MB`}`
5793
+ ] })
5794
+ ] })
5795
+ ] })
5796
+ ] });
5797
+ }
5798
+ function formatDuration2(minutes, unit) {
5799
+ if (unit && unit !== "minutes") return `${minutes} ${unit}`;
5800
+ if (minutes >= 60) {
5801
+ const h = Math.floor(minutes / 60);
5802
+ const m = minutes % 60;
5803
+ return m > 0 ? `${h}h ${m}m` : `${h} hr${h > 1 ? "s" : ""}`;
5804
+ }
5805
+ return `${minutes} min`;
5806
+ }
5807
+ function StandardServiceCard({
5808
+ product,
5809
+ onBook,
5810
+ renderImage,
5811
+ renderLink,
5812
+ className
5813
+ }) {
5814
+ const image = product.image_url || product.images?.[0] || "";
5815
+ const hasDeposit = product.deposit_type && product.deposit_type !== "none" && product.deposit_amount;
5816
+ return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, className, children: [
5817
+ /* @__PURE__ */ jsxRuntime.jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "16/9", renderImage, children: [
5818
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/50 to-transparent pointer-events-none" }),
5819
+ product.duration_minutes != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute bottom-3 left-3 inline-flex items-center gap-1 text-[12px] font-semibold px-2.5 py-1 rounded-lg bg-background/92 backdrop-blur-xl text-foreground shadow-sm", children: formatDuration2(product.duration_minutes, product.duration_unit) }),
5820
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute bottom-3 right-3 text-white font-bold text-lg drop-shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price }) })
5821
+ ] }),
5822
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4", children: [
5823
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[14.5px] font-bold text-foreground leading-snug tracking-tight", children: product.name }),
5824
+ product.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[12.5px] text-muted-foreground mt-1 leading-relaxed line-clamp-2", children: product.description }),
5825
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mt-3 pt-3 border-t border-border", children: [
5826
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-[12px] text-muted-foreground", children: [
5827
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-[7px] h-[7px] rounded-full bg-emerald-500 animate-pulse" }),
5828
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Available" }),
5829
+ hasDeposit && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5830
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-border", children: "\xB7" }),
5831
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
5832
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.deposit_amount }),
5833
+ " deposit"
5834
+ ] })
5835
+ ] })
5836
+ ] }),
5837
+ /* @__PURE__ */ jsxRuntime.jsx(
5838
+ "button",
5839
+ {
5840
+ onClick: (e) => {
5841
+ e.preventDefault();
5842
+ e.stopPropagation();
5843
+ onBook?.(product);
5844
+ },
5845
+ className: "text-[13px] font-semibold text-primary hover:text-primary/80 transition-colors",
5846
+ children: "Book now \u2192"
5847
+ }
5848
+ )
5849
+ ] })
5850
+ ] })
5851
+ ] });
5852
+ }
5853
+ function formatDuration3(minutes, unit) {
5854
+ if (unit && unit !== "minutes") return `${minutes} ${unit}`;
5855
+ if (minutes >= 60) {
5856
+ const h = Math.floor(minutes / 60);
5857
+ const m = minutes % 60;
5858
+ return m > 0 ? `${h}h ${m}m` : `${h} hr`;
5859
+ }
5860
+ return `${minutes} min`;
5861
+ }
5862
+ function CompactServiceCard({
5863
+ product,
5864
+ renderImage,
5865
+ renderLink,
5866
+ className
5867
+ }) {
5868
+ const image = product.image_url || product.images?.[0] || "";
5869
+ const hasDeposit = product.deposit_type && product.deposit_type !== "none" && product.deposit_amount;
5870
+ const hasBillingPlans = product.billing_plans && product.billing_plans.length > 0;
5871
+ const href = `/products/${product.slug}`;
5872
+ const content = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4 p-3", children: [
5873
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-[72px] h-[72px] rounded-xl overflow-hidden bg-muted shrink-0", children: renderImage ? renderImage({ src: image, alt: product.name, className: "w-full h-full object-cover" }) : /* @__PURE__ */ jsxRuntime.jsx("img", { src: image, alt: product.name, className: "w-full h-full object-cover" }) }),
5874
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
5875
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[14px] font-semibold text-foreground leading-tight truncate", children: product.name }),
5876
+ product.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[12px] text-muted-foreground mt-0.5 truncate", children: product.description }),
5877
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mt-2 flex-wrap", children: [
5878
+ product.duration_minutes != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10.5px] font-medium text-muted-foreground px-1.5 py-0.5 bg-muted rounded", children: formatDuration3(product.duration_minutes, product.duration_unit) }),
5879
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1 text-[10.5px] font-medium text-emerald-600", children: [
5880
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-[6px] h-[6px] rounded-full bg-emerald-500" }),
5881
+ "Available"
5882
+ ] }),
5883
+ hasDeposit && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10.5px] font-medium text-amber-600", children: [
5884
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.deposit_amount }),
5885
+ " deposit"
5886
+ ] }),
5887
+ hasBillingPlans && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex items-center gap-0.5 text-[10.5px] font-semibold text-primary px-1.5 py-0.5 bg-primary/10 rounded", children: "Subscription" })
5888
+ ] })
5889
+ ] }),
5890
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 shrink-0", children: [
5891
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price, className: "text-sm font-bold" }),
5892
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-4 h-4 text-muted-foreground group-hover:text-primary transition-colors", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" }) })
5893
+ ] })
5894
+ ] });
5895
+ const shellClass = cn(
5896
+ "group block text-left cursor-pointer bg-card rounded-[14px] overflow-hidden",
5897
+ "shadow-[0_1px_3px_rgba(0,0,0,0.04),0_6px_24px_rgba(0,0,0,0.06)]",
5898
+ "border border-transparent",
5899
+ "transition-all duration-300 ease-[cubic-bezier(0.19,1,0.22,1)]",
5900
+ "hover:-translate-y-[1px] hover:shadow-[0_2px_6px_rgba(0,0,0,0.04),0_12px_40px_rgba(0,0,0,0.10)] hover:border-primary/20",
5901
+ className
5902
+ );
5903
+ if (renderLink) {
5904
+ return renderLink({ href, className: shellClass, children: content });
5905
+ }
5906
+ return /* @__PURE__ */ jsxRuntime.jsx("a", { href, className: shellClass, "data-cimplify-card": true, children: content });
5907
+ }
5908
+ function ScheduleServiceCard({
5909
+ product,
5910
+ slots,
5911
+ onBook,
5912
+ renderImage,
5913
+ renderLink,
5914
+ className
5915
+ }) {
5916
+ const image = product.image_url || product.images?.[0] || "";
5917
+ const href = `/products/${product.slug}`;
5918
+ const durationLabel = product.duration_minutes != null ? `${product.duration_minutes} ${product.duration_unit ?? "min"}` : null;
5919
+ const displaySlots = (slots || []).slice(0, 3);
5920
+ const shellClass = cn(
5921
+ "group block text-left cursor-pointer bg-card rounded-[14px] overflow-hidden",
5922
+ "shadow-[0_1px_3px_rgba(0,0,0,0.04),0_6px_24px_rgba(0,0,0,0.06)]",
5923
+ "transition-all duration-300 ease-[cubic-bezier(0.19,1,0.22,1)]",
5924
+ "hover:-translate-y-1 hover:shadow-[0_2px_6px_rgba(0,0,0,0.04),0_12px_40px_rgba(0,0,0,0.10)]",
5925
+ className
5926
+ );
5927
+ const inner = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4", children: [
5928
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
5929
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
5930
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[14.5px] font-bold text-foreground leading-snug tracking-tight", children: product.name }),
5931
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-[12.5px] text-muted-foreground mt-0.5", children: [
5932
+ durationLabel && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5933
+ durationLabel,
5934
+ " \xB7 "
5935
+ ] }),
5936
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price })
5937
+ ] })
5938
+ ] }),
5939
+ image && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-14 h-14 rounded-xl overflow-hidden bg-muted shrink-0", children: renderImage ? renderImage({ src: image, alt: product.name, className: "w-full h-full object-cover" }) : /* @__PURE__ */ jsxRuntime.jsx("img", { src: image, alt: product.name, className: "w-full h-full object-cover" }) })
5940
+ ] }),
5941
+ product.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[12px] text-muted-foreground mt-2 line-clamp-2 leading-relaxed", children: product.description }),
5942
+ displaySlots.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4 pt-3 border-t border-border", children: [
5943
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] font-semibold text-muted-foreground uppercase tracking-widest mb-2", children: product.general_service_capacity != null && product.general_service_capacity > 1 ? "Upcoming classes" : "Next available" }),
5944
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-2 flex-wrap", children: displaySlots.map((slot, i) => /* @__PURE__ */ jsxRuntime.jsx(
5945
+ "button",
5946
+ {
5947
+ onClick: (e) => {
5948
+ e.preventDefault();
5949
+ e.stopPropagation();
5950
+ onBook?.(product);
5951
+ },
5952
+ className: cn(
5953
+ "text-[12.5px] font-medium px-3 py-1.5 rounded-lg transition-all duration-200 ease-out hover:scale-[1.04]",
5954
+ i === 0 ? "bg-primary text-primary-foreground font-semibold shadow-sm" : "bg-muted text-foreground hover:bg-muted/80"
5955
+ ),
5956
+ children: new Date(slot.start_time).toLocaleString(void 0, {
5957
+ weekday: "short",
5958
+ hour: "numeric",
5959
+ minute: "2-digit"
5960
+ })
5961
+ },
5962
+ i
5963
+ )) })
5964
+ ] })
5965
+ ] });
5966
+ if (renderLink) {
5967
+ return renderLink({ href, className: shellClass, children: inner });
5968
+ }
5969
+ return /* @__PURE__ */ jsxRuntime.jsx("a", { href, className: shellClass, "data-cimplify-card": true, children: inner });
5970
+ }
5971
+ var UNIT_LABELS = {
5972
+ minutes: "min",
5973
+ hours: "hr",
5974
+ days: "day",
5975
+ nights: "night",
5976
+ weeks: "week",
5977
+ months: "mo",
5978
+ years: "yr"
5979
+ };
5980
+ function RentalServiceCard({
5981
+ product,
5982
+ onBook,
5983
+ renderImage,
5984
+ renderLink,
5985
+ className
5986
+ }) {
5987
+ const image = product.image_url || product.images?.[0] || "";
5988
+ const hasDeposit = product.deposit_type && product.deposit_type !== "none" && product.deposit_amount;
5989
+ const unit = product.duration_unit ? UNIT_LABELS[product.duration_unit] || product.duration_unit : "day";
5990
+ const status = product.inventory_status;
5991
+ return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, className, children: [
5992
+ /* @__PURE__ */ jsxRuntime.jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "16/9", renderImage, children: [
5993
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/50 to-transparent pointer-events-none" }),
5994
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute bottom-3 left-3 inline-flex items-center text-[12px] font-semibold px-2.5 py-1 rounded-lg bg-background/92 backdrop-blur-xl text-foreground shadow-sm", children: [
5995
+ "Per ",
5996
+ unit
5997
+ ] }),
5998
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute bottom-3 right-3 text-white font-bold text-lg drop-shadow-sm", children: [
5999
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price }),
6000
+ "/",
6001
+ unit
6002
+ ] }),
6003
+ product.general_service_capacity != null && product.general_service_capacity > 1 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute top-3 left-3 text-[11px] font-semibold tracking-wide bg-blue-50/90 text-blue-700 border border-blue-200/50 backdrop-blur px-2 py-0.5 rounded-md", children: [
6004
+ "Up to ",
6005
+ product.general_service_capacity,
6006
+ " guests"
6007
+ ] })
6008
+ ] }),
6009
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4", children: [
6010
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[14.5px] font-bold text-foreground leading-snug tracking-tight", children: product.name }),
6011
+ product.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[12.5px] text-muted-foreground mt-1 leading-relaxed line-clamp-2", children: product.description }),
6012
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2 mt-3", children: [
6013
+ product.min_order_quantity != null && product.min_order_quantity > 1 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10.5px] font-medium text-muted-foreground px-1.5 py-0.5 bg-muted rounded", children: [
6014
+ "Min. ",
6015
+ product.min_order_quantity,
6016
+ " ",
6017
+ unit,
6018
+ product.min_order_quantity > 1 ? "s" : ""
6019
+ ] }),
6020
+ hasDeposit && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10.5px] font-medium text-amber-600", children: [
6021
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.deposit_amount }),
6022
+ " deposit"
6023
+ ] })
6024
+ ] }),
6025
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mt-3 pt-3 border-t border-border", children: [
6026
+ status && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-[12px]", children: [
6027
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
6028
+ "w-[7px] h-[7px] rounded-full shrink-0",
6029
+ status.in_stock ? "bg-emerald-500" : "bg-red-500"
6030
+ ) }),
6031
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: status.in_stock ? "text-muted-foreground" : "text-red-600", children: status.in_stock ? status.stock_level != null ? `${status.stock_level} available` : "Available" : "Unavailable" })
6032
+ ] }),
6033
+ /* @__PURE__ */ jsxRuntime.jsx(
6034
+ "button",
6035
+ {
6036
+ onClick: (e) => {
6037
+ e.preventDefault();
6038
+ e.stopPropagation();
6039
+ onBook?.(product);
6040
+ },
6041
+ className: "text-[13px] font-semibold text-primary hover:text-primary/80 transition-colors",
6042
+ children: "Reserve now \u2192"
6043
+ }
6044
+ )
6045
+ ] })
6046
+ ] })
6047
+ ] });
6048
+ }
6049
+ function AccommodationCard({
6050
+ product,
6051
+ onBook,
6052
+ renderImage,
6053
+ renderLink,
6054
+ className
6055
+ }) {
6056
+ const image = product.image_url || product.images?.[0] || "";
6057
+ const hasTiers = product.quantity_pricing && product.quantity_pricing.length > 1;
6058
+ const cancellationHours = product.cancellation_window_minutes ? Math.floor(product.cancellation_window_minutes / 60) : null;
6059
+ const tags = product.tags || [];
6060
+ return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, className, children: [
6061
+ /* @__PURE__ */ jsxRuntime.jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "16/9", renderImage, children: [
6062
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/50 to-transparent pointer-events-none" }),
6063
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute bottom-3 left-3 inline-flex items-center text-[12px] font-semibold px-2.5 py-1 rounded-lg bg-background/92 backdrop-blur-xl text-foreground shadow-sm", children: "Per night" }),
6064
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute bottom-3 right-3 text-white font-bold text-lg drop-shadow-sm", children: [
6065
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price }),
6066
+ "/night"
6067
+ ] })
6068
+ ] }),
6069
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4", children: [
6070
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[14.5px] font-bold text-foreground leading-snug tracking-tight", children: product.name }),
6071
+ product.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[12.5px] text-muted-foreground mt-1 leading-relaxed line-clamp-2", children: product.description }),
6072
+ tags.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1 mt-2.5", children: tags.slice(0, 4).map((tag) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium text-muted-foreground px-1.5 py-0.5 bg-muted rounded", children: tag }, tag)) }),
6073
+ product.general_service_capacity != null && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 mt-2 text-[11px] text-muted-foreground", children: [
6074
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-3.5 h-3.5", fill: "none", stroke: "currentColor", strokeWidth: "1.5", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0" }) }),
6075
+ product.general_service_capacity,
6076
+ " guest",
6077
+ product.general_service_capacity > 1 ? "s" : ""
6078
+ ] }),
6079
+ hasTiers && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3", children: /* @__PURE__ */ jsxRuntime.jsx(VolumePricing, { tiers: product.quantity_pricing }) }),
6080
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mt-3 pt-3 border-t border-border", children: [
6081
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-[11px] text-muted-foreground", children: [
6082
+ cancellationHours != null && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-emerald-600 font-medium", children: [
6083
+ "Free cancellation ",
6084
+ cancellationHours,
6085
+ "h"
6086
+ ] }),
6087
+ product.min_order_quantity != null && product.min_order_quantity > 1 && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
6088
+ "Min. ",
6089
+ product.min_order_quantity,
6090
+ " nights"
6091
+ ] })
6092
+ ] }),
6093
+ /* @__PURE__ */ jsxRuntime.jsx(
6094
+ "button",
6095
+ {
6096
+ onClick: (e) => {
6097
+ e.preventDefault();
6098
+ e.stopPropagation();
6099
+ onBook?.(product);
6100
+ },
6101
+ className: "text-[13px] font-semibold text-primary hover:text-primary/80 transition-colors",
6102
+ children: "Book room \u2192"
6103
+ }
6104
+ )
6105
+ ] })
6106
+ ] })
6107
+ ] });
6108
+ }
6109
+ var UNIT_LABELS2 = {
6110
+ weeks: "week",
6111
+ months: "mo",
6112
+ years: "yr"
6113
+ };
6114
+ function LeaseServiceCard({
6115
+ product,
6116
+ onBook,
6117
+ renderImage,
6118
+ renderLink,
6119
+ className
6120
+ }) {
6121
+ const image = product.image_url || product.images?.[0] || "";
6122
+ const hasDeposit = product.deposit_type && product.deposit_type !== "none" && product.deposit_amount;
6123
+ const hasTiers = product.quantity_pricing && product.quantity_pricing.length > 1;
6124
+ const unit = product.duration_unit ? UNIT_LABELS2[product.duration_unit] || product.duration_unit : "mo";
6125
+ const tags = product.tags || [];
6126
+ const cancellationHours = product.cancellation_window_minutes ? Math.floor(product.cancellation_window_minutes / 60) : null;
6127
+ return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, className, children: [
6128
+ /* @__PURE__ */ jsxRuntime.jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "16/9", renderImage, children: [
6129
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/50 to-transparent pointer-events-none" }),
6130
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute bottom-3 left-3 inline-flex items-center text-[12px] font-semibold px-2.5 py-1 rounded-lg bg-background/92 backdrop-blur-xl text-foreground shadow-sm", children: [
6131
+ "Per ",
6132
+ unit
6133
+ ] }),
6134
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute bottom-3 right-3 text-white font-bold text-lg drop-shadow-sm", children: [
6135
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price }),
6136
+ "/",
6137
+ unit
6138
+ ] })
6139
+ ] }),
6140
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4", children: [
6141
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[14.5px] font-bold text-foreground leading-snug tracking-tight", children: product.name }),
6142
+ product.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[12.5px] text-muted-foreground mt-1 leading-relaxed line-clamp-2", children: product.description }),
6143
+ tags.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1 mt-2.5", children: tags.slice(0, 4).map((tag) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium text-muted-foreground px-1.5 py-0.5 bg-muted rounded", children: tag }, tag)) }),
6144
+ hasTiers && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3", children: /* @__PURE__ */ jsxRuntime.jsx(VolumePricing, { tiers: product.quantity_pricing }) }),
6145
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2 mt-3", children: [
6146
+ product.min_order_quantity != null && product.min_order_quantity > 1 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10.5px] font-medium text-muted-foreground px-1.5 py-0.5 bg-muted rounded", children: [
6147
+ "Min. ",
6148
+ product.min_order_quantity,
6149
+ " ",
6150
+ unit,
6151
+ product.min_order_quantity > 1 ? "s" : ""
6152
+ ] }),
6153
+ hasDeposit && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10.5px] font-medium text-amber-600", children: [
6154
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.deposit_amount }),
6155
+ " deposit"
6156
+ ] }),
6157
+ cancellationHours != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10.5px] font-medium text-muted-foreground", children: cancellationHours >= 720 ? `${Math.floor(cancellationHours / 720)} month notice` : `${cancellationHours}h notice` })
6158
+ ] }),
6159
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mt-3 pt-3 border-t border-border", children: [
6160
+ product.billing_plans && product.billing_plans.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10.5px] font-semibold text-primary px-1.5 py-0.5 bg-primary/10 rounded", children: [
6161
+ product.billing_plans[0].frequency,
6162
+ " billing"
6163
+ ] }),
6164
+ /* @__PURE__ */ jsxRuntime.jsx(
6165
+ "button",
6166
+ {
6167
+ onClick: (e) => {
6168
+ e.preventDefault();
6169
+ e.stopPropagation();
6170
+ onBook?.(product);
6171
+ },
6172
+ className: "text-[13px] font-semibold text-primary hover:text-primary/80 transition-colors ml-auto",
6173
+ children: "Enquire now \u2192"
6174
+ }
6175
+ )
6176
+ ] })
6177
+ ] })
6178
+ ] });
6179
+ }
6180
+ var FREQUENCY_LABELS2 = {
6181
+ weekly: "/week",
6182
+ monthly: "/mo",
6183
+ quarterly: "/qtr",
6184
+ annually: "/yr"
6185
+ };
6186
+ function SubscriptionCard({
6187
+ product,
6188
+ onBook,
6189
+ renderImage,
6190
+ renderLink,
6191
+ className
6192
+ }) {
6193
+ const image = product.image_url || product.images?.[0] || "";
6194
+ const plans = product.billing_plans || [];
6195
+ const primaryPlan = plans[0];
6196
+ const frequency = primaryPlan?.frequency ? FREQUENCY_LABELS2[primaryPlan.frequency] || `/${primaryPlan.frequency}` : "/mo";
6197
+ const hasTrial = primaryPlan?.trial_days != null && primaryPlan.trial_days > 0;
6198
+ const tags = product.tags || [];
6199
+ return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, className, children: [
6200
+ /* @__PURE__ */ jsxRuntime.jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "16/9", renderImage, children: [
6201
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/50 to-transparent pointer-events-none" }),
6202
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute bottom-3 right-3 text-white font-bold text-lg drop-shadow-sm", children: [
6203
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price }),
6204
+ frequency
6205
+ ] }),
6206
+ hasTrial && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute top-3 left-3 text-[11px] font-semibold tracking-wide bg-emerald-50/90 text-emerald-700 border border-emerald-200/50 backdrop-blur px-2 py-0.5 rounded-md", children: [
6207
+ primaryPlan.trial_days,
6208
+ "-day free trial"
6209
+ ] })
6210
+ ] }),
6211
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4", children: [
6212
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[14.5px] font-bold text-foreground leading-snug tracking-tight", children: product.name }),
6213
+ product.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[12.5px] text-muted-foreground mt-1 leading-relaxed line-clamp-2", children: product.description }),
6214
+ tags.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1 mt-2.5", children: tags.slice(0, 3).map((tag) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium text-muted-foreground px-1.5 py-0.5 bg-muted rounded", children: tag }, tag)) }),
6215
+ plans.length > 1 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 space-y-1", children: plans.slice(0, 3).map((plan) => {
6216
+ const label = plan.frequency ? plan.frequency.charAt(0).toUpperCase() + plan.frequency.slice(1) : "Standard";
6217
+ const hasMarkup = plan.markup_type && plan.markup_amount;
6218
+ const isSavings = plan.markup_type === "percentage" && plan.markup_amount != null && plan.markup_amount < 0;
6219
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-[11px]", children: [
6220
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: label }),
6221
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: hasMarkup && isSavings && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-emerald-600 mr-1", children: [
6222
+ "Save ",
6223
+ Math.abs(plan.markup_amount),
6224
+ "%"
6225
+ ] }) })
6226
+ ] }, plan.id);
6227
+ }) }),
6228
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mt-3 pt-3 border-t border-border", children: [
6229
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-[11px] text-muted-foreground", children: [
6230
+ hasTrial && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-emerald-600 font-medium", children: "Free trial" }),
6231
+ primaryPlan?.setup_fee != null && primaryPlan.setup_fee > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
6232
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: primaryPlan.setup_fee }),
6233
+ " setup"
6234
+ ] })
6235
+ ] }),
6236
+ /* @__PURE__ */ jsxRuntime.jsx(
6237
+ "button",
6238
+ {
6239
+ onClick: (e) => {
6240
+ e.preventDefault();
6241
+ e.stopPropagation();
6242
+ onBook?.(product);
6243
+ },
6244
+ className: "text-[13px] font-semibold text-primary hover:text-primary/80 transition-colors",
6245
+ children: "Subscribe \u2192"
6246
+ }
6247
+ )
6248
+ ] })
6249
+ ] })
6250
+ ] });
6251
+ }
6252
+
6253
+ // src/react/cards/index.ts
6254
+ var CardVariant = /* @__PURE__ */ ((CardVariant2) => {
6255
+ CardVariant2["Food"] = "food";
6256
+ CardVariant2["Retail"] = "retail";
6257
+ CardVariant2["Wholesale"] = "wholesale";
6258
+ CardVariant2["Digital"] = "digital";
6259
+ CardVariant2["Standard"] = "standard";
6260
+ CardVariant2["Compact"] = "compact";
6261
+ CardVariant2["Schedule"] = "schedule";
6262
+ CardVariant2["Rental"] = "rental";
6263
+ CardVariant2["Accommodation"] = "accommodation";
6264
+ CardVariant2["Lease"] = "lease";
6265
+ CardVariant2["Subscription"] = "subscription";
6266
+ return CardVariant2;
6267
+ })(CardVariant || {});
5495
6268
  var ASPECT_STYLES2 = {
5496
6269
  square: { aspectRatio: "1/1" },
5497
6270
  "4/3": { aspectRatio: "4/3" },
5498
6271
  "16/10": { aspectRatio: "16/10" },
5499
6272
  "3/4": { aspectRatio: "3/4" }
5500
6273
  };
6274
+ var BUILT_IN_CARDS = {
6275
+ ["food" /* Food */]: FoodProductCard,
6276
+ ["retail" /* Retail */]: RetailProductCard,
6277
+ ["wholesale" /* Wholesale */]: WholesaleProductCard,
6278
+ ["digital" /* Digital */]: DigitalProductCard,
6279
+ ["standard" /* Standard */]: StandardServiceCard,
6280
+ ["rental" /* Rental */]: RentalServiceCard,
6281
+ ["accommodation" /* Accommodation */]: AccommodationCard,
6282
+ ["lease" /* Lease */]: LeaseServiceCard,
6283
+ ["subscription" /* Subscription */]: SubscriptionCard
6284
+ };
6285
+ var RENTAL_UNITS = /* @__PURE__ */ new Set([chunkWMQXSDRC_js.DURATION_UNIT.Days, chunkWMQXSDRC_js.DURATION_UNIT.Hours]);
6286
+ var LEASE_UNITS = /* @__PURE__ */ new Set([chunkWMQXSDRC_js.DURATION_UNIT.Weeks, chunkWMQXSDRC_js.DURATION_UNIT.Months, chunkWMQXSDRC_js.DURATION_UNIT.Years]);
6287
+ function resolveCardVariant(product) {
6288
+ if (product.quantity_pricing && product.quantity_pricing.length > 1) {
6289
+ return "wholesale" /* Wholesale */;
6290
+ }
6291
+ if (product.type === chunkWMQXSDRC_js.PRODUCT_TYPE.Digital) {
6292
+ return "digital" /* Digital */;
6293
+ }
6294
+ if (product.type === chunkWMQXSDRC_js.PRODUCT_TYPE.Service) {
6295
+ if (product.duration_unit && RENTAL_UNITS.has(product.duration_unit)) {
6296
+ return "rental" /* Rental */;
6297
+ }
6298
+ if (product.duration_unit === chunkWMQXSDRC_js.DURATION_UNIT.Nights) {
6299
+ return "accommodation" /* Accommodation */;
6300
+ }
6301
+ if (product.duration_unit && LEASE_UNITS.has(product.duration_unit)) {
6302
+ return "lease" /* Lease */;
6303
+ }
6304
+ if (product.billing_plans && product.billing_plans.length > 0 && !product.duration_minutes) {
6305
+ return "subscription" /* Subscription */;
6306
+ }
6307
+ return "standard" /* Standard */;
6308
+ }
6309
+ if (product.render_hint === chunkWMQXSDRC_js.RENDER_HINT.Food) {
6310
+ return "food" /* Food */;
6311
+ }
6312
+ if (product.render_hint === chunkWMQXSDRC_js.RENDER_HINT.Physical) {
6313
+ return "retail" /* Retail */;
6314
+ }
6315
+ return "retail" /* Retail */;
6316
+ }
5501
6317
  function ProductCard({
5502
6318
  product,
5503
6319
  displayMode,
6320
+ variant,
6321
+ cards,
5504
6322
  href,
5505
6323
  renderModal,
5506
6324
  renderImage,
5507
6325
  renderLink,
6326
+ onQuickAdd,
5508
6327
  children,
5509
6328
  aspectRatio = "4/3",
5510
6329
  className,
@@ -5530,61 +6349,42 @@ function ProductCard({
5530
6349
  setIsOpen(false);
5531
6350
  }, []);
5532
6351
  const imageUrl = product.image_url || product.images?.[0];
5533
- const cardBody = children ?? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5534
- imageUrl && /* @__PURE__ */ jsxRuntime.jsx(
5535
- "div",
5536
- {
5537
- "data-cimplify-product-card-image-container": true,
5538
- className: cn("overflow-hidden rounded-t-xl", classNames?.imageContainer),
5539
- style: ASPECT_STYLES2[aspectRatio],
5540
- children: renderImage ? renderImage({
5541
- src: imageUrl,
5542
- alt: product.name,
5543
- className: classNames?.image
5544
- }) : /* @__PURE__ */ jsxRuntime.jsx(
5545
- "img",
5546
- {
5547
- src: imageUrl,
5548
- alt: product.name,
5549
- className: cn("w-full h-full object-cover transition-transform duration-300 group-hover:scale-105", classNames?.image),
5550
- "data-cimplify-product-card-image": true
5551
- }
5552
- )
5553
- }
5554
- ),
5555
- /* @__PURE__ */ jsxRuntime.jsxs(
5556
- "div",
5557
- {
5558
- "data-cimplify-product-card-body": true,
5559
- className: cn("p-4 flex flex-col gap-1", classNames?.body),
5560
- children: [
5561
- /* @__PURE__ */ jsxRuntime.jsx(
5562
- "span",
5563
- {
5564
- "data-cimplify-product-card-name": true,
5565
- className: cn("font-semibold text-foreground leading-tight", classNames?.name),
5566
- children: product.name
5567
- }
5568
- ),
5569
- product.description && /* @__PURE__ */ jsxRuntime.jsx(
5570
- "span",
5571
- {
5572
- "data-cimplify-product-card-description": true,
5573
- className: cn("text-sm text-muted-foreground line-clamp-2", classNames?.description),
5574
- children: product.description
5575
- }
5576
- ),
5577
- /* @__PURE__ */ jsxRuntime.jsx(
5578
- Price,
6352
+ const cardBody = (() => {
6353
+ if (children) return children;
6354
+ const SlugCard = cards?.[product.slug];
6355
+ if (SlugCard) {
6356
+ return /* @__PURE__ */ jsxRuntime.jsx(SlugCard, { product, onQuickAdd, renderImage, renderLink });
6357
+ }
6358
+ const key = variant ?? resolveCardVariant(product);
6359
+ const ResolvedCard = BUILT_IN_CARDS[key];
6360
+ if (ResolvedCard) {
6361
+ return /* @__PURE__ */ jsxRuntime.jsx(ResolvedCard, { product, onQuickAdd, renderImage, renderLink });
6362
+ }
6363
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6364
+ imageUrl && /* @__PURE__ */ jsxRuntime.jsx(
6365
+ "div",
6366
+ {
6367
+ "data-cimplify-product-card-image-container": true,
6368
+ className: cn("overflow-hidden rounded-t-xl", classNames?.imageContainer),
6369
+ style: ASPECT_STYLES2[aspectRatio],
6370
+ children: renderImage ? renderImage({ src: imageUrl, alt: product.name, className: classNames?.image }) : /* @__PURE__ */ jsxRuntime.jsx(
6371
+ "img",
5579
6372
  {
5580
- amount: product.default_price,
5581
- className: cn("text-sm font-medium text-foreground mt-1", classNames?.price)
6373
+ src: imageUrl,
6374
+ alt: product.name,
6375
+ className: cn("w-full h-full object-cover transition-transform duration-300 group-hover:scale-105", classNames?.image),
6376
+ "data-cimplify-product-card-image": true
5582
6377
  }
5583
6378
  )
5584
- ]
5585
- }
5586
- )
5587
- ] });
6379
+ }
6380
+ ),
6381
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-product-card-body": true, className: cn("p-4 flex flex-col gap-1", classNames?.body), children: [
6382
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-product-card-name": true, className: cn("font-semibold text-foreground leading-tight", classNames?.name), children: product.name }),
6383
+ product.description && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-product-card-description": true, className: cn("text-sm text-muted-foreground line-clamp-2", classNames?.description), children: product.description }),
6384
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price, className: cn("text-sm font-medium text-foreground mt-1", classNames?.price) })
6385
+ ] })
6386
+ ] });
6387
+ })();
5588
6388
  if (mode === "page") {
5589
6389
  const linkHref = href ?? `/menu/${product.slug}`;
5590
6390
  const linkClassName = cn("group block no-underline text-[inherit] rounded-xl border border-border bg-background transition-shadow duration-200 hover:shadow-md", className, classNames?.root);
@@ -7078,7 +7878,7 @@ function BookingList({
7078
7878
  }
7079
7879
 
7080
7880
  // src/react/utils/format-duration.ts
7081
- var UNIT_LABELS = {
7881
+ var UNIT_LABELS3 = {
7082
7882
  minutes: { singular: "min", plural: "min" },
7083
7883
  hours: { singular: "hr", plural: "hrs" },
7084
7884
  days: { singular: "day", plural: "days" },
@@ -7087,9 +7887,9 @@ var UNIT_LABELS = {
7087
7887
  months: { singular: "month", plural: "months" },
7088
7888
  years: { singular: "year", plural: "years" }
7089
7889
  };
7090
- function formatDuration2(value, unit) {
7890
+ function formatDuration4(value, unit) {
7091
7891
  const resolved = unit ?? "minutes";
7092
- const labels = UNIT_LABELS[resolved];
7892
+ const labels = UNIT_LABELS3[resolved];
7093
7893
  const label = value === 1 ? labels.singular : labels.plural;
7094
7894
  return `${value} ${label}`;
7095
7895
  }
@@ -7144,7 +7944,7 @@ function ServiceCard({
7144
7944
  }
7145
7945
  ),
7146
7946
  /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-service-card-meta": true, className: cn("flex items-center gap-2 mt-1 text-sm", classNames?.meta), children: [
7147
- /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-service-card-duration": true, className: cn("text-muted-foreground", classNames?.duration), children: formatDuration2(service.duration_minutes, service.duration_unit) }),
7947
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-service-card-duration": true, className: cn("text-muted-foreground", classNames?.duration), children: formatDuration4(service.duration_minutes, service.duration_unit) }),
7148
7948
  service.price && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-service-card-price": true, className: cn("font-medium text-foreground", classNames?.price), children: /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: service.price }) })
7149
7949
  ] })
7150
7950
  ] }),
@@ -7626,12 +8426,6 @@ function getMetadataStringList(metadata, key) {
7626
8426
  if (!Array.isArray(value)) return [];
7627
8427
  return value.filter((item) => typeof item === "string");
7628
8428
  }
7629
- function PriceRange({ product, className }) {
7630
- const { displayCurrency } = useCimplify();
7631
- const range = chunkPEDLCL72_js.getPriceRange(product);
7632
- if (!range) return null;
7633
- return /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-price-range": true, className, children: chunkPEDLCL72_js.formatPriceRange(range.min, range.max, displayCurrency) });
7634
- }
7635
8429
  function DefaultProductLayout({
7636
8430
  product,
7637
8431
  onAddToCart,
@@ -7719,18 +8513,6 @@ function DefaultProductLayout({
7719
8513
  )
7720
8514
  ] });
7721
8515
  }
7722
- var DIETARY_TAGS = /* @__PURE__ */ new Set([
7723
- "vegetarian",
7724
- "vegan",
7725
- "gluten-free",
7726
- "dairy-free",
7727
- "nut-free",
7728
- "spicy",
7729
- "halal",
7730
- "kosher",
7731
- "organic",
7732
- "sugar-free"
7733
- ]);
7734
8516
  function FoodProductLayout({
7735
8517
  product,
7736
8518
  onAddToCart,
@@ -7740,9 +8522,7 @@ function FoodProductLayout({
7740
8522
  className
7741
8523
  }) {
7742
8524
  const images = product.images || (product.image_url ? [product.image_url] : []);
7743
- const allTags = product.tags || [];
7744
- const dietaryTags = allTags.filter((t) => DIETARY_TAGS.has(t));
7745
- const otherTags = allTags.filter((t) => !DIETARY_TAGS.has(t));
8525
+ const tags = product.tags || [];
7746
8526
  const ingredients = getMetadataStringList(product.metadata, "ingredients");
7747
8527
  const pairings = getMetadataStringList(product.metadata, "pairings");
7748
8528
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-product-layout": "food", className: cn("space-y-8", className), children: [
@@ -7759,13 +8539,12 @@ function FoodProductLayout({
7759
8539
  ),
7760
8540
  right: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
7761
8541
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-1.5", children: [
7762
- dietaryTags.map((tag) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex items-center gap-1 px-2.5 py-1 bg-green-100 text-green-800 text-xs font-medium rounded-full", children: tag }, tag)),
8542
+ tags.map((tag) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex items-center gap-1 px-2.5 py-1 bg-green-100 text-green-800 text-xs font-medium rounded-full", children: tag }, tag)),
7763
8543
  product.allergies && product.allergies.map((allergy) => /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1 px-2.5 py-1 bg-amber-100 text-amber-800 text-xs font-medium rounded-full", children: [
7764
8544
  "Contains ",
7765
8545
  allergy
7766
8546
  ] }, allergy))
7767
8547
  ] }),
7768
- /* @__PURE__ */ jsxRuntime.jsx(TagPills, { tags: otherTags }),
7769
8548
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
7770
8549
  /* @__PURE__ */ jsxRuntime.jsx("h1", { "data-cimplify-product-layout-name": true, className: "text-3xl lg:text-4xl font-bold tracking-tight", children: product.name }),
7771
8550
  /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price, className: "text-2xl font-semibold mt-2 block" })
@@ -8151,16 +8930,16 @@ function resolveTemplateKey(product) {
8151
8930
  if (product.quantity_pricing && product.quantity_pricing.length > 1) {
8152
8931
  return "wholesale" /* Wholesale */;
8153
8932
  }
8154
- if (product.type === "service") {
8933
+ if (product.type === chunkWMQXSDRC_js.PRODUCT_TYPE.Service) {
8155
8934
  return "service" /* Service */;
8156
8935
  }
8157
- if (product.type === "digital") {
8936
+ if (product.type === chunkWMQXSDRC_js.PRODUCT_TYPE.Digital) {
8158
8937
  return "digital" /* Digital */;
8159
8938
  }
8160
- if (product.render_hint === "food") {
8939
+ if (product.render_hint === chunkWMQXSDRC_js.RENDER_HINT.Food) {
8161
8940
  return "food" /* Food */;
8162
8941
  }
8163
- if (product.render_hint === "physical") {
8942
+ if (product.render_hint === chunkWMQXSDRC_js.RENDER_HINT.Physical) {
8164
8943
  return "physical" /* Physical */;
8165
8944
  }
8166
8945
  return "default" /* Default */;
@@ -8857,7 +9636,7 @@ function BookingPage({
8857
9636
  ] }) }),
8858
9637
  /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-service-info": true, className: classNames?.serviceInfo, children: [
8859
9638
  /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-booking-service-name": true, children: service.name }),
8860
- /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-booking-service-duration": true, children: formatDuration2(service.duration_minutes, service.duration_unit) }),
9639
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-booking-service-duration": true, children: formatDuration4(service.duration_minutes, service.duration_unit) }),
8861
9640
  service.price && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-booking-service-price": true, children: /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: service.price }) }),
8862
9641
  hasDeposit && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-booking-deposit-info": true, className: classNames?.depositInfo, children: [
8863
9642
  "Deposit: ",
@@ -8929,7 +9708,7 @@ function BookingPage({
8929
9708
  ] }),
8930
9709
  /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
8931
9710
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Duration" }),
8932
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatDuration2(service.duration_minutes, service.duration_unit) })
9711
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatDuration4(service.duration_minutes, service.duration_unit) })
8933
9712
  ] }),
8934
9713
  selectedResourceId && resources && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
8935
9714
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Room" }),
@@ -9409,8 +10188,9 @@ function CurrencySelector({
9409
10188
 
9410
10189
  Object.defineProperty(exports, "getVariantDisplayName", {
9411
10190
  enumerable: true,
9412
- get: function () { return chunkIYQGGFVQ_js.getVariantDisplayName; }
10191
+ get: function () { return chunkWMQXSDRC_js.getVariantDisplayName; }
9413
10192
  });
10193
+ exports.AccommodationCard = AccommodationCard;
9414
10194
  exports.Ad = Ad;
9415
10195
  exports.AdProvider = AdProvider;
9416
10196
  exports.AddOnSelector = AddOnSelector;
@@ -9423,6 +10203,9 @@ exports.BookingList = BookingList;
9423
10203
  exports.BookingPage = BookingPage;
9424
10204
  exports.BookingsPage = BookingsPage;
9425
10205
  exports.BundleSelector = BundleSelector;
10206
+ exports.CardImage = CardImage;
10207
+ exports.CardShell = CardShell;
10208
+ exports.CardVariant = CardVariant;
9426
10209
  exports.CartPage = CartPage;
9427
10210
  exports.CartSummary = CartSummary;
9428
10211
  exports.CataloguePage = CataloguePage;
@@ -9432,6 +10215,7 @@ exports.CheckoutPage = CheckoutPage;
9432
10215
  exports.CimplifyCheckout = CimplifyCheckout;
9433
10216
  exports.CimplifyProvider = CimplifyProvider;
9434
10217
  exports.CollectionPage = CollectionPage;
10218
+ exports.CompactServiceCard = CompactServiceCard;
9435
10219
  exports.CompositeSelector = CompositeSelector;
9436
10220
  exports.CurrencySelector = CurrencySelector;
9437
10221
  exports.CustomAttributesTable = CustomAttributesTable;
@@ -9440,11 +10224,14 @@ exports.DealBanner = DealBanner;
9440
10224
  exports.DealsPage = DealsPage;
9441
10225
  exports.DefaultProductLayout = DefaultProductLayout;
9442
10226
  exports.DeliveryEstimate = DeliveryEstimate;
10227
+ exports.DigitalProductCard = DigitalProductCard;
9443
10228
  exports.DigitalProductLayout = DigitalProductLayout;
9444
10229
  exports.DiscountInput = DiscountInput;
9445
10230
  exports.ElementsProvider = ElementsProvider;
10231
+ exports.FoodProductCard = FoodProductCard;
9446
10232
  exports.FoodProductLayout = FoodProductLayout;
9447
10233
  exports.InventoryBadge = InventoryBadge;
10234
+ exports.LeaseServiceCard = LeaseServiceCard;
9448
10235
  exports.LocationPicker = LocationPicker;
9449
10236
  exports.MetadataStringList = MetadataStringList;
9450
10237
  exports.OrderDetailPage = OrderDetailPage;
@@ -9463,11 +10250,15 @@ exports.ProductSheet = ProductSheet;
9463
10250
  exports.ProductTemplate = ProductTemplate;
9464
10251
  exports.PropertiesTable = PropertiesTable;
9465
10252
  exports.QuantitySelector = QuantitySelector;
10253
+ exports.QuickAddButton = QuickAddButton;
9466
10254
  exports.RecentlyViewed = RecentlyViewed;
9467
10255
  exports.RecommendationCarousel = RecommendationCarousel;
9468
10256
  exports.RelatedProductsSection = RelatedProductsSection;
10257
+ exports.RentalServiceCard = RentalServiceCard;
9469
10258
  exports.ResourcePicker = ResourcePicker;
10259
+ exports.RetailProductCard = RetailProductCard;
9470
10260
  exports.SaleBadge = SaleBadge;
10261
+ exports.ScheduleServiceCard = ScheduleServiceCard;
9471
10262
  exports.SearchInput = SearchInput;
9472
10263
  exports.SearchPage = SearchPage;
9473
10264
  exports.ServiceCard = ServiceCard;
@@ -9475,13 +10266,18 @@ exports.ServiceGrid = ServiceGrid;
9475
10266
  exports.ServiceProductLayout = ServiceProductLayout;
9476
10267
  exports.SessionMessageBanner = SessionMessageBanner;
9477
10268
  exports.SlotPicker = SlotPicker;
10269
+ exports.SoldOutOverlay = SoldOutOverlay;
9478
10270
  exports.StaffPicker = StaffPicker;
10271
+ exports.StandardServiceCard = StandardServiceCard;
9479
10272
  exports.StoreNav = StoreNav;
10273
+ exports.SubscriptionCard = SubscriptionCard;
9480
10274
  exports.TagPills = TagPills;
9481
10275
  exports.TwoColumnGrid = TwoColumnGrid;
9482
10276
  exports.VariantSelector = VariantSelector;
9483
10277
  exports.VolumePricing = VolumePricing;
10278
+ exports.WholesaleProductCard = WholesaleProductCard;
9484
10279
  exports.WholesaleProductLayout = WholesaleProductLayout;
10280
+ exports.WishlistButton = WishlistButton;
9485
10281
  exports.cn = cn;
9486
10282
  exports.roomToResource = roomToResource;
9487
10283
  exports.useActivityState = useActivityState;