@cimplify/sdk 0.24.2 → 0.26.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 (43) 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 +457 -405
  18. package/dist/react.d.ts +457 -405
  19. package/dist/react.js +2193 -1065
  20. package/dist/react.mjs +2161 -1059
  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/cart-page.json +1 -1
  27. package/registry/catalogue-page.json +1 -1
  28. package/registry/collection-page.json +1 -1
  29. package/registry/compact-service-card.json +16 -0
  30. package/registry/digital-product-card.json +16 -0
  31. package/registry/food-product-card.json +16 -0
  32. package/registry/food-product-layout.json +1 -1
  33. package/registry/index.json +87 -17
  34. package/registry/lease-service-card.json +17 -0
  35. package/registry/product-card.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/search-page.json +1 -1
  41. package/registry/standard-service-card.json +16 -0
  42. package/registry/subscription-card.json +16 -0
  43. 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');
@@ -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) {
@@ -3565,7 +3565,7 @@ function VariantSelector({
3565
3565
  {
3566
3566
  "data-cimplify-variant-name": true,
3567
3567
  className: cn("flex-1 min-w-0 text-sm", classNames?.name),
3568
- children: chunkIYQGGFVQ_js.getVariantDisplayName(variant, productName)
3568
+ children: chunkWMQXSDRC_js.getVariantDisplayName(variant, productName)
3569
3569
  }
3570
3570
  ),
3571
3571
  /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-variant-pricing": true, className: cn("text-sm text-muted-foreground", classNames?.pricing), children: [
@@ -5101,7 +5101,7 @@ function CartLineItemRow({
5101
5101
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-item": true, className: classNames?.item, children: [
5102
5102
  /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-item-info": true, children: [
5103
5103
  /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-name": true, className: classNames?.itemName, children: item.product.name }),
5104
- 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) }),
5105
5105
  item.addOnOptions && item.addOnOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-cart-item-addons": true, children: [
5106
5106
  "+ ",
5107
5107
  item.addOnOptions.map((opt) => opt.name).join(", ")
@@ -5498,19 +5498,832 @@ function ProductSheet({
5498
5498
  }
5499
5499
  );
5500
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 || {});
5501
6268
  var ASPECT_STYLES2 = {
5502
6269
  square: { aspectRatio: "1/1" },
5503
6270
  "4/3": { aspectRatio: "4/3" },
5504
6271
  "16/10": { aspectRatio: "16/10" },
5505
6272
  "3/4": { aspectRatio: "3/4" }
5506
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
+ }
5507
6317
  function ProductCard({
5508
6318
  product,
5509
6319
  displayMode,
6320
+ variant,
6321
+ cards,
5510
6322
  href,
5511
6323
  renderModal,
5512
6324
  renderImage,
5513
6325
  renderLink,
6326
+ onQuickAdd,
5514
6327
  children,
5515
6328
  aspectRatio = "4/3",
5516
6329
  className,
@@ -5536,61 +6349,42 @@ function ProductCard({
5536
6349
  setIsOpen(false);
5537
6350
  }, []);
5538
6351
  const imageUrl = product.image_url || product.images?.[0];
5539
- const cardBody = children ?? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5540
- imageUrl && /* @__PURE__ */ jsxRuntime.jsx(
5541
- "div",
5542
- {
5543
- "data-cimplify-product-card-image-container": true,
5544
- className: cn("overflow-hidden rounded-t-xl", classNames?.imageContainer),
5545
- style: ASPECT_STYLES2[aspectRatio],
5546
- children: renderImage ? renderImage({
5547
- src: imageUrl,
5548
- alt: product.name,
5549
- className: classNames?.image
5550
- }) : /* @__PURE__ */ jsxRuntime.jsx(
5551
- "img",
5552
- {
5553
- src: imageUrl,
5554
- alt: product.name,
5555
- className: cn("w-full h-full object-cover transition-transform duration-300 group-hover:scale-105", classNames?.image),
5556
- "data-cimplify-product-card-image": true
5557
- }
5558
- )
5559
- }
5560
- ),
5561
- /* @__PURE__ */ jsxRuntime.jsxs(
5562
- "div",
5563
- {
5564
- "data-cimplify-product-card-body": true,
5565
- className: cn("p-4 flex flex-col gap-1", classNames?.body),
5566
- children: [
5567
- /* @__PURE__ */ jsxRuntime.jsx(
5568
- "span",
5569
- {
5570
- "data-cimplify-product-card-name": true,
5571
- className: cn("font-semibold text-foreground leading-tight", classNames?.name),
5572
- children: product.name
5573
- }
5574
- ),
5575
- product.description && /* @__PURE__ */ jsxRuntime.jsx(
5576
- "span",
5577
- {
5578
- "data-cimplify-product-card-description": true,
5579
- className: cn("text-sm text-muted-foreground line-clamp-2", classNames?.description),
5580
- children: product.description
5581
- }
5582
- ),
5583
- /* @__PURE__ */ jsxRuntime.jsx(
5584
- 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",
5585
6372
  {
5586
- amount: product.default_price,
5587
- 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
5588
6377
  }
5589
6378
  )
5590
- ]
5591
- }
5592
- )
5593
- ] });
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
+ })();
5594
6388
  if (mode === "page") {
5595
6389
  const linkHref = href ?? `/menu/${product.slug}`;
5596
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);
@@ -7033,458 +7827,356 @@ function BookingList({
7033
7827
  filter,
7034
7828
  enabled: bookingsProp === void 0
7035
7829
  });
7036
- const bookings = bookingsProp ?? fetched;
7037
- if (isLoading && bookings.length === 0) {
7038
- return /* @__PURE__ */ jsxRuntime.jsx(
7039
- "div",
7040
- {
7041
- "data-cimplify-booking-list": true,
7042
- "aria-busy": "true",
7043
- className: cn(className, classNames?.root, classNames?.loading)
7044
- }
7045
- );
7046
- }
7047
- if (bookings.length === 0) {
7048
- return /* @__PURE__ */ jsxRuntime.jsx(
7049
- "div",
7050
- {
7051
- "data-cimplify-booking-list": true,
7052
- "data-empty": true,
7053
- className: cn(className, classNames?.root, classNames?.empty),
7054
- children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: emptyMessage })
7055
- }
7056
- );
7057
- }
7058
- return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-booking-list": true, className: cn(className, classNames?.root), children: bookings.map((booking) => /* @__PURE__ */ jsxRuntime.jsx(
7059
- "div",
7060
- {
7061
- "data-cimplify-booking-list-item": true,
7062
- className: classNames?.item,
7063
- onClick: () => onBookingClick?.(booking),
7064
- role: onBookingClick ? "button" : void 0,
7065
- tabIndex: onBookingClick ? 0 : void 0,
7066
- onKeyDown: onBookingClick ? (e) => {
7067
- if (e.key === "Enter" || e.key === " ") {
7068
- e.preventDefault();
7069
- onBookingClick(booking);
7070
- }
7071
- } : void 0,
7072
- children: /* @__PURE__ */ jsxRuntime.jsx(
7073
- BookingCard,
7074
- {
7075
- booking,
7076
- onCancel,
7077
- onReschedule,
7078
- renderBooking
7079
- }
7080
- )
7081
- },
7082
- booking.order_id
7083
- )) });
7084
- }
7085
-
7086
- // src/react/utils/format-duration.ts
7087
- var UNIT_LABELS = {
7088
- minutes: { singular: "min", plural: "min" },
7089
- hours: { singular: "hr", plural: "hrs" },
7090
- days: { singular: "day", plural: "days" },
7091
- nights: { singular: "night", plural: "nights" },
7092
- weeks: { singular: "week", plural: "weeks" },
7093
- months: { singular: "month", plural: "months" },
7094
- years: { singular: "year", plural: "years" }
7095
- };
7096
- function formatDuration2(value, unit) {
7097
- const resolved = unit ?? "minutes";
7098
- const labels = UNIT_LABELS[resolved];
7099
- const label = value === 1 ? labels.singular : labels.plural;
7100
- return `${value} ${label}`;
7101
- }
7102
- var ASPECT_STYLES3 = {
7103
- square: { aspectRatio: "1/1" },
7104
- "4/3": { aspectRatio: "4/3" },
7105
- "16/10": { aspectRatio: "16/10" },
7106
- "3/4": { aspectRatio: "3/4" }
7107
- };
7108
- function ServiceCard({
7109
- service,
7110
- onBook,
7111
- href,
7112
- actionLabel = "Book",
7113
- renderImage,
7114
- children,
7115
- aspectRatio = "4/3",
7116
- className,
7117
- classNames
7118
- }) {
7119
- const imageUrl = service.image_url;
7120
- const cardBody = children ?? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7121
- imageUrl && /* @__PURE__ */ jsxRuntime.jsx(
7122
- "div",
7123
- {
7124
- "data-cimplify-service-card-image-container": true,
7125
- className: cn("overflow-hidden rounded-t-xl", classNames?.imageContainer),
7126
- style: ASPECT_STYLES3[aspectRatio],
7127
- children: renderImage ? renderImage({
7128
- src: imageUrl,
7129
- alt: service.name,
7130
- className: classNames?.image
7131
- }) : /* @__PURE__ */ jsxRuntime.jsx(
7132
- "img",
7133
- {
7134
- src: imageUrl,
7135
- alt: service.name,
7136
- className: cn("w-full h-full object-cover transition-transform duration-300 group-hover:scale-105", classNames?.image),
7137
- "data-cimplify-service-card-image": true
7138
- }
7139
- )
7140
- }
7141
- ),
7142
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-service-card-body": true, className: cn("p-4 flex flex-col gap-1.5", classNames?.body), children: [
7143
- /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-service-card-name": true, className: cn("font-semibold text-foreground leading-tight", classNames?.name), children: service.name }),
7144
- service.description && /* @__PURE__ */ jsxRuntime.jsx(
7145
- "span",
7146
- {
7147
- "data-cimplify-service-card-description": true,
7148
- className: cn("text-sm text-muted-foreground line-clamp-2", classNames?.description),
7149
- children: service.description
7150
- }
7151
- ),
7152
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-service-card-meta": true, className: cn("flex items-center gap-2 mt-1 text-sm", classNames?.meta), children: [
7153
- /* @__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) }),
7154
- 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 }) })
7155
- ] })
7156
- ] }),
7157
- !href && onBook && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-service-card-action": true, className: cn("px-4 pb-4 pt-1 text-sm font-medium text-primary", classNames?.action), children: actionLabel })
7158
- ] });
7159
- const cardClasses = cn(
7160
- "group block w-full rounded-xl border border-border bg-background text-left transition-shadow duration-200 hover:shadow-md",
7161
- !service.is_available && "opacity-60",
7162
- className,
7163
- classNames?.root
7164
- );
7165
- if (href) {
7166
- return /* @__PURE__ */ jsxRuntime.jsx(
7167
- "a",
7168
- {
7169
- href,
7170
- "data-cimplify-service-card": true,
7171
- "data-available": service.is_available || void 0,
7172
- className: cn(cardClasses, "no-underline text-[inherit]"),
7173
- children: cardBody
7174
- }
7175
- );
7176
- }
7177
- return /* @__PURE__ */ jsxRuntime.jsx(
7178
- "button",
7179
- {
7180
- type: "button",
7181
- onClick: () => onBook?.(service),
7182
- disabled: !service.is_available,
7183
- "data-cimplify-service-card": true,
7184
- "data-available": service.is_available || void 0,
7185
- className: cn(cardClasses, "cursor-pointer font-[inherit] p-0 border-border"),
7186
- children: cardBody
7187
- }
7188
- );
7189
- }
7190
- function ServiceGrid({
7191
- services: servicesProp,
7192
- columns,
7193
- onServiceSelect,
7194
- getServiceHref,
7195
- renderCard,
7196
- renderImage,
7197
- availableOnly = true,
7198
- actionLabel,
7199
- emptyMessage = "No services available",
7200
- className,
7201
- classNames
7202
- }) {
7203
- const rawId = React3__default.default.useId();
7204
- const gridId = `cimplify-service-grid-${rawId.replace(/:/g, "")}`;
7205
- const { services: fetched, isLoading } = useServices({
7206
- enabled: servicesProp === void 0
7207
- });
7208
- const allServices = servicesProp ?? fetched;
7209
- const services = availableOnly ? allServices.filter((s) => s.is_available) : allServices;
7210
- const sm = columns?.sm ?? 1;
7211
- const md = columns?.md ?? 2;
7212
- const lg = columns?.lg ?? 3;
7213
- const xl = columns?.xl ?? 4;
7214
- if (isLoading && services.length === 0) {
7830
+ const bookings = bookingsProp ?? fetched;
7831
+ if (isLoading && bookings.length === 0) {
7215
7832
  return /* @__PURE__ */ jsxRuntime.jsx(
7216
7833
  "div",
7217
7834
  {
7218
- "data-cimplify-service-grid": true,
7835
+ "data-cimplify-booking-list": true,
7219
7836
  "aria-busy": "true",
7220
7837
  className: cn(className, classNames?.root, classNames?.loading)
7221
7838
  }
7222
7839
  );
7223
7840
  }
7224
- if (services.length === 0) {
7841
+ if (bookings.length === 0) {
7225
7842
  return /* @__PURE__ */ jsxRuntime.jsx(
7226
7843
  "div",
7227
7844
  {
7228
- "data-cimplify-service-grid": true,
7845
+ "data-cimplify-booking-list": true,
7229
7846
  "data-empty": true,
7230
7847
  className: cn(className, classNames?.root, classNames?.empty),
7231
7848
  children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: emptyMessage })
7232
7849
  }
7233
7850
  );
7234
7851
  }
7235
- const css = [
7236
- `#${gridId}{display:grid;grid-template-columns:repeat(${sm},1fr);gap:1rem}`,
7237
- `@media(min-width:768px){#${gridId}{grid-template-columns:repeat(${md},1fr)}}`,
7238
- `@media(min-width:1024px){#${gridId}{grid-template-columns:repeat(${lg},1fr)}}`,
7239
- `@media(min-width:1280px){#${gridId}{grid-template-columns:repeat(${xl},1fr)}}`
7240
- ].join("");
7241
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7242
- /* @__PURE__ */ jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: css } }),
7243
- /* @__PURE__ */ jsxRuntime.jsx(
7244
- "div",
7245
- {
7246
- id: gridId,
7247
- "data-cimplify-service-grid": true,
7248
- className: cn(className, classNames?.root),
7249
- children: services.map((service) => /* @__PURE__ */ jsxRuntime.jsx(
7250
- "div",
7251
- {
7252
- "data-cimplify-service-grid-item": true,
7253
- className: classNames?.item,
7254
- children: renderCard ? renderCard(service) : /* @__PURE__ */ jsxRuntime.jsx(
7255
- ServiceCard,
7256
- {
7257
- service,
7258
- onBook: onServiceSelect,
7259
- href: getServiceHref?.(service),
7260
- actionLabel,
7261
- renderImage
7262
- }
7263
- )
7264
- },
7265
- service.id
7266
- ))
7267
- }
7268
- )
7269
- ] });
7852
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-booking-list": true, className: cn(className, classNames?.root), children: bookings.map((booking) => /* @__PURE__ */ jsxRuntime.jsx(
7853
+ "div",
7854
+ {
7855
+ "data-cimplify-booking-list-item": true,
7856
+ className: classNames?.item,
7857
+ onClick: () => onBookingClick?.(booking),
7858
+ role: onBookingClick ? "button" : void 0,
7859
+ tabIndex: onBookingClick ? 0 : void 0,
7860
+ onKeyDown: onBookingClick ? (e) => {
7861
+ if (e.key === "Enter" || e.key === " ") {
7862
+ e.preventDefault();
7863
+ onBookingClick(booking);
7864
+ }
7865
+ } : void 0,
7866
+ children: /* @__PURE__ */ jsxRuntime.jsx(
7867
+ BookingCard,
7868
+ {
7869
+ booking,
7870
+ onCancel,
7871
+ onReschedule,
7872
+ renderBooking
7873
+ }
7874
+ )
7875
+ },
7876
+ booking.order_id
7877
+ )) });
7270
7878
  }
