@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.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  "use client";
2
- import { getVariantDisplayName, createCimplifyClient } from './chunk-H34GSEGR.mjs';
3
- export { getVariantDisplayName } from './chunk-H34GSEGR.mjs';
2
+ import { DURATION_UNIT, getVariantDisplayName, PRODUCT_TYPE, createCimplifyClient, RENDER_HINT } from './chunk-JMNMSVDQ.mjs';
3
+ export { getVariantDisplayName } from './chunk-JMNMSVDQ.mjs';
4
4
  import { ELEMENT_TYPES, EVENT_TYPES } from './chunk-TBZLJPM4.mjs';
5
5
  import { isSupportedCurrency, formatPrice, parsePrice, getUnitPriceAtQuantity, isOnSale, getDiscountPercentage, getBasePrice, getPriceRange, formatPriceRange } from './chunk-E3HC2YAE.mjs';
6
6
  import React3, { createContext, useRef, useState, useCallback, useEffect, useContext, useMemo, useSyncExternalStore, useId } from 'react';
@@ -5493,19 +5493,832 @@ function ProductSheet({
5493
5493
  }
5494
5494
  );
5495
5495
  }
5496
+ function CardImage({
5497
+ src,
5498
+ alt,
5499
+ aspectRatio = "square",
5500
+ renderImage,
5501
+ className,
5502
+ children
5503
+ }) {
5504
+ const aspectClass = {
5505
+ square: "aspect-square",
5506
+ "3/4": "aspect-[3/4]",
5507
+ "4/3": "aspect-[4/3]",
5508
+ "16/9": "aspect-[16/9]"
5509
+ }[aspectRatio];
5510
+ return /* @__PURE__ */ jsxs("div", { "data-cimplify-card-image": true, className: cn("relative overflow-hidden bg-muted", aspectClass, className), children: [
5511
+ renderImage ? renderImage({ src, alt, className: "w-full h-full object-cover transition-transform duration-700 ease-out group-hover:scale-[1.04]" }) : /* @__PURE__ */ jsx(
5512
+ "img",
5513
+ {
5514
+ src,
5515
+ alt,
5516
+ className: "w-full h-full object-cover transition-transform duration-700 ease-out group-hover:scale-[1.04]"
5517
+ }
5518
+ ),
5519
+ children
5520
+ ] });
5521
+ }
5522
+ function QuickAddButton({
5523
+ onClick,
5524
+ className
5525
+ }) {
5526
+ return /* @__PURE__ */ jsx(
5527
+ "button",
5528
+ {
5529
+ "data-cimplify-card-quick-add": true,
5530
+ onClick: (e) => {
5531
+ e.stopPropagation();
5532
+ onClick?.();
5533
+ },
5534
+ className: cn(
5535
+ "w-9 h-9 rounded-full bg-background text-foreground flex items-center justify-center",
5536
+ "shadow-[0_1px_4px_rgba(0,0,0,0.10),0_4px_12px_rgba(0,0,0,0.08)]",
5537
+ "transition-all duration-200 ease-out",
5538
+ "opacity-0 group-hover:opacity-100 translate-y-1 group-hover:translate-y-0",
5539
+ "hover:!bg-foreground hover:!text-background hover:!scale-110",
5540
+ className
5541
+ ),
5542
+ children: /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: [
5543
+ /* @__PURE__ */ jsx("line", { x1: "8", y1: "3", x2: "8", y2: "13" }),
5544
+ /* @__PURE__ */ jsx("line", { x1: "3", y1: "8", x2: "13", y2: "8" })
5545
+ ] })
5546
+ }
5547
+ );
5548
+ }
5549
+ function WishlistButton({
5550
+ filled = false,
5551
+ onClick,
5552
+ className
5553
+ }) {
5554
+ return /* @__PURE__ */ jsx(
5555
+ "button",
5556
+ {
5557
+ "data-cimplify-card-wishlist": true,
5558
+ onClick: (e) => {
5559
+ e.stopPropagation();
5560
+ onClick?.();
5561
+ },
5562
+ className: cn(
5563
+ "w-8 h-8 rounded-full bg-background/90 backdrop-blur flex items-center justify-center",
5564
+ "transition-all duration-200 ease-out hover:scale-110 hover:bg-background",
5565
+ filled ? "text-destructive" : "text-muted-foreground hover:text-destructive",
5566
+ className
5567
+ ),
5568
+ children: /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: filled ? "currentColor" : "none", stroke: "currentColor", strokeWidth: "1.5", viewBox: "0 0 24 24", children: /* @__PURE__ */ 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" }) })
5569
+ }
5570
+ );
5571
+ }
5572
+ function SoldOutOverlay() {
5573
+ return /* @__PURE__ */ jsx(
5574
+ "div",
5575
+ {
5576
+ "data-cimplify-card-sold-out": true,
5577
+ className: "absolute inset-0 bg-background/50 backdrop-blur-[1px] flex items-center justify-center z-10 rounded-[inherit]",
5578
+ children: /* @__PURE__ */ jsx("span", { className: "bg-background/90 text-foreground text-xs font-bold px-4 py-2 uppercase tracking-wider", children: "Sold Out" })
5579
+ }
5580
+ );
5581
+ }
5582
+ function SaleBadge2({ product }) {
5583
+ if (!isOnSale(product)) return null;
5584
+ const pct = getDiscountPercentage(product);
5585
+ if (!pct || pct <= 0) return null;
5586
+ return /* @__PURE__ */ 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: [
5587
+ "-",
5588
+ pct,
5589
+ "%"
5590
+ ] });
5591
+ }
5592
+ function CardShell({
5593
+ product,
5594
+ renderLink,
5595
+ disabled = false,
5596
+ className,
5597
+ children
5598
+ }) {
5599
+ const href = `/products/${product.slug}`;
5600
+ const shellClass = cn(
5601
+ "group block text-left cursor-pointer bg-card rounded-[14px] overflow-hidden",
5602
+ "shadow-[0_1px_3px_rgba(0,0,0,0.04),0_6px_24px_rgba(0,0,0,0.06)]",
5603
+ "transition-all duration-300 ease-[cubic-bezier(0.19,1,0.22,1)]",
5604
+ !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)]",
5605
+ disabled && "opacity-60 cursor-default",
5606
+ className
5607
+ );
5608
+ if (renderLink) {
5609
+ return renderLink({ href, className: shellClass, children: /* @__PURE__ */ jsx(Fragment, { children }) });
5610
+ }
5611
+ return /* @__PURE__ */ jsx("a", { href, className: shellClass, "data-cimplify-card": true, children });
5612
+ }
5613
+ function FoodProductCard({
5614
+ product,
5615
+ onQuickAdd,
5616
+ renderImage,
5617
+ renderLink,
5618
+ className
5619
+ }) {
5620
+ const image = product.image_url || product.images?.[0] || "";
5621
+ const tags = product.tags || [];
5622
+ const isSignature = product.metadata?.is_signature === true;
5623
+ const isNew = product.metadata?.is_new === true;
5624
+ const isComposite = product.type === PRODUCT_TYPE.Composite;
5625
+ return /* @__PURE__ */ jsxs(CardShell, { product, renderLink, className, children: [
5626
+ /* @__PURE__ */ jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "square", renderImage, children: [
5627
+ isSignature && /* @__PURE__ */ 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: [
5628
+ /* @__PURE__ */ jsx("svg", { className: "w-3 h-3 opacity-70", fill: "currentColor", viewBox: "0 0 16 16", children: /* @__PURE__ */ 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" }) }),
5629
+ "Signature"
5630
+ ] }),
5631
+ isNew && !isSignature && /* @__PURE__ */ 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" }),
5632
+ isComposite && /* @__PURE__ */ 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" }),
5633
+ /* @__PURE__ */ jsx(
5634
+ QuickAddButton,
5635
+ {
5636
+ onClick: () => onQuickAdd?.(product),
5637
+ className: "absolute bottom-3 right-3"
5638
+ }
5639
+ )
5640
+ ] }),
5641
+ /* @__PURE__ */ jsxs("div", { className: "p-3.5", children: [
5642
+ /* @__PURE__ */ jsx("h3", { className: "text-[14.5px] font-semibold text-foreground leading-snug tracking-tight truncate", children: product.name }),
5643
+ product.description && /* @__PURE__ */ jsx("p", { className: "text-[12.5px] text-muted-foreground mt-1 leading-relaxed line-clamp-2", children: product.description }),
5644
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mt-3", children: [
5645
+ isComposite ? /* @__PURE__ */ jsxs("span", { className: "text-sm font-bold", children: [
5646
+ "From ",
5647
+ /* @__PURE__ */ jsx(Price, { amount: product.default_price })
5648
+ ] }) : /* @__PURE__ */ jsx(Price, { amount: product.default_price, className: "text-sm font-bold" }),
5649
+ tags.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex gap-1", children: tags.slice(0, 2).map((tag) => /* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium text-muted-foreground px-1.5 py-0.5 bg-muted rounded", children: tag }, tag)) })
5650
+ ] })
5651
+ ] })
5652
+ ] });
5653
+ }
5654
+ function getColorSwatches(product) {
5655
+ const variants = product.variants;
5656
+ if (!variants || variants.length === 0) return [];
5657
+ const seen = /* @__PURE__ */ new Set();
5658
+ for (const v of variants) {
5659
+ if (v.display_attributes) {
5660
+ for (const attr of v.display_attributes) {
5661
+ if (attr.axis_name.toLowerCase() === "color" && !seen.has(attr.value_name)) {
5662
+ seen.add(attr.value_name);
5663
+ }
5664
+ }
5665
+ }
5666
+ }
5667
+ return Array.from(seen).slice(0, 5);
5668
+ }
5669
+ function RetailProductCard({
5670
+ product,
5671
+ renderImage,
5672
+ renderLink,
5673
+ className
5674
+ }) {
5675
+ const image = product.image_url || product.images?.[0] || "";
5676
+ const outOfStock = product.inventory_status?.in_stock === false;
5677
+ const onSale = isOnSale(product);
5678
+ const swatches = getColorSwatches(product);
5679
+ return /* @__PURE__ */ jsxs(CardShell, { product, renderLink, disabled: outOfStock, className, children: [
5680
+ outOfStock && /* @__PURE__ */ jsx(SoldOutOverlay, {}),
5681
+ /* @__PURE__ */ jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "3/4", renderImage, children: [
5682
+ onSale && /* @__PURE__ */ jsx("div", { className: "absolute top-3 left-3", children: /* @__PURE__ */ jsx(SaleBadge2, { product }) }),
5683
+ /* @__PURE__ */ jsx(WishlistButton, { className: "absolute top-3 right-3" }),
5684
+ product.inventory_status?.low_stock && product.inventory_status?.stock_level && /* @__PURE__ */ 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: [
5685
+ "Only ",
5686
+ product.inventory_status.stock_level,
5687
+ " left"
5688
+ ] })
5689
+ ] }),
5690
+ /* @__PURE__ */ jsxs("div", { className: "p-3.5", children: [
5691
+ product.vendor && /* @__PURE__ */ jsx("p", { className: "text-[10px] font-semibold text-muted-foreground uppercase tracking-widest", children: product.vendor }),
5692
+ /* @__PURE__ */ jsx("h3", { className: "text-[14.5px] font-semibold text-foreground leading-snug tracking-tight mt-1 truncate", children: product.name }),
5693
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-2", children: [
5694
+ /* @__PURE__ */ jsx(Price, { amount: product.default_price, className: "text-sm font-bold" }),
5695
+ onSale && /* @__PURE__ */ jsx(Price, { amount: getBasePrice(product), className: "text-xs text-muted-foreground line-through" })
5696
+ ] }),
5697
+ swatches.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex gap-1.5 mt-2.5", children: swatches.map((name) => /* @__PURE__ */ jsx(
5698
+ "span",
5699
+ {
5700
+ title: name,
5701
+ className: "text-[9px] font-medium text-muted-foreground px-1.5 py-0.5 bg-muted rounded",
5702
+ children: name
5703
+ },
5704
+ name
5705
+ )) })
5706
+ ] })
5707
+ ] });
5708
+ }
5709
+ function PriceRange({ product, currency, className }) {
5710
+ const context = useOptionalCimplify();
5711
+ const resolvedCurrency = currency ?? context?.displayCurrency ?? "USD";
5712
+ const range = getPriceRange(product);
5713
+ if (!range) return null;
5714
+ return /* @__PURE__ */ jsx("span", { "data-cimplify-price-range": true, className, children: formatPriceRange(range.min, range.max, resolvedCurrency) });
5715
+ }
5716
+ function WholesaleProductCard({
5717
+ product,
5718
+ onQuickAdd,
5719
+ renderImage,
5720
+ renderLink,
5721
+ className
5722
+ }) {
5723
+ const image = product.image_url || product.images?.[0] || "";
5724
+ const hasTiers = product.quantity_pricing && product.quantity_pricing.length > 1;
5725
+ const status = product.inventory_status;
5726
+ return /* @__PURE__ */ jsxs(CardShell, { product, renderLink, className, children: [
5727
+ /* @__PURE__ */ jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "square", renderImage, children: [
5728
+ product.min_order_quantity != null && product.min_order_quantity > 1 && /* @__PURE__ */ 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: [
5729
+ "MOQ: ",
5730
+ product.min_order_quantity
5731
+ ] }),
5732
+ /* @__PURE__ */ jsx(
5733
+ QuickAddButton,
5734
+ {
5735
+ onClick: () => onQuickAdd?.(product),
5736
+ className: "absolute bottom-3 right-3"
5737
+ }
5738
+ )
5739
+ ] }),
5740
+ /* @__PURE__ */ jsxs("div", { className: "p-3.5", children: [
5741
+ product.sku && /* @__PURE__ */ jsx("p", { className: "text-[10px] text-muted-foreground font-mono", children: product.sku }),
5742
+ /* @__PURE__ */ jsx("h3", { className: "text-[14.5px] font-semibold text-foreground leading-snug tracking-tight mt-1 truncate", children: product.name }),
5743
+ /* @__PURE__ */ jsx("div", { className: "mt-2", children: hasTiers ? /* @__PURE__ */ jsx(PriceRange, { product, className: "text-sm font-bold" }) : /* @__PURE__ */ jsx(Price, { amount: product.default_price, className: "text-sm font-bold" }) }),
5744
+ status && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 mt-2", children: [
5745
+ /* @__PURE__ */ jsx("span", { className: cn(
5746
+ "w-[7px] h-[7px] rounded-full shrink-0",
5747
+ status.in_stock ? status.low_stock ? "bg-amber-500" : "bg-emerald-500" : "bg-red-500"
5748
+ ) }),
5749
+ /* @__PURE__ */ jsx("span", { className: cn(
5750
+ "text-[10.5px] font-medium",
5751
+ status.in_stock ? status.low_stock ? "text-amber-600" : "text-emerald-600" : "text-red-600"
5752
+ ), children: !status.in_stock ? "Out of stock" : status.stock_level != null ? `${status.stock_level.toLocaleString()} in stock` : "In stock" })
5753
+ ] })
5754
+ ] })
5755
+ ] });
5756
+ }
5757
+ var TYPE_BADGES = {
5758
+ download: { label: "Download", color: "bg-sky-50 text-sky-700 border-sky-200/60" },
5759
+ license: { label: "License", color: "bg-blue-50 text-blue-700 border-blue-200/60" },
5760
+ event_ticket: { label: "Event", color: "bg-violet-50 text-violet-700 border-violet-200/60" },
5761
+ access_pass: { label: "Access", color: "bg-emerald-50 text-emerald-700 border-emerald-200/60" },
5762
+ gift_card: { label: "Gift Card", color: "bg-amber-50 text-amber-700 border-amber-200/60" }
5763
+ };
5764
+ function DigitalProductCard({
5765
+ product,
5766
+ renderImage,
5767
+ renderLink,
5768
+ className
5769
+ }) {
5770
+ const image = product.image_url || product.images?.[0] || "";
5771
+ const typeBadge = product.digital_type ? TYPE_BADGES[product.digital_type] : null;
5772
+ const isTicket = product.digital_type === "event_ticket";
5773
+ return /* @__PURE__ */ jsxs(CardShell, { product, renderLink, className, children: [
5774
+ /* @__PURE__ */ jsx(CardImage, { src: image, alt: product.name, aspectRatio: "4/3", renderImage, children: typeBadge && /* @__PURE__ */ 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 }) }),
5775
+ /* @__PURE__ */ jsxs("div", { className: "p-3.5", children: [
5776
+ /* @__PURE__ */ jsx("h3", { className: "text-[14.5px] font-semibold text-foreground leading-snug tracking-tight truncate", children: product.name }),
5777
+ isTicket && (product.event_date || product.venue) && /* @__PURE__ */ jsxs("p", { className: "text-[12px] text-muted-foreground mt-1 truncate", children: [
5778
+ product.event_date && new Date(product.event_date).toLocaleDateString(void 0, { month: "short", day: "numeric" }),
5779
+ product.event_date && product.venue && " \xB7 ",
5780
+ product.venue
5781
+ ] }),
5782
+ !isTicket && product.description && /* @__PURE__ */ jsx("p", { className: "text-[12px] text-muted-foreground mt-1 line-clamp-1", children: product.description }),
5783
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mt-2.5", children: [
5784
+ /* @__PURE__ */ jsx(Price, { amount: product.default_price, className: "text-sm font-bold" }),
5785
+ product.file_type && /* @__PURE__ */ jsxs("span", { className: "text-[10px] text-muted-foreground bg-muted px-1.5 py-0.5 rounded", children: [
5786
+ product.file_type.toUpperCase(),
5787
+ product.file_size_mb != null && ` \xB7 ${product.file_size_mb >= 1024 ? `${(product.file_size_mb / 1024).toFixed(1)}GB` : `${product.file_size_mb}MB`}`
5788
+ ] })
5789
+ ] })
5790
+ ] })
5791
+ ] });
5792
+ }
5793
+ function formatDuration2(minutes, unit) {
5794
+ if (unit && unit !== "minutes") return `${minutes} ${unit}`;
5795
+ if (minutes >= 60) {
5796
+ const h = Math.floor(minutes / 60);
5797
+ const m = minutes % 60;
5798
+ return m > 0 ? `${h}h ${m}m` : `${h} hr${h > 1 ? "s" : ""}`;
5799
+ }
5800
+ return `${minutes} min`;
5801
+ }
5802
+ function StandardServiceCard({
5803
+ product,
5804
+ onBook,
5805
+ renderImage,
5806
+ renderLink,
5807
+ className
5808
+ }) {
5809
+ const image = product.image_url || product.images?.[0] || "";
5810
+ const hasDeposit = product.deposit_type && product.deposit_type !== "none" && product.deposit_amount;
5811
+ return /* @__PURE__ */ jsxs(CardShell, { product, renderLink, className, children: [
5812
+ /* @__PURE__ */ jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "16/9", renderImage, children: [
5813
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/50 to-transparent pointer-events-none" }),
5814
+ product.duration_minutes != null && /* @__PURE__ */ 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) }),
5815
+ /* @__PURE__ */ jsx("span", { className: "absolute bottom-3 right-3 text-white font-bold text-lg drop-shadow-sm", children: /* @__PURE__ */ jsx(Price, { amount: product.default_price }) })
5816
+ ] }),
5817
+ /* @__PURE__ */ jsxs("div", { className: "p-4", children: [
5818
+ /* @__PURE__ */ jsx("h3", { className: "text-[14.5px] font-bold text-foreground leading-snug tracking-tight", children: product.name }),
5819
+ product.description && /* @__PURE__ */ jsx("p", { className: "text-[12.5px] text-muted-foreground mt-1 leading-relaxed line-clamp-2", children: product.description }),
5820
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mt-3 pt-3 border-t border-border", children: [
5821
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-[12px] text-muted-foreground", children: [
5822
+ /* @__PURE__ */ jsx("span", { className: "w-[7px] h-[7px] rounded-full bg-emerald-500 animate-pulse" }),
5823
+ /* @__PURE__ */ jsx("span", { children: "Available" }),
5824
+ hasDeposit && /* @__PURE__ */ jsxs(Fragment, { children: [
5825
+ /* @__PURE__ */ jsx("span", { className: "text-border", children: "\xB7" }),
5826
+ /* @__PURE__ */ jsxs("span", { children: [
5827
+ /* @__PURE__ */ jsx(Price, { amount: product.deposit_amount }),
5828
+ " deposit"
5829
+ ] })
5830
+ ] })
5831
+ ] }),
5832
+ /* @__PURE__ */ jsx(
5833
+ "button",
5834
+ {
5835
+ onClick: (e) => {
5836
+ e.preventDefault();
5837
+ e.stopPropagation();
5838
+ onBook?.(product);
5839
+ },
5840
+ className: "text-[13px] font-semibold text-primary hover:text-primary/80 transition-colors",
5841
+ children: "Book now \u2192"
5842
+ }
5843
+ )
5844
+ ] })
5845
+ ] })
5846
+ ] });
5847
+ }
5848
+ function formatDuration3(minutes, unit) {
5849
+ if (unit && unit !== "minutes") return `${minutes} ${unit}`;
5850
+ if (minutes >= 60) {
5851
+ const h = Math.floor(minutes / 60);
5852
+ const m = minutes % 60;
5853
+ return m > 0 ? `${h}h ${m}m` : `${h} hr`;
5854
+ }
5855
+ return `${minutes} min`;
5856
+ }
5857
+ function CompactServiceCard({
5858
+ product,
5859
+ renderImage,
5860
+ renderLink,
5861
+ className
5862
+ }) {
5863
+ const image = product.image_url || product.images?.[0] || "";
5864
+ const hasDeposit = product.deposit_type && product.deposit_type !== "none" && product.deposit_amount;
5865
+ const hasBillingPlans = product.billing_plans && product.billing_plans.length > 0;
5866
+ const href = `/products/${product.slug}`;
5867
+ const content = /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 p-3", children: [
5868
+ /* @__PURE__ */ 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__ */ jsx("img", { src: image, alt: product.name, className: "w-full h-full object-cover" }) }),
5869
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
5870
+ /* @__PURE__ */ jsx("h3", { className: "text-[14px] font-semibold text-foreground leading-tight truncate", children: product.name }),
5871
+ product.description && /* @__PURE__ */ jsx("p", { className: "text-[12px] text-muted-foreground mt-0.5 truncate", children: product.description }),
5872
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-2 flex-wrap", children: [
5873
+ product.duration_minutes != null && /* @__PURE__ */ 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) }),
5874
+ /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-[10.5px] font-medium text-emerald-600", children: [
5875
+ /* @__PURE__ */ jsx("span", { className: "w-[6px] h-[6px] rounded-full bg-emerald-500" }),
5876
+ "Available"
5877
+ ] }),
5878
+ hasDeposit && /* @__PURE__ */ jsxs("span", { className: "text-[10.5px] font-medium text-amber-600", children: [
5879
+ /* @__PURE__ */ jsx(Price, { amount: product.deposit_amount }),
5880
+ " deposit"
5881
+ ] }),
5882
+ hasBillingPlans && /* @__PURE__ */ 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" })
5883
+ ] })
5884
+ ] }),
5885
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 shrink-0", children: [
5886
+ /* @__PURE__ */ jsx(Price, { amount: product.default_price, className: "text-sm font-bold" }),
5887
+ /* @__PURE__ */ 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__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" }) })
5888
+ ] })
5889
+ ] });
5890
+ const shellClass = cn(
5891
+ "group block text-left cursor-pointer bg-card rounded-[14px] overflow-hidden",
5892
+ "shadow-[0_1px_3px_rgba(0,0,0,0.04),0_6px_24px_rgba(0,0,0,0.06)]",
5893
+ "border border-transparent",
5894
+ "transition-all duration-300 ease-[cubic-bezier(0.19,1,0.22,1)]",
5895
+ "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",
5896
+ className
5897
+ );
5898
+ if (renderLink) {
5899
+ return renderLink({ href, className: shellClass, children: content });
5900
+ }
5901
+ return /* @__PURE__ */ jsx("a", { href, className: shellClass, "data-cimplify-card": true, children: content });
5902
+ }
5903
+ function ScheduleServiceCard({
5904
+ product,
5905
+ slots,
5906
+ onBook,
5907
+ renderImage,
5908
+ renderLink,
5909
+ className
5910
+ }) {
5911
+ const image = product.image_url || product.images?.[0] || "";
5912
+ const href = `/products/${product.slug}`;
5913
+ const durationLabel = product.duration_minutes != null ? `${product.duration_minutes} ${product.duration_unit ?? "min"}` : null;
5914
+ const displaySlots = (slots || []).slice(0, 3);
5915
+ const shellClass = cn(
5916
+ "group block text-left cursor-pointer bg-card rounded-[14px] overflow-hidden",
5917
+ "shadow-[0_1px_3px_rgba(0,0,0,0.04),0_6px_24px_rgba(0,0,0,0.06)]",
5918
+ "transition-all duration-300 ease-[cubic-bezier(0.19,1,0.22,1)]",
5919
+ "hover:-translate-y-1 hover:shadow-[0_2px_6px_rgba(0,0,0,0.04),0_12px_40px_rgba(0,0,0,0.10)]",
5920
+ className
5921
+ );
5922
+ const inner = /* @__PURE__ */ jsxs("div", { className: "p-4", children: [
5923
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
5924
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
5925
+ /* @__PURE__ */ jsx("h3", { className: "text-[14.5px] font-bold text-foreground leading-snug tracking-tight", children: product.name }),
5926
+ /* @__PURE__ */ jsxs("p", { className: "text-[12.5px] text-muted-foreground mt-0.5", children: [
5927
+ durationLabel && /* @__PURE__ */ jsxs(Fragment, { children: [
5928
+ durationLabel,
5929
+ " \xB7 "
5930
+ ] }),
5931
+ /* @__PURE__ */ jsx(Price, { amount: product.default_price })
5932
+ ] })
5933
+ ] }),
5934
+ image && /* @__PURE__ */ 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__ */ jsx("img", { src: image, alt: product.name, className: "w-full h-full object-cover" }) })
5935
+ ] }),
5936
+ product.description && /* @__PURE__ */ jsx("p", { className: "text-[12px] text-muted-foreground mt-2 line-clamp-2 leading-relaxed", children: product.description }),
5937
+ displaySlots.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mt-4 pt-3 border-t border-border", children: [
5938
+ /* @__PURE__ */ 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" }),
5939
+ /* @__PURE__ */ jsx("div", { className: "flex gap-2 flex-wrap", children: displaySlots.map((slot, i) => /* @__PURE__ */ jsx(
5940
+ "button",
5941
+ {
5942
+ onClick: (e) => {
5943
+ e.preventDefault();
5944
+ e.stopPropagation();
5945
+ onBook?.(product);
5946
+ },
5947
+ className: cn(
5948
+ "text-[12.5px] font-medium px-3 py-1.5 rounded-lg transition-all duration-200 ease-out hover:scale-[1.04]",
5949
+ i === 0 ? "bg-primary text-primary-foreground font-semibold shadow-sm" : "bg-muted text-foreground hover:bg-muted/80"
5950
+ ),
5951
+ children: new Date(slot.start_time).toLocaleString(void 0, {
5952
+ weekday: "short",
5953
+ hour: "numeric",
5954
+ minute: "2-digit"
5955
+ })
5956
+ },
5957
+ i
5958
+ )) })
5959
+ ] })
5960
+ ] });
5961
+ if (renderLink) {
5962
+ return renderLink({ href, className: shellClass, children: inner });
5963
+ }
5964
+ return /* @__PURE__ */ jsx("a", { href, className: shellClass, "data-cimplify-card": true, children: inner });
5965
+ }
5966
+ var UNIT_LABELS = {
5967
+ minutes: "min",
5968
+ hours: "hr",
5969
+ days: "day",
5970
+ nights: "night",
5971
+ weeks: "week",
5972
+ months: "mo",
5973
+ years: "yr"
5974
+ };
5975
+ function RentalServiceCard({
5976
+ product,
5977
+ onBook,
5978
+ renderImage,
5979
+ renderLink,
5980
+ className
5981
+ }) {
5982
+ const image = product.image_url || product.images?.[0] || "";
5983
+ const hasDeposit = product.deposit_type && product.deposit_type !== "none" && product.deposit_amount;
5984
+ const unit = product.duration_unit ? UNIT_LABELS[product.duration_unit] || product.duration_unit : "day";
5985
+ const status = product.inventory_status;
5986
+ return /* @__PURE__ */ jsxs(CardShell, { product, renderLink, className, children: [
5987
+ /* @__PURE__ */ jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "16/9", renderImage, children: [
5988
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/50 to-transparent pointer-events-none" }),
5989
+ /* @__PURE__ */ 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: [
5990
+ "Per ",
5991
+ unit
5992
+ ] }),
5993
+ /* @__PURE__ */ jsxs("span", { className: "absolute bottom-3 right-3 text-white font-bold text-lg drop-shadow-sm", children: [
5994
+ /* @__PURE__ */ jsx(Price, { amount: product.default_price }),
5995
+ "/",
5996
+ unit
5997
+ ] }),
5998
+ product.general_service_capacity != null && product.general_service_capacity > 1 && /* @__PURE__ */ 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: [
5999
+ "Up to ",
6000
+ product.general_service_capacity,
6001
+ " guests"
6002
+ ] })
6003
+ ] }),
6004
+ /* @__PURE__ */ jsxs("div", { className: "p-4", children: [
6005
+ /* @__PURE__ */ jsx("h3", { className: "text-[14.5px] font-bold text-foreground leading-snug tracking-tight", children: product.name }),
6006
+ product.description && /* @__PURE__ */ jsx("p", { className: "text-[12.5px] text-muted-foreground mt-1 leading-relaxed line-clamp-2", children: product.description }),
6007
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 mt-3", children: [
6008
+ product.min_order_quantity != null && product.min_order_quantity > 1 && /* @__PURE__ */ jsxs("span", { className: "text-[10.5px] font-medium text-muted-foreground px-1.5 py-0.5 bg-muted rounded", children: [
6009
+ "Min. ",
6010
+ product.min_order_quantity,
6011
+ " ",
6012
+ unit,
6013
+ product.min_order_quantity > 1 ? "s" : ""
6014
+ ] }),
6015
+ hasDeposit && /* @__PURE__ */ jsxs("span", { className: "text-[10.5px] font-medium text-amber-600", children: [
6016
+ /* @__PURE__ */ jsx(Price, { amount: product.deposit_amount }),
6017
+ " deposit"
6018
+ ] })
6019
+ ] }),
6020
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mt-3 pt-3 border-t border-border", children: [
6021
+ status && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-[12px]", children: [
6022
+ /* @__PURE__ */ jsx("span", { className: cn(
6023
+ "w-[7px] h-[7px] rounded-full shrink-0",
6024
+ status.in_stock ? "bg-emerald-500" : "bg-red-500"
6025
+ ) }),
6026
+ /* @__PURE__ */ 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" })
6027
+ ] }),
6028
+ /* @__PURE__ */ jsx(
6029
+ "button",
6030
+ {
6031
+ onClick: (e) => {
6032
+ e.preventDefault();
6033
+ e.stopPropagation();
6034
+ onBook?.(product);
6035
+ },
6036
+ className: "text-[13px] font-semibold text-primary hover:text-primary/80 transition-colors",
6037
+ children: "Reserve now \u2192"
6038
+ }
6039
+ )
6040
+ ] })
6041
+ ] })
6042
+ ] });
6043
+ }
6044
+ function AccommodationCard({
6045
+ product,
6046
+ onBook,
6047
+ renderImage,
6048
+ renderLink,
6049
+ className
6050
+ }) {
6051
+ const image = product.image_url || product.images?.[0] || "";
6052
+ const hasTiers = product.quantity_pricing && product.quantity_pricing.length > 1;
6053
+ const cancellationHours = product.cancellation_window_minutes ? Math.floor(product.cancellation_window_minutes / 60) : null;
6054
+ const tags = product.tags || [];
6055
+ return /* @__PURE__ */ jsxs(CardShell, { product, renderLink, className, children: [
6056
+ /* @__PURE__ */ jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "16/9", renderImage, children: [
6057
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/50 to-transparent pointer-events-none" }),
6058
+ /* @__PURE__ */ 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" }),
6059
+ /* @__PURE__ */ jsxs("span", { className: "absolute bottom-3 right-3 text-white font-bold text-lg drop-shadow-sm", children: [
6060
+ /* @__PURE__ */ jsx(Price, { amount: product.default_price }),
6061
+ "/night"
6062
+ ] })
6063
+ ] }),
6064
+ /* @__PURE__ */ jsxs("div", { className: "p-4", children: [
6065
+ /* @__PURE__ */ jsx("h3", { className: "text-[14.5px] font-bold text-foreground leading-snug tracking-tight", children: product.name }),
6066
+ product.description && /* @__PURE__ */ jsx("p", { className: "text-[12.5px] text-muted-foreground mt-1 leading-relaxed line-clamp-2", children: product.description }),
6067
+ tags.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1 mt-2.5", children: tags.slice(0, 4).map((tag) => /* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium text-muted-foreground px-1.5 py-0.5 bg-muted rounded", children: tag }, tag)) }),
6068
+ product.general_service_capacity != null && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 mt-2 text-[11px] text-muted-foreground", children: [
6069
+ /* @__PURE__ */ jsx("svg", { className: "w-3.5 h-3.5", fill: "none", stroke: "currentColor", strokeWidth: "1.5", viewBox: "0 0 24 24", children: /* @__PURE__ */ 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" }) }),
6070
+ product.general_service_capacity,
6071
+ " guest",
6072
+ product.general_service_capacity > 1 ? "s" : ""
6073
+ ] }),
6074
+ hasTiers && /* @__PURE__ */ jsx("div", { className: "mt-3", children: /* @__PURE__ */ jsx(VolumePricing, { tiers: product.quantity_pricing }) }),
6075
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mt-3 pt-3 border-t border-border", children: [
6076
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-[11px] text-muted-foreground", children: [
6077
+ cancellationHours != null && /* @__PURE__ */ jsxs("span", { className: "text-emerald-600 font-medium", children: [
6078
+ "Free cancellation ",
6079
+ cancellationHours,
6080
+ "h"
6081
+ ] }),
6082
+ product.min_order_quantity != null && product.min_order_quantity > 1 && /* @__PURE__ */ jsxs("span", { children: [
6083
+ "Min. ",
6084
+ product.min_order_quantity,
6085
+ " nights"
6086
+ ] })
6087
+ ] }),
6088
+ /* @__PURE__ */ jsx(
6089
+ "button",
6090
+ {
6091
+ onClick: (e) => {
6092
+ e.preventDefault();
6093
+ e.stopPropagation();
6094
+ onBook?.(product);
6095
+ },
6096
+ className: "text-[13px] font-semibold text-primary hover:text-primary/80 transition-colors",
6097
+ children: "Book room \u2192"
6098
+ }
6099
+ )
6100
+ ] })
6101
+ ] })
6102
+ ] });
6103
+ }
6104
+ var UNIT_LABELS2 = {
6105
+ weeks: "week",
6106
+ months: "mo",
6107
+ years: "yr"
6108
+ };
6109
+ function LeaseServiceCard({
6110
+ product,
6111
+ onBook,
6112
+ renderImage,
6113
+ renderLink,
6114
+ className
6115
+ }) {
6116
+ const image = product.image_url || product.images?.[0] || "";
6117
+ const hasDeposit = product.deposit_type && product.deposit_type !== "none" && product.deposit_amount;
6118
+ const hasTiers = product.quantity_pricing && product.quantity_pricing.length > 1;
6119
+ const unit = product.duration_unit ? UNIT_LABELS2[product.duration_unit] || product.duration_unit : "mo";
6120
+ const tags = product.tags || [];
6121
+ const cancellationHours = product.cancellation_window_minutes ? Math.floor(product.cancellation_window_minutes / 60) : null;
6122
+ return /* @__PURE__ */ jsxs(CardShell, { product, renderLink, className, children: [
6123
+ /* @__PURE__ */ jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "16/9", renderImage, children: [
6124
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/50 to-transparent pointer-events-none" }),
6125
+ /* @__PURE__ */ 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: [
6126
+ "Per ",
6127
+ unit
6128
+ ] }),
6129
+ /* @__PURE__ */ jsxs("span", { className: "absolute bottom-3 right-3 text-white font-bold text-lg drop-shadow-sm", children: [
6130
+ /* @__PURE__ */ jsx(Price, { amount: product.default_price }),
6131
+ "/",
6132
+ unit
6133
+ ] })
6134
+ ] }),
6135
+ /* @__PURE__ */ jsxs("div", { className: "p-4", children: [
6136
+ /* @__PURE__ */ jsx("h3", { className: "text-[14.5px] font-bold text-foreground leading-snug tracking-tight", children: product.name }),
6137
+ product.description && /* @__PURE__ */ jsx("p", { className: "text-[12.5px] text-muted-foreground mt-1 leading-relaxed line-clamp-2", children: product.description }),
6138
+ tags.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1 mt-2.5", children: tags.slice(0, 4).map((tag) => /* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium text-muted-foreground px-1.5 py-0.5 bg-muted rounded", children: tag }, tag)) }),
6139
+ hasTiers && /* @__PURE__ */ jsx("div", { className: "mt-3", children: /* @__PURE__ */ jsx(VolumePricing, { tiers: product.quantity_pricing }) }),
6140
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 mt-3", children: [
6141
+ product.min_order_quantity != null && product.min_order_quantity > 1 && /* @__PURE__ */ jsxs("span", { className: "text-[10.5px] font-medium text-muted-foreground px-1.5 py-0.5 bg-muted rounded", children: [
6142
+ "Min. ",
6143
+ product.min_order_quantity,
6144
+ " ",
6145
+ unit,
6146
+ product.min_order_quantity > 1 ? "s" : ""
6147
+ ] }),
6148
+ hasDeposit && /* @__PURE__ */ jsxs("span", { className: "text-[10.5px] font-medium text-amber-600", children: [
6149
+ /* @__PURE__ */ jsx(Price, { amount: product.deposit_amount }),
6150
+ " deposit"
6151
+ ] }),
6152
+ cancellationHours != null && /* @__PURE__ */ jsx("span", { className: "text-[10.5px] font-medium text-muted-foreground", children: cancellationHours >= 720 ? `${Math.floor(cancellationHours / 720)} month notice` : `${cancellationHours}h notice` })
6153
+ ] }),
6154
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mt-3 pt-3 border-t border-border", children: [
6155
+ product.billing_plans && product.billing_plans.length > 0 && /* @__PURE__ */ jsxs("span", { className: "text-[10.5px] font-semibold text-primary px-1.5 py-0.5 bg-primary/10 rounded", children: [
6156
+ product.billing_plans[0].frequency,
6157
+ " billing"
6158
+ ] }),
6159
+ /* @__PURE__ */ jsx(
6160
+ "button",
6161
+ {
6162
+ onClick: (e) => {
6163
+ e.preventDefault();
6164
+ e.stopPropagation();
6165
+ onBook?.(product);
6166
+ },
6167
+ className: "text-[13px] font-semibold text-primary hover:text-primary/80 transition-colors ml-auto",
6168
+ children: "Enquire now \u2192"
6169
+ }
6170
+ )
6171
+ ] })
6172
+ ] })
6173
+ ] });
6174
+ }
6175
+ var FREQUENCY_LABELS2 = {
6176
+ weekly: "/week",
6177
+ monthly: "/mo",
6178
+ quarterly: "/qtr",
6179
+ annually: "/yr"
6180
+ };
6181
+ function SubscriptionCard({
6182
+ product,
6183
+ onBook,
6184
+ renderImage,
6185
+ renderLink,
6186
+ className
6187
+ }) {
6188
+ const image = product.image_url || product.images?.[0] || "";
6189
+ const plans = product.billing_plans || [];
6190
+ const primaryPlan = plans[0];
6191
+ const frequency = primaryPlan?.frequency ? FREQUENCY_LABELS2[primaryPlan.frequency] || `/${primaryPlan.frequency}` : "/mo";
6192
+ const hasTrial = primaryPlan?.trial_days != null && primaryPlan.trial_days > 0;
6193
+ const tags = product.tags || [];
6194
+ return /* @__PURE__ */ jsxs(CardShell, { product, renderLink, className, children: [
6195
+ /* @__PURE__ */ jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "16/9", renderImage, children: [
6196
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/50 to-transparent pointer-events-none" }),
6197
+ /* @__PURE__ */ jsxs("span", { className: "absolute bottom-3 right-3 text-white font-bold text-lg drop-shadow-sm", children: [
6198
+ /* @__PURE__ */ jsx(Price, { amount: product.default_price }),
6199
+ frequency
6200
+ ] }),
6201
+ hasTrial && /* @__PURE__ */ 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: [
6202
+ primaryPlan.trial_days,
6203
+ "-day free trial"
6204
+ ] })
6205
+ ] }),
6206
+ /* @__PURE__ */ jsxs("div", { className: "p-4", children: [
6207
+ /* @__PURE__ */ jsx("h3", { className: "text-[14.5px] font-bold text-foreground leading-snug tracking-tight", children: product.name }),
6208
+ product.description && /* @__PURE__ */ jsx("p", { className: "text-[12.5px] text-muted-foreground mt-1 leading-relaxed line-clamp-2", children: product.description }),
6209
+ tags.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1 mt-2.5", children: tags.slice(0, 3).map((tag) => /* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium text-muted-foreground px-1.5 py-0.5 bg-muted rounded", children: tag }, tag)) }),
6210
+ plans.length > 1 && /* @__PURE__ */ jsx("div", { className: "mt-3 space-y-1", children: plans.slice(0, 3).map((plan) => {
6211
+ const label = plan.frequency ? plan.frequency.charAt(0).toUpperCase() + plan.frequency.slice(1) : "Standard";
6212
+ const hasMarkup = plan.markup_type && plan.markup_amount;
6213
+ const isSavings = plan.markup_type === "percentage" && plan.markup_amount != null && plan.markup_amount < 0;
6214
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-[11px]", children: [
6215
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: label }),
6216
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: hasMarkup && isSavings && /* @__PURE__ */ jsxs("span", { className: "text-emerald-600 mr-1", children: [
6217
+ "Save ",
6218
+ Math.abs(plan.markup_amount),
6219
+ "%"
6220
+ ] }) })
6221
+ ] }, plan.id);
6222
+ }) }),
6223
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mt-3 pt-3 border-t border-border", children: [
6224
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-[11px] text-muted-foreground", children: [
6225
+ hasTrial && /* @__PURE__ */ jsx("span", { className: "text-emerald-600 font-medium", children: "Free trial" }),
6226
+ primaryPlan?.setup_fee != null && primaryPlan.setup_fee > 0 && /* @__PURE__ */ jsxs("span", { children: [
6227
+ /* @__PURE__ */ jsx(Price, { amount: primaryPlan.setup_fee }),
6228
+ " setup"
6229
+ ] })
6230
+ ] }),
6231
+ /* @__PURE__ */ jsx(
6232
+ "button",
6233
+ {
6234
+ onClick: (e) => {
6235
+ e.preventDefault();
6236
+ e.stopPropagation();
6237
+ onBook?.(product);
6238
+ },
6239
+ className: "text-[13px] font-semibold text-primary hover:text-primary/80 transition-colors",
6240
+ children: "Subscribe \u2192"
6241
+ }
6242
+ )
6243
+ ] })
6244
+ ] })
6245
+ ] });
6246
+ }
6247
+
6248
+ // src/react/cards/index.ts
6249
+ var CardVariant = /* @__PURE__ */ ((CardVariant2) => {
6250
+ CardVariant2["Food"] = "food";
6251
+ CardVariant2["Retail"] = "retail";
6252
+ CardVariant2["Wholesale"] = "wholesale";
6253
+ CardVariant2["Digital"] = "digital";
6254
+ CardVariant2["Standard"] = "standard";
6255
+ CardVariant2["Compact"] = "compact";
6256
+ CardVariant2["Schedule"] = "schedule";
6257
+ CardVariant2["Rental"] = "rental";
6258
+ CardVariant2["Accommodation"] = "accommodation";
6259
+ CardVariant2["Lease"] = "lease";
6260
+ CardVariant2["Subscription"] = "subscription";
6261
+ return CardVariant2;
6262
+ })(CardVariant || {});
5496
6263
  var ASPECT_STYLES2 = {
5497
6264
  square: { aspectRatio: "1/1" },
5498
6265
  "4/3": { aspectRatio: "4/3" },
5499
6266
  "16/10": { aspectRatio: "16/10" },
5500
6267
  "3/4": { aspectRatio: "3/4" }
5501
6268
  };
