@cimplify/sdk 0.25.0 → 0.27.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.
package/dist/react.js CHANGED
@@ -1,14 +1,14 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var chunkWMQXSDRC_js = require('./chunk-WMQXSDRC.js');
5
- var chunkI4F4Y3D4_js = require('./chunk-I4F4Y3D4.js');
4
+ var chunk4JSRPSNA_js = require('./chunk-4JSRPSNA.js');
5
+ var chunk2CGA3MUW_js = require('./chunk-2CGA3MUW.js');
6
6
  var chunkPEDLCL72_js = require('./chunk-PEDLCL72.js');
7
7
  var React3 = require('react');
8
8
  var jsxRuntime = require('react/jsx-runtime');
9
- var numberField = require('@base-ui/react/number-field');
10
9
  var clsx = require('clsx');
11
10
  var tailwindMerge = require('tailwind-merge');
11
+ var numberField = require('@base-ui/react/number-field');
12
12
  var radioGroup = require('@base-ui/react/radio-group');
13
13
  var radio = require('@base-ui/react/radio');
14
14
  var checkbox = require('@base-ui/react/checkbox');
@@ -1061,7 +1061,7 @@ var DEFAULT_COUNTRY = "US";
1061
1061
  function createDefaultClient() {
1062
1062
  const processRef = globalThis.process;
1063
1063
  const envPublicKey = processRef?.env?.NEXT_PUBLIC_CIMPLIFY_PUBLIC_KEY || "";
1064
- return chunkWMQXSDRC_js.createCimplifyClient({ publicKey: envPublicKey });
1064
+ return chunk4JSRPSNA_js.createCimplifyClient({ publicKey: envPublicKey });
1065
1065
  }
1066
1066
  function getStoredLocationId() {
1067
1067
  if (typeof window === "undefined" || !window.localStorage) {
@@ -1702,6 +1702,101 @@ function CimplifyCheckout({
1702
1702
  errorMessage && /* @__PURE__ */ jsxRuntime.jsx("p", { "data-cimplify-error": "", style: { marginTop: SPACE.sm, fontSize: 13, color: colors.error }, children: errorMessage })
1703
1703
  ] });
1704
1704
  }
1705
+ function cn(...inputs) {
1706
+ return tailwindMerge.twMerge(clsx.clsx(inputs));
1707
+ }
1708
+ var DEFAULT_LINK_URL = "https://link.cimplify.io";
1709
+ function CimplifyAccount({
1710
+ client: clientProp,
1711
+ linkUrl,
1712
+ section,
1713
+ appearance,
1714
+ onLogout,
1715
+ className
1716
+ }) {
1717
+ const context = useOptionalCimplify();
1718
+ const client = clientProp ?? context?.client;
1719
+ const resolvedLinkUrl = linkUrl || DEFAULT_LINK_URL;
1720
+ const iframeRef = React3.useRef(null);
1721
+ const [height, setHeight] = React3.useState(400);
1722
+ const [isReady, setIsReady] = React3.useState(false);
1723
+ const iframeSrc = React3.useMemo(() => {
1724
+ const path = section ? `/elements/account/${section}` : "/elements/account";
1725
+ const url = new URL(path, resolvedLinkUrl);
1726
+ if (client) {
1727
+ const businessId = client.getBusinessId?.() ?? "";
1728
+ if (businessId) url.searchParams.set("businessId", businessId);
1729
+ }
1730
+ return url.toString();
1731
+ }, [resolvedLinkUrl, section, client]);
1732
+ React3.useEffect(() => {
1733
+ function handleMessage(event) {
1734
+ if (!event.data || typeof event.data !== "object") return;
1735
+ if (iframeRef.current?.contentWindow && event.source !== iframeRef.current.contentWindow) {
1736
+ return;
1737
+ }
1738
+ switch (event.data.type) {
1739
+ case "ready":
1740
+ setIsReady(true);
1741
+ if (typeof event.data.height === "number") {
1742
+ setHeight(event.data.height);
1743
+ }
1744
+ sendInit();
1745
+ break;
1746
+ case "height_change":
1747
+ if (typeof event.data.height === "number") {
1748
+ setHeight(event.data.height);
1749
+ }
1750
+ break;
1751
+ case "logout_complete":
1752
+ onLogout?.();
1753
+ break;
1754
+ }
1755
+ }
1756
+ window.addEventListener("message", handleMessage);
1757
+ return () => window.removeEventListener("message", handleMessage);
1758
+ }, [appearance, client, onLogout]);
1759
+ function sendInit() {
1760
+ const contentWindow = iframeRef.current?.contentWindow;
1761
+ if (!contentWindow) return;
1762
+ const token = client?.getAccessToken?.();
1763
+ contentWindow.postMessage(
1764
+ {
1765
+ type: "init",
1766
+ token: token ?? void 0,
1767
+ appearance: appearance ?? void 0
1768
+ },
1769
+ resolvedLinkUrl
1770
+ );
1771
+ }
1772
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1773
+ "div",
1774
+ {
1775
+ "data-cimplify-account": true,
1776
+ className: cn("relative overflow-hidden", className),
1777
+ children: [
1778
+ !isReady && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-6 h-6 border-2 border-border border-t-foreground rounded-full animate-spin" }) }),
1779
+ /* @__PURE__ */ jsxRuntime.jsx(
1780
+ "iframe",
1781
+ {
1782
+ ref: iframeRef,
1783
+ src: iframeSrc,
1784
+ style: {
1785
+ border: "none",
1786
+ width: "100%",
1787
+ height: `${height}px`,
1788
+ display: isReady ? "block" : "none",
1789
+ overflow: "hidden",
1790
+ background: "transparent"
1791
+ },
1792
+ allow: "geolocation",
1793
+ sandbox: "allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox"
1794
+ }
1795
+ )
1796
+ ]
1797
+ }
1798
+ );
1799
+ }
1705
1800
  function Price({ amount, currency, className, prefix }) {
1706
1801
  const context = useOptionalCimplify();
1707
1802
  const resolvedCurrency = currency ?? context?.displayCurrency ?? "USD";
@@ -3215,19 +3310,19 @@ function AuthElement({
3215
3310
  }, [onReady, onAuthenticated, onRequiresOtp, onError]);
3216
3311
  React3.useEffect(() => {
3217
3312
  if (!elements || !containerRef.current) return;
3218
- const element = elements.create(chunkI4F4Y3D4_js.ELEMENT_TYPES.AUTH, { prefillEmail });
3313
+ const element = elements.create(chunk2CGA3MUW_js.ELEMENT_TYPES.AUTH, { prefillEmail });
3219
3314
  elementRef.current = element;
3220
- element.on(chunkI4F4Y3D4_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
3315
+ element.on(chunk2CGA3MUW_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
3221
3316
  element.on(
3222
- chunkI4F4Y3D4_js.EVENT_TYPES.AUTHENTICATED,
3317
+ chunk2CGA3MUW_js.EVENT_TYPES.AUTHENTICATED,
3223
3318
  (data) => onAuthenticatedRef.current?.(data)
3224
3319
  );
3225
3320
  element.on(
3226
- chunkI4F4Y3D4_js.EVENT_TYPES.REQUIRES_OTP,
3321
+ chunk2CGA3MUW_js.EVENT_TYPES.REQUIRES_OTP,
3227
3322
  (data) => onRequiresOtpRef.current?.(data)
3228
3323
  );
3229
3324
  element.on(
3230
- chunkI4F4Y3D4_js.EVENT_TYPES.ERROR,
3325
+ chunk2CGA3MUW_js.EVENT_TYPES.ERROR,
3231
3326
  (data) => onErrorRef.current?.(data)
3232
3327
  );
3233
3328
  element.mount(containerRef.current);
@@ -3256,15 +3351,15 @@ function AddressElement({
3256
3351
  }, [onReady, onChange, onError]);
3257
3352
  React3.useEffect(() => {
3258
3353
  if (!elements || !containerRef.current) return;
3259
- const element = elements.create(chunkI4F4Y3D4_js.ELEMENT_TYPES.ADDRESS, { mode });
3354
+ const element = elements.create(chunk2CGA3MUW_js.ELEMENT_TYPES.ADDRESS, { mode });
3260
3355
  elementRef.current = element;
3261
- element.on(chunkI4F4Y3D4_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
3356
+ element.on(chunk2CGA3MUW_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
3262
3357
  element.on(
3263
- chunkI4F4Y3D4_js.EVENT_TYPES.CHANGE,
3358
+ chunk2CGA3MUW_js.EVENT_TYPES.CHANGE,
3264
3359
  (data) => onChangeRef.current?.(data)
3265
3360
  );
3266
3361
  element.on(
3267
- chunkI4F4Y3D4_js.EVENT_TYPES.ERROR,
3362
+ chunk2CGA3MUW_js.EVENT_TYPES.ERROR,
3268
3363
  (data) => onErrorRef.current?.(data)
3269
3364
  );
3270
3365
  element.mount(containerRef.current);
@@ -3294,15 +3389,15 @@ function PaymentElement({
3294
3389
  }, [onReady, onChange, onError]);
3295
3390
  React3.useEffect(() => {
3296
3391
  if (!elements || !containerRef.current) return;
3297
- const element = elements.create(chunkI4F4Y3D4_js.ELEMENT_TYPES.PAYMENT, { amount, currency });
3392
+ const element = elements.create(chunk2CGA3MUW_js.ELEMENT_TYPES.PAYMENT, { amount, currency });
3298
3393
  elementRef.current = element;
3299
- element.on(chunkI4F4Y3D4_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
3394
+ element.on(chunk2CGA3MUW_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
3300
3395
  element.on(
3301
- chunkI4F4Y3D4_js.EVENT_TYPES.CHANGE,
3396
+ chunk2CGA3MUW_js.EVENT_TYPES.CHANGE,
3302
3397
  (data) => onChangeRef.current?.(data)
3303
3398
  );
3304
3399
  element.on(
3305
- chunkI4F4Y3D4_js.EVENT_TYPES.ERROR,
3400
+ chunk2CGA3MUW_js.EVENT_TYPES.ERROR,
3306
3401
  (data) => onErrorRef.current?.(data)
3307
3402
  );
3308
3403
  element.mount(containerRef.current);
@@ -3346,9 +3441,6 @@ function useCheckout() {
3346
3441
  );
3347
3442
  return { submit, process, isLoading };
3348
3443
  }
3349
- function cn(...inputs) {
3350
- return tailwindMerge.twMerge(clsx.clsx(inputs));
3351
- }
3352
3444
  function QuantitySelector({
3353
3445
  value,
3354
3446
  onChange,
@@ -3565,7 +3657,7 @@ function VariantSelector({
3565
3657
  {
3566
3658
  "data-cimplify-variant-name": true,
3567
3659
  className: cn("flex-1 min-w-0 text-sm", classNames?.name),
3568
- children: chunkWMQXSDRC_js.getVariantDisplayName(variant, productName)
3660
+ children: chunk4JSRPSNA_js.getVariantDisplayName(variant, productName)
3569
3661
  }
3570
3662
  ),
3571
3663
  /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-variant-pricing": true, className: cn("text-sm text-muted-foreground", classNames?.pricing), children: [
@@ -5101,7 +5193,7 @@ function CartLineItemRow({
5101
5193
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-item": true, className: classNames?.item, children: [
5102
5194
  /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-item-info": true, children: [
5103
5195
  /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-name": true, className: classNames?.itemName, children: item.product.name }),
5104
- item.variant && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-variant": true, children: chunkWMQXSDRC_js.getVariantDisplayName(item.variant, item.product.name) }),
5196
+ item.variant && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-variant": true, children: chunk4JSRPSNA_js.getVariantDisplayName(item.variant, item.product.name) }),
5105
5197
  item.addOnOptions && item.addOnOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-cart-item-addons": true, children: [
5106
5198
  "+ ",
5107
5199
  item.addOnOptions.map((opt) => opt.name).join(", ")
@@ -5626,7 +5718,7 @@ function FoodProductCard({
5626
5718
  const tags = product.tags || [];
5627
5719
  const isSignature = product.metadata?.is_signature === true;
5628
5720
  const isNew = product.metadata?.is_new === true;
5629
- const isComposite = product.type === chunkWMQXSDRC_js.PRODUCT_TYPE.Composite;
5721
+ const isComposite = product.type === chunk4JSRPSNA_js.PRODUCT_TYPE.Composite;
5630
5722
  return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, className, children: [
5631
5723
  /* @__PURE__ */ jsxRuntime.jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "square", renderImage, children: [
5632
5724
  isSignature && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute top-3 left-3 inline-flex items-center gap-1 text-[11px] font-semibold tracking-wide bg-amber-50 text-amber-700 border border-amber-200/60 px-2 py-0.5 rounded-md", children: [
@@ -6282,20 +6374,20 @@ var BUILT_IN_CARDS = {
6282
6374
  ["lease" /* Lease */]: LeaseServiceCard,
6283
6375
  ["subscription" /* Subscription */]: SubscriptionCard
6284
6376
  };
6285
- var RENTAL_UNITS = /* @__PURE__ */ new Set([chunkWMQXSDRC_js.DURATION_UNIT.Days, chunkWMQXSDRC_js.DURATION_UNIT.Hours]);
6286
- var LEASE_UNITS = /* @__PURE__ */ new Set([chunkWMQXSDRC_js.DURATION_UNIT.Weeks, chunkWMQXSDRC_js.DURATION_UNIT.Months, chunkWMQXSDRC_js.DURATION_UNIT.Years]);
6377
+ var RENTAL_UNITS = /* @__PURE__ */ new Set([chunk4JSRPSNA_js.DURATION_UNIT.Days, chunk4JSRPSNA_js.DURATION_UNIT.Hours]);
6378
+ var LEASE_UNITS = /* @__PURE__ */ new Set([chunk4JSRPSNA_js.DURATION_UNIT.Weeks, chunk4JSRPSNA_js.DURATION_UNIT.Months, chunk4JSRPSNA_js.DURATION_UNIT.Years]);
6287
6379
  function resolveCardVariant(product) {
6288
6380
  if (product.quantity_pricing && product.quantity_pricing.length > 1) {
6289
6381
  return "wholesale" /* Wholesale */;
6290
6382
  }
6291
- if (product.type === chunkWMQXSDRC_js.PRODUCT_TYPE.Digital) {
6383
+ if (product.type === chunk4JSRPSNA_js.PRODUCT_TYPE.Digital) {
6292
6384
  return "digital" /* Digital */;
6293
6385
  }
6294
- if (product.type === chunkWMQXSDRC_js.PRODUCT_TYPE.Service) {
6386
+ if (product.type === chunk4JSRPSNA_js.PRODUCT_TYPE.Service) {
6295
6387
  if (product.duration_unit && RENTAL_UNITS.has(product.duration_unit)) {
6296
6388
  return "rental" /* Rental */;
6297
6389
  }
6298
- if (product.duration_unit === chunkWMQXSDRC_js.DURATION_UNIT.Nights) {
6390
+ if (product.duration_unit === chunk4JSRPSNA_js.DURATION_UNIT.Nights) {
6299
6391
  return "accommodation" /* Accommodation */;
6300
6392
  }
6301
6393
  if (product.duration_unit && LEASE_UNITS.has(product.duration_unit)) {
@@ -6306,10 +6398,10 @@ function resolveCardVariant(product) {
6306
6398
  }
6307
6399
  return "standard" /* Standard */;
6308
6400
  }
6309
- if (product.render_hint === chunkWMQXSDRC_js.RENDER_HINT.Food) {
6401
+ if (product.render_hint === chunk4JSRPSNA_js.RENDER_HINT.Food) {
6310
6402
  return "food" /* Food */;
6311
6403
  }
6312
- if (product.render_hint === chunkWMQXSDRC_js.RENDER_HINT.Physical) {
6404
+ if (product.render_hint === chunk4JSRPSNA_js.RENDER_HINT.Physical) {
6313
6405
  return "retail" /* Retail */;
6314
6406
  }
6315
6407
  return "retail" /* Retail */;
@@ -7876,226 +7968,346 @@ function BookingList({
7876
7968
  booking.order_id
7877
7969
  )) });
7878
7970
  }
7879
-
7880
- // src/react/utils/format-duration.ts
7881
- var UNIT_LABELS3 = {
7882
- minutes: { singular: "min", plural: "min" },
7883
- hours: { singular: "hr", plural: "hrs" },
7884
- days: { singular: "day", plural: "days" },
7885
- nights: { singular: "night", plural: "nights" },
7886
- weeks: { singular: "week", plural: "weeks" },
7887
- months: { singular: "month", plural: "months" },
7888
- years: { singular: "year", plural: "years" }
7889
- };
7890
- function formatDuration4(value, unit) {
7891
- const resolved = unit ?? "minutes";
7892
- const labels = UNIT_LABELS3[resolved];
7893
- const label = value === 1 ? labels.singular : labels.plural;
7894
- return `${value} ${label}`;
7895
- }
7896
- var ASPECT_STYLES3 = {
7897
- square: { aspectRatio: "1/1" },
7898
- "4/3": { aspectRatio: "4/3" },
7899
- "16/10": { aspectRatio: "16/10" },
7900
- "3/4": { aspectRatio: "3/4" }
7901
- };
7902
- function ServiceCard({
7903
- service,
7904
- onBook,
7905
- href,
7906
- actionLabel = "Book",
7971
+ function DefaultCatalogueLayout({
7972
+ products,
7973
+ categories,
7974
+ facets,
7975
+ isLoading,
7976
+ selectedCategory,
7977
+ onCategoryChange,
7978
+ searchQuery,
7979
+ onSearchChange,
7980
+ sortBy,
7981
+ sortOrder,
7982
+ onSortChange,
7983
+ inStockOnly,
7984
+ onInStockChange,
7985
+ selectedTags,
7986
+ availableTags,
7987
+ onTagToggle,
7988
+ minPrice,
7989
+ maxPrice,
7990
+ onPriceRangeChange,
7991
+ page,
7992
+ totalPages,
7993
+ onPageChange,
7994
+ renderCard,
7907
7995
  renderImage,
7908
- children,
7909
- aspectRatio = "4/3",
7910
- className,
7911
- classNames
7996
+ renderLink,
7997
+ onQuickAdd,
7998
+ title = "Products",
7999
+ className
7912
8000
  }) {
7913
- const imageUrl = service.image_url;
7914
- const cardBody = children ?? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7915
- imageUrl && /* @__PURE__ */ jsxRuntime.jsx(
7916
- "div",
7917
- {
7918
- "data-cimplify-service-card-image-container": true,
7919
- className: cn("overflow-hidden rounded-t-xl", classNames?.imageContainer),
7920
- style: ASPECT_STYLES3[aspectRatio],
7921
- children: renderImage ? renderImage({
7922
- src: imageUrl,
7923
- alt: service.name,
7924
- className: classNames?.image
7925
- }) : /* @__PURE__ */ jsxRuntime.jsx(
7926
- "img",
8001
+ const hasSidebar = facets && facets.length > 0 || availableTags && availableTags.length > 0;
8002
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-catalogue-layout": "default", className: cn("space-y-6", className), children: [
8003
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4", children: [
8004
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
8005
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-bold tracking-tight", children: title }),
8006
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground mt-0.5", children: [
8007
+ products.length,
8008
+ " items"
8009
+ ] })
8010
+ ] }),
8011
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full sm:max-w-xs", children: [
8012
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
8013
+ /* @__PURE__ */ jsxRuntime.jsx(
8014
+ "input",
7927
8015
  {
7928
- src: imageUrl,
7929
- alt: service.name,
7930
- className: cn("w-full h-full object-cover transition-transform duration-300 group-hover:scale-105", classNames?.image),
7931
- "data-cimplify-service-card-image": true
8016
+ type: "search",
8017
+ value: searchQuery,
8018
+ onChange: (e) => onSearchChange(e.target.value),
8019
+ placeholder: "Search...",
8020
+ 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"
7932
8021
  }
7933
8022
  )
7934
- }
7935
- ),
7936
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-service-card-body": true, className: cn("p-4 flex flex-col gap-1.5", classNames?.body), children: [
7937
- /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-service-card-name": true, className: cn("font-semibold text-foreground leading-tight", classNames?.name), children: service.name }),
7938
- service.description && /* @__PURE__ */ jsxRuntime.jsx(
7939
- "span",
8023
+ ] })
8024
+ ] }),
8025
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3", children: [
8026
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5 overflow-x-auto pb-1", children: [
8027
+ /* @__PURE__ */ jsxRuntime.jsx(
8028
+ "button",
8029
+ {
8030
+ onClick: () => onCategoryChange(null),
8031
+ className: cn(
8032
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
8033
+ !selectedCategory ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
8034
+ ),
8035
+ children: "All"
8036
+ }
8037
+ ),
8038
+ categories.map((cat) => /* @__PURE__ */ jsxRuntime.jsx(
8039
+ "button",
8040
+ {
8041
+ onClick: () => onCategoryChange(selectedCategory === cat.id ? null : cat.id),
8042
+ className: cn(
8043
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
8044
+ selectedCategory === cat.id ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
8045
+ ),
8046
+ children: cat.name
8047
+ },
8048
+ cat.id
8049
+ ))
8050
+ ] }),
8051
+ /* @__PURE__ */ jsxRuntime.jsxs(
8052
+ "select",
7940
8053
  {
7941
- "data-cimplify-service-card-description": true,
7942
- className: cn("text-sm text-muted-foreground line-clamp-2", classNames?.description),
7943
- children: service.description
8054
+ value: `${sortBy}:${sortOrder}`,
8055
+ onChange: (e) => {
8056
+ const [by, order] = e.target.value.split(":");
8057
+ onSortChange(by, order);
8058
+ },
8059
+ className: "text-xs border border-border rounded-lg px-2 py-1.5 bg-background outline-none shrink-0",
8060
+ children: [
8061
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "created_at:desc", children: "Newest" }),
8062
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "price:asc", children: "Price: Low to High" }),
8063
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "price:desc", children: "Price: High to Low" }),
8064
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "name:asc", children: "Name: A-Z" })
8065
+ ]
7944
8066
  }
7945
- ),
7946
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-service-card-meta": true, className: cn("flex items-center gap-2 mt-1 text-sm", classNames?.meta), children: [
7947
- /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-service-card-duration": true, className: cn("text-muted-foreground", classNames?.duration), children: formatDuration4(service.duration_minutes, service.duration_unit) }),
7948
- service.price && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-service-card-price": true, className: cn("font-medium text-foreground", classNames?.price), children: /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: service.price }) })
7949
- ] })
8067
+ )
7950
8068
  ] }),