7271
- function CataloguePage({
7272
- title = "Products",
7273
- products: productsProp,
7274
- categories: categoriesProp,
7275
- showFilter = true,
7276
- showSearch = true,
7277
- showSort = false,
7278
- showInStockFilter = false,
7279
- showPriceRange = false,
7280
- showTagsFilter = false,
7879
+ function DefaultCatalogueLayout({
7880
+ products,
7881
+ categories,
7882
+ facets,
7883
+ isLoading,
7884
+ selectedCategory,
7885
+ onCategoryChange,
7886
+ searchQuery,
7887
+ onSearchChange,
7888
+ sortBy,
7889
+ sortOrder,
7890
+ onSortChange,
7891
+ inStockOnly,
7892
+ onInStockChange,
7893
+ selectedTags,
7281
7894
  availableTags,
7282
- defaultSort,
7283
- pageSize,
7284
- onProductClick,
7285
- onCategoryClick,
7895
+ onTagToggle,
7896
+ minPrice,
7897
+ maxPrice,
7898
+ onPriceRangeChange,
7899
+ page,
7900
+ totalPages,
7901
+ onPageChange,
7286
7902
  renderCard,
7287
7903
  renderImage,
7288
- columns,
7289
- className,
7290
- classNames
7904
+ renderLink,
7905
+ onQuickAdd,
7906
+ title = "Products",
7907
+ className
7291
7908
  }) {
7292
- const [selectedCategoryId, setSelectedCategoryId] = React3.useState(null);
7293
- const [searchQuery, setSearchQuery] = React3.useState("");
7294
- const [sortBy, setSortBy] = React3.useState(defaultSort?.by ?? "name");
7295
- const [sortOrder, setSortOrder] = React3.useState(defaultSort?.order ?? "asc");
7296
- const [inStockOnly, setInStockOnly] = React3.useState(false);
7297
- const [selectedTags, setSelectedTags] = React3.useState([]);
7298
- const [minPrice, setMinPrice] = React3.useState("");
7299
- const [maxPrice, setMaxPrice] = React3.useState("");
7300
- const [page, setPage] = React3.useState(1);
7301
- const debouncedSearch = useDebounce(searchQuery, 300);
7302
- const { products: fetchedProducts, isLoading: productsLoading, pagination } = useProducts({
7303
- enabled: productsProp === void 0,
7304
- category: selectedCategoryId ?? void 0,
7305
- search: debouncedSearch.length >= 2 ? debouncedSearch : void 0,
7306
- sort_by: sortBy,
7307
- sort_order: sortOrder,
7308
- in_stock: inStockOnly || void 0,
7309
- tags: selectedTags.length > 0 ? selectedTags : void 0,
7310
- min_price: minPrice ? parseFloat(minPrice) : void 0,
7311
- max_price: maxPrice ? parseFloat(maxPrice) : void 0,
7312
- page,
7313
- limit: pageSize
7314
- });
7315
- const { categories: fetchedCategories } = useCategories({
7316
- enabled: showFilter && categoriesProp === void 0
7317
- });
7318
- const allProducts = productsProp ?? fetchedProducts;
7319
- const categories = categoriesProp ?? fetchedCategories;
7320
- const handleCategorySelect = React3.useCallback(
7321
- (id) => {
7322
- setSelectedCategoryId(id);
7323
- setPage(1);
7324
- if (id) {
7325
- const cat = categories.find((c) => c.id === id);
7326
- if (cat) onCategoryClick?.(cat);
7327
- }
7328
- },
7329
- [categories, onCategoryClick]
7330
- );
7331
- const handleTagToggle = React3.useCallback((tag) => {
7332
- setSelectedTags(
7333
- (prev) => prev.includes(tag) ? prev.filter((t) => t !== tag) : [...prev, tag]
7334
- );
7335
- setPage(1);
7336
- }, []);
7337
- const totalPages = pagination?.total_pages ?? 1;
7338
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-catalogue-page": true, className: cn(className, classNames?.root), children: [
7339
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-catalogue-header": true, className: classNames?.header, children: [
7340
- /* @__PURE__ */ jsxRuntime.jsx("h1", { "data-cimplify-catalogue-title": true, className: classNames?.title, children: title }),
7341
- showSearch && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-catalogue-search": true, className: classNames?.searchContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
7342
- SearchInput,
7343
- {
7344
- onResultClick: onProductClick,
7345
- searchOptions: { category: selectedCategoryId ?? void 0 }
7346
- }
7347
- ) })
7909
+ const hasSidebar = facets && facets.length > 0 || availableTags && availableTags.length > 0;
7910
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-catalogue-layout": "default", className: cn("space-y-6", className), children: [
7911
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4", children: [
7912
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
7913
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-bold tracking-tight", children: title }),
7914
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground mt-0.5", children: [
7915
+ products.length,
7916
+ " items"
7917
+ ] })
7918
+ ] }),
7919
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full sm:max-w-xs", children: [
7920
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
7921
+ /* @__PURE__ */ jsxRuntime.jsx(
7922
+ "input",
7923
+ {
7924
+ type: "search",
7925
+ value: searchQuery,
7926
+ onChange: (e) => onSearchChange(e.target.value),
7927
+ placeholder: "Search...",
7928
+ className: "w-full h-10 pl-10 pr-4 text-sm border border-border rounded-lg bg-background outline-none focus:ring-2 focus:ring-primary/10 focus:border-primary/30 transition-all"
7929
+ }
7930
+ )
7931
+ ] })
7348
7932
  ] }),
7349
- showFilter && categories.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-catalogue-filter": true, className: classNames?.filterContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
7350
- CategoryFilter,
7351
- {
7352
- selectedId: selectedCategoryId,
7353
- onSelect: handleCategorySelect
7354
- }
7355
- ) }),
7356
- (showSort || showInStockFilter || showPriceRange || showTagsFilter) && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-catalogue-toolbar": true, className: cn("flex flex-wrap items-center gap-3", classNames?.toolbar), children: [
7357
- showSort && /* @__PURE__ */ jsxRuntime.jsxs(
7933
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3", children: [
7934
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5 overflow-x-auto pb-1", children: [
7935
+ /* @__PURE__ */ jsxRuntime.jsx(
7936
+ "button",
7937
+ {
7938
+ onClick: () => onCategoryChange(null),
7939
+ className: cn(
7940
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
7941
+ !selectedCategory ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
7942
+ ),
7943
+ children: "All"
7944
+ }
7945
+ ),
7946
+ categories.map((cat) => /* @__PURE__ */ jsxRuntime.jsx(
7947
+ "button",
7948
+ {
7949
+ onClick: () => onCategoryChange(selectedCategory === cat.id ? null : cat.id),
7950
+ className: cn(
7951
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
7952
+ selectedCategory === cat.id ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
7953
+ ),
7954
+ children: cat.name
7955
+ },
7956
+ cat.id
7957
+ ))
7958
+ ] }),
7959
+ /* @__PURE__ */ jsxRuntime.jsxs(
7358
7960
  "select",
7359
7961
  {
7360
- "data-cimplify-sort": true,
7361
7962
  value: `${sortBy}:${sortOrder}`,
7362
7963
  onChange: (e) => {
7363
7964
  const [by, order] = e.target.value.split(":");
7364
- setSortBy(by);
7365
- setSortOrder(order);
7366
- setPage(1);
7965
+ onSortChange(by, order);
7367
7966
  },
7368
- className: "rounded-md border border-input bg-background px-3 py-1.5 text-sm",
7967
+ className: "text-xs border border-border rounded-lg px-2 py-1.5 bg-background outline-none shrink-0",
7369
7968
  children: [
7370
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "name:asc", children: "Name A\u2013Z" }),
7371
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "name:desc", children: "Name Z\u2013A" }),
7969
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "created_at:desc", children: "Newest" }),
7372
7970
  /* @__PURE__ */ jsxRuntime.jsx("option", { value: "price:asc", children: "Price: Low to High" }),
7373
7971
  /* @__PURE__ */ jsxRuntime.jsx("option", { value: "price:desc", children: "Price: High to Low" }),
7374
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "created_at:desc", children: "Newest" }),
7375
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "created_at:asc", children: "Oldest" }),
7376
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "updated_at:desc", children: "Recently Updated" })
7972
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "name:asc", children: "Name: A-Z" })
7377
7973
  ]
7378
7974
  }
7379
- ),
7380
- showInStockFilter && /* @__PURE__ */ jsxRuntime.jsxs("label", { "data-cimplify-stock-filter": true, className: "flex items-center gap-1.5 text-sm cursor-pointer", children: [
7381
- /* @__PURE__ */ jsxRuntime.jsx(
7382
- "input",
7383
- {
7384
- type: "checkbox",
7385
- checked: inStockOnly,
7386
- onChange: (e) => {
7387
- setInStockOnly(e.target.checked);
7388
- setPage(1);
7389
- },
7390
- className: "accent-primary"
7391
- }
7392
- ),
7393
- "In stock only"
7975
+ )
7976
+ ] }),
7977
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: hasSidebar ? "flex gap-6" : "", children: [
7978
+ hasSidebar && /* @__PURE__ */ jsxRuntime.jsxs("aside", { className: "hidden lg:block w-60 shrink-0 space-y-6", children: [
7979
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
7980
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: "In stock only" }),
7981
+ /* @__PURE__ */ jsxRuntime.jsx(
7982
+ "button",
7983
+ {
7984
+ onClick: () => onInStockChange(!inStockOnly),
7985
+ className: cn("w-10 h-6 rounded-full transition-colors relative", inStockOnly ? "bg-foreground" : "bg-border"),
7986
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("absolute top-1 w-4 h-4 rounded-full bg-background transition-transform shadow-sm", inStockOnly ? "left-5" : "left-1") })
7987
+ }
7988
+ )
7989
+ ] }),
7990
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
7991
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-semibold mb-2", children: "Price Range" }),
7992
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
7993
+ /* @__PURE__ */ jsxRuntime.jsx(
7994
+ "input",
7995
+ {
7996
+ type: "number",
7997
+ placeholder: "Min",
7998
+ value: minPrice,
7999
+ onChange: (e) => onPriceRangeChange(e.target.value, maxPrice),
8000
+ className: "w-full rounded-lg border border-border px-2 py-1.5 text-xs bg-background outline-none focus:ring-1 focus:ring-primary/20"
8001
+ }
8002
+ ),
8003
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-xs", children: "\u2013" }),
8004
+ /* @__PURE__ */ jsxRuntime.jsx(
8005
+ "input",
8006
+ {
8007
+ type: "number",
8008
+ placeholder: "Max",
8009
+ value: maxPrice,
8010
+ onChange: (e) => onPriceRangeChange(minPrice, e.target.value),
8011
+ className: "w-full rounded-lg border border-border px-2 py-1.5 text-xs bg-background outline-none focus:ring-1 focus:ring-primary/20"
8012
+ }
8013
+ )
8014
+ ] })
8015
+ ] }),
8016
+ facets?.map((facet) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
8017
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-semibold mb-2", children: facet.name }),
8018
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1.5", children: facet.values.slice(0, 8).map((fv) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2 text-sm cursor-pointer group", children: [
8019
+ /* @__PURE__ */ jsxRuntime.jsx("input", { type: "checkbox", className: "w-3.5 h-3.5 accent-foreground rounded" }),
8020
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground group-hover:text-foreground transition-colors flex-1", children: fv.value }),
8021
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground/60", children: fv.count })
8022
+ ] }, fv.value)) })
8023
+ ] }, facet.slug)),
8024
+ availableTags && availableTags.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
8025
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-semibold mb-2", children: "Tags" }),
8026
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1.5", children: availableTags.map((tag) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2 text-sm cursor-pointer group", children: [
8027
+ /* @__PURE__ */ jsxRuntime.jsx(
8028
+ "input",
8029
+ {
8030
+ type: "checkbox",
8031
+ checked: selectedTags.includes(tag),
8032
+ onChange: () => onTagToggle(tag),
8033
+ className: "w-3.5 h-3.5 accent-foreground rounded"
8034
+ }
8035
+ ),
8036
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground group-hover:text-foreground transition-colors", children: tag })
8037
+ ] }, tag)) })
8038
+ ] })
7394
8039
  ] }),
7395
- showPriceRange && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-price-range": true, className: "flex items-center gap-1.5", children: [
8040
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
8041
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 gap-4 animate-pulse", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
8042
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-square bg-muted rounded-[14px]" }),
8043
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 space-y-2", children: [
8044
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-3/4 bg-muted rounded" }),
8045
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-3 w-1/2 bg-muted rounded" })
8046
+ ] })
8047
+ ] }, i)) }) : products.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-16", children: [
8048
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg font-medium", children: "No products found" }),
8049
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Try adjusting your filters" })
8050
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 gap-4", children: products.map(
8051
+ (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React3__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
8052
+ ProductCard,
8053
+ {
8054
+ product,
8055
+ renderImage,
8056
+ renderLink,
8057
+ onQuickAdd
8058
+ },
8059
+ product.id
8060
+ )
8061
+ ) }),
8062
+ totalPages > 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-2 pt-8", children: [
8063
+ /* @__PURE__ */ jsxRuntime.jsx(
8064
+ "button",
8065
+ {
8066
+ disabled: page <= 1,
8067
+ onClick: () => onPageChange(page - 1),
8068
+ className: "text-sm px-3 py-1.5 border border-border rounded-lg disabled:opacity-40 hover:bg-muted transition-colors",
8069
+ children: "Previous"
8070
+ }
8071
+ ),
8072
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-muted-foreground tabular-nums px-2", children: [
8073
+ page,
8074
+ " / ",
8075
+ totalPages
8076
+ ] }),
8077
+ /* @__PURE__ */ jsxRuntime.jsx(
8078
+ "button",
8079
+ {
8080
+ disabled: page >= totalPages,
8081
+ onClick: () => onPageChange(page + 1),
8082
+ className: "text-sm px-3 py-1.5 border border-border rounded-lg disabled:opacity-40 hover:bg-muted transition-colors",
8083
+ children: "Next"
8084
+ }
8085
+ )
8086
+ ] })
8087
+ ] })
8088
+ ] })
8089
+ ] });
8090
+ }
8091
+ function CompactCatalogueLayout({
8092
+ products,
8093
+ categories,
8094
+ isLoading,
8095
+ selectedCategory,
8096
+ onCategoryChange,
8097
+ searchQuery,
8098
+ onSearchChange,
8099
+ renderCard,
8100
+ renderImage,
8101
+ renderLink,
8102
+ onQuickAdd,
8103
+ title = "Menu",
8104
+ className
8105
+ }) {
8106
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-catalogue-layout": "compact", className: cn("space-y-6", className), children: [
8107
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-bold tracking-tight", children: title }),
8108
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col sm:flex-row items-start sm:items-center gap-3", children: [
8109
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5 overflow-x-auto pb-1 flex-1", children: [
7396
8110
  /* @__PURE__ */ jsxRuntime.jsx(
7397
- "input",
8111
+ "button",
7398
8112
  {
7399
- type: "number",
7400
- placeholder: "Min",
7401
- value: minPrice,
7402
- onChange: (e) => {
7403
- setMinPrice(e.target.value);
7404
- setPage(1);
7405
- },
7406
- className: "w-20 rounded-md border border-input bg-background px-2 py-1.5 text-sm",
7407
- min: 0,
7408
- step: "0.01"
8113
+ onClick: () => onCategoryChange(null),
8114
+ className: cn(
8115
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
8116
+ !selectedCategory ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
8117
+ ),
8118
+ children: "All"
7409
8119
  }
7410
8120
  ),
7411
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-sm", children: "\u2013" }),
8121
+ categories.map((cat) => /* @__PURE__ */ jsxRuntime.jsx(
8122
+ "button",
8123
+ {
8124
+ onClick: () => onCategoryChange(selectedCategory === cat.id ? null : cat.id),
8125
+ className: cn(
8126
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
8127
+ selectedCategory === cat.id ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
8128
+ ),
8129
+ children: cat.name
8130
+ },
8131
+ cat.id
8132
+ ))
8133
+ ] }),
8134
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full sm:max-w-[200px]", children: [
8135
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
7412
8136
  /* @__PURE__ */ jsxRuntime.jsx(
7413
8137
  "input",
7414
8138
  {
7415
- type: "number",
7416
- placeholder: "Max",
7417
- value: maxPrice,
7418
- onChange: (e) => {
7419
- setMaxPrice(e.target.value);
7420
- setPage(1);
7421
- },
7422
- className: "w-20 rounded-md border border-input bg-background px-2 py-1.5 text-sm",
7423
- min: 0,
7424
- step: "0.01"
8139
+ type: "search",
8140
+ value: searchQuery,
8141
+ onChange: (e) => onSearchChange(e.target.value),
8142
+ placeholder: "Search...",
8143
+ className: "w-full h-9 pl-10 pr-3 text-sm border border-border rounded-lg bg-background outline-none focus:ring-2 focus:ring-primary/10 transition-all"
7425
8144
  }
7426
8145
  )