6269
+ var BUILT_IN_CARDS = {
6270
+ ["food" /* Food */]: FoodProductCard,
6271
+ ["retail" /* Retail */]: RetailProductCard,
6272
+ ["wholesale" /* Wholesale */]: WholesaleProductCard,
6273
+ ["digital" /* Digital */]: DigitalProductCard,
6274
+ ["standard" /* Standard */]: StandardServiceCard,
6275
+ ["rental" /* Rental */]: RentalServiceCard,
6276
+ ["accommodation" /* Accommodation */]: AccommodationCard,
6277
+ ["lease" /* Lease */]: LeaseServiceCard,
6278
+ ["subscription" /* Subscription */]: SubscriptionCard
6279
+ };
6280
+ var RENTAL_UNITS = /* @__PURE__ */ new Set([DURATION_UNIT.Days, DURATION_UNIT.Hours]);
6281
+ var LEASE_UNITS = /* @__PURE__ */ new Set([DURATION_UNIT.Weeks, DURATION_UNIT.Months, DURATION_UNIT.Years]);
6282
+ function resolveCardVariant(product) {
6283
+ if (product.quantity_pricing && product.quantity_pricing.length > 1) {
6284
+ return "wholesale" /* Wholesale */;
6285
+ }
6286
+ if (product.type === PRODUCT_TYPE.Digital) {
6287
+ return "digital" /* Digital */;
6288
+ }
6289
+ if (product.type === PRODUCT_TYPE.Service) {
6290
+ if (product.duration_unit && RENTAL_UNITS.has(product.duration_unit)) {
6291
+ return "rental" /* Rental */;
6292
+ }
6293
+ if (product.duration_unit === DURATION_UNIT.Nights) {
6294
+ return "accommodation" /* Accommodation */;
6295
+ }
6296
+ if (product.duration_unit && LEASE_UNITS.has(product.duration_unit)) {
6297
+ return "lease" /* Lease */;
6298
+ }
6299
+ if (product.billing_plans && product.billing_plans.length > 0 && !product.duration_minutes) {
6300
+ return "subscription" /* Subscription */;
6301
+ }
6302
+ return "standard" /* Standard */;
6303
+ }
6304
+ if (product.render_hint === RENDER_HINT.Food) {
6305
+ return "food" /* Food */;
6306
+ }
6307
+ if (product.render_hint === RENDER_HINT.Physical) {
6308
+ return "retail" /* Retail */;
6309
+ }
6310
+ return "retail" /* Retail */;
6311
+ }
5502
6312
  function ProductCard({
5503
6313
  product,
5504
6314
  displayMode,
6315
+ variant,
6316
+ cards,
5505
6317
  href,
5506
6318
  renderModal,
5507
6319
  renderImage,
5508
6320
  renderLink,
6321
+ onQuickAdd,
5509
6322
  children,
5510
6323
  aspectRatio = "4/3",
5511
6324
  className,
@@ -5531,61 +6344,42 @@ function ProductCard({
5531
6344
  setIsOpen(false);
5532
6345
  }, []);
5533
6346
  const imageUrl = product.image_url || product.images?.[0];
5534
- const cardBody = children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
5535
- imageUrl && /* @__PURE__ */ jsx(
5536
- "div",
5537
- {
5538
- "data-cimplify-product-card-image-container": true,
5539
- className: cn("overflow-hidden rounded-t-xl", classNames?.imageContainer),
5540
- style: ASPECT_STYLES2[aspectRatio],
5541
- children: renderImage ? renderImage({
5542
- src: imageUrl,
5543
- alt: product.name,
5544
- className: classNames?.image
5545
- }) : /* @__PURE__ */ jsx(
5546
- "img",
5547
- {
5548
- src: imageUrl,
5549
- alt: product.name,
5550
- className: cn("w-full h-full object-cover transition-transform duration-300 group-hover:scale-105", classNames?.image),
5551
- "data-cimplify-product-card-image": true
5552
- }
5553
- )
5554
- }
5555
- ),
5556
- /* @__PURE__ */ jsxs(
5557
- "div",
5558
- {
5559
- "data-cimplify-product-card-body": true,
5560
- className: cn("p-4 flex flex-col gap-1", classNames?.body),
5561
- children: [
5562
- /* @__PURE__ */ jsx(
5563
- "span",
5564
- {
5565
- "data-cimplify-product-card-name": true,
5566
- className: cn("font-semibold text-foreground leading-tight", classNames?.name),
5567
- children: product.name
5568
- }
5569
- ),
5570
- product.description && /* @__PURE__ */ jsx(
5571
- "span",
5572
- {
5573
- "data-cimplify-product-card-description": true,
5574
- className: cn("text-sm text-muted-foreground line-clamp-2", classNames?.description),
5575
- children: product.description
5576
- }
5577
- ),
5578
- /* @__PURE__ */ jsx(
5579
- Price,
6347
+ const cardBody = (() => {
6348
+ if (children) return children;
6349
+ const SlugCard = cards?.[product.slug];
6350
+ if (SlugCard) {
6351
+ return /* @__PURE__ */ jsx(SlugCard, { product, onQuickAdd, renderImage, renderLink });
6352
+ }
6353
+ const key = variant ?? resolveCardVariant(product);
6354
+ const ResolvedCard = BUILT_IN_CARDS[key];
6355
+ if (ResolvedCard) {
6356
+ return /* @__PURE__ */ jsx(ResolvedCard, { product, onQuickAdd, renderImage, renderLink });
6357
+ }
6358
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
6359
+ imageUrl && /* @__PURE__ */ jsx(
6360
+ "div",
6361
+ {
6362
+ "data-cimplify-product-card-image-container": true,
6363
+ className: cn("overflow-hidden rounded-t-xl", classNames?.imageContainer),
6364
+ style: ASPECT_STYLES2[aspectRatio],
6365
+ children: renderImage ? renderImage({ src: imageUrl, alt: product.name, className: classNames?.image }) : /* @__PURE__ */ jsx(
6366
+ "img",
5580
6367
  {
5581
- amount: product.default_price,
5582
- className: cn("text-sm font-medium text-foreground mt-1", classNames?.price)
6368
+ src: imageUrl,
6369
+ alt: product.name,
6370
+ className: cn("w-full h-full object-cover transition-transform duration-300 group-hover:scale-105", classNames?.image),
6371
+ "data-cimplify-product-card-image": true
5583
6372
  }
5584
6373
  )
5585
- ]
5586
- }
5587
- )
5588
- ] });
6374
+ }
6375
+ ),
6376
+ /* @__PURE__ */ jsxs("div", { "data-cimplify-product-card-body": true, className: cn("p-4 flex flex-col gap-1", classNames?.body), children: [
6377
+ /* @__PURE__ */ jsx("span", { "data-cimplify-product-card-name": true, className: cn("font-semibold text-foreground leading-tight", classNames?.name), children: product.name }),
6378
+ product.description && /* @__PURE__ */ jsx("span", { "data-cimplify-product-card-description": true, className: cn("text-sm text-muted-foreground line-clamp-2", classNames?.description), children: product.description }),
6379
+ /* @__PURE__ */ jsx(Price, { amount: product.default_price, className: cn("text-sm font-medium text-foreground mt-1", classNames?.price) })
6380
+ ] })
6381
+ ] });
6382
+ })();
5589
6383
  if (mode === "page") {
5590
6384
  const linkHref = href ?? `/menu/${product.slug}`;
5591
6385
  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);