7951
- !href && onBook && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-service-card-action": true, className: cn("px-4 pb-4 pt-1 text-sm font-medium text-primary", classNames?.action), children: actionLabel })
8069
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: hasSidebar ? "flex gap-6" : "", children: [
8070
+ hasSidebar && /* @__PURE__ */ jsxRuntime.jsxs("aside", { className: "hidden lg:block w-60 shrink-0 space-y-6", children: [
8071
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
8072
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: "In stock only" }),
8073
+ /* @__PURE__ */ jsxRuntime.jsx(
8074
+ "button",
8075
+ {
8076
+ onClick: () => onInStockChange(!inStockOnly),
8077
+ className: cn("w-10 h-6 rounded-full transition-colors relative", inStockOnly ? "bg-foreground" : "bg-border"),
8078
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("absolute top-1 w-4 h-4 rounded-full bg-background transition-transform shadow-sm", inStockOnly ? "left-5" : "left-1") })
8079
+ }
8080
+ )
8081
+ ] }),
8082
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
8083
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-semibold mb-2", children: "Price Range" }),
8084
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
8085
+ /* @__PURE__ */ jsxRuntime.jsx(
8086
+ "input",
8087
+ {
8088
+ type: "number",
8089
+ placeholder: "Min",
8090
+ value: minPrice,
8091
+ onChange: (e) => onPriceRangeChange(e.target.value, maxPrice),
8092
+ 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"
8093
+ }
8094
+ ),
8095
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-xs", children: "\u2013" }),
8096
+ /* @__PURE__ */ jsxRuntime.jsx(
8097
+ "input",
8098
+ {
8099
+ type: "number",
8100
+ placeholder: "Max",
8101
+ value: maxPrice,
8102
+ onChange: (e) => onPriceRangeChange(minPrice, e.target.value),
8103
+ 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"
8104
+ }
8105
+ )
8106
+ ] })
8107
+ ] }),
8108
+ facets?.map((facet) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
8109
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-semibold mb-2", children: facet.name }),
8110
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1.5", children: facet.values.slice(0, 8).map((fv) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2 text-sm cursor-pointer group", children: [
8111
+ /* @__PURE__ */ jsxRuntime.jsx("input", { type: "checkbox", className: "w-3.5 h-3.5 accent-foreground rounded" }),
8112
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground group-hover:text-foreground transition-colors flex-1", children: fv.value }),
8113
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground/60", children: fv.count })
8114
+ ] }, fv.value)) })
8115
+ ] }, facet.slug)),
8116
+ availableTags && availableTags.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
8117
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-semibold mb-2", children: "Tags" }),
8118
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1.5", children: availableTags.map((tag) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2 text-sm cursor-pointer group", children: [
8119
+ /* @__PURE__ */ jsxRuntime.jsx(
8120
+ "input",
8121
+ {
8122
+ type: "checkbox",
8123
+ checked: selectedTags.includes(tag),
8124
+ onChange: () => onTagToggle(tag),
8125
+ className: "w-3.5 h-3.5 accent-foreground rounded"
8126
+ }
8127
+ ),
8128
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground group-hover:text-foreground transition-colors", children: tag })
8129
+ ] }, tag)) })
8130
+ ] })
8131
+ ] }),
8132
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
8133
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 gap-4 animate-pulse", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
8134
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-square bg-muted rounded-[14px]" }),
8135
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 space-y-2", children: [
8136
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-3/4 bg-muted rounded" }),
8137
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-3 w-1/2 bg-muted rounded" })
8138
+ ] })
8139
+ ] }, i)) }) : products.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-16", children: [
8140
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg font-medium", children: "No products found" }),
8141
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Try adjusting your filters" })
8142
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 gap-4", children: products.map(
8143
+ (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React3__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
8144
+ ProductCard,
8145
+ {
8146
+ product,
8147
+ renderImage,
8148
+ renderLink,
8149
+ onQuickAdd
8150
+ },
8151
+ product.id
8152
+ )
8153
+ ) }),
8154
+ totalPages > 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-2 pt-8", children: [
8155
+ /* @__PURE__ */ jsxRuntime.jsx(
8156
+ "button",
8157
+ {
8158
+ disabled: page <= 1,
8159
+ onClick: () => onPageChange(page - 1),
8160
+ className: "text-sm px-3 py-1.5 border border-border rounded-lg disabled:opacity-40 hover:bg-muted transition-colors",
8161
+ children: "Previous"
8162
+ }
8163
+ ),
8164
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-muted-foreground tabular-nums px-2", children: [
8165
+ page,
8166
+ " / ",
8167
+ totalPages
8168
+ ] }),
8169
+ /* @__PURE__ */ jsxRuntime.jsx(
8170
+ "button",
8171
+ {
8172
+ disabled: page >= totalPages,
8173
+ onClick: () => onPageChange(page + 1),
8174
+ className: "text-sm px-3 py-1.5 border border-border rounded-lg disabled:opacity-40 hover:bg-muted transition-colors",
8175
+ children: "Next"
8176
+ }
8177
+ )
8178
+ ] })
8179
+ ] })
8180
+ ] })
7952
8181
  ] });
7953
- const cardClasses = cn(
7954
- "group block w-full rounded-xl border border-border bg-background text-left transition-shadow duration-200 hover:shadow-md",
7955
- !service.is_available && "opacity-60",
7956
- className,
7957
- classNames?.root
7958
- );
7959
- if (href) {
7960
- return /* @__PURE__ */ jsxRuntime.jsx(
7961
- "a",
7962
- {
7963
- href,
7964
- "data-cimplify-service-card": true,
7965
- "data-available": service.is_available || void 0,
7966
- className: cn(cardClasses, "no-underline text-[inherit]"),
7967
- children: cardBody
7968
- }
7969
- );
7970
- }
7971
- return /* @__PURE__ */ jsxRuntime.jsx(
7972
- "button",
7973
- {
7974
- type: "button",
7975
- onClick: () => onBook?.(service),
7976
- disabled: !service.is_available,
7977
- "data-cimplify-service-card": true,
7978
- "data-available": service.is_available || void 0,
7979
- className: cn(cardClasses, "cursor-pointer font-[inherit] p-0 border-border"),
7980
- children: cardBody
7981
- }
7982
- );
7983
8182
  }
7984
- function ServiceGrid({
7985
- services: servicesProp,
7986
- columns,
7987
- onServiceSelect,
7988
- getServiceHref,
8183
+ function CompactCatalogueLayout({
8184
+ products,
8185
+ categories,
8186
+ isLoading,
8187
+ selectedCategory,
8188
+ onCategoryChange,
8189
+ searchQuery,
8190
+ onSearchChange,
7989
8191
  renderCard,
7990
8192
  renderImage,
7991
- availableOnly = true,
7992
- actionLabel,
7993
- emptyMessage = "No services available",
7994
- className,
7995
- classNames
8193
+ renderLink,
8194
+ onQuickAdd,
8195
+ title = "Menu",
8196
+ className
7996
8197
  }) {
7997
- const rawId = React3__default.default.useId();
7998
- const gridId = `cimplify-service-grid-${rawId.replace(/:/g, "")}`;
7999
- const { services: fetched, isLoading } = useServices({
8000
- enabled: servicesProp === void 0
8001
- });
8002
- const allServices = servicesProp ?? fetched;
8003
- const services = availableOnly ? allServices.filter((s) => s.is_available) : allServices;
8004
- const sm = columns?.sm ?? 1;
8005
- const md = columns?.md ?? 2;
8006
- const lg = columns?.lg ?? 3;
8007
- const xl = columns?.xl ?? 4;
8008
- if (isLoading && services.length === 0) {
8009
- return /* @__PURE__ */ jsxRuntime.jsx(
8010
- "div",
8011
- {
8012
- "data-cimplify-service-grid": true,
8013
- "aria-busy": "true",
8014
- className: cn(className, classNames?.root, classNames?.loading)
8015
- }
8016
- );
8017
- }
8018
- if (services.length === 0) {
8019
- return /* @__PURE__ */ jsxRuntime.jsx(
8020
- "div",
8021
- {
8022
- "data-cimplify-service-grid": true,
8023
- "data-empty": true,
8024
- className: cn(className, classNames?.root, classNames?.empty),
8025
- children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: emptyMessage })
8026
- }
8027
- );
8028
- }
8029
- const css = [
8030
- `#${gridId}{display:grid;grid-template-columns:repeat(${sm},1fr);gap:1rem}`,
8031
- `@media(min-width:768px){#${gridId}{grid-template-columns:repeat(${md},1fr)}}`,
8032
- `@media(min-width:1024px){#${gridId}{grid-template-columns:repeat(${lg},1fr)}}`,
8033
- `@media(min-width:1280px){#${gridId}{grid-template-columns:repeat(${xl},1fr)}}`
8034
- ].join("");
8035
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
8036
- /* @__PURE__ */ jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: css } }),
8037
- /* @__PURE__ */ jsxRuntime.jsx(
8038
- "div",
8039
- {
8040
- id: gridId,
8041
- "data-cimplify-service-grid": true,
8042
- className: cn(className, classNames?.root),
8043
- children: services.map((service) => /* @__PURE__ */ jsxRuntime.jsx(
8044
- "div",
8198
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-catalogue-layout": "compact", className: cn("space-y-6", className), children: [
8199
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-bold tracking-tight", children: title }),
8200
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col sm:flex-row items-start sm:items-center gap-3", children: [
8201
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5 overflow-x-auto pb-1 flex-1", children: [
8202
+ /* @__PURE__ */ jsxRuntime.jsx(
8203
+ "button",
8045
8204
  {
8046
- "data-cimplify-service-grid-item": true,
8047
- className: classNames?.item,
8048
- children: renderCard ? renderCard(service) : /* @__PURE__ */ jsxRuntime.jsx(
8049
- ServiceCard,
8050
- {
8051
- service,
8052
- onBook: onServiceSelect,
8053
- href: getServiceHref?.(service),
8054
- actionLabel,
8055
- renderImage
8056
- }
8057
- )
8205
+ onClick: () => onCategoryChange(null),
8206
+ className: cn(
8207
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
8208
+ !selectedCategory ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
8209
+ ),
8210
+ children: "All"
8211
+ }
8212
+ ),
8213
+ categories.map((cat) => /* @__PURE__ */ jsxRuntime.jsx(
8214
+ "button",
8215
+ {
8216
+ onClick: () => onCategoryChange(selectedCategory === cat.id ? null : cat.id),
8217
+ className: cn(
8218
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
8219
+ selectedCategory === cat.id ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
8220
+ ),
8221
+ children: cat.name
8058
8222
  },
8059
- service.id
8223
+ cat.id
8060
8224
  ))
8061
- }
8062
- )
8225
+ ] }),
8226
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full sm:max-w-[200px]", children: [
8227
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
8228
+ /* @__PURE__ */ jsxRuntime.jsx(
8229
+ "input",
8230
+ {
8231
+ type: "search",
8232
+ value: searchQuery,
8233
+ onChange: (e) => onSearchChange(e.target.value),
8234
+ placeholder: "Search...",
8235
+ 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"
8236
+ }
8237
+ )
8238
+ ] })
8239
+ ] }),
8240
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 lg:grid-cols-3 gap-5 animate-pulse", children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
8241
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-square bg-muted rounded-[14px]" }),
8242
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 space-y-2", children: [
8243
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-3/4 bg-muted rounded" }),
8244
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-3 w-1/2 bg-muted rounded" })
8245
+ ] })
8246
+ ] }, i)) }) : products.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-16", children: [
8247
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg font-medium", children: "No items found" }),
8248
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Try a different category or search" })
8249
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 lg:grid-cols-3 gap-5", children: products.map(
8250
+ (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React3__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
8251
+ ProductCard,
8252
+ {
8253
+ product,
8254
+ renderImage,
8255
+ renderLink,
8256
+ onQuickAdd
8257
+ },
8258
+ product.id
8259
+ )
8260
+ ) })
8063
8261
  ] });