7427
- ] }),
7428
- showTagsFilter && availableTags && availableTags.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-tags-filter": true, className: "flex flex-wrap gap-1.5", children: availableTags.map((tag) => /* @__PURE__ */ jsxRuntime.jsx(
7429
- "button",
7430
- {
7431
- type: "button",
7432
- onClick: () => handleTagToggle(tag),
7433
- className: cn(
7434
- "rounded-full px-3 py-1 text-xs font-medium border transition-colors",
7435
- selectedTags.includes(tag) ? "bg-primary text-primary-foreground border-primary" : "bg-background text-foreground border-input hover:bg-muted"
7436
- ),
7437
- children: tag
7438
- },
7439
- tag
7440
- )) })
8146
+ ] })
7441
8147
  ] }),
7442
- /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-catalogue-grid": true, className: classNames?.gridContainer, children: productsLoading && !productsProp ? /* @__PURE__ */ jsxRuntime.jsx(
7443
- "div",
7444
- {
7445
- "data-cimplify-catalogue-loading": true,
7446
- "aria-busy": "true",
7447
- className: classNames?.loading
7448
- }
7449
- ) : /* @__PURE__ */ jsxRuntime.jsx(
7450
- ProductGrid,
7451
- {
7452
- products: allProducts,
7453
- renderCard,
7454
- renderImage,
7455
- columns,
7456
- emptyMessage: "No products found"
7457
- }
7458
- ) }),
7459
- totalPages > 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-catalogue-pagination": true, className: cn("flex items-center justify-center gap-2 pt-6", classNames?.pagination), children: [
7460
- /* @__PURE__ */ jsxRuntime.jsx(
7461
- "button",
7462
- {
7463
- type: "button",
7464
- disabled: page <= 1,
7465
- onClick: () => setPage((p) => Math.max(1, p - 1)),
7466
- className: "rounded-md border border-input bg-background px-3 py-1.5 text-sm disabled:opacity-40",
7467
- children: "Previous"
7468
- }
7469
- ),
7470
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-muted-foreground tabular-nums", children: [
7471
- page,
7472
- " / ",
7473
- totalPages
7474
- ] }),
7475
- /* @__PURE__ */ jsxRuntime.jsx(
7476
- "button",
8148
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 lg:grid-cols-3 gap-5 animate-pulse", children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
8149
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-square bg-muted rounded-[14px]" }),
8150
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 space-y-2", children: [
8151
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-3/4 bg-muted rounded" }),
8152
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-3 w-1/2 bg-muted rounded" })
8153
+ ] })
8154
+ ] }, i)) }) : products.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-16", children: [
8155
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg font-medium", children: "No items found" }),
8156
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Try a different category or search" })
8157
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 lg:grid-cols-3 gap-5", children: products.map(
8158
+ (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React3__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
8159
+ ProductCard,
7477
8160
  {
7478
- type: "button",
7479
- disabled: page >= totalPages,
7480
- onClick: () => setPage((p) => p + 1),
7481
- className: "rounded-md border border-input bg-background px-3 py-1.5 text-sm disabled:opacity-40",
7482
- children: "Next"
7483
- }
8161
+ product,
8162
+ renderImage,
8163
+ renderLink,
8164
+ onQuickAdd
8165
+ },
8166
+ product.id
7484
8167
  )
7485
- ] })
8168
+ ) })
7486
8169
  ] });
7487
8170
  }
8171
+ var CatalogueTemplate = /* @__PURE__ */ ((CatalogueTemplate2) => {
8172
+ CatalogueTemplate2["Default"] = "default";
8173
+ CatalogueTemplate2["Compact"] = "compact";
8174
+ return CatalogueTemplate2;
8175
+ })(CatalogueTemplate || {});
8176
+ var BUILT_IN_LAYOUTS = {
8177
+ ["default" /* Default */]: DefaultCatalogueLayout,
8178
+ ["compact" /* Compact */]: CompactCatalogueLayout
8179
+ };
7488
8180
  function useDebounce(value, delay) {
7489
8181
  const [debounced, setDebounced] = React3__default.default.useState(value);
7490
8182
  React3__default.default.useEffect(() => {
@@ -7493,6 +8185,109 @@ function useDebounce(value, delay) {
7493
8185
  }, [value, delay]);
7494
8186
  return debounced;
7495
8187
  }
8188
+ function CataloguePage({
8189
+ template,
8190
+ layouts,
8191
+ title,
8192
+ products: productsProp,
8193
+ categories: categoriesProp,
8194
+ facets,
8195
+ availableTags,
8196
+ pageSize,
8197
+ defaultSort,
8198
+ renderCard,
8199
+ renderImage,
8200
+ renderLink,
8201
+ onQuickAdd,
8202
+ onProductClick,
8203
+ className,
8204
+ classNames
8205
+ }) {
8206
+ const [selectedCategory, setSelectedCategory] = React3.useState(null);
8207
+ const [searchQuery, setSearchQuery] = React3.useState("");
8208
+ const [sortBy, setSortBy] = React3.useState(defaultSort?.by ?? "created_at");
8209
+ const [sortOrder, setSortOrder] = React3.useState(defaultSort?.order ?? "desc");
8210
+ const [inStockOnly, setInStockOnly] = React3.useState(false);
8211
+ const [selectedTags, setSelectedTags] = React3.useState([]);
8212
+ const [minPrice, setMinPrice] = React3.useState("");
8213
+ const [maxPrice, setMaxPrice] = React3.useState("");
8214
+ const [page, setPage] = React3.useState(1);
8215
+ const debouncedSearch = useDebounce(searchQuery, 300);
8216
+ const { products: fetchedProducts, isLoading, pagination } = useProducts({
8217
+ enabled: productsProp === void 0,
8218
+ category: selectedCategory ?? void 0,
8219
+ search: debouncedSearch.length >= 2 ? debouncedSearch : void 0,
8220
+ sort_by: sortBy,
8221
+ sort_order: sortOrder,
8222
+ in_stock: inStockOnly || void 0,
8223
+ tags: selectedTags.length > 0 ? selectedTags : void 0,
8224
+ min_price: minPrice ? parseFloat(minPrice) : void 0,
8225
+ max_price: maxPrice ? parseFloat(maxPrice) : void 0,
8226
+ page,
8227
+ limit: pageSize
8228
+ });
8229
+ const { categories: fetchedCategories } = useCategories({
8230
+ enabled: categoriesProp === void 0
8231
+ });
8232
+ const products = productsProp ?? fetchedProducts;
8233
+ const categories = categoriesProp ?? fetchedCategories;
8234
+ const totalPages = pagination?.total_pages ?? 1;
8235
+ const handleCategoryChange = React3.useCallback((id) => {
8236
+ setSelectedCategory(id);
8237
+ setPage(1);
8238
+ }, []);
8239
+ const handleSortChange = React3.useCallback((by, order) => {
8240
+ setSortBy(by);
8241
+ setSortOrder(order);
8242
+ setPage(1);
8243
+ }, []);
8244
+ const handleTagToggle = React3.useCallback((tag) => {
8245
+ setSelectedTags(
8246
+ (prev) => prev.includes(tag) ? prev.filter((t) => t !== tag) : [...prev, tag]
8247
+ );
8248
+ setPage(1);
8249
+ }, []);
8250
+ const handlePriceRangeChange = React3.useCallback((min, max) => {
8251
+ setMinPrice(min);
8252
+ setMaxPrice(max);
8253
+ setPage(1);
8254
+ }, []);
8255
+ const key = template ?? "default" /* Default */;
8256
+ const Layout = layouts?.[key] ?? BUILT_IN_LAYOUTS[key] ?? DefaultCatalogueLayout;
8257
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-catalogue-page": true, className: cn(className, classNames?.root), children: /* @__PURE__ */ jsxRuntime.jsx(
8258
+ Layout,
8259
+ {
8260
+ products,
8261
+ categories,
8262
+ facets,
8263
+ isLoading,
8264
+ selectedCategory,
8265
+ onCategoryChange: handleCategoryChange,
8266
+ searchQuery,
8267
+ onSearchChange: setSearchQuery,
8268
+ sortBy,
8269
+ sortOrder,
8270
+ onSortChange: handleSortChange,
8271
+ inStockOnly,
8272
+ onInStockChange: setInStockOnly,
8273
+ selectedTags,
8274
+ availableTags,
8275
+ onTagToggle: handleTagToggle,
8276
+ minPrice,
8277
+ maxPrice,
8278
+ onPriceRangeChange: handlePriceRangeChange,
8279
+ page,
8280
+ totalPages,
8281
+ onPageChange: setPage,
8282
+ renderCard,
8283
+ renderImage,
8284
+ renderLink,
8285
+ onQuickAdd,
8286
+ onProductClick,
8287
+ title
8288
+ }
8289
+ ) });
8290
+ }
7496
8291
  function TwoColumnGrid({
7497
8292
  left,
7498
8293
  right,
@@ -7632,13 +8427,6 @@ function getMetadataStringList(metadata, key) {
7632
8427
  if (!Array.isArray(value)) return [];
7633
8428
  return value.filter((item) => typeof item === "string");
7634
8429
  }
7635
- function PriceRange({ product, currency, className }) {
7636
- const context = useOptionalCimplify();
7637
- const resolvedCurrency = currency ?? context?.displayCurrency ?? "USD";
7638
- const range = chunkPEDLCL72_js.getPriceRange(product);
7639
- if (!range) return null;
7640
- return /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-price-range": true, className, children: chunkPEDLCL72_js.formatPriceRange(range.min, range.max, resolvedCurrency) });
7641
- }
7642
8430
  function DefaultProductLayout({
7643
8431
  product,
7644
8432
  onAddToCart,
@@ -7726,18 +8514,6 @@ function DefaultProductLayout({
7726
8514
  )
7727
8515
  ] });
7728
8516
  }
7729
- var DIETARY_TAGS = /* @__PURE__ */ new Set([
7730
- "vegetarian",
7731
- "vegan",
7732
- "gluten-free",
7733
- "dairy-free",
7734
- "nut-free",
7735
- "spicy",
7736
- "halal",
7737
- "kosher",
7738
- "organic",
7739
- "sugar-free"
7740
- ]);
7741
8517
  function FoodProductLayout({
7742
8518
  product,
7743
8519
  onAddToCart,
@@ -7747,9 +8523,7 @@ function FoodProductLayout({
7747
8523
  className
7748
8524
  }) {
7749
8525
  const images = product.images || (product.image_url ? [product.image_url] : []);
7750
- const allTags = product.tags || [];
7751
- const dietaryTags = allTags.filter((t) => DIETARY_TAGS.has(t));
7752
- const otherTags = allTags.filter((t) => !DIETARY_TAGS.has(t));
8526
+ const tags = product.tags || [];
7753
8527
  const ingredients = getMetadataStringList(product.metadata, "ingredients");
7754
8528
  const pairings = getMetadataStringList(product.metadata, "pairings");
7755
8529
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-product-layout": "food", className: cn("space-y-8", className), children: [
@@ -7766,13 +8540,12 @@ function FoodProductLayout({
7766
8540
  ),
7767
8541
  right: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
7768
8542
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-1.5", children: [
7769
- 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)),
8543
+ 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)),
7770
8544
  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: [
7771
8545
  "Contains ",
7772
8546
  allergy
7773
8547
  ] }, allergy))
7774
8548
  ] }),
7775
- /* @__PURE__ */ jsxRuntime.jsx(TagPills, { tags: otherTags }),
7776
8549
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
7777
8550
  /* @__PURE__ */ jsxRuntime.jsx("h1", { "data-cimplify-product-layout-name": true, className: "text-3xl lg:text-4xl font-bold tracking-tight", children: product.name }),
7778
8551
  /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price, className: "text-2xl font-semibold mt-2 block" })
@@ -8143,7 +8916,7 @@ var ProductTemplate = /* @__PURE__ */ ((ProductTemplate2) => {
8143
8916
  ProductTemplate2["Physical"] = "physical";
8144
8917
  return ProductTemplate2;
8145
8918
  })(ProductTemplate || {});