@@ -7028,458 +7822,356 @@ function BookingList({
7028
7822
  filter,
7029
7823
  enabled: bookingsProp === void 0
7030
7824
  });
7031
- const bookings = bookingsProp ?? fetched;
7032
- if (isLoading && bookings.length === 0) {
7033
- return /* @__PURE__ */ jsx(
7034
- "div",
7035
- {
7036
- "data-cimplify-booking-list": true,
7037
- "aria-busy": "true",
7038
- className: cn(className, classNames?.root, classNames?.loading)
7039
- }
7040
- );
7041
- }
7042
- if (bookings.length === 0) {
7043
- return /* @__PURE__ */ jsx(
7044
- "div",
7045
- {
7046
- "data-cimplify-booking-list": true,
7047
- "data-empty": true,
7048
- className: cn(className, classNames?.root, classNames?.empty),
7049
- children: /* @__PURE__ */ jsx("p", { children: emptyMessage })
7050
- }
7051
- );
7052
- }
7053
- return /* @__PURE__ */ jsx("div", { "data-cimplify-booking-list": true, className: cn(className, classNames?.root), children: bookings.map((booking) => /* @__PURE__ */ jsx(
7054
- "div",
7055
- {
7056
- "data-cimplify-booking-list-item": true,
7057
- className: classNames?.item,
7058
- onClick: () => onBookingClick?.(booking),
7059
- role: onBookingClick ? "button" : void 0,
7060
- tabIndex: onBookingClick ? 0 : void 0,
7061
- onKeyDown: onBookingClick ? (e) => {
7062
- if (e.key === "Enter" || e.key === " ") {
7063
- e.preventDefault();
7064
- onBookingClick(booking);
7065
- }
7066
- } : void 0,
7067
- children: /* @__PURE__ */ jsx(
7068
- BookingCard,
7069
- {
7070
- booking,
7071
- onCancel,
7072
- onReschedule,
7073
- renderBooking
7074
- }
7075
- )
7076
- },
7077
- booking.order_id
7078
- )) });
7079
- }
7080
-
7081
- // src/react/utils/format-duration.ts
7082
- var UNIT_LABELS = {
7083
- minutes: { singular: "min", plural: "min" },
7084
- hours: { singular: "hr", plural: "hrs" },
7085
- days: { singular: "day", plural: "days" },
7086
- nights: { singular: "night", plural: "nights" },
7087
- weeks: { singular: "week", plural: "weeks" },
7088
- months: { singular: "month", plural: "months" },
7089
- years: { singular: "year", plural: "years" }
7090
- };
7091
- function formatDuration2(value, unit) {
7092
- const resolved = unit ?? "minutes";
7093
- const labels = UNIT_LABELS[resolved];
7094
- const label = value === 1 ? labels.singular : labels.plural;
7095
- return `${value} ${label}`;
7096
- }
7097
- var ASPECT_STYLES3 = {
7098
- square: { aspectRatio: "1/1" },
7099
- "4/3": { aspectRatio: "4/3" },
7100
- "16/10": { aspectRatio: "16/10" },
7101
- "3/4": { aspectRatio: "3/4" }
7102
- };
7103
- function ServiceCard({
7104
- service,
7105
- onBook,
7106
- href,
7107
- actionLabel = "Book",
7108
- renderImage,
7109
- children,
7110
- aspectRatio = "4/3",
7111
- className,
7112
- classNames
7113
- }) {
7114
- const imageUrl = service.image_url;
7115
- const cardBody = children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
7116
- imageUrl && /* @__PURE__ */ jsx(
7117
- "div",
7118
- {
7119
- "data-cimplify-service-card-image-container": true,
7120
- className: cn("overflow-hidden rounded-t-xl", classNames?.imageContainer),
7121
- style: ASPECT_STYLES3[aspectRatio],
7122
- children: renderImage ? renderImage({
7123
- src: imageUrl,
7124
- alt: service.name,
7125
- className: classNames?.image
7126
- }) : /* @__PURE__ */ jsx(
7127
- "img",
7128
- {
7129
- src: imageUrl,
7130
- alt: service.name,
7131
- className: cn("w-full h-full object-cover transition-transform duration-300 group-hover:scale-105", classNames?.image),
7132
- "data-cimplify-service-card-image": true
7133
- }
7134
- )
7135
- }
7136
- ),
7137
- /* @__PURE__ */ jsxs("div", { "data-cimplify-service-card-body": true, className: cn("p-4 flex flex-col gap-1.5", classNames?.body), children: [
7138
- /* @__PURE__ */ jsx("span", { "data-cimplify-service-card-name": true, className: cn("font-semibold text-foreground leading-tight", classNames?.name), children: service.name }),
7139
- service.description && /* @__PURE__ */ jsx(
7140
- "span",
7141
- {
7142
- "data-cimplify-service-card-description": true,
7143
- className: cn("text-sm text-muted-foreground line-clamp-2", classNames?.description),
7144
- children: service.description
7145
- }
7146
- ),
7147
- /* @__PURE__ */ jsxs("div", { "data-cimplify-service-card-meta": true, className: cn("flex items-center gap-2 mt-1 text-sm", classNames?.meta), children: [
7148
- /* @__PURE__ */ jsx("span", { "data-cimplify-service-card-duration": true, className: cn("text-muted-foreground", classNames?.duration), children: formatDuration2(service.duration_minutes, service.duration_unit) }),
7149
- service.price && /* @__PURE__ */ jsx("span", { "data-cimplify-service-card-price": true, className: cn("font-medium text-foreground", classNames?.price), children: /* @__PURE__ */ jsx(Price, { amount: service.price }) })
7150
- ] })
7151
- ] }),
7152
- !href && onBook && /* @__PURE__ */ 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 })
7153
- ] });
7154
- const cardClasses = cn(
7155
- "group block w-full rounded-xl border border-border bg-background text-left transition-shadow duration-200 hover:shadow-md",
7156
- !service.is_available && "opacity-60",
7157
- className,
7158
- classNames?.root
7159
- );
7160
- if (href) {
7161
- return /* @__PURE__ */ jsx(
7162
- "a",
7163
- {
7164
- href,
7165
- "data-cimplify-service-card": true,
7166
- "data-available": service.is_available || void 0,
7167
- className: cn(cardClasses, "no-underline text-[inherit]"),
7168
- children: cardBody
7169
- }
7170
- );
7171
- }
7172
- return /* @__PURE__ */ jsx(
7173
- "button",
7174
- {
7175
- type: "button",
7176
- onClick: () => onBook?.(service),
7177
- disabled: !service.is_available,
7178
- "data-cimplify-service-card": true,
7179
- "data-available": service.is_available || void 0,
7180
- className: cn(cardClasses, "cursor-pointer font-[inherit] p-0 border-border"),
7181
- children: cardBody
7182
- }
7183
- );
7184
- }
7185
- function ServiceGrid({
7186
- services: servicesProp,
7187
- columns,
7188
- onServiceSelect,
7189
- getServiceHref,
7190
- renderCard,
7191
- renderImage,
7192
- availableOnly = true,
7193
- actionLabel,
7194
- emptyMessage = "No services available",
7195
- className,
7196
- classNames
7197
- }) {
7198
- const rawId = React3.useId();
7199
- const gridId = `cimplify-service-grid-${rawId.replace(/:/g, "")}`;
7200
- const { services: fetched, isLoading } = useServices({
7201
- enabled: servicesProp === void 0
7202
- });
7203
- const allServices = servicesProp ?? fetched;
7204
- const services = availableOnly ? allServices.filter((s) => s.is_available) : allServices;
7205
- const sm = columns?.sm ?? 1;
7206
- const md = columns?.md ?? 2;
7207
- const lg = columns?.lg ?? 3;
7208
- const xl = columns?.xl ?? 4;
7209
- if (isLoading && services.length === 0) {
7825
+ const bookings = bookingsProp ?? fetched;
7826
+ if (isLoading && bookings.length === 0) {
7210
7827
  return /* @__PURE__ */ jsx(
7211
7828
  "div",
7212
7829
  {
7213
- "data-cimplify-service-grid": true,
7830
+ "data-cimplify-booking-list": true,
7214
7831
  "aria-busy": "true",
7215
7832
  className: cn(className, classNames?.root, classNames?.loading)
7216
7833
  }
7217
7834
  );
7218
7835
  }
7219
- if (services.length === 0) {
7836
+ if (bookings.length === 0) {
7220
7837
  return /* @__PURE__ */ jsx(
7221
7838
  "div",
7222
7839
  {
7223
- "data-cimplify-service-grid": true,
7840
+ "data-cimplify-booking-list": true,
7224
7841
  "data-empty": true,
7225
7842
  className: cn(className, classNames?.root, classNames?.empty),
7226
7843
  children: /* @__PURE__ */ jsx("p", { children: emptyMessage })
7227
7844
  }
7228
7845
  );
7229
7846
  }
7230
- const css = [
7231
- `#${gridId}{display:grid;grid-template-columns:repeat(${sm},1fr);gap:1rem}`,
7232
- `@media(min-width:768px){#${gridId}{grid-template-columns:repeat(${md},1fr)}}`,
7233
- `@media(min-width:1024px){#${gridId}{grid-template-columns:repeat(${lg},1fr)}}`,
7234
- `@media(min-width:1280px){#${gridId}{grid-template-columns:repeat(${xl},1fr)}}`
7235
- ].join("");
7236
- return /* @__PURE__ */ jsxs(Fragment, { children: [
7237
- /* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: css } }),
7238
- /* @__PURE__ */ jsx(
7239
- "div",
7240
- {
7241
- id: gridId,
7242
- "data-cimplify-service-grid": true,
7243
- className: cn(className, classNames?.root),
7244
- children: services.map((service) => /* @__PURE__ */ jsx(
7245
- "div",
7246
- {
7247
- "data-cimplify-service-grid-item": true,
7248
- className: classNames?.item,
7249
- children: renderCard ? renderCard(service) : /* @__PURE__ */ jsx(
7250
- ServiceCard,
7251
- {
7252
- service,
7253
- onBook: onServiceSelect,
7254
- href: getServiceHref?.(service),
7255
- actionLabel,
7256
- renderImage
7257
- }
7258
- )
7259
- },
7260
- service.id
7261
- ))
7262
- }
7263
- )
7264
- ] });
7847
+ return /* @__PURE__ */ jsx("div", { "data-cimplify-booking-list": true, className: cn(className, classNames?.root), children: bookings.map((booking) => /* @__PURE__ */ jsx(
7848
+ "div",
7849
+ {
7850
+ "data-cimplify-booking-list-item": true,
7851
+ className: classNames?.item,
7852
+ onClick: () => onBookingClick?.(booking),
7853
+ role: onBookingClick ? "button" : void 0,
7854
+ tabIndex: onBookingClick ? 0 : void 0,
7855
+ onKeyDown: onBookingClick ? (e) => {
7856
+ if (e.key === "Enter" || e.key === " ") {
7857
+ e.preventDefault();
7858
+ onBookingClick(booking);
7859
+ }
7860
+ } : void 0,
7861
+ children: /* @__PURE__ */ jsx(
7862
+ BookingCard,
7863
+ {
7864
+ booking,
7865
+ onCancel,
7866
+ onReschedule,
7867
+ renderBooking
7868
+ }
7869
+ )
7870
+ },
7871
+ booking.order_id
7872
+ )) });
7265
7873
  }
7266
- function CataloguePage({
7267
- title = "Products",
7268
- products: productsProp,
7269
- categories: categoriesProp,
7270
- showFilter = true,
7271
- showSearch = true,
7272
- showSort = false,
7273
- showInStockFilter = false,
7274
- showPriceRange = false,
7275
- showTagsFilter = false,
7874
+ function DefaultCatalogueLayout({
7875
+ products,
7876
+ categories,
7877
+ facets,
7878
+ isLoading,
7879
+ selectedCategory,
7880
+ onCategoryChange,
7881
+ searchQuery,
7882
+ onSearchChange,
7883
+ sortBy,
7884
+ sortOrder,
7885
+ onSortChange,
7886
+ inStockOnly,
7887
+ onInStockChange,
7888
+ selectedTags,
7276
7889
  availableTags,
7277
- defaultSort,
7278
- pageSize,
7279
- onProductClick,
7280
- onCategoryClick,
7890
+ onTagToggle,
7891
+ minPrice,
7892
+ maxPrice,
7893
+ onPriceRangeChange,
7894
+ page,
7895
+ totalPages,
7896
+ onPageChange,
7281
7897
  renderCard,
7282
7898
  renderImage,
7283
- columns,
7284
- className,
7285
- classNames
7899
+ renderLink,
7900
+ onQuickAdd,
7901
+ title = "Products",
7902
+ className
7286
7903
  }) {
7287
- const [selectedCategoryId, setSelectedCategoryId] = useState(null);
7288
- const [searchQuery, setSearchQuery] = useState("");
7289
- const [sortBy, setSortBy] = useState(defaultSort?.by ?? "name");
7290
- const [sortOrder, setSortOrder] = useState(defaultSort?.order ?? "asc");
7291
- const [inStockOnly, setInStockOnly] = useState(false);
7292
- const [selectedTags, setSelectedTags] = useState([]);
7293
- const [minPrice, setMinPrice] = useState("");
7294
- const [maxPrice, setMaxPrice] = useState("");
7295
- const [page, setPage] = useState(1);
7296
- const debouncedSearch = useDebounce(searchQuery, 300);
7297
- const { products: fetchedProducts, isLoading: productsLoading, pagination } = useProducts({
7298
- enabled: productsProp === void 0,
7299
- category: selectedCategoryId ?? void 0,
7300
- search: debouncedSearch.length >= 2 ? debouncedSearch : void 0,
7301
- sort_by: sortBy,
7302
- sort_order: sortOrder,
7303
- in_stock: inStockOnly || void 0,
7304
- tags: selectedTags.length > 0 ? selectedTags : void 0,
7305
- min_price: minPrice ? parseFloat(minPrice) : void 0,
7306
- max_price: maxPrice ? parseFloat(maxPrice) : void 0,
7307
- page,
7308
- limit: pageSize
7309
- });
7310
- const { categories: fetchedCategories } = useCategories({
7311
- enabled: showFilter && categoriesProp === void 0
7312
- });
7313
- const allProducts = productsProp ?? fetchedProducts;
7314
- const categories = categoriesProp ?? fetchedCategories;
7315
- const handleCategorySelect = useCallback(
7316
- (id) => {
7317
- setSelectedCategoryId(id);
7318
- setPage(1);
7319
- if (id) {
7320
- const cat = categories.find((c) => c.id === id);
7321
- if (cat) onCategoryClick?.(cat);
7322
- }
7323
- },
7324
- [categories, onCategoryClick]
7325
- );
7326
- const handleTagToggle = useCallback((tag) => {
7327
- setSelectedTags(
7328
- (prev) => prev.includes(tag) ? prev.filter((t) => t !== tag) : [...prev, tag]
7329
- );
7330
- setPage(1);
7331
- }, []);
7332
- const totalPages = pagination?.total_pages ?? 1;
7333
- return /* @__PURE__ */ jsxs("div", { "data-cimplify-catalogue-page": true, className: cn(className, classNames?.root), children: [
7334
- /* @__PURE__ */ jsxs("div", { "data-cimplify-catalogue-header": true, className: classNames?.header, children: [
7335
- /* @__PURE__ */ jsx("h1", { "data-cimplify-catalogue-title": true, className: classNames?.title, children: title }),
7336
- showSearch && /* @__PURE__ */ jsx("div", { "data-cimplify-catalogue-search": true, className: classNames?.searchContainer, children: /* @__PURE__ */ jsx(
7337
- SearchInput,
7338
- {
7339
- onResultClick: onProductClick,
7340
- searchOptions: { category: selectedCategoryId ?? void 0 }
7341
- }
7342
- ) })
7904
+ const hasSidebar = facets && facets.length > 0 || availableTags && availableTags.length > 0;
7905
+ return /* @__PURE__ */ jsxs("div", { "data-cimplify-catalogue-layout": "default", className: cn("space-y-6", className), children: [
7906
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4", children: [
7907
+ /* @__PURE__ */ jsxs("div", { children: [
7908
+ /* @__PURE__ */ jsx("h1", { className: "text-2xl font-bold tracking-tight", children: title }),
7909
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground mt-0.5", children: [
7910
+ products.length,
7911
+ " items"
7912
+ ] })
7913
+ ] }),
7914
+ /* @__PURE__ */ jsxs("div", { className: "relative w-full sm:max-w-xs", children: [
7915
+ /* @__PURE__ */ 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__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
7916
+ /* @__PURE__ */ jsx(
7917
+ "input",
7918
+ {
7919
+ type: "search",
7920
+ value: searchQuery,
7921
+ onChange: (e) => onSearchChange(e.target.value),
7922
+ placeholder: "Search...",
7923
+ 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"
7924
+ }
7925
+ )
7926
+ ] })
7343
7927
  ] }),
7344
- showFilter && categories.length > 0 && /* @__PURE__ */ jsx("div", { "data-cimplify-catalogue-filter": true, className: classNames?.filterContainer, children: /* @__PURE__ */ jsx(
7345
- CategoryFilter,
7346
- {
7347
- selectedId: selectedCategoryId,
7348
- onSelect: handleCategorySelect
7349
- }
7350
- ) }),
7351
- (showSort || showInStockFilter || showPriceRange || showTagsFilter) && /* @__PURE__ */ jsxs("div", { "data-cimplify-catalogue-toolbar": true, className: cn("flex flex-wrap items-center gap-3", classNames?.toolbar), children: [
7352
- showSort && /* @__PURE__ */ jsxs(
7928
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
7929
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5 overflow-x-auto pb-1", children: [
7930
+ /* @__PURE__ */ jsx(
7931
+ "button",
7932
+ {
7933
+ onClick: () => onCategoryChange(null),
7934
+ className: cn(
7935
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
7936
+ !selectedCategory ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
7937
+ ),
7938
+ children: "All"
7939
+ }
7940
+ ),
7941
+ categories.map((cat) => /* @__PURE__ */ jsx(
7942
+ "button",
7943
+ {
7944
+ onClick: () => onCategoryChange(selectedCategory === cat.id ? null : cat.id),
7945
+ className: cn(
7946
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
7947
+ selectedCategory === cat.id ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
7948
+ ),
7949
+ children: cat.name
7950
+ },
7951
+ cat.id
7952
+ ))
7953
+ ] }),
7954
+ /* @__PURE__ */ jsxs(
7353
7955
  "select",
7354
7956
  {
7355
- "data-cimplify-sort": true,
7356
7957
  value: `${sortBy}:${sortOrder}`,
7357
7958
  onChange: (e) => {
7358
7959
  const [by, order] = e.target.value.split(":");
7359
- setSortBy(by);
7360
- setSortOrder(order);
7361
- setPage(1);
7960
+ onSortChange(by, order);
7362
7961
  },
7363
- className: "rounded-md border border-input bg-background px-3 py-1.5 text-sm",
7962
+ className: "text-xs border border-border rounded-lg px-2 py-1.5 bg-background outline-none shrink-0",
7364
7963
  children: [
7365
- /* @__PURE__ */ jsx("option", { value: "name:asc", children: "Name A\u2013Z" }),
7366
- /* @__PURE__ */ jsx("option", { value: "name:desc", children: "Name Z\u2013A" }),
7964
+ /* @__PURE__ */ jsx("option", { value: "created_at:desc", children: "Newest" }),
7367
7965
  /* @__PURE__ */ jsx("option", { value: "price:asc", children: "Price: Low to High" }),
7368
7966
  /* @__PURE__ */ jsx("option", { value: "price:desc", children: "Price: High to Low" }),
7369
- /* @__PURE__ */ jsx("option", { value: "created_at:desc", children: "Newest" }),
7370
- /* @__PURE__ */ jsx("option", { value: "created_at:asc", children: "Oldest" }),
7371
- /* @__PURE__ */ jsx("option", { value: "updated_at:desc", children: "Recently Updated" })
7967
+ /* @__PURE__ */ jsx("option", { value: "name:asc", children: "Name: A-Z" })
7372
7968
  ]
7373
7969
  }
7374
- ),
7375
- showInStockFilter && /* @__PURE__ */ jsxs("label", { "data-cimplify-stock-filter": true, className: "flex items-center gap-1.5 text-sm cursor-pointer", children: [
7376
- /* @__PURE__ */ jsx(
7377
- "input",
7378
- {
7379
- type: "checkbox",
7380
- checked: inStockOnly,
7381
- onChange: (e) => {
7382
- setInStockOnly(e.target.checked);
7383
- setPage(1);
7384
- },
7385
- className: "accent-primary"
7386
- }
7387
- ),
7388
- "In stock only"
7970
+ )
7971
+ ] }),
7972
+ /* @__PURE__ */ jsxs("div", { className: hasSidebar ? "flex gap-6" : "", children: [
7973
+ hasSidebar && /* @__PURE__ */ jsxs("aside", { className: "hidden lg:block w-60 shrink-0 space-y-6", children: [
7974
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
7975
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: "In stock only" }),
7976
+ /* @__PURE__ */ jsx(
7977
+ "button",
7978
+ {
7979
+ onClick: () => onInStockChange(!inStockOnly),
7980
+ className: cn("w-10 h-6 rounded-full transition-colors relative", inStockOnly ? "bg-foreground" : "bg-border"),
7981
+ children: /* @__PURE__ */ jsx("span", { className: cn("absolute top-1 w-4 h-4 rounded-full bg-background transition-transform shadow-sm", inStockOnly ? "left-5" : "left-1") })
7982
+ }
7983
+ )
7984
+ ] }),
7985
+ /* @__PURE__ */ jsxs("div", { children: [
7986
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold mb-2", children: "Price Range" }),
7987
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
7988
+ /* @__PURE__ */ jsx(
7989
+ "input",
7990
+ {
7991
+ type: "number",
7992
+ placeholder: "Min",
7993
+ value: minPrice,
7994
+ onChange: (e) => onPriceRangeChange(e.target.value, maxPrice),
7995
+ 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"
7996
+ }
7997
+ ),
7998
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-xs", children: "\u2013" }),
7999
+ /* @__PURE__ */ jsx(
8000
+ "input",
8001
+ {
8002
+ type: "number",
8003
+ placeholder: "Max",
8004
+ value: maxPrice,
8005
+ onChange: (e) => onPriceRangeChange(minPrice, e.target.value),
8006
+ 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"
8007
+ }
8008
+ )
8009
+ ] })
8010
+ ] }),
8011
+ facets?.map((facet) => /* @__PURE__ */ jsxs("div", { children: [
8012
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold mb-2", children: facet.name }),
8013
+ /* @__PURE__ */ jsx("div", { className: "space-y-1.5", children: facet.values.slice(0, 8).map((fv) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-sm cursor-pointer group", children: [
8014
+ /* @__PURE__ */ jsx("input", { type: "checkbox", className: "w-3.5 h-3.5 accent-foreground rounded" }),
8015
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground group-hover:text-foreground transition-colors flex-1", children: fv.value }),
8016
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground/60", children: fv.count })
8017
+ ] }, fv.value)) })
8018
+ ] }, facet.slug)),
8019
+ availableTags && availableTags.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
8020
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold mb-2", children: "Tags" }),
8021
+ /* @__PURE__ */ jsx("div", { className: "space-y-1.5", children: availableTags.map((tag) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-sm cursor-pointer group", children: [
8022
+ /* @__PURE__ */ jsx(
8023
+ "input",
8024
+ {
8025
+ type: "checkbox",
8026
+ checked: selectedTags.includes(tag),
8027
+ onChange: () => onTagToggle(tag),
8028
+ className: "w-3.5 h-3.5 accent-foreground rounded"
8029
+ }
8030
+ ),
8031
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground group-hover:text-foreground transition-colors", children: tag })
8032
+ ] }, tag)) })
8033
+ ] })
7389
8034
  ] }),