8064
8262
  }
8263
+ var CatalogueTemplate = /* @__PURE__ */ ((CatalogueTemplate2) => {
8264
+ CatalogueTemplate2["Default"] = "default";
8265
+ CatalogueTemplate2["Compact"] = "compact";
8266
+ return CatalogueTemplate2;
8267
+ })(CatalogueTemplate || {});
8268
+ var BUILT_IN_LAYOUTS = {
8269
+ ["default" /* Default */]: DefaultCatalogueLayout,
8270
+ ["compact" /* Compact */]: CompactCatalogueLayout
8271
+ };
8272
+ function useDebounce(value, delay) {
8273
+ const [debounced, setDebounced] = React3__default.default.useState(value);
8274
+ React3__default.default.useEffect(() => {
8275
+ const timer = setTimeout(() => setDebounced(value), delay);
8276
+ return () => clearTimeout(timer);
8277
+ }, [value, delay]);
8278
+ return debounced;
8279
+ }
8065
8280
  function CataloguePage({
8066
- title = "Products",
8281
+ template,
8282
+ layouts,
8283
+ title,
8067
8284
  products: productsProp,
8068
8285
  categories: categoriesProp,
8069
- showFilter = true,
8070
- showSearch = true,
8071
- showSort = false,
8072
- showInStockFilter = false,
8073
- showPriceRange = false,
8074
- showTagsFilter = false,
8286
+ facets,
8075
8287
  availableTags,
8076
- defaultSort,
8077
8288
  pageSize,
8078
- onProductClick,
8079
- onCategoryClick,
8289
+ defaultSort,
8080
8290
  renderCard,
8081
8291
  renderImage,
8082
- columns,
8292
+ renderLink,
8293
+ onQuickAdd,
8294
+ onProductClick,
8083
8295
  className,
8084
8296
  classNames
8085
8297
  }) {
8086
- const [selectedCategoryId, setSelectedCategoryId] = React3.useState(null);
8298
+ const [selectedCategory, setSelectedCategory] = React3.useState(null);
8087
8299
  const [searchQuery, setSearchQuery] = React3.useState("");
8088
- const [sortBy, setSortBy] = React3.useState(defaultSort?.by ?? "name");
8089
- const [sortOrder, setSortOrder] = React3.useState(defaultSort?.order ?? "asc");
8300
+ const [sortBy, setSortBy] = React3.useState(defaultSort?.by ?? "created_at");
8301
+ const [sortOrder, setSortOrder] = React3.useState(defaultSort?.order ?? "desc");
8090
8302
  const [inStockOnly, setInStockOnly] = React3.useState(false);
8091
8303
  const [selectedTags, setSelectedTags] = React3.useState([]);
8092
8304
  const [minPrice, setMinPrice] = React3.useState("");
8093
8305
  const [maxPrice, setMaxPrice] = React3.useState("");
8094
8306
  const [page, setPage] = React3.useState(1);
8095
8307
  const debouncedSearch = useDebounce(searchQuery, 300);
8096
- const { products: fetchedProducts, isLoading: productsLoading, pagination } = useProducts({
8308
+ const { products: fetchedProducts, isLoading, pagination } = useProducts({
8097
8309
  enabled: productsProp === void 0,
8098
- category: selectedCategoryId ?? void 0,
8310
+ category: selectedCategory ?? void 0,
8099
8311
  search: debouncedSearch.length >= 2 ? debouncedSearch : void 0,
8100
8312
  sort_by: sortBy,
8101
8313
  sort_order: sortOrder,
@@ -8107,185 +8319,66 @@ function CataloguePage({
8107
8319
  limit: pageSize
8108
8320
  });
8109
8321
  const { categories: fetchedCategories } = useCategories({
8110
- enabled: showFilter && categoriesProp === void 0
8322
+ enabled: categoriesProp === void 0
8111
8323
  });
8112
- const allProducts = productsProp ?? fetchedProducts;
8324
+ const products = productsProp ?? fetchedProducts;
8113
8325
  const categories = categoriesProp ?? fetchedCategories;
8114
- const handleCategorySelect = React3.useCallback(
8115
- (id) => {
8116
- setSelectedCategoryId(id);
8117
- setPage(1);
8118
- if (id) {
8119
- const cat = categories.find((c) => c.id === id);
8120
- if (cat) onCategoryClick?.(cat);
8121
- }
8122
- },
8123
- [categories, onCategoryClick]
8124
- );
8125
- const handleTagToggle = React3.useCallback((tag) => {
8126
- setSelectedTags(
8326
+ const totalPages = pagination?.total_pages ?? 1;
8327
+ const handleCategoryChange = React3.useCallback((id) => {
8328
+ setSelectedCategory(id);
8329
+ setPage(1);
8330
+ }, []);
8331
+ const handleSortChange = React3.useCallback((by, order) => {
8332
+ setSortBy(by);
8333
+ setSortOrder(order);
8334
+ setPage(1);
8335
+ }, []);
8336
+ const handleTagToggle = React3.useCallback((tag) => {
8337
+ setSelectedTags(
8127
8338
  (prev) => prev.includes(tag) ? prev.filter((t) => t !== tag) : [...prev, tag]
8128
8339
  );
8129
8340
  setPage(1);
8130
8341
  }, []);
8131
- const totalPages = pagination?.total_pages ?? 1;
8132
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-catalogue-page": true, className: cn(className, classNames?.root), children: [
8133
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-catalogue-header": true, className: classNames?.header, children: [
8134
- /* @__PURE__ */ jsxRuntime.jsx("h1", { "data-cimplify-catalogue-title": true, className: classNames?.title, children: title }),
8135
- showSearch && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-catalogue-search": true, className: classNames?.searchContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
8136
- SearchInput,
8137
- {
8138
- onResultClick: onProductClick,
8139
- searchOptions: { category: selectedCategoryId ?? void 0 }
8140
- }
8141
- ) })
8142
- ] }),
8143
- showFilter && categories.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-catalogue-filter": true, className: classNames?.filterContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
8144
- CategoryFilter,
8145
- {
8146
- selectedId: selectedCategoryId,
8147
- onSelect: handleCategorySelect
8148
- }
8149
- ) }),
8150
- (showSort || showInStockFilter || showPriceRange || showTagsFilter) && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-catalogue-toolbar": true, className: cn("flex flex-wrap items-center gap-3", classNames?.toolbar), children: [
8151
- showSort && /* @__PURE__ */ jsxRuntime.jsxs(
8152
- "select",
8153
- {
8154
- "data-cimplify-sort": true,
8155
- value: `${sortBy}:${sortOrder}`,
8156
- onChange: (e) => {
8157
- const [by, order] = e.target.value.split(":");
8158
- setSortBy(by);
8159
- setSortOrder(order);
8160
- setPage(1);
8161
- },
8162
- className: "rounded-md border border-input bg-background px-3 py-1.5 text-sm",
8163
- children: [
8164
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "name:asc", children: "Name A\u2013Z" }),
8165
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "name:desc", children: "Name Z\u2013A" }),
8166
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "price:asc", children: "Price: Low to High" }),
8167
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "price:desc", children: "Price: High to Low" }),
8168
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "created_at:desc", children: "Newest" }),
8169
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "created_at:asc", children: "Oldest" }),
8170
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "updated_at:desc", children: "Recently Updated" })
8171
- ]
8172
- }
8173
- ),
8174
- showInStockFilter && /* @__PURE__ */ jsxRuntime.jsxs("label", { "data-cimplify-stock-filter": true, className: "flex items-center gap-1.5 text-sm cursor-pointer", children: [
8175
- /* @__PURE__ */ jsxRuntime.jsx(
8176
- "input",
8177
- {
8178
- type: "checkbox",
8179
- checked: inStockOnly,
8180
- onChange: (e) => {
8181
- setInStockOnly(e.target.checked);
8182
- setPage(1);
8183
- },
8184
- className: "accent-primary"
8185
- }
8186
- ),
8187
- "In stock only"
8188
- ] }),
8189
- showPriceRange && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-price-range": true, className: "flex items-center gap-1.5", children: [
8190
- /* @__PURE__ */ jsxRuntime.jsx(
8191
- "input",
8192
- {
8193
- type: "number",
8194
- placeholder: "Min",
8195
- value: minPrice,
8196
- onChange: (e) => {
8197
- setMinPrice(e.target.value);
8198
- setPage(1);
8199
- },
8200
- className: "w-20 rounded-md border border-input bg-background px-2 py-1.5 text-sm",
8201
- min: 0,
8202
- step: "0.01"
8203
- }
8204
- ),
8205
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-sm", children: "\u2013" }),
8206
- /* @__PURE__ */ jsxRuntime.jsx(
8207
- "input",
8208
- {
8209
- type: "number",
8210
- placeholder: "Max",
8211
- value: maxPrice,
8212
- onChange: (e) => {
8213
- setMaxPrice(e.target.value);
8214
- setPage(1);
8215
- },
8216
- className: "w-20 rounded-md border border-input bg-background px-2 py-1.5 text-sm",
8217
- min: 0,
8218
- step: "0.01"
8219
- }
8220
- )
8221
- ] }),
8222
- showTagsFilter && availableTags && availableTags.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-tags-filter": true, className: "flex flex-wrap gap-1.5", children: availableTags.map((tag) => /* @__PURE__ */ jsxRuntime.jsx(
8223
- "button",
8224
- {
8225
- type: "button",
8226
- onClick: () => handleTagToggle(tag),
8227
- className: cn(
8228
- "rounded-full px-3 py-1 text-xs font-medium border transition-colors",
8229
- selectedTags.includes(tag) ? "bg-primary text-primary-foreground border-primary" : "bg-background text-foreground border-input hover:bg-muted"
8230
- ),
8231
- children: tag
8232
- },
8233
- tag
8234
- )) })
8235
- ] }),
8236
- /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-catalogue-grid": true, className: classNames?.gridContainer, children: productsLoading && !productsProp ? /* @__PURE__ */ jsxRuntime.jsx(
8237
- "div",
8238
- {
8239
- "data-cimplify-catalogue-loading": true,
8240
- "aria-busy": "true",
8241
- className: classNames?.loading
8242
- }
8243
- ) : /* @__PURE__ */ jsxRuntime.jsx(
8244
- ProductGrid,
8245
- {
8246
- products: allProducts,
8247
- renderCard,
8248
- renderImage,
8249
- columns,
8250
- emptyMessage: "No products found"
8251
- }
8252
- ) }),
8253
- totalPages > 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-catalogue-pagination": true, className: cn("flex items-center justify-center gap-2 pt-6", classNames?.pagination), children: [
8254
- /* @__PURE__ */ jsxRuntime.jsx(
8255
- "button",
8256
- {
8257
- type: "button",
8258
- disabled: page <= 1,
8259
- onClick: () => setPage((p) => Math.max(1, p - 1)),
8260
- className: "rounded-md border border-input bg-background px-3 py-1.5 text-sm disabled:opacity-40",
8261
- children: "Previous"
8262
- }
8263
- ),
8264
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-muted-foreground tabular-nums", children: [
8265
- page,
8266
- " / ",
8267
- totalPages
8268
- ] }),
8269
- /* @__PURE__ */ jsxRuntime.jsx(
8270
- "button",
8271
- {
8272
- type: "button",
8273
- disabled: page >= totalPages,
8274
- onClick: () => setPage((p) => p + 1),
8275
- className: "rounded-md border border-input bg-background px-3 py-1.5 text-sm disabled:opacity-40",
8276
- children: "Next"
8277
- }
8278
- )
8279
- ] })
8280
- ] });
8281
- }
8282
- function useDebounce(value, delay) {
8283
- const [debounced, setDebounced] = React3__default.default.useState(value);
8284
- React3__default.default.useEffect(() => {
8285
- const timer = setTimeout(() => setDebounced(value), delay);
8286
- return () => clearTimeout(timer);
8287
- }, [value, delay]);
8288
- return debounced;
8342
+ const handlePriceRangeChange = React3.useCallback((min, max) => {
8343
+ setMinPrice(min);
8344
+ setMaxPrice(max);
8345
+ setPage(1);
8346
+ }, []);
8347
+ const key = template ?? "default" /* Default */;
8348
+ const Layout = layouts?.[key] ?? BUILT_IN_LAYOUTS[key] ?? DefaultCatalogueLayout;
8349
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-catalogue-page": true, className: cn(className, classNames?.root), children: /* @__PURE__ */ jsxRuntime.jsx(
8350
+ Layout,
8351
+ {
8352
+ products,
8353
+ categories,
8354
+ facets,
8355
+ isLoading,
8356
+ selectedCategory,
8357
+ onCategoryChange: handleCategoryChange,
8358
+ searchQuery,
8359
+ onSearchChange: setSearchQuery,
8360
+ sortBy,
8361
+ sortOrder,
8362
+ onSortChange: handleSortChange,
8363
+ inStockOnly,
8364
+ onInStockChange: setInStockOnly,
8365
+ selectedTags,
8366
+ availableTags,
8367
+ onTagToggle: handleTagToggle,
8368
+ minPrice,
8369
+ maxPrice,
8370
+ onPriceRangeChange: handlePriceRangeChange,
8371
+ page,
8372
+ totalPages,
8373
+ onPageChange: setPage,
8374
+ renderCard,
8375
+ renderImage,
8376
+ renderLink,
8377
+ onQuickAdd,
8378
+ onProductClick,
8379
+ title
8380
+ }
8381
+ ) });
8289
8382
  }