8146
- var BUILT_IN_LAYOUTS = {
8919
+ var BUILT_IN_LAYOUTS2 = {
8147
8920
  ["food" /* Food */]: FoodProductLayout,
8148
8921
  ["wholesale" /* Wholesale */]: WholesaleProductLayout,
8149
8922
  ["service" /* Service */]: ServiceProductLayout,
@@ -8158,16 +8931,16 @@ function resolveTemplateKey(product) {
8158
8931
  if (product.quantity_pricing && product.quantity_pricing.length > 1) {
8159
8932
  return "wholesale" /* Wholesale */;
8160
8933
  }
8161
- if (product.type === "service") {
8934
+ if (product.type === chunkWMQXSDRC_js.PRODUCT_TYPE.Service) {
8162
8935
  return "service" /* Service */;
8163
8936
  }
8164
- if (product.type === "digital") {
8937
+ if (product.type === chunkWMQXSDRC_js.PRODUCT_TYPE.Digital) {
8165
8938
  return "digital" /* Digital */;
8166
8939
  }
8167
- if (product.render_hint === "food") {
8940
+ if (product.render_hint === chunkWMQXSDRC_js.RENDER_HINT.Food) {
8168
8941
  return "food" /* Food */;
8169
8942
  }
8170
- if (product.render_hint === "physical") {
8943
+ if (product.render_hint === chunkWMQXSDRC_js.RENDER_HINT.Physical) {
8171
8944
  return "physical" /* Physical */;
8172
8945
  }
8173
8946
  return "default" /* Default */;
@@ -8180,8 +8953,8 @@ function resolveLayout(product, pages, templates) {
8180
8953
  if (templates?.[key]) {
8181
8954
  return templates[key];
8182
8955
  }
8183
- if (BUILT_IN_LAYOUTS[key]) {
8184
- return BUILT_IN_LAYOUTS[key];
8956
+ if (BUILT_IN_LAYOUTS2[key]) {
8957
+ return BUILT_IN_LAYOUTS2[key];
8185
8958
  }
8186
8959
  return DefaultProductLayout;
8187
8960
  }
@@ -8239,56 +9012,168 @@ function ProductPage({
8239
9012
  }
8240
9013
  ) });
8241
9014
  }
8242
- function CartPage({
8243
- title = "Your Cart",
9015
+ function DefaultCartLayout({
9016
+ cart,
8244
9017
  onCheckout,
8245
9018
  onContinueShopping,
8246
9019
  onDiscountApply,
8247
9020
  onDiscountClear,
8248
9021
  showDiscount = true,
8249
- showContinueShopping = true,
8250
9022
  checkoutLabel = "Proceed to Checkout",
8251
- className,
8252
- classNames
9023
+ className
8253
9024
  }) {
8254
- const { isEmpty, subtotal } = useCart();
8255
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-page": true, className: cn(className, classNames?.root), children: [
8256
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-page-header": true, className: classNames?.header, children: [
8257
- /* @__PURE__ */ jsxRuntime.jsx("h1", { "data-cimplify-cart-page-title": true, className: classNames?.title, children: title }),
8258
- showContinueShopping && /* @__PURE__ */ jsxRuntime.jsx(
9025
+ if (cart.isEmpty) {
9026
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-layout": "default", className: cn("text-center py-20", className), children: [
9027
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-16 h-16 mx-auto text-muted-foreground/30", fill: "none", stroke: "currentColor", strokeWidth: "1", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z" }) }),
9028
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg font-medium mt-4", children: "Your cart is empty" }),
9029
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Add some items to get started" }),
9030
+ onContinueShopping && /* @__PURE__ */ jsxRuntime.jsx(
8259
9031
  "button",
8260
9032
  {
8261
- type: "button",
8262
9033
  onClick: onContinueShopping,
8263
- "data-cimplify-cart-continue": true,
8264
- className: classNames?.continueButton,
8265
- children: "Continue Shopping"
9034
+ className: "text-sm font-medium text-primary mt-4 hover:underline",
9035
+ children: "Continue shopping"
8266
9036
  }
8267
9037
  )
8268
- ] }),
8269
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-page-content": true, className: classNames?.content, children: [
8270
- /* @__PURE__ */ jsxRuntime.jsx(CartSummary, {}),
8271
- showDiscount && !isEmpty && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-cart-page-discount": true, className: classNames?.discount, children: /* @__PURE__ */ jsxRuntime.jsx(
8272
- DiscountInput,
9038
+ ] });
9039
+ }
9040
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-layout": "default", className: cn("space-y-6", className), children: [
9041
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
9042
+ /* @__PURE__ */ jsxRuntime.jsxs("h1", { className: "text-2xl font-bold tracking-tight", children: [
9043
+ "Your Cart (",
9044
+ cart.itemCount,
9045
+ " ",
9046
+ cart.itemCount === 1 ? "item" : "items",
9047
+ ")"
9048
+ ] }),
9049
+ onContinueShopping && /* @__PURE__ */ jsxRuntime.jsx(
9050
+ "button",
8273
9051
  {
8274
- orderSubtotal: subtotal.toString(),
8275
- onApply: onDiscountApply,
8276
- onClear: onDiscountClear
9052
+ onClick: onContinueShopping,
9053
+ className: "text-sm text-muted-foreground hover:text-foreground transition-colors",
9054
+ children: "Continue shopping"
8277
9055
  }
8278
- ) })
9056
+ )
9057
+ ] }),
9058
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid lg:grid-cols-[1fr_380px] gap-8", children: [
9059
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(CartSummary, {}) }),
9060
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "lg:sticky lg:top-6 h-fit space-y-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border border-border rounded-[14px] p-6 space-y-4", children: [
9061
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "font-semibold", children: "Order Summary" }),
9062
+ showDiscount && /* @__PURE__ */ jsxRuntime.jsx(
9063
+ DiscountInput,
9064
+ {
9065
+ orderSubtotal: cart.subtotal.toString(),
9066
+ onApply: onDiscountApply,
9067
+ onClear: onDiscountClear
9068
+ }
9069
+ ),
9070
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 text-sm", children: [
9071
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
9072
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Subtotal" }),
9073
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: cart.subtotal })
9074
+ ] }),
9075
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
9076
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Tax" }),
9077
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: cart.tax })
9078
+ ] }),
9079
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between font-semibold text-base pt-2 border-t border-border", children: [
9080
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Total" }),
9081
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: cart.total })
9082
+ ] })
9083
+ ] }),
9084
+ /* @__PURE__ */ jsxRuntime.jsx(
9085
+ "button",
9086
+ {
9087
+ onClick: onCheckout,
9088
+ className: "w-full h-12 bg-foreground text-background font-medium text-sm rounded-lg hover:bg-foreground/90 transition-colors",
9089
+ children: checkoutLabel
9090
+ }
9091
+ )
9092
+ ] }) })
9093
+ ] })
9094
+ ] });
9095
+ }
9096
+ function CompactCartLayout({
9097
+ cart,
9098
+ onCheckout,
9099
+ onContinueShopping,
9100
+ checkoutLabel = "Place Order",
9101
+ className
9102
+ }) {
9103
+ if (cart.isEmpty) {
9104
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-layout": "compact", className: cn("text-center py-16", className), children: [
9105
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg font-medium", children: "Your order is empty" }),
9106
+ onContinueShopping && /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onContinueShopping, className: "text-sm font-medium text-primary mt-3 hover:underline", children: "Browse menu" })
9107
+ ] });
9108
+ }
9109
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-layout": "compact", className: cn("max-w-lg mx-auto space-y-4", className), children: [
9110
+ /* @__PURE__ */ jsxRuntime.jsxs("h1", { className: "text-xl font-bold tracking-tight", children: [
9111
+ "Your Order (",
9112
+ cart.itemCount,
9113
+ ")"
9114
+ ] }),
9115
+ /* @__PURE__ */ jsxRuntime.jsx(CartSummary, {}),
9116
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 text-sm pt-4 border-t border-border", children: [
9117
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
9118
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Subtotal" }),
9119
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: cart.subtotal })
9120
+ ] }),
9121
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
9122
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Tax" }),
9123
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: cart.tax })
9124
+ ] }),
9125
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between font-semibold text-base pt-2 border-t border-border", children: [
9126
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Total" }),
9127
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: cart.total })
9128
+ ] })
8279
9129
  ] }),
8280
- !isEmpty && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-cart-page-footer": true, className: classNames?.footer, children: /* @__PURE__ */ jsxRuntime.jsx(
9130
+ /* @__PURE__ */ jsxRuntime.jsx(
8281
9131
  "button",
8282
9132
  {
8283
- type: "button",
8284
9133
  onClick: onCheckout,
8285
- "data-cimplify-cart-checkout-button": true,
8286
- className: classNames?.checkoutButton,
9134
+ className: "w-full h-12 bg-foreground text-background font-medium text-sm rounded-lg hover:bg-foreground/90 transition-colors",
8287
9135
  children: checkoutLabel
8288
9136
  }
8289
- ) })
9137
+ )
8290
9138
  ] });
8291
9139
  }
9140
+ var CartTemplate = /* @__PURE__ */ ((CartTemplate2) => {
9141
+ CartTemplate2["Default"] = "default";
9142
+ CartTemplate2["Compact"] = "compact";
9143
+ return CartTemplate2;
9144
+ })(CartTemplate || {});
9145
+ var BUILT_IN_LAYOUTS3 = {
9146
+ ["default" /* Default */]: DefaultCartLayout,
9147
+ ["compact" /* Compact */]: CompactCartLayout
9148
+ };
9149
+ function CartPage({
9150
+ template,
9151
+ layouts,
9152
+ onCheckout,
9153
+ onContinueShopping,
9154
+ onDiscountApply,
9155
+ onDiscountClear,
9156
+ showDiscount = true,
9157
+ checkoutLabel,
9158
+ className,
9159
+ classNames
9160
+ }) {
9161
+ const cart = useCart();
9162
+ const key = template ?? "default" /* Default */;
9163
+ const Layout = layouts?.[key] ?? BUILT_IN_LAYOUTS3[key] ?? DefaultCartLayout;
9164
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-cart-page": true, className: cn(className, classNames?.root), children: /* @__PURE__ */ jsxRuntime.jsx(
9165
+ Layout,
9166
+ {
9167
+ cart,
9168
+ onCheckout,
9169
+ onContinueShopping,
9170
+ onDiscountApply,
9171
+ onDiscountClear,
9172
+ showDiscount,
9173
+ checkoutLabel
9174
+ }
9175
+ ) });
9176
+ }
8292
9177
  function CheckoutPage({
8293
9178
  title = "Checkout",
8294
9179
  onComplete,
@@ -8312,22 +9197,362 @@ function CheckoutPage({
8312
9197
  )
8313
9198
  ] });
8314
9199
  }