7390
- showPriceRange && /* @__PURE__ */ jsxs("div", { "data-cimplify-price-range": true, className: "flex items-center gap-1.5", children: [
8035
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
8036
+ isLoading ? /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 gap-4 animate-pulse", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxs("div", { children: [
8037
+ /* @__PURE__ */ jsx("div", { className: "aspect-square bg-muted rounded-[14px]" }),
8038
+ /* @__PURE__ */ jsxs("div", { className: "mt-3 space-y-2", children: [
8039
+ /* @__PURE__ */ jsx("div", { className: "h-4 w-3/4 bg-muted rounded" }),
8040
+ /* @__PURE__ */ jsx("div", { className: "h-3 w-1/2 bg-muted rounded" })
8041
+ ] })
8042
+ ] }, i)) }) : products.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "text-center py-16", children: [
8043
+ /* @__PURE__ */ jsx("p", { className: "text-lg font-medium", children: "No products found" }),
8044
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Try adjusting your filters" })
8045
+ ] }) : /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 gap-4", children: products.map(
8046
+ (product) => renderCard ? /* @__PURE__ */ jsx(React3.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsx(
8047
+ ProductCard,
8048
+ {
8049
+ product,
8050
+ renderImage,
8051
+ renderLink,
8052
+ onQuickAdd
8053
+ },
8054
+ product.id
8055
+ )
8056
+ ) }),
8057
+ totalPages > 1 && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-2 pt-8", children: [
8058
+ /* @__PURE__ */ jsx(
8059
+ "button",
8060
+ {
8061
+ disabled: page <= 1,
8062
+ onClick: () => onPageChange(page - 1),
8063
+ className: "text-sm px-3 py-1.5 border border-border rounded-lg disabled:opacity-40 hover:bg-muted transition-colors",
8064
+ children: "Previous"
8065
+ }
8066
+ ),
8067
+ /* @__PURE__ */ jsxs("span", { className: "text-sm text-muted-foreground tabular-nums px-2", children: [
8068
+ page,
8069
+ " / ",
8070
+ totalPages
8071
+ ] }),
8072
+ /* @__PURE__ */ jsx(
8073
+ "button",
8074
+ {
8075
+ disabled: page >= totalPages,
8076
+ onClick: () => onPageChange(page + 1),
8077
+ className: "text-sm px-3 py-1.5 border border-border rounded-lg disabled:opacity-40 hover:bg-muted transition-colors",
8078
+ children: "Next"
8079
+ }
8080
+ )
8081
+ ] })
8082
+ ] })
8083
+ ] })
8084
+ ] });
8085
+ }
8086
+ function CompactCatalogueLayout({
8087
+ products,
8088
+ categories,
8089
+ isLoading,
8090
+ selectedCategory,
8091
+ onCategoryChange,
8092
+ searchQuery,
8093
+ onSearchChange,
8094
+ renderCard,
8095
+ renderImage,
8096
+ renderLink,
8097
+ onQuickAdd,
8098
+ title = "Menu",
8099
+ className
8100
+ }) {
8101
+ return /* @__PURE__ */ jsxs("div", { "data-cimplify-catalogue-layout": "compact", className: cn("space-y-6", className), children: [
8102
+ /* @__PURE__ */ jsx("h1", { className: "text-2xl font-bold tracking-tight", children: title }),
8103
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col sm:flex-row items-start sm:items-center gap-3", children: [
8104
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5 overflow-x-auto pb-1 flex-1", children: [
7391
8105
  /* @__PURE__ */ jsx(
7392
- "input",
8106
+ "button",
7393
8107
  {
7394
- type: "number",
7395
- placeholder: "Min",
7396
- value: minPrice,
7397
- onChange: (e) => {
7398
- setMinPrice(e.target.value);
7399
- setPage(1);
7400
- },
7401
- className: "w-20 rounded-md border border-input bg-background px-2 py-1.5 text-sm",
7402
- min: 0,
7403
- step: "0.01"
8108
+ onClick: () => onCategoryChange(null),
8109
+ className: cn(
8110
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
8111
+ !selectedCategory ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
8112
+ ),
8113
+ children: "All"
7404
8114
  }
7405
8115
  ),
7406
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-sm", children: "\u2013" }),
8116
+ categories.map((cat) => /* @__PURE__ */ jsx(
8117
+ "button",
8118
+ {
8119
+ onClick: () => onCategoryChange(selectedCategory === cat.id ? null : cat.id),
8120
+ className: cn(
8121
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
8122
+ selectedCategory === cat.id ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
8123
+ ),
8124
+ children: cat.name
8125
+ },
8126
+ cat.id
8127
+ ))
8128
+ ] }),
8129
+ /* @__PURE__ */ jsxs("div", { className: "relative w-full sm:max-w-[200px]", children: [
8130
+ /* @__PURE__ */ 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__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
7407
8131
  /* @__PURE__ */ jsx(
7408
8132
  "input",
7409
8133
  {
7410
- type: "number",
7411
- placeholder: "Max",
7412
- value: maxPrice,
7413
- onChange: (e) => {
7414
- setMaxPrice(e.target.value);
7415
- setPage(1);
7416
- },
7417
- className: "w-20 rounded-md border border-input bg-background px-2 py-1.5 text-sm",
7418
- min: 0,
7419
- step: "0.01"
8134
+ type: "search",
8135
+ value: searchQuery,
8136
+ onChange: (e) => onSearchChange(e.target.value),
8137
+ placeholder: "Search...",
8138
+ 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"
7420
8139
  }
7421
8140
  )
7422
- ] }),
7423
- showTagsFilter && availableTags && availableTags.length > 0 && /* @__PURE__ */ jsx("div", { "data-cimplify-tags-filter": true, className: "flex flex-wrap gap-1.5", children: availableTags.map((tag) => /* @__PURE__ */ jsx(
7424
- "button",
7425
- {
7426
- type: "button",
7427
- onClick: () => handleTagToggle(tag),
7428
- className: cn(
7429
- "rounded-full px-3 py-1 text-xs font-medium border transition-colors",
7430
- selectedTags.includes(tag) ? "bg-primary text-primary-foreground border-primary" : "bg-background text-foreground border-input hover:bg-muted"
7431
- ),
7432
- children: tag
7433
- },
7434
- tag
7435
- )) })
8141
+ ] })
7436
8142
  ] }),
7437
- /* @__PURE__ */ jsx("div", { "data-cimplify-catalogue-grid": true, className: classNames?.gridContainer, children: productsLoading && !productsProp ? /* @__PURE__ */ jsx(
7438
- "div",
7439
- {
7440
- "data-cimplify-catalogue-loading": true,
7441
- "aria-busy": "true",
7442
- className: classNames?.loading
7443
- }
7444
- ) : /* @__PURE__ */ jsx(
7445
- ProductGrid,
7446
- {
7447
- products: allProducts,
7448
- renderCard,
7449
- renderImage,
7450
- columns,
7451
- emptyMessage: "No products found"
7452
- }
7453
- ) }),
7454
- totalPages > 1 && /* @__PURE__ */ jsxs("div", { "data-cimplify-catalogue-pagination": true, className: cn("flex items-center justify-center gap-2 pt-6", classNames?.pagination), children: [
7455
- /* @__PURE__ */ jsx(
7456
- "button",
7457
- {
7458
- type: "button",
7459
- disabled: page <= 1,
7460
- onClick: () => setPage((p) => Math.max(1, p - 1)),
7461
- className: "rounded-md border border-input bg-background px-3 py-1.5 text-sm disabled:opacity-40",
7462
- children: "Previous"
7463
- }
7464
- ),
7465
- /* @__PURE__ */ jsxs("span", { className: "text-sm text-muted-foreground tabular-nums", children: [
7466
- page,
7467
- " / ",
7468
- totalPages
7469
- ] }),
7470
- /* @__PURE__ */ jsx(
7471
- "button",
8143
+ isLoading ? /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 lg:grid-cols-3 gap-5 animate-pulse", children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsxs("div", { children: [
8144
+ /* @__PURE__ */ jsx("div", { className: "aspect-square bg-muted rounded-[14px]" }),
8145
+ /* @__PURE__ */ jsxs("div", { className: "mt-3 space-y-2", children: [
8146
+ /* @__PURE__ */ jsx("div", { className: "h-4 w-3/4 bg-muted rounded" }),
8147
+ /* @__PURE__ */ jsx("div", { className: "h-3 w-1/2 bg-muted rounded" })
8148
+ ] })
8149
+ ] }, i)) }) : products.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "text-center py-16", children: [
8150
+ /* @__PURE__ */ jsx("p", { className: "text-lg font-medium", children: "No items found" }),
8151
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Try a different category or search" })
8152
+ ] }) : /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 lg:grid-cols-3 gap-5", children: products.map(
8153
+ (product) => renderCard ? /* @__PURE__ */ jsx(React3.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsx(
8154
+ ProductCard,
7472
8155
  {
7473
- type: "button",
7474
- disabled: page >= totalPages,
7475
- onClick: () => setPage((p) => p + 1),
7476
- className: "rounded-md border border-input bg-background px-3 py-1.5 text-sm disabled:opacity-40",
7477
- children: "Next"
7478
- }
8156
+ product,
8157
+ renderImage,
8158
+ renderLink,
8159
+ onQuickAdd
8160
+ },
8161
+ product.id
7479
8162
  )
7480
- ] })
8163
+ ) })
7481
8164
  ] });
7482
8165
  }