8290
8383
  function TwoColumnGrid({
8291
8384
  left,
@@ -8915,7 +9008,7 @@ var ProductTemplate = /* @__PURE__ */ ((ProductTemplate2) => {
8915
9008
  ProductTemplate2["Physical"] = "physical";
8916
9009
  return ProductTemplate2;
8917
9010
  })(ProductTemplate || {});
8918
- var BUILT_IN_LAYOUTS = {
9011
+ var BUILT_IN_LAYOUTS2 = {
8919
9012
  ["food" /* Food */]: FoodProductLayout,
8920
9013
  ["wholesale" /* Wholesale */]: WholesaleProductLayout,
8921
9014
  ["service" /* Service */]: ServiceProductLayout,
@@ -8930,16 +9023,16 @@ function resolveTemplateKey(product) {
8930
9023
  if (product.quantity_pricing && product.quantity_pricing.length > 1) {
8931
9024
  return "wholesale" /* Wholesale */;
8932
9025
  }
8933
- if (product.type === chunkWMQXSDRC_js.PRODUCT_TYPE.Service) {
9026
+ if (product.type === chunk4JSRPSNA_js.PRODUCT_TYPE.Service) {
8934
9027
  return "service" /* Service */;
8935
9028
  }
8936
- if (product.type === chunkWMQXSDRC_js.PRODUCT_TYPE.Digital) {
9029
+ if (product.type === chunk4JSRPSNA_js.PRODUCT_TYPE.Digital) {
8937
9030
  return "digital" /* Digital */;
8938
9031
  }
8939
- if (product.render_hint === chunkWMQXSDRC_js.RENDER_HINT.Food) {
9032
+ if (product.render_hint === chunk4JSRPSNA_js.RENDER_HINT.Food) {
8940
9033
  return "food" /* Food */;
8941
9034
  }
8942
- if (product.render_hint === chunkWMQXSDRC_js.RENDER_HINT.Physical) {
9035
+ if (product.render_hint === chunk4JSRPSNA_js.RENDER_HINT.Physical) {
8943
9036
  return "physical" /* Physical */;
8944
9037
  }
8945
9038
  return "default" /* Default */;
@@ -8952,8 +9045,8 @@ function resolveLayout(product, pages, templates) {
8952
9045
  if (templates?.[key]) {
8953
9046
  return templates[key];
8954
9047
  }
8955
- if (BUILT_IN_LAYOUTS[key]) {
8956
- return BUILT_IN_LAYOUTS[key];
9048
+ if (BUILT_IN_LAYOUTS2[key]) {
9049
+ return BUILT_IN_LAYOUTS2[key];
8957
9050
  }
8958
9051
  return DefaultProductLayout;
8959
9052
  }
@@ -9011,56 +9104,168 @@ function ProductPage({
9011
9104
  }
9012
9105
  ) });
9013
9106
  }
9014
- function CartPage({
9015
- title = "Your Cart",
9107
+ function DefaultCartLayout({
9108
+ cart,
9016
9109
  onCheckout,
9017
9110
  onContinueShopping,
9018
9111
  onDiscountApply,
9019
9112
  onDiscountClear,
9020
9113
  showDiscount = true,
9021
- showContinueShopping = true,
9022
9114
  checkoutLabel = "Proceed to Checkout",
9023
- className,
9024
- classNames
9115
+ className
9025
9116
  }) {
9026
- const { isEmpty, subtotal } = useCart();
9027
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-page": true, className: cn(className, classNames?.root), children: [
9028
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-page-header": true, className: classNames?.header, children: [
9029
- /* @__PURE__ */ jsxRuntime.jsx("h1", { "data-cimplify-cart-page-title": true, className: classNames?.title, children: title }),
9030
- showContinueShopping && /* @__PURE__ */ jsxRuntime.jsx(
9117
+ if (cart.isEmpty) {
9118
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-layout": "default", className: cn("text-center py-20", className), children: [
9119
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-16 h-16 mx-auto text-muted-foreground/30", fill: "none", stroke: "currentColor", strokeWidth: "1", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z" }) }),
9120
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg font-medium mt-4", children: "Your cart is empty" }),
9121
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Add some items to get started" }),
9122
+ onContinueShopping && /* @__PURE__ */ jsxRuntime.jsx(
9031
9123
  "button",
9032
9124
  {
9033
- type: "button",
9034
9125
  onClick: onContinueShopping,
9035
- "data-cimplify-cart-continue": true,
9036
- className: classNames?.continueButton,
9037
- children: "Continue Shopping"
9126
+ className: "text-sm font-medium text-primary mt-4 hover:underline",
9127
+ children: "Continue shopping"
9038
9128
  }
9039
9129
  )
9040
- ] }),
9041
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-page-content": true, className: classNames?.content, children: [
9042
- /* @__PURE__ */ jsxRuntime.jsx(CartSummary, {}),
9043
- showDiscount && !isEmpty && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-cart-page-discount": true, className: classNames?.discount, children: /* @__PURE__ */ jsxRuntime.jsx(
9044
- DiscountInput,
9130
+ ] });
9131
+ }
9132
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-layout": "default", className: cn("space-y-6", className), children: [
9133
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
9134
+ /* @__PURE__ */ jsxRuntime.jsxs("h1", { className: "text-2xl font-bold tracking-tight", children: [
9135
+ "Your Cart (",
9136
+ cart.itemCount,
9137
+ " ",
9138
+ cart.itemCount === 1 ? "item" : "items",
9139
+ ")"
9140
+ ] }),
9141
+ onContinueShopping && /* @__PURE__ */ jsxRuntime.jsx(
9142
+ "button",
9045
9143
  {
9046
- orderSubtotal: subtotal.toString(),
9047
- onApply: onDiscountApply,
9048
- onClear: onDiscountClear
9144
+ onClick: onContinueShopping,
9145
+ className: "text-sm text-muted-foreground hover:text-foreground transition-colors",
9146
+ children: "Continue shopping"
9049
9147
  }
9050
- ) })
9148
+ )
9149
+ ] }),
9150
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid lg:grid-cols-[1fr_380px] gap-8", children: [
9151
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(CartSummary, {}) }),
9152
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "lg:sticky lg:top-6 h-fit space-y-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border border-border rounded-[14px] p-6 space-y-4", children: [
9153
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "font-semibold", children: "Order Summary" }),
9154
+ showDiscount && /* @__PURE__ */ jsxRuntime.jsx(
9155
+ DiscountInput,
9156
+ {
9157
+ orderSubtotal: cart.subtotal.toString(),
9158
+ onApply: onDiscountApply,
9159
+ onClear: onDiscountClear
9160
+ }
9161
+ ),
9162
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 text-sm", children: [
9163
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
9164
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Subtotal" }),
9165
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: cart.subtotal })
9166
+ ] }),
9167
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
9168
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Tax" }),
9169
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: cart.tax })
9170
+ ] }),
9171
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between font-semibold text-base pt-2 border-t border-border", children: [
9172
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Total" }),
9173
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: cart.total })
9174
+ ] })
9175
+ ] }),
9176
+ /* @__PURE__ */ jsxRuntime.jsx(
9177
+ "button",
9178
+ {
9179
+ onClick: onCheckout,
9180
+ className: "w-full h-12 bg-foreground text-background font-medium text-sm rounded-lg hover:bg-foreground/90 transition-colors",
9181
+ children: checkoutLabel
9182
+ }
9183
+ )
9184
+ ] }) })
9185
+ ] })
9186
+ ] });
9187
+ }
9188
+ function CompactCartLayout({
9189
+ cart,
9190
+ onCheckout,
9191
+ onContinueShopping,
9192
+ checkoutLabel = "Place Order",
9193
+ className
9194
+ }) {
9195
+ if (cart.isEmpty) {
9196
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-layout": "compact", className: cn("text-center py-16", className), children: [
9197
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg font-medium", children: "Your order is empty" }),
9198
+ onContinueShopping && /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onContinueShopping, className: "text-sm font-medium text-primary mt-3 hover:underline", children: "Browse menu" })
9199
+ ] });
9200
+ }
9201
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-layout": "compact", className: cn("max-w-lg mx-auto space-y-4", className), children: [
9202
+ /* @__PURE__ */ jsxRuntime.jsxs("h1", { className: "text-xl font-bold tracking-tight", children: [
9203
+ "Your Order (",
9204
+ cart.itemCount,
9205
+ ")"
9206
+ ] }),
9207
+ /* @__PURE__ */ jsxRuntime.jsx(CartSummary, {}),
9208
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 text-sm pt-4 border-t border-border", children: [
9209
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
9210
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Subtotal" }),
9211
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: cart.subtotal })
9212
+ ] }),
9213
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
9214
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Tax" }),
9215
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: cart.tax })
9216
+ ] }),
9217
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between font-semibold text-base pt-2 border-t border-border", children: [
9218
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Total" }),
9219
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: cart.total })
9220
+ ] })
9051
9221
  ] }),
9052
- !isEmpty && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-cart-page-footer": true, className: classNames?.footer, children: /* @__PURE__ */ jsxRuntime.jsx(
9222
+ /* @__PURE__ */ jsxRuntime.jsx(
9053
9223
  "button",
9054
9224
  {
9055
- type: "button",
9056
9225
  onClick: onCheckout,
9057
- "data-cimplify-cart-checkout-button": true,
9058
- className: classNames?.checkoutButton,
9226
+ className: "w-full h-12 bg-foreground text-background font-medium text-sm rounded-lg hover:bg-foreground/90 transition-colors",
9059
9227
  children: checkoutLabel
9060
9228
  }
9061
- ) })
9229
+ )
9062
9230
  ] });
9063
9231
  }
9232
+ var CartTemplate = /* @__PURE__ */ ((CartTemplate2) => {
9233
+ CartTemplate2["Default"] = "default";
9234
+ CartTemplate2["Compact"] = "compact";
9235
+ return CartTemplate2;
9236
+ })(CartTemplate || {});
9237
+ var BUILT_IN_LAYOUTS3 = {
9238
+ ["default" /* Default */]: DefaultCartLayout,
9239
+ ["compact" /* Compact */]: CompactCartLayout
9240
+ };
9241
+ function CartPage({
9242
+ template,
9243
+ layouts,
9244
+ onCheckout,
9245
+ onContinueShopping,
9246
+ onDiscountApply,
9247
+ onDiscountClear,
9248
+ showDiscount = true,
9249
+ checkoutLabel,
9250
+ className,
9251
+ classNames
9252
+ }) {
9253
+ const cart = useCart();
9254
+ const key = template ?? "default" /* Default */;
9255
+ const Layout = layouts?.[key] ?? BUILT_IN_LAYOUTS3[key] ?? DefaultCartLayout;
9256
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-cart-page": true, className: cn(className, classNames?.root), children: /* @__PURE__ */ jsxRuntime.jsx(
9257
+ Layout,
9258
+ {
9259
+ cart,
9260
+ onCheckout,
9261
+ onContinueShopping,
9262
+ onDiscountApply,
9263
+ onDiscountClear,
9264
+ showDiscount,
9265
+ checkoutLabel
9266
+ }
9267
+ ) });
9268
+ }
9064
9269
  function CheckoutPage({
9065
9270
  title = "Checkout",
9066
9271
  onComplete,
@@ -9084,88 +9289,426 @@ function CheckoutPage({
9084
9289
  )
9085
9290
  ] });
9086
9291
  }
9087
- function CollectionPage({
9088
- collectionId,
9089
- collection: collectionProp,
9090
- products: productsProp,
9292
+ function DefaultCollectionLayout({
9293
+ collection,
9294
+ products,
9091
9295
  renderCard,
9092
9296
  renderImage,
9093
- columns,
9094
- className,
9095
- classNames
9297
+ renderLink,
9298
+ onQuickAdd,
9299
+ className
9096
9300
  }) {
9097
- const {
9098
- collection: fetchedCollection,
9099
- products: fetchedProducts,
9100
- isLoading
9101
- } = useCollection(collectionProp ? null : collectionId, {
9102
- enabled: !collectionProp
9103
- });
9104
- const collection = collectionProp ?? fetchedCollection;
9105
- const products = productsProp ?? fetchedProducts;
9106
- if (isLoading && !collection) {
9107
- return /* @__PURE__ */ jsxRuntime.jsx(
9108
- "div",
9109
- {
9110
- "data-cimplify-collection-page": true,
9111
- "aria-busy": "true",
9112
- className: cn(className, classNames?.root, classNames?.loading)
9113
- }
9114
- );
9115
- }
9116
- if (!collection) {
9117
- return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-collection-page": true, className: cn(className, classNames?.root), children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Collection not found." }) });
9118
- }
9119
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-collection-page": true, className: cn(className, classNames?.root), children: [
9120
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-collection-header": true, className: classNames?.header, children: [
9301
+ const [searchQuery, setSearchQuery] = React3.useState("");
9302
+ const [activeTag, setActiveTag] = React3.useState(null);
9303
+ const collectionTags = React3.useMemo(() => {
9304
+ const tagSet = /* @__PURE__ */ new Set();
9305
+ for (const p of products) {
9306
+ if (p.tags) {
9307
+ for (const t of p.tags) tagSet.add(t);
9308
+ }
9309
+ }
9310
+ return Array.from(tagSet).slice(0, 6);
9311
+ }, [products]);
9312
+ const filtered = React3.useMemo(() => {
9313
+ let result = products;
9314
+ if (searchQuery.trim().length >= 2) {
9315
+ const q = searchQuery.toLowerCase();
9316
+ result = result.filter(
9317
+ (p) => p.name.toLowerCase().includes(q) || p.description?.toLowerCase().includes(q)
9318
+ );
9319
+ }
9320
+ if (activeTag) {
9321
+ result = result.filter((p) => p.tags?.includes(activeTag));
9322
+ }
9323
+ return result;
9324
+ }, [products, searchQuery, activeTag]);
9325
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-collection-layout": "default", className: cn("space-y-8", className), children: [
9326
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-collection-hero": true, className: "relative overflow-hidden rounded-2xl bg-muted", children: [
9121
9327
  collection.image_url && /* @__PURE__ */ jsxRuntime.jsx(
9122
9328
  "img",
9123
9329
  {
9124
9330
  src: collection.image_url,
9125
9331
  alt: collection.name,
9126
- "data-cimplify-collection-image": true,
9127
- className: classNames?.image
9332
+ className: "w-full h-64 lg:h-80 object-cover"
9128
9333
  }
9129
9334
  ),
9130
- /* @__PURE__ */ jsxRuntime.jsx("h1", { "data-cimplify-collection-title": true, className: classNames?.title, children: collection.name }),
9131
- collection.description && /* @__PURE__ */ jsxRuntime.jsx("p", { "data-cimplify-collection-description": true, className: classNames?.description, children: collection.description })
9335
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/60 via-black/20 to-transparent" }),
9336
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute bottom-0 left-0 right-0 p-6 lg:p-8", children: [
9337
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl lg:text-4xl font-bold text-white tracking-tight", children: collection.name }),
9338
+ collection.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-white/80 mt-2 max-w-lg text-sm lg:text-base", children: collection.description }),
9339
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-white/60 text-sm mt-2", children: [
9340
+ products.length,
9341
+ " ",
9342
+ products.length === 1 ? "item" : "items"
9343
+ ] })
9344
+ ] })
9132
9345
  ] }),