9200
+ function DefaultCollectionLayout({
9201
+ collection,
9202
+ products,
9203
+ renderCard,
9204
+ renderImage,
9205
+ renderLink,
9206
+ onQuickAdd,
9207
+ className
9208
+ }) {
9209
+ const [searchQuery, setSearchQuery] = React3.useState("");
9210
+ const [activeTag, setActiveTag] = React3.useState(null);
9211
+ const collectionTags = React3.useMemo(() => {
9212
+ const tagSet = /* @__PURE__ */ new Set();
9213
+ for (const p of products) {
9214
+ if (p.tags) {
9215
+ for (const t of p.tags) tagSet.add(t);
9216
+ }
9217
+ }
9218
+ return Array.from(tagSet).slice(0, 6);
9219
+ }, [products]);
9220
+ const filtered = React3.useMemo(() => {
9221
+ let result = products;
9222
+ if (searchQuery.trim().length >= 2) {
9223
+ const q = searchQuery.toLowerCase();
9224
+ result = result.filter(
9225
+ (p) => p.name.toLowerCase().includes(q) || p.description?.toLowerCase().includes(q)
9226
+ );
9227
+ }
9228
+ if (activeTag) {
9229
+ result = result.filter((p) => p.tags?.includes(activeTag));
9230
+ }
9231
+ return result;
9232
+ }, [products, searchQuery, activeTag]);
9233
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-collection-layout": "default", className: cn("space-y-8", className), children: [
9234
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-collection-hero": true, className: "relative overflow-hidden rounded-2xl bg-muted", children: [
9235
+ collection.image_url && /* @__PURE__ */ jsxRuntime.jsx(
9236
+ "img",
9237
+ {
9238
+ src: collection.image_url,
9239
+ alt: collection.name,
9240
+ className: "w-full h-64 lg:h-80 object-cover"
9241
+ }
9242
+ ),
9243
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/60 via-black/20 to-transparent" }),
9244
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute bottom-0 left-0 right-0 p-6 lg:p-8", children: [
9245
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl lg:text-4xl font-bold text-white tracking-tight", children: collection.name }),
9246
+ collection.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-white/80 mt-2 max-w-lg text-sm lg:text-base", children: collection.description }),
9247
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-white/60 text-sm mt-2", children: [
9248
+ products.length,
9249
+ " ",
9250
+ products.length === 1 ? "item" : "items"
9251
+ ] })
9252
+ ] })
9253
+ ] }),
9254
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col sm:flex-row items-start sm:items-center gap-3", children: [
9255
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 min-w-0 w-full sm:max-w-xs", children: [
9256
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
9257
+ /* @__PURE__ */ jsxRuntime.jsx(
9258
+ "input",
9259
+ {
9260
+ type: "search",
9261
+ value: searchQuery,
9262
+ onChange: (e) => setSearchQuery(e.target.value),
9263
+ placeholder: `Search ${collection.name}...`,
9264
+ className: "w-full h-10 pl-10 pr-4 text-sm border border-border rounded-lg bg-background outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary transition-colors"
9265
+ }
9266
+ )
9267
+ ] }),
9268
+ collectionTags.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-1.5", children: [
9269
+ /* @__PURE__ */ jsxRuntime.jsx(
9270
+ "button",
9271
+ {
9272
+ onClick: () => setActiveTag(null),
9273
+ className: cn(
9274
+ "text-xs font-medium px-3 py-1.5 rounded-full transition-colors",
9275
+ !activeTag ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
9276
+ ),
9277
+ children: "All"
9278
+ }
9279
+ ),
9280
+ collectionTags.map((tag) => /* @__PURE__ */ jsxRuntime.jsx(
9281
+ "button",
9282
+ {
9283
+ onClick: () => setActiveTag(activeTag === tag ? null : tag),
9284
+ className: cn(
9285
+ "text-xs font-medium px-3 py-1.5 rounded-full transition-colors",
9286
+ activeTag === tag ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
9287
+ ),
9288
+ children: tag
9289
+ },
9290
+ tag
9291
+ ))
9292
+ ] })
9293
+ ] }),
9294
+ filtered.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4", children: filtered.map(
9295
+ (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React3__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
9296
+ ProductCard,
9297
+ {
9298
+ product,
9299
+ renderImage,
9300
+ renderLink,
9301
+ onQuickAdd
9302
+ },
9303
+ product.id
9304
+ )
9305
+ ) }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-16", children: [
9306
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: "No items match your search." }),
9307
+ /* @__PURE__ */ jsxRuntime.jsx(
9308
+ "button",
9309
+ {
9310
+ onClick: () => {
9311
+ setSearchQuery("");
9312
+ setActiveTag(null);
9313
+ },
9314
+ className: "text-sm font-medium text-primary mt-2 hover:underline",
9315
+ children: "Clear filters"
9316
+ }
9317
+ )
9318
+ ] })
9319
+ ] });
9320
+ }
9321
+ function FeaturedCollectionLayout({
9322
+ collection,
9323
+ products,
9324
+ renderCard,
9325
+ renderImage,
9326
+ renderLink,
9327
+ onQuickAdd,
9328
+ className
9329
+ }) {
9330
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-collection-layout": "featured", className: cn("space-y-10", className), children: [
9331
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-collection-hero": true, className: "relative overflow-hidden rounded-2xl bg-muted", children: [
9332
+ collection.image_url && /* @__PURE__ */ jsxRuntime.jsx(
9333
+ "img",
9334
+ {
9335
+ src: collection.image_url,
9336
+ alt: collection.name,
9337
+ className: "w-full h-72 lg:h-96 object-cover"
9338
+ }
9339
+ ),
9340
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/70 via-black/30 to-transparent" }),
9341
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute bottom-0 left-0 right-0 p-8 lg:p-12", children: [
9342
+ collection.tags && collection.tags.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-semibold text-white/70 uppercase tracking-widest", children: collection.tags[0] }),
9343
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl lg:text-5xl font-bold text-white tracking-tight mt-2", children: collection.name }),
9344
+ collection.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-white/80 mt-3 max-w-2xl text-base lg:text-lg leading-relaxed", children: collection.description })
9345
+ ] })
9346
+ ] }),
9347
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6", children: products.map(
9348
+ (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React3__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
9349
+ ProductCard,
9350
+ {
9351
+ product,
9352
+ renderImage,
9353
+ renderLink,
9354
+ onQuickAdd
9355
+ },
9356
+ product.id
9357
+ )
9358
+ ) })
9359
+ ] });
9360
+ }
9361
+ function CatalogueCollectionLayout({
9362
+ collection,
9363
+ products,
9364
+ renderCard,
9365
+ renderImage,
9366
+ renderLink,
9367
+ onQuickAdd,
9368
+ className
9369
+ }) {
9370
+ const [searchQuery, setSearchQuery] = React3.useState("");
9371
+ const [activeCategory, setActiveCategory] = React3.useState(null);
9372
+ const [sortBy, setSortBy] = React3.useState("default");
9373
+ const categories = React3.useMemo(() => {
9374
+ const cats = /* @__PURE__ */ new Map();
9375
+ for (const p of products) {
9376
+ if (p.category_id && p.tags) {
9377
+ for (const t of p.tags) {
9378
+ if (!cats.has(t)) cats.set(t, t);
9379
+ }
9380
+ }
9381
+ }
9382
+ return Array.from(cats.values()).slice(0, 8);
9383
+ }, [products]);
9384
+ const filtered = React3.useMemo(() => {
9385
+ let result = products;
9386
+ if (searchQuery.trim().length >= 2) {
9387
+ const q = searchQuery.toLowerCase();
9388
+ result = result.filter(
9389
+ (p) => p.name.toLowerCase().includes(q) || p.description?.toLowerCase().includes(q)
9390
+ );
9391
+ }
9392
+ if (activeCategory) {
9393
+ result = result.filter((p) => p.tags?.includes(activeCategory));
9394
+ }
9395
+ if (sortBy === "price-asc") {
9396
+ result = [...result].sort((a, b) => chunkPEDLCL72_js.parsePrice(a.default_price) - chunkPEDLCL72_js.parsePrice(b.default_price));
9397
+ } else if (sortBy === "price-desc") {
9398
+ result = [...result].sort((a, b) => chunkPEDLCL72_js.parsePrice(b.default_price) - chunkPEDLCL72_js.parsePrice(a.default_price));
9399
+ } else if (sortBy === "name") {
9400
+ result = [...result].sort((a, b) => a.name.localeCompare(b.name));
9401
+ }
9402
+ return result;
9403
+ }, [products, searchQuery, activeCategory, sortBy]);
9404
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-collection-layout": "catalogue", className: cn("space-y-6", className), children: [
9405
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
9406
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl lg:text-3xl font-bold tracking-tight", children: collection.name }),
9407
+ collection.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground mt-1 max-w-2xl", children: collection.description })
9408
+ ] }),
9409
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 pb-4 border-b border-border", children: [
9410
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 flex-1 min-w-0 w-full", children: [
9411
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 max-w-sm", children: [
9412
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
9413
+ /* @__PURE__ */ jsxRuntime.jsx(
9414
+ "input",
9415
+ {
9416
+ type: "search",
9417
+ value: searchQuery,
9418
+ onChange: (e) => setSearchQuery(e.target.value),
9419
+ placeholder: "Search...",
9420
+ className: "w-full h-9 pl-10 pr-4 text-sm border border-border rounded-lg bg-background outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary transition-colors"
9421
+ }
9422
+ )
9423
+ ] }),
9424
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5 overflow-x-auto scrollbar-hide", children: [
9425
+ /* @__PURE__ */ jsxRuntime.jsx(
9426
+ "button",
9427
+ {
9428
+ onClick: () => setActiveCategory(null),
9429
+ className: cn(
9430
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
9431
+ !activeCategory ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
9432
+ ),
9433
+ children: "All"
9434
+ }
9435
+ ),
9436
+ categories.map((cat) => /* @__PURE__ */ jsxRuntime.jsx(
9437
+ "button",
9438
+ {
9439
+ onClick: () => setActiveCategory(activeCategory === cat ? null : cat),
9440
+ className: cn(
9441
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
9442
+ activeCategory === cat ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
9443
+ ),
9444
+ children: cat
9445
+ },
9446
+ cat
9447
+ ))
9448
+ ] })
9449
+ ] }),
9450
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 shrink-0", children: [
9451
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: [
9452
+ filtered.length,
9453
+ " items"
9454
+ ] }),
9455
+ /* @__PURE__ */ jsxRuntime.jsxs(
9456
+ "select",
9457
+ {
9458
+ value: sortBy,
9459
+ onChange: (e) => setSortBy(e.target.value),
9460
+ className: "text-xs border border-border rounded-lg px-2 py-1.5 bg-background outline-none focus:ring-2 focus:ring-primary/20",
9461
+ children: [
9462
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "default", children: "Sort: Default" }),
9463
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "price-asc", children: "Price: Low to High" }),
9464
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "price-desc", children: "Price: High to Low" }),
9465
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "name", children: "Name: A-Z" })
9466
+ ]
9467
+ }
9468
+ )
9469
+ ] })
9470
+ ] }),
9471
+ filtered.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4", children: filtered.map(
9472
+ (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React3__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
9473
+ ProductCard,
9474
+ {
9475
+ product,
9476
+ renderImage,
9477
+ renderLink,
9478
+ onQuickAdd
9479
+ },
9480
+ product.id
9481
+ )
9482
+ ) }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-16", children: [
9483
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: "No products found." }),
9484
+ /* @__PURE__ */ jsxRuntime.jsx(
9485
+ "button",
9486
+ {
9487
+ onClick: () => {
9488
+ setSearchQuery("");
9489
+ setActiveCategory(null);
9490
+ },
9491
+ className: "text-sm font-medium text-primary mt-2 hover:underline",
9492
+ children: "Clear filters"
9493
+ }
9494
+ )
9495
+ ] })
9496
+ ] });
9497
+ }
9498
+ var CollectionTemplate = /* @__PURE__ */ ((CollectionTemplate2) => {
9499
+ CollectionTemplate2["Default"] = "default";
9500
+ CollectionTemplate2["Featured"] = "featured";
9501
+ CollectionTemplate2["Catalogue"] = "catalogue";
9502
+ return CollectionTemplate2;
9503
+ })(CollectionTemplate || {});
9504
+ var BUILT_IN_LAYOUTS4 = {
9505
+ ["default" /* Default */]: DefaultCollectionLayout,
9506
+ ["featured" /* Featured */]: FeaturedCollectionLayout,
9507
+ ["catalogue" /* Catalogue */]: CatalogueCollectionLayout
9508
+ };
9509
+ var LARGE_COLLECTION_THRESHOLD = 30;
9510
+ function resolveTemplateKey2(collection, productCount) {
9511
+ const metaTemplate = collection.metadata?.page_template;
9512
+ if (typeof metaTemplate === "string" && metaTemplate.trim()) {
9513
+ return metaTemplate.trim();
9514
+ }
9515
+ if (collection.tags?.includes("featured") || collection.metadata?.is_featured === true) {
9516
+ return "featured" /* Featured */;
9517
+ }
9518
+ if (productCount > LARGE_COLLECTION_THRESHOLD) {
9519
+ return "catalogue" /* Catalogue */;
9520
+ }
9521
+ return "default" /* Default */;
9522
+ }
9523
+ function resolveLayout2(collection, productCount, pages, templates) {
9524
+ if (pages?.[collection.slug]) {
9525
+ return pages[collection.slug];
9526
+ }
9527
+ const key = resolveTemplateKey2(collection, productCount);
9528
+ if (templates?.[key]) {
9529
+ return templates[key];
9530
+ }
9531
+ if (BUILT_IN_LAYOUTS4[key]) {
9532
+ return BUILT_IN_LAYOUTS4[key];
9533
+ }
9534
+ return DefaultCollectionLayout;
9535
+ }
8315
9536
  function CollectionPage({
8316
9537
  collectionId,
8317
9538
  collection: collectionProp,
8318
9539
  products: productsProp,
9540
+ pages,
9541
+ templates,
8319
9542
  renderCard,
8320
9543
  renderImage,
8321
- columns,
9544
+ renderLink,
9545
+ onQuickAdd,
8322
9546
  className,
8323
9547
  classNames
8324
9548
  }) {
9549
+ const resolvedId = collectionId || collectionProp?.slug || collectionProp?.id || "";
8325
9550
  const {
8326
9551
  collection: fetchedCollection,
8327
9552
  products: fetchedProducts,
8328
9553
  isLoading
8329
- } = useCollection(collectionProp ? null : collectionId, {
8330
- enabled: !collectionProp
9554
+ } = useCollection(collectionProp ? null : resolvedId, {
9555
+ enabled: !collectionProp && resolvedId.length > 0
8331
9556
  });
8332
9557
  const collection = collectionProp ?? fetchedCollection;
8333
9558
  const products = productsProp ?? fetchedProducts;
@@ -8337,37 +9562,35 @@ function CollectionPage({
8337
9562
  {
8338
9563
  "data-cimplify-collection-page": true,
8339
9564
  "aria-busy": "true",
8340
- className: cn(className, classNames?.root, classNames?.loading)
9565
+ className: cn(className, classNames?.root, classNames?.loading),
9566
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "animate-pulse space-y-6", children: [
9567
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-64 lg:h-80 bg-muted rounded-2xl" }),
9568
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4", children: Array.from({ length: 8 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
9569
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-square bg-muted rounded-[14px]" }),
9570
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 space-y-2", children: [
9571
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-3/4 bg-muted rounded" }),
9572
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-3 w-1/2 bg-muted rounded" })
9573
+ ] })
9574
+ ] }, i)) })
9575
+ ] })
8341
9576
  }
8342
9577
  );
8343
9578
  }
8344
9579
  if (!collection) {
8345
- return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-collection-page": true, className: cn(className, classNames?.root), children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Collection not found." }) });
9580
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-collection-page": true, className: cn(className, classNames?.root), children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: "Collection not found." }) });
8346
9581
  }
8347
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-collection-page": true, className: cn(className, classNames?.root), children: [
8348
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-collection-header": true, className: classNames?.header, children: [
8349
- collection.image_url && /* @__PURE__ */ jsxRuntime.jsx(
8350
- "img",
8351
- {
8352
- src: collection.image_url,
8353
- alt: collection.name,
8354
- "data-cimplify-collection-image": true,
8355
- className: classNames?.image
8356
- }
8357
- ),
8358
- /* @__PURE__ */ jsxRuntime.jsx("h1", { "data-cimplify-collection-title": true, className: classNames?.title, children: collection.name }),
8359
- collection.description && /* @__PURE__ */ jsxRuntime.jsx("p", { "data-cimplify-collection-description": true, className: classNames?.description, children: collection.description })
8360
- ] }),
8361
- /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-collection-grid": true, className: classNames?.grid, children: /* @__PURE__ */ jsxRuntime.jsx(
8362
- ProductGrid,
8363
- {
8364
- products,
8365
- renderCard,
8366
- renderImage,
8367
- columns
8368
- }
8369
- ) })
8370
- ] });
9582
+ const Layout = resolveLayout2(collection, products.length, pages, templates);
9583
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-collection-page": true, className: cn(className, classNames?.root), children: /* @__PURE__ */ jsxRuntime.jsx(
9584
+ Layout,
9585
+ {
9586
+ collection,
9587
+ products,
9588
+ renderCard,
9589
+ renderImage,
9590
+ renderLink,
9591
+ onQuickAdd
9592
+ }
9593
+ ) });
8371
9594
  }
8372
9595
  function OrderDetailPage({
8373
9596
  orderId,
@@ -8486,573 +9709,355 @@ function OrderHistoryPage({
8486
9709
  ) })
8487
9710
  ] });
8488
9711
  }
8489
- function SearchPage({
8490
- title = "Search",
8491
- placeholder = "What are you looking for?",
8492
- onProductClick,
9712
+ function DefaultSearchLayout({
9713
+ search,
9714
+ facets,
9715
+ categories,
9716
+ activeCategory,
9717
+ onCategoryChange,
9718
+ inStockOnly,
9719
+ onInStockChange,
9720
+ sortBy,
9721
+ onSortChange,
8493
9722
  renderCard,
8494
9723
  renderImage,
8495
- columns,
8496
- className,
8497
- classNames
9724
+ renderLink,
9725
+ onQuickAdd,
9726
+ placeholder = "Search products...",
9727
+ className
8498
9728
  }) {
8499
- const { results, isLoading, query, setQuery, clear } = useSearch();
8500
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-search-page": true, className: cn(className, classNames?.root), children: [
8501
- /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-search-page-header": true, className: classNames?.header, children: /* @__PURE__ */ jsxRuntime.jsx("h1", { "data-cimplify-search-page-title": true, className: classNames?.title, children: title }) }),
8502
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-search-page-input": true, className: classNames?.inputContainer, children: [
9729
+ const { query, setQuery, results, isLoading, clear } = search;
9730
+ const hasFacets = facets && facets.length > 0 || categories && categories.length > 0;
9731
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-search-layout": "default", className: cn("space-y-6", className), children: [
9732
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
9733
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "absolute left-4 top-1/2 -translate-y-1/2 w-5 h-5 text-muted-foreground", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
8503
9734
  /* @__PURE__ */ jsxRuntime.jsx(
8504
- input.Input,
9735
+ "input",
8505
9736
  {
8506
9737
  type: "search",
8507
9738
  value: query,
8508
9739
  onChange: (e) => setQuery(e.target.value),
8509
9740
  placeholder,
8510
- "data-cimplify-search-page-field": true,
8511
- className: classNames?.input,
8512
- "aria-label": "Search products",
9741
+ className: "w-full h-14 pl-12 pr-12 text-base border border-border rounded-xl bg-background outline-none focus:ring-2 focus:ring-primary/10 focus:border-primary/30 transition-all",
8513
9742
  autoFocus: true
8514
9743
  }
8515
9744
  ),
8516
9745
  query.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
8517
9746
  "button",
8518
9747
  {
8519
- type: "button",
8520
9748
  onClick: clear,
8521
- "data-cimplify-search-page-clear": true,
8522
- className: classNames?.clearButton,
9749
+ className: "absolute right-4 top-1/2 -translate-y-1/2 w-6 h-6 flex items-center justify-center text-muted-foreground hover:text-foreground rounded-full hover:bg-muted transition-colors",
8523
9750
  "aria-label": "Clear search",
8524
- children: "\xD7"
9751
+ children: /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", d: "M6 18L18 6M6 6l12 12" }) })
8525
9752
  }
8526
9753
  )
8527
9754
  ] }),