8166
+ var CatalogueTemplate = /* @__PURE__ */ ((CatalogueTemplate2) => {
8167
+ CatalogueTemplate2["Default"] = "default";
8168
+ CatalogueTemplate2["Compact"] = "compact";
8169
+ return CatalogueTemplate2;
8170
+ })(CatalogueTemplate || {});
8171
+ var BUILT_IN_LAYOUTS = {
8172
+ ["default" /* Default */]: DefaultCatalogueLayout,
8173
+ ["compact" /* Compact */]: CompactCatalogueLayout
8174
+ };
7483
8175
  function useDebounce(value, delay) {
7484
8176
  const [debounced, setDebounced] = React3.useState(value);
7485
8177
  React3.useEffect(() => {
@@ -7488,6 +8180,109 @@ function useDebounce(value, delay) {
7488
8180
  }, [value, delay]);
7489
8181
  return debounced;
7490
8182
  }
8183
+ function CataloguePage({
8184
+ template,
8185
+ layouts,
8186
+ title,
8187
+ products: productsProp,
8188
+ categories: categoriesProp,
8189
+ facets,
8190
+ availableTags,
8191
+ pageSize,
8192
+ defaultSort,
8193
+ renderCard,
8194
+ renderImage,
8195
+ renderLink,
8196
+ onQuickAdd,
8197
+ onProductClick,
8198
+ className,
8199
+ classNames
8200
+ }) {
8201
+ const [selectedCategory, setSelectedCategory] = useState(null);
8202
+ const [searchQuery, setSearchQuery] = useState("");
8203
+ const [sortBy, setSortBy] = useState(defaultSort?.by ?? "created_at");
8204
+ const [sortOrder, setSortOrder] = useState(defaultSort?.order ?? "desc");
8205
+ const [inStockOnly, setInStockOnly] = useState(false);
8206
+ const [selectedTags, setSelectedTags] = useState([]);
8207
+ const [minPrice, setMinPrice] = useState("");
8208
+ const [maxPrice, setMaxPrice] = useState("");
8209
+ const [page, setPage] = useState(1);
8210
+ const debouncedSearch = useDebounce(searchQuery, 300);
8211
+ const { products: fetchedProducts, isLoading, pagination } = useProducts({
8212
+ enabled: productsProp === void 0,
8213
+ category: selectedCategory ?? void 0,
8214
+ search: debouncedSearch.length >= 2 ? debouncedSearch : void 0,
8215
+ sort_by: sortBy,
8216
+ sort_order: sortOrder,
8217
+ in_stock: inStockOnly || void 0,
8218
+ tags: selectedTags.length > 0 ? selectedTags : void 0,
8219
+ min_price: minPrice ? parseFloat(minPrice) : void 0,
8220
+ max_price: maxPrice ? parseFloat(maxPrice) : void 0,
8221
+ page,
8222
+ limit: pageSize
8223
+ });
8224
+ const { categories: fetchedCategories } = useCategories({
8225
+ enabled: categoriesProp === void 0
8226
+ });
8227
+ const products = productsProp ?? fetchedProducts;
8228
+ const categories = categoriesProp ?? fetchedCategories;
8229
+ const totalPages = pagination?.total_pages ?? 1;
8230
+ const handleCategoryChange = useCallback((id) => {
8231
+ setSelectedCategory(id);
8232
+ setPage(1);
8233
+ }, []);
8234
+ const handleSortChange = useCallback((by, order) => {
8235
+ setSortBy(by);
8236
+ setSortOrder(order);
8237
+ setPage(1);
8238
+ }, []);
8239
+ const handleTagToggle = useCallback((tag) => {
8240
+ setSelectedTags(
8241
+ (prev) => prev.includes(tag) ? prev.filter((t) => t !== tag) : [...prev, tag]
8242
+ );
8243
+ setPage(1);
8244
+ }, []);
8245
+ const handlePriceRangeChange = useCallback((min, max) => {
8246
+ setMinPrice(min);
8247
+ setMaxPrice(max);
8248
+ setPage(1);
8249
+ }, []);
8250
+ const key = template ?? "default" /* Default */;
8251
+ const Layout = layouts?.[key] ?? BUILT_IN_LAYOUTS[key] ?? DefaultCatalogueLayout;
8252
+ return /* @__PURE__ */ jsx("div", { "data-cimplify-catalogue-page": true, className: cn(className, classNames?.root), children: /* @__PURE__ */ jsx(
8253
+ Layout,
8254
+ {
8255
+ products,
8256
+ categories,
8257
+ facets,
8258
+ isLoading,
8259
+ selectedCategory,
8260
+ onCategoryChange: handleCategoryChange,
8261
+ searchQuery,
8262
+ onSearchChange: setSearchQuery,
8263
+ sortBy,
8264
+ sortOrder,
8265
+ onSortChange: handleSortChange,
8266
+ inStockOnly,
8267
+ onInStockChange: setInStockOnly,
8268
+ selectedTags,
8269
+ availableTags,
8270
+ onTagToggle: handleTagToggle,
8271
+ minPrice,
8272
+ maxPrice,
8273
+ onPriceRangeChange: handlePriceRangeChange,
8274
+ page,
8275
+ totalPages,
8276
+ onPageChange: setPage,
8277
+ renderCard,
8278
+ renderImage,
8279
+ renderLink,
8280
+ onQuickAdd,
8281
+ onProductClick,
8282
+ title
8283
+ }
8284
+ ) });
8285
+ }
7491
8286
  function TwoColumnGrid({
7492
8287
  left,
7493
8288
  right,
@@ -7627,13 +8422,6 @@ function getMetadataStringList(metadata, key) {
7627
8422
  if (!Array.isArray(value)) return [];
7628
8423
  return value.filter((item) => typeof item === "string");
7629
8424
  }
7630
- function PriceRange({ product, currency, className }) {
7631
- const context = useOptionalCimplify();
7632
- const resolvedCurrency = currency ?? context?.displayCurrency ?? "USD";
7633
- const range = getPriceRange(product);
7634
- if (!range) return null;
7635
- return /* @__PURE__ */ jsx("span", { "data-cimplify-price-range": true, className, children: formatPriceRange(range.min, range.max, resolvedCurrency) });
7636
- }
7637
8425
  function DefaultProductLayout({
7638
8426
  product,
7639
8427
  onAddToCart,
@@ -7721,18 +8509,6 @@ function DefaultProductLayout({
7721
8509
  )
7722
8510
  ] });
7723
8511
  }
7724
- var DIETARY_TAGS = /* @__PURE__ */ new Set([
7725
- "vegetarian",
7726
- "vegan",
7727
- "gluten-free",
7728
- "dairy-free",
7729
- "nut-free",
7730
- "spicy",
7731
- "halal",
7732
- "kosher",
7733
- "organic",
7734
- "sugar-free"
7735
- ]);
7736
8512
  function FoodProductLayout({
7737
8513
  product,
7738
8514
  onAddToCart,
@@ -7742,9 +8518,7 @@ function FoodProductLayout({
7742
8518
  className
7743
8519
  }) {
7744
8520
  const images = product.images || (product.image_url ? [product.image_url] : []);
7745
- const allTags = product.tags || [];
7746
- const dietaryTags = allTags.filter((t) => DIETARY_TAGS.has(t));
7747
- const otherTags = allTags.filter((t) => !DIETARY_TAGS.has(t));
8521
+ const tags = product.tags || [];
7748
8522
  const ingredients = getMetadataStringList(product.metadata, "ingredients");
7749
8523
  const pairings = getMetadataStringList(product.metadata, "pairings");
7750
8524
  return /* @__PURE__ */ jsxs("div", { "data-cimplify-product-layout": "food", className: cn("space-y-8", className), children: [
@@ -7761,13 +8535,12 @@ function FoodProductLayout({
7761
8535
  ),
7762
8536
  right: /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
7763
8537
  /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-1.5", children: [
7764
- dietaryTags.map((tag) => /* @__PURE__ */ 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)),
8538
+ tags.map((tag) => /* @__PURE__ */ 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)),
7765
8539
  product.allergies && product.allergies.map((allergy) => /* @__PURE__ */ 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: [
7766
8540
  "Contains ",
7767
8541
  allergy
7768
8542
  ] }, allergy))
7769
8543
  ] }),
7770
- /* @__PURE__ */ jsx(TagPills, { tags: otherTags }),
7771
8544
  /* @__PURE__ */ jsxs("div", { children: [
7772
8545
  /* @__PURE__ */ jsx("h1", { "data-cimplify-product-layout-name": true, className: "text-3xl lg:text-4xl font-bold tracking-tight", children: product.name }),
7773
8546
  /* @__PURE__ */ jsx(Price, { amount: product.default_price, className: "text-2xl font-semibold mt-2 block" })
@@ -8138,7 +8911,7 @@ var ProductTemplate = /* @__PURE__ */ ((ProductTemplate2) => {
8138
8911
  ProductTemplate2["Physical"] = "physical";
8139
8912
  return ProductTemplate2;
8140
8913
  })(ProductTemplate || {});
8141
- var BUILT_IN_LAYOUTS = {
8914
+ var BUILT_IN_LAYOUTS2 = {
8142
8915
  ["food" /* Food */]: FoodProductLayout,
8143
8916
  ["wholesale" /* Wholesale */]: WholesaleProductLayout,
8144
8917
  ["service" /* Service */]: ServiceProductLayout,
@@ -8153,16 +8926,16 @@ function resolveTemplateKey(product) {
8153
8926
  if (product.quantity_pricing && product.quantity_pricing.length > 1) {
8154
8927
  return "wholesale" /* Wholesale */;
8155
8928
  }
8156
- if (product.type === "service") {
8929
+ if (product.type === PRODUCT_TYPE.Service) {
8157
8930
  return "service" /* Service */;
8158
8931
  }
8159
- if (product.type === "digital") {
8932
+ if (product.type === PRODUCT_TYPE.Digital) {
8160
8933
  return "digital" /* Digital */;
8161
8934
  }
8162
- if (product.render_hint === "food") {
8935
+ if (product.render_hint === RENDER_HINT.Food) {
8163
8936
  return "food" /* Food */;
8164
8937
  }
8165
- if (product.render_hint === "physical") {
8938
+ if (product.render_hint === RENDER_HINT.Physical) {
8166
8939
  return "physical" /* Physical */;
8167
8940
  }
8168
8941
  return "default" /* Default */;
@@ -8175,8 +8948,8 @@ function resolveLayout(product, pages, templates) {
8175
8948
  if (templates?.[key]) {
8176
8949
  return templates[key];
8177
8950
  }
8178
- if (BUILT_IN_LAYOUTS[key]) {
8179
- return BUILT_IN_LAYOUTS[key];
8951
+ if (BUILT_IN_LAYOUTS2[key]) {
8952
+ return BUILT_IN_LAYOUTS2[key];
8180
8953
  }
8181
8954
  return DefaultProductLayout;
8182
8955
  }
@@ -8234,56 +9007,168 @@ function ProductPage({
8234
9007
  }
8235
9008
  ) });
8236
9009
  }
8237
- function CartPage({
8238
- title = "Your Cart",
9010
+ function DefaultCartLayout({
9011
+ cart,
8239
9012
  onCheckout,
8240
9013
  onContinueShopping,
8241
9014
  onDiscountApply,
8242
9015
  onDiscountClear,
8243
9016
  showDiscount = true,
8244
- showContinueShopping = true,
8245
9017
  checkoutLabel = "Proceed to Checkout",
8246
- className,
8247
- classNames
9018
+ className
8248
9019
  }) {
8249
- const { isEmpty, subtotal } = useCart();
8250
- return /* @__PURE__ */ jsxs("div", { "data-cimplify-cart-page": true, className: cn(className, classNames?.root), children: [
8251
- /* @__PURE__ */ jsxs("div", { "data-cimplify-cart-page-header": true, className: classNames?.header, children: [
8252
- /* @__PURE__ */ jsx("h1", { "data-cimplify-cart-page-title": true, className: classNames?.title, children: title }),
8253
- showContinueShopping && /* @__PURE__ */ jsx(
9020
+ if (cart.isEmpty) {
9021
+ return /* @__PURE__ */ jsxs("div", { "data-cimplify-cart-layout": "default", className: cn("text-center py-20", className), children: [
9022
+ /* @__PURE__ */ 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__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z" }) }),
9023
+ /* @__PURE__ */ jsx("p", { className: "text-lg font-medium mt-4", children: "Your cart is empty" }),
9024
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Add some items to get started" }),
9025
+ onContinueShopping && /* @__PURE__ */ jsx(
8254
9026
  "button",
8255
9027
  {
8256
- type: "button",
8257
9028
  onClick: onContinueShopping,
8258
- "data-cimplify-cart-continue": true,
8259
- className: classNames?.continueButton,
8260
- children: "Continue Shopping"
9029
+ className: "text-sm font-medium text-primary mt-4 hover:underline",
9030
+ children: "Continue shopping"
8261
9031
  }
8262
9032
  )
8263
- ] }),
8264
- /* @__PURE__ */ jsxs("div", { "data-cimplify-cart-page-content": true, className: classNames?.content, children: [
8265
- /* @__PURE__ */ jsx(CartSummary, {}),
8266
- showDiscount && !isEmpty && /* @__PURE__ */ jsx("div", { "data-cimplify-cart-page-discount": true, className: classNames?.discount, children: /* @__PURE__ */ jsx(
8267
- DiscountInput,
9033
+ ] });
9034
+ }
9035
+ return /* @__PURE__ */ jsxs("div", { "data-cimplify-cart-layout": "default", className: cn("space-y-6", className), children: [
9036
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
9037
+ /* @__PURE__ */ jsxs("h1", { className: "text-2xl font-bold tracking-tight", children: [
9038
+ "Your Cart (",
9039
+ cart.itemCount,
9040
+ " ",
9041
+ cart.itemCount === 1 ? "item" : "items",
9042
+ ")"
9043
+ ] }),
9044
+ onContinueShopping && /* @__PURE__ */ jsx(
9045
+ "button",
8268
9046
  {
8269
- orderSubtotal: subtotal.toString(),
8270
- onApply: onDiscountApply,
8271
- onClear: onDiscountClear
9047
+ onClick: onContinueShopping,
9048
+ className: "text-sm text-muted-foreground hover:text-foreground transition-colors",
9049
+ children: "Continue shopping"
8272
9050
  }
8273
- ) })
9051
+ )
9052
+ ] }),
9053
+ /* @__PURE__ */ jsxs("div", { className: "grid lg:grid-cols-[1fr_380px] gap-8", children: [
9054
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(CartSummary, {}) }),
9055
+ /* @__PURE__ */ jsx("div", { className: "lg:sticky lg:top-6 h-fit space-y-4", children: /* @__PURE__ */ jsxs("div", { className: "border border-border rounded-[14px] p-6 space-y-4", children: [
9056
+ /* @__PURE__ */ jsx("h2", { className: "font-semibold", children: "Order Summary" }),
9057
+ showDiscount && /* @__PURE__ */ jsx(
9058
+ DiscountInput,
9059
+ {
9060
+ orderSubtotal: cart.subtotal.toString(),
9061
+ onApply: onDiscountApply,
9062
+ onClear: onDiscountClear
9063
+ }
9064
+ ),
9065
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2 text-sm", children: [
9066
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
9067
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Subtotal" }),
9068
+ /* @__PURE__ */ jsx(Price, { amount: cart.subtotal })
9069
+ ] }),
9070
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
9071
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Tax" }),
9072
+ /* @__PURE__ */ jsx(Price, { amount: cart.tax })
9073
+ ] }),
9074
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between font-semibold text-base pt-2 border-t border-border", children: [
9075
+ /* @__PURE__ */ jsx("span", { children: "Total" }),
9076
+ /* @__PURE__ */ jsx(Price, { amount: cart.total })
9077
+ ] })
9078
+ ] }),
9079
+ /* @__PURE__ */ jsx(
9080
+ "button",
9081
+ {
9082
+ onClick: onCheckout,
9083
+ className: "w-full h-12 bg-foreground text-background font-medium text-sm rounded-lg hover:bg-foreground/90 transition-colors",
9084
+ children: checkoutLabel
9085
+ }
9086
+ )
9087
+ ] }) })
9088
+ ] })
9089
+ ] });
9090
+ }
9091
+ function CompactCartLayout({
9092
+ cart,
9093
+ onCheckout,
9094
+ onContinueShopping,
9095
+ checkoutLabel = "Place Order",
9096
+ className
9097
+ }) {
9098
+ if (cart.isEmpty) {
9099
+ return /* @__PURE__ */ jsxs("div", { "data-cimplify-cart-layout": "compact", className: cn("text-center py-16", className), children: [
9100
+ /* @__PURE__ */ jsx("p", { className: "text-lg font-medium", children: "Your order is empty" }),
9101
+ onContinueShopping && /* @__PURE__ */ jsx("button", { onClick: onContinueShopping, className: "text-sm font-medium text-primary mt-3 hover:underline", children: "Browse menu" })
9102
+ ] });
9103
+ }
9104
+ return /* @__PURE__ */ jsxs("div", { "data-cimplify-cart-layout": "compact", className: cn("max-w-lg mx-auto space-y-4", className), children: [
9105
+ /* @__PURE__ */ jsxs("h1", { className: "text-xl font-bold tracking-tight", children: [
9106
+ "Your Order (",
9107
+ cart.itemCount,
9108
+ ")"
9109
+ ] }),
9110
+ /* @__PURE__ */ jsx(CartSummary, {}),
9111
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2 text-sm pt-4 border-t border-border", children: [
9112
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
9113
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Subtotal" }),
9114
+ /* @__PURE__ */ jsx(Price, { amount: cart.subtotal })
9115
+ ] }),
9116
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
9117
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Tax" }),
9118
+ /* @__PURE__ */ jsx(Price, { amount: cart.tax })
9119
+ ] }),
9120
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between font-semibold text-base pt-2 border-t border-border", children: [
9121
+ /* @__PURE__ */ jsx("span", { children: "Total" }),
9122
+ /* @__PURE__ */ jsx(Price, { amount: cart.total })
9123
+ ] })
8274
9124
  ] }),
8275
- !isEmpty && /* @__PURE__ */ jsx("div", { "data-cimplify-cart-page-footer": true, className: classNames?.footer, children: /* @__PURE__ */ jsx(
9125
+ /* @__PURE__ */ jsx(
8276
9126
  "button",
8277
9127
  {
8278
- type: "button",
8279
9128
  onClick: onCheckout,
8280
- "data-cimplify-cart-checkout-button": true,
8281
- className: classNames?.checkoutButton,
9129
+ className: "w-full h-12 bg-foreground text-background font-medium text-sm rounded-lg hover:bg-foreground/90 transition-colors",
8282
9130
  children: checkoutLabel
8283
9131
  }
8284
- ) })
9132
+ )
8285
9133
  ] });
8286
9134
  }
9135
+ var CartTemplate = /* @__PURE__ */ ((CartTemplate2) => {
9136
+ CartTemplate2["Default"] = "default";
9137
+ CartTemplate2["Compact"] = "compact";
9138
+ return CartTemplate2;
9139
+ })(CartTemplate || {});
9140
+ var BUILT_IN_LAYOUTS3 = {
9141
+ ["default" /* Default */]: DefaultCartLayout,
9142
+ ["compact" /* Compact */]: CompactCartLayout
9143
+ };
9144
+ function CartPage({
9145
+ template,
9146
+ layouts,
9147
+ onCheckout,
9148
+ onContinueShopping,
9149
+ onDiscountApply,
9150
+ onDiscountClear,
9151
+ showDiscount = true,
9152
+ checkoutLabel,
9153
+ className,
9154
+ classNames
9155
+ }) {
9156
+ const cart = useCart();
9157
+ const key = template ?? "default" /* Default */;
9158
+ const Layout = layouts?.[key] ?? BUILT_IN_LAYOUTS3[key] ?? DefaultCartLayout;
9159
+ return /* @__PURE__ */ jsx("div", { "data-cimplify-cart-page": true, className: cn(className, classNames?.root), children: /* @__PURE__ */ jsx(
9160
+ Layout,
9161
+ {
9162
+ cart,
9163
+ onCheckout,
9164
+ onContinueShopping,
9165
+ onDiscountApply,
9166
+ onDiscountClear,
9167
+ showDiscount,
9168
+ checkoutLabel
9169
+ }
9170
+ ) });
9171
+ }
8287
9172
  function CheckoutPage({
8288
9173
  title = "Checkout",
8289
9174
  onComplete,
@@ -8307,22 +9192,362 @@ function CheckoutPage({
8307
9192
  )
8308
9193
  ] });
8309
9194
  }