9133
- /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-collection-grid": true, className: classNames?.grid, children: /* @__PURE__ */ jsxRuntime.jsx(
9134
- ProductGrid,
9135
- {
9136
- products,
9137
- renderCard,
9138
- renderImage,
9139
- columns
9140
- }
9141
- ) })
9346
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col sm:flex-row items-start sm:items-center gap-3", children: [
9347
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 min-w-0 w-full sm:max-w-xs", children: [
9348
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
9349
+ /* @__PURE__ */ jsxRuntime.jsx(
9350
+ "input",
9351
+ {
9352
+ type: "search",
9353
+ value: searchQuery,
9354
+ onChange: (e) => setSearchQuery(e.target.value),
9355
+ placeholder: `Search ${collection.name}...`,
9356
+ 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"
9357
+ }
9358
+ )
9359
+ ] }),
9360
+ collectionTags.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-1.5", children: [
9361
+ /* @__PURE__ */ jsxRuntime.jsx(
9362
+ "button",
9363
+ {
9364
+ onClick: () => setActiveTag(null),
9365
+ className: cn(
9366
+ "text-xs font-medium px-3 py-1.5 rounded-full transition-colors",
9367
+ !activeTag ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
9368
+ ),
9369
+ children: "All"
9370
+ }
9371
+ ),
9372
+ collectionTags.map((tag) => /* @__PURE__ */ jsxRuntime.jsx(
9373
+ "button",
9374
+ {
9375
+ onClick: () => setActiveTag(activeTag === tag ? null : tag),
9376
+ className: cn(
9377
+ "text-xs font-medium px-3 py-1.5 rounded-full transition-colors",
9378
+ activeTag === tag ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
9379
+ ),
9380
+ children: tag
9381
+ },
9382
+ tag
9383
+ ))
9384
+ ] })
9385
+ ] }),
9386
+ filtered.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4", children: filtered.map(
9387
+ (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React3__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
9388
+ ProductCard,
9389
+ {
9390
+ product,
9391
+ renderImage,
9392
+ renderLink,
9393
+ onQuickAdd
9394
+ },
9395
+ product.id
9396
+ )
9397
+ ) }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-16", children: [
9398
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: "No items match your search." }),
9399
+ /* @__PURE__ */ jsxRuntime.jsx(
9400
+ "button",
9401
+ {
9402
+ onClick: () => {
9403
+ setSearchQuery("");
9404
+ setActiveTag(null);
9405
+ },
9406
+ className: "text-sm font-medium text-primary mt-2 hover:underline",
9407
+ children: "Clear filters"
9408
+ }
9409
+ )
9410
+ ] })
9142
9411
  ] });
9143
9412
  }
9144
- function OrderDetailPage({
9145
- orderId,
9146
- order,
9147
- poll = true,
9148
- onBack,
9149
- renderLineItem,
9150
- onReorder,
9151
- onStatusChange,
9152
- backLabel = "Back to orders",
9153
- className,
9154
- classNames
9413
+ function FeaturedCollectionLayout({
9414
+ collection,
9415
+ products,
9416
+ renderCard,
9417
+ renderImage,
9418
+ renderLink,
9419
+ onQuickAdd,
9420
+ className
9155
9421
  }) {
9156
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-order-detail-page": true, className: cn(className, classNames?.root), children: [
9157
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-order-detail-header": true, className: classNames?.header, children: [
9158
- onBack && /* @__PURE__ */ jsxRuntime.jsx(
9159
- "button",
9422
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-collection-layout": "featured", className: cn("space-y-10", className), children: [
9423
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-collection-hero": true, className: "relative overflow-hidden rounded-2xl bg-muted", children: [
9424
+ collection.image_url && /* @__PURE__ */ jsxRuntime.jsx(
9425
+ "img",
9160
9426
  {
9161
- type: "button",
9162
- onClick: onBack,
9163
- "data-cimplify-order-detail-back": true,
9164
- className: classNames?.backButton,
9165
- children: backLabel
9427
+ src: collection.image_url,
9428
+ alt: collection.name,
9429
+ className: "w-full h-72 lg:h-96 object-cover"
9166
9430
  }
9167
9431
  ),
9168
- /* @__PURE__ */ jsxRuntime.jsx("h1", { "data-cimplify-order-detail-title": true, className: classNames?.title, children: "Order Details" })
9432
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/70 via-black/30 to-transparent" }),
9433
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute bottom-0 left-0 right-0 p-8 lg:p-12", children: [
9434
+ collection.tags && collection.tags.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-semibold text-white/70 uppercase tracking-widest", children: collection.tags[0] }),
9435
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl lg:text-5xl font-bold text-white tracking-tight mt-2", children: collection.name }),
9436
+ collection.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-white/80 mt-3 max-w-2xl text-base lg:text-lg leading-relaxed", children: collection.description })
9437
+ ] })
9438
+ ] }),
9439
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6", children: products.map(
9440
+ (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React3__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
9441
+ ProductCard,
9442
+ {
9443
+ product,
9444
+ renderImage,
9445
+ renderLink,
9446
+ onQuickAdd
9447
+ },
9448
+ product.id
9449
+ )
9450
+ ) })
9451
+ ] });
9452
+ }
9453
+ function CatalogueCollectionLayout({
9454
+ collection,
9455
+ products,
9456
+ renderCard,
9457
+ renderImage,
9458
+ renderLink,
9459
+ onQuickAdd,
9460
+ className
9461
+ }) {
9462
+ const [searchQuery, setSearchQuery] = React3.useState("");
9463
+ const [activeCategory, setActiveCategory] = React3.useState(null);
9464
+ const [sortBy, setSortBy] = React3.useState("default");
9465
+ const categories = React3.useMemo(() => {
9466
+ const cats = /* @__PURE__ */ new Map();
9467
+ for (const p of products) {
9468
+ if (p.category_id && p.tags) {
9469
+ for (const t of p.tags) {
9470
+ if (!cats.has(t)) cats.set(t, t);
9471
+ }
9472
+ }
9473
+ }
9474
+ return Array.from(cats.values()).slice(0, 8);
9475
+ }, [products]);
9476
+ const filtered = React3.useMemo(() => {
9477
+ let result = products;
9478
+ if (searchQuery.trim().length >= 2) {
9479
+ const q = searchQuery.toLowerCase();
9480
+ result = result.filter(
9481
+ (p) => p.name.toLowerCase().includes(q) || p.description?.toLowerCase().includes(q)
9482
+ );
9483
+ }
9484
+ if (activeCategory) {
9485
+ result = result.filter((p) => p.tags?.includes(activeCategory));
9486
+ }
9487
+ if (sortBy === "price-asc") {
9488
+ result = [...result].sort((a, b) => chunkPEDLCL72_js.parsePrice(a.default_price) - chunkPEDLCL72_js.parsePrice(b.default_price));
9489
+ } else if (sortBy === "price-desc") {
9490
+ result = [...result].sort((a, b) => chunkPEDLCL72_js.parsePrice(b.default_price) - chunkPEDLCL72_js.parsePrice(a.default_price));
9491
+ } else if (sortBy === "name") {
9492
+ result = [...result].sort((a, b) => a.name.localeCompare(b.name));
9493
+ }
9494
+ return result;
9495
+ }, [products, searchQuery, activeCategory, sortBy]);
9496
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-collection-layout": "catalogue", className: cn("space-y-6", className), children: [
9497
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
9498
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl lg:text-3xl font-bold tracking-tight", children: collection.name }),
9499
+ collection.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground mt-1 max-w-2xl", children: collection.description })
9500
+ ] }),
9501
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 pb-4 border-b border-border", children: [
9502
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 flex-1 min-w-0 w-full", children: [
9503
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 max-w-sm", children: [
9504
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
9505
+ /* @__PURE__ */ jsxRuntime.jsx(
9506
+ "input",
9507
+ {
9508
+ type: "search",
9509
+ value: searchQuery,
9510
+ onChange: (e) => setSearchQuery(e.target.value),
9511
+ placeholder: "Search...",
9512
+ 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"
9513
+ }
9514
+ )
9515
+ ] }),
9516
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5 overflow-x-auto scrollbar-hide", children: [
9517
+ /* @__PURE__ */ jsxRuntime.jsx(
9518
+ "button",
9519
+ {
9520
+ onClick: () => setActiveCategory(null),
9521
+ className: cn(
9522
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
9523
+ !activeCategory ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
9524
+ ),
9525
+ children: "All"
9526
+ }
9527
+ ),
9528
+ categories.map((cat) => /* @__PURE__ */ jsxRuntime.jsx(
9529
+ "button",
9530
+ {
9531
+ onClick: () => setActiveCategory(activeCategory === cat ? null : cat),
9532
+ className: cn(
9533
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
9534
+ activeCategory === cat ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
9535
+ ),
9536
+ children: cat
9537
+ },
9538
+ cat
9539
+ ))
9540
+ ] })
9541
+ ] }),
9542
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 shrink-0", children: [
9543
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: [
9544
+ filtered.length,
9545
+ " items"
9546
+ ] }),
9547
+ /* @__PURE__ */ jsxRuntime.jsxs(
9548
+ "select",
9549
+ {
9550
+ value: sortBy,
9551
+ onChange: (e) => setSortBy(e.target.value),
9552
+ className: "text-xs border border-border rounded-lg px-2 py-1.5 bg-background outline-none focus:ring-2 focus:ring-primary/20",
9553
+ children: [
9554
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "default", children: "Sort: Default" }),
9555
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "price-asc", children: "Price: Low to High" }),
9556
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "price-desc", children: "Price: High to Low" }),
9557
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "name", children: "Name: A-Z" })
9558
+ ]
9559
+ }
9560
+ )
9561
+ ] })
9562
+ ] }),
9563
+ filtered.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4", children: filtered.map(
9564
+ (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React3__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
9565
+ ProductCard,
9566
+ {
9567
+ product,
9568
+ renderImage,
9569
+ renderLink,
9570
+ onQuickAdd
9571
+ },
9572
+ product.id
9573
+ )
9574
+ ) }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-16", children: [
9575
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: "No products found." }),
9576
+ /* @__PURE__ */ jsxRuntime.jsx(
9577
+ "button",
9578
+ {
9579
+ onClick: () => {
9580
+ setSearchQuery("");
9581
+ setActiveCategory(null);
9582
+ },
9583
+ className: "text-sm font-medium text-primary mt-2 hover:underline",
9584
+ children: "Clear filters"
9585
+ }
9586
+ )
9587
+ ] })
9588
+ ] });
9589
+ }
9590
+ var CollectionTemplate = /* @__PURE__ */ ((CollectionTemplate2) => {
9591
+ CollectionTemplate2["Default"] = "default";
9592
+ CollectionTemplate2["Featured"] = "featured";
9593
+ CollectionTemplate2["Catalogue"] = "catalogue";
9594
+ return CollectionTemplate2;
9595
+ })(CollectionTemplate || {});
9596
+ var BUILT_IN_LAYOUTS4 = {
9597
+ ["default" /* Default */]: DefaultCollectionLayout,
9598
+ ["featured" /* Featured */]: FeaturedCollectionLayout,
9599
+ ["catalogue" /* Catalogue */]: CatalogueCollectionLayout
9600
+ };
9601
+ var LARGE_COLLECTION_THRESHOLD = 30;
9602
+ function resolveTemplateKey2(collection, productCount) {
9603
+ const metaTemplate = collection.metadata?.page_template;
9604
+ if (typeof metaTemplate === "string" && metaTemplate.trim()) {
9605
+ return metaTemplate.trim();
9606
+ }
9607
+ if (collection.tags?.includes("featured") || collection.metadata?.is_featured === true) {
9608
+ return "featured" /* Featured */;
9609
+ }
9610
+ if (productCount > LARGE_COLLECTION_THRESHOLD) {
9611
+ return "catalogue" /* Catalogue */;
9612
+ }
9613
+ return "default" /* Default */;
9614
+ }
9615
+ function resolveLayout2(collection, productCount, pages, templates) {
9616
+ if (pages?.[collection.slug]) {
9617
+ return pages[collection.slug];
9618
+ }
9619
+ const key = resolveTemplateKey2(collection, productCount);
9620
+ if (templates?.[key]) {
9621
+ return templates[key];
9622
+ }
9623
+ if (BUILT_IN_LAYOUTS4[key]) {
9624
+ return BUILT_IN_LAYOUTS4[key];
9625
+ }
9626
+ return DefaultCollectionLayout;
9627
+ }
9628
+ function CollectionPage({
9629
+ collectionId,
9630
+ collection: collectionProp,
9631
+ products: productsProp,
9632
+ pages,
9633
+ templates,
9634
+ renderCard,
9635
+ renderImage,
9636
+ renderLink,
9637
+ onQuickAdd,
9638
+ className,
9639
+ classNames
9640
+ }) {
9641
+ const resolvedId = collectionId || collectionProp?.slug || collectionProp?.id || "";
9642
+ const {
9643
+ collection: fetchedCollection,
9644
+ products: fetchedProducts,
9645
+ isLoading
9646
+ } = useCollection(collectionProp ? null : resolvedId, {
9647
+ enabled: !collectionProp && resolvedId.length > 0
9648
+ });
9649
+ const collection = collectionProp ?? fetchedCollection;
9650
+ const products = productsProp ?? fetchedProducts;
9651
+ if (isLoading && !collection) {
9652
+ return /* @__PURE__ */ jsxRuntime.jsx(
9653
+ "div",
9654
+ {
9655
+ "data-cimplify-collection-page": true,
9656
+ "aria-busy": "true",
9657
+ className: cn(className, classNames?.root, classNames?.loading),
9658
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "animate-pulse space-y-6", children: [
9659
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-64 lg:h-80 bg-muted rounded-2xl" }),
9660
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4", children: Array.from({ length: 8 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
9661
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-square bg-muted rounded-[14px]" }),
9662
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 space-y-2", children: [
9663
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-3/4 bg-muted rounded" }),
9664
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-3 w-1/2 bg-muted rounded" })
9665
+ ] })
9666
+ ] }, i)) })
9667
+ ] })
9668
+ }
9669
+ );
9670
+ }
9671
+ if (!collection) {
9672
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-collection-page": true, className: cn(className, classNames?.root), children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: "Collection not found." }) });
9673
+ }
9674
+ const Layout = resolveLayout2(collection, products.length, pages, templates);
9675
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-collection-page": true, className: cn(className, classNames?.root), children: /* @__PURE__ */ jsxRuntime.jsx(
9676
+ Layout,
9677
+ {
9678
+ collection,
9679
+ products,
9680
+ renderCard,
9681
+ renderImage,
9682
+ renderLink,
9683
+ onQuickAdd
9684
+ }
9685
+ ) });
9686
+ }
9687
+ function OrderDetailPage({
9688
+ orderId,
9689
+ order,
9690
+ poll = true,
9691
+ onBack,
9692
+ renderLineItem,
9693
+ onReorder,
9694
+ onStatusChange,
9695
+ backLabel = "Back to orders",
9696
+ className,
9697
+ classNames
9698
+ }) {
9699
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-order-detail-page": true, className: cn(className, classNames?.root), children: [
9700
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-order-detail-header": true, className: classNames?.header, children: [
9701
+ onBack && /* @__PURE__ */ jsxRuntime.jsx(
9702
+ "button",
9703
+ {
9704
+ type: "button",
9705
+ onClick: onBack,
9706
+ "data-cimplify-order-detail-back": true,
9707
+ className: classNames?.backButton,
9708
+ children: backLabel
9709
+ }
9710
+ ),
9711
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { "data-cimplify-order-detail-title": true, className: classNames?.title, children: "Order Details" })
9169
9712
  ] }),
9170
9713
  /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-order-detail-content": true, className: classNames?.summary, children: /* @__PURE__ */ jsxRuntime.jsx(
9171
9714
  OrderSummary,
@@ -9258,573 +9801,355 @@ function OrderHistoryPage({
9258
9801
  ) })
9259
9802
  ] });
9260
9803
  }