8528
- query.length >= 2 && !isLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-search-page-count": true, className: classNames?.resultCount, children: [
8529
- results.length,
8530
- " ",
8531
- results.length === 1 ? "result" : "results",
8532
- " for \u201C",
8533
- query,
8534
- "\u201D"
8535
- ] }),
8536
- /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-search-page-grid": true, className: classNames?.grid, children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-search-page-loading": true, "aria-busy": "true", className: classNames?.loading, children: "Searching..." }) : query.length >= 2 && results.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-search-page-empty": true, className: classNames?.empty, children: /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
8537
- "No products found for \u201C",
8538
- query,
8539
- "\u201D"
8540
- ] }) }) : results.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
8541
- ProductGrid,
8542
- {
8543
- products: results,
8544
- renderCard,
8545
- renderImage,
8546
- columns
8547
- }
8548
- ) })
8549
- ] });
8550
- }
8551
- function DealsPage({
8552
- title = "Deals & Offers",
8553
- deals: dealsProp,
8554
- productsOnSale: productsOnSaleProp,
8555
- products: productsProp,
8556
- locationId,
8557
- renderImage,
8558
- columns,
8559
- className,
8560
- classNames
8561
- }) {
8562
- const { deals: fetchedDeals, isLoading: dealsLoading } = useDeals({
8563
- locationId,
8564
- enabled: dealsProp === void 0
8565
- });
8566
- const { products: fetchedOnSale, isLoading: productsLoading } = useProductsOnSale({
8567
- enabled: productsOnSaleProp === void 0
8568
- });
8569
- const deals = dealsProp ?? fetchedDeals;
8570
- const onSale = productsOnSaleProp ?? fetchedOnSale;
8571
- const isLoading = dealsLoading || productsLoading;
8572
- const isEmpty = deals.length === 0 && onSale.length === 0;
8573
- if (isLoading && isEmpty) {
8574
- return /* @__PURE__ */ jsxRuntime.jsx(
8575
- "div",
8576
- {
8577
- "data-cimplify-deals-page": true,
8578
- "aria-busy": "true",
8579
- className: cn(className, classNames?.root, classNames?.loading)
8580
- }
8581
- );
8582
- }
8583
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-deals-page": true, className: cn(className, classNames?.root), children: [
8584
- /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-deals-header": true, className: classNames?.header, children: /* @__PURE__ */ jsxRuntime.jsx("h1", { "data-cimplify-deals-title": true, className: classNames?.title, children: title }) }),
8585
- deals.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-deals-banner-section": true, className: classNames?.bannerSection, children: /* @__PURE__ */ jsxRuntime.jsx(DealBanner, { deals }) }),
8586
- (onSale.length > 0 || productsProp && productsProp.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-deals-products": true, className: classNames?.productsSection, children: [
8587
- /* @__PURE__ */ jsxRuntime.jsx("h2", { "data-cimplify-deals-products-title": true, className: classNames?.productsTitle, children: "On Sale Now" }),
8588
- productsProp ? /* @__PURE__ */ jsxRuntime.jsx(
8589
- ProductGrid,
9755
+ query.length >= 2 && !isLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
9756
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground", children: [
9757
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground", children: results.length }),
9758
+ " result",
9759
+ results.length !== 1 ? "s" : "",
9760
+ " for ",
9761
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium text-foreground", children: [
9762
+ "\u201C",
9763
+ query,
9764
+ "\u201D"
9765
+ ] })
9766
+ ] }),
9767
+ onSortChange && /* @__PURE__ */ jsxRuntime.jsxs(
9768
+ "select",
8590
9769
  {
8591
- products: productsProp,
8592
- renderImage,
8593
- columns
9770
+ value: sortBy || "relevance",
9771
+ onChange: (e) => onSortChange(e.target.value),
9772
+ className: "text-xs border border-border rounded-lg px-2 py-1.5 bg-background outline-none focus:ring-2 focus:ring-primary/10",
9773
+ children: [
9774
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "relevance", children: "Relevance" }),
9775
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "price-asc", children: "Price: Low to High" }),
9776
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "price-desc", children: "Price: High to Low" }),
9777
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "name", children: "Name: A-Z" }),
9778
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "newest", children: "Newest" })
9779
+ ]
8594
9780
  }
8595
- ) : /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-deals-sale-list": true, children: onSale.map((dealInfo) => /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-deals-sale-item": true, children: /* @__PURE__ */ jsxRuntime.jsx(
8596
- SaleBadge,
9781
+ )
9782
+ ] }),
9783
+ categories && categories.length > 0 && onCategoryChange && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5 overflow-x-auto pb-1", children: [
9784
+ /* @__PURE__ */ jsxRuntime.jsx(
9785
+ "button",
8597
9786
  {
8598
- product: { id: dealInfo.product_id, name: dealInfo.deal_name },
8599
- dealInfo,
8600
- showOriginalPrice: true
9787
+ onClick: () => onCategoryChange(null),
9788
+ className: cn(
9789
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
9790
+ !activeCategory ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
9791
+ ),
9792
+ children: "All"
8601
9793
  }
8602
- ) }, `${dealInfo.product_id}-${dealInfo.deal_id}`)) })
9794
+ ),
9795
+ categories.map((cat) => /* @__PURE__ */ jsxRuntime.jsx(
9796
+ "button",
9797
+ {
9798
+ onClick: () => onCategoryChange(activeCategory === cat.id ? null : cat.id),
9799
+ className: cn(
9800
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
9801
+ activeCategory === cat.id ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
9802
+ ),
9803
+ children: cat.name
9804
+ },
9805
+ cat.id
9806
+ ))
8603
9807
  ] }),
8604
- isEmpty && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-deals-empty": true, className: classNames?.empty, children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: "No deals available right now. Check back soon!" }) })
8605
- ] });
8606
- }
8607
- var ANY_VALUE2 = "__any__";
8608
- function roomToResource(room) {
8609
- return {
8610
- id: room.id,
8611
- name: room.name,
8612
- capacity: room.capacity,
8613
- floor: room.floor,
8614
- is_available: room.status === "available"
8615
- };
8616
- }
8617
- function ResourcePicker({
8618
- resources,
8619
- selectedResourceId,
8620
- onResourceSelect,
8621
- showAnyOption = true,
8622
- anyLabel = "Any available",
8623
- renderImage,
8624
- className,
8625
- classNames
8626
- }) {
8627
- const groupValue = selectedResourceId === null ? ANY_VALUE2 : selectedResourceId ?? "";
8628
- return /* @__PURE__ */ jsxRuntime.jsxs(
8629
- radioGroup.RadioGroup,
8630
- {
8631
- "data-cimplify-resource-picker": true,
8632
- className: cn("flex flex-col gap-2", className, classNames?.root),
8633
- value: groupValue,
8634
- onValueChange: (value) => {
8635
- onResourceSelect?.(value === ANY_VALUE2 ? null : value);
8636
- },
8637
- children: [
8638
- showAnyOption && /* @__PURE__ */ jsxRuntime.jsx(
8639
- radio.Radio.Root,
8640
- {
8641
- value: ANY_VALUE2,
8642
- "data-cimplify-resource-option": true,
8643
- "data-selected": selectedResourceId === null || void 0,
8644
- "data-any": true,
8645
- className: cn(
8646
- "flex items-center gap-3 rounded-lg border border-border p-3 transition-colors cursor-pointer",
8647
- "hover:bg-muted data-[checked]:border-primary data-[checked]:bg-primary/5",
8648
- classNames?.option
8649
- ),
8650
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-resource-name": true, className: cn("font-medium text-foreground", classNames?.name), children: anyLabel })
8651
- }
8652
- ),
8653
- resources.map((resource) => {
8654
- const unavailable = resource.is_available === false;
8655
- return /* @__PURE__ */ jsxRuntime.jsxs(
8656
- radio.Radio.Root,
9808
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: hasFacets ? "flex gap-6" : "", children: [
9809
+ hasFacets && /* @__PURE__ */ jsxRuntime.jsxs("aside", { "data-cimplify-search-facets": true, className: "hidden lg:block w-60 shrink-0 space-y-6", children: [
9810
+ onInStockChange && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
9811
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: "In stock only" }),
9812
+ /* @__PURE__ */ jsxRuntime.jsx(
9813
+ "button",
8657
9814
  {
8658
- value: resource.id,
8659
- disabled: unavailable,
8660
- "data-cimplify-resource-option": true,
8661
- "data-selected": selectedResourceId === resource.id || void 0,
8662
- "data-unavailable": unavailable || void 0,
9815
+ onClick: () => onInStockChange(!inStockOnly),
8663
9816
  className: cn(
8664
- "flex items-center gap-3 rounded-lg border border-border p-3 transition-colors cursor-pointer",
8665
- "hover:bg-muted data-[checked]:border-primary data-[checked]:bg-primary/5",
8666
- unavailable && "opacity-50 cursor-not-allowed",
8667
- classNames?.option,
8668
- unavailable ? classNames?.unavailable : void 0
9817
+ "w-10 h-6 rounded-full transition-colors relative",
9818
+ inStockOnly ? "bg-foreground" : "bg-border"
8669
9819
  ),
8670
- children: [
8671
- resource.image_url && (renderImage ? renderImage({
8672
- src: resource.image_url,
8673
- alt: resource.name,
8674
- className: classNames?.image
8675
- }) : /* @__PURE__ */ jsxRuntime.jsx(
8676
- "img",
8677
- {
8678
- src: resource.image_url,
8679
- alt: resource.name,
8680
- "data-cimplify-resource-image": true,
8681
- className: cn("w-10 h-10 rounded-lg object-cover", classNames?.image)
8682
- }
8683
- )),
8684
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5 flex-1 min-w-0", children: [
8685
- /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-resource-name": true, className: cn("font-medium text-foreground", classNames?.name), children: resource.name }),
8686
- resource.description && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-resource-description": true, className: cn("text-sm text-muted-foreground truncate", classNames?.description), children: resource.description }),
8687
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-resource-meta": true, className: cn("flex items-center gap-2 text-xs text-muted-foreground", classNames?.meta), children: [
8688
- resource.capacity !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-resource-capacity": true, className: classNames?.capacity, children: [
8689
- "Up to ",
8690
- resource.capacity
8691
- ] }),
8692
- resource.floor && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-resource-floor": true, className: classNames?.floor, children: resource.floor })
8693
- ] })
8694
- ] })
8695
- ]
8696
- },
8697
- resource.id
8698
- );
8699
- })
8700
- ]
8701
- }
8702
- );
8703
- }
8704
- var STEP = {
8705
- SELECT_SLOT: "select-slot",
8706
- SELECT_RESOURCE: "select-resource",
8707
- SELECT_STAFF: "select-staff",
8708
- CONFIRM: "confirm"
8709
- };
8710
- function BookingPage({
8711
- service,
8712
- product,
8713
- staff,
8714
- resources,
8715
- participantCount,
8716
- title,
8717
- onBooked,
8718
- onBack,
8719
- existingBooking,
8720
- onRescheduled,
8721
- showPrice = true,
8722
- className,
8723
- classNames
8724
- }) {
8725
- const { addItem } = useCart();
8726
- const { client } = useCimplifyClient();
8727
- const isReschedule = existingBooking !== void 0;
8728
- const [step, setStep] = React3.useState(STEP.SELECT_SLOT);
8729
- const [selectedSlot, setSelectedSlot] = React3.useState(null);
8730
- const [selectedDate, setSelectedDate] = React3.useState(null);
8731
- const [selectedStaffId, setSelectedStaffId] = React3.useState(null);
8732
- const [selectedResourceId, setSelectedResourceId] = React3.useState(null);
8733
- const [isSubmitting, setIsSubmitting] = React3.useState(false);
8734
- const [error, setError] = React3.useState(null);
8735
- const hasResourceStep = resources && resources.length > 0;
8736
- const hasStaffStep = staff && staff.length > 0;
8737
- const depositType = product?.deposit_type;
8738
- const depositAmount = product?.deposit_amount;
8739
- const hasDeposit = depositType !== void 0 && depositType !== "none" && depositAmount !== void 0 && chunkPEDLCL72_js.parsePrice(depositAmount) !== 0;
8740
- const cancellationMinutes = product?.cancellation_window_minutes;
8741
- const noShowFee = product?.no_show_fee;
8742
- const handleSlotSelect = React3.useCallback(
8743
- (slot, date) => {
8744
- setSelectedSlot(slot);
8745
- setSelectedDate(date);
8746
- setError(null);
8747
- if (hasResourceStep) {
8748
- setStep(STEP.SELECT_RESOURCE);
8749
- } else if (hasStaffStep) {
8750
- setStep(STEP.SELECT_STAFF);
8751
- } else {
8752
- setStep(STEP.CONFIRM);
8753
- }
8754
- },
8755
- [hasResourceStep, hasStaffStep]
8756
- );
8757
- const handleResourceSelect = React3.useCallback(
8758
- (resourceId) => {
8759
- setSelectedResourceId(resourceId);
8760
- if (hasStaffStep) {
8761
- setStep(STEP.SELECT_STAFF);
8762
- } else {
8763
- setStep(STEP.CONFIRM);
8764
- }
8765
- },
8766
- [hasStaffStep]
8767
- );
8768
- const handleStaffSelect = React3.useCallback((staffId) => {
8769
- setSelectedStaffId(staffId);
8770
- setStep(STEP.CONFIRM);
8771
- }, []);
8772
- const handleBack = React3.useCallback(() => {
8773
- setError(null);
8774
- if (step === STEP.CONFIRM && hasStaffStep) {
8775
- setStep(STEP.SELECT_STAFF);
8776
- } else if (step === STEP.CONFIRM && hasResourceStep) {
8777
- setStep(STEP.SELECT_RESOURCE);
8778
- } else if (step === STEP.SELECT_STAFF && hasResourceStep) {
8779
- setStep(STEP.SELECT_RESOURCE);
8780
- } else if (step === STEP.CONFIRM || step === STEP.SELECT_STAFF || step === STEP.SELECT_RESOURCE) {
8781
- setStep(STEP.SELECT_SLOT);
8782
- } else {
8783
- onBack?.();
8784
- }
8785
- }, [step, hasStaffStep, hasResourceStep, onBack]);
8786
- const handleConfirm = React3.useCallback(async () => {
8787
- if (!selectedSlot || !selectedDate) return;
8788
- setIsSubmitting(true);
8789
- setError(null);
8790
- try {
8791
- if (isReschedule && existingBooking) {
8792
- const serviceItem = existingBooking.service_items[0];
8793
- const result = await client.scheduling.rescheduleBooking({
8794
- order_id: existingBooking.order_id,
8795
- line_item_id: serviceItem?.service_id ?? existingBooking.order_id,
8796
- new_start_time: selectedSlot.start_time,
8797
- new_end_time: selectedSlot.end_time,
8798
- new_staff_id: selectedStaffId || void 0,
8799
- reschedule_type: "customer"
8800
- });
8801
- if (!result.ok) {
8802
- throw result.error;
8803
- }
8804
- onRescheduled?.(existingBooking, selectedSlot);
8805
- } else {
8806
- const serviceProduct = {
8807
- id: service.product_id || service.id,
8808
- business_id: service.business_id || "",
8809
- category_id: service.category_id || void 0,
8810
- name: service.name,
8811
- slug: service.id,
8812
- description: service.description || void 0,
8813
- image_url: service.image_url || void 0,
8814
- default_price: service.price || "0",
8815
- type: "service",
8816
- inventory_type: "none",
8817
- variant_strategy: "fetch_all",
8818
- is_active: service.is_available,
8819
- created_at: (/* @__PURE__ */ new Date()).toISOString(),
8820
- updated_at: (/* @__PURE__ */ new Date()).toISOString()
8821
- };
8822
- await addItem(serviceProduct, 1, {
8823
- scheduledStart: selectedSlot.start_time,
8824
- scheduledEnd: selectedSlot.end_time,
8825
- staffId: selectedStaffId || void 0,
8826
- resourceId: selectedResourceId || void 0
8827
- });
8828
- onBooked?.(selectedSlot, selectedStaffId);
8829
- }
8830
- } catch (err) {
8831
- const fallbackMessage = isReschedule ? "Failed to reschedule booking" : "Failed to add booking to cart";
8832
- setError(err instanceof Error ? err.message : fallbackMessage);
8833
- } finally {
8834
- setIsSubmitting(false);
8835
- }
8836
- }, [selectedSlot, selectedDate, selectedStaffId, service, addItem, onBooked, isReschedule, existingBooking, client, onRescheduled]);
8837
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-page": true, className: cn(className, classNames?.root), children: [
8838
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-page-header": true, className: classNames?.header, children: [
8839
- onBack && step === STEP.SELECT_SLOT && /* @__PURE__ */ jsxRuntime.jsx(
8840
- "button",
9820
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
9821
+ "absolute top-1 w-4 h-4 rounded-full bg-background transition-transform shadow-sm",
9822
+ inStockOnly ? "left-5" : "left-1"
9823
+ ) })
9824
+ }
9825
+ )
9826
+ ] }),
9827
+ facets?.map((facet) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
9828
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-semibold mb-2", children: facet.name }),
9829
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1.5", children: facet.values.slice(0, 8).map((fv) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2 text-sm cursor-pointer group", children: [
9830
+ /* @__PURE__ */ jsxRuntime.jsx("input", { type: "checkbox", className: "w-3.5 h-3.5 accent-foreground rounded" }),
9831
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground group-hover:text-foreground transition-colors flex-1", children: fv.value }),
9832
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground/60", children: fv.count })
9833
+ ] }, fv.value)) })
9834
+ ] }, facet.slug))
9835
+ ] }),
9836
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 gap-4 animate-pulse", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
9837
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-square bg-muted rounded-[14px]" }),
9838
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 space-y-2", children: [
9839
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-3/4 bg-muted rounded" }),
9840
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-3 w-1/2 bg-muted rounded" })
9841
+ ] })
9842
+ ] }, i)) }) : query.length >= 2 && results.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-20", children: [
9843
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-12 h-12 mx-auto text-muted-foreground/30", fill: "none", stroke: "currentColor", strokeWidth: "1", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
9844
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-lg font-medium mt-4", children: [
9845
+ "No results for \u201C",
9846
+ query,
9847
+ "\u201D"
9848
+ ] }),
9849
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Try a different search term" }),
9850
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: clear, className: "text-sm font-medium text-primary mt-4 hover:underline", children: "Clear search" })
9851
+ ] }) : results.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 gap-4", children: results.map(
9852
+ (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React3__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
9853
+ ProductCard,
9854
+ {
9855
+ product,
9856
+ renderImage,
9857
+ renderLink,
9858
+ onQuickAdd
9859
+ },
9860
+ product.id
9861
+ )
9862
+ ) }) : null })
9863
+ ] })
9864
+ ] });
9865
+ }
9866
+ function CompactSearchLayout({
9867
+ search,
9868
+ categories,
9869
+ activeCategory,
9870
+ onCategoryChange,
9871
+ renderCard,
9872
+ renderImage,
9873
+ renderLink,
9874
+ onQuickAdd,
9875
+ placeholder = "Search menu...",
9876
+ className
9877
+ }) {
9878
+ const { query, setQuery, results, isLoading, clear } = search;
9879
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-search-layout": "compact", className: cn("space-y-6", className), children: [
9880
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
9881
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "absolute left-4 top-1/2 -translate-y-1/2 w-5 h-5 text-muted-foreground", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
9882
+ /* @__PURE__ */ jsxRuntime.jsx(
9883
+ "input",
8841
9884
  {
8842
- type: "button",
8843
- onClick: onBack,
8844
- "data-cimplify-booking-page-back": true,
8845
- className: classNames?.backButton,
8846
- children: "Back"
9885
+ type: "search",
9886
+ value: query,
9887
+ onChange: (e) => setQuery(e.target.value),
9888
+ placeholder,
9889
+ className: "w-full h-12 pl-12 pr-12 text-base border border-border rounded-xl bg-background outline-none focus:ring-2 focus:ring-primary/10 focus:border-primary/30 transition-all",
9890
+ autoFocus: true
8847
9891
  }
8848
9892
  ),
8849
- step !== STEP.SELECT_SLOT && /* @__PURE__ */ jsxRuntime.jsx(
9893
+ query.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
8850
9894
  "button",
8851
9895
  {
8852
- type: "button",
8853
- onClick: handleBack,
8854
- "data-cimplify-booking-page-back": true,
8855
- className: classNames?.backButton,
8856
- children: "Back"
8857
- }
8858
- ),
8859
- /* @__PURE__ */ jsxRuntime.jsx("h1", { "data-cimplify-booking-page-title": true, className: classNames?.title, children: title || (isReschedule ? "Reschedule Booking" : `Book ${service.name}`) })
8860
- ] }),
8861
- isReschedule && existingBooking && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-booking-reschedule-info": true, className: classNames?.rescheduleInfo, children: /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
8862
- "Rescheduling booking from ",
8863
- new Date(existingBooking.service_items[0]?.scheduled_start ?? existingBooking.created_at).toLocaleDateString()
8864
- ] }) }),
8865
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-service-info": true, className: classNames?.serviceInfo, children: [
8866
- /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-booking-service-name": true, children: service.name }),
8867
- /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-booking-service-duration": true, children: formatDuration2(service.duration_minutes, service.duration_unit) }),
8868
- service.price && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-booking-service-price": true, children: /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: service.price }) }),
8869
- hasDeposit && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-booking-deposit-info": true, className: classNames?.depositInfo, children: [
8870
- "Deposit: ",
8871
- depositType === "percentage" ? `${chunkPEDLCL72_js.parsePrice(depositAmount)}%` : /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: depositAmount })
8872
- ] }),
8873
- cancellationMinutes !== void 0 && cancellationMinutes > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-booking-cancellation-policy": true, className: classNames?.cancellationPolicy, children: [
8874
- "Free cancellation up to ",
8875
- cancellationMinutes >= 60 ? `${Math.floor(cancellationMinutes / 60)} hour${Math.floor(cancellationMinutes / 60) !== 1 ? "s" : ""}` : `${cancellationMinutes} minute${cancellationMinutes !== 1 ? "s" : ""}`,
8876
- " before"
8877
- ] }),
8878
- noShowFee !== void 0 && chunkPEDLCL72_js.parsePrice(noShowFee) !== 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-booking-no-show-fee": true, className: classNames?.cancellationPolicy, children: [
8879
- "No-show fee: ",
8880
- /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: noShowFee })
8881
- ] })
8882
- ] }),
8883
- error && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-booking-error": true, className: classNames?.error, children: error }),
8884
- step === STEP.SELECT_SLOT && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-step": "select-slot", className: classNames?.step, children: [
8885
- /* @__PURE__ */ jsxRuntime.jsx("h2", { "data-cimplify-booking-step-title": true, className: classNames?.stepTitle, children: "Select a date & time" }),
8886
- /* @__PURE__ */ jsxRuntime.jsx(
8887
- DateSlotPicker,
8888
- {
8889
- serviceId: service.id,
8890
- participantCount,
8891
- selectedSlot,
8892
- onSlotSelect: handleSlotSelect,
8893
- showPrice
9896
+ onClick: clear,
9897
+ className: "absolute right-4 top-1/2 -translate-y-1/2 w-6 h-6 flex items-center justify-center text-muted-foreground hover:text-foreground rounded-full hover:bg-muted transition-colors",
9898
+ "aria-label": "Clear search",
9899
+ children: /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", d: "M6 18L18 6M6 6l12 12" }) })
8894
9900
  }
8895
9901
  )