9195
+ function DefaultCollectionLayout({
9196
+ collection,
9197
+ products,
9198
+ renderCard,
9199
+ renderImage,
9200
+ renderLink,
9201
+ onQuickAdd,
9202
+ className
9203
+ }) {
9204
+ const [searchQuery, setSearchQuery] = useState("");
9205
+ const [activeTag, setActiveTag] = useState(null);
9206
+ const collectionTags = useMemo(() => {
9207
+ const tagSet = /* @__PURE__ */ new Set();
9208
+ for (const p of products) {
9209
+ if (p.tags) {
9210
+ for (const t of p.tags) tagSet.add(t);
9211
+ }
9212
+ }
9213
+ return Array.from(tagSet).slice(0, 6);
9214
+ }, [products]);
9215
+ const filtered = useMemo(() => {
9216
+ let result = products;
9217
+ if (searchQuery.trim().length >= 2) {
9218
+ const q = searchQuery.toLowerCase();
9219
+ result = result.filter(
9220
+ (p) => p.name.toLowerCase().includes(q) || p.description?.toLowerCase().includes(q)
9221
+ );
9222
+ }
9223
+ if (activeTag) {
9224
+ result = result.filter((p) => p.tags?.includes(activeTag));
9225
+ }
9226
+ return result;
9227
+ }, [products, searchQuery, activeTag]);
9228
+ return /* @__PURE__ */ jsxs("div", { "data-cimplify-collection-layout": "default", className: cn("space-y-8", className), children: [
9229
+ /* @__PURE__ */ jsxs("div", { "data-cimplify-collection-hero": true, className: "relative overflow-hidden rounded-2xl bg-muted", children: [
9230
+ collection.image_url && /* @__PURE__ */ jsx(
9231
+ "img",
9232
+ {
9233
+ src: collection.image_url,
9234
+ alt: collection.name,
9235
+ className: "w-full h-64 lg:h-80 object-cover"
9236
+ }
9237
+ ),
9238
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/60 via-black/20 to-transparent" }),
9239
+ /* @__PURE__ */ jsxs("div", { className: "absolute bottom-0 left-0 right-0 p-6 lg:p-8", children: [
9240
+ /* @__PURE__ */ jsx("h1", { className: "text-2xl lg:text-4xl font-bold text-white tracking-tight", children: collection.name }),
9241
+ collection.description && /* @__PURE__ */ jsx("p", { className: "text-white/80 mt-2 max-w-lg text-sm lg:text-base", children: collection.description }),
9242
+ /* @__PURE__ */ jsxs("p", { className: "text-white/60 text-sm mt-2", children: [
9243
+ products.length,
9244
+ " ",
9245
+ products.length === 1 ? "item" : "items"
9246
+ ] })
9247
+ ] })
9248
+ ] }),
9249
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col sm:flex-row items-start sm:items-center gap-3", children: [
9250
+ /* @__PURE__ */ jsxs("div", { className: "relative flex-1 min-w-0 w-full sm:max-w-xs", children: [
9251
+ /* @__PURE__ */ 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__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
9252
+ /* @__PURE__ */ jsx(
9253
+ "input",
9254
+ {
9255
+ type: "search",
9256
+ value: searchQuery,
9257
+ onChange: (e) => setSearchQuery(e.target.value),
9258
+ placeholder: `Search ${collection.name}...`,
9259
+ 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"
9260
+ }
9261
+ )
9262
+ ] }),
9263
+ collectionTags.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-1.5", children: [
9264
+ /* @__PURE__ */ jsx(
9265
+ "button",
9266
+ {
9267
+ onClick: () => setActiveTag(null),
9268
+ className: cn(
9269
+ "text-xs font-medium px-3 py-1.5 rounded-full transition-colors",
9270
+ !activeTag ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
9271
+ ),
9272
+ children: "All"
9273
+ }
9274
+ ),
9275
+ collectionTags.map((tag) => /* @__PURE__ */ jsx(
9276
+ "button",
9277
+ {
9278
+ onClick: () => setActiveTag(activeTag === tag ? null : tag),
9279
+ className: cn(
9280
+ "text-xs font-medium px-3 py-1.5 rounded-full transition-colors",
9281
+ activeTag === tag ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
9282
+ ),
9283
+ children: tag
9284
+ },
9285
+ tag
9286
+ ))
9287
+ ] })
9288
+ ] }),
9289
+ filtered.length > 0 ? /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4", children: filtered.map(
9290
+ (product) => renderCard ? /* @__PURE__ */ jsx(React3.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsx(
9291
+ ProductCard,
9292
+ {
9293
+ product,
9294
+ renderImage,
9295
+ renderLink,
9296
+ onQuickAdd
9297
+ },
9298
+ product.id
9299
+ )
9300
+ ) }) : /* @__PURE__ */ jsxs("div", { className: "text-center py-16", children: [
9301
+ /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: "No items match your search." }),
9302
+ /* @__PURE__ */ jsx(
9303
+ "button",
9304
+ {
9305
+ onClick: () => {
9306
+ setSearchQuery("");
9307
+ setActiveTag(null);
9308
+ },
9309
+ className: "text-sm font-medium text-primary mt-2 hover:underline",
9310
+ children: "Clear filters"
9311
+ }
9312
+ )
9313
+ ] })
9314
+ ] });
9315
+ }
9316
+ function FeaturedCollectionLayout({
9317
+ collection,
9318
+ products,
9319
+ renderCard,
9320
+ renderImage,
9321
+ renderLink,
9322
+ onQuickAdd,
9323
+ className
9324
+ }) {
9325
+ return /* @__PURE__ */ jsxs("div", { "data-cimplify-collection-layout": "featured", className: cn("space-y-10", className), children: [
9326
+ /* @__PURE__ */ jsxs("div", { "data-cimplify-collection-hero": true, className: "relative overflow-hidden rounded-2xl bg-muted", children: [
9327
+ collection.image_url && /* @__PURE__ */ jsx(
9328
+ "img",
9329
+ {
9330
+ src: collection.image_url,
9331
+ alt: collection.name,
9332
+ className: "w-full h-72 lg:h-96 object-cover"
9333
+ }
9334
+ ),
9335
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/70 via-black/30 to-transparent" }),
9336
+ /* @__PURE__ */ jsxs("div", { className: "absolute bottom-0 left-0 right-0 p-8 lg:p-12", children: [
9337
+ collection.tags && collection.tags.length > 0 && /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold text-white/70 uppercase tracking-widest", children: collection.tags[0] }),
9338
+ /* @__PURE__ */ jsx("h1", { className: "text-3xl lg:text-5xl font-bold text-white tracking-tight mt-2", children: collection.name }),
9339
+ collection.description && /* @__PURE__ */ jsx("p", { className: "text-white/80 mt-3 max-w-2xl text-base lg:text-lg leading-relaxed", children: collection.description })
9340
+ ] })
9341
+ ] }),
9342
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6", children: products.map(
9343
+ (product) => renderCard ? /* @__PURE__ */ jsx(React3.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsx(
9344
+ ProductCard,
9345
+ {
9346
+ product,
9347
+ renderImage,
9348
+ renderLink,
9349
+ onQuickAdd
9350
+ },
9351
+ product.id
9352
+ )
9353
+ ) })
9354
+ ] });
9355
+ }
9356
+ function CatalogueCollectionLayout({
9357
+ collection,
9358
+ products,
9359
+ renderCard,
9360
+ renderImage,
9361
+ renderLink,
9362
+ onQuickAdd,
9363
+ className
9364
+ }) {
9365
+ const [searchQuery, setSearchQuery] = useState("");
9366
+ const [activeCategory, setActiveCategory] = useState(null);
9367
+ const [sortBy, setSortBy] = useState("default");
9368
+ const categories = useMemo(() => {
9369
+ const cats = /* @__PURE__ */ new Map();
9370
+ for (const p of products) {
9371
+ if (p.category_id && p.tags) {
9372
+ for (const t of p.tags) {
9373
+ if (!cats.has(t)) cats.set(t, t);
9374
+ }
9375
+ }
9376
+ }
9377
+ return Array.from(cats.values()).slice(0, 8);
9378
+ }, [products]);
9379
+ const filtered = useMemo(() => {
9380
+ let result = products;
9381
+ if (searchQuery.trim().length >= 2) {
9382
+ const q = searchQuery.toLowerCase();
9383
+ result = result.filter(
9384
+ (p) => p.name.toLowerCase().includes(q) || p.description?.toLowerCase().includes(q)
9385
+ );
9386
+ }
9387
+ if (activeCategory) {
9388
+ result = result.filter((p) => p.tags?.includes(activeCategory));
9389
+ }
9390
+ if (sortBy === "price-asc") {
9391
+ result = [...result].sort((a, b) => parsePrice(a.default_price) - parsePrice(b.default_price));
9392
+ } else if (sortBy === "price-desc") {
9393
+ result = [...result].sort((a, b) => parsePrice(b.default_price) - parsePrice(a.default_price));
9394
+ } else if (sortBy === "name") {
9395
+ result = [...result].sort((a, b) => a.name.localeCompare(b.name));
9396
+ }
9397
+ return result;
9398
+ }, [products, searchQuery, activeCategory, sortBy]);
9399
+ return /* @__PURE__ */ jsxs("div", { "data-cimplify-collection-layout": "catalogue", className: cn("space-y-6", className), children: [
9400
+ /* @__PURE__ */ jsxs("div", { children: [
9401
+ /* @__PURE__ */ jsx("h1", { className: "text-2xl lg:text-3xl font-bold tracking-tight", children: collection.name }),
9402
+ collection.description && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground mt-1 max-w-2xl", children: collection.description })
9403
+ ] }),
9404
+ /* @__PURE__ */ 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: [
9405
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 flex-1 min-w-0 w-full", children: [
9406
+ /* @__PURE__ */ jsxs("div", { className: "relative flex-1 max-w-sm", children: [
9407
+ /* @__PURE__ */ 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__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
9408
+ /* @__PURE__ */ jsx(
9409
+ "input",
9410
+ {
9411
+ type: "search",
9412
+ value: searchQuery,
9413
+ onChange: (e) => setSearchQuery(e.target.value),
9414
+ placeholder: "Search...",
9415
+ 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"
9416
+ }
9417
+ )
9418
+ ] }),
9419
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5 overflow-x-auto scrollbar-hide", children: [
9420
+ /* @__PURE__ */ jsx(
9421
+ "button",
9422
+ {
9423
+ onClick: () => setActiveCategory(null),
9424
+ className: cn(
9425
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
9426
+ !activeCategory ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
9427
+ ),
9428
+ children: "All"
9429
+ }
9430
+ ),
9431
+ categories.map((cat) => /* @__PURE__ */ jsx(
9432
+ "button",
9433
+ {
9434
+ onClick: () => setActiveCategory(activeCategory === cat ? null : cat),
9435
+ className: cn(
9436
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
9437
+ activeCategory === cat ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
9438
+ ),
9439
+ children: cat
9440
+ },
9441
+ cat
9442
+ ))
9443
+ ] })
9444
+ ] }),
9445
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 shrink-0", children: [
9446
+ /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", children: [
9447
+ filtered.length,
9448
+ " items"
9449
+ ] }),
9450
+ /* @__PURE__ */ jsxs(
9451
+ "select",
9452
+ {
9453
+ value: sortBy,
9454
+ onChange: (e) => setSortBy(e.target.value),
9455
+ className: "text-xs border border-border rounded-lg px-2 py-1.5 bg-background outline-none focus:ring-2 focus:ring-primary/20",
9456
+ children: [
9457
+ /* @__PURE__ */ jsx("option", { value: "default", children: "Sort: Default" }),
9458
+ /* @__PURE__ */ jsx("option", { value: "price-asc", children: "Price: Low to High" }),
9459
+ /* @__PURE__ */ jsx("option", { value: "price-desc", children: "Price: High to Low" }),
9460
+ /* @__PURE__ */ jsx("option", { value: "name", children: "Name: A-Z" })
9461
+ ]
9462
+ }
9463
+ )
9464
+ ] })
9465
+ ] }),
9466
+ filtered.length > 0 ? /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4", children: filtered.map(
9467
+ (product) => renderCard ? /* @__PURE__ */ jsx(React3.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsx(
9468
+ ProductCard,
9469
+ {
9470
+ product,
9471
+ renderImage,
9472
+ renderLink,
9473
+ onQuickAdd
9474
+ },
9475
+ product.id
9476
+ )
9477
+ ) }) : /* @__PURE__ */ jsxs("div", { className: "text-center py-16", children: [
9478
+ /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: "No products found." }),
9479
+ /* @__PURE__ */ jsx(
9480
+ "button",
9481
+ {
9482
+ onClick: () => {
9483
+ setSearchQuery("");
9484
+ setActiveCategory(null);
9485
+ },
9486
+ className: "text-sm font-medium text-primary mt-2 hover:underline",
9487
+ children: "Clear filters"
9488
+ }
9489
+ )
9490
+ ] })
9491
+ ] });
9492
+ }
9493
+ var CollectionTemplate = /* @__PURE__ */ ((CollectionTemplate2) => {
9494
+ CollectionTemplate2["Default"] = "default";
9495
+ CollectionTemplate2["Featured"] = "featured";
9496
+ CollectionTemplate2["Catalogue"] = "catalogue";
9497
+ return CollectionTemplate2;
9498
+ })(CollectionTemplate || {});
9499
+ var BUILT_IN_LAYOUTS4 = {
9500
+ ["default" /* Default */]: DefaultCollectionLayout,
9501
+ ["featured" /* Featured */]: FeaturedCollectionLayout,
9502
+ ["catalogue" /* Catalogue */]: CatalogueCollectionLayout
9503
+ };
9504
+ var LARGE_COLLECTION_THRESHOLD = 30;
9505
+ function resolveTemplateKey2(collection, productCount) {
9506
+ const metaTemplate = collection.metadata?.page_template;
9507
+ if (typeof metaTemplate === "string" && metaTemplate.trim()) {
9508
+ return metaTemplate.trim();
9509
+ }
9510
+ if (collection.tags?.includes("featured") || collection.metadata?.is_featured === true) {
9511
+ return "featured" /* Featured */;
9512
+ }
9513
+ if (productCount > LARGE_COLLECTION_THRESHOLD) {
9514
+ return "catalogue" /* Catalogue */;
9515
+ }
9516
+ return "default" /* Default */;
9517
+ }
9518
+ function resolveLayout2(collection, productCount, pages, templates) {
9519
+ if (pages?.[collection.slug]) {
9520
+ return pages[collection.slug];
9521
+ }
9522
+ const key = resolveTemplateKey2(collection, productCount);
9523
+ if (templates?.[key]) {
9524
+ return templates[key];
9525
+ }
9526
+ if (BUILT_IN_LAYOUTS4[key]) {
9527
+ return BUILT_IN_LAYOUTS4[key];
9528
+ }
9529
+ return DefaultCollectionLayout;
9530
+ }
8310
9531
  function CollectionPage({
8311
9532
  collectionId,
8312
9533
  collection: collectionProp,
8313
9534
  products: productsProp,
9535
+ pages,
9536
+ templates,
8314
9537
  renderCard,
8315
9538
  renderImage,
8316
- columns,
9539
+ renderLink,
9540
+ onQuickAdd,
8317
9541
  className,
8318
9542
  classNames
8319
9543
  }) {
9544
+ const resolvedId = collectionId || collectionProp?.slug || collectionProp?.id || "";
8320
9545
  const {
8321
9546
  collection: fetchedCollection,
8322
9547
  products: fetchedProducts,
8323
9548
  isLoading
8324
- } = useCollection(collectionProp ? null : collectionId, {
8325
- enabled: !collectionProp
9549
+ } = useCollection(collectionProp ? null : resolvedId, {
9550
+ enabled: !collectionProp && resolvedId.length > 0
8326
9551
  });
8327
9552
  const collection = collectionProp ?? fetchedCollection;
8328
9553
  const products = productsProp ?? fetchedProducts;
@@ -8332,37 +9557,35 @@ function CollectionPage({
8332
9557
  {
8333
9558
  "data-cimplify-collection-page": true,
8334
9559
  "aria-busy": "true",
8335
- className: cn(className, classNames?.root, classNames?.loading)
9560
+ className: cn(className, classNames?.root, classNames?.loading),
9561
+ children: /* @__PURE__ */ jsxs("div", { className: "animate-pulse space-y-6", children: [
9562
+ /* @__PURE__ */ jsx("div", { className: "h-64 lg:h-80 bg-muted rounded-2xl" }),
9563
+ /* @__PURE__ */ 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__ */ jsxs("div", { children: [
9564
+ /* @__PURE__ */ jsx("div", { className: "aspect-square bg-muted rounded-[14px]" }),
9565
+ /* @__PURE__ */ jsxs("div", { className: "mt-3 space-y-2", children: [
9566
+ /* @__PURE__ */ jsx("div", { className: "h-4 w-3/4 bg-muted rounded" }),
9567
+ /* @__PURE__ */ jsx("div", { className: "h-3 w-1/2 bg-muted rounded" })
9568
+ ] })
9569
+ ] }, i)) })
9570
+ ] })
8336
9571
  }
8337
9572
  );
8338
9573
  }
8339
9574
  if (!collection) {
8340
- return /* @__PURE__ */ jsx("div", { "data-cimplify-collection-page": true, className: cn(className, classNames?.root), children: /* @__PURE__ */ jsx("p", { children: "Collection not found." }) });
9575
+ return /* @__PURE__ */ jsx("div", { "data-cimplify-collection-page": true, className: cn(className, classNames?.root), children: /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: "Collection not found." }) });
8341
9576
  }
8342
- return /* @__PURE__ */ jsxs("div", { "data-cimplify-collection-page": true, className: cn(className, classNames?.root), children: [
8343
- /* @__PURE__ */ jsxs("div", { "data-cimplify-collection-header": true, className: classNames?.header, children: [
8344
- collection.image_url && /* @__PURE__ */ jsx(
8345
- "img",
8346
- {
8347
- src: collection.image_url,
8348
- alt: collection.name,
8349
- "data-cimplify-collection-image": true,
8350
- className: classNames?.image
8351
- }
8352
- ),
8353
- /* @__PURE__ */ jsx("h1", { "data-cimplify-collection-title": true, className: classNames?.title, children: collection.name }),
8354
- collection.description && /* @__PURE__ */ jsx("p", { "data-cimplify-collection-description": true, className: classNames?.description, children: collection.description })
8355
- ] }),
8356
- /* @__PURE__ */ jsx("div", { "data-cimplify-collection-grid": true, className: classNames?.grid, children: /* @__PURE__ */ jsx(
8357
- ProductGrid,
8358
- {
8359
- products,
8360
- renderCard,
8361
- renderImage,
8362
- columns
8363
- }
8364
- ) })
8365
- ] });
9577
+ const Layout = resolveLayout2(collection, products.length, pages, templates);
9578
+ return /* @__PURE__ */ jsx("div", { "data-cimplify-collection-page": true, className: cn(className, classNames?.root), children: /* @__PURE__ */ jsx(
9579
+ Layout,
9580
+ {
9581
+ collection,
9582
+ products,
9583
+ renderCard,
9584
+ renderImage,
9585
+ renderLink,
9586
+ onQuickAdd
9587
+ }
9588
+ ) });
8366
9589
  }
8367
9590
  function OrderDetailPage({
8368
9591
  orderId,
@@ -8481,573 +9704,355 @@ function OrderHistoryPage({
8481
9704
  ) })
8482
9705
  ] });
8483
9706
  }