9261
- function SearchPage({
9262
- title = "Search",
9263
- placeholder = "What are you looking for?",
9264
- onProductClick,
9804
+ function DefaultSearchLayout({
9805
+ search,
9806
+ facets,
9807
+ categories,
9808
+ activeCategory,
9809
+ onCategoryChange,
9810
+ inStockOnly,
9811
+ onInStockChange,
9812
+ sortBy,
9813
+ onSortChange,
9265
9814
  renderCard,
9266
9815
  renderImage,
9267
- columns,
9268
- className,
9269
- classNames
9816
+ renderLink,
9817
+ onQuickAdd,
9818
+ placeholder = "Search products...",
9819
+ className
9270
9820
  }) {
9271
- const { results, isLoading, query, setQuery, clear } = useSearch();
9272
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-search-page": true, className: cn(className, classNames?.root), children: [
9273
- /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-search-page-header": true, className: classNames?.header, children: /* @__PURE__ */ jsxRuntime.jsx("h1", { "data-cimplify-search-page-title": true, className: classNames?.title, children: title }) }),
9274
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-search-page-input": true, className: classNames?.inputContainer, children: [
9821
+ const { query, setQuery, results, isLoading, clear } = search;
9822
+ const hasFacets = facets && facets.length > 0 || categories && categories.length > 0;
9823
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-search-layout": "default", className: cn("space-y-6", className), children: [
9824
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
9825
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "absolute left-4 top-1/2 -translate-y-1/2 w-5 h-5 text-muted-foreground", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
9275
9826
  /* @__PURE__ */ jsxRuntime.jsx(
9276
- input.Input,
9827
+ "input",
9277
9828
  {
9278
9829
  type: "search",
9279
9830
  value: query,
9280
9831
  onChange: (e) => setQuery(e.target.value),
9281
9832
  placeholder,
9282
- "data-cimplify-search-page-field": true,
9283
- className: classNames?.input,
9284
- "aria-label": "Search products",
9833
+ 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",
9285
9834
  autoFocus: true
9286
9835
  }
9287
9836
  ),
9288
9837
  query.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
9289
9838
  "button",
9290
9839
  {
9291
- type: "button",
9292
9840
  onClick: clear,
9293
- "data-cimplify-search-page-clear": true,
9294
- className: classNames?.clearButton,
9841
+ 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",
9295
9842
  "aria-label": "Clear search",
9296
- children: "\xD7"
9843
+ children: /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", d: "M6 18L18 6M6 6l12 12" }) })
9297
9844
  }
9298
9845
  )
9299
9846
  ] }),
9300
- query.length >= 2 && !isLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-search-page-count": true, className: classNames?.resultCount, children: [
9301
- results.length,
9302
- " ",
9303
- results.length === 1 ? "result" : "results",
9304
- " for \u201C",
9305
- query,
9306
- "\u201D"
9307
- ] }),
9308
- /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-search-page-grid": true, className: classNames?.grid, children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-search-page-loading": true, "aria-busy": "true", className: classNames?.loading, children: "Searching..." }) : query.length >= 2 && results.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-search-page-empty": true, className: classNames?.empty, children: /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
9309
- "No products found for \u201C",
9310
- query,
9311
- "\u201D"
9312
- ] }) }) : results.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
9313
- ProductGrid,
9314
- {
9315
- products: results,
9316
- renderCard,
9317
- renderImage,
9318
- columns
9319
- }
9320
- ) })
9321
- ] });
9322
- }
9323
- function DealsPage({
9324
- title = "Deals & Offers",
9325
- deals: dealsProp,
9326
- productsOnSale: productsOnSaleProp,
9327
- products: productsProp,
9328
- locationId,
9329
- renderImage,
9330
- columns,
9331
- className,
9332
- classNames
9333
- }) {
9334
- const { deals: fetchedDeals, isLoading: dealsLoading } = useDeals({
9335
- locationId,
9336
- enabled: dealsProp === void 0
9337
- });
9338
- const { products: fetchedOnSale, isLoading: productsLoading } = useProductsOnSale({
9339
- enabled: productsOnSaleProp === void 0
9340
- });
9341
- const deals = dealsProp ?? fetchedDeals;
9342
- const onSale = productsOnSaleProp ?? fetchedOnSale;
9343
- const isLoading = dealsLoading || productsLoading;
9344
- const isEmpty = deals.length === 0 && onSale.length === 0;
9345
- if (isLoading && isEmpty) {
9346
- return /* @__PURE__ */ jsxRuntime.jsx(
9347
- "div",
9348
- {
9349
- "data-cimplify-deals-page": true,
9350
- "aria-busy": "true",
9351
- className: cn(className, classNames?.root, classNames?.loading)
9352
- }
9353
- );
9354
- }
9355
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-deals-page": true, className: cn(className, classNames?.root), children: [
9356
- /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-deals-header": true, className: classNames?.header, children: /* @__PURE__ */ jsxRuntime.jsx("h1", { "data-cimplify-deals-title": true, className: classNames?.title, children: title }) }),
9357
- deals.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-deals-banner-section": true, className: classNames?.bannerSection, children: /* @__PURE__ */ jsxRuntime.jsx(DealBanner, { deals }) }),
9358
- (onSale.length > 0 || productsProp && productsProp.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-deals-products": true, className: classNames?.productsSection, children: [
9359
- /* @__PURE__ */ jsxRuntime.jsx("h2", { "data-cimplify-deals-products-title": true, className: classNames?.productsTitle, children: "On Sale Now" }),
9360
- productsProp ? /* @__PURE__ */ jsxRuntime.jsx(
9361
- ProductGrid,
9847
+ query.length >= 2 && !isLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
9848
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground", children: [
9849
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground", children: results.length }),
9850
+ " result",
9851
+ results.length !== 1 ? "s" : "",
9852
+ " for ",
9853
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium text-foreground", children: [
9854
+ "\u201C",
9855
+ query,
9856
+ "\u201D"
9857
+ ] })
9858
+ ] }),
9859
+ onSortChange && /* @__PURE__ */ jsxRuntime.jsxs(
9860
+ "select",
9362
9861
  {
9363
- products: productsProp,
9364
- renderImage,
9365
- columns
9862
+ value: sortBy || "relevance",
9863
+ onChange: (e) => onSortChange(e.target.value),
9864
+ className: "text-xs border border-border rounded-lg px-2 py-1.5 bg-background outline-none focus:ring-2 focus:ring-primary/10",
9865
+ children: [
9866
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "relevance", children: "Relevance" }),
9867
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "price-asc", children: "Price: Low to High" }),
9868
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "price-desc", children: "Price: High to Low" }),
9869
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "name", children: "Name: A-Z" }),
9870
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "newest", children: "Newest" })
9871
+ ]
9366
9872
  }
9367
- ) : /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-deals-sale-list": true, children: onSale.map((dealInfo) => /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-deals-sale-item": true, children: /* @__PURE__ */ jsxRuntime.jsx(
9368
- SaleBadge,
9873
+ )
9874
+ ] }),
9875
+ categories && categories.length > 0 && onCategoryChange && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5 overflow-x-auto pb-1", children: [
9876
+ /* @__PURE__ */ jsxRuntime.jsx(
9877
+ "button",
9369
9878
  {
9370
- product: { id: dealInfo.product_id, name: dealInfo.deal_name },
9371
- dealInfo,
9372
- showOriginalPrice: true
9879
+ onClick: () => onCategoryChange(null),
9880
+ className: cn(
9881
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
9882
+ !activeCategory ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
9883
+ ),
9884
+ children: "All"
9373
9885
  }
9374
- ) }, `${dealInfo.product_id}-${dealInfo.deal_id}`)) })
9886
+ ),
9887
+ categories.map((cat) => /* @__PURE__ */ jsxRuntime.jsx(
9888
+ "button",
9889
+ {
9890
+ onClick: () => onCategoryChange(activeCategory === cat.id ? null : cat.id),
9891
+ className: cn(
9892
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
9893
+ activeCategory === cat.id ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
9894
+ ),
9895
+ children: cat.name
9896
+ },
9897
+ cat.id
9898
+ ))
9375
9899
  ] }),