8896
9902
  ] }),
8897
- step === STEP.SELECT_RESOURCE && resources && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-step": "select-resource", className: cn(classNames?.step, classNames?.resourceStep), children: [
8898
- /* @__PURE__ */ jsxRuntime.jsx("h2", { "data-cimplify-booking-step-title": true, className: classNames?.stepTitle, children: "Choose a room" }),
9903
+ categories && categories.length > 0 && onCategoryChange && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5 overflow-x-auto pb-1", children: [
8899
9904
  /* @__PURE__ */ jsxRuntime.jsx(
8900
- ResourcePicker,
9905
+ "button",
8901
9906
  {
8902
- resources,
8903
- selectedResourceId,
8904
- onResourceSelect: handleResourceSelect
9907
+ onClick: () => onCategoryChange(null),
9908
+ className: cn(
9909
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
9910
+ !activeCategory ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
9911
+ ),
9912
+ children: "All"
8905
9913
  }
8906
- )
8907
- ] }),
8908
- step === STEP.SELECT_STAFF && staff && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-step": "select-staff", className: classNames?.step, children: [
8909
- /* @__PURE__ */ jsxRuntime.jsx("h2", { "data-cimplify-booking-step-title": true, className: classNames?.stepTitle, children: "Choose a provider" }),
8910
- /* @__PURE__ */ jsxRuntime.jsx(
8911
- StaffPicker,
9914
+ ),
9915
+ categories.map((cat) => /* @__PURE__ */ jsxRuntime.jsx(
9916
+ "button",
8912
9917
  {
8913
- staff,
8914
- selectedStaffId,
8915
- onStaffSelect: handleStaffSelect
8916
- }
8917
- )
9918
+ onClick: () => onCategoryChange(activeCategory === cat.id ? null : cat.id),
9919
+ className: cn(
9920
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
9921
+ activeCategory === cat.id ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
9922
+ ),
9923
+ children: cat.name
9924
+ },
9925
+ cat.id
9926
+ ))
8918
9927
  ] }),
8919
- step === STEP.CONFIRM && selectedSlot && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-step": "confirm", className: classNames?.step, children: [
8920
- /* @__PURE__ */ jsxRuntime.jsx("h2", { "data-cimplify-booking-step-title": true, className: classNames?.stepTitle, children: "Confirm your booking" }),
8921
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary": true, className: classNames?.summary, children: [
8922
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
8923
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Service" }),
8924
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: service.name })
8925
- ] }),
8926
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
8927
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Date" }),
8928
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: selectedDate })
8929
- ] }),
8930
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
8931
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Time" }),
8932
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: new Date(selectedSlot.start_time).toLocaleTimeString(void 0, {
8933
- hour: "numeric",
8934
- minute: "2-digit"
8935
- }) })
8936
- ] }),
8937
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
8938
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Duration" }),
8939
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatDuration2(service.duration_minutes, service.duration_unit) })
8940
- ] }),
8941
- selectedResourceId && resources && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
8942
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Room" }),
8943
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: resources.find((r) => r.id === selectedResourceId)?.name ?? "Selected" })
8944
- ] }),
8945
- selectedStaffId && staff && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
8946
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Provider" }),
8947
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: staff.find((s) => s.id === selectedStaffId)?.name ?? "Selected" })
8948
- ] }),
8949
- (selectedSlot.price || service.price) && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
8950
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Price" }),
8951
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: selectedSlot.price || service.price }) })
8952
- ] }),
8953
- hasDeposit && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary-row": true, className: cn(classNames?.summaryRow, classNames?.depositInfo), children: [
8954
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Deposit" }),
8955
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: depositType === "percentage" ? `${chunkPEDLCL72_js.parsePrice(depositAmount)}%` : /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: depositAmount }) })
8956
- ] })
9928
+ query.length >= 2 && !isLoading && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground", children: [
9929
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground", children: results.length }),
9930
+ " result",
9931
+ results.length !== 1 ? "s" : "",
9932
+ " for ",
9933
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium text-foreground", children: [
9934
+ "\u201C",
9935
+ query,
9936
+ "\u201D"
9937
+ ] })
9938
+ ] }),
9939
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-5 animate-pulse", children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
9940
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-square bg-muted rounded-[14px]" }),
9941
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 space-y-2", children: [
9942
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-3/4 bg-muted rounded" }),
9943
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-3 w-1/2 bg-muted rounded" })
9944
+ ] })
9945
+ ] }, i)) }) : query.length >= 2 && results.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-16", children: [
9946
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-lg font-medium", children: [
9947
+ "No results for \u201C",
9948
+ query,
9949
+ "\u201D"
8957
9950
  ] }),
8958
- /* @__PURE__ */ jsxRuntime.jsx(
8959
- "button",
9951
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Try a different search term" }),
9952
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: clear, className: "text-sm font-medium text-primary mt-4 hover:underline", children: "Clear search" })
9953
+ ] }) : results.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 lg:grid-cols-3 gap-5", children: results.map(
9954
+ (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React3__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
9955
+ ProductCard,
8960
9956
  {
8961
- type: "button",
8962
- onClick: handleConfirm,
8963
- disabled: isSubmitting,
8964
- "data-cimplify-booking-confirm": true,
8965
- className: classNames?.confirmButton,
8966
- children: isSubmitting ? isReschedule ? "Rescheduling\u2026" : "Adding to cart\u2026" : isReschedule ? "Reschedule" : "Confirm Booking"
8967
- }
9957
+ product,
9958
+ renderImage,
9959
+ renderLink,
9960
+ onQuickAdd
9961
+ },
9962
+ product.id
8968
9963
  )
8969
- ] })
9964
+ ) }) : null
8970
9965
  ] });
8971
9966
  }