8484
- function SearchPage({
8485
- title = "Search",
8486
- placeholder = "What are you looking for?",
8487
- onProductClick,
9707
+ function DefaultSearchLayout({
9708
+ search,
9709
+ facets,
9710
+ categories,
9711
+ activeCategory,
9712
+ onCategoryChange,
9713
+ inStockOnly,
9714
+ onInStockChange,
9715
+ sortBy,
9716
+ onSortChange,
8488
9717
  renderCard,
8489
9718
  renderImage,
8490
- columns,
8491
- className,
8492
- classNames
9719
+ renderLink,
9720
+ onQuickAdd,
9721
+ placeholder = "Search products...",
9722
+ className
8493
9723
  }) {
8494
- const { results, isLoading, query, setQuery, clear } = useSearch();
8495
- return /* @__PURE__ */ jsxs("div", { "data-cimplify-search-page": true, className: cn(className, classNames?.root), children: [
8496
- /* @__PURE__ */ jsx("div", { "data-cimplify-search-page-header": true, className: classNames?.header, children: /* @__PURE__ */ jsx("h1", { "data-cimplify-search-page-title": true, className: classNames?.title, children: title }) }),
8497
- /* @__PURE__ */ jsxs("div", { "data-cimplify-search-page-input": true, className: classNames?.inputContainer, children: [
9724
+ const { query, setQuery, results, isLoading, clear } = search;
9725
+ const hasFacets = facets && facets.length > 0 || categories && categories.length > 0;
9726
+ return /* @__PURE__ */ jsxs("div", { "data-cimplify-search-layout": "default", className: cn("space-y-6", className), children: [
9727
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
9728
+ /* @__PURE__ */ 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__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
8498
9729
  /* @__PURE__ */ jsx(
8499
- Input,
9730
+ "input",
8500
9731
  {
8501
9732
  type: "search",
8502
9733
  value: query,
8503
9734
  onChange: (e) => setQuery(e.target.value),
8504
9735
  placeholder,
8505
- "data-cimplify-search-page-field": true,
8506
- className: classNames?.input,
8507
- "aria-label": "Search products",
9736
+ 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",
8508
9737
  autoFocus: true
8509
9738
  }
8510
9739
  ),
8511
9740
  query.length > 0 && /* @__PURE__ */ jsx(
8512
9741
  "button",
8513
9742
  {
8514
- type: "button",
8515
9743
  onClick: clear,
8516
- "data-cimplify-search-page-clear": true,
8517
- className: classNames?.clearButton,
9744
+ 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",
8518
9745
  "aria-label": "Clear search",
8519
- children: "\xD7"
9746
+ children: /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", d: "M6 18L18 6M6 6l12 12" }) })
8520
9747
  }
8521
9748
  )
8522
9749
  ] }),
8523
- query.length >= 2 && !isLoading && /* @__PURE__ */ jsxs("div", { "data-cimplify-search-page-count": true, className: classNames?.resultCount, children: [
8524
- results.length,
8525
- " ",
8526
- results.length === 1 ? "result" : "results",
8527
- " for \u201C",
8528
- query,
8529
- "\u201D"
8530
- ] }),
8531
- /* @__PURE__ */ jsx("div", { "data-cimplify-search-page-grid": true, className: classNames?.grid, children: isLoading ? /* @__PURE__ */ jsx("div", { "data-cimplify-search-page-loading": true, "aria-busy": "true", className: classNames?.loading, children: "Searching..." }) : query.length >= 2 && results.length === 0 ? /* @__PURE__ */ jsx("div", { "data-cimplify-search-page-empty": true, className: classNames?.empty, children: /* @__PURE__ */ jsxs("p", { children: [
8532
- "No products found for \u201C",
8533
- query,
8534
- "\u201D"
8535
- ] }) }) : results.length > 0 && /* @__PURE__ */ jsx(
8536
- ProductGrid,
8537
- {
8538
- products: results,
8539
- renderCard,
8540
- renderImage,
8541
- columns
8542
- }
8543
- ) })
8544
- ] });
8545
- }
8546
- function DealsPage({
8547
- title = "Deals & Offers",
8548
- deals: dealsProp,
8549
- productsOnSale: productsOnSaleProp,
8550
- products: productsProp,
8551
- locationId,
8552
- renderImage,
8553
- columns,
8554
- className,
8555
- classNames
8556
- }) {
8557
- const { deals: fetchedDeals, isLoading: dealsLoading } = useDeals({
8558
- locationId,
8559
- enabled: dealsProp === void 0
8560
- });
8561
- const { products: fetchedOnSale, isLoading: productsLoading } = useProductsOnSale({
8562
- enabled: productsOnSaleProp === void 0
8563
- });
8564
- const deals = dealsProp ?? fetchedDeals;
8565
- const onSale = productsOnSaleProp ?? fetchedOnSale;
8566
- const isLoading = dealsLoading || productsLoading;
8567
- const isEmpty = deals.length === 0 && onSale.length === 0;
8568
- if (isLoading && isEmpty) {
8569
- return /* @__PURE__ */ jsx(
8570
- "div",
8571
- {
8572
- "data-cimplify-deals-page": true,
8573
- "aria-busy": "true",
8574
- className: cn(className, classNames?.root, classNames?.loading)
8575
- }
8576
- );
8577
- }
8578
- return /* @__PURE__ */ jsxs("div", { "data-cimplify-deals-page": true, className: cn(className, classNames?.root), children: [
8579
- /* @__PURE__ */ jsx("div", { "data-cimplify-deals-header": true, className: classNames?.header, children: /* @__PURE__ */ jsx("h1", { "data-cimplify-deals-title": true, className: classNames?.title, children: title }) }),
8580
- deals.length > 0 && /* @__PURE__ */ jsx("div", { "data-cimplify-deals-banner-section": true, className: classNames?.bannerSection, children: /* @__PURE__ */ jsx(DealBanner, { deals }) }),
8581
- (onSale.length > 0 || productsProp && productsProp.length > 0) && /* @__PURE__ */ jsxs("div", { "data-cimplify-deals-products": true, className: classNames?.productsSection, children: [
8582
- /* @__PURE__ */ jsx("h2", { "data-cimplify-deals-products-title": true, className: classNames?.productsTitle, children: "On Sale Now" }),
8583
- productsProp ? /* @__PURE__ */ jsx(
8584
- ProductGrid,
9750
+ query.length >= 2 && !isLoading && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
9751
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
9752
+ /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: results.length }),
9753
+ " result",
9754
+ results.length !== 1 ? "s" : "",
9755
+ " for ",
9756
+ /* @__PURE__ */ jsxs("span", { className: "font-medium text-foreground", children: [
9757
+ "\u201C",
9758
+ query,
9759
+ "\u201D"
9760
+ ] })
9761
+ ] }),
9762
+ onSortChange && /* @__PURE__ */ jsxs(
9763
+ "select",
8585
9764
  {
8586
- products: productsProp,
8587
- renderImage,
8588
- columns
9765
+ value: sortBy || "relevance",
9766
+ onChange: (e) => onSortChange(e.target.value),
9767
+ className: "text-xs border border-border rounded-lg px-2 py-1.5 bg-background outline-none focus:ring-2 focus:ring-primary/10",
9768
+ children: [
9769
+ /* @__PURE__ */ jsx("option", { value: "relevance", children: "Relevance" }),
9770
+ /* @__PURE__ */ jsx("option", { value: "price-asc", children: "Price: Low to High" }),
9771
+ /* @__PURE__ */ jsx("option", { value: "price-desc", children: "Price: High to Low" }),
9772
+ /* @__PURE__ */ jsx("option", { value: "name", children: "Name: A-Z" }),
9773
+ /* @__PURE__ */ jsx("option", { value: "newest", children: "Newest" })
9774
+ ]
8589
9775
  }
8590
- ) : /* @__PURE__ */ jsx("div", { "data-cimplify-deals-sale-list": true, children: onSale.map((dealInfo) => /* @__PURE__ */ jsx("div", { "data-cimplify-deals-sale-item": true, children: /* @__PURE__ */ jsx(
8591
- SaleBadge,
9776
+ )
9777
+ ] }),
9778
+ categories && categories.length > 0 && onCategoryChange && /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5 overflow-x-auto pb-1", children: [
9779
+ /* @__PURE__ */ jsx(
9780
+ "button",
8592
9781
  {
8593
- product: { id: dealInfo.product_id, name: dealInfo.deal_name },
8594
- dealInfo,
8595
- showOriginalPrice: true
9782
+ onClick: () => onCategoryChange(null),
9783
+ className: cn(
9784
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
9785
+ !activeCategory ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
9786
+ ),
9787
+ children: "All"
8596
9788
  }
8597
- ) }, `${dealInfo.product_id}-${dealInfo.deal_id}`)) })
9789
+ ),
9790
+ categories.map((cat) => /* @__PURE__ */ jsx(
9791
+ "button",
9792
+ {
9793
+ onClick: () => onCategoryChange(activeCategory === cat.id ? null : cat.id),
9794
+ className: cn(
9795
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
9796
+ activeCategory === cat.id ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
9797
+ ),
9798
+ children: cat.name
9799
+ },
9800
+ cat.id
9801
+ ))
8598
9802
  ] }),
8599
- isEmpty && /* @__PURE__ */ jsx("div", { "data-cimplify-deals-empty": true, className: classNames?.empty, children: /* @__PURE__ */ jsx("p", { children: "No deals available right now. Check back soon!" }) })
8600
- ] });
8601
- }
8602
- var ANY_VALUE2 = "__any__";
8603
- function roomToResource(room) {
8604
- return {
8605
- id: room.id,
8606
- name: room.name,
8607
- capacity: room.capacity,
8608
- floor: room.floor,
8609
- is_available: room.status === "available"
8610
- };
8611
- }
8612
- function ResourcePicker({
8613
- resources,
8614
- selectedResourceId,
8615
- onResourceSelect,
8616
- showAnyOption = true,
8617
- anyLabel = "Any available",
8618
- renderImage,
8619
- className,
8620
- classNames
8621
- }) {
8622
- const groupValue = selectedResourceId === null ? ANY_VALUE2 : selectedResourceId ?? "";
8623
- return /* @__PURE__ */ jsxs(
8624
- RadioGroup,
8625
- {
8626
- "data-cimplify-resource-picker": true,
8627
- className: cn("flex flex-col gap-2", className, classNames?.root),
8628
- value: groupValue,
8629
- onValueChange: (value) => {
8630
- onResourceSelect?.(value === ANY_VALUE2 ? null : value);
8631
- },
8632
- children: [
8633
- showAnyOption && /* @__PURE__ */ jsx(
8634
- Radio.Root,
8635
- {
8636
- value: ANY_VALUE2,
8637
- "data-cimplify-resource-option": true,
8638
- "data-selected": selectedResourceId === null || void 0,
8639
- "data-any": true,
8640
- className: cn(
8641
- "flex items-center gap-3 rounded-lg border border-border p-3 transition-colors cursor-pointer",
8642
- "hover:bg-muted data-[checked]:border-primary data-[checked]:bg-primary/5",
8643
- classNames?.option
8644
- ),
8645
- children: /* @__PURE__ */ jsx("span", { "data-cimplify-resource-name": true, className: cn("font-medium text-foreground", classNames?.name), children: anyLabel })
8646
- }
8647
- ),
8648
- resources.map((resource) => {
8649
- const unavailable = resource.is_available === false;
8650
- return /* @__PURE__ */ jsxs(
8651
- Radio.Root,
9803
+ /* @__PURE__ */ jsxs("div", { className: hasFacets ? "flex gap-6" : "", children: [
9804
+ hasFacets && /* @__PURE__ */ jsxs("aside", { "data-cimplify-search-facets": true, className: "hidden lg:block w-60 shrink-0 space-y-6", children: [
9805
+ onInStockChange && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
9806
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: "In stock only" }),
9807
+ /* @__PURE__ */ jsx(
9808
+ "button",
8652
9809
  {
8653
- value: resource.id,
8654
- disabled: unavailable,
8655
- "data-cimplify-resource-option": true,
8656
- "data-selected": selectedResourceId === resource.id || void 0,
8657
- "data-unavailable": unavailable || void 0,
9810
+ onClick: () => onInStockChange(!inStockOnly),
8658
9811
  className: cn(
8659
- "flex items-center gap-3 rounded-lg border border-border p-3 transition-colors cursor-pointer",
8660
- "hover:bg-muted data-[checked]:border-primary data-[checked]:bg-primary/5",
8661
- unavailable && "opacity-50 cursor-not-allowed",
8662
- classNames?.option,
8663
- unavailable ? classNames?.unavailable : void 0
9812
+ "w-10 h-6 rounded-full transition-colors relative",
9813
+ inStockOnly ? "bg-foreground" : "bg-border"
8664
9814
  ),
8665
- children: [
8666
- resource.image_url && (renderImage ? renderImage({
8667
- src: resource.image_url,
8668
- alt: resource.name,
8669
- className: classNames?.image
8670
- }) : /* @__PURE__ */ jsx(
8671
- "img",
8672
- {
8673
- src: resource.image_url,
8674
- alt: resource.name,
8675
- "data-cimplify-resource-image": true,
8676
- className: cn("w-10 h-10 rounded-lg object-cover", classNames?.image)
8677
- }
8678
- )),
8679
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5 flex-1 min-w-0", children: [
8680
- /* @__PURE__ */ jsx("span", { "data-cimplify-resource-name": true, className: cn("font-medium text-foreground", classNames?.name), children: resource.name }),
8681
- resource.description && /* @__PURE__ */ jsx("span", { "data-cimplify-resource-description": true, className: cn("text-sm text-muted-foreground truncate", classNames?.description), children: resource.description }),
8682
- /* @__PURE__ */ jsxs("div", { "data-cimplify-resource-meta": true, className: cn("flex items-center gap-2 text-xs text-muted-foreground", classNames?.meta), children: [
8683
- resource.capacity !== void 0 && /* @__PURE__ */ jsxs("span", { "data-cimplify-resource-capacity": true, className: classNames?.capacity, children: [
8684
- "Up to ",
8685
- resource.capacity
8686
- ] }),
8687
- resource.floor && /* @__PURE__ */ jsx("span", { "data-cimplify-resource-floor": true, className: classNames?.floor, children: resource.floor })
8688
- ] })
8689
- ] })
8690
- ]
8691
- },
8692
- resource.id
8693
- );
8694
- })
8695
- ]
8696
- }
8697
- );
8698
- }
8699
- var STEP = {
8700
- SELECT_SLOT: "select-slot",
8701
- SELECT_RESOURCE: "select-resource",
8702
- SELECT_STAFF: "select-staff",
8703
- CONFIRM: "confirm"
8704
- };
8705
- function BookingPage({
8706
- service,
8707
- product,
8708
- staff,
8709
- resources,
8710
- participantCount,
8711
- title,
8712
- onBooked,
8713
- onBack,
8714
- existingBooking,
8715
- onRescheduled,
8716
- showPrice = true,
8717
- className,
8718
- classNames
8719
- }) {
8720
- const { addItem } = useCart();
8721
- const { client } = useCimplifyClient();
8722
- const isReschedule = existingBooking !== void 0;
8723
- const [step, setStep] = useState(STEP.SELECT_SLOT);
8724
- const [selectedSlot, setSelectedSlot] = useState(null);
8725
- const [selectedDate, setSelectedDate] = useState(null);
8726
- const [selectedStaffId, setSelectedStaffId] = useState(null);
8727
- const [selectedResourceId, setSelectedResourceId] = useState(null);
8728
- const [isSubmitting, setIsSubmitting] = useState(false);
8729
- const [error, setError] = useState(null);
8730
- const hasResourceStep = resources && resources.length > 0;
8731
- const hasStaffStep = staff && staff.length > 0;
8732
- const depositType = product?.deposit_type;
8733
- const depositAmount = product?.deposit_amount;
8734
- const hasDeposit = depositType !== void 0 && depositType !== "none" && depositAmount !== void 0 && parsePrice(depositAmount) !== 0;
8735
- const cancellationMinutes = product?.cancellation_window_minutes;
8736
- const noShowFee = product?.no_show_fee;
8737
- const handleSlotSelect = useCallback(
8738
- (slot, date) => {
8739
- setSelectedSlot(slot);
8740
- setSelectedDate(date);
8741
- setError(null);
8742
- if (hasResourceStep) {
8743
- setStep(STEP.SELECT_RESOURCE);
8744
- } else if (hasStaffStep) {
8745
- setStep(STEP.SELECT_STAFF);
8746
- } else {
8747
- setStep(STEP.CONFIRM);
8748
- }
8749
- },
8750
- [hasResourceStep, hasStaffStep]
8751
- );
8752
- const handleResourceSelect = useCallback(
8753
- (resourceId) => {
8754
- setSelectedResourceId(resourceId);
8755
- if (hasStaffStep) {
8756
- setStep(STEP.SELECT_STAFF);
8757
- } else {
8758
- setStep(STEP.CONFIRM);
8759
- }
8760
- },
8761
- [hasStaffStep]
8762
- );
8763
- const handleStaffSelect = useCallback((staffId) => {
8764
- setSelectedStaffId(staffId);
8765
- setStep(STEP.CONFIRM);
8766
- }, []);
8767
- const handleBack = useCallback(() => {
8768
- setError(null);
8769
- if (step === STEP.CONFIRM && hasStaffStep) {
8770
- setStep(STEP.SELECT_STAFF);
8771
- } else if (step === STEP.CONFIRM && hasResourceStep) {
8772
- setStep(STEP.SELECT_RESOURCE);
8773
- } else if (step === STEP.SELECT_STAFF && hasResourceStep) {
8774
- setStep(STEP.SELECT_RESOURCE);
8775
- } else if (step === STEP.CONFIRM || step === STEP.SELECT_STAFF || step === STEP.SELECT_RESOURCE) {
8776
- setStep(STEP.SELECT_SLOT);
8777
- } else {
8778
- onBack?.();
8779
- }
8780
- }, [step, hasStaffStep, hasResourceStep, onBack]);
8781
- const handleConfirm = useCallback(async () => {
8782
- if (!selectedSlot || !selectedDate) return;
8783
- setIsSubmitting(true);
8784
- setError(null);
8785
- try {
8786
- if (isReschedule && existingBooking) {
8787
- const serviceItem = existingBooking.service_items[0];
8788
- const result = await client.scheduling.rescheduleBooking({
8789
- order_id: existingBooking.order_id,
8790
- line_item_id: serviceItem?.service_id ?? existingBooking.order_id,
8791
- new_start_time: selectedSlot.start_time,
8792
- new_end_time: selectedSlot.end_time,
8793
- new_staff_id: selectedStaffId || void 0,
8794
- reschedule_type: "customer"
8795
- });
8796
- if (!result.ok) {
8797
- throw result.error;
8798
- }
8799
- onRescheduled?.(existingBooking, selectedSlot);
8800
- } else {
8801
- const serviceProduct = {
8802
- id: service.product_id || service.id,
8803
- business_id: service.business_id || "",
8804
- category_id: service.category_id || void 0,
8805
- name: service.name,
8806
- slug: service.id,
8807
- description: service.description || void 0,
8808
- image_url: service.image_url || void 0,
8809
- default_price: service.price || "0",
8810
- type: "service",
8811
- inventory_type: "none",
8812
- variant_strategy: "fetch_all",
8813
- is_active: service.is_available,
8814
- created_at: (/* @__PURE__ */ new Date()).toISOString(),
8815
- updated_at: (/* @__PURE__ */ new Date()).toISOString()
8816
- };
8817
- await addItem(serviceProduct, 1, {
8818
- scheduledStart: selectedSlot.start_time,
8819
- scheduledEnd: selectedSlot.end_time,
8820
- staffId: selectedStaffId || void 0,
8821
- resourceId: selectedResourceId || void 0
8822
- });
8823
- onBooked?.(selectedSlot, selectedStaffId);
8824
- }
8825
- } catch (err) {
8826
- const fallbackMessage = isReschedule ? "Failed to reschedule booking" : "Failed to add booking to cart";
8827
- setError(err instanceof Error ? err.message : fallbackMessage);
8828
- } finally {
8829
- setIsSubmitting(false);
8830
- }
8831
- }, [selectedSlot, selectedDate, selectedStaffId, service, addItem, onBooked, isReschedule, existingBooking, client, onRescheduled]);
8832
- return /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-page": true, className: cn(className, classNames?.root), children: [
8833
- /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-page-header": true, className: classNames?.header, children: [
8834
- onBack && step === STEP.SELECT_SLOT && /* @__PURE__ */ jsx(
8835
- "button",
9815
+ children: /* @__PURE__ */ jsx("span", { className: cn(
9816
+ "absolute top-1 w-4 h-4 rounded-full bg-background transition-transform shadow-sm",
9817
+ inStockOnly ? "left-5" : "left-1"
9818
+ ) })
9819
+ }
9820
+ )
9821
+ ] }),
9822
+ facets?.map((facet) => /* @__PURE__ */ jsxs("div", { children: [
9823
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold mb-2", children: facet.name }),
9824
+ /* @__PURE__ */ jsx("div", { className: "space-y-1.5", children: facet.values.slice(0, 8).map((fv) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-sm cursor-pointer group", children: [
9825
+ /* @__PURE__ */ jsx("input", { type: "checkbox", className: "w-3.5 h-3.5 accent-foreground rounded" }),
9826
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground group-hover:text-foreground transition-colors flex-1", children: fv.value }),
9827
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground/60", children: fv.count })
9828
+ ] }, fv.value)) })
9829
+ ] }, facet.slug))
9830
+ ] }),
9831
+ /* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: isLoading ? /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 gap-4 animate-pulse", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxs("div", { children: [
9832
+ /* @__PURE__ */ jsx("div", { className: "aspect-square bg-muted rounded-[14px]" }),
9833
+ /* @__PURE__ */ jsxs("div", { className: "mt-3 space-y-2", children: [
9834
+ /* @__PURE__ */ jsx("div", { className: "h-4 w-3/4 bg-muted rounded" }),
9835
+ /* @__PURE__ */ jsx("div", { className: "h-3 w-1/2 bg-muted rounded" })
9836
+ ] })
9837
+ ] }, i)) }) : query.length >= 2 && results.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "text-center py-20", children: [
9838
+ /* @__PURE__ */ 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__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
9839
+ /* @__PURE__ */ jsxs("p", { className: "text-lg font-medium mt-4", children: [
9840
+ "No results for \u201C",
9841
+ query,
9842
+ "\u201D"
9843
+ ] }),
9844
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Try a different search term" }),
9845
+ /* @__PURE__ */ jsx("button", { onClick: clear, className: "text-sm font-medium text-primary mt-4 hover:underline", children: "Clear search" })
9846
+ ] }) : results.length > 0 ? /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 gap-4", children: results.map(
9847
+ (product) => renderCard ? /* @__PURE__ */ jsx(React3.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsx(
9848
+ ProductCard,
9849
+ {
9850
+ product,
9851
+ renderImage,
9852
+ renderLink,
9853
+ onQuickAdd
9854
+ },
9855
+ product.id
9856
+ )
9857
+ ) }) : null })
9858
+ ] })
9859
+ ] });
9860
+ }
9861
+ function CompactSearchLayout({
9862
+ search,
9863
+ categories,
9864
+ activeCategory,
9865
+ onCategoryChange,
9866
+ renderCard,
9867
+ renderImage,
9868
+ renderLink,
9869
+ onQuickAdd,
9870
+ placeholder = "Search menu...",
9871
+ className
9872
+ }) {
9873
+ const { query, setQuery, results, isLoading, clear } = search;
9874
+ return /* @__PURE__ */ jsxs("div", { "data-cimplify-search-layout": "compact", className: cn("space-y-6", className), children: [
9875
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
9876
+ /* @__PURE__ */ 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__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
9877
+ /* @__PURE__ */ jsx(
9878
+ "input",
8836
9879
  {
8837
- type: "button",
8838
- onClick: onBack,
8839
- "data-cimplify-booking-page-back": true,
8840
- className: classNames?.backButton,
8841
- children: "Back"
9880
+ type: "search",
9881
+ value: query,
9882
+ onChange: (e) => setQuery(e.target.value),
9883
+ placeholder,
9884
+ 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",
9885
+ autoFocus: true
8842
9886
  }
8843
9887
  ),
8844
- step !== STEP.SELECT_SLOT && /* @__PURE__ */ jsx(
9888
+ query.length > 0 && /* @__PURE__ */ jsx(
8845
9889
  "button",
8846
9890
  {
8847
- type: "button",
8848
- onClick: handleBack,
8849
- "data-cimplify-booking-page-back": true,
8850
- className: classNames?.backButton,
8851
- children: "Back"
8852
- }
8853
- ),
8854
- /* @__PURE__ */ jsx("h1", { "data-cimplify-booking-page-title": true, className: classNames?.title, children: title || (isReschedule ? "Reschedule Booking" : `Book ${service.name}`) })
8855
- ] }),
8856
- isReschedule && existingBooking && /* @__PURE__ */ jsx("div", { "data-cimplify-booking-reschedule-info": true, className: classNames?.rescheduleInfo, children: /* @__PURE__ */ jsxs("span", { children: [
8857
- "Rescheduling booking from ",
8858
- new Date(existingBooking.service_items[0]?.scheduled_start ?? existingBooking.created_at).toLocaleDateString()
8859
- ] }) }),
8860
- /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-service-info": true, className: classNames?.serviceInfo, children: [
8861
- /* @__PURE__ */ jsx("span", { "data-cimplify-booking-service-name": true, children: service.name }),
8862
- /* @__PURE__ */ jsx("span", { "data-cimplify-booking-service-duration": true, children: formatDuration2(service.duration_minutes, service.duration_unit) }),
8863
- service.price && /* @__PURE__ */ jsx("span", { "data-cimplify-booking-service-price": true, children: /* @__PURE__ */ jsx(Price, { amount: service.price }) }),
8864
- hasDeposit && /* @__PURE__ */ jsxs("span", { "data-cimplify-booking-deposit-info": true, className: classNames?.depositInfo, children: [
8865
- "Deposit: ",
8866
- depositType === "percentage" ? `${parsePrice(depositAmount)}%` : /* @__PURE__ */ jsx(Price, { amount: depositAmount })
8867
- ] }),
8868
- cancellationMinutes !== void 0 && cancellationMinutes > 0 && /* @__PURE__ */ jsxs("span", { "data-cimplify-booking-cancellation-policy": true, className: classNames?.cancellationPolicy, children: [
8869
- "Free cancellation up to ",
8870
- cancellationMinutes >= 60 ? `${Math.floor(cancellationMinutes / 60)} hour${Math.floor(cancellationMinutes / 60) !== 1 ? "s" : ""}` : `${cancellationMinutes} minute${cancellationMinutes !== 1 ? "s" : ""}`,
8871
- " before"
8872
- ] }),
8873
- noShowFee !== void 0 && parsePrice(noShowFee) !== 0 && /* @__PURE__ */ jsxs("span", { "data-cimplify-booking-no-show-fee": true, className: classNames?.cancellationPolicy, children: [
8874
- "No-show fee: ",
8875
- /* @__PURE__ */ jsx(Price, { amount: noShowFee })
8876
- ] })
8877
- ] }),
8878
- error && /* @__PURE__ */ jsx("div", { "data-cimplify-booking-error": true, className: classNames?.error, children: error }),
8879
- step === STEP.SELECT_SLOT && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-step": "select-slot", className: classNames?.step, children: [
8880
- /* @__PURE__ */ jsx("h2", { "data-cimplify-booking-step-title": true, className: classNames?.stepTitle, children: "Select a date & time" }),
8881
- /* @__PURE__ */ jsx(
8882
- DateSlotPicker,
8883
- {
8884
- serviceId: service.id,
8885
- participantCount,
8886
- selectedSlot,
8887
- onSlotSelect: handleSlotSelect,
8888
- showPrice
9891
+ onClick: clear,
9892
+ 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",
9893
+ "aria-label": "Clear search",
9894
+ children: /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", d: "M6 18L18 6M6 6l12 12" }) })
8889
9895
  }
8890
9896
  )
8891
9897
  ] }),
8892
- step === STEP.SELECT_RESOURCE && resources && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-step": "select-resource", className: cn(classNames?.step, classNames?.resourceStep), children: [
8893
- /* @__PURE__ */ jsx("h2", { "data-cimplify-booking-step-title": true, className: classNames?.stepTitle, children: "Choose a room" }),
9898
+ categories && categories.length > 0 && onCategoryChange && /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5 overflow-x-auto pb-1", children: [
8894
9899
  /* @__PURE__ */ jsx(
8895
- ResourcePicker,
9900
+ "button",
8896
9901
  {
8897
- resources,
8898
- selectedResourceId,
8899
- onResourceSelect: handleResourceSelect
9902
+ onClick: () => onCategoryChange(null),
9903
+ className: cn(
9904
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
9905
+ !activeCategory ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
9906
+ ),
9907
+ children: "All"
8900
9908
  }
8901
- )
8902
- ] }),
8903
- step === STEP.SELECT_STAFF && staff && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-step": "select-staff", className: classNames?.step, children: [
8904
- /* @__PURE__ */ jsx("h2", { "data-cimplify-booking-step-title": true, className: classNames?.stepTitle, children: "Choose a provider" }),
8905
- /* @__PURE__ */ jsx(
8906
- StaffPicker,
9909
+ ),
9910
+ categories.map((cat) => /* @__PURE__ */ jsx(
9911
+ "button",
8907
9912
  {
8908
- staff,
8909
- selectedStaffId,
8910
- onStaffSelect: handleStaffSelect
8911
- }
8912
- )
9913
+ onClick: () => onCategoryChange(activeCategory === cat.id ? null : cat.id),
9914
+ className: cn(
9915
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
9916
+ activeCategory === cat.id ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
9917
+ ),
9918
+ children: cat.name
9919
+ },
9920
+ cat.id
9921
+ ))
8913
9922
  ] }),