9376
- isEmpty && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-deals-empty": true, className: classNames?.empty, children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: "No deals available right now. Check back soon!" }) })
9377
- ] });
9378
- }
9379
- var ANY_VALUE2 = "__any__";
9380
- function roomToResource(room) {
9381
- return {
9382
- id: room.id,
9383
- name: room.name,
9384
- capacity: room.capacity,
9385
- floor: room.floor,
9386
- is_available: room.status === "available"
9387
- };
9388
- }
9389
- function ResourcePicker({
9390
- resources,
9391
- selectedResourceId,
9392
- onResourceSelect,
9393
- showAnyOption = true,
9394
- anyLabel = "Any available",
9395
- renderImage,
9396
- className,
9397
- classNames
9398
- }) {
9399
- const groupValue = selectedResourceId === null ? ANY_VALUE2 : selectedResourceId ?? "";
9400
- return /* @__PURE__ */ jsxRuntime.jsxs(
9401
- radioGroup.RadioGroup,
9402
- {
9403
- "data-cimplify-resource-picker": true,
9404
- className: cn("flex flex-col gap-2", className, classNames?.root),
9405
- value: groupValue,
9406
- onValueChange: (value) => {
9407
- onResourceSelect?.(value === ANY_VALUE2 ? null : value);
9408
- },
9409
- children: [
9410
- showAnyOption && /* @__PURE__ */ jsxRuntime.jsx(
9411
- radio.Radio.Root,
9412
- {
9413
- value: ANY_VALUE2,
9414
- "data-cimplify-resource-option": true,
9415
- "data-selected": selectedResourceId === null || void 0,
9416
- "data-any": true,
9417
- className: cn(
9418
- "flex items-center gap-3 rounded-lg border border-border p-3 transition-colors cursor-pointer",
9419
- "hover:bg-muted data-[checked]:border-primary data-[checked]:bg-primary/5",
9420
- classNames?.option
9421
- ),
9422
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-resource-name": true, className: cn("font-medium text-foreground", classNames?.name), children: anyLabel })
9423
- }
9424
- ),
9425
- resources.map((resource) => {
9426
- const unavailable = resource.is_available === false;
9427
- return /* @__PURE__ */ jsxRuntime.jsxs(
9428
- radio.Radio.Root,
9900
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: hasFacets ? "flex gap-6" : "", children: [
9901
+ hasFacets && /* @__PURE__ */ jsxRuntime.jsxs("aside", { "data-cimplify-search-facets": true, className: "hidden lg:block w-60 shrink-0 space-y-6", children: [
9902
+ onInStockChange && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
9903
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: "In stock only" }),
9904
+ /* @__PURE__ */ jsxRuntime.jsx(
9905
+ "button",
9429
9906
  {
9430
- value: resource.id,
9431
- disabled: unavailable,
9432
- "data-cimplify-resource-option": true,
9433
- "data-selected": selectedResourceId === resource.id || void 0,
9434
- "data-unavailable": unavailable || void 0,
9907
+ onClick: () => onInStockChange(!inStockOnly),
9435
9908
  className: cn(
9436
- "flex items-center gap-3 rounded-lg border border-border p-3 transition-colors cursor-pointer",
9437
- "hover:bg-muted data-[checked]:border-primary data-[checked]:bg-primary/5",
9438
- unavailable && "opacity-50 cursor-not-allowed",
9439
- classNames?.option,
9440
- unavailable ? classNames?.unavailable : void 0
9909
+ "w-10 h-6 rounded-full transition-colors relative",
9910
+ inStockOnly ? "bg-foreground" : "bg-border"
9441
9911
  ),
9442
- children: [
9443
- resource.image_url && (renderImage ? renderImage({
9444
- src: resource.image_url,
9445
- alt: resource.name,
9446
- className: classNames?.image
9447
- }) : /* @__PURE__ */ jsxRuntime.jsx(
9448
- "img",
9449
- {
9450
- src: resource.image_url,
9451
- alt: resource.name,
9452
- "data-cimplify-resource-image": true,
9453
- className: cn("w-10 h-10 rounded-lg object-cover", classNames?.image)
9454
- }
9455
- )),
9456
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5 flex-1 min-w-0", children: [
9457
- /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-resource-name": true, className: cn("font-medium text-foreground", classNames?.name), children: resource.name }),
9458
- resource.description && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-resource-description": true, className: cn("text-sm text-muted-foreground truncate", classNames?.description), children: resource.description }),
9459
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-resource-meta": true, className: cn("flex items-center gap-2 text-xs text-muted-foreground", classNames?.meta), children: [
9460
- resource.capacity !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-resource-capacity": true, className: classNames?.capacity, children: [
9461
- "Up to ",
9462
- resource.capacity
9463
- ] }),
9464
- resource.floor && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-resource-floor": true, className: classNames?.floor, children: resource.floor })
9465
- ] })
9466
- ] })
9467
- ]
9468
- },
9469
- resource.id
9470
- );
9471
- })
9472
- ]
9473
- }
9474
- );
9475
- }
9476
- var STEP = {
9477
- SELECT_SLOT: "select-slot",
9478
- SELECT_RESOURCE: "select-resource",
9479
- SELECT_STAFF: "select-staff",
9480
- CONFIRM: "confirm"
9481
- };
9482
- function BookingPage({
9483
- service,
9484
- product,
9485
- staff,
9486
- resources,
9487
- participantCount,
9488
- title,
9489
- onBooked,
9490
- onBack,
9491
- existingBooking,
9492
- onRescheduled,
9493
- showPrice = true,
9494
- className,
9495
- classNames
9496
- }) {
9497
- const { addItem } = useCart();
9498
- const { client } = useCimplifyClient();
9499
- const isReschedule = existingBooking !== void 0;
9500
- const [step, setStep] = React3.useState(STEP.SELECT_SLOT);
9501
- const [selectedSlot, setSelectedSlot] = React3.useState(null);
9502
- const [selectedDate, setSelectedDate] = React3.useState(null);
9503
- const [selectedStaffId, setSelectedStaffId] = React3.useState(null);
9504
- const [selectedResourceId, setSelectedResourceId] = React3.useState(null);
9505
- const [isSubmitting, setIsSubmitting] = React3.useState(false);
9506
- const [error, setError] = React3.useState(null);
9507
- const hasResourceStep = resources && resources.length > 0;
9508
- const hasStaffStep = staff && staff.length > 0;
9509
- const depositType = product?.deposit_type;
9510
- const depositAmount = product?.deposit_amount;
9511
- const hasDeposit = depositType !== void 0 && depositType !== "none" && depositAmount !== void 0 && chunkPEDLCL72_js.parsePrice(depositAmount) !== 0;
9512
- const cancellationMinutes = product?.cancellation_window_minutes;
9513
- const noShowFee = product?.no_show_fee;
9514
- const handleSlotSelect = React3.useCallback(
9515
- (slot, date) => {
9516
- setSelectedSlot(slot);
9517
- setSelectedDate(date);
9518
- setError(null);
9519
- if (hasResourceStep) {
9520
- setStep(STEP.SELECT_RESOURCE);
9521
- } else if (hasStaffStep) {
9522
- setStep(STEP.SELECT_STAFF);
9523
- } else {
9524
- setStep(STEP.CONFIRM);
9525
- }
9526
- },
9527
- [hasResourceStep, hasStaffStep]
9528
- );
9529
- const handleResourceSelect = React3.useCallback(
9530
- (resourceId) => {
9531
- setSelectedResourceId(resourceId);
9532
- if (hasStaffStep) {
9533
- setStep(STEP.SELECT_STAFF);
9534
- } else {
9535
- setStep(STEP.CONFIRM);
9536
- }
9537
- },
9538
- [hasStaffStep]
9539
- );
9540
- const handleStaffSelect = React3.useCallback((staffId) => {
9541
- setSelectedStaffId(staffId);
9542
- setStep(STEP.CONFIRM);
9543
- }, []);
9544
- const handleBack = React3.useCallback(() => {
9545
- setError(null);
9546
- if (step === STEP.CONFIRM && hasStaffStep) {
9547
- setStep(STEP.SELECT_STAFF);
9548
- } else if (step === STEP.CONFIRM && hasResourceStep) {
9549
- setStep(STEP.SELECT_RESOURCE);
9550
- } else if (step === STEP.SELECT_STAFF && hasResourceStep) {
9551
- setStep(STEP.SELECT_RESOURCE);
9552
- } else if (step === STEP.CONFIRM || step === STEP.SELECT_STAFF || step === STEP.SELECT_RESOURCE) {
9553
- setStep(STEP.SELECT_SLOT);
9554
- } else {
9555
- onBack?.();
9556
- }
9557
- }, [step, hasStaffStep, hasResourceStep, onBack]);
9558
- const handleConfirm = React3.useCallback(async () => {
9559
- if (!selectedSlot || !selectedDate) return;
9560
- setIsSubmitting(true);
9561
- setError(null);
9562
- try {
9563
- if (isReschedule && existingBooking) {
9564
- const serviceItem = existingBooking.service_items[0];
9565
- const result = await client.scheduling.rescheduleBooking({
9566
- order_id: existingBooking.order_id,
9567
- line_item_id: serviceItem?.service_id ?? existingBooking.order_id,
9568
- new_start_time: selectedSlot.start_time,
9569
- new_end_time: selectedSlot.end_time,
9570
- new_staff_id: selectedStaffId || void 0,
9571
- reschedule_type: "customer"
9572
- });
9573
- if (!result.ok) {
9574
- throw result.error;
9575
- }
9576
- onRescheduled?.(existingBooking, selectedSlot);
9577
- } else {
9578
- const serviceProduct = {
9579
- id: service.product_id || service.id,
9580
- business_id: service.business_id || "",
9581
- category_id: service.category_id || void 0,
9582
- name: service.name,
9583
- slug: service.id,
9584
- description: service.description || void 0,
9585
- image_url: service.image_url || void 0,
9586
- default_price: service.price || "0",
9587
- type: "service",
9588
- inventory_type: "none",
9589
- variant_strategy: "fetch_all",
9590
- is_active: service.is_available,
9591
- created_at: (/* @__PURE__ */ new Date()).toISOString(),
9592
- updated_at: (/* @__PURE__ */ new Date()).toISOString()
9593
- };
9594
- await addItem(serviceProduct, 1, {
9595
- scheduledStart: selectedSlot.start_time,
9596
- scheduledEnd: selectedSlot.end_time,
9597
- staffId: selectedStaffId || void 0,
9598
- resourceId: selectedResourceId || void 0
9599
- });
9600
- onBooked?.(selectedSlot, selectedStaffId);
9601
- }
9602
- } catch (err) {
9603
- const fallbackMessage = isReschedule ? "Failed to reschedule booking" : "Failed to add booking to cart";
9604
- setError(err instanceof Error ? err.message : fallbackMessage);
9605
- } finally {
9606
- setIsSubmitting(false);
9607
- }
9608
- }, [selectedSlot, selectedDate, selectedStaffId, service, addItem, onBooked, isReschedule, existingBooking, client, onRescheduled]);
9609
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-page": true, className: cn(className, classNames?.root), children: [
9610
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-page-header": true, className: classNames?.header, children: [
9611
- onBack && step === STEP.SELECT_SLOT && /* @__PURE__ */ jsxRuntime.jsx(
9612
- "button",
9912
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
9913
+ "absolute top-1 w-4 h-4 rounded-full bg-background transition-transform shadow-sm",
9914
+ inStockOnly ? "left-5" : "left-1"
9915
+ ) })
9916
+ }
9917
+ )
9918
+ ] }),
9919
+ facets?.map((facet) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
9920
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-semibold mb-2", children: facet.name }),
9921
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1.5", children: facet.values.slice(0, 8).map((fv) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2 text-sm cursor-pointer group", children: [
9922
+ /* @__PURE__ */ jsxRuntime.jsx("input", { type: "checkbox", className: "w-3.5 h-3.5 accent-foreground rounded" }),
9923
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground group-hover:text-foreground transition-colors flex-1", children: fv.value }),
9924
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground/60", children: fv.count })
9925
+ ] }, fv.value)) })
9926
+ ] }, facet.slug))
9927
+ ] }),
9928
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 gap-4 animate-pulse", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
9929
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-square bg-muted rounded-[14px]" }),
9930
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 space-y-2", children: [
9931
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-3/4 bg-muted rounded" }),
9932
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-3 w-1/2 bg-muted rounded" })
9933
+ ] })
9934
+ ] }, i)) }) : query.length >= 2 && results.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-20", children: [
9935
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-12 h-12 mx-auto text-muted-foreground/30", fill: "none", stroke: "currentColor", strokeWidth: "1", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
9936
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-lg font-medium mt-4", children: [
9937
+ "No results for \u201C",
9938
+ query,
9939
+ "\u201D"
9940
+ ] }),
9941
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Try a different search term" }),
9942
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: clear, className: "text-sm font-medium text-primary mt-4 hover:underline", children: "Clear search" })
9943
+ ] }) : results.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 gap-4", children: results.map(
9944
+ (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React3__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
9945
+ ProductCard,
9946
+ {
9947
+ product,
9948
+ renderImage,
9949
+ renderLink,
9950
+ onQuickAdd
9951
+ },
9952
+ product.id
9953
+ )
9954
+ ) }) : null })
9955
+ ] })
9956
+ ] });
9957
+ }
9958
+ function CompactSearchLayout({
9959
+ search,
9960
+ categories,
9961
+ activeCategory,
9962
+ onCategoryChange,
9963
+ renderCard,
9964
+ renderImage,
9965
+ renderLink,
9966
+ onQuickAdd,
9967
+ placeholder = "Search menu...",
9968
+ className
9969
+ }) {
9970
+ const { query, setQuery, results, isLoading, clear } = search;
9971
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-search-layout": "compact", className: cn("space-y-6", className), children: [
9972
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
9973
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "absolute left-4 top-1/2 -translate-y-1/2 w-5 h-5 text-muted-foreground", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
9974
+ /* @__PURE__ */ jsxRuntime.jsx(
9975
+ "input",
9613
9976
  {
9614
- type: "button",
9615
- onClick: onBack,
9616
- "data-cimplify-booking-page-back": true,
9617
- className: classNames?.backButton,
9618
- children: "Back"
9977
+ type: "search",
9978
+ value: query,
9979
+ onChange: (e) => setQuery(e.target.value),
9980
+ placeholder,
9981
+ 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",
9982
+ autoFocus: true
9619
9983
  }
9620
9984
  ),
9621
- step !== STEP.SELECT_SLOT && /* @__PURE__ */ jsxRuntime.jsx(
9985
+ query.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
9622
9986
  "button",
9623
9987
  {
9624
- type: "button",
9625
- onClick: handleBack,
9626
- "data-cimplify-booking-page-back": true,
9627
- className: classNames?.backButton,
9628
- children: "Back"
9629
- }
9630
- ),
9631
- /* @__PURE__ */ jsxRuntime.jsx("h1", { "data-cimplify-booking-page-title": true, className: classNames?.title, children: title || (isReschedule ? "Reschedule Booking" : `Book ${service.name}`) })
9632
- ] }),
9633
- isReschedule && existingBooking && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-booking-reschedule-info": true, className: classNames?.rescheduleInfo, children: /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
9634
- "Rescheduling booking from ",
9635
- new Date(existingBooking.service_items[0]?.scheduled_start ?? existingBooking.created_at).toLocaleDateString()
9636
- ] }) }),
9637
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-service-info": true, className: classNames?.serviceInfo, children: [
9638
- /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-booking-service-name": true, children: service.name }),
9639
- /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-booking-service-duration": true, children: formatDuration4(service.duration_minutes, service.duration_unit) }),
9640
- service.price && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-booking-service-price": true, children: /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: service.price }) }),
9641
- hasDeposit && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-booking-deposit-info": true, className: classNames?.depositInfo, children: [
9642
- "Deposit: ",
9643
- depositType === "percentage" ? `${chunkPEDLCL72_js.parsePrice(depositAmount)}%` : /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: depositAmount })
9644
- ] }),
9645
- cancellationMinutes !== void 0 && cancellationMinutes > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-booking-cancellation-policy": true, className: classNames?.cancellationPolicy, children: [
9646
- "Free cancellation up to ",
9647
- cancellationMinutes >= 60 ? `${Math.floor(cancellationMinutes / 60)} hour${Math.floor(cancellationMinutes / 60) !== 1 ? "s" : ""}` : `${cancellationMinutes} minute${cancellationMinutes !== 1 ? "s" : ""}`,
9648
- " before"
9649
- ] }),
9650
- noShowFee !== void 0 && chunkPEDLCL72_js.parsePrice(noShowFee) !== 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-booking-no-show-fee": true, className: classNames?.cancellationPolicy, children: [
9651
- "No-show fee: ",
9652
- /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: noShowFee })
9653
- ] })
9654
- ] }),
9655
- error && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-booking-error": true, className: classNames?.error, children: error }),
9656
- step === STEP.SELECT_SLOT && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-step": "select-slot", className: classNames?.step, children: [
9657
- /* @__PURE__ */ jsxRuntime.jsx("h2", { "data-cimplify-booking-step-title": true, className: classNames?.stepTitle, children: "Select a date & time" }),
9658
- /* @__PURE__ */ jsxRuntime.jsx(
9659
- DateSlotPicker,
9660
- {
9661
- serviceId: service.id,
9662
- participantCount,
9663
- selectedSlot,
9664
- onSlotSelect: handleSlotSelect,
9665
- showPrice
9988
+ onClick: clear,
9989
+ 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",
9990
+ "aria-label": "Clear search",
9991
+ children: /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", d: "M6 18L18 6M6 6l12 12" }) })
9666
9992
  }
9667
9993
  )
9668
9994
  ] }),
9669
- step === STEP.SELECT_RESOURCE && resources && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-step": "select-resource", className: cn(classNames?.step, classNames?.resourceStep), children: [
9670
- /* @__PURE__ */ jsxRuntime.jsx("h2", { "data-cimplify-booking-step-title": true, className: classNames?.stepTitle, children: "Choose a room" }),
9995
+ categories && categories.length > 0 && onCategoryChange && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5 overflow-x-auto pb-1", children: [
9671
9996
  /* @__PURE__ */ jsxRuntime.jsx(
9672
- ResourcePicker,
9997
+ "button",
9673
9998
  {
9674
- resources,
9675
- selectedResourceId,
9676
- onResourceSelect: handleResourceSelect
9999
+ onClick: () => onCategoryChange(null),
10000
+ className: cn(
10001
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
10002
+ !activeCategory ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
10003
+ ),
10004
+ children: "All"
9677
10005
  }
9678
- )
9679
- ] }),
9680
- step === STEP.SELECT_STAFF && staff && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-step": "select-staff", className: classNames?.step, children: [
9681
- /* @__PURE__ */ jsxRuntime.jsx("h2", { "data-cimplify-booking-step-title": true, className: classNames?.stepTitle, children: "Choose a provider" }),
9682
- /* @__PURE__ */ jsxRuntime.jsx(
9683
- StaffPicker,
10006
+ ),
10007
+ categories.map((cat) => /* @__PURE__ */ jsxRuntime.jsx(
10008
+ "button",
9684
10009
  {
9685
- staff,
9686
- selectedStaffId,
9687
- onStaffSelect: handleStaffSelect
9688
- }
9689
- )
10010
+ onClick: () => onCategoryChange(activeCategory === cat.id ? null : cat.id),
10011
+ className: cn(
10012
+ "text-xs font-medium px-3 py-1.5 rounded-full shrink-0 transition-colors",
10013
+ activeCategory === cat.id ? "bg-foreground text-background" : "bg-muted text-muted-foreground hover:bg-muted/80"
10014
+ ),
10015
+ children: cat.name
10016
+ },
10017
+ cat.id
10018
+ ))
9690
10019
  ] }),
9691
- step === STEP.CONFIRM && selectedSlot && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-step": "confirm", className: classNames?.step, children: [
9692
- /* @__PURE__ */ jsxRuntime.jsx("h2", { "data-cimplify-booking-step-title": true, className: classNames?.stepTitle, children: "Confirm your booking" }),
9693
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary": true, className: classNames?.summary, children: [
9694
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
9695
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Service" }),
9696
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: service.name })
9697
- ] }),
9698
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
9699
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Date" }),
9700
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: selectedDate })
9701
- ] }),
9702
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
9703
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Time" }),
9704
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: new Date(selectedSlot.start_time).toLocaleTimeString(void 0, {
9705
- hour: "numeric",
9706
- minute: "2-digit"
9707
- }) })
9708
- ] }),
9709
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
9710
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Duration" }),
9711
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatDuration4(service.duration_minutes, service.duration_unit) })
9712
- ] }),
9713
- selectedResourceId && resources && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
9714
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Room" }),
9715
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: resources.find((r) => r.id === selectedResourceId)?.name ?? "Selected" })
9716
- ] }),
9717
- selectedStaffId && staff && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
9718
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Provider" }),
9719
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: staff.find((s) => s.id === selectedStaffId)?.name ?? "Selected" })
9720
- ] }),
9721
- (selectedSlot.price || service.price) && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
9722
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Price" }),
9723
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: selectedSlot.price || service.price }) })
9724
- ] }),
9725
- hasDeposit && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary-row": true, className: cn(classNames?.summaryRow, classNames?.depositInfo), children: [
9726
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Deposit" }),
9727
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: depositType === "percentage" ? `${chunkPEDLCL72_js.parsePrice(depositAmount)}%` : /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: depositAmount }) })
9728
- ] })
10020
+ query.length >= 2 && !isLoading && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground", children: [
10021
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground", children: results.length }),
10022
+ " result",
10023
+ results.length !== 1 ? "s" : "",
10024
+ " for ",
10025
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium text-foreground", children: [
10026
+ "\u201C",
10027
+ query,
10028
+ "\u201D"
10029
+ ] })
10030
+ ] }),
10031
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-5 animate-pulse", children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10032
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-square bg-muted rounded-[14px]" }),
10033
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 space-y-2", children: [
10034
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-3/4 bg-muted rounded" }),
10035
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-3 w-1/2 bg-muted rounded" })
10036
+ ] })
10037
+ ] }, i)) }) : query.length >= 2 && results.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-16", children: [
10038
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-lg font-medium", children: [
10039
+ "No results for \u201C",
10040
+ query,
10041
+ "\u201D"
9729
10042
  ] }),
9730
- /* @__PURE__ */ jsxRuntime.jsx(
9731
- "button",
10043
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Try a different search term" }),
10044
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: clear, className: "text-sm font-medium text-primary mt-4 hover:underline", children: "Clear search" })
10045
+ ] }) : results.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 lg:grid-cols-3 gap-5", children: results.map(
10046
+ (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React3__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
10047
+ ProductCard,
9732
10048
  {
9733
- type: "button",
9734
- onClick: handleConfirm,
9735
- disabled: isSubmitting,
9736
- "data-cimplify-booking-confirm": true,
9737
- className: classNames?.confirmButton,
9738
- children: isSubmitting ? isReschedule ? "Rescheduling\u2026" : "Adding to cart\u2026" : isReschedule ? "Reschedule" : "Confirm Booking"
9739
- }
10049
+ product,
10050
+ renderImage,
10051
+ renderLink,
10052
+ onQuickAdd
10053
+ },
10054
+ product.id
9740
10055
  )
9741
- ] })
10056
+ ) }) : null
9742
10057
  ] });
9743
10058
  }