8972
- var BOOKING_FILTERS = [
8973
- { label: "All", value: "all" },
8974
- { label: "Upcoming", value: "upcoming" },
8975
- { label: "Past", value: "past" }
8976
- ];
8977
- function BookingsPage({
8978
- title = "My Bookings",
8979
- bookings: bookingsProp,
8980
- onBookingNavigate,
8981
- onCancel,
8982
- onReschedule,
8983
- showFilters = true,
8984
- renderBooking,
9967
+ var SearchTemplate = /* @__PURE__ */ ((SearchTemplate2) => {
9968
+ SearchTemplate2["Default"] = "default";
9969
+ SearchTemplate2["Compact"] = "compact";
9970
+ return SearchTemplate2;
9971
+ })(SearchTemplate || {});
9972
+ var BUILT_IN_LAYOUTS5 = {
9973
+ ["default" /* Default */]: DefaultSearchLayout,
9974
+ ["compact" /* Compact */]: CompactSearchLayout
9975
+ };
9976
+ function SearchPage({
9977
+ template,
9978
+ layouts,
9979
+ categories,
9980
+ facets,
9981
+ searchOptions,
9982
+ placeholder,
9983
+ renderCard,
9984
+ renderImage,
9985
+ renderLink,
9986
+ onQuickAdd,
8985
9987
  className,
8986
9988
  classNames
8987
9989
  }) {
8988
- const [filter, setFilter] = React3.useState("all");
8989
- const [selectedBooking, setSelectedBooking] = React3.useState(null);
8990
- const handleBookingClick = React3.useCallback(
8991
- (booking) => {
8992
- if (onBookingNavigate) {
8993
- onBookingNavigate(booking);
8994
- } else {
8995
- setSelectedBooking(booking);
9990
+ const search = useSearch(searchOptions);
9991
+ const key = template ?? "default" /* Default */;
9992
+ const Layout = layouts?.[key] ?? BUILT_IN_LAYOUTS5[key] ?? DefaultSearchLayout;
9993
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-search-page": true, className: cn(className, classNames?.root), children: /* @__PURE__ */ jsxRuntime.jsx(
9994
+ Layout,
9995
+ {
9996
+ search,
9997
+ facets,
9998
+ categories,
9999
+ renderCard,
10000
+ renderImage,
10001
+ renderLink,
10002
+ onQuickAdd,
10003
+ placeholder
10004
+ }
10005
+ ) });
10006
+ }
10007
+ function DealsPage({
10008
+ title = "Deals & Offers",
10009
+ deals: dealsProp,
10010
+ productsOnSale: productsOnSaleProp,
10011
+ products: productsProp,
10012
+ locationId,
10013
+ renderImage,
10014
+ columns,
10015
+ className,
10016
+ classNames
10017
+ }) {
10018
+ const { deals: fetchedDeals, isLoading: dealsLoading } = useDeals({
10019
+ locationId,
10020
+ enabled: dealsProp === void 0
10021
+ });
10022
+ const { products: fetchedOnSale, isLoading: productsLoading } = useProductsOnSale({
10023
+ enabled: productsOnSaleProp === void 0
10024
+ });
10025
+ const deals = dealsProp ?? fetchedDeals;
10026
+ const onSale = productsOnSaleProp ?? fetchedOnSale;
10027
+ const isLoading = dealsLoading || productsLoading;
10028
+ const isEmpty = deals.length === 0 && onSale.length === 0;
10029
+ if (isLoading && isEmpty) {
10030
+ return /* @__PURE__ */ jsxRuntime.jsx(
10031
+ "div",
10032
+ {
10033
+ "data-cimplify-deals-page": true,
10034
+ "aria-busy": "true",
10035
+ className: cn(className, classNames?.root, classNames?.loading)
8996
10036
  }
8997
- },
8998
- [onBookingNavigate]
8999
- );
9000
- const handleBack = React3.useCallback(() => {
9001
- setSelectedBooking(null);
9002
- }, []);
9003
- if (selectedBooking && !onBookingNavigate) {
9004
- return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-bookings-page": true, className: cn(className, classNames?.root), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-bookings-detail": true, className: classNames?.detail, children: [
9005
- /* @__PURE__ */ jsxRuntime.jsx(
9006
- "button",
10037
+ );
10038
+ }
10039
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-deals-page": true, className: cn(className, classNames?.root), children: [
10040
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-deals-header": true, className: classNames?.header, children: /* @__PURE__ */ jsxRuntime.jsx("h1", { "data-cimplify-deals-title": true, className: classNames?.title, children: title }) }),
10041
+ deals.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-deals-banner-section": true, className: classNames?.bannerSection, children: /* @__PURE__ */ jsxRuntime.jsx(DealBanner, { deals }) }),
10042
+ (onSale.length > 0 || productsProp && productsProp.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-deals-products": true, className: classNames?.productsSection, children: [
10043
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { "data-cimplify-deals-products-title": true, className: classNames?.productsTitle, children: "On Sale Now" }),
10044
+ productsProp ? /* @__PURE__ */ jsxRuntime.jsx(
10045
+ ProductGrid,
9007
10046
  {
9008
- type: "button",
9009
- onClick: handleBack,
9010
- "data-cimplify-bookings-back": true,
9011
- className: classNames?.backButton,
9012
- children: "Back to bookings"
10047
+ products: productsProp,
10048
+ renderImage,
10049
+ columns
9013
10050
  }
9014
- ),
9015
- /* @__PURE__ */ jsxRuntime.jsx(
9016
- BookingCard,
10051
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-deals-sale-list": true, children: onSale.map((dealInfo) => /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-deals-sale-item": true, children: /* @__PURE__ */ jsxRuntime.jsx(
10052
+ SaleBadge,
9017
10053
  {
9018
- booking: selectedBooking,
9019
- onCancel,
9020
- onReschedule
10054
+ product: { id: dealInfo.product_id, name: dealInfo.deal_name },
10055
+ dealInfo,
10056
+ showOriginalPrice: true
9021
10057
  }
9022
- )
9023
- ] }) });
9024
- }
9025
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-bookings-page": true, className: cn(className, classNames?.root), children: [
9026
- /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-bookings-header": true, className: classNames?.header, children: /* @__PURE__ */ jsxRuntime.jsx("h1", { "data-cimplify-bookings-title": true, className: classNames?.title, children: title }) }),
9027
- showFilters && /* @__PURE__ */ jsxRuntime.jsx(
9028
- tabs.Tabs.Root,
9029
- {
9030
- value: filter,
9031
- onValueChange: (value) => setFilter(value),
9032
- children: /* @__PURE__ */ jsxRuntime.jsx(tabs.Tabs.List, { "data-cimplify-bookings-filters": true, className: classNames?.filters, children: BOOKING_FILTERS.map((f) => /* @__PURE__ */ jsxRuntime.jsx(
9033
- tabs.Tabs.Tab,
9034
- {
9035
- value: f.value,
9036
- "data-cimplify-booking-filter": true,
9037
- "data-selected": filter === f.value || void 0,
9038
- className: classNames?.filterButton,
9039
- children: f.label
9040
- },
9041
- f.value
9042
- )) })
9043
- }
9044
- ),
9045
- /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-bookings-list": true, className: classNames?.list, children: /* @__PURE__ */ jsxRuntime.jsx(
9046
- BookingList,
9047
- {
9048
- bookings: bookingsProp,
9049
- filter,
9050
- onCancel,
9051
- onReschedule,
9052
- onBookingClick: handleBookingClick,
9053
- renderBooking
9054
- }
9055
- ) })
10058
+ ) }, `${dealInfo.product_id}-${dealInfo.deal_id}`)) })
10059
+ ] }),
10060
+ isEmpty && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-deals-empty": true, className: classNames?.empty, children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: "No deals available right now. Check back soon!" }) })
9056
10061
  ] });
9057
10062
  }
9058
10063
  function LocationPicker({
@@ -9413,11 +10418,109 @@ function CurrencySelector({
9413
10418
  );
9414
10419
  }) });
9415
10420
  }
10421
+ var ANY_VALUE2 = "__any__";
10422
+ function roomToResource(room) {
10423
+ return {
10424
+ id: room.id,
10425
+ name: room.name,
10426
+ capacity: room.capacity,
10427
+ floor: room.floor,
10428
+ is_available: room.status === "available"
10429
+ };
10430
+ }
10431
+ function ResourcePicker({
10432
+ resources,
10433
+ selectedResourceId,
10434
+ onResourceSelect,
10435
+ showAnyOption = true,
10436
+ anyLabel = "Any available",
10437
+ renderImage,
10438
+ className,
10439
+ classNames
10440
+ }) {
10441
+ const groupValue = selectedResourceId === null ? ANY_VALUE2 : selectedResourceId ?? "";
10442
+ return /* @__PURE__ */ jsxRuntime.jsxs(
10443
+ radioGroup.RadioGroup,
10444
+ {
10445
+ "data-cimplify-resource-picker": true,
10446
+ className: cn("flex flex-col gap-2", className, classNames?.root),
10447
+ value: groupValue,
10448
+ onValueChange: (value) => {
10449
+ onResourceSelect?.(value === ANY_VALUE2 ? null : value);
10450
+ },
10451
+ children: [
10452
+ showAnyOption && /* @__PURE__ */ jsxRuntime.jsx(
10453
+ radio.Radio.Root,
10454
+ {
10455
+ value: ANY_VALUE2,
10456
+ "data-cimplify-resource-option": true,
10457
+ "data-selected": selectedResourceId === null || void 0,
10458
+ "data-any": true,
10459
+ className: cn(
10460
+ "flex items-center gap-3 rounded-lg border border-border p-3 transition-colors cursor-pointer",
10461
+ "hover:bg-muted data-[checked]:border-primary data-[checked]:bg-primary/5",
10462
+ classNames?.option
10463
+ ),
10464
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-resource-name": true, className: cn("font-medium text-foreground", classNames?.name), children: anyLabel })
10465
+ }
10466
+ ),
10467
+ resources.map((resource) => {
10468
+ const unavailable = resource.is_available === false;
10469
+ return /* @__PURE__ */ jsxRuntime.jsxs(
10470
+ radio.Radio.Root,
10471
+ {
10472
+ value: resource.id,
10473
+ disabled: unavailable,
10474
+ "data-cimplify-resource-option": true,
10475
+ "data-selected": selectedResourceId === resource.id || void 0,
10476
+ "data-unavailable": unavailable || void 0,
10477
+ className: cn(
10478
+ "flex items-center gap-3 rounded-lg border border-border p-3 transition-colors cursor-pointer",
10479
+ "hover:bg-muted data-[checked]:border-primary data-[checked]:bg-primary/5",
10480
+ unavailable && "opacity-50 cursor-not-allowed",
10481
+ classNames?.option,
10482
+ unavailable ? classNames?.unavailable : void 0
10483
+ ),
10484
+ children: [
10485
+ resource.image_url && (renderImage ? renderImage({
10486
+ src: resource.image_url,
10487
+ alt: resource.name,
10488
+ className: classNames?.image
10489
+ }) : /* @__PURE__ */ jsxRuntime.jsx(
10490
+ "img",
10491
+ {
10492
+ src: resource.image_url,
10493
+ alt: resource.name,
10494
+ "data-cimplify-resource-image": true,
10495
+ className: cn("w-10 h-10 rounded-lg object-cover", classNames?.image)
10496
+ }
10497
+ )),
10498
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5 flex-1 min-w-0", children: [
10499
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-resource-name": true, className: cn("font-medium text-foreground", classNames?.name), children: resource.name }),
10500
+ resource.description && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-resource-description": true, className: cn("text-sm text-muted-foreground truncate", classNames?.description), children: resource.description }),
10501
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-resource-meta": true, className: cn("flex items-center gap-2 text-xs text-muted-foreground", classNames?.meta), children: [
10502
+ resource.capacity !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-resource-capacity": true, className: classNames?.capacity, children: [
10503
+ "Up to ",
10504
+ resource.capacity
10505
+ ] }),
10506
+ resource.floor && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-resource-floor": true, className: classNames?.floor, children: resource.floor })
10507
+ ] })
10508
+ ] })
10509
+ ]
10510
+ },
10511
+ resource.id
10512
+ );
10513
+ })
10514
+ ]
10515
+ }
10516
+ );
10517
+ }
9416
10518
 
9417
10519
  Object.defineProperty(exports, "getVariantDisplayName", {
9418
10520
  enumerable: true,
9419
- get: function () { return chunkIYQGGFVQ_js.getVariantDisplayName; }
10521
+ get: function () { return chunkWMQXSDRC_js.getVariantDisplayName; }
9420
10522
  });
10523
+ exports.AccommodationCard = AccommodationCard;
9421
10524
  exports.Ad = Ad;
9422
10525
  exports.AdProvider = AdProvider;
9423
10526
  exports.AddOnSelector = AddOnSelector;
@@ -9427,31 +10530,48 @@ exports.AvailabilityBadge = AvailabilityBadge;
9427
10530
  exports.BillingPlanSelector = BillingPlanSelector;
9428
10531
  exports.BookingCard = BookingCard;
9429
10532
  exports.BookingList = BookingList;
9430
- exports.BookingPage = BookingPage;
9431
- exports.BookingsPage = BookingsPage;
9432
10533
  exports.BundleSelector = BundleSelector;
10534
+ exports.CardImage = CardImage;
10535
+ exports.CardShell = CardShell;
10536
+ exports.CardVariant = CardVariant;
9433
10537
  exports.CartPage = CartPage;
9434
10538
  exports.CartSummary = CartSummary;
10539
+ exports.CartTemplate = CartTemplate;
10540
+ exports.CatalogueCollectionLayout = CatalogueCollectionLayout;
9435
10541
  exports.CataloguePage = CataloguePage;
10542
+ exports.CatalogueTemplate = CatalogueTemplate;
9436
10543
  exports.CategoryFilter = CategoryFilter;
9437
10544
  exports.CategoryGrid = CategoryGrid;
9438
10545
  exports.CheckoutPage = CheckoutPage;
9439
10546
  exports.CimplifyCheckout = CimplifyCheckout;
9440
10547
  exports.CimplifyProvider = CimplifyProvider;
9441
10548
  exports.CollectionPage = CollectionPage;
10549
+ exports.CollectionTemplate = CollectionTemplate;
10550
+ exports.CompactCartLayout = CompactCartLayout;
10551
+ exports.CompactCatalogueLayout = CompactCatalogueLayout;
10552
+ exports.CompactSearchLayout = CompactSearchLayout;
10553
+ exports.CompactServiceCard = CompactServiceCard;
9442
10554
  exports.CompositeSelector = CompositeSelector;
9443
10555
  exports.CurrencySelector = CurrencySelector;
9444
10556
  exports.CustomAttributesTable = CustomAttributesTable;
9445
10557
  exports.DateSlotPicker = DateSlotPicker;
9446
10558
  exports.DealBanner = DealBanner;
9447
10559
  exports.DealsPage = DealsPage;
10560
+ exports.DefaultCartLayout = DefaultCartLayout;
10561
+ exports.DefaultCatalogueLayout = DefaultCatalogueLayout;
10562
+ exports.DefaultCollectionLayout = DefaultCollectionLayout;
9448
10563
  exports.DefaultProductLayout = DefaultProductLayout;
10564
+ exports.DefaultSearchLayout = DefaultSearchLayout;
9449
10565
  exports.DeliveryEstimate = DeliveryEstimate;
10566
+ exports.DigitalProductCard = DigitalProductCard;
9450
10567
  exports.DigitalProductLayout = DigitalProductLayout;
9451
10568
  exports.DiscountInput = DiscountInput;
9452
10569
  exports.ElementsProvider = ElementsProvider;
10570
+ exports.FeaturedCollectionLayout = FeaturedCollectionLayout;
10571
+ exports.FoodProductCard = FoodProductCard;
9453
10572
  exports.FoodProductLayout = FoodProductLayout;
9454
10573
  exports.InventoryBadge = InventoryBadge;
10574
+ exports.LeaseServiceCard = LeaseServiceCard;
9455
10575
  exports.LocationPicker = LocationPicker;
9456
10576
  exports.MetadataStringList = MetadataStringList;
9457
10577
  exports.OrderDetailPage = OrderDetailPage;
@@ -9470,25 +10590,33 @@ exports.ProductSheet = ProductSheet;
9470
10590
  exports.ProductTemplate = ProductTemplate;
9471
10591
  exports.PropertiesTable = PropertiesTable;
9472
10592
  exports.QuantitySelector = QuantitySelector;
10593
+ exports.QuickAddButton = QuickAddButton;
9473
10594
  exports.RecentlyViewed = RecentlyViewed;
9474
10595
  exports.RecommendationCarousel = RecommendationCarousel;
9475
10596
  exports.RelatedProductsSection = RelatedProductsSection;
10597
+ exports.RentalServiceCard = RentalServiceCard;
9476
10598
  exports.ResourcePicker = ResourcePicker;
10599
+ exports.RetailProductCard = RetailProductCard;
9477
10600
  exports.SaleBadge = SaleBadge;
10601
+ exports.ScheduleServiceCard = ScheduleServiceCard;
9478
10602
  exports.SearchInput = SearchInput;
9479
10603
  exports.SearchPage = SearchPage;
9480
- exports.ServiceCard = ServiceCard;
9481
- exports.ServiceGrid = ServiceGrid;
10604
+ exports.SearchTemplate = SearchTemplate;
9482
10605
  exports.ServiceProductLayout = ServiceProductLayout;
9483
10606
  exports.SessionMessageBanner = SessionMessageBanner;
9484
10607
  exports.SlotPicker = SlotPicker;
10608
+ exports.SoldOutOverlay = SoldOutOverlay;
9485
10609
  exports.StaffPicker = StaffPicker;
10610
+ exports.StandardServiceCard = StandardServiceCard;
9486
10611
  exports.StoreNav = StoreNav;
10612
+ exports.SubscriptionCard = SubscriptionCard;
9487
10613
  exports.TagPills = TagPills;
9488
10614
  exports.TwoColumnGrid = TwoColumnGrid;
9489
10615
  exports.VariantSelector = VariantSelector;
9490
10616
  exports.VolumePricing = VolumePricing;
10617
+ exports.WholesaleProductCard = WholesaleProductCard;
9491
10618
  exports.WholesaleProductLayout = WholesaleProductLayout;
10619
+ exports.WishlistButton = WishlistButton;
9492
10620
  exports.cn = cn;
9493
10621
  exports.roomToResource = roomToResource;
9494
10622
  exports.useActivityState = useActivityState;