8914
- step === STEP.CONFIRM && selectedSlot && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-step": "confirm", className: classNames?.step, children: [
8915
- /* @__PURE__ */ jsx("h2", { "data-cimplify-booking-step-title": true, className: classNames?.stepTitle, children: "Confirm your booking" }),
8916
- /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-summary": true, className: classNames?.summary, children: [
8917
- /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
8918
- /* @__PURE__ */ jsx("span", { children: "Service" }),
8919
- /* @__PURE__ */ jsx("span", { children: service.name })
8920
- ] }),
8921
- /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
8922
- /* @__PURE__ */ jsx("span", { children: "Date" }),
8923
- /* @__PURE__ */ jsx("span", { children: selectedDate })
8924
- ] }),
8925
- /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
8926
- /* @__PURE__ */ jsx("span", { children: "Time" }),
8927
- /* @__PURE__ */ jsx("span", { children: new Date(selectedSlot.start_time).toLocaleTimeString(void 0, {
8928
- hour: "numeric",
8929
- minute: "2-digit"
8930
- }) })
8931
- ] }),
8932
- /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
8933
- /* @__PURE__ */ jsx("span", { children: "Duration" }),
8934
- /* @__PURE__ */ jsx("span", { children: formatDuration2(service.duration_minutes, service.duration_unit) })
8935
- ] }),
8936
- selectedResourceId && resources && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
8937
- /* @__PURE__ */ jsx("span", { children: "Room" }),
8938
- /* @__PURE__ */ jsx("span", { children: resources.find((r) => r.id === selectedResourceId)?.name ?? "Selected" })
8939
- ] }),
8940
- selectedStaffId && staff && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
8941
- /* @__PURE__ */ jsx("span", { children: "Provider" }),
8942
- /* @__PURE__ */ jsx("span", { children: staff.find((s) => s.id === selectedStaffId)?.name ?? "Selected" })
8943
- ] }),
8944
- (selectedSlot.price || service.price) && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
8945
- /* @__PURE__ */ jsx("span", { children: "Price" }),
8946
- /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(Price, { amount: selectedSlot.price || service.price }) })
8947
- ] }),
8948
- hasDeposit && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-summary-row": true, className: cn(classNames?.summaryRow, classNames?.depositInfo), children: [
8949
- /* @__PURE__ */ jsx("span", { children: "Deposit" }),
8950
- /* @__PURE__ */ jsx("span", { children: depositType === "percentage" ? `${parsePrice(depositAmount)}%` : /* @__PURE__ */ jsx(Price, { amount: depositAmount }) })
8951
- ] })
9923
+ query.length >= 2 && !isLoading && /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
9924
+ /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: results.length }),
9925
+ " result",
9926
+ results.length !== 1 ? "s" : "",
9927
+ " for ",
9928
+ /* @__PURE__ */ jsxs("span", { className: "font-medium text-foreground", children: [
9929
+ "\u201C",
9930
+ query,
9931
+ "\u201D"
9932
+ ] })
9933
+ ] }),
9934
+ isLoading ? /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-5 animate-pulse", children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsxs("div", { children: [
9935
+ /* @__PURE__ */ jsx("div", { className: "aspect-square bg-muted rounded-[14px]" }),
9936
+ /* @__PURE__ */ jsxs("div", { className: "mt-3 space-y-2", children: [
9937
+ /* @__PURE__ */ jsx("div", { className: "h-4 w-3/4 bg-muted rounded" }),
9938
+ /* @__PURE__ */ jsx("div", { className: "h-3 w-1/2 bg-muted rounded" })
9939
+ ] })
9940
+ ] }, i)) }) : query.length >= 2 && results.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "text-center py-16", children: [
9941
+ /* @__PURE__ */ jsxs("p", { className: "text-lg font-medium", children: [
9942
+ "No results for \u201C",
9943
+ query,
9944
+ "\u201D"
8952
9945
  ] }),
8953
- /* @__PURE__ */ jsx(
8954
- "button",
9946
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Try a different search term" }),
9947
+ /* @__PURE__ */ jsx("button", { onClick: clear, className: "text-sm font-medium text-primary mt-4 hover:underline", children: "Clear search" })
9948
+ ] }) : results.length > 0 ? /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 lg:grid-cols-3 gap-5", children: results.map(
9949
+ (product) => renderCard ? /* @__PURE__ */ jsx(React3.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsx(
9950
+ ProductCard,
8955
9951
  {
8956
- type: "button",
8957
- onClick: handleConfirm,
8958
- disabled: isSubmitting,
8959
- "data-cimplify-booking-confirm": true,
8960
- className: classNames?.confirmButton,
8961
- children: isSubmitting ? isReschedule ? "Rescheduling\u2026" : "Adding to cart\u2026" : isReschedule ? "Reschedule" : "Confirm Booking"
8962
- }
9952
+ product,
9953
+ renderImage,
9954
+ renderLink,
9955
+ onQuickAdd
9956
+ },
9957
+ product.id
8963
9958
  )
8964
- ] })
9959
+ ) }) : null
8965
9960
  ] });
8966
9961
  }
8967
- var BOOKING_FILTERS = [
8968
- { label: "All", value: "all" },
8969
- { label: "Upcoming", value: "upcoming" },
8970
- { label: "Past", value: "past" }
8971
- ];
8972
- function BookingsPage({
8973
- title = "My Bookings",
8974
- bookings: bookingsProp,
8975
- onBookingNavigate,
8976
- onCancel,
8977
- onReschedule,
8978
- showFilters = true,
8979
- renderBooking,
9962
+ var SearchTemplate = /* @__PURE__ */ ((SearchTemplate2) => {
9963
+ SearchTemplate2["Default"] = "default";
9964
+ SearchTemplate2["Compact"] = "compact";
9965
+ return SearchTemplate2;
9966
+ })(SearchTemplate || {});
9967
+ var BUILT_IN_LAYOUTS5 = {
9968
+ ["default" /* Default */]: DefaultSearchLayout,
9969
+ ["compact" /* Compact */]: CompactSearchLayout
9970
+ };
9971
+ function SearchPage({
9972
+ template,
9973
+ layouts,
9974
+ categories,
9975
+ facets,
9976
+ searchOptions,
9977
+ placeholder,
9978
+ renderCard,
9979
+ renderImage,
9980
+ renderLink,
9981
+ onQuickAdd,
8980
9982
  className,
8981
9983
  classNames
8982
9984
  }) {
8983
- const [filter, setFilter] = useState("all");
8984
- const [selectedBooking, setSelectedBooking] = useState(null);
8985
- const handleBookingClick = useCallback(
8986
- (booking) => {
8987
- if (onBookingNavigate) {
8988
- onBookingNavigate(booking);
8989
- } else {
8990
- setSelectedBooking(booking);
9985
+ const search = useSearch(searchOptions);
9986
+ const key = template ?? "default" /* Default */;
9987
+ const Layout = layouts?.[key] ?? BUILT_IN_LAYOUTS5[key] ?? DefaultSearchLayout;
9988
+ return /* @__PURE__ */ jsx("div", { "data-cimplify-search-page": true, className: cn(className, classNames?.root), children: /* @__PURE__ */ jsx(
9989
+ Layout,
9990
+ {
9991
+ search,
9992
+ facets,
9993
+ categories,
9994
+ renderCard,
9995
+ renderImage,
9996
+ renderLink,
9997
+ onQuickAdd,
9998
+ placeholder
9999
+ }
10000
+ ) });
10001
+ }
10002
+ function DealsPage({
10003
+ title = "Deals & Offers",
10004
+ deals: dealsProp,
10005
+ productsOnSale: productsOnSaleProp,
10006
+ products: productsProp,
10007
+ locationId,
10008
+ renderImage,
10009
+ columns,
10010
+ className,
10011
+ classNames
10012
+ }) {
10013
+ const { deals: fetchedDeals, isLoading: dealsLoading } = useDeals({
10014
+ locationId,
10015
+ enabled: dealsProp === void 0
10016
+ });
10017
+ const { products: fetchedOnSale, isLoading: productsLoading } = useProductsOnSale({
10018
+ enabled: productsOnSaleProp === void 0
10019
+ });
10020
+ const deals = dealsProp ?? fetchedDeals;
10021
+ const onSale = productsOnSaleProp ?? fetchedOnSale;
10022
+ const isLoading = dealsLoading || productsLoading;
10023
+ const isEmpty = deals.length === 0 && onSale.length === 0;
10024
+ if (isLoading && isEmpty) {
10025
+ return /* @__PURE__ */ jsx(
10026
+ "div",
10027
+ {
10028
+ "data-cimplify-deals-page": true,
10029
+ "aria-busy": "true",
10030
+ className: cn(className, classNames?.root, classNames?.loading)
8991
10031
  }
8992
- },
8993
- [onBookingNavigate]
8994
- );
8995
- const handleBack = useCallback(() => {
8996
- setSelectedBooking(null);
8997
- }, []);
8998
- if (selectedBooking && !onBookingNavigate) {
8999
- return /* @__PURE__ */ jsx("div", { "data-cimplify-bookings-page": true, className: cn(className, classNames?.root), children: /* @__PURE__ */ jsxs("div", { "data-cimplify-bookings-detail": true, className: classNames?.detail, children: [
9000
- /* @__PURE__ */ jsx(
9001
- "button",
10032
+ );
10033
+ }
10034
+ return /* @__PURE__ */ jsxs("div", { "data-cimplify-deals-page": true, className: cn(className, classNames?.root), children: [
10035
+ /* @__PURE__ */ jsx("div", { "data-cimplify-deals-header": true, className: classNames?.header, children: /* @__PURE__ */ jsx("h1", { "data-cimplify-deals-title": true, className: classNames?.title, children: title }) }),
10036
+ deals.length > 0 && /* @__PURE__ */ jsx("div", { "data-cimplify-deals-banner-section": true, className: classNames?.bannerSection, children: /* @__PURE__ */ jsx(DealBanner, { deals }) }),
10037
+ (onSale.length > 0 || productsProp && productsProp.length > 0) && /* @__PURE__ */ jsxs("div", { "data-cimplify-deals-products": true, className: classNames?.productsSection, children: [
10038
+ /* @__PURE__ */ jsx("h2", { "data-cimplify-deals-products-title": true, className: classNames?.productsTitle, children: "On Sale Now" }),
10039
+ productsProp ? /* @__PURE__ */ jsx(
10040
+ ProductGrid,
9002
10041
  {
9003
- type: "button",
9004
- onClick: handleBack,
9005
- "data-cimplify-bookings-back": true,
9006
- className: classNames?.backButton,
9007
- children: "Back to bookings"
10042
+ products: productsProp,
10043
+ renderImage,
10044
+ columns
9008
10045
  }
9009
- ),
9010
- /* @__PURE__ */ jsx(
9011
- BookingCard,
10046
+ ) : /* @__PURE__ */ jsx("div", { "data-cimplify-deals-sale-list": true, children: onSale.map((dealInfo) => /* @__PURE__ */ jsx("div", { "data-cimplify-deals-sale-item": true, children: /* @__PURE__ */ jsx(
10047
+ SaleBadge,
9012
10048
  {
9013
- booking: selectedBooking,
9014
- onCancel,
9015
- onReschedule
10049
+ product: { id: dealInfo.product_id, name: dealInfo.deal_name },
10050
+ dealInfo,
10051
+ showOriginalPrice: true
9016
10052
  }
9017
- )
9018
- ] }) });
9019
- }
9020
- return /* @__PURE__ */ jsxs("div", { "data-cimplify-bookings-page": true, className: cn(className, classNames?.root), children: [
9021
- /* @__PURE__ */ jsx("div", { "data-cimplify-bookings-header": true, className: classNames?.header, children: /* @__PURE__ */ jsx("h1", { "data-cimplify-bookings-title": true, className: classNames?.title, children: title }) }),
9022
- showFilters && /* @__PURE__ */ jsx(
9023
- Tabs.Root,
9024
- {
9025
- value: filter,
9026
- onValueChange: (value) => setFilter(value),
9027
- children: /* @__PURE__ */ jsx(Tabs.List, { "data-cimplify-bookings-filters": true, className: classNames?.filters, children: BOOKING_FILTERS.map((f) => /* @__PURE__ */ jsx(
9028
- Tabs.Tab,
9029
- {
9030
- value: f.value,
9031
- "data-cimplify-booking-filter": true,
9032
- "data-selected": filter === f.value || void 0,
9033
- className: classNames?.filterButton,
9034
- children: f.label
9035
- },
9036
- f.value
9037
- )) })
9038
- }
9039
- ),
9040
- /* @__PURE__ */ jsx("div", { "data-cimplify-bookings-list": true, className: classNames?.list, children: /* @__PURE__ */ jsx(
9041
- BookingList,
9042
- {
9043
- bookings: bookingsProp,
9044
- filter,
9045
- onCancel,
9046
- onReschedule,
9047
- onBookingClick: handleBookingClick,
9048
- renderBooking
9049
- }
9050
- ) })
10053
+ ) }, `${dealInfo.product_id}-${dealInfo.deal_id}`)) })
10054
+ ] }),
10055
+ isEmpty && /* @__PURE__ */ jsx("div", { "data-cimplify-deals-empty": true, className: classNames?.empty, children: /* @__PURE__ */ jsx("p", { children: "No deals available right now. Check back soon!" }) })
9051
10056
  ] });
9052
10057
  }
9053
10058
  function LocationPicker({
@@ -9408,5 +10413,102 @@ function CurrencySelector({
9408
10413
  );
9409
10414
  }) });
9410
10415
  }
10416
+ var ANY_VALUE2 = "__any__";
10417
+ function roomToResource(room) {
10418
+ return {
10419
+ id: room.id,
10420
+ name: room.name,
10421
+ capacity: room.capacity,
10422
+ floor: room.floor,
10423
+ is_available: room.status === "available"
10424
+ };
10425
+ }
10426
+ function ResourcePicker({
10427
+ resources,
10428
+ selectedResourceId,
10429
+ onResourceSelect,
10430
+ showAnyOption = true,
10431
+ anyLabel = "Any available",
10432
+ renderImage,
10433
+ className,
10434
+ classNames
10435
+ }) {
10436
+ const groupValue = selectedResourceId === null ? ANY_VALUE2 : selectedResourceId ?? "";
10437
+ return /* @__PURE__ */ jsxs(
10438
+ RadioGroup,
10439
+ {
10440
+ "data-cimplify-resource-picker": true,
10441
+ className: cn("flex flex-col gap-2", className, classNames?.root),
10442
+ value: groupValue,
10443
+ onValueChange: (value) => {
10444
+ onResourceSelect?.(value === ANY_VALUE2 ? null : value);
10445
+ },
10446
+ children: [
10447
+ showAnyOption && /* @__PURE__ */ jsx(
10448
+ Radio.Root,
10449
+ {
10450
+ value: ANY_VALUE2,
10451
+ "data-cimplify-resource-option": true,
10452
+ "data-selected": selectedResourceId === null || void 0,
10453
+ "data-any": true,
10454
+ className: cn(
10455
+ "flex items-center gap-3 rounded-lg border border-border p-3 transition-colors cursor-pointer",
10456
+ "hover:bg-muted data-[checked]:border-primary data-[checked]:bg-primary/5",
10457
+ classNames?.option
10458
+ ),
10459
+ children: /* @__PURE__ */ jsx("span", { "data-cimplify-resource-name": true, className: cn("font-medium text-foreground", classNames?.name), children: anyLabel })
10460
+ }
10461
+ ),
10462
+ resources.map((resource) => {
10463
+ const unavailable = resource.is_available === false;
10464
+ return /* @__PURE__ */ jsxs(
10465
+ Radio.Root,
10466
+ {
10467
+ value: resource.id,
10468
+ disabled: unavailable,
10469
+ "data-cimplify-resource-option": true,
10470
+ "data-selected": selectedResourceId === resource.id || void 0,
10471
+ "data-unavailable": unavailable || void 0,
10472
+ className: cn(
10473
+ "flex items-center gap-3 rounded-lg border border-border p-3 transition-colors cursor-pointer",
10474
+ "hover:bg-muted data-[checked]:border-primary data-[checked]:bg-primary/5",
10475
+ unavailable && "opacity-50 cursor-not-allowed",
10476
+ classNames?.option,
10477
+ unavailable ? classNames?.unavailable : void 0
10478
+ ),
10479
+ children: [
10480
+ resource.image_url && (renderImage ? renderImage({
10481
+ src: resource.image_url,
10482
+ alt: resource.name,
10483
+ className: classNames?.image
10484
+ }) : /* @__PURE__ */ jsx(
10485
+ "img",
10486
+ {
10487
+ src: resource.image_url,
10488
+ alt: resource.name,
10489
+ "data-cimplify-resource-image": true,
10490
+ className: cn("w-10 h-10 rounded-lg object-cover", classNames?.image)
10491
+ }
10492
+ )),
10493
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5 flex-1 min-w-0", children: [
10494
+ /* @__PURE__ */ jsx("span", { "data-cimplify-resource-name": true, className: cn("font-medium text-foreground", classNames?.name), children: resource.name }),
10495
+ resource.description && /* @__PURE__ */ jsx("span", { "data-cimplify-resource-description": true, className: cn("text-sm text-muted-foreground truncate", classNames?.description), children: resource.description }),
10496
+ /* @__PURE__ */ jsxs("div", { "data-cimplify-resource-meta": true, className: cn("flex items-center gap-2 text-xs text-muted-foreground", classNames?.meta), children: [
10497
+ resource.capacity !== void 0 && /* @__PURE__ */ jsxs("span", { "data-cimplify-resource-capacity": true, className: classNames?.capacity, children: [
10498
+ "Up to ",
10499
+ resource.capacity
10500
+ ] }),
10501
+ resource.floor && /* @__PURE__ */ jsx("span", { "data-cimplify-resource-floor": true, className: classNames?.floor, children: resource.floor })
10502
+ ] })
10503
+ ] })
10504
+ ]
10505
+ },
10506
+ resource.id
10507
+ );
10508
+ })
10509
+ ]
10510
+ }
10511
+ );
10512
+ }
9411
10513
 
9412
- export { Ad, AdProvider, AddOnSelector, AddressElement, AuthElement, AvailabilityBadge, BillingPlanSelector, BookingCard, BookingList, BookingPage, BookingsPage, BundleSelector, CartPage, CartSummary, CataloguePage, CategoryFilter, CategoryGrid, CheckoutPage, CimplifyCheckout, CimplifyProvider, CollectionPage, CompositeSelector, CurrencySelector, CustomAttributesTable, DateSlotPicker, DealBanner, DealsPage, DefaultProductLayout, DeliveryEstimate, DigitalProductLayout, DiscountInput, ElementsProvider, FoodProductLayout, InventoryBadge, LocationPicker, MetadataStringList, OrderDetailPage, OrderHistory, OrderHistoryPage, OrderSummary, PaymentElement, Price, PriceRange, ProductCard, ProductCustomizer, ProductGrid, ProductImageGallery, ProductPage, ProductSheet, ProductTemplate, PropertiesTable, QuantitySelector, RecentlyViewed, RecommendationCarousel, RelatedProductsSection, ResourcePicker, SaleBadge, SearchInput, SearchPage, ServiceCard, ServiceGrid, ServiceProductLayout, SessionMessageBanner, SlotPicker, StaffPicker, StoreNav, TagPills, TwoColumnGrid, VariantSelector, VolumePricing, WholesaleProductLayout, cn, roomToResource, useActivityState, useAds, useAttributeDefinitions, useAvailableSlots, useBillingPlans, useBookings, useBootstrap, useBundles, useCart, useCategories, useCheckout, useCimplify, useCimplifyClient, useCollection, useCollections, useDeals, useDeliveryFee, useElements, useElementsReady, useFxRate, useLocations, useOptionalCimplify, useOrder, useOrders, useProduct, useProductAvailability, useProductDeals, useProductPrice, useProductSchedules, useProducts, useProductsOnSale, usePropertyFacets, useQuote, useRecommendations, useSearch, useServiceAvailability, useServices, useTaxonomies, useTaxonomy, useTaxonomyPath, useValidateDiscount, useVariantSelector };
10514
+ export { AccommodationCard, Ad, AdProvider, AddOnSelector, AddressElement, AuthElement, AvailabilityBadge, BillingPlanSelector, BookingCard, BookingList, BundleSelector, CardImage, CardShell, CardVariant, CartPage, CartSummary, CartTemplate, CatalogueCollectionLayout, CataloguePage, CatalogueTemplate, CategoryFilter, CategoryGrid, CheckoutPage, CimplifyCheckout, CimplifyProvider, CollectionPage, CollectionTemplate, CompactCartLayout, CompactCatalogueLayout, CompactSearchLayout, CompactServiceCard, CompositeSelector, CurrencySelector, CustomAttributesTable, DateSlotPicker, DealBanner, DealsPage, DefaultCartLayout, DefaultCatalogueLayout, DefaultCollectionLayout, DefaultProductLayout, DefaultSearchLayout, DeliveryEstimate, DigitalProductCard, DigitalProductLayout, DiscountInput, ElementsProvider, FeaturedCollectionLayout, FoodProductCard, FoodProductLayout, InventoryBadge, LeaseServiceCard, LocationPicker, MetadataStringList, OrderDetailPage, OrderHistory, OrderHistoryPage, OrderSummary, PaymentElement, Price, PriceRange, ProductCard, ProductCustomizer, ProductGrid, ProductImageGallery, ProductPage, ProductSheet, ProductTemplate, PropertiesTable, QuantitySelector, QuickAddButton, RecentlyViewed, RecommendationCarousel, RelatedProductsSection, RentalServiceCard, ResourcePicker, RetailProductCard, SaleBadge, ScheduleServiceCard, SearchInput, SearchPage, SearchTemplate, ServiceProductLayout, SessionMessageBanner, SlotPicker, SoldOutOverlay, StaffPicker, StandardServiceCard, StoreNav, SubscriptionCard, TagPills, TwoColumnGrid, VariantSelector, VolumePricing, WholesaleProductCard, WholesaleProductLayout, WishlistButton, cn, roomToResource, useActivityState, useAds, useAttributeDefinitions, useAvailableSlots, useBillingPlans, useBookings, useBootstrap, useBundles, useCart, useCategories, useCheckout, useCimplify, useCimplifyClient, useCollection, useCollections, useDeals, useDeliveryFee, useElements, useElementsReady, useFxRate, useLocations, useOptionalCimplify, useOrder, useOrders, useProduct, useProductAvailability, useProductDeals, useProductPrice, useProductSchedules, useProducts, useProductsOnSale, usePropertyFacets, useQuote, useRecommendations, useSearch, useServiceAvailability, useServices, useTaxonomies, useTaxonomy, useTaxonomyPath, useValidateDiscount, useVariantSelector };