9744
- var BOOKING_FILTERS = [
9745
- { label: "All", value: "all" },
9746
- { label: "Upcoming", value: "upcoming" },
9747
- { label: "Past", value: "past" }
9748
- ];
9749
- function BookingsPage({
9750
- title = "My Bookings",
9751
- bookings: bookingsProp,
9752
- onBookingNavigate,
9753
- onCancel,
9754
- onReschedule,
9755
- showFilters = true,
9756
- renderBooking,
10059
+ var SearchTemplate = /* @__PURE__ */ ((SearchTemplate2) => {
10060
+ SearchTemplate2["Default"] = "default";
10061
+ SearchTemplate2["Compact"] = "compact";
10062
+ return SearchTemplate2;
10063
+ })(SearchTemplate || {});
10064
+ var BUILT_IN_LAYOUTS5 = {
10065
+ ["default" /* Default */]: DefaultSearchLayout,
10066
+ ["compact" /* Compact */]: CompactSearchLayout
10067
+ };
10068
+ function SearchPage({
10069
+ template,
10070
+ layouts,
10071
+ categories,
10072
+ facets,
10073
+ searchOptions,
10074
+ placeholder,
10075
+ renderCard,
10076
+ renderImage,
10077
+ renderLink,
10078
+ onQuickAdd,
9757
10079
  className,
9758
10080
  classNames
9759
10081
  }) {
9760
- const [filter, setFilter] = React3.useState("all");
9761
- const [selectedBooking, setSelectedBooking] = React3.useState(null);
9762
- const handleBookingClick = React3.useCallback(
9763
- (booking) => {
9764
- if (onBookingNavigate) {
9765
- onBookingNavigate(booking);
9766
- } else {
9767
- setSelectedBooking(booking);
10082
+ const search = useSearch(searchOptions);
10083
+ const key = template ?? "default" /* Default */;
10084
+ const Layout = layouts?.[key] ?? BUILT_IN_LAYOUTS5[key] ?? DefaultSearchLayout;
10085
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-search-page": true, className: cn(className, classNames?.root), children: /* @__PURE__ */ jsxRuntime.jsx(
10086
+ Layout,
10087
+ {
10088
+ search,
10089
+ facets,
10090
+ categories,
10091
+ renderCard,
10092
+ renderImage,
10093
+ renderLink,
10094
+ onQuickAdd,
10095
+ placeholder
10096
+ }
10097
+ ) });
10098
+ }
10099
+ function DealsPage({
10100
+ title = "Deals & Offers",
10101
+ deals: dealsProp,
10102
+ productsOnSale: productsOnSaleProp,
10103
+ products: productsProp,
10104
+ locationId,
10105
+ renderImage,
10106
+ columns,
10107
+ className,
10108
+ classNames
10109
+ }) {
10110
+ const { deals: fetchedDeals, isLoading: dealsLoading } = useDeals({
10111
+ locationId,
10112
+ enabled: dealsProp === void 0
10113
+ });
10114
+ const { products: fetchedOnSale, isLoading: productsLoading } = useProductsOnSale({
10115
+ enabled: productsOnSaleProp === void 0
10116
+ });
10117
+ const deals = dealsProp ?? fetchedDeals;
10118
+ const onSale = productsOnSaleProp ?? fetchedOnSale;
10119
+ const isLoading = dealsLoading || productsLoading;
10120
+ const isEmpty = deals.length === 0 && onSale.length === 0;
10121
+ if (isLoading && isEmpty) {
10122
+ return /* @__PURE__ */ jsxRuntime.jsx(
10123
+ "div",
10124
+ {
10125
+ "data-cimplify-deals-page": true,
10126
+ "aria-busy": "true",
10127
+ className: cn(className, classNames?.root, classNames?.loading)
9768
10128
  }
9769
- },
9770
- [onBookingNavigate]
9771
- );
9772
- const handleBack = React3.useCallback(() => {
9773
- setSelectedBooking(null);
9774
- }, []);
9775
- if (selectedBooking && !onBookingNavigate) {
9776
- return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-bookings-page": true, className: cn(className, classNames?.root), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-bookings-detail": true, className: classNames?.detail, children: [
9777
- /* @__PURE__ */ jsxRuntime.jsx(
9778
- "button",
10129
+ );
10130
+ }
10131
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-deals-page": true, className: cn(className, classNames?.root), children: [
10132
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-deals-header": true, className: classNames?.header, children: /* @__PURE__ */ jsxRuntime.jsx("h1", { "data-cimplify-deals-title": true, className: classNames?.title, children: title }) }),
10133
+ deals.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-deals-banner-section": true, className: classNames?.bannerSection, children: /* @__PURE__ */ jsxRuntime.jsx(DealBanner, { deals }) }),
10134
+ (onSale.length > 0 || productsProp && productsProp.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-deals-products": true, className: classNames?.productsSection, children: [
10135
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { "data-cimplify-deals-products-title": true, className: classNames?.productsTitle, children: "On Sale Now" }),
10136
+ productsProp ? /* @__PURE__ */ jsxRuntime.jsx(
10137
+ ProductGrid,
9779
10138
  {
9780
- type: "button",
9781
- onClick: handleBack,
9782
- "data-cimplify-bookings-back": true,
9783
- className: classNames?.backButton,
9784
- children: "Back to bookings"
10139
+ products: productsProp,
10140
+ renderImage,
10141
+ columns
9785
10142
  }
9786
- ),
9787
- /* @__PURE__ */ jsxRuntime.jsx(
9788
- BookingCard,
10143
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-deals-sale-list": true, children: onSale.map((dealInfo) => /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-deals-sale-item": true, children: /* @__PURE__ */ jsxRuntime.jsx(
10144
+ SaleBadge,
9789
10145
  {
9790
- booking: selectedBooking,
9791
- onCancel,
9792
- onReschedule
10146
+ product: { id: dealInfo.product_id, name: dealInfo.deal_name },
10147
+ dealInfo,
10148
+ showOriginalPrice: true
9793
10149
  }
9794
- )
9795
- ] }) });
9796
- }
9797
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-bookings-page": true, className: cn(className, classNames?.root), children: [
9798
- /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-bookings-header": true, className: classNames?.header, children: /* @__PURE__ */ jsxRuntime.jsx("h1", { "data-cimplify-bookings-title": true, className: classNames?.title, children: title }) }),
9799
- showFilters && /* @__PURE__ */ jsxRuntime.jsx(
9800
- tabs.Tabs.Root,
9801
- {
9802
- value: filter,
9803
- onValueChange: (value) => setFilter(value),
9804
- children: /* @__PURE__ */ jsxRuntime.jsx(tabs.Tabs.List, { "data-cimplify-bookings-filters": true, className: classNames?.filters, children: BOOKING_FILTERS.map((f) => /* @__PURE__ */ jsxRuntime.jsx(
9805
- tabs.Tabs.Tab,
9806
- {
9807
- value: f.value,
9808
- "data-cimplify-booking-filter": true,
9809
- "data-selected": filter === f.value || void 0,
9810
- className: classNames?.filterButton,
9811
- children: f.label
9812
- },
9813
- f.value
9814
- )) })
9815
- }
9816
- ),
9817
- /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-bookings-list": true, className: classNames?.list, children: /* @__PURE__ */ jsxRuntime.jsx(
9818
- BookingList,
9819
- {
9820
- bookings: bookingsProp,
9821
- filter,
9822
- onCancel,
9823
- onReschedule,
9824
- onBookingClick: handleBookingClick,
9825
- renderBooking
9826
- }
9827
- ) })
10150
+ ) }, `${dealInfo.product_id}-${dealInfo.deal_id}`)) })
10151
+ ] }),
10152
+ isEmpty && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-deals-empty": true, className: classNames?.empty, children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: "No deals available right now. Check back soon!" }) })
9828
10153
  ] });
9829
10154
  }
9830
10155
  function LocationPicker({
@@ -10185,10 +10510,107 @@ function CurrencySelector({
10185
10510
  );
10186
10511
  }) });
10187
10512
  }
10513
+ var ANY_VALUE2 = "__any__";
10514
+ function roomToResource(room) {
10515
+ return {
10516
+ id: room.id,
10517
+ name: room.name,
10518
+ capacity: room.capacity,
10519
+ floor: room.floor,
10520
+ is_available: room.status === "available"
10521
+ };
10522
+ }
10523
+ function ResourcePicker({
10524
+ resources,
10525
+ selectedResourceId,
10526
+ onResourceSelect,
10527
+ showAnyOption = true,
10528
+ anyLabel = "Any available",
10529
+ renderImage,
10530
+ className,
10531
+ classNames
10532
+ }) {
10533
+ const groupValue = selectedResourceId === null ? ANY_VALUE2 : selectedResourceId ?? "";
10534
+ return /* @__PURE__ */ jsxRuntime.jsxs(
10535
+ radioGroup.RadioGroup,
10536
+ {
10537
+ "data-cimplify-resource-picker": true,
10538
+ className: cn("flex flex-col gap-2", className, classNames?.root),
10539
+ value: groupValue,
10540
+ onValueChange: (value) => {
10541
+ onResourceSelect?.(value === ANY_VALUE2 ? null : value);
10542
+ },
10543
+ children: [
10544
+ showAnyOption && /* @__PURE__ */ jsxRuntime.jsx(
10545
+ radio.Radio.Root,
10546
+ {
10547
+ value: ANY_VALUE2,
10548
+ "data-cimplify-resource-option": true,
10549
+ "data-selected": selectedResourceId === null || void 0,
10550
+ "data-any": true,
10551
+ className: cn(
10552
+ "flex items-center gap-3 rounded-lg border border-border p-3 transition-colors cursor-pointer",
10553
+ "hover:bg-muted data-[checked]:border-primary data-[checked]:bg-primary/5",
10554
+ classNames?.option
10555
+ ),
10556
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-resource-name": true, className: cn("font-medium text-foreground", classNames?.name), children: anyLabel })
10557
+ }
10558
+ ),
10559
+ resources.map((resource) => {
10560
+ const unavailable = resource.is_available === false;
10561
+ return /* @__PURE__ */ jsxRuntime.jsxs(
10562
+ radio.Radio.Root,
10563
+ {
10564
+ value: resource.id,
10565
+ disabled: unavailable,
10566
+ "data-cimplify-resource-option": true,
10567
+ "data-selected": selectedResourceId === resource.id || void 0,
10568
+ "data-unavailable": unavailable || void 0,
10569
+ className: cn(
10570
+ "flex items-center gap-3 rounded-lg border border-border p-3 transition-colors cursor-pointer",
10571
+ "hover:bg-muted data-[checked]:border-primary data-[checked]:bg-primary/5",
10572
+ unavailable && "opacity-50 cursor-not-allowed",
10573
+ classNames?.option,
10574
+ unavailable ? classNames?.unavailable : void 0
10575
+ ),
10576
+ children: [
10577
+ resource.image_url && (renderImage ? renderImage({
10578
+ src: resource.image_url,
10579
+ alt: resource.name,
10580
+ className: classNames?.image
10581
+ }) : /* @__PURE__ */ jsxRuntime.jsx(
10582
+ "img",
10583
+ {
10584
+ src: resource.image_url,
10585
+ alt: resource.name,
10586
+ "data-cimplify-resource-image": true,
10587
+ className: cn("w-10 h-10 rounded-lg object-cover", classNames?.image)
10588
+ }
10589
+ )),
10590
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5 flex-1 min-w-0", children: [
10591
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-resource-name": true, className: cn("font-medium text-foreground", classNames?.name), children: resource.name }),
10592
+ resource.description && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-resource-description": true, className: cn("text-sm text-muted-foreground truncate", classNames?.description), children: resource.description }),
10593
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-resource-meta": true, className: cn("flex items-center gap-2 text-xs text-muted-foreground", classNames?.meta), children: [
10594
+ resource.capacity !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-resource-capacity": true, className: classNames?.capacity, children: [
10595
+ "Up to ",
10596
+ resource.capacity
10597
+ ] }),
10598
+ resource.floor && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-resource-floor": true, className: classNames?.floor, children: resource.floor })
10599
+ ] })
10600
+ ] })
10601
+ ]
10602
+ },
10603
+ resource.id
10604
+ );
10605
+ })
10606
+ ]
10607
+ }
10608
+ );
10609
+ }
10188
10610
 
10189
10611
  Object.defineProperty(exports, "getVariantDisplayName", {
10190
10612
  enumerable: true,
10191
- get: function () { return chunkWMQXSDRC_js.getVariantDisplayName; }
10613
+ get: function () { return chunk4JSRPSNA_js.getVariantDisplayName; }
10192
10614
  });
10193
10615
  exports.AccommodationCard = AccommodationCard;
10194
10616
  exports.Ad = Ad;
@@ -10200,21 +10622,27 @@ exports.AvailabilityBadge = AvailabilityBadge;
10200
10622
  exports.BillingPlanSelector = BillingPlanSelector;
10201
10623
  exports.BookingCard = BookingCard;
10202
10624
  exports.BookingList = BookingList;
10203
- exports.BookingPage = BookingPage;
10204
- exports.BookingsPage = BookingsPage;
10205
10625
  exports.BundleSelector = BundleSelector;
10206
10626
  exports.CardImage = CardImage;
10207
10627
  exports.CardShell = CardShell;
10208
10628
  exports.CardVariant = CardVariant;
10209
10629
  exports.CartPage = CartPage;
10210
10630
  exports.CartSummary = CartSummary;
10631
+ exports.CartTemplate = CartTemplate;
10632
+ exports.CatalogueCollectionLayout = CatalogueCollectionLayout;
10211
10633
  exports.CataloguePage = CataloguePage;
10634
+ exports.CatalogueTemplate = CatalogueTemplate;
10212
10635
  exports.CategoryFilter = CategoryFilter;
10213
10636
  exports.CategoryGrid = CategoryGrid;
10214
10637
  exports.CheckoutPage = CheckoutPage;
10638
+ exports.CimplifyAccount = CimplifyAccount;
10215
10639
  exports.CimplifyCheckout = CimplifyCheckout;
10216
10640
  exports.CimplifyProvider = CimplifyProvider;
10217
10641
  exports.CollectionPage = CollectionPage;
10642
+ exports.CollectionTemplate = CollectionTemplate;
10643
+ exports.CompactCartLayout = CompactCartLayout;
10644
+ exports.CompactCatalogueLayout = CompactCatalogueLayout;
10645
+ exports.CompactSearchLayout = CompactSearchLayout;
10218
10646
  exports.CompactServiceCard = CompactServiceCard;
10219
10647
  exports.CompositeSelector = CompositeSelector;
10220
10648
  exports.CurrencySelector = CurrencySelector;
@@ -10222,12 +10650,17 @@ exports.CustomAttributesTable = CustomAttributesTable;
10222
10650
  exports.DateSlotPicker = DateSlotPicker;
10223
10651
  exports.DealBanner = DealBanner;
10224
10652
  exports.DealsPage = DealsPage;
10653
+ exports.DefaultCartLayout = DefaultCartLayout;
10654
+ exports.DefaultCatalogueLayout = DefaultCatalogueLayout;
10655
+ exports.DefaultCollectionLayout = DefaultCollectionLayout;
10225
10656
  exports.DefaultProductLayout = DefaultProductLayout;
10657
+ exports.DefaultSearchLayout = DefaultSearchLayout;
10226
10658
  exports.DeliveryEstimate = DeliveryEstimate;
10227
10659
  exports.DigitalProductCard = DigitalProductCard;
10228
10660
  exports.DigitalProductLayout = DigitalProductLayout;
10229
10661
  exports.DiscountInput = DiscountInput;
10230
10662
  exports.ElementsProvider = ElementsProvider;
10663
+ exports.FeaturedCollectionLayout = FeaturedCollectionLayout;
10231
10664
  exports.FoodProductCard = FoodProductCard;
10232
10665
  exports.FoodProductLayout = FoodProductLayout;
10233
10666
  exports.InventoryBadge = InventoryBadge;
@@ -10261,8 +10694,7 @@ exports.SaleBadge = SaleBadge;
10261
10694
  exports.ScheduleServiceCard = ScheduleServiceCard;
10262
10695
  exports.SearchInput = SearchInput;
10263
10696
  exports.SearchPage = SearchPage;
10264
- exports.ServiceCard = ServiceCard;
10265
- exports.ServiceGrid = ServiceGrid;
10697
+ exports.SearchTemplate = SearchTemplate;
10266
10698
  exports.ServiceProductLayout = ServiceProductLayout;
10267
10699
  exports.SessionMessageBanner = SessionMessageBanner;
10268
10700
  exports.SlotPicker = SlotPicker;