@cimplify/sdk 0.21.0 → 0.22.1
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/advanced.d.mts +2 -2
- package/dist/advanced.d.ts +2 -2
- package/dist/{client-B8PO4NKN.d.mts → client-uvCOGdBp.d.ts} +14 -2
- package/dist/{client-DjrlvxW7.d.ts → client-v1NFqZFG.d.mts} +14 -2
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/{payment-CKqMU4xT.d.mts → payment-DazihbCY.d.mts} +1 -0
- package/dist/{payment-CKqMU4xT.d.ts → payment-DazihbCY.d.ts} +1 -0
- package/dist/{price-e4beObLZ.d.ts → price-5_L8WK6Q.d.ts} +1 -1
- package/dist/{price-BqV_DjjQ.d.mts → price-BcHVTqqu.d.mts} +1 -1
- package/dist/react.d.mts +83 -95
- package/dist/react.d.ts +83 -95
- package/dist/react.js +1035 -2489
- package/dist/react.mjs +1035 -2491
- package/dist/styles.css +1 -1
- package/dist/utils.d.mts +2 -2
- package/dist/utils.d.ts +2 -2
- package/package.json +1 -1
- package/registry/booking-card.json +1 -1
- package/registry/booking-page.json +1 -1
- package/registry/product-card.json +1 -1
- package/registry/service-card.json +1 -1
package/dist/react.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import { getVariantDisplayName, createCimplifyClient } from './chunk-W3DMONZR.mj
|
|
|
3
3
|
export { getVariantDisplayName } from './chunk-W3DMONZR.mjs';
|
|
4
4
|
import { ELEMENT_TYPES, EVENT_TYPES } from './chunk-R4EYMPSN.mjs';
|
|
5
5
|
import { isSupportedCurrency, formatPrice, parsePrice, isOnSale, getDiscountPercentage, getBasePrice } from './chunk-JFT63H34.mjs';
|
|
6
|
-
import React3, { createContext,
|
|
6
|
+
import React3, { createContext, useRef, useState, useCallback, useEffect, useContext, useMemo, useSyncExternalStore, useId } from 'react';
|
|
7
7
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
8
8
|
import { NumberField } from '@base-ui/react/number-field';
|
|
9
9
|
import { clsx } from 'clsx';
|
|
@@ -439,6 +439,9 @@ function buildLineKey(productId, options) {
|
|
|
439
439
|
if (options.staffId) {
|
|
440
440
|
parts.push(`st:${options.staffId}`);
|
|
441
441
|
}
|
|
442
|
+
if (options.resourceId) {
|
|
443
|
+
parts.push(`r:${options.resourceId}`);
|
|
444
|
+
}
|
|
442
445
|
return parts.join("|");
|
|
443
446
|
}
|
|
444
447
|
function calculateLineSubtotal(item) {
|
|
@@ -756,7 +759,8 @@ function createCartStore(params) {
|
|
|
756
759
|
composite_selections: normalizedOptions.compositeSelections,
|
|
757
760
|
scheduled_start: normalizedOptions.scheduledStart,
|
|
758
761
|
scheduled_end: normalizedOptions.scheduledEnd,
|
|
759
|
-
staff_id: normalizedOptions.staffId
|
|
762
|
+
staff_id: normalizedOptions.staffId,
|
|
763
|
+
resource_id: normalizedOptions.resourceId
|
|
760
764
|
});
|
|
761
765
|
if (!result.ok) {
|
|
762
766
|
throw result.error;
|
|
@@ -1675,41 +1679,130 @@ function Price({ amount, className, prefix }) {
|
|
|
1675
1679
|
formatPrice(convertPrice(amount), displayCurrency)
|
|
1676
1680
|
] });
|
|
1677
1681
|
}
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
options.tags?.join(",") ?? "",
|
|
1692
|
-
options.in_stock ?? "",
|
|
1693
|
-
options.min_price ?? "",
|
|
1694
|
-
options.max_price ?? "",
|
|
1695
|
-
options.page ?? "",
|
|
1696
|
-
options.properties ? JSON.stringify(options.properties) : ""
|
|
1697
|
-
].join("|");
|
|
1698
|
-
}
|
|
1699
|
-
function useProducts(options = {}) {
|
|
1700
|
-
const context = useOptionalCimplifyClient();
|
|
1701
|
-
const client = options.client ?? context?.client;
|
|
1702
|
-
if (!client) {
|
|
1703
|
-
throw new Error("useProducts must be used within CimplifyProvider or passed { client }.");
|
|
1682
|
+
function createCachedQuery(config) {
|
|
1683
|
+
const cache = /* @__PURE__ */ new Map();
|
|
1684
|
+
const inflight = /* @__PURE__ */ new Map();
|
|
1685
|
+
const gcMaxAge = config.gcMaxAge ?? 3e5;
|
|
1686
|
+
let lastSweep = 0;
|
|
1687
|
+
function sweep() {
|
|
1688
|
+
const now = Date.now();
|
|
1689
|
+
if (now - lastSweep < 6e4) return;
|
|
1690
|
+
lastSweep = now;
|
|
1691
|
+
const cutoff = now - gcMaxAge;
|
|
1692
|
+
for (const [key, entry] of cache) {
|
|
1693
|
+
if (entry.ts < cutoff) cache.delete(key);
|
|
1694
|
+
}
|
|
1704
1695
|
}
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1696
|
+
function useCachedQuery(options = {}) {
|
|
1697
|
+
const context = useOptionalCimplifyClient();
|
|
1698
|
+
const client = options.client ?? context?.client;
|
|
1699
|
+
if (!client) {
|
|
1700
|
+
throw new Error(
|
|
1701
|
+
`${config.name} must be used within CimplifyProvider or passed { client }.`
|
|
1702
|
+
);
|
|
1703
|
+
}
|
|
1704
|
+
const enabled = options.enabled ?? true;
|
|
1705
|
+
const locationId = client.getLocationId();
|
|
1706
|
+
const previousLocationRef = useRef(locationId);
|
|
1707
|
+
const requestIdRef = useRef(0);
|
|
1708
|
+
const optionsRef = useRef(options);
|
|
1709
|
+
optionsRef.current = options;
|
|
1710
|
+
if (config.locationSensitive && previousLocationRef.current !== locationId) {
|
|
1711
|
+
cache.clear();
|
|
1712
|
+
inflight.clear();
|
|
1713
|
+
previousLocationRef.current = locationId;
|
|
1714
|
+
}
|
|
1715
|
+
sweep();
|
|
1716
|
+
const cacheKey2 = config.key(client, options);
|
|
1717
|
+
const cached = cache.get(cacheKey2);
|
|
1718
|
+
const [data, setData] = useState(cached?.data ?? null);
|
|
1719
|
+
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
1720
|
+
const [error, setError] = useState(null);
|
|
1721
|
+
const load = useCallback(
|
|
1722
|
+
async (force = false) => {
|
|
1723
|
+
if (!enabled) {
|
|
1724
|
+
setIsLoading(false);
|
|
1725
|
+
return;
|
|
1726
|
+
}
|
|
1727
|
+
const nextRequestId = ++requestIdRef.current;
|
|
1728
|
+
setError(null);
|
|
1729
|
+
if (!force) {
|
|
1730
|
+
const hit = cache.get(cacheKey2);
|
|
1731
|
+
if (hit) {
|
|
1732
|
+
setData(hit.data);
|
|
1733
|
+
setIsLoading(false);
|
|
1734
|
+
return;
|
|
1735
|
+
}
|
|
1736
|
+
}
|
|
1737
|
+
setIsLoading(true);
|
|
1738
|
+
try {
|
|
1739
|
+
const existing = inflight.get(cacheKey2);
|
|
1740
|
+
const promise = existing ?? (async () => config.fetch(client, optionsRef.current))();
|
|
1741
|
+
if (!existing) {
|
|
1742
|
+
inflight.set(cacheKey2, promise);
|
|
1743
|
+
promise.finally(() => inflight.delete(cacheKey2)).catch(() => {
|
|
1744
|
+
});
|
|
1745
|
+
}
|
|
1746
|
+
const value = await promise;
|
|
1747
|
+
cache.set(cacheKey2, { data: value, ts: Date.now() });
|
|
1748
|
+
if (nextRequestId === requestIdRef.current) {
|
|
1749
|
+
setData(value);
|
|
1750
|
+
setError(null);
|
|
1751
|
+
}
|
|
1752
|
+
} catch (loadError) {
|
|
1753
|
+
if (nextRequestId === requestIdRef.current) {
|
|
1754
|
+
setError(loadError);
|
|
1755
|
+
}
|
|
1756
|
+
} finally {
|
|
1757
|
+
if (nextRequestId === requestIdRef.current) {
|
|
1758
|
+
setIsLoading(false);
|
|
1759
|
+
}
|
|
1760
|
+
}
|
|
1761
|
+
},
|
|
1762
|
+
[cacheKey2, client, enabled]
|
|
1763
|
+
);
|
|
1764
|
+
useEffect(() => {
|
|
1765
|
+
void load(false);
|
|
1766
|
+
}, [load]);
|
|
1767
|
+
const refetch = useCallback(async () => {
|
|
1768
|
+
cache.delete(cacheKey2);
|
|
1769
|
+
await load(true);
|
|
1770
|
+
}, [cacheKey2, load]);
|
|
1771
|
+
return { data, isLoading, error, refetch };
|
|
1772
|
+
}
|
|
1773
|
+
useCachedQuery.clear = () => {
|
|
1774
|
+
cache.clear();
|
|
1775
|
+
inflight.clear();
|
|
1776
|
+
};
|
|
1777
|
+
return useCachedQuery;
|
|
1778
|
+
}
|
|
1779
|
+
function cacheKey(...parts) {
|
|
1780
|
+
return parts.map((p) => String(p ?? "")).join("|");
|
|
1781
|
+
}
|
|
1782
|
+
|
|
1783
|
+
// src/react/hooks/use-products.ts
|
|
1784
|
+
var productsQuery = createCachedQuery({
|
|
1785
|
+
name: "useProducts",
|
|
1786
|
+
locationSensitive: true,
|
|
1787
|
+
key: (client, options) => cacheKey(
|
|
1788
|
+
client.getPublicKey(),
|
|
1789
|
+
client.getLocationId(),
|
|
1790
|
+
options.category,
|
|
1791
|
+
options.taxonomy,
|
|
1792
|
+
options.search,
|
|
1793
|
+
options.featured,
|
|
1794
|
+
options.limit,
|
|
1795
|
+
options.sort_by,
|
|
1796
|
+
options.sort_order,
|
|
1797
|
+
options.tags?.join(","),
|
|
1798
|
+
options.in_stock,
|
|
1799
|
+
options.min_price,
|
|
1800
|
+
options.max_price,
|
|
1801
|
+
options.page,
|
|
1802
|
+
options.properties ? JSON.stringify(options.properties) : void 0
|
|
1803
|
+
),
|
|
1804
|
+
fetch: async (client, options) => {
|
|
1805
|
+
const result = await client.catalogue.getProducts({
|
|
1713
1806
|
category: options.category,
|
|
1714
1807
|
taxonomy: options.taxonomy,
|
|
1715
1808
|
search: options.search,
|
|
@@ -1723,301 +1816,71 @@ function useProducts(options = {}) {
|
|
|
1723
1816
|
max_price: options.max_price,
|
|
1724
1817
|
page: options.page,
|
|
1725
1818
|
properties: options.properties
|
|
1726
|
-
})
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
options.max_price,
|
|
1739
|
-
options.page,
|
|
1740
|
-
propertiesSignature
|
|
1741
|
-
]
|
|
1742
|
-
);
|
|
1743
|
-
const cacheKey = useMemo(
|
|
1744
|
-
() => buildProductsCacheKey(client, locationId, queryOptions),
|
|
1745
|
-
[client, locationId, queryOptions]
|
|
1746
|
-
);
|
|
1747
|
-
const cached = productsCache.get(cacheKey);
|
|
1748
|
-
const [products, setProducts] = useState(cached?.products ?? []);
|
|
1749
|
-
const [isComplete, setIsComplete] = useState(cached?.is_complete ?? true);
|
|
1750
|
-
const [totalAvailable, setTotalAvailable] = useState(cached?.total_available);
|
|
1751
|
-
const [pagination, setPagination] = useState(cached?.pagination);
|
|
1752
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
1753
|
-
const [error, setError] = useState(null);
|
|
1754
|
-
useEffect(() => {
|
|
1755
|
-
if (previousLocationIdRef.current !== locationId) {
|
|
1756
|
-
productsCache.clear();
|
|
1757
|
-
productsInflight.clear();
|
|
1758
|
-
previousLocationIdRef.current = locationId;
|
|
1759
|
-
}
|
|
1760
|
-
}, [locationId]);
|
|
1761
|
-
const load = useCallback(
|
|
1762
|
-
async (force = false) => {
|
|
1763
|
-
if (!enabled) {
|
|
1764
|
-
setIsLoading(false);
|
|
1765
|
-
return;
|
|
1766
|
-
}
|
|
1767
|
-
const nextRequestId = ++requestIdRef.current;
|
|
1768
|
-
setError(null);
|
|
1769
|
-
if (!force) {
|
|
1770
|
-
const cacheEntry = productsCache.get(cacheKey);
|
|
1771
|
-
if (cacheEntry) {
|
|
1772
|
-
setProducts(cacheEntry.products);
|
|
1773
|
-
setIsComplete(cacheEntry.is_complete);
|
|
1774
|
-
setTotalAvailable(cacheEntry.total_available);
|
|
1775
|
-
setPagination(cacheEntry.pagination);
|
|
1776
|
-
setIsLoading(false);
|
|
1777
|
-
return;
|
|
1778
|
-
}
|
|
1779
|
-
}
|
|
1780
|
-
setIsLoading(true);
|
|
1781
|
-
try {
|
|
1782
|
-
const existing = productsInflight.get(cacheKey);
|
|
1783
|
-
const promise = existing ?? (async () => {
|
|
1784
|
-
const result = await client.catalogue.getProducts(queryOptions);
|
|
1785
|
-
if (!result.ok) {
|
|
1786
|
-
throw result.error;
|
|
1787
|
-
}
|
|
1788
|
-
return result.value;
|
|
1789
|
-
})();
|
|
1790
|
-
if (!existing) {
|
|
1791
|
-
productsInflight.set(
|
|
1792
|
-
cacheKey,
|
|
1793
|
-
promise.finally(() => {
|
|
1794
|
-
productsInflight.delete(cacheKey);
|
|
1795
|
-
})
|
|
1796
|
-
);
|
|
1797
|
-
}
|
|
1798
|
-
const value = await promise;
|
|
1799
|
-
productsCache.set(cacheKey, {
|
|
1800
|
-
products: value.items,
|
|
1801
|
-
is_complete: value.is_complete,
|
|
1802
|
-
total_available: value.total_available,
|
|
1803
|
-
pagination: value.pagination
|
|
1804
|
-
});
|
|
1805
|
-
if (nextRequestId === requestIdRef.current) {
|
|
1806
|
-
setProducts(value.items);
|
|
1807
|
-
setIsComplete(value.is_complete);
|
|
1808
|
-
setTotalAvailable(value.total_available);
|
|
1809
|
-
setPagination(value.pagination);
|
|
1810
|
-
setError(null);
|
|
1811
|
-
}
|
|
1812
|
-
} catch (loadError) {
|
|
1813
|
-
if (nextRequestId === requestIdRef.current) {
|
|
1814
|
-
setError(loadError);
|
|
1815
|
-
}
|
|
1816
|
-
} finally {
|
|
1817
|
-
if (nextRequestId === requestIdRef.current) {
|
|
1818
|
-
setIsLoading(false);
|
|
1819
|
-
}
|
|
1820
|
-
}
|
|
1821
|
-
},
|
|
1822
|
-
[cacheKey, client, enabled, queryOptions]
|
|
1823
|
-
);
|
|
1824
|
-
useEffect(() => {
|
|
1825
|
-
void load(false);
|
|
1826
|
-
}, [load]);
|
|
1827
|
-
const refetch = useCallback(async () => {
|
|
1828
|
-
productsCache.delete(cacheKey);
|
|
1829
|
-
await load(true);
|
|
1830
|
-
}, [cacheKey, load]);
|
|
1819
|
+
});
|
|
1820
|
+
if (!result.ok) throw result.error;
|
|
1821
|
+
return {
|
|
1822
|
+
products: result.value.items,
|
|
1823
|
+
is_complete: result.value.is_complete,
|
|
1824
|
+
total_available: result.value.total_available,
|
|
1825
|
+
pagination: result.value.pagination
|
|
1826
|
+
};
|
|
1827
|
+
}
|
|
1828
|
+
});
|
|
1829
|
+
function useProducts(options = {}) {
|
|
1830
|
+
const { data, isLoading, error, refetch } = productsQuery(options);
|
|
1831
1831
|
return {
|
|
1832
|
-
products,
|
|
1833
|
-
is_complete:
|
|
1834
|
-
total_available:
|
|
1835
|
-
pagination,
|
|
1832
|
+
products: data?.products ?? [],
|
|
1833
|
+
is_complete: data?.is_complete ?? true,
|
|
1834
|
+
total_available: data?.total_available,
|
|
1835
|
+
pagination: data?.pagination,
|
|
1836
1836
|
isLoading,
|
|
1837
1837
|
error,
|
|
1838
1838
|
refetch
|
|
1839
1839
|
};
|
|
1840
1840
|
}
|
|
1841
|
-
|
|
1842
|
-
|
|
1841
|
+
|
|
1842
|
+
// src/react/hooks/use-product.ts
|
|
1843
1843
|
function isLikelySlug(value) {
|
|
1844
1844
|
return /^[a-z0-9-]+$/.test(value);
|
|
1845
1845
|
}
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1846
|
+
var productQuery = createCachedQuery({
|
|
1847
|
+
name: "useProduct",
|
|
1848
|
+
locationSensitive: true,
|
|
1849
|
+
key: (client, options) => cacheKey(client.getPublicKey(), client.getLocationId(), options.slugOrId),
|
|
1850
|
+
fetch: async (client, options) => {
|
|
1851
|
+
const result = isLikelySlug(options.slugOrId) ? await client.catalogue.getProductBySlug(options.slugOrId) : await client.catalogue.getProduct(options.slugOrId);
|
|
1852
|
+
if (!result.ok) throw result.error;
|
|
1853
|
+
client.activity.trackProductView(result.value.id, {
|
|
1854
|
+
productName: result.value.name,
|
|
1855
|
+
categoryId: result.value.category_id,
|
|
1856
|
+
price: String(result.value.default_price)
|
|
1857
|
+
});
|
|
1858
|
+
return result.value;
|
|
1859
|
+
}
|
|
1860
|
+
});
|
|
1861
|
+
function useProduct(slugOrId, options = {}) {
|
|
1862
|
+
const normalized = (slugOrId || "").trim();
|
|
1863
|
+
const { data, isLoading, error, refetch } = productQuery({
|
|
1864
|
+
...options,
|
|
1865
|
+
slugOrId: normalized,
|
|
1866
|
+
enabled: (options.enabled ?? true) && normalized.length > 0
|
|
1851
1867
|
});
|
|
1868
|
+
return { product: data, isLoading, error, refetch };
|
|
1852
1869
|
}
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1870
|
+
|
|
1871
|
+
// src/react/hooks/use-categories.ts
|
|
1872
|
+
var categoriesQuery = createCachedQuery({
|
|
1873
|
+
name: "useCategories",
|
|
1874
|
+
key: (client) => client.getPublicKey() || "__demo__",
|
|
1875
|
+
fetch: async (client) => {
|
|
1876
|
+
const result = await client.catalogue.getCategories();
|
|
1877
|
+
if (!result.ok) throw result.error;
|
|
1878
|
+
return result.value;
|
|
1858
1879
|
}
|
|
1859
|
-
|
|
1860
|
-
const locationId = client.getLocationId();
|
|
1861
|
-
const previousLocationIdRef = useRef(locationId);
|
|
1862
|
-
const requestIdRef = useRef(0);
|
|
1863
|
-
const trackedProductRef = useRef(null);
|
|
1864
|
-
const normalizedSlugOrId = useMemo(() => (slugOrId || "").trim(), [slugOrId]);
|
|
1865
|
-
const cacheKey = useMemo(
|
|
1866
|
-
() => buildProductCacheKey(client, locationId, normalizedSlugOrId),
|
|
1867
|
-
[client, locationId, normalizedSlugOrId]
|
|
1868
|
-
);
|
|
1869
|
-
const cached = productCache.get(cacheKey);
|
|
1870
|
-
const [product, setProduct] = useState(cached?.product ?? null);
|
|
1871
|
-
const [isLoading, setIsLoading] = useState(
|
|
1872
|
-
enabled && normalizedSlugOrId.length > 0 && !cached
|
|
1873
|
-
);
|
|
1874
|
-
const [error, setError] = useState(null);
|
|
1875
|
-
useEffect(() => {
|
|
1876
|
-
if (previousLocationIdRef.current !== locationId) {
|
|
1877
|
-
productCache.clear();
|
|
1878
|
-
productInflight.clear();
|
|
1879
|
-
previousLocationIdRef.current = locationId;
|
|
1880
|
-
}
|
|
1881
|
-
}, [locationId]);
|
|
1882
|
-
const load = useCallback(
|
|
1883
|
-
async (force = false) => {
|
|
1884
|
-
if (!enabled || normalizedSlugOrId.length === 0) {
|
|
1885
|
-
setProduct(null);
|
|
1886
|
-
setIsLoading(false);
|
|
1887
|
-
return;
|
|
1888
|
-
}
|
|
1889
|
-
const nextRequestId = ++requestIdRef.current;
|
|
1890
|
-
setError(null);
|
|
1891
|
-
if (!force) {
|
|
1892
|
-
const cacheEntry = productCache.get(cacheKey);
|
|
1893
|
-
if (cacheEntry) {
|
|
1894
|
-
setProduct(cacheEntry.product);
|
|
1895
|
-
setIsLoading(false);
|
|
1896
|
-
return;
|
|
1897
|
-
}
|
|
1898
|
-
}
|
|
1899
|
-
setIsLoading(true);
|
|
1900
|
-
try {
|
|
1901
|
-
const existing = productInflight.get(cacheKey);
|
|
1902
|
-
const promise = existing ?? (async () => {
|
|
1903
|
-
const result = isLikelySlug(normalizedSlugOrId) ? await client.catalogue.getProductBySlug(normalizedSlugOrId) : await client.catalogue.getProduct(normalizedSlugOrId);
|
|
1904
|
-
if (!result.ok) {
|
|
1905
|
-
throw result.error;
|
|
1906
|
-
}
|
|
1907
|
-
return result.value;
|
|
1908
|
-
})();
|
|
1909
|
-
if (!existing) {
|
|
1910
|
-
productInflight.set(
|
|
1911
|
-
cacheKey,
|
|
1912
|
-
promise.finally(() => {
|
|
1913
|
-
productInflight.delete(cacheKey);
|
|
1914
|
-
})
|
|
1915
|
-
);
|
|
1916
|
-
}
|
|
1917
|
-
const value = await promise;
|
|
1918
|
-
productCache.set(cacheKey, { product: value });
|
|
1919
|
-
if (nextRequestId === requestIdRef.current) {
|
|
1920
|
-
setProduct(value);
|
|
1921
|
-
setError(null);
|
|
1922
|
-
if (value && trackedProductRef.current !== value.id) {
|
|
1923
|
-
trackedProductRef.current = value.id;
|
|
1924
|
-
client.activity.trackProductView(value.id, {
|
|
1925
|
-
productName: value.name,
|
|
1926
|
-
categoryId: value.category_id,
|
|
1927
|
-
price: String(value.default_price)
|
|
1928
|
-
});
|
|
1929
|
-
}
|
|
1930
|
-
}
|
|
1931
|
-
} catch (loadError) {
|
|
1932
|
-
if (nextRequestId === requestIdRef.current) {
|
|
1933
|
-
setError(loadError);
|
|
1934
|
-
}
|
|
1935
|
-
} finally {
|
|
1936
|
-
if (nextRequestId === requestIdRef.current) {
|
|
1937
|
-
setIsLoading(false);
|
|
1938
|
-
}
|
|
1939
|
-
}
|
|
1940
|
-
},
|
|
1941
|
-
[cacheKey, client, enabled, normalizedSlugOrId]
|
|
1942
|
-
);
|
|
1943
|
-
useEffect(() => {
|
|
1944
|
-
void load(false);
|
|
1945
|
-
}, [load]);
|
|
1946
|
-
const refetch = useCallback(async () => {
|
|
1947
|
-
productCache.delete(cacheKey);
|
|
1948
|
-
await load(true);
|
|
1949
|
-
}, [cacheKey, load]);
|
|
1950
|
-
return { product, isLoading, error, refetch };
|
|
1951
|
-
}
|
|
1952
|
-
var categoriesCache = /* @__PURE__ */ new Map();
|
|
1953
|
-
var categoriesInflight = /* @__PURE__ */ new Map();
|
|
1954
|
-
function buildCategoriesCacheKey(client) {
|
|
1955
|
-
return client.getPublicKey() || "__demo__";
|
|
1956
|
-
}
|
|
1880
|
+
});
|
|
1957
1881
|
function useCategories(options = {}) {
|
|
1958
|
-
const
|
|
1959
|
-
|
|
1960
|
-
if (!client) {
|
|
1961
|
-
throw new Error("useCategories must be used within CimplifyProvider or passed { client }.");
|
|
1962
|
-
}
|
|
1963
|
-
const enabled = options.enabled ?? true;
|
|
1964
|
-
const cacheKey = useMemo(() => buildCategoriesCacheKey(client), [client]);
|
|
1965
|
-
const cached = categoriesCache.get(cacheKey);
|
|
1966
|
-
const [categories, setCategories] = useState(cached ?? []);
|
|
1967
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
1968
|
-
const [error, setError] = useState(null);
|
|
1969
|
-
const load = useCallback(
|
|
1970
|
-
async (force = false) => {
|
|
1971
|
-
if (!enabled) {
|
|
1972
|
-
setIsLoading(false);
|
|
1973
|
-
return;
|
|
1974
|
-
}
|
|
1975
|
-
setError(null);
|
|
1976
|
-
if (!force) {
|
|
1977
|
-
const cachedCategories = categoriesCache.get(cacheKey);
|
|
1978
|
-
if (cachedCategories) {
|
|
1979
|
-
setCategories(cachedCategories);
|
|
1980
|
-
setIsLoading(false);
|
|
1981
|
-
return;
|
|
1982
|
-
}
|
|
1983
|
-
}
|
|
1984
|
-
setIsLoading(true);
|
|
1985
|
-
try {
|
|
1986
|
-
const existing = categoriesInflight.get(cacheKey);
|
|
1987
|
-
const promise = existing ?? (async () => {
|
|
1988
|
-
const result = await client.catalogue.getCategories();
|
|
1989
|
-
if (!result.ok) {
|
|
1990
|
-
throw result.error;
|
|
1991
|
-
}
|
|
1992
|
-
return result.value;
|
|
1993
|
-
})();
|
|
1994
|
-
if (!existing) {
|
|
1995
|
-
categoriesInflight.set(
|
|
1996
|
-
cacheKey,
|
|
1997
|
-
promise.finally(() => {
|
|
1998
|
-
categoriesInflight.delete(cacheKey);
|
|
1999
|
-
})
|
|
2000
|
-
);
|
|
2001
|
-
}
|
|
2002
|
-
const value = await promise;
|
|
2003
|
-
categoriesCache.set(cacheKey, value);
|
|
2004
|
-
setCategories(value);
|
|
2005
|
-
} catch (loadError) {
|
|
2006
|
-
setError(loadError);
|
|
2007
|
-
} finally {
|
|
2008
|
-
setIsLoading(false);
|
|
2009
|
-
}
|
|
2010
|
-
},
|
|
2011
|
-
[cacheKey, client, enabled]
|
|
2012
|
-
);
|
|
2013
|
-
useEffect(() => {
|
|
2014
|
-
void load(false);
|
|
2015
|
-
}, [load]);
|
|
2016
|
-
const refetch = useCallback(async () => {
|
|
2017
|
-
categoriesCache.delete(cacheKey);
|
|
2018
|
-
await load(true);
|
|
2019
|
-
}, [cacheKey, load]);
|
|
2020
|
-
return { categories, isLoading, error, refetch };
|
|
1882
|
+
const { data, isLoading, error, refetch } = categoriesQuery(options);
|
|
1883
|
+
return { categories: data ?? [], isLoading, error, refetch };
|
|
2021
1884
|
}
|
|
2022
1885
|
var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["completed", "cancelled", "refunded"]);
|
|
2023
1886
|
var orderCache = /* @__PURE__ */ new Map();
|
|
@@ -2039,11 +1902,11 @@ function useOrder(orderId, options = {}) {
|
|
|
2039
1902
|
const previousStatusRef = useRef(null);
|
|
2040
1903
|
const onStatusChangeRef = useRef(options.onStatusChange);
|
|
2041
1904
|
onStatusChangeRef.current = options.onStatusChange;
|
|
2042
|
-
const
|
|
1905
|
+
const cacheKey2 = useMemo(
|
|
2043
1906
|
() => buildOrderCacheKey(client, normalizedOrderId),
|
|
2044
1907
|
[client, normalizedOrderId]
|
|
2045
1908
|
);
|
|
2046
|
-
const cached = orderCache.get(
|
|
1909
|
+
const cached = orderCache.get(cacheKey2);
|
|
2047
1910
|
const [order, setOrder] = useState(cached?.order ?? null);
|
|
2048
1911
|
const [isLoading, setIsLoading] = useState(
|
|
2049
1912
|
enabled && normalizedOrderId.length > 0 && !cached
|
|
@@ -2059,7 +1922,7 @@ function useOrder(orderId, options = {}) {
|
|
|
2059
1922
|
const nextRequestId = ++requestIdRef.current;
|
|
2060
1923
|
setError(null);
|
|
2061
1924
|
if (!force) {
|
|
2062
|
-
const cacheEntry = orderCache.get(
|
|
1925
|
+
const cacheEntry = orderCache.get(cacheKey2);
|
|
2063
1926
|
if (cacheEntry) {
|
|
2064
1927
|
setOrder(cacheEntry.order);
|
|
2065
1928
|
setIsLoading(false);
|
|
@@ -2068,7 +1931,7 @@ function useOrder(orderId, options = {}) {
|
|
|
2068
1931
|
}
|
|
2069
1932
|
setIsLoading(true);
|
|
2070
1933
|
try {
|
|
2071
|
-
const existing = orderInflight.get(
|
|
1934
|
+
const existing = orderInflight.get(cacheKey2);
|
|
2072
1935
|
const promise = existing ?? (async () => {
|
|
2073
1936
|
const result = await client.orders.get(normalizedOrderId);
|
|
2074
1937
|
if (!result.ok) {
|
|
@@ -2078,14 +1941,14 @@ function useOrder(orderId, options = {}) {
|
|
|
2078
1941
|
})();
|
|
2079
1942
|
if (!existing) {
|
|
2080
1943
|
orderInflight.set(
|
|
2081
|
-
|
|
1944
|
+
cacheKey2,
|
|
2082
1945
|
promise.finally(() => {
|
|
2083
|
-
orderInflight.delete(
|
|
1946
|
+
orderInflight.delete(cacheKey2);
|
|
2084
1947
|
})
|
|
2085
1948
|
);
|
|
2086
1949
|
}
|
|
2087
1950
|
const value = await promise;
|
|
2088
|
-
orderCache.set(
|
|
1951
|
+
orderCache.set(cacheKey2, { order: value });
|
|
2089
1952
|
if (nextRequestId === requestIdRef.current) {
|
|
2090
1953
|
setOrder(value);
|
|
2091
1954
|
setError(null);
|
|
@@ -2106,7 +1969,7 @@ function useOrder(orderId, options = {}) {
|
|
|
2106
1969
|
}
|
|
2107
1970
|
}
|
|
2108
1971
|
},
|
|
2109
|
-
[
|
|
1972
|
+
[cacheKey2, client, enabled, normalizedOrderId]
|
|
2110
1973
|
);
|
|
2111
1974
|
useEffect(() => {
|
|
2112
1975
|
void load(false);
|
|
@@ -2124,9 +1987,9 @@ function useOrder(orderId, options = {}) {
|
|
|
2124
1987
|
};
|
|
2125
1988
|
}, [enabled, isTerminal, load, normalizedOrderId, poll, pollInterval]);
|
|
2126
1989
|
const refetch = useCallback(async () => {
|
|
2127
|
-
orderCache.delete(
|
|
1990
|
+
orderCache.delete(cacheKey2);
|
|
2128
1991
|
await load(true);
|
|
2129
|
-
}, [
|
|
1992
|
+
}, [cacheKey2, load]);
|
|
2130
1993
|
return { order, isLoading, error, refetch, isTerminal };
|
|
2131
1994
|
}
|
|
2132
1995
|
var LOCATION_STORAGE_KEY2 = "cimplify_location_id";
|
|
@@ -2229,216 +2092,64 @@ function useLocations(options = {}) {
|
|
|
2229
2092
|
isLoading
|
|
2230
2093
|
};
|
|
2231
2094
|
}
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2095
|
+
|
|
2096
|
+
// src/react/hooks/use-collections.ts
|
|
2097
|
+
var collectionsQuery = createCachedQuery({
|
|
2098
|
+
name: "useCollections",
|
|
2099
|
+
locationSensitive: true,
|
|
2100
|
+
key: (client) => cacheKey(client.getPublicKey(), client.getLocationId()),
|
|
2101
|
+
fetch: async (client) => {
|
|
2102
|
+
const result = await client.catalogue.getCollections();
|
|
2103
|
+
if (!result.ok) throw result.error;
|
|
2104
|
+
return result.value;
|
|
2105
|
+
}
|
|
2106
|
+
});
|
|
2107
|
+
function useCollections(options = {}) {
|
|
2108
|
+
const { data, isLoading, error, refetch } = collectionsQuery(options);
|
|
2109
|
+
return { collections: data ?? [], isLoading, error, refetch };
|
|
2110
|
+
}
|
|
2111
|
+
|
|
2112
|
+
// src/react/hooks/use-collection.ts
|
|
2113
|
+
function isLikelySlug2(value) {
|
|
2114
|
+
return /^[a-z0-9-]+$/.test(value);
|
|
2115
|
+
}
|
|
2116
|
+
var collectionQuery = createCachedQuery({
|
|
2117
|
+
name: "useCollection",
|
|
2118
|
+
locationSensitive: true,
|
|
2119
|
+
key: (client, options) => cacheKey(client.getPublicKey(), client.getLocationId(), options.idOrSlug),
|
|
2120
|
+
fetch: async (client, options) => {
|
|
2121
|
+
const collectionResult = isLikelySlug2(options.idOrSlug) ? await client.catalogue.getCollectionBySlug(options.idOrSlug) : await client.catalogue.getCollection(options.idOrSlug);
|
|
2122
|
+
if (!collectionResult.ok) throw collectionResult.error;
|
|
2123
|
+
const productsResult = await client.catalogue.getCollectionProducts(
|
|
2124
|
+
collectionResult.value.id
|
|
2125
|
+
);
|
|
2126
|
+
if (!productsResult.ok) throw productsResult.error;
|
|
2127
|
+
return {
|
|
2128
|
+
collection: collectionResult.value,
|
|
2129
|
+
products: productsResult.value
|
|
2130
|
+
};
|
|
2131
|
+
}
|
|
2132
|
+
});
|
|
2133
|
+
function useCollection(idOrSlug, options = {}) {
|
|
2134
|
+
const normalized = (idOrSlug || "").trim();
|
|
2135
|
+
const { data, isLoading, error, refetch } = collectionQuery({
|
|
2136
|
+
...options,
|
|
2137
|
+
idOrSlug: normalized,
|
|
2138
|
+
enabled: (options.enabled ?? true) && normalized.length > 0
|
|
2238
2139
|
});
|
|
2140
|
+
return {
|
|
2141
|
+
collection: data?.collection ?? null,
|
|
2142
|
+
products: data?.products ?? [],
|
|
2143
|
+
isLoading,
|
|
2144
|
+
error,
|
|
2145
|
+
refetch
|
|
2146
|
+
};
|
|
2239
2147
|
}
|
|
2240
|
-
function
|
|
2148
|
+
function useSearch(options = {}) {
|
|
2241
2149
|
const context = useOptionalCimplifyClient();
|
|
2242
2150
|
const client = options.client ?? context?.client;
|
|
2243
2151
|
if (!client) {
|
|
2244
|
-
throw new Error("
|
|
2245
|
-
}
|
|
2246
|
-
const enabled = options.enabled ?? true;
|
|
2247
|
-
const locationId = client.getLocationId();
|
|
2248
|
-
const previousLocationIdRef = useRef(locationId);
|
|
2249
|
-
const requestIdRef = useRef(0);
|
|
2250
|
-
const cacheKey = useMemo(
|
|
2251
|
-
() => buildCollectionsCacheKey(client, locationId),
|
|
2252
|
-
[client, locationId]
|
|
2253
|
-
);
|
|
2254
|
-
const cached = collectionsCache.get(cacheKey);
|
|
2255
|
-
const [collections, setCollections] = useState(cached?.collections ?? []);
|
|
2256
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
2257
|
-
const [error, setError] = useState(null);
|
|
2258
|
-
useEffect(() => {
|
|
2259
|
-
if (previousLocationIdRef.current !== locationId) {
|
|
2260
|
-
collectionsCache.clear();
|
|
2261
|
-
collectionsInflight.clear();
|
|
2262
|
-
previousLocationIdRef.current = locationId;
|
|
2263
|
-
}
|
|
2264
|
-
}, [locationId]);
|
|
2265
|
-
const load = useCallback(
|
|
2266
|
-
async (force = false) => {
|
|
2267
|
-
if (!enabled) {
|
|
2268
|
-
setIsLoading(false);
|
|
2269
|
-
return;
|
|
2270
|
-
}
|
|
2271
|
-
const nextRequestId = ++requestIdRef.current;
|
|
2272
|
-
setError(null);
|
|
2273
|
-
if (!force) {
|
|
2274
|
-
const cacheEntry = collectionsCache.get(cacheKey);
|
|
2275
|
-
if (cacheEntry) {
|
|
2276
|
-
setCollections(cacheEntry.collections);
|
|
2277
|
-
setIsLoading(false);
|
|
2278
|
-
return;
|
|
2279
|
-
}
|
|
2280
|
-
}
|
|
2281
|
-
setIsLoading(true);
|
|
2282
|
-
try {
|
|
2283
|
-
const existing = collectionsInflight.get(cacheKey);
|
|
2284
|
-
const promise = existing ?? (async () => {
|
|
2285
|
-
const result = await client.catalogue.getCollections();
|
|
2286
|
-
if (!result.ok) {
|
|
2287
|
-
throw result.error;
|
|
2288
|
-
}
|
|
2289
|
-
return result.value;
|
|
2290
|
-
})();
|
|
2291
|
-
if (!existing) {
|
|
2292
|
-
collectionsInflight.set(cacheKey, promise);
|
|
2293
|
-
promise.finally(() => {
|
|
2294
|
-
collectionsInflight.delete(cacheKey);
|
|
2295
|
-
}).catch(() => void 0);
|
|
2296
|
-
}
|
|
2297
|
-
const value = await promise;
|
|
2298
|
-
collectionsCache.set(cacheKey, { collections: value });
|
|
2299
|
-
if (nextRequestId === requestIdRef.current) {
|
|
2300
|
-
setCollections(value);
|
|
2301
|
-
setError(null);
|
|
2302
|
-
}
|
|
2303
|
-
} catch (loadError) {
|
|
2304
|
-
if (nextRequestId === requestIdRef.current) {
|
|
2305
|
-
setError(loadError);
|
|
2306
|
-
}
|
|
2307
|
-
} finally {
|
|
2308
|
-
if (nextRequestId === requestIdRef.current) {
|
|
2309
|
-
setIsLoading(false);
|
|
2310
|
-
}
|
|
2311
|
-
}
|
|
2312
|
-
},
|
|
2313
|
-
[cacheKey, client, enabled]
|
|
2314
|
-
);
|
|
2315
|
-
useEffect(() => {
|
|
2316
|
-
void load(false);
|
|
2317
|
-
}, [load]);
|
|
2318
|
-
const refetch = useCallback(async () => {
|
|
2319
|
-
collectionsCache.delete(cacheKey);
|
|
2320
|
-
await load(true);
|
|
2321
|
-
}, [cacheKey, load]);
|
|
2322
|
-
return { collections, isLoading, error, refetch };
|
|
2323
|
-
}
|
|
2324
|
-
var collectionCache = /* @__PURE__ */ new Map();
|
|
2325
|
-
var collectionInflight = /* @__PURE__ */ new Map();
|
|
2326
|
-
function isLikelySlug2(value) {
|
|
2327
|
-
return /^[a-z0-9-]+$/.test(value);
|
|
2328
|
-
}
|
|
2329
|
-
function buildCollectionCacheKey(client, locationId, idOrSlug) {
|
|
2330
|
-
return JSON.stringify({
|
|
2331
|
-
key: client.getPublicKey(),
|
|
2332
|
-
location_id: locationId || "__none__",
|
|
2333
|
-
collection: idOrSlug
|
|
2334
|
-
});
|
|
2335
|
-
}
|
|
2336
|
-
function useCollection(idOrSlug, options = {}) {
|
|
2337
|
-
const context = useOptionalCimplifyClient();
|
|
2338
|
-
const client = options.client ?? context?.client;
|
|
2339
|
-
if (!client) {
|
|
2340
|
-
throw new Error("useCollection must be used within CimplifyProvider or passed { client }.");
|
|
2341
|
-
}
|
|
2342
|
-
const enabled = options.enabled ?? true;
|
|
2343
|
-
const locationId = client.getLocationId();
|
|
2344
|
-
const previousLocationIdRef = useRef(locationId);
|
|
2345
|
-
const requestIdRef = useRef(0);
|
|
2346
|
-
const normalizedIdOrSlug = useMemo(() => (idOrSlug || "").trim(), [idOrSlug]);
|
|
2347
|
-
const cacheKey = useMemo(
|
|
2348
|
-
() => buildCollectionCacheKey(client, locationId, normalizedIdOrSlug),
|
|
2349
|
-
[client, locationId, normalizedIdOrSlug]
|
|
2350
|
-
);
|
|
2351
|
-
const cached = collectionCache.get(cacheKey);
|
|
2352
|
-
const [collection, setCollection] = useState(cached?.collection ?? null);
|
|
2353
|
-
const [products, setProducts] = useState(cached?.products ?? []);
|
|
2354
|
-
const [isLoading, setIsLoading] = useState(
|
|
2355
|
-
enabled && normalizedIdOrSlug.length > 0 && !cached
|
|
2356
|
-
);
|
|
2357
|
-
const [error, setError] = useState(null);
|
|
2358
|
-
useEffect(() => {
|
|
2359
|
-
if (previousLocationIdRef.current !== locationId) {
|
|
2360
|
-
collectionCache.clear();
|
|
2361
|
-
collectionInflight.clear();
|
|
2362
|
-
previousLocationIdRef.current = locationId;
|
|
2363
|
-
}
|
|
2364
|
-
}, [locationId]);
|
|
2365
|
-
const load = useCallback(
|
|
2366
|
-
async (force = false) => {
|
|
2367
|
-
if (!enabled || normalizedIdOrSlug.length === 0) {
|
|
2368
|
-
setCollection(null);
|
|
2369
|
-
setProducts([]);
|
|
2370
|
-
setIsLoading(false);
|
|
2371
|
-
return;
|
|
2372
|
-
}
|
|
2373
|
-
const nextRequestId = ++requestIdRef.current;
|
|
2374
|
-
setError(null);
|
|
2375
|
-
if (!force) {
|
|
2376
|
-
const cacheEntry = collectionCache.get(cacheKey);
|
|
2377
|
-
if (cacheEntry) {
|
|
2378
|
-
setCollection(cacheEntry.collection);
|
|
2379
|
-
setProducts(cacheEntry.products);
|
|
2380
|
-
setIsLoading(false);
|
|
2381
|
-
return;
|
|
2382
|
-
}
|
|
2383
|
-
}
|
|
2384
|
-
setIsLoading(true);
|
|
2385
|
-
try {
|
|
2386
|
-
const existing = collectionInflight.get(cacheKey);
|
|
2387
|
-
const promise = existing ?? (async () => {
|
|
2388
|
-
const collectionResult = isLikelySlug2(normalizedIdOrSlug) ? await client.catalogue.getCollectionBySlug(normalizedIdOrSlug) : await client.catalogue.getCollection(normalizedIdOrSlug);
|
|
2389
|
-
if (!collectionResult.ok) {
|
|
2390
|
-
throw collectionResult.error;
|
|
2391
|
-
}
|
|
2392
|
-
const productsResult = await client.catalogue.getCollectionProducts(
|
|
2393
|
-
collectionResult.value.id
|
|
2394
|
-
);
|
|
2395
|
-
if (!productsResult.ok) {
|
|
2396
|
-
throw productsResult.error;
|
|
2397
|
-
}
|
|
2398
|
-
return {
|
|
2399
|
-
collection: collectionResult.value,
|
|
2400
|
-
products: productsResult.value
|
|
2401
|
-
};
|
|
2402
|
-
})();
|
|
2403
|
-
if (!existing) {
|
|
2404
|
-
collectionInflight.set(cacheKey, promise);
|
|
2405
|
-
promise.finally(() => {
|
|
2406
|
-
collectionInflight.delete(cacheKey);
|
|
2407
|
-
}).catch(() => void 0);
|
|
2408
|
-
}
|
|
2409
|
-
const value = await promise;
|
|
2410
|
-
collectionCache.set(cacheKey, value);
|
|
2411
|
-
if (nextRequestId === requestIdRef.current) {
|
|
2412
|
-
setCollection(value.collection);
|
|
2413
|
-
setProducts(value.products);
|
|
2414
|
-
setError(null);
|
|
2415
|
-
}
|
|
2416
|
-
} catch (loadError) {
|
|
2417
|
-
if (nextRequestId === requestIdRef.current) {
|
|
2418
|
-
setError(loadError);
|
|
2419
|
-
}
|
|
2420
|
-
} finally {
|
|
2421
|
-
if (nextRequestId === requestIdRef.current) {
|
|
2422
|
-
setIsLoading(false);
|
|
2423
|
-
}
|
|
2424
|
-
}
|
|
2425
|
-
},
|
|
2426
|
-
[cacheKey, client, enabled, normalizedIdOrSlug]
|
|
2427
|
-
);
|
|
2428
|
-
useEffect(() => {
|
|
2429
|
-
void load(false);
|
|
2430
|
-
}, [load]);
|
|
2431
|
-
const refetch = useCallback(async () => {
|
|
2432
|
-
collectionCache.delete(cacheKey);
|
|
2433
|
-
await load(true);
|
|
2434
|
-
}, [cacheKey, load]);
|
|
2435
|
-
return { collection, products, isLoading, error, refetch };
|
|
2436
|
-
}
|
|
2437
|
-
function useSearch(options = {}) {
|
|
2438
|
-
const context = useOptionalCimplifyClient();
|
|
2439
|
-
const client = options.client ?? context?.client;
|
|
2440
|
-
if (!client) {
|
|
2441
|
-
throw new Error("useSearch must be used within CimplifyProvider or passed { client }.");
|
|
2152
|
+
throw new Error("useSearch must be used within CimplifyProvider or passed { client }.");
|
|
2442
2153
|
}
|
|
2443
2154
|
const minLength = Math.max(0, options.minLength ?? 2);
|
|
2444
2155
|
const debounceMs = Math.max(0, options.debounceMs ?? 300);
|
|
@@ -2609,11 +2320,11 @@ function useQuote(input, options = {}) {
|
|
|
2609
2320
|
const normalized = normalizeInput(input, locationId);
|
|
2610
2321
|
return normalized.product_id.length > 0 ? normalized : null;
|
|
2611
2322
|
}, [inputSignature, locationId]);
|
|
2612
|
-
const
|
|
2323
|
+
const cacheKey2 = useMemo(
|
|
2613
2324
|
() => buildQuoteCacheKey(client, locationId, inputSignature),
|
|
2614
2325
|
[client, inputSignature, locationId]
|
|
2615
2326
|
);
|
|
2616
|
-
const cached = quoteCache.get(
|
|
2327
|
+
const cached = quoteCache.get(cacheKey2);
|
|
2617
2328
|
const [quote, setQuote] = useState(cached?.quote ?? null);
|
|
2618
2329
|
const [isLoading, setIsLoading] = useState(enabled && normalizedInput !== null && !cached);
|
|
2619
2330
|
const [error, setError] = useState(null);
|
|
@@ -2639,7 +2350,7 @@ function useQuote(input, options = {}) {
|
|
|
2639
2350
|
const nextRequestId = ++requestIdRef.current;
|
|
2640
2351
|
setError(null);
|
|
2641
2352
|
if (!force) {
|
|
2642
|
-
const cacheEntry = quoteCache.get(
|
|
2353
|
+
const cacheEntry = quoteCache.get(cacheKey2);
|
|
2643
2354
|
if (cacheEntry) {
|
|
2644
2355
|
setQuote(cacheEntry.quote);
|
|
2645
2356
|
setMessages(cacheEntry.quote?.ui_messages ?? []);
|
|
@@ -2652,7 +2363,7 @@ function useQuote(input, options = {}) {
|
|
|
2652
2363
|
setQuote(null);
|
|
2653
2364
|
setMessages([]);
|
|
2654
2365
|
try {
|
|
2655
|
-
const existing = quoteInflight.get(
|
|
2366
|
+
const existing = quoteInflight.get(cacheKey2);
|
|
2656
2367
|
const promise = existing ?? (async () => {
|
|
2657
2368
|
const result = await client.catalogue.fetchQuote(normalizedInput);
|
|
2658
2369
|
if (!result.ok) {
|
|
@@ -2661,13 +2372,13 @@ function useQuote(input, options = {}) {
|
|
|
2661
2372
|
return result.value;
|
|
2662
2373
|
})();
|
|
2663
2374
|
if (!existing) {
|
|
2664
|
-
quoteInflight.set(
|
|
2375
|
+
quoteInflight.set(cacheKey2, promise);
|
|
2665
2376
|
promise.finally(() => {
|
|
2666
|
-
quoteInflight.delete(
|
|
2377
|
+
quoteInflight.delete(cacheKey2);
|
|
2667
2378
|
}).catch(() => void 0);
|
|
2668
2379
|
}
|
|
2669
2380
|
const value = await promise;
|
|
2670
|
-
quoteCache.set(
|
|
2381
|
+
quoteCache.set(cacheKey2, { quote: value });
|
|
2671
2382
|
if (nextRequestId === requestIdRef.current) {
|
|
2672
2383
|
setQuote(value);
|
|
2673
2384
|
setMessages(value.ui_messages ?? []);
|
|
@@ -2684,13 +2395,13 @@ function useQuote(input, options = {}) {
|
|
|
2684
2395
|
}
|
|
2685
2396
|
}
|
|
2686
2397
|
},
|
|
2687
|
-
[
|
|
2398
|
+
[cacheKey2, client, enabled, normalizedInput]
|
|
2688
2399
|
);
|
|
2689
2400
|
useEffect(() => {
|
|
2690
2401
|
if (debounceTimerRef.current) {
|
|
2691
2402
|
clearTimeout(debounceTimerRef.current);
|
|
2692
2403
|
}
|
|
2693
|
-
const hasCached = quoteCache.has(
|
|
2404
|
+
const hasCached = quoteCache.has(cacheKey2);
|
|
2694
2405
|
if (hasCached || !enabled || !normalizedInput) {
|
|
2695
2406
|
void load(false);
|
|
2696
2407
|
} else {
|
|
@@ -2704,7 +2415,7 @@ function useQuote(input, options = {}) {
|
|
|
2704
2415
|
debounceTimerRef.current = null;
|
|
2705
2416
|
}
|
|
2706
2417
|
};
|
|
2707
|
-
}, [load,
|
|
2418
|
+
}, [load, cacheKey2, enabled, normalizedInput]);
|
|
2708
2419
|
const refresh = useCallback(async () => {
|
|
2709
2420
|
if (!enabled || !normalizedInput) {
|
|
2710
2421
|
return;
|
|
@@ -2725,7 +2436,7 @@ function useQuote(input, options = {}) {
|
|
|
2725
2436
|
throw result.error;
|
|
2726
2437
|
}
|
|
2727
2438
|
const refreshed = result.value.quote;
|
|
2728
|
-
quoteCache.set(
|
|
2439
|
+
quoteCache.set(cacheKey2, { quote: refreshed });
|
|
2729
2440
|
if (nextRequestId === requestIdRef.current) {
|
|
2730
2441
|
setQuote(refreshed);
|
|
2731
2442
|
setMessages(refreshed.ui_messages ?? []);
|
|
@@ -2741,7 +2452,7 @@ function useQuote(input, options = {}) {
|
|
|
2741
2452
|
setIsLoading(false);
|
|
2742
2453
|
}
|
|
2743
2454
|
}
|
|
2744
|
-
}, [
|
|
2455
|
+
}, [cacheKey2, client, enabled, load, normalizedInput, quote]);
|
|
2745
2456
|
useEffect(() => {
|
|
2746
2457
|
if (!Number.isFinite(quoteExpiryTimestamp)) {
|
|
2747
2458
|
setIsExpired(false);
|
|
@@ -2773,1930 +2484,628 @@ function useQuote(input, options = {}) {
|
|
|
2773
2484
|
}, [autoRefresh, enabled, quoteExpiryTimestamp, refresh, refreshBeforeExpiryMs]);
|
|
2774
2485
|
return { quote, isLoading, error, refresh, isExpired, messages };
|
|
2775
2486
|
}
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2487
|
+
|
|
2488
|
+
// src/react/hooks/use-taxonomies.ts
|
|
2489
|
+
var taxonomiesQuery = createCachedQuery({
|
|
2490
|
+
name: "useTaxonomies",
|
|
2491
|
+
key: (client, options) => cacheKey(client.getPublicKey(), options.parentId ?? "__root__"),
|
|
2492
|
+
fetch: async (client, options) => {
|
|
2493
|
+
const result = await client.catalogue.getTaxonomies(options.parentId);
|
|
2494
|
+
if (!result.ok) throw result.error;
|
|
2495
|
+
return result.value;
|
|
2496
|
+
}
|
|
2497
|
+
});
|
|
2784
2498
|
function useTaxonomies(options = {}) {
|
|
2499
|
+
const { data, isLoading, error, refetch } = taxonomiesQuery(options);
|
|
2500
|
+
return { taxonomies: data ?? [], isLoading, error, refetch };
|
|
2501
|
+
}
|
|
2502
|
+
|
|
2503
|
+
// src/react/hooks/use-taxonomy.ts
|
|
2504
|
+
var taxonomyQuery = createCachedQuery({
|
|
2505
|
+
name: "useTaxonomy",
|
|
2506
|
+
key: (client, options) => cacheKey(client.getPublicKey(), options.id),
|
|
2507
|
+
fetch: async (client, options) => {
|
|
2508
|
+
const result = await client.catalogue.getTaxonomy(options.id);
|
|
2509
|
+
if (!result.ok) throw result.error;
|
|
2510
|
+
client.activity.trackCategoryView(result.value.id, {
|
|
2511
|
+
categoryName: result.value.name
|
|
2512
|
+
});
|
|
2513
|
+
return result.value;
|
|
2514
|
+
}
|
|
2515
|
+
});
|
|
2516
|
+
function useTaxonomy(id, options = {}) {
|
|
2517
|
+
const { data, isLoading, error, refetch } = taxonomyQuery({ ...options, id });
|
|
2518
|
+
return { taxonomy: data, isLoading, error, refetch };
|
|
2519
|
+
}
|
|
2520
|
+
|
|
2521
|
+
// src/react/hooks/use-taxonomy-path.ts
|
|
2522
|
+
var taxonomyPathQuery = createCachedQuery({
|
|
2523
|
+
name: "useTaxonomyPath",
|
|
2524
|
+
key: (client, options) => cacheKey(client.getPublicKey(), options.id),
|
|
2525
|
+
fetch: async (client, options) => {
|
|
2526
|
+
const result = await client.catalogue.getTaxonomyPath(options.id);
|
|
2527
|
+
if (!result.ok) throw result.error;
|
|
2528
|
+
return result.value;
|
|
2529
|
+
}
|
|
2530
|
+
});
|
|
2531
|
+
function useTaxonomyPath(id, options = {}) {
|
|
2532
|
+
const { data, isLoading, error, refetch } = taxonomyPathQuery({ ...options, id });
|
|
2533
|
+
return { path: data ?? [], isLoading, error, refetch };
|
|
2534
|
+
}
|
|
2535
|
+
|
|
2536
|
+
// src/react/hooks/use-product-schedules.ts
|
|
2537
|
+
var productSchedulesQuery = createCachedQuery({
|
|
2538
|
+
name: "useProductSchedules",
|
|
2539
|
+
key: (client, options) => cacheKey(client.getPublicKey(), options.productId),
|
|
2540
|
+
fetch: async (client, options) => {
|
|
2541
|
+
const result = await client.catalogue.getProductSchedules(options.productId);
|
|
2542
|
+
if (!result.ok) throw result.error;
|
|
2543
|
+
return result.value;
|
|
2544
|
+
}
|
|
2545
|
+
});
|
|
2546
|
+
function useProductSchedules(productId, options = {}) {
|
|
2547
|
+
const { data, isLoading, error, refetch } = productSchedulesQuery({ ...options, productId });
|
|
2548
|
+
return { schedules: data ?? [], isLoading, error, refetch };
|
|
2549
|
+
}
|
|
2550
|
+
|
|
2551
|
+
// src/react/hooks/use-product-availability.ts
|
|
2552
|
+
var productAvailabilityQuery = createCachedQuery({
|
|
2553
|
+
name: "useProductAvailability",
|
|
2554
|
+
locationSensitive: true,
|
|
2555
|
+
key: (client, options) => {
|
|
2556
|
+
const locationId = options.locationId ?? client.getLocationId();
|
|
2557
|
+
return cacheKey(client.getPublicKey(), options.productId, locationId);
|
|
2558
|
+
},
|
|
2559
|
+
fetch: async (client, options) => {
|
|
2560
|
+
const locationId = options.locationId ?? client.getLocationId();
|
|
2561
|
+
if (!locationId) return null;
|
|
2562
|
+
const result = await client.catalogue.checkProductAvailableNow(options.productId, locationId);
|
|
2563
|
+
if (!result.ok) throw result.error;
|
|
2564
|
+
return result.value;
|
|
2565
|
+
}
|
|
2566
|
+
});
|
|
2567
|
+
function useProductAvailability(productId, options = {}) {
|
|
2568
|
+
const { data, isLoading, error, refetch } = productAvailabilityQuery({ ...options, productId });
|
|
2569
|
+
return {
|
|
2570
|
+
isAvailable: data?.is_available ?? null,
|
|
2571
|
+
schedulesToday: data?.schedules_today ?? [],
|
|
2572
|
+
isLoading,
|
|
2573
|
+
error,
|
|
2574
|
+
refetch
|
|
2575
|
+
};
|
|
2576
|
+
}
|
|
2577
|
+
|
|
2578
|
+
// src/react/hooks/use-deals.ts
|
|
2579
|
+
function resolveLocationId(client, options) {
|
|
2580
|
+
return options.locationId ?? client.getLocationId() ?? void 0;
|
|
2581
|
+
}
|
|
2582
|
+
var dealsQuery = createCachedQuery({
|
|
2583
|
+
name: "useDeals",
|
|
2584
|
+
locationSensitive: true,
|
|
2585
|
+
key: (client, options) => cacheKey(client.getPublicKey(), resolveLocationId(client, options)),
|
|
2586
|
+
fetch: async (client, options) => {
|
|
2587
|
+
const result = await client.catalogue.getDeals(resolveLocationId(client, options));
|
|
2588
|
+
if (!result.ok) throw result.error;
|
|
2589
|
+
return result.value;
|
|
2590
|
+
}
|
|
2591
|
+
});
|
|
2592
|
+
function useDeals(options = {}) {
|
|
2593
|
+
const { data, isLoading, error, refetch } = dealsQuery(options);
|
|
2594
|
+
return { deals: data ?? [], isLoading, error, refetch };
|
|
2595
|
+
}
|
|
2596
|
+
|
|
2597
|
+
// src/react/hooks/use-products-on-sale.ts
|
|
2598
|
+
var productsOnSaleQuery = createCachedQuery({
|
|
2599
|
+
name: "useProductsOnSale",
|
|
2600
|
+
key: (client) => client.getPublicKey() || "__demo__",
|
|
2601
|
+
fetch: async (client) => {
|
|
2602
|
+
const result = await client.catalogue.getProductsOnSale();
|
|
2603
|
+
if (!result.ok) throw result.error;
|
|
2604
|
+
return result.value;
|
|
2605
|
+
}
|
|
2606
|
+
});
|
|
2607
|
+
function useProductsOnSale(options = {}) {
|
|
2608
|
+
const { data, isLoading, error, refetch } = productsOnSaleQuery(options);
|
|
2609
|
+
return { products: data ?? [], isLoading, error, refetch };
|
|
2610
|
+
}
|
|
2611
|
+
|
|
2612
|
+
// src/react/hooks/use-product-deals.ts
|
|
2613
|
+
var productDealsQuery = createCachedQuery({
|
|
2614
|
+
name: "useProductDeals",
|
|
2615
|
+
key: (client, options) => cacheKey(client.getPublicKey(), options.productId),
|
|
2616
|
+
fetch: async (client, options) => {
|
|
2617
|
+
const result = await client.catalogue.getProductDeals(options.productId);
|
|
2618
|
+
if (!result.ok) throw result.error;
|
|
2619
|
+
return result.value;
|
|
2620
|
+
}
|
|
2621
|
+
});
|
|
2622
|
+
function useProductDeals(productId, options = {}) {
|
|
2623
|
+
const { data, isLoading, error, refetch } = productDealsQuery({ ...options, productId });
|
|
2624
|
+
return { deals: data ?? [], isLoading, error, refetch };
|
|
2625
|
+
}
|
|
2626
|
+
function useValidateDiscount(options = {}) {
|
|
2785
2627
|
const context = useOptionalCimplifyClient();
|
|
2786
2628
|
const client = options.client ?? context?.client;
|
|
2787
2629
|
if (!client) {
|
|
2788
|
-
throw new Error("
|
|
2630
|
+
throw new Error("useValidateDiscount must be used within CimplifyProvider or passed { client }.");
|
|
2789
2631
|
}
|
|
2790
|
-
const
|
|
2791
|
-
const cacheKey = useMemo(
|
|
2792
|
-
() => buildTaxonomiesCacheKey(client, options.parentId),
|
|
2793
|
-
[client, options.parentId]
|
|
2794
|
-
);
|
|
2795
|
-
const cached = taxonomiesCache.get(cacheKey);
|
|
2796
|
-
const [taxonomies, setTaxonomies] = useState(cached ?? []);
|
|
2797
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
2632
|
+
const [isValidating, setIsValidating] = useState(false);
|
|
2798
2633
|
const [error, setError] = useState(null);
|
|
2799
|
-
const
|
|
2800
|
-
|
|
2801
|
-
async (force = false) => {
|
|
2802
|
-
if (!enabled) {
|
|
2803
|
-
setIsLoading(false);
|
|
2804
|
-
return;
|
|
2805
|
-
}
|
|
2634
|
+
const validate = useCallback(
|
|
2635
|
+
async (code, orderSubtotal, locationId) => {
|
|
2806
2636
|
setError(null);
|
|
2807
|
-
|
|
2808
|
-
const cachedTaxonomies = taxonomiesCache.get(cacheKey);
|
|
2809
|
-
if (cachedTaxonomies) {
|
|
2810
|
-
setTaxonomies(cachedTaxonomies);
|
|
2811
|
-
setIsLoading(false);
|
|
2812
|
-
return;
|
|
2813
|
-
}
|
|
2814
|
-
}
|
|
2815
|
-
setIsLoading(true);
|
|
2637
|
+
setIsValidating(true);
|
|
2816
2638
|
try {
|
|
2817
|
-
const
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
throw result.error;
|
|
2822
|
-
}
|
|
2823
|
-
return result.value;
|
|
2824
|
-
})();
|
|
2825
|
-
if (!existing) {
|
|
2826
|
-
taxonomiesInflight.set(
|
|
2827
|
-
cacheKey,
|
|
2828
|
-
promise.finally(() => {
|
|
2829
|
-
taxonomiesInflight.delete(cacheKey);
|
|
2830
|
-
})
|
|
2831
|
-
);
|
|
2639
|
+
const result = await client.catalogue.validateDiscountCode(code, orderSubtotal, locationId);
|
|
2640
|
+
if (!result.ok) {
|
|
2641
|
+
setError(result.error);
|
|
2642
|
+
return null;
|
|
2832
2643
|
}
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
setError(loadError);
|
|
2644
|
+
return result.value;
|
|
2645
|
+
} catch (validateError) {
|
|
2646
|
+
setError(validateError);
|
|
2647
|
+
return null;
|
|
2838
2648
|
} finally {
|
|
2839
|
-
|
|
2649
|
+
setIsValidating(false);
|
|
2840
2650
|
}
|
|
2841
2651
|
},
|
|
2842
|
-
[
|
|
2652
|
+
[client]
|
|
2843
2653
|
);
|
|
2844
|
-
|
|
2845
|
-
void load(false);
|
|
2846
|
-
}, [load]);
|
|
2847
|
-
const refetch = useCallback(async () => {
|
|
2848
|
-
taxonomiesCache.delete(cacheKey);
|
|
2849
|
-
await load(true);
|
|
2850
|
-
}, [cacheKey, load]);
|
|
2851
|
-
return { taxonomies, isLoading, error, refetch };
|
|
2852
|
-
}
|
|
2853
|
-
var taxonomyCache = /* @__PURE__ */ new Map();
|
|
2854
|
-
var taxonomyInflight = /* @__PURE__ */ new Map();
|
|
2855
|
-
function buildTaxonomyCacheKey(client, id) {
|
|
2856
|
-
return JSON.stringify({
|
|
2857
|
-
key: client.getPublicKey(),
|
|
2858
|
-
id
|
|
2859
|
-
});
|
|
2654
|
+
return { validate, isValidating, error };
|
|
2860
2655
|
}
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2656
|
+
|
|
2657
|
+
// src/react/hooks/use-bundles.ts
|
|
2658
|
+
var bundlesQuery = createCachedQuery({
|
|
2659
|
+
name: "useBundles",
|
|
2660
|
+
locationSensitive: true,
|
|
2661
|
+
key: (client) => cacheKey(client.getPublicKey(), client.getLocationId()),
|
|
2662
|
+
fetch: async (client) => {
|
|
2663
|
+
const result = await client.catalogue.getBundles();
|
|
2664
|
+
if (!result.ok) throw result.error;
|
|
2665
|
+
return result.value;
|
|
2866
2666
|
}
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
const
|
|
2870
|
-
|
|
2871
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
2872
|
-
const [error, setError] = useState(null);
|
|
2873
|
-
const trackedTaxonomyRef = useRef(null);
|
|
2874
|
-
const load = useCallback(
|
|
2875
|
-
async (force = false) => {
|
|
2876
|
-
if (!enabled) {
|
|
2877
|
-
setIsLoading(false);
|
|
2878
|
-
return;
|
|
2879
|
-
}
|
|
2880
|
-
setError(null);
|
|
2881
|
-
if (!force) {
|
|
2882
|
-
const cachedTaxonomy = taxonomyCache.get(cacheKey);
|
|
2883
|
-
if (cachedTaxonomy) {
|
|
2884
|
-
setTaxonomy(cachedTaxonomy);
|
|
2885
|
-
setIsLoading(false);
|
|
2886
|
-
return;
|
|
2887
|
-
}
|
|
2888
|
-
}
|
|
2889
|
-
setIsLoading(true);
|
|
2890
|
-
try {
|
|
2891
|
-
const existing = taxonomyInflight.get(cacheKey);
|
|
2892
|
-
const promise = existing ?? (async () => {
|
|
2893
|
-
const result = await client.catalogue.getTaxonomy(id);
|
|
2894
|
-
if (!result.ok) {
|
|
2895
|
-
throw result.error;
|
|
2896
|
-
}
|
|
2897
|
-
return result.value;
|
|
2898
|
-
})();
|
|
2899
|
-
if (!existing) {
|
|
2900
|
-
taxonomyInflight.set(
|
|
2901
|
-
cacheKey,
|
|
2902
|
-
promise.finally(() => {
|
|
2903
|
-
taxonomyInflight.delete(cacheKey);
|
|
2904
|
-
})
|
|
2905
|
-
);
|
|
2906
|
-
}
|
|
2907
|
-
const value = await promise;
|
|
2908
|
-
taxonomyCache.set(cacheKey, value);
|
|
2909
|
-
setTaxonomy(value);
|
|
2910
|
-
if (value && trackedTaxonomyRef.current !== value.id) {
|
|
2911
|
-
trackedTaxonomyRef.current = value.id;
|
|
2912
|
-
client.activity.trackCategoryView(value.id, {
|
|
2913
|
-
categoryName: value.name
|
|
2914
|
-
});
|
|
2915
|
-
}
|
|
2916
|
-
} catch (loadError) {
|
|
2917
|
-
setError(loadError);
|
|
2918
|
-
} finally {
|
|
2919
|
-
setIsLoading(false);
|
|
2920
|
-
}
|
|
2921
|
-
},
|
|
2922
|
-
[cacheKey, client, enabled, id]
|
|
2923
|
-
);
|
|
2924
|
-
useEffect(() => {
|
|
2925
|
-
void load(false);
|
|
2926
|
-
}, [load]);
|
|
2927
|
-
const refetch = useCallback(async () => {
|
|
2928
|
-
taxonomyCache.delete(cacheKey);
|
|
2929
|
-
await load(true);
|
|
2930
|
-
}, [cacheKey, load]);
|
|
2931
|
-
return { taxonomy, isLoading, error, refetch };
|
|
2932
|
-
}
|
|
2933
|
-
var taxonomyPathCache = /* @__PURE__ */ new Map();
|
|
2934
|
-
var taxonomyPathInflight = /* @__PURE__ */ new Map();
|
|
2935
|
-
function buildTaxonomyPathCacheKey(client, id) {
|
|
2936
|
-
return JSON.stringify({
|
|
2937
|
-
key: client.getPublicKey(),
|
|
2938
|
-
id
|
|
2939
|
-
});
|
|
2940
|
-
}
|
|
2941
|
-
function useTaxonomyPath(id, options = {}) {
|
|
2942
|
-
const context = useOptionalCimplifyClient();
|
|
2943
|
-
const client = options.client ?? context?.client;
|
|
2944
|
-
if (!client) {
|
|
2945
|
-
throw new Error("useTaxonomyPath must be used within CimplifyProvider or passed { client }.");
|
|
2946
|
-
}
|
|
2947
|
-
const enabled = options.enabled ?? true;
|
|
2948
|
-
const cacheKey = useMemo(() => buildTaxonomyPathCacheKey(client, id), [client, id]);
|
|
2949
|
-
const cached = taxonomyPathCache.get(cacheKey);
|
|
2950
|
-
const [path, setPath] = useState(cached ?? []);
|
|
2951
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
2952
|
-
const [error, setError] = useState(null);
|
|
2953
|
-
const load = useCallback(
|
|
2954
|
-
async (force = false) => {
|
|
2955
|
-
if (!enabled) {
|
|
2956
|
-
setIsLoading(false);
|
|
2957
|
-
return;
|
|
2958
|
-
}
|
|
2959
|
-
setError(null);
|
|
2960
|
-
if (!force) {
|
|
2961
|
-
const cachedPath = taxonomyPathCache.get(cacheKey);
|
|
2962
|
-
if (cachedPath) {
|
|
2963
|
-
setPath(cachedPath);
|
|
2964
|
-
setIsLoading(false);
|
|
2965
|
-
return;
|
|
2966
|
-
}
|
|
2967
|
-
}
|
|
2968
|
-
setIsLoading(true);
|
|
2969
|
-
try {
|
|
2970
|
-
const existing = taxonomyPathInflight.get(cacheKey);
|
|
2971
|
-
const promise = existing ?? (async () => {
|
|
2972
|
-
const result = await client.catalogue.getTaxonomyPath(id);
|
|
2973
|
-
if (!result.ok) {
|
|
2974
|
-
throw result.error;
|
|
2975
|
-
}
|
|
2976
|
-
return result.value;
|
|
2977
|
-
})();
|
|
2978
|
-
if (!existing) {
|
|
2979
|
-
taxonomyPathInflight.set(
|
|
2980
|
-
cacheKey,
|
|
2981
|
-
promise.finally(() => {
|
|
2982
|
-
taxonomyPathInflight.delete(cacheKey);
|
|
2983
|
-
})
|
|
2984
|
-
);
|
|
2985
|
-
}
|
|
2986
|
-
const value = await promise;
|
|
2987
|
-
taxonomyPathCache.set(cacheKey, value);
|
|
2988
|
-
setPath(value);
|
|
2989
|
-
} catch (loadError) {
|
|
2990
|
-
setError(loadError);
|
|
2991
|
-
} finally {
|
|
2992
|
-
setIsLoading(false);
|
|
2993
|
-
}
|
|
2994
|
-
},
|
|
2995
|
-
[cacheKey, client, enabled, id]
|
|
2996
|
-
);
|
|
2997
|
-
useEffect(() => {
|
|
2998
|
-
void load(false);
|
|
2999
|
-
}, [load]);
|
|
3000
|
-
const refetch = useCallback(async () => {
|
|
3001
|
-
taxonomyPathCache.delete(cacheKey);
|
|
3002
|
-
await load(true);
|
|
3003
|
-
}, [cacheKey, load]);
|
|
3004
|
-
return { path, isLoading, error, refetch };
|
|
3005
|
-
}
|
|
3006
|
-
var schedulesCache = /* @__PURE__ */ new Map();
|
|
3007
|
-
var schedulesInflight = /* @__PURE__ */ new Map();
|
|
3008
|
-
function buildSchedulesCacheKey(client, productId) {
|
|
3009
|
-
return JSON.stringify({
|
|
3010
|
-
key: client.getPublicKey(),
|
|
3011
|
-
product_id: productId
|
|
3012
|
-
});
|
|
3013
|
-
}
|
|
3014
|
-
function useProductSchedules(productId, options = {}) {
|
|
3015
|
-
const context = useOptionalCimplifyClient();
|
|
3016
|
-
const client = options.client ?? context?.client;
|
|
3017
|
-
if (!client) {
|
|
3018
|
-
throw new Error("useProductSchedules must be used within CimplifyProvider or passed { client }.");
|
|
3019
|
-
}
|
|
3020
|
-
const enabled = options.enabled ?? true;
|
|
3021
|
-
const cacheKey = useMemo(() => buildSchedulesCacheKey(client, productId), [client, productId]);
|
|
3022
|
-
const cached = schedulesCache.get(cacheKey);
|
|
3023
|
-
const [schedules, setSchedules] = useState(cached ?? []);
|
|
3024
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
3025
|
-
const [error, setError] = useState(null);
|
|
3026
|
-
const load = useCallback(
|
|
3027
|
-
async (force = false) => {
|
|
3028
|
-
if (!enabled) {
|
|
3029
|
-
setIsLoading(false);
|
|
3030
|
-
return;
|
|
3031
|
-
}
|
|
3032
|
-
setError(null);
|
|
3033
|
-
if (!force) {
|
|
3034
|
-
const cachedSchedules = schedulesCache.get(cacheKey);
|
|
3035
|
-
if (cachedSchedules) {
|
|
3036
|
-
setSchedules(cachedSchedules);
|
|
3037
|
-
setIsLoading(false);
|
|
3038
|
-
return;
|
|
3039
|
-
}
|
|
3040
|
-
}
|
|
3041
|
-
setIsLoading(true);
|
|
3042
|
-
try {
|
|
3043
|
-
const existing = schedulesInflight.get(cacheKey);
|
|
3044
|
-
const promise = existing ?? (async () => {
|
|
3045
|
-
const result = await client.catalogue.getProductSchedules(productId);
|
|
3046
|
-
if (!result.ok) {
|
|
3047
|
-
throw result.error;
|
|
3048
|
-
}
|
|
3049
|
-
return result.value;
|
|
3050
|
-
})();
|
|
3051
|
-
if (!existing) {
|
|
3052
|
-
schedulesInflight.set(
|
|
3053
|
-
cacheKey,
|
|
3054
|
-
promise.finally(() => {
|
|
3055
|
-
schedulesInflight.delete(cacheKey);
|
|
3056
|
-
})
|
|
3057
|
-
);
|
|
3058
|
-
}
|
|
3059
|
-
const value = await promise;
|
|
3060
|
-
schedulesCache.set(cacheKey, value);
|
|
3061
|
-
setSchedules(value);
|
|
3062
|
-
} catch (loadError) {
|
|
3063
|
-
setError(loadError);
|
|
3064
|
-
} finally {
|
|
3065
|
-
setIsLoading(false);
|
|
3066
|
-
}
|
|
3067
|
-
},
|
|
3068
|
-
[cacheKey, client, enabled, productId]
|
|
3069
|
-
);
|
|
3070
|
-
useEffect(() => {
|
|
3071
|
-
void load(false);
|
|
3072
|
-
}, [load]);
|
|
3073
|
-
const refetch = useCallback(async () => {
|
|
3074
|
-
schedulesCache.delete(cacheKey);
|
|
3075
|
-
await load(true);
|
|
3076
|
-
}, [cacheKey, load]);
|
|
3077
|
-
return { schedules, isLoading, error, refetch };
|
|
3078
|
-
}
|
|
3079
|
-
var availabilityCache = /* @__PURE__ */ new Map();
|
|
3080
|
-
var availabilityInflight = /* @__PURE__ */ new Map();
|
|
3081
|
-
function buildAvailabilityCacheKey(client, productId, locationId) {
|
|
3082
|
-
return JSON.stringify({
|
|
3083
|
-
key: client.getPublicKey(),
|
|
3084
|
-
product_id: productId,
|
|
3085
|
-
location_id: locationId
|
|
3086
|
-
});
|
|
3087
|
-
}
|
|
3088
|
-
function useProductAvailability(productId, options = {}) {
|
|
3089
|
-
const context = useOptionalCimplifyClient();
|
|
3090
|
-
const client = options.client ?? context?.client;
|
|
3091
|
-
if (!client) {
|
|
3092
|
-
throw new Error("useProductAvailability must be used within CimplifyProvider or passed { client }.");
|
|
3093
|
-
}
|
|
3094
|
-
const enabled = options.enabled ?? true;
|
|
3095
|
-
const locationId = options.locationId ?? client.getLocationId();
|
|
3096
|
-
const previousLocationIdRef = useRef(locationId);
|
|
3097
|
-
const cacheKey = useMemo(
|
|
3098
|
-
() => locationId ? buildAvailabilityCacheKey(client, productId, locationId) : null,
|
|
3099
|
-
[client, productId, locationId]
|
|
3100
|
-
);
|
|
3101
|
-
const cached = cacheKey ? availabilityCache.get(cacheKey) : void 0;
|
|
3102
|
-
const [isAvailable, setIsAvailable] = useState(cached?.is_available ?? null);
|
|
3103
|
-
const [schedulesToday, setSchedulesToday] = useState(
|
|
3104
|
-
cached?.schedules_today ?? []
|
|
3105
|
-
);
|
|
3106
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached && !!locationId);
|
|
3107
|
-
const [error, setError] = useState(null);
|
|
3108
|
-
useEffect(() => {
|
|
3109
|
-
if (previousLocationIdRef.current !== locationId) {
|
|
3110
|
-
availabilityCache.clear();
|
|
3111
|
-
availabilityInflight.clear();
|
|
3112
|
-
previousLocationIdRef.current = locationId;
|
|
3113
|
-
}
|
|
3114
|
-
}, [locationId]);
|
|
3115
|
-
const load = useCallback(
|
|
3116
|
-
async (force = false) => {
|
|
3117
|
-
if (!enabled || !locationId || !cacheKey) {
|
|
3118
|
-
setIsLoading(false);
|
|
3119
|
-
return;
|
|
3120
|
-
}
|
|
3121
|
-
setError(null);
|
|
3122
|
-
if (!force) {
|
|
3123
|
-
const cachedAvailability = availabilityCache.get(cacheKey);
|
|
3124
|
-
if (cachedAvailability) {
|
|
3125
|
-
setIsAvailable(cachedAvailability.is_available);
|
|
3126
|
-
setSchedulesToday(cachedAvailability.schedules_today);
|
|
3127
|
-
setIsLoading(false);
|
|
3128
|
-
return;
|
|
3129
|
-
}
|
|
3130
|
-
}
|
|
3131
|
-
setIsLoading(true);
|
|
3132
|
-
try {
|
|
3133
|
-
const existing = availabilityInflight.get(cacheKey);
|
|
3134
|
-
const promise = existing ?? (async () => {
|
|
3135
|
-
const result = await client.catalogue.checkProductAvailableNow(productId, locationId);
|
|
3136
|
-
if (!result.ok) {
|
|
3137
|
-
throw result.error;
|
|
3138
|
-
}
|
|
3139
|
-
return result.value;
|
|
3140
|
-
})();
|
|
3141
|
-
if (!existing) {
|
|
3142
|
-
availabilityInflight.set(
|
|
3143
|
-
cacheKey,
|
|
3144
|
-
promise.finally(() => {
|
|
3145
|
-
availabilityInflight.delete(cacheKey);
|
|
3146
|
-
})
|
|
3147
|
-
);
|
|
3148
|
-
}
|
|
3149
|
-
const value = await promise;
|
|
3150
|
-
availabilityCache.set(cacheKey, value);
|
|
3151
|
-
setIsAvailable(value.is_available);
|
|
3152
|
-
setSchedulesToday(value.schedules_today);
|
|
3153
|
-
} catch (loadError) {
|
|
3154
|
-
setError(loadError);
|
|
3155
|
-
} finally {
|
|
3156
|
-
setIsLoading(false);
|
|
3157
|
-
}
|
|
3158
|
-
},
|
|
3159
|
-
[cacheKey, client, enabled, locationId, productId]
|
|
3160
|
-
);
|
|
3161
|
-
useEffect(() => {
|
|
3162
|
-
void load(false);
|
|
3163
|
-
}, [load]);
|
|
3164
|
-
const refetch = useCallback(async () => {
|
|
3165
|
-
if (cacheKey) {
|
|
3166
|
-
availabilityCache.delete(cacheKey);
|
|
3167
|
-
}
|
|
3168
|
-
await load(true);
|
|
3169
|
-
}, [cacheKey, load]);
|
|
3170
|
-
return { isAvailable, schedulesToday, isLoading, error, refetch };
|
|
3171
|
-
}
|
|
3172
|
-
var dealsCache = /* @__PURE__ */ new Map();
|
|
3173
|
-
var dealsInflight = /* @__PURE__ */ new Map();
|
|
3174
|
-
function buildDealsCacheKey(client, locationId) {
|
|
3175
|
-
return JSON.stringify({ key: client.getPublicKey(), location_id: locationId });
|
|
3176
|
-
}
|
|
3177
|
-
function useDeals(options = {}) {
|
|
3178
|
-
const context = useOptionalCimplifyClient();
|
|
3179
|
-
const client = options.client ?? context?.client;
|
|
3180
|
-
if (!client) {
|
|
3181
|
-
throw new Error("useDeals must be used within CimplifyProvider or passed { client }.");
|
|
3182
|
-
}
|
|
3183
|
-
const enabled = options.enabled ?? true;
|
|
3184
|
-
const locationId = options.locationId ?? client.getLocationId() ?? void 0;
|
|
3185
|
-
const previousLocationIdRef = useRef(locationId);
|
|
3186
|
-
const cacheKey = useMemo(() => buildDealsCacheKey(client, locationId), [client, locationId]);
|
|
3187
|
-
const cached = dealsCache.get(cacheKey);
|
|
3188
|
-
const [deals, setDeals] = useState(cached ?? []);
|
|
3189
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
3190
|
-
const [error, setError] = useState(null);
|
|
3191
|
-
useEffect(() => {
|
|
3192
|
-
if (previousLocationIdRef.current !== locationId) {
|
|
3193
|
-
dealsCache.clear();
|
|
3194
|
-
dealsInflight.clear();
|
|
3195
|
-
previousLocationIdRef.current = locationId;
|
|
3196
|
-
}
|
|
3197
|
-
}, [locationId]);
|
|
3198
|
-
const load = useCallback(
|
|
3199
|
-
async (force = false) => {
|
|
3200
|
-
if (!enabled) {
|
|
3201
|
-
setIsLoading(false);
|
|
3202
|
-
return;
|
|
3203
|
-
}
|
|
3204
|
-
setError(null);
|
|
3205
|
-
if (!force) {
|
|
3206
|
-
const cachedDeals = dealsCache.get(cacheKey);
|
|
3207
|
-
if (cachedDeals) {
|
|
3208
|
-
setDeals(cachedDeals);
|
|
3209
|
-
setIsLoading(false);
|
|
3210
|
-
return;
|
|
3211
|
-
}
|
|
3212
|
-
}
|
|
3213
|
-
setIsLoading(true);
|
|
3214
|
-
try {
|
|
3215
|
-
const existing = dealsInflight.get(cacheKey);
|
|
3216
|
-
const promise = existing ?? (async () => {
|
|
3217
|
-
const result = await client.catalogue.getDeals(locationId);
|
|
3218
|
-
if (!result.ok) {
|
|
3219
|
-
throw result.error;
|
|
3220
|
-
}
|
|
3221
|
-
return result.value;
|
|
3222
|
-
})();
|
|
3223
|
-
if (!existing) {
|
|
3224
|
-
dealsInflight.set(
|
|
3225
|
-
cacheKey,
|
|
3226
|
-
promise.finally(() => {
|
|
3227
|
-
dealsInflight.delete(cacheKey);
|
|
3228
|
-
})
|
|
3229
|
-
);
|
|
3230
|
-
}
|
|
3231
|
-
const value = await promise;
|
|
3232
|
-
dealsCache.set(cacheKey, value);
|
|
3233
|
-
setDeals(value);
|
|
3234
|
-
} catch (loadError) {
|
|
3235
|
-
setError(loadError);
|
|
3236
|
-
} finally {
|
|
3237
|
-
setIsLoading(false);
|
|
3238
|
-
}
|
|
3239
|
-
},
|
|
3240
|
-
[cacheKey, client, enabled, locationId]
|
|
3241
|
-
);
|
|
3242
|
-
useEffect(() => {
|
|
3243
|
-
void load(false);
|
|
3244
|
-
}, [load]);
|
|
3245
|
-
const refetch = useCallback(async () => {
|
|
3246
|
-
dealsCache.delete(cacheKey);
|
|
3247
|
-
await load(true);
|
|
3248
|
-
}, [cacheKey, load]);
|
|
3249
|
-
return { deals, isLoading, error, refetch };
|
|
3250
|
-
}
|
|
3251
|
-
var onSaleCache = /* @__PURE__ */ new Map();
|
|
3252
|
-
var onSaleInflight = /* @__PURE__ */ new Map();
|
|
3253
|
-
function buildOnSaleCacheKey(client) {
|
|
3254
|
-
return client.getPublicKey() || "__demo__";
|
|
3255
|
-
}
|
|
3256
|
-
function useProductsOnSale(options = {}) {
|
|
3257
|
-
const context = useOptionalCimplifyClient();
|
|
3258
|
-
const client = options.client ?? context?.client;
|
|
3259
|
-
if (!client) {
|
|
3260
|
-
throw new Error("useProductsOnSale must be used within CimplifyProvider or passed { client }.");
|
|
3261
|
-
}
|
|
3262
|
-
const enabled = options.enabled ?? true;
|
|
3263
|
-
const cacheKey = useMemo(() => buildOnSaleCacheKey(client), [client]);
|
|
3264
|
-
const cached = onSaleCache.get(cacheKey);
|
|
3265
|
-
const [products, setProducts] = useState(cached ?? []);
|
|
3266
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
3267
|
-
const [error, setError] = useState(null);
|
|
3268
|
-
const load = useCallback(
|
|
3269
|
-
async (force = false) => {
|
|
3270
|
-
if (!enabled) {
|
|
3271
|
-
setIsLoading(false);
|
|
3272
|
-
return;
|
|
3273
|
-
}
|
|
3274
|
-
setError(null);
|
|
3275
|
-
if (!force) {
|
|
3276
|
-
const cachedProducts = onSaleCache.get(cacheKey);
|
|
3277
|
-
if (cachedProducts) {
|
|
3278
|
-
setProducts(cachedProducts);
|
|
3279
|
-
setIsLoading(false);
|
|
3280
|
-
return;
|
|
3281
|
-
}
|
|
3282
|
-
}
|
|
3283
|
-
setIsLoading(true);
|
|
3284
|
-
try {
|
|
3285
|
-
const existing = onSaleInflight.get(cacheKey);
|
|
3286
|
-
const promise = existing ?? (async () => {
|
|
3287
|
-
const result = await client.catalogue.getProductsOnSale();
|
|
3288
|
-
if (!result.ok) {
|
|
3289
|
-
throw result.error;
|
|
3290
|
-
}
|
|
3291
|
-
return result.value;
|
|
3292
|
-
})();
|
|
3293
|
-
if (!existing) {
|
|
3294
|
-
onSaleInflight.set(
|
|
3295
|
-
cacheKey,
|
|
3296
|
-
promise.finally(() => {
|
|
3297
|
-
onSaleInflight.delete(cacheKey);
|
|
3298
|
-
})
|
|
3299
|
-
);
|
|
3300
|
-
}
|
|
3301
|
-
const value = await promise;
|
|
3302
|
-
onSaleCache.set(cacheKey, value);
|
|
3303
|
-
setProducts(value);
|
|
3304
|
-
} catch (loadError) {
|
|
3305
|
-
setError(loadError);
|
|
3306
|
-
} finally {
|
|
3307
|
-
setIsLoading(false);
|
|
3308
|
-
}
|
|
3309
|
-
},
|
|
3310
|
-
[cacheKey, client, enabled]
|
|
3311
|
-
);
|
|
3312
|
-
useEffect(() => {
|
|
3313
|
-
void load(false);
|
|
3314
|
-
}, [load]);
|
|
3315
|
-
const refetch = useCallback(async () => {
|
|
3316
|
-
onSaleCache.delete(cacheKey);
|
|
3317
|
-
await load(true);
|
|
3318
|
-
}, [cacheKey, load]);
|
|
3319
|
-
return { products, isLoading, error, refetch };
|
|
3320
|
-
}
|
|
3321
|
-
var productDealsCache = /* @__PURE__ */ new Map();
|
|
3322
|
-
var productDealsInflight = /* @__PURE__ */ new Map();
|
|
3323
|
-
function buildProductDealsCacheKey(client, productId) {
|
|
3324
|
-
return JSON.stringify({ key: client.getPublicKey(), product_id: productId });
|
|
3325
|
-
}
|
|
3326
|
-
function useProductDeals(productId, options = {}) {
|
|
3327
|
-
const context = useOptionalCimplifyClient();
|
|
3328
|
-
const client = options.client ?? context?.client;
|
|
3329
|
-
if (!client) {
|
|
3330
|
-
throw new Error("useProductDeals must be used within CimplifyProvider or passed { client }.");
|
|
3331
|
-
}
|
|
3332
|
-
const enabled = options.enabled ?? true;
|
|
3333
|
-
const cacheKey = useMemo(
|
|
3334
|
-
() => buildProductDealsCacheKey(client, productId),
|
|
3335
|
-
[client, productId]
|
|
3336
|
-
);
|
|
3337
|
-
const cached = productDealsCache.get(cacheKey);
|
|
3338
|
-
const [deals, setDeals] = useState(cached ?? []);
|
|
3339
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
3340
|
-
const [error, setError] = useState(null);
|
|
3341
|
-
const load = useCallback(
|
|
3342
|
-
async (force = false) => {
|
|
3343
|
-
if (!enabled) {
|
|
3344
|
-
setIsLoading(false);
|
|
3345
|
-
return;
|
|
3346
|
-
}
|
|
3347
|
-
setError(null);
|
|
3348
|
-
if (!force) {
|
|
3349
|
-
const cachedDeals = productDealsCache.get(cacheKey);
|
|
3350
|
-
if (cachedDeals) {
|
|
3351
|
-
setDeals(cachedDeals);
|
|
3352
|
-
setIsLoading(false);
|
|
3353
|
-
return;
|
|
3354
|
-
}
|
|
3355
|
-
}
|
|
3356
|
-
setIsLoading(true);
|
|
3357
|
-
try {
|
|
3358
|
-
const existing = productDealsInflight.get(cacheKey);
|
|
3359
|
-
const promise = existing ?? (async () => {
|
|
3360
|
-
const result = await client.catalogue.getProductDeals(productId);
|
|
3361
|
-
if (!result.ok) {
|
|
3362
|
-
throw result.error;
|
|
3363
|
-
}
|
|
3364
|
-
return result.value;
|
|
3365
|
-
})();
|
|
3366
|
-
if (!existing) {
|
|
3367
|
-
productDealsInflight.set(
|
|
3368
|
-
cacheKey,
|
|
3369
|
-
promise.finally(() => {
|
|
3370
|
-
productDealsInflight.delete(cacheKey);
|
|
3371
|
-
})
|
|
3372
|
-
);
|
|
3373
|
-
}
|
|
3374
|
-
const value = await promise;
|
|
3375
|
-
productDealsCache.set(cacheKey, value);
|
|
3376
|
-
setDeals(value);
|
|
3377
|
-
} catch (loadError) {
|
|
3378
|
-
setError(loadError);
|
|
3379
|
-
} finally {
|
|
3380
|
-
setIsLoading(false);
|
|
3381
|
-
}
|
|
3382
|
-
},
|
|
3383
|
-
[cacheKey, client, enabled, productId]
|
|
3384
|
-
);
|
|
3385
|
-
useEffect(() => {
|
|
3386
|
-
void load(false);
|
|
3387
|
-
}, [load]);
|
|
3388
|
-
const refetch = useCallback(async () => {
|
|
3389
|
-
productDealsCache.delete(cacheKey);
|
|
3390
|
-
await load(true);
|
|
3391
|
-
}, [cacheKey, load]);
|
|
3392
|
-
return { deals, isLoading, error, refetch };
|
|
3393
|
-
}
|
|
3394
|
-
function useValidateDiscount(options = {}) {
|
|
3395
|
-
const context = useOptionalCimplifyClient();
|
|
3396
|
-
const client = options.client ?? context?.client;
|
|
3397
|
-
if (!client) {
|
|
3398
|
-
throw new Error("useValidateDiscount must be used within CimplifyProvider or passed { client }.");
|
|
3399
|
-
}
|
|
3400
|
-
const [isValidating, setIsValidating] = useState(false);
|
|
3401
|
-
const [error, setError] = useState(null);
|
|
3402
|
-
const validate = useCallback(
|
|
3403
|
-
async (code, orderSubtotal, locationId) => {
|
|
3404
|
-
setError(null);
|
|
3405
|
-
setIsValidating(true);
|
|
3406
|
-
try {
|
|
3407
|
-
const result = await client.catalogue.validateDiscountCode(code, orderSubtotal, locationId);
|
|
3408
|
-
if (!result.ok) {
|
|
3409
|
-
setError(result.error);
|
|
3410
|
-
return null;
|
|
3411
|
-
}
|
|
3412
|
-
return result.value;
|
|
3413
|
-
} catch (validateError) {
|
|
3414
|
-
setError(validateError);
|
|
3415
|
-
return null;
|
|
3416
|
-
} finally {
|
|
3417
|
-
setIsValidating(false);
|
|
3418
|
-
}
|
|
3419
|
-
},
|
|
3420
|
-
[client]
|
|
3421
|
-
);
|
|
3422
|
-
return { validate, isValidating, error };
|
|
3423
|
-
}
|
|
3424
|
-
var bundlesCache = /* @__PURE__ */ new Map();
|
|
3425
|
-
var bundlesInflight = /* @__PURE__ */ new Map();
|
|
3426
|
-
function buildBundlesCacheKey(client, locationId) {
|
|
3427
|
-
return JSON.stringify({
|
|
3428
|
-
key: client.getPublicKey(),
|
|
3429
|
-
location_id: locationId || "__none__"
|
|
3430
|
-
});
|
|
3431
|
-
}
|
|
3432
|
-
function useBundles(options = {}) {
|
|
3433
|
-
const context = useOptionalCimplifyClient();
|
|
3434
|
-
const client = options.client ?? context?.client;
|
|
3435
|
-
if (!client) {
|
|
3436
|
-
throw new Error("useBundles must be used within CimplifyProvider or passed { client }.");
|
|
3437
|
-
}
|
|
3438
|
-
const enabled = options.enabled ?? true;
|
|
3439
|
-
const locationId = client.getLocationId();
|
|
3440
|
-
const previousLocationIdRef = useRef(locationId);
|
|
3441
|
-
const requestIdRef = useRef(0);
|
|
3442
|
-
const cacheKey = useMemo(
|
|
3443
|
-
() => buildBundlesCacheKey(client, locationId),
|
|
3444
|
-
[client, locationId]
|
|
3445
|
-
);
|
|
3446
|
-
const cached = bundlesCache.get(cacheKey);
|
|
3447
|
-
const [bundles, setBundles] = useState(cached?.bundles ?? []);
|
|
3448
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
3449
|
-
const [error, setError] = useState(null);
|
|
3450
|
-
useEffect(() => {
|
|
3451
|
-
if (previousLocationIdRef.current !== locationId) {
|
|
3452
|
-
bundlesCache.clear();
|
|
3453
|
-
bundlesInflight.clear();
|
|
3454
|
-
previousLocationIdRef.current = locationId;
|
|
3455
|
-
}
|
|
3456
|
-
}, [locationId]);
|
|
3457
|
-
const load = useCallback(
|
|
3458
|
-
async (force = false) => {
|
|
3459
|
-
if (!enabled) {
|
|
3460
|
-
setIsLoading(false);
|
|
3461
|
-
return;
|
|
3462
|
-
}
|
|
3463
|
-
const nextRequestId = ++requestIdRef.current;
|
|
3464
|
-
setError(null);
|
|
3465
|
-
if (!force) {
|
|
3466
|
-
const cacheEntry = bundlesCache.get(cacheKey);
|
|
3467
|
-
if (cacheEntry) {
|
|
3468
|
-
setBundles(cacheEntry.bundles);
|
|
3469
|
-
setIsLoading(false);
|
|
3470
|
-
return;
|
|
3471
|
-
}
|
|
3472
|
-
}
|
|
3473
|
-
setIsLoading(true);
|
|
3474
|
-
try {
|
|
3475
|
-
const existing = bundlesInflight.get(cacheKey);
|
|
3476
|
-
const promise = existing ?? (async () => {
|
|
3477
|
-
const result = await client.catalogue.getBundles();
|
|
3478
|
-
if (!result.ok) {
|
|
3479
|
-
throw result.error;
|
|
3480
|
-
}
|
|
3481
|
-
return result.value;
|
|
3482
|
-
})();
|
|
3483
|
-
if (!existing) {
|
|
3484
|
-
bundlesInflight.set(cacheKey, promise);
|
|
3485
|
-
promise.finally(() => {
|
|
3486
|
-
bundlesInflight.delete(cacheKey);
|
|
3487
|
-
}).catch(() => void 0);
|
|
3488
|
-
}
|
|
3489
|
-
const value = await promise;
|
|
3490
|
-
bundlesCache.set(cacheKey, { bundles: value });
|
|
3491
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3492
|
-
setBundles(value);
|
|
3493
|
-
setError(null);
|
|
3494
|
-
}
|
|
3495
|
-
} catch (loadError) {
|
|
3496
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3497
|
-
setError(loadError);
|
|
3498
|
-
}
|
|
3499
|
-
} finally {
|
|
3500
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3501
|
-
setIsLoading(false);
|
|
3502
|
-
}
|
|
3503
|
-
}
|
|
3504
|
-
},
|
|
3505
|
-
[cacheKey, client, enabled]
|
|
3506
|
-
);
|
|
3507
|
-
useEffect(() => {
|
|
3508
|
-
void load(false);
|
|
3509
|
-
}, [load]);
|
|
3510
|
-
const refetch = useCallback(async () => {
|
|
3511
|
-
bundlesCache.delete(cacheKey);
|
|
3512
|
-
await load(true);
|
|
3513
|
-
}, [cacheKey, load]);
|
|
3514
|
-
return { bundles, isLoading, error, refetch };
|
|
3515
|
-
}
|
|
3516
|
-
function useProductPrice(input) {
|
|
3517
|
-
const {
|
|
3518
|
-
product,
|
|
3519
|
-
quantity = 1,
|
|
3520
|
-
variant,
|
|
3521
|
-
addOnOptions,
|
|
3522
|
-
compositePrice,
|
|
3523
|
-
bundleTotalPrice
|
|
3524
|
-
} = input;
|
|
3525
|
-
return useMemo(() => {
|
|
3526
|
-
let unitPrice;
|
|
3527
|
-
if (bundleTotalPrice != null) {
|
|
3528
|
-
unitPrice = bundleTotalPrice;
|
|
3529
|
-
} else if (compositePrice) {
|
|
3530
|
-
unitPrice = parsePrice(compositePrice.final_price);
|
|
3531
|
-
} else {
|
|
3532
|
-
unitPrice = parsePrice(product.default_price);
|
|
3533
|
-
if (variant?.price_adjustment) {
|
|
3534
|
-
unitPrice += parsePrice(variant.price_adjustment);
|
|
3535
|
-
}
|
|
3536
|
-
if (addOnOptions) {
|
|
3537
|
-
for (const option of addOnOptions) {
|
|
3538
|
-
if (option.default_price) {
|
|
3539
|
-
unitPrice += parsePrice(option.default_price);
|
|
3540
|
-
}
|
|
3541
|
-
}
|
|
3542
|
-
}
|
|
3543
|
-
}
|
|
3544
|
-
unitPrice = Math.round(unitPrice * 100) / 100;
|
|
3545
|
-
const totalPrice = Math.round(unitPrice * quantity * 100) / 100;
|
|
3546
|
-
return {
|
|
3547
|
-
unitPrice,
|
|
3548
|
-
totalPrice,
|
|
3549
|
-
displayTotalPrice: totalPrice
|
|
3550
|
-
};
|
|
3551
|
-
}, [product.default_price, quantity, variant?.price_adjustment, addOnOptions, compositePrice, bundleTotalPrice]);
|
|
3552
|
-
}
|
|
3553
|
-
var ordersCache = /* @__PURE__ */ new Map();
|
|
3554
|
-
var ordersInflight = /* @__PURE__ */ new Map();
|
|
3555
|
-
function buildOrdersCacheKey(client, status, limit) {
|
|
3556
|
-
return JSON.stringify({ key: client.getPublicKey(), status, limit });
|
|
3557
|
-
}
|
|
3558
|
-
function useOrders(options = {}) {
|
|
3559
|
-
const context = useOptionalCimplifyClient();
|
|
3560
|
-
const client = options.client ?? context?.client;
|
|
3561
|
-
if (!client) {
|
|
3562
|
-
throw new Error("useOrders must be used within CimplifyProvider or passed { client }.");
|
|
3563
|
-
}
|
|
3564
|
-
const enabled = options.enabled ?? true;
|
|
3565
|
-
const requestIdRef = useRef(0);
|
|
3566
|
-
const cacheKey = useMemo(
|
|
3567
|
-
() => buildOrdersCacheKey(client, options.status, options.limit),
|
|
3568
|
-
[client, options.status, options.limit]
|
|
3569
|
-
);
|
|
3570
|
-
const cached = ordersCache.get(cacheKey);
|
|
3571
|
-
const [orders, setOrders] = useState(cached ?? []);
|
|
3572
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
3573
|
-
const [error, setError] = useState(null);
|
|
3574
|
-
const load = useCallback(
|
|
3575
|
-
async (force = false) => {
|
|
3576
|
-
if (!enabled) {
|
|
3577
|
-
setIsLoading(false);
|
|
3578
|
-
return;
|
|
3579
|
-
}
|
|
3580
|
-
const nextRequestId = ++requestIdRef.current;
|
|
3581
|
-
setError(null);
|
|
3582
|
-
if (!force) {
|
|
3583
|
-
const cachedOrders = ordersCache.get(cacheKey);
|
|
3584
|
-
if (cachedOrders) {
|
|
3585
|
-
setOrders(cachedOrders);
|
|
3586
|
-
setIsLoading(false);
|
|
3587
|
-
return;
|
|
3588
|
-
}
|
|
3589
|
-
}
|
|
3590
|
-
setIsLoading(true);
|
|
3591
|
-
try {
|
|
3592
|
-
const existing = ordersInflight.get(cacheKey);
|
|
3593
|
-
const promise = existing ?? (async () => {
|
|
3594
|
-
const result = await client.orders.list({
|
|
3595
|
-
status: options.status,
|
|
3596
|
-
limit: options.limit
|
|
3597
|
-
});
|
|
3598
|
-
if (!result.ok) {
|
|
3599
|
-
throw result.error;
|
|
3600
|
-
}
|
|
3601
|
-
return result.value;
|
|
3602
|
-
})();
|
|
3603
|
-
if (!existing) {
|
|
3604
|
-
ordersInflight.set(
|
|
3605
|
-
cacheKey,
|
|
3606
|
-
promise.finally(() => {
|
|
3607
|
-
ordersInflight.delete(cacheKey);
|
|
3608
|
-
})
|
|
3609
|
-
);
|
|
3610
|
-
}
|
|
3611
|
-
const value = await promise;
|
|
3612
|
-
ordersCache.set(cacheKey, value);
|
|
3613
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3614
|
-
setOrders(value);
|
|
3615
|
-
setError(null);
|
|
3616
|
-
}
|
|
3617
|
-
} catch (loadError) {
|
|
3618
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3619
|
-
setError(loadError);
|
|
3620
|
-
}
|
|
3621
|
-
} finally {
|
|
3622
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3623
|
-
setIsLoading(false);
|
|
3624
|
-
}
|
|
3625
|
-
}
|
|
3626
|
-
},
|
|
3627
|
-
[cacheKey, client, enabled, options.status, options.limit]
|
|
3628
|
-
);
|
|
3629
|
-
useEffect(() => {
|
|
3630
|
-
void load(false);
|
|
3631
|
-
}, [load]);
|
|
3632
|
-
const refetch = useCallback(async () => {
|
|
3633
|
-
ordersCache.delete(cacheKey);
|
|
3634
|
-
await load(true);
|
|
3635
|
-
}, [cacheKey, load]);
|
|
3636
|
-
return { orders, isLoading, error, refetch };
|
|
3637
|
-
}
|
|
3638
|
-
var servicesCache = /* @__PURE__ */ new Map();
|
|
3639
|
-
var servicesInflight = /* @__PURE__ */ new Map();
|
|
3640
|
-
function buildServicesCacheKey(client) {
|
|
3641
|
-
return JSON.stringify({ key: client.getPublicKey() });
|
|
3642
|
-
}
|
|
3643
|
-
function useServices(options = {}) {
|
|
3644
|
-
const context = useOptionalCimplifyClient();
|
|
3645
|
-
const client = options.client ?? context?.client;
|
|
3646
|
-
if (!client) {
|
|
3647
|
-
throw new Error("useServices must be used within CimplifyProvider or passed { client }.");
|
|
3648
|
-
}
|
|
3649
|
-
const enabled = options.enabled ?? true;
|
|
3650
|
-
const requestIdRef = useRef(0);
|
|
3651
|
-
const cacheKey = useMemo(() => buildServicesCacheKey(client), [client]);
|
|
3652
|
-
const cached = servicesCache.get(cacheKey);
|
|
3653
|
-
const [services, setServices] = useState(cached ?? []);
|
|
3654
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
3655
|
-
const [error, setError] = useState(null);
|
|
3656
|
-
const load = useCallback(
|
|
3657
|
-
async (force = false) => {
|
|
3658
|
-
if (!enabled) {
|
|
3659
|
-
setIsLoading(false);
|
|
3660
|
-
return;
|
|
3661
|
-
}
|
|
3662
|
-
const nextRequestId = ++requestIdRef.current;
|
|
3663
|
-
setError(null);
|
|
3664
|
-
if (!force) {
|
|
3665
|
-
const cachedServices = servicesCache.get(cacheKey);
|
|
3666
|
-
if (cachedServices) {
|
|
3667
|
-
setServices(cachedServices);
|
|
3668
|
-
setIsLoading(false);
|
|
3669
|
-
return;
|
|
3670
|
-
}
|
|
3671
|
-
}
|
|
3672
|
-
setIsLoading(true);
|
|
3673
|
-
try {
|
|
3674
|
-
const existing = servicesInflight.get(cacheKey);
|
|
3675
|
-
const promise = existing ?? (async () => {
|
|
3676
|
-
const result = await client.scheduling.getServices();
|
|
3677
|
-
if (!result.ok) {
|
|
3678
|
-
throw result.error;
|
|
3679
|
-
}
|
|
3680
|
-
return result.value;
|
|
3681
|
-
})();
|
|
3682
|
-
if (!existing) {
|
|
3683
|
-
servicesInflight.set(
|
|
3684
|
-
cacheKey,
|
|
3685
|
-
promise.finally(() => {
|
|
3686
|
-
servicesInflight.delete(cacheKey);
|
|
3687
|
-
})
|
|
3688
|
-
);
|
|
3689
|
-
}
|
|
3690
|
-
const value = await promise;
|
|
3691
|
-
servicesCache.set(cacheKey, value);
|
|
3692
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3693
|
-
setServices(value);
|
|
3694
|
-
setError(null);
|
|
3695
|
-
}
|
|
3696
|
-
} catch (loadError) {
|
|
3697
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3698
|
-
setError(loadError);
|
|
3699
|
-
}
|
|
3700
|
-
} finally {
|
|
3701
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3702
|
-
setIsLoading(false);
|
|
3703
|
-
}
|
|
3704
|
-
}
|
|
3705
|
-
},
|
|
3706
|
-
[cacheKey, client, enabled]
|
|
3707
|
-
);
|
|
3708
|
-
useEffect(() => {
|
|
3709
|
-
void load(false);
|
|
3710
|
-
}, [load]);
|
|
3711
|
-
const refetch = useCallback(async () => {
|
|
3712
|
-
servicesCache.delete(cacheKey);
|
|
3713
|
-
await load(true);
|
|
3714
|
-
}, [cacheKey, load]);
|
|
3715
|
-
return { services, isLoading, error, refetch };
|
|
3716
|
-
}
|
|
3717
|
-
var slotsCache = /* @__PURE__ */ new Map();
|
|
3718
|
-
var slotsInflight = /* @__PURE__ */ new Map();
|
|
3719
|
-
function buildSlotsCacheKey(client, serviceId, date, participantCount) {
|
|
3720
|
-
return JSON.stringify({
|
|
3721
|
-
key: client.getPublicKey(),
|
|
3722
|
-
serviceId,
|
|
3723
|
-
date,
|
|
3724
|
-
participantCount
|
|
3725
|
-
});
|
|
3726
|
-
}
|
|
3727
|
-
function useAvailableSlots(serviceId, date, options = {}) {
|
|
3728
|
-
const context = useOptionalCimplifyClient();
|
|
3729
|
-
const client = options.client ?? context?.client;
|
|
3730
|
-
if (!client) {
|
|
3731
|
-
throw new Error("useAvailableSlots must be used within CimplifyProvider or passed { client }.");
|
|
3732
|
-
}
|
|
3733
|
-
const enabled = (options.enabled ?? true) && !!serviceId && !!date;
|
|
3734
|
-
const requestIdRef = useRef(0);
|
|
3735
|
-
const cacheKey = useMemo(
|
|
3736
|
-
() => serviceId && date ? buildSlotsCacheKey(client, serviceId, date, options.participantCount) : null,
|
|
3737
|
-
[client, serviceId, date, options.participantCount]
|
|
3738
|
-
);
|
|
3739
|
-
const cached = cacheKey ? slotsCache.get(cacheKey) : void 0;
|
|
3740
|
-
const [slots, setSlots] = useState(cached ?? []);
|
|
3741
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
3742
|
-
const [error, setError] = useState(null);
|
|
3743
|
-
const load = useCallback(
|
|
3744
|
-
async (force = false) => {
|
|
3745
|
-
if (!enabled || !cacheKey || !serviceId || !date) {
|
|
3746
|
-
setIsLoading(false);
|
|
3747
|
-
return;
|
|
3748
|
-
}
|
|
3749
|
-
const nextRequestId = ++requestIdRef.current;
|
|
3750
|
-
setError(null);
|
|
3751
|
-
if (!force) {
|
|
3752
|
-
const cachedSlots = slotsCache.get(cacheKey);
|
|
3753
|
-
if (cachedSlots) {
|
|
3754
|
-
setSlots(cachedSlots);
|
|
3755
|
-
setIsLoading(false);
|
|
3756
|
-
return;
|
|
3757
|
-
}
|
|
3758
|
-
}
|
|
3759
|
-
setIsLoading(true);
|
|
3760
|
-
try {
|
|
3761
|
-
const existing = slotsInflight.get(cacheKey);
|
|
3762
|
-
const promise = existing ?? (async () => {
|
|
3763
|
-
const result = await client.scheduling.getAvailableSlots({
|
|
3764
|
-
service_id: serviceId,
|
|
3765
|
-
date,
|
|
3766
|
-
participant_count: options.participantCount
|
|
3767
|
-
});
|
|
3768
|
-
if (!result.ok) {
|
|
3769
|
-
throw result.error;
|
|
3770
|
-
}
|
|
3771
|
-
return result.value;
|
|
3772
|
-
})();
|
|
3773
|
-
if (!existing) {
|
|
3774
|
-
slotsInflight.set(
|
|
3775
|
-
cacheKey,
|
|
3776
|
-
promise.finally(() => {
|
|
3777
|
-
slotsInflight.delete(cacheKey);
|
|
3778
|
-
})
|
|
3779
|
-
);
|
|
3780
|
-
}
|
|
3781
|
-
const value = await promise;
|
|
3782
|
-
slotsCache.set(cacheKey, value);
|
|
3783
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3784
|
-
setSlots(value);
|
|
3785
|
-
setError(null);
|
|
3786
|
-
}
|
|
3787
|
-
} catch (loadError) {
|
|
3788
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3789
|
-
setError(loadError);
|
|
3790
|
-
}
|
|
3791
|
-
} finally {
|
|
3792
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3793
|
-
setIsLoading(false);
|
|
3794
|
-
}
|
|
3795
|
-
}
|
|
3796
|
-
},
|
|
3797
|
-
[cacheKey, client, enabled, serviceId, date, options.participantCount]
|
|
3798
|
-
);
|
|
3799
|
-
useEffect(() => {
|
|
3800
|
-
void load(false);
|
|
3801
|
-
}, [load]);
|
|
3802
|
-
const refetch = useCallback(async () => {
|
|
3803
|
-
if (cacheKey) {
|
|
3804
|
-
slotsCache.delete(cacheKey);
|
|
3805
|
-
}
|
|
3806
|
-
await load(true);
|
|
3807
|
-
}, [cacheKey, load]);
|
|
3808
|
-
return { slots, isLoading, error, refetch };
|
|
3809
|
-
}
|
|
3810
|
-
var availabilityCache2 = /* @__PURE__ */ new Map();
|
|
3811
|
-
var availabilityInflight2 = /* @__PURE__ */ new Map();
|
|
3812
|
-
function buildAvailabilityCacheKey2(client, serviceId, startDate, endDate, participantCount) {
|
|
3813
|
-
return JSON.stringify({
|
|
3814
|
-
key: client.getPublicKey(),
|
|
3815
|
-
serviceId,
|
|
3816
|
-
startDate,
|
|
3817
|
-
endDate,
|
|
3818
|
-
participantCount
|
|
3819
|
-
});
|
|
3820
|
-
}
|
|
3821
|
-
function useServiceAvailability(serviceId, startDate, endDate, options = {}) {
|
|
3822
|
-
const context = useOptionalCimplifyClient();
|
|
3823
|
-
const client = options.client ?? context?.client;
|
|
3824
|
-
if (!client) {
|
|
3825
|
-
throw new Error(
|
|
3826
|
-
"useServiceAvailability must be used within CimplifyProvider or passed { client }."
|
|
3827
|
-
);
|
|
3828
|
-
}
|
|
3829
|
-
const enabled = (options.enabled ?? true) && !!serviceId && !!startDate && !!endDate;
|
|
3830
|
-
const requestIdRef = useRef(0);
|
|
3831
|
-
const cacheKey = useMemo(
|
|
3832
|
-
() => serviceId && startDate && endDate ? buildAvailabilityCacheKey2(
|
|
3833
|
-
client,
|
|
3834
|
-
serviceId,
|
|
3835
|
-
startDate,
|
|
3836
|
-
endDate,
|
|
3837
|
-
options.participantCount
|
|
3838
|
-
) : null,
|
|
3839
|
-
[client, serviceId, startDate, endDate, options.participantCount]
|
|
3840
|
-
);
|
|
3841
|
-
const cached = cacheKey ? availabilityCache2.get(cacheKey) : void 0;
|
|
3842
|
-
const [days, setDays] = useState(cached ?? []);
|
|
3843
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
3844
|
-
const [error, setError] = useState(null);
|
|
3845
|
-
const load = useCallback(
|
|
3846
|
-
async (force = false) => {
|
|
3847
|
-
if (!enabled || !cacheKey || !serviceId || !startDate || !endDate) {
|
|
3848
|
-
setIsLoading(false);
|
|
3849
|
-
return;
|
|
3850
|
-
}
|
|
3851
|
-
const nextRequestId = ++requestIdRef.current;
|
|
3852
|
-
setError(null);
|
|
3853
|
-
if (!force) {
|
|
3854
|
-
const cachedDays = availabilityCache2.get(cacheKey);
|
|
3855
|
-
if (cachedDays) {
|
|
3856
|
-
setDays(cachedDays);
|
|
3857
|
-
setIsLoading(false);
|
|
3858
|
-
return;
|
|
3859
|
-
}
|
|
3860
|
-
}
|
|
3861
|
-
setIsLoading(true);
|
|
3862
|
-
try {
|
|
3863
|
-
const existing = availabilityInflight2.get(cacheKey);
|
|
3864
|
-
const promise = existing ?? (async () => {
|
|
3865
|
-
const result = await client.scheduling.getServiceAvailability({
|
|
3866
|
-
service_id: serviceId,
|
|
3867
|
-
start_date: startDate,
|
|
3868
|
-
end_date: endDate,
|
|
3869
|
-
location_id: options.locationId,
|
|
3870
|
-
participant_count: options.participantCount
|
|
3871
|
-
});
|
|
3872
|
-
if (!result.ok) {
|
|
3873
|
-
throw result.error;
|
|
3874
|
-
}
|
|
3875
|
-
return result.value.availability;
|
|
3876
|
-
})();
|
|
3877
|
-
if (!existing) {
|
|
3878
|
-
availabilityInflight2.set(
|
|
3879
|
-
cacheKey,
|
|
3880
|
-
promise.finally(() => {
|
|
3881
|
-
availabilityInflight2.delete(cacheKey);
|
|
3882
|
-
})
|
|
3883
|
-
);
|
|
3884
|
-
}
|
|
3885
|
-
const value = await promise;
|
|
3886
|
-
availabilityCache2.set(cacheKey, value);
|
|
3887
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3888
|
-
setDays(value);
|
|
3889
|
-
setError(null);
|
|
3890
|
-
}
|
|
3891
|
-
} catch (loadError) {
|
|
3892
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3893
|
-
setError(loadError);
|
|
3894
|
-
}
|
|
3895
|
-
} finally {
|
|
3896
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3897
|
-
setIsLoading(false);
|
|
3898
|
-
}
|
|
3899
|
-
}
|
|
3900
|
-
},
|
|
3901
|
-
[cacheKey, client, enabled, serviceId, startDate, endDate, options.locationId, options.participantCount]
|
|
3902
|
-
);
|
|
3903
|
-
useEffect(() => {
|
|
3904
|
-
void load(false);
|
|
3905
|
-
}, [load]);
|
|
3906
|
-
const refetch = useCallback(async () => {
|
|
3907
|
-
if (cacheKey) {
|
|
3908
|
-
availabilityCache2.delete(cacheKey);
|
|
3909
|
-
}
|
|
3910
|
-
await load(true);
|
|
3911
|
-
}, [cacheKey, load]);
|
|
3912
|
-
return { days, isLoading, error, refetch };
|
|
3913
|
-
}
|
|
3914
|
-
var bookingsCache = /* @__PURE__ */ new Map();
|
|
3915
|
-
var bookingsInflight = /* @__PURE__ */ new Map();
|
|
3916
|
-
function buildBookingsCacheKey(client, filter) {
|
|
3917
|
-
return JSON.stringify({ key: client.getPublicKey(), filter });
|
|
3918
|
-
}
|
|
3919
|
-
function useBookings(options = {}) {
|
|
3920
|
-
const context = useOptionalCimplifyClient();
|
|
3921
|
-
const client = options.client ?? context?.client;
|
|
3922
|
-
if (!client) {
|
|
3923
|
-
throw new Error("useBookings must be used within CimplifyProvider or passed { client }.");
|
|
3924
|
-
}
|
|
3925
|
-
const filter = options.filter ?? "all";
|
|
3926
|
-
const enabled = options.enabled ?? true;
|
|
3927
|
-
const requestIdRef = useRef(0);
|
|
3928
|
-
const cacheKey = useMemo(
|
|
3929
|
-
() => buildBookingsCacheKey(client, filter),
|
|
3930
|
-
[client, filter]
|
|
3931
|
-
);
|
|
3932
|
-
const cached = bookingsCache.get(cacheKey);
|
|
3933
|
-
const [bookings, setBookings] = useState(cached ?? []);
|
|
3934
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
3935
|
-
const [error, setError] = useState(null);
|
|
3936
|
-
const load = useCallback(
|
|
3937
|
-
async (force = false) => {
|
|
3938
|
-
if (!enabled) {
|
|
3939
|
-
setIsLoading(false);
|
|
3940
|
-
return;
|
|
3941
|
-
}
|
|
3942
|
-
const nextRequestId = ++requestIdRef.current;
|
|
3943
|
-
setError(null);
|
|
3944
|
-
if (!force) {
|
|
3945
|
-
const cachedBookings = bookingsCache.get(cacheKey);
|
|
3946
|
-
if (cachedBookings) {
|
|
3947
|
-
setBookings(cachedBookings);
|
|
3948
|
-
setIsLoading(false);
|
|
3949
|
-
return;
|
|
3950
|
-
}
|
|
3951
|
-
}
|
|
3952
|
-
setIsLoading(true);
|
|
3953
|
-
try {
|
|
3954
|
-
const existing = bookingsInflight.get(cacheKey);
|
|
3955
|
-
const promise = existing ?? (async () => {
|
|
3956
|
-
let result;
|
|
3957
|
-
switch (filter) {
|
|
3958
|
-
case "upcoming":
|
|
3959
|
-
result = await client.scheduling.getUpcomingBookings();
|
|
3960
|
-
break;
|
|
3961
|
-
case "past":
|
|
3962
|
-
result = await client.scheduling.getPastBookings();
|
|
3963
|
-
break;
|
|
3964
|
-
default:
|
|
3965
|
-
result = await client.scheduling.getCustomerBookings();
|
|
3966
|
-
break;
|
|
3967
|
-
}
|
|
3968
|
-
if (!result.ok) {
|
|
3969
|
-
throw result.error;
|
|
3970
|
-
}
|
|
3971
|
-
return result.value;
|
|
3972
|
-
})();
|
|
3973
|
-
if (!existing) {
|
|
3974
|
-
bookingsInflight.set(
|
|
3975
|
-
cacheKey,
|
|
3976
|
-
promise.finally(() => {
|
|
3977
|
-
bookingsInflight.delete(cacheKey);
|
|
3978
|
-
})
|
|
3979
|
-
);
|
|
3980
|
-
}
|
|
3981
|
-
const value = await promise;
|
|
3982
|
-
bookingsCache.set(cacheKey, value);
|
|
3983
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3984
|
-
setBookings(value);
|
|
3985
|
-
setError(null);
|
|
3986
|
-
}
|
|
3987
|
-
} catch (loadError) {
|
|
3988
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3989
|
-
setError(loadError);
|
|
3990
|
-
}
|
|
3991
|
-
} finally {
|
|
3992
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3993
|
-
setIsLoading(false);
|
|
3994
|
-
}
|
|
3995
|
-
}
|
|
3996
|
-
},
|
|
3997
|
-
[cacheKey, client, enabled, filter]
|
|
3998
|
-
);
|
|
3999
|
-
useEffect(() => {
|
|
4000
|
-
void load(false);
|
|
4001
|
-
}, [load]);
|
|
4002
|
-
const refetch = useCallback(async () => {
|
|
4003
|
-
bookingsCache.delete(cacheKey);
|
|
4004
|
-
await load(true);
|
|
4005
|
-
}, [cacheKey, load]);
|
|
4006
|
-
const cancelBooking = useCallback(
|
|
4007
|
-
async (bookingId, reason) => {
|
|
4008
|
-
const result = await client.scheduling.cancelBooking({
|
|
4009
|
-
booking_id: bookingId,
|
|
4010
|
-
reason
|
|
4011
|
-
});
|
|
4012
|
-
if (!result.ok) {
|
|
4013
|
-
throw result.error;
|
|
4014
|
-
}
|
|
4015
|
-
for (const key of bookingsCache.keys()) {
|
|
4016
|
-
bookingsCache.delete(key);
|
|
4017
|
-
}
|
|
4018
|
-
await load(true);
|
|
4019
|
-
return result.value;
|
|
4020
|
-
},
|
|
4021
|
-
[client, load]
|
|
4022
|
-
);
|
|
4023
|
-
return { bookings, isLoading, error, refetch, cancelBooking };
|
|
4024
|
-
}
|
|
4025
|
-
var definitionsCache = /* @__PURE__ */ new Map();
|
|
4026
|
-
var definitionsInflight = /* @__PURE__ */ new Map();
|
|
4027
|
-
function buildCacheKey(client, namespace) {
|
|
4028
|
-
return `attr_defs_${client.getPublicKey() || "__demo__"}${namespace ? `_${namespace}` : ""}`;
|
|
4029
|
-
}
|
|
4030
|
-
function useAttributeDefinitions(options = {}) {
|
|
4031
|
-
const context = useOptionalCimplifyClient();
|
|
4032
|
-
const client = options.client ?? context?.client;
|
|
4033
|
-
if (!client) {
|
|
4034
|
-
throw new Error(
|
|
4035
|
-
"useAttributeDefinitions must be used within CimplifyProvider or passed { client }."
|
|
4036
|
-
);
|
|
4037
|
-
}
|
|
4038
|
-
const enabled = options.enabled ?? true;
|
|
4039
|
-
const namespace = options.namespace;
|
|
4040
|
-
const cacheKey = useMemo(() => buildCacheKey(client, namespace), [client, namespace]);
|
|
4041
|
-
const cached = definitionsCache.get(cacheKey);
|
|
4042
|
-
const [definitions, setDefinitions] = useState(cached ?? []);
|
|
4043
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
4044
|
-
const [error, setError] = useState(null);
|
|
4045
|
-
const load = useCallback(
|
|
4046
|
-
async (force = false) => {
|
|
4047
|
-
if (!enabled) {
|
|
4048
|
-
setIsLoading(false);
|
|
4049
|
-
return;
|
|
4050
|
-
}
|
|
4051
|
-
setError(null);
|
|
4052
|
-
if (!force) {
|
|
4053
|
-
const cachedDefs = definitionsCache.get(cacheKey);
|
|
4054
|
-
if (cachedDefs) {
|
|
4055
|
-
setDefinitions(cachedDefs);
|
|
4056
|
-
setIsLoading(false);
|
|
4057
|
-
return;
|
|
4058
|
-
}
|
|
4059
|
-
}
|
|
4060
|
-
setIsLoading(true);
|
|
4061
|
-
try {
|
|
4062
|
-
const existing = definitionsInflight.get(cacheKey);
|
|
4063
|
-
const promise = existing ?? (async () => {
|
|
4064
|
-
const result = await client.catalogue.getAttributeDefinitions(namespace);
|
|
4065
|
-
if (!result.ok) {
|
|
4066
|
-
throw result.error;
|
|
4067
|
-
}
|
|
4068
|
-
return result.value;
|
|
4069
|
-
})();
|
|
4070
|
-
if (!existing) {
|
|
4071
|
-
definitionsInflight.set(
|
|
4072
|
-
cacheKey,
|
|
4073
|
-
promise.finally(() => {
|
|
4074
|
-
definitionsInflight.delete(cacheKey);
|
|
4075
|
-
})
|
|
4076
|
-
);
|
|
4077
|
-
}
|
|
4078
|
-
const value = await promise;
|
|
4079
|
-
definitionsCache.set(cacheKey, value);
|
|
4080
|
-
setDefinitions(value);
|
|
4081
|
-
} catch (loadError) {
|
|
4082
|
-
setError(loadError);
|
|
4083
|
-
} finally {
|
|
4084
|
-
setIsLoading(false);
|
|
4085
|
-
}
|
|
4086
|
-
},
|
|
4087
|
-
[cacheKey, client, enabled]
|
|
4088
|
-
);
|
|
4089
|
-
useEffect(() => {
|
|
4090
|
-
void load(false);
|
|
4091
|
-
}, [load]);
|
|
4092
|
-
const refetch = useCallback(async () => {
|
|
4093
|
-
definitionsCache.delete(cacheKey);
|
|
4094
|
-
await load(true);
|
|
4095
|
-
}, [cacheKey, load]);
|
|
4096
|
-
return { definitions, isLoading, error, refetch };
|
|
4097
|
-
}
|
|
4098
|
-
var facetsCache = /* @__PURE__ */ new Map();
|
|
4099
|
-
var facetsInflight = /* @__PURE__ */ new Map();
|
|
4100
|
-
function usePropertyFacets(options = {}) {
|
|
4101
|
-
const context = useOptionalCimplifyClient();
|
|
4102
|
-
const client = options.client ?? context?.client;
|
|
4103
|
-
if (!client) {
|
|
4104
|
-
throw new Error(
|
|
4105
|
-
"usePropertyFacets must be used within CimplifyProvider or passed { client }."
|
|
4106
|
-
);
|
|
4107
|
-
}
|
|
4108
|
-
const enabled = options.enabled ?? true;
|
|
4109
|
-
const cacheKey = useMemo(
|
|
4110
|
-
() => `facets_${client.getPublicKey() || "__demo__"}_${options.category_id ?? ""}_${options.product_type ?? ""}`,
|
|
4111
|
-
[client, options.category_id, options.product_type]
|
|
4112
|
-
);
|
|
4113
|
-
const cached = facetsCache.get(cacheKey);
|
|
4114
|
-
const [facets, setFacets] = useState(cached ?? []);
|
|
4115
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
4116
|
-
const [error, setError] = useState(null);
|
|
4117
|
-
const load = useCallback(
|
|
4118
|
-
async (force = false) => {
|
|
4119
|
-
if (!enabled) {
|
|
4120
|
-
setIsLoading(false);
|
|
4121
|
-
return;
|
|
4122
|
-
}
|
|
4123
|
-
setError(null);
|
|
4124
|
-
if (!force) {
|
|
4125
|
-
const cachedFacets = facetsCache.get(cacheKey);
|
|
4126
|
-
if (cachedFacets) {
|
|
4127
|
-
setFacets(cachedFacets);
|
|
4128
|
-
setIsLoading(false);
|
|
4129
|
-
return;
|
|
4130
|
-
}
|
|
4131
|
-
}
|
|
4132
|
-
setIsLoading(true);
|
|
4133
|
-
try {
|
|
4134
|
-
const existing = facetsInflight.get(cacheKey);
|
|
4135
|
-
const promise = existing ?? (async () => {
|
|
4136
|
-
const result = await client.catalogue.getPropertyFacets({
|
|
4137
|
-
category_id: options.category_id,
|
|
4138
|
-
product_type: options.product_type
|
|
4139
|
-
});
|
|
4140
|
-
if (!result.ok) {
|
|
4141
|
-
throw result.error;
|
|
4142
|
-
}
|
|
4143
|
-
return result.value;
|
|
4144
|
-
})();
|
|
4145
|
-
if (!existing) {
|
|
4146
|
-
facetsInflight.set(
|
|
4147
|
-
cacheKey,
|
|
4148
|
-
promise.finally(() => {
|
|
4149
|
-
facetsInflight.delete(cacheKey);
|
|
4150
|
-
})
|
|
4151
|
-
);
|
|
4152
|
-
}
|
|
4153
|
-
const value = await promise;
|
|
4154
|
-
facetsCache.set(cacheKey, value);
|
|
4155
|
-
setFacets(value);
|
|
4156
|
-
} catch (loadError) {
|
|
4157
|
-
setError(loadError);
|
|
4158
|
-
} finally {
|
|
4159
|
-
setIsLoading(false);
|
|
4160
|
-
}
|
|
4161
|
-
},
|
|
4162
|
-
[cacheKey, client, enabled, options.category_id, options.product_type]
|
|
4163
|
-
);
|
|
4164
|
-
useEffect(() => {
|
|
4165
|
-
void load(false);
|
|
4166
|
-
}, [load]);
|
|
4167
|
-
const refetch = useCallback(async () => {
|
|
4168
|
-
facetsCache.delete(cacheKey);
|
|
4169
|
-
await load(true);
|
|
4170
|
-
}, [cacheKey, load]);
|
|
4171
|
-
return { facets, isLoading, error, refetch };
|
|
4172
|
-
}
|
|
4173
|
-
function useBillingPlans(productId, options = {}) {
|
|
4174
|
-
const context = useOptionalCimplifyClient();
|
|
4175
|
-
const client = options.client ?? context?.client;
|
|
4176
|
-
if (!client) {
|
|
4177
|
-
throw new Error("useBillingPlans must be used within CimplifyProvider or passed { client }.");
|
|
4178
|
-
}
|
|
4179
|
-
const enabled = options.enabled ?? true;
|
|
4180
|
-
const requestIdRef = useRef(0);
|
|
4181
|
-
const [plans, setPlans] = useState([]);
|
|
4182
|
-
const [isLoading, setIsLoading] = useState(enabled && !!productId);
|
|
4183
|
-
const [error, setError] = useState(null);
|
|
4184
|
-
const customerId = options.customerId;
|
|
4185
|
-
const quantity = options.quantity;
|
|
4186
|
-
const orderValue = options.orderValue;
|
|
4187
|
-
const load = useCallback(
|
|
4188
|
-
async (force = false) => {
|
|
4189
|
-
if (!enabled || !productId) {
|
|
4190
|
-
setPlans([]);
|
|
4191
|
-
setIsLoading(false);
|
|
4192
|
-
return;
|
|
4193
|
-
}
|
|
4194
|
-
const nextRequestId = ++requestIdRef.current;
|
|
4195
|
-
setError(null);
|
|
4196
|
-
setIsLoading(true);
|
|
4197
|
-
try {
|
|
4198
|
-
const result = await client.catalogue.getEligibleBillingPlans(productId, {
|
|
4199
|
-
customer_id: customerId,
|
|
4200
|
-
quantity,
|
|
4201
|
-
order_value: orderValue
|
|
4202
|
-
});
|
|
4203
|
-
if (!result.ok) {
|
|
4204
|
-
throw result.error;
|
|
4205
|
-
}
|
|
4206
|
-
if (nextRequestId === requestIdRef.current) {
|
|
4207
|
-
setPlans(result.value);
|
|
4208
|
-
setError(null);
|
|
4209
|
-
}
|
|
4210
|
-
} catch (loadError) {
|
|
4211
|
-
if (nextRequestId === requestIdRef.current) {
|
|
4212
|
-
setError(loadError);
|
|
4213
|
-
}
|
|
4214
|
-
} finally {
|
|
4215
|
-
if (nextRequestId === requestIdRef.current) {
|
|
4216
|
-
setIsLoading(false);
|
|
4217
|
-
}
|
|
4218
|
-
}
|
|
4219
|
-
},
|
|
4220
|
-
[client, enabled, productId, customerId, quantity, orderValue]
|
|
4221
|
-
);
|
|
4222
|
-
useEffect(() => {
|
|
4223
|
-
void load(false);
|
|
4224
|
-
}, [load]);
|
|
4225
|
-
const refetch = useCallback(async () => {
|
|
4226
|
-
await load(true);
|
|
4227
|
-
}, [load]);
|
|
4228
|
-
const subscriptionPlans = useMemo(
|
|
4229
|
-
() => plans.filter((p) => p.plan_type === "subscription"),
|
|
4230
|
-
[plans]
|
|
4231
|
-
);
|
|
4232
|
-
const installmentPlans = useMemo(
|
|
4233
|
-
() => plans.filter((p) => p.plan_type === "installment"),
|
|
4234
|
-
[plans]
|
|
4235
|
-
);
|
|
4236
|
-
return { plans, subscriptionPlans, installmentPlans, isLoading, error, refetch };
|
|
4237
|
-
}
|
|
4238
|
-
function findMatchingVariant(variants, selections) {
|
|
4239
|
-
const axisCount = Object.keys(selections).length;
|
|
4240
|
-
if (axisCount === 0) return null;
|
|
4241
|
-
return variants.find((v) => {
|
|
4242
|
-
const sel = v.axis_selections;
|
|
4243
|
-
if (!sel) return false;
|
|
4244
|
-
return Object.entries(selections).every(([axisId, valueId]) => sel[axisId] === valueId);
|
|
4245
|
-
}) ?? null;
|
|
4246
|
-
}
|
|
4247
|
-
function computeAvailableValues(variants, axes, selections) {
|
|
4248
|
-
const result = {};
|
|
4249
|
-
for (const axis of axes) {
|
|
4250
|
-
const otherSelections = Object.entries(selections).filter(([id]) => id !== axis.id);
|
|
4251
|
-
const candidates = variants.filter((v) => {
|
|
4252
|
-
const sel = v.axis_selections;
|
|
4253
|
-
if (!sel) return false;
|
|
4254
|
-
return otherSelections.every(([axisId, valueId]) => sel[axisId] === valueId);
|
|
4255
|
-
});
|
|
4256
|
-
const available = /* @__PURE__ */ new Set();
|
|
4257
|
-
for (const v of candidates) {
|
|
4258
|
-
const val = v.axis_selections?.[axis.id];
|
|
4259
|
-
if (val) available.add(val);
|
|
4260
|
-
}
|
|
4261
|
-
result[axis.id] = available;
|
|
4262
|
-
}
|
|
4263
|
-
return result;
|
|
4264
|
-
}
|
|
4265
|
-
function useVariantSelector(options) {
|
|
4266
|
-
const { variants, axes } = options;
|
|
4267
|
-
const [selectedValues, setSelectedValues] = useState({});
|
|
4268
|
-
const selectValue = useCallback(
|
|
4269
|
-
(axisId, valueId) => {
|
|
4270
|
-
setSelectedValues((prev) => {
|
|
4271
|
-
if (prev[axisId] === valueId) {
|
|
4272
|
-
const next = { ...prev };
|
|
4273
|
-
delete next[axisId];
|
|
4274
|
-
return next;
|
|
4275
|
-
}
|
|
4276
|
-
return { ...prev, [axisId]: valueId };
|
|
4277
|
-
});
|
|
4278
|
-
},
|
|
4279
|
-
[]
|
|
4280
|
-
);
|
|
4281
|
-
const reset = useCallback(() => setSelectedValues({}), []);
|
|
4282
|
-
const selectedVariant = useMemo(
|
|
4283
|
-
() => findMatchingVariant(variants, selectedValues),
|
|
4284
|
-
[variants, selectedValues]
|
|
4285
|
-
);
|
|
4286
|
-
const variantImage = useMemo(
|
|
4287
|
-
() => selectedVariant?.images?.[0] ?? null,
|
|
4288
|
-
[selectedVariant]
|
|
4289
|
-
);
|
|
4290
|
-
const availableValues = useMemo(
|
|
4291
|
-
() => computeAvailableValues(variants, axes, selectedValues),
|
|
4292
|
-
[variants, axes, selectedValues]
|
|
4293
|
-
);
|
|
4294
|
-
return {
|
|
4295
|
-
selectedValues,
|
|
4296
|
-
selectedVariant,
|
|
4297
|
-
variantImage,
|
|
4298
|
-
availableValues,
|
|
4299
|
-
selectValue,
|
|
4300
|
-
reset
|
|
4301
|
-
};
|
|
4302
|
-
}
|
|
4303
|
-
var activityStateCache = /* @__PURE__ */ new Map();
|
|
4304
|
-
var activityStateInflight = /* @__PURE__ */ new Map();
|
|
4305
|
-
function buildActivityStateCacheKey(client) {
|
|
4306
|
-
return JSON.stringify({ key: client.getPublicKey(), type: "activity_state" });
|
|
2667
|
+
});
|
|
2668
|
+
function useBundles(options = {}) {
|
|
2669
|
+
const { data, isLoading, error, refetch } = bundlesQuery(options);
|
|
2670
|
+
return { bundles: data ?? [], isLoading, error, refetch };
|
|
4307
2671
|
}
|
|
4308
|
-
function
|
|
4309
|
-
const
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
if (!force) {
|
|
4328
|
-
const cachedState = activityStateCache.get(cacheKey);
|
|
4329
|
-
if (cachedState) {
|
|
4330
|
-
setState(cachedState);
|
|
4331
|
-
setIsLoading(false);
|
|
4332
|
-
return;
|
|
4333
|
-
}
|
|
2672
|
+
function useProductPrice(input) {
|
|
2673
|
+
const {
|
|
2674
|
+
product,
|
|
2675
|
+
quantity = 1,
|
|
2676
|
+
variant,
|
|
2677
|
+
addOnOptions,
|
|
2678
|
+
compositePrice,
|
|
2679
|
+
bundleTotalPrice
|
|
2680
|
+
} = input;
|
|
2681
|
+
return useMemo(() => {
|
|
2682
|
+
let unitPrice;
|
|
2683
|
+
if (bundleTotalPrice != null) {
|
|
2684
|
+
unitPrice = bundleTotalPrice;
|
|
2685
|
+
} else if (compositePrice) {
|
|
2686
|
+
unitPrice = parsePrice(compositePrice.final_price);
|
|
2687
|
+
} else {
|
|
2688
|
+
unitPrice = parsePrice(product.default_price);
|
|
2689
|
+
if (variant?.price_adjustment) {
|
|
2690
|
+
unitPrice += parsePrice(variant.price_adjustment);
|
|
4334
2691
|
}
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
const result = await client.activity.getState();
|
|
4340
|
-
if (!result.ok) {
|
|
4341
|
-
throw result.error;
|
|
2692
|
+
if (addOnOptions) {
|
|
2693
|
+
for (const option of addOnOptions) {
|
|
2694
|
+
if (option.default_price) {
|
|
2695
|
+
unitPrice += parsePrice(option.default_price);
|
|
4342
2696
|
}
|
|
4343
|
-
return result.value;
|
|
4344
|
-
})();
|
|
4345
|
-
if (!existing) {
|
|
4346
|
-
activityStateInflight.set(
|
|
4347
|
-
cacheKey,
|
|
4348
|
-
promise.finally(() => {
|
|
4349
|
-
activityStateInflight.delete(cacheKey);
|
|
4350
|
-
})
|
|
4351
|
-
);
|
|
4352
2697
|
}
|
|
4353
|
-
const value = await promise;
|
|
4354
|
-
activityStateCache.set(cacheKey, value);
|
|
4355
|
-
setState(value);
|
|
4356
|
-
} catch (loadError) {
|
|
4357
|
-
setError(loadError);
|
|
4358
|
-
} finally {
|
|
4359
|
-
setIsLoading(false);
|
|
4360
|
-
}
|
|
4361
|
-
},
|
|
4362
|
-
[cacheKey, client, enabled]
|
|
4363
|
-
);
|
|
4364
|
-
useEffect(() => {
|
|
4365
|
-
void load(false);
|
|
4366
|
-
}, [load]);
|
|
4367
|
-
const refetch = useCallback(async () => {
|
|
4368
|
-
activityStateCache.delete(cacheKey);
|
|
4369
|
-
await load(true);
|
|
4370
|
-
}, [cacheKey, load]);
|
|
4371
|
-
const dismissMessage = useCallback(
|
|
4372
|
-
async (code) => {
|
|
4373
|
-
const result = await client.activity.dismissMessage(code);
|
|
4374
|
-
if (!result.ok) {
|
|
4375
|
-
setError(result.error);
|
|
4376
|
-
return;
|
|
4377
2698
|
}
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
);
|
|
4387
|
-
const messages = state?.messages ?? [];
|
|
4388
|
-
const intent = state?.intent ?? "";
|
|
4389
|
-
return { state, messages, intent, isLoading, error, refetch, dismissMessage };
|
|
4390
|
-
}
|
|
4391
|
-
var recommendationsCache = /* @__PURE__ */ new Map();
|
|
4392
|
-
var recommendationsInflight = /* @__PURE__ */ new Map();
|
|
4393
|
-
function buildRecommendationsCacheKey(client, locationId, limit) {
|
|
4394
|
-
return JSON.stringify({
|
|
4395
|
-
key: client.getPublicKey(),
|
|
4396
|
-
type: "recommendations",
|
|
4397
|
-
location_id: locationId,
|
|
4398
|
-
limit
|
|
4399
|
-
});
|
|
2699
|
+
}
|
|
2700
|
+
unitPrice = Math.round(unitPrice * 100) / 100;
|
|
2701
|
+
const totalPrice = Math.round(unitPrice * quantity * 100) / 100;
|
|
2702
|
+
return {
|
|
2703
|
+
unitPrice,
|
|
2704
|
+
totalPrice,
|
|
2705
|
+
displayTotalPrice: totalPrice
|
|
2706
|
+
};
|
|
2707
|
+
}, [product.default_price, quantity, variant?.price_adjustment, addOnOptions, compositePrice, bundleTotalPrice]);
|
|
4400
2708
|
}
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
2709
|
+
|
|
2710
|
+
// src/react/hooks/use-orders.ts
|
|
2711
|
+
var ordersQuery = createCachedQuery({
|
|
2712
|
+
name: "useOrders",
|
|
2713
|
+
key: (client, options) => cacheKey(client.getPublicKey(), options.status, options.limit),
|
|
2714
|
+
fetch: async (client, options) => {
|
|
2715
|
+
const result = await client.orders.list({
|
|
2716
|
+
status: options.status,
|
|
2717
|
+
limit: options.limit
|
|
2718
|
+
});
|
|
2719
|
+
if (!result.ok) throw result.error;
|
|
2720
|
+
return result.value;
|
|
4408
2721
|
}
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
const
|
|
4412
|
-
|
|
4413
|
-
const cacheKey = useMemo(
|
|
4414
|
-
() => buildRecommendationsCacheKey(client, locationId, limit),
|
|
4415
|
-
[client, locationId, limit]
|
|
4416
|
-
);
|
|
4417
|
-
const cached = recommendationsCache.get(cacheKey);
|
|
4418
|
-
const [response, setResponse] = useState(cached ?? null);
|
|
4419
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
4420
|
-
const [error, setError] = useState(null);
|
|
4421
|
-
useEffect(() => {
|
|
4422
|
-
if (previousLocationIdRef.current !== locationId) {
|
|
4423
|
-
recommendationsCache.clear();
|
|
4424
|
-
recommendationsInflight.clear();
|
|
4425
|
-
previousLocationIdRef.current = locationId;
|
|
4426
|
-
}
|
|
4427
|
-
}, [locationId]);
|
|
4428
|
-
const load = useCallback(
|
|
4429
|
-
async (force = false) => {
|
|
4430
|
-
if (!enabled) {
|
|
4431
|
-
setIsLoading(false);
|
|
4432
|
-
return;
|
|
4433
|
-
}
|
|
4434
|
-
setError(null);
|
|
4435
|
-
if (!force) {
|
|
4436
|
-
const cachedResponse = recommendationsCache.get(cacheKey);
|
|
4437
|
-
if (cachedResponse) {
|
|
4438
|
-
setResponse(cachedResponse);
|
|
4439
|
-
setIsLoading(false);
|
|
4440
|
-
return;
|
|
4441
|
-
}
|
|
4442
|
-
}
|
|
4443
|
-
setIsLoading(true);
|
|
4444
|
-
try {
|
|
4445
|
-
const existing = recommendationsInflight.get(cacheKey);
|
|
4446
|
-
const promise = existing ?? (async () => {
|
|
4447
|
-
const result = await client.activity.getRecommendations({
|
|
4448
|
-
location_id: locationId,
|
|
4449
|
-
limit
|
|
4450
|
-
});
|
|
4451
|
-
if (!result.ok) {
|
|
4452
|
-
throw result.error;
|
|
4453
|
-
}
|
|
4454
|
-
return result.value;
|
|
4455
|
-
})();
|
|
4456
|
-
if (!existing) {
|
|
4457
|
-
recommendationsInflight.set(
|
|
4458
|
-
cacheKey,
|
|
4459
|
-
promise.finally(() => {
|
|
4460
|
-
recommendationsInflight.delete(cacheKey);
|
|
4461
|
-
})
|
|
4462
|
-
);
|
|
4463
|
-
}
|
|
4464
|
-
const value = await promise;
|
|
4465
|
-
recommendationsCache.set(cacheKey, value);
|
|
4466
|
-
setResponse(value);
|
|
4467
|
-
} catch (loadError) {
|
|
4468
|
-
setError(loadError);
|
|
4469
|
-
} finally {
|
|
4470
|
-
setIsLoading(false);
|
|
4471
|
-
}
|
|
4472
|
-
},
|
|
4473
|
-
[cacheKey, client, enabled, locationId, limit]
|
|
4474
|
-
);
|
|
4475
|
-
useEffect(() => {
|
|
4476
|
-
void load(false);
|
|
4477
|
-
}, [load]);
|
|
4478
|
-
const refetch = useCallback(async () => {
|
|
4479
|
-
recommendationsCache.delete(cacheKey);
|
|
4480
|
-
await load(true);
|
|
4481
|
-
}, [cacheKey, load]);
|
|
4482
|
-
const recommendations = response?.recommendations ?? [];
|
|
4483
|
-
const intent = response?.intent ?? "";
|
|
4484
|
-
return { recommendations, intent, isLoading, error, refetch };
|
|
4485
|
-
}
|
|
4486
|
-
var deliveryFeeCache = /* @__PURE__ */ new Map();
|
|
4487
|
-
function buildDeliveryFeeCacheKey(client, latitude, longitude, country) {
|
|
4488
|
-
return JSON.stringify({
|
|
4489
|
-
key: client.getPublicKey(),
|
|
4490
|
-
lat: latitude,
|
|
4491
|
-
lng: longitude,
|
|
4492
|
-
country
|
|
4493
|
-
});
|
|
2722
|
+
});
|
|
2723
|
+
function useOrders(options = {}) {
|
|
2724
|
+
const { data, isLoading, error, refetch } = ordersQuery(options);
|
|
2725
|
+
return { orders: data ?? [], isLoading, error, refetch };
|
|
4494
2726
|
}
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
2727
|
+
|
|
2728
|
+
// src/react/hooks/use-services.ts
|
|
2729
|
+
var servicesQuery = createCachedQuery({
|
|
2730
|
+
name: "useServices",
|
|
2731
|
+
key: (client) => cacheKey(client.getPublicKey()),
|
|
2732
|
+
fetch: async (client) => {
|
|
2733
|
+
const result = await client.scheduling.getServices();
|
|
2734
|
+
if (!result.ok) throw result.error;
|
|
2735
|
+
return result.value;
|
|
4500
2736
|
}
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
const
|
|
4504
|
-
|
|
4505
|
-
[client, latitude, longitude, country]
|
|
4506
|
-
);
|
|
4507
|
-
const cached = deliveryFeeCache.get(cacheKey);
|
|
4508
|
-
const [fee, setFee] = useState(cached ?? null);
|
|
4509
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
4510
|
-
const [error, setError] = useState(null);
|
|
4511
|
-
const requestIdRef = useRef(0);
|
|
4512
|
-
const load = useCallback(
|
|
4513
|
-
async (force = false) => {
|
|
4514
|
-
if (!enabled) {
|
|
4515
|
-
setIsLoading(false);
|
|
4516
|
-
return;
|
|
4517
|
-
}
|
|
4518
|
-
setError(null);
|
|
4519
|
-
if (!force) {
|
|
4520
|
-
const cachedFee = deliveryFeeCache.get(cacheKey);
|
|
4521
|
-
if (cachedFee) {
|
|
4522
|
-
setFee(cachedFee);
|
|
4523
|
-
setIsLoading(false);
|
|
4524
|
-
return;
|
|
4525
|
-
}
|
|
4526
|
-
}
|
|
4527
|
-
setIsLoading(true);
|
|
4528
|
-
const currentRequestId = ++requestIdRef.current;
|
|
4529
|
-
try {
|
|
4530
|
-
const result = await client.delivery.getFee(latitude, longitude, country);
|
|
4531
|
-
if (currentRequestId !== requestIdRef.current) return;
|
|
4532
|
-
if (!result.ok) {
|
|
4533
|
-
throw result.error;
|
|
4534
|
-
}
|
|
4535
|
-
deliveryFeeCache.set(cacheKey, result.value);
|
|
4536
|
-
setFee(result.value);
|
|
4537
|
-
} catch (loadError) {
|
|
4538
|
-
if (currentRequestId !== requestIdRef.current) return;
|
|
4539
|
-
setError(loadError);
|
|
4540
|
-
} finally {
|
|
4541
|
-
if (currentRequestId === requestIdRef.current) {
|
|
4542
|
-
setIsLoading(false);
|
|
4543
|
-
}
|
|
4544
|
-
}
|
|
4545
|
-
},
|
|
4546
|
-
[cacheKey, client, country, enabled, latitude, longitude]
|
|
4547
|
-
);
|
|
4548
|
-
useEffect(() => {
|
|
4549
|
-
void load(false);
|
|
4550
|
-
}, [load]);
|
|
4551
|
-
const refetch = useCallback(async () => {
|
|
4552
|
-
deliveryFeeCache.delete(cacheKey);
|
|
4553
|
-
await load(true);
|
|
4554
|
-
}, [cacheKey, load]);
|
|
4555
|
-
return { fee, isLoading, error, refetch };
|
|
2737
|
+
});
|
|
2738
|
+
function useServices(options = {}) {
|
|
2739
|
+
const { data, isLoading, error, refetch } = servicesQuery(options);
|
|
2740
|
+
return { services: data ?? [], isLoading, error, refetch };
|
|
4556
2741
|
}
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
2742
|
+
|
|
2743
|
+
// src/react/hooks/use-available-slots.ts
|
|
2744
|
+
var slotsQuery = createCachedQuery({
|
|
2745
|
+
name: "useAvailableSlots",
|
|
2746
|
+
key: (client, options) => cacheKey(client.getPublicKey(), options.serviceId, options.date, options.participantCount),
|
|
2747
|
+
fetch: async (client, options) => {
|
|
2748
|
+
const result = await client.scheduling.getAvailableSlots({
|
|
2749
|
+
service_id: options.serviceId,
|
|
2750
|
+
date: options.date,
|
|
2751
|
+
participant_count: options.participantCount
|
|
2752
|
+
});
|
|
2753
|
+
if (!result.ok) throw result.error;
|
|
2754
|
+
return result.value;
|
|
2755
|
+
}
|
|
2756
|
+
});
|
|
2757
|
+
function useAvailableSlots(serviceId, date, options = {}) {
|
|
2758
|
+
const { data, isLoading, error, refetch } = slotsQuery({
|
|
2759
|
+
...options,
|
|
2760
|
+
serviceId: serviceId || "",
|
|
2761
|
+
date: date || "",
|
|
2762
|
+
enabled: (options.enabled ?? true) && !!serviceId && !!date
|
|
2763
|
+
});
|
|
2764
|
+
return { slots: data ?? [], isLoading, error, refetch };
|
|
4561
2765
|
}
|
|
4562
|
-
|
|
2766
|
+
|
|
2767
|
+
// src/react/hooks/use-service-availability.ts
|
|
2768
|
+
var serviceAvailabilityQuery = createCachedQuery({
|
|
2769
|
+
name: "useServiceAvailability",
|
|
2770
|
+
key: (client, options) => cacheKey(
|
|
2771
|
+
client.getPublicKey(),
|
|
2772
|
+
options.serviceId,
|
|
2773
|
+
options.startDate,
|
|
2774
|
+
options.endDate,
|
|
2775
|
+
options.participantCount
|
|
2776
|
+
),
|
|
2777
|
+
fetch: async (client, options) => {
|
|
2778
|
+
const result = await client.scheduling.getServiceAvailability({
|
|
2779
|
+
service_id: options.serviceId,
|
|
2780
|
+
start_date: options.startDate,
|
|
2781
|
+
end_date: options.endDate,
|
|
2782
|
+
location_id: options.locationId,
|
|
2783
|
+
participant_count: options.participantCount
|
|
2784
|
+
});
|
|
2785
|
+
if (!result.ok) throw result.error;
|
|
2786
|
+
return result.value.availability;
|
|
2787
|
+
}
|
|
2788
|
+
});
|
|
2789
|
+
function useServiceAvailability(serviceId, startDate, endDate, options = {}) {
|
|
2790
|
+
const { data, isLoading, error, refetch } = serviceAvailabilityQuery({
|
|
2791
|
+
...options,
|
|
2792
|
+
serviceId: serviceId || "",
|
|
2793
|
+
startDate: startDate || "",
|
|
2794
|
+
endDate: endDate || "",
|
|
2795
|
+
enabled: (options.enabled ?? true) && !!serviceId && !!startDate && !!endDate
|
|
2796
|
+
});
|
|
2797
|
+
return { days: data ?? [], isLoading, error, refetch };
|
|
2798
|
+
}
|
|
2799
|
+
var bookingsQuery = createCachedQuery({
|
|
2800
|
+
name: "useBookings",
|
|
2801
|
+
key: (client, options) => cacheKey(client.getPublicKey(), options.filter ?? "all"),
|
|
2802
|
+
fetch: async (client, options) => {
|
|
2803
|
+
const filter = options.filter ?? "all";
|
|
2804
|
+
let result;
|
|
2805
|
+
switch (filter) {
|
|
2806
|
+
case "upcoming":
|
|
2807
|
+
result = await client.scheduling.getUpcomingBookings();
|
|
2808
|
+
break;
|
|
2809
|
+
case "past":
|
|
2810
|
+
result = await client.scheduling.getPastBookings();
|
|
2811
|
+
break;
|
|
2812
|
+
default:
|
|
2813
|
+
result = await client.scheduling.getCustomerBookings();
|
|
2814
|
+
break;
|
|
2815
|
+
}
|
|
2816
|
+
if (!result.ok) throw result.error;
|
|
2817
|
+
return result.value;
|
|
2818
|
+
}
|
|
2819
|
+
});
|
|
2820
|
+
function useBookings(options = {}) {
|
|
4563
2821
|
const context = useOptionalCimplifyClient();
|
|
4564
2822
|
const client = options.client ?? context?.client;
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
const [error, setError] = useState(null);
|
|
4578
|
-
const load = useCallback(
|
|
4579
|
-
async (force = false) => {
|
|
4580
|
-
if (!enabled) {
|
|
4581
|
-
setIsLoading(false);
|
|
4582
|
-
return;
|
|
4583
|
-
}
|
|
4584
|
-
setError(null);
|
|
4585
|
-
if (!force) {
|
|
4586
|
-
const cachedRate = fxRateCache.get(cacheKey);
|
|
4587
|
-
if (cachedRate) {
|
|
4588
|
-
setRate(cachedRate);
|
|
4589
|
-
setIsLoading(false);
|
|
4590
|
-
return;
|
|
4591
|
-
}
|
|
4592
|
-
}
|
|
4593
|
-
setIsLoading(true);
|
|
4594
|
-
try {
|
|
4595
|
-
const existing = fxRateInflight.get(cacheKey);
|
|
4596
|
-
const promise = existing ?? (async () => {
|
|
4597
|
-
const result = await client.fx.getRate(from, to);
|
|
4598
|
-
if (!result.ok) {
|
|
4599
|
-
throw result.error;
|
|
4600
|
-
}
|
|
4601
|
-
return result.value;
|
|
4602
|
-
})();
|
|
4603
|
-
if (!existing) {
|
|
4604
|
-
fxRateInflight.set(
|
|
4605
|
-
cacheKey,
|
|
4606
|
-
promise.finally(() => {
|
|
4607
|
-
fxRateInflight.delete(cacheKey);
|
|
4608
|
-
})
|
|
4609
|
-
);
|
|
4610
|
-
}
|
|
4611
|
-
const value = await promise;
|
|
4612
|
-
fxRateCache.set(cacheKey, value);
|
|
4613
|
-
setRate(value);
|
|
4614
|
-
} catch (loadError) {
|
|
4615
|
-
setError(loadError);
|
|
4616
|
-
} finally {
|
|
4617
|
-
setIsLoading(false);
|
|
4618
|
-
}
|
|
2823
|
+
const { data, isLoading, error, refetch } = bookingsQuery(options);
|
|
2824
|
+
const cancelBooking = useCallback(
|
|
2825
|
+
async (bookingId, reason) => {
|
|
2826
|
+
if (!client) throw new Error("useBookings must be used within CimplifyProvider or passed { client }.");
|
|
2827
|
+
const result = await client.scheduling.cancelBooking({
|
|
2828
|
+
booking_id: bookingId,
|
|
2829
|
+
reason
|
|
2830
|
+
});
|
|
2831
|
+
if (!result.ok) throw result.error;
|
|
2832
|
+
bookingsQuery.clear();
|
|
2833
|
+
await refetch();
|
|
2834
|
+
return result.value;
|
|
4619
2835
|
},
|
|
4620
|
-
[
|
|
2836
|
+
[client, refetch]
|
|
4621
2837
|
);
|
|
4622
|
-
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
|
|
4626
|
-
|
|
4627
|
-
|
|
4628
|
-
|
|
4629
|
-
|
|
2838
|
+
return { bookings: data ?? [], isLoading, error, refetch, cancelBooking };
|
|
2839
|
+
}
|
|
2840
|
+
|
|
2841
|
+
// src/react/hooks/use-attribute-definitions.ts
|
|
2842
|
+
var attributeDefinitionsQuery = createCachedQuery({
|
|
2843
|
+
name: "useAttributeDefinitions",
|
|
2844
|
+
key: (client, options) => cacheKey(client.getPublicKey() || "__demo__", options.namespace),
|
|
2845
|
+
fetch: async (client, options) => {
|
|
2846
|
+
const result = await client.catalogue.getAttributeDefinitions(options.namespace);
|
|
2847
|
+
if (!result.ok) throw result.error;
|
|
2848
|
+
return result.value;
|
|
2849
|
+
}
|
|
2850
|
+
});
|
|
2851
|
+
function useAttributeDefinitions(options = {}) {
|
|
2852
|
+
const { data, isLoading, error, refetch } = attributeDefinitionsQuery(options);
|
|
2853
|
+
return { definitions: data ?? [], isLoading, error, refetch };
|
|
4630
2854
|
}
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
|
|
4634
|
-
|
|
2855
|
+
|
|
2856
|
+
// src/react/hooks/use-property-facets.ts
|
|
2857
|
+
var propertyFacetsQuery = createCachedQuery({
|
|
2858
|
+
name: "usePropertyFacets",
|
|
2859
|
+
key: (client, options) => cacheKey(client.getPublicKey() || "__demo__", options.category_id, options.product_type),
|
|
2860
|
+
fetch: async (client, options) => {
|
|
2861
|
+
const result = await client.catalogue.getPropertyFacets({
|
|
2862
|
+
category_id: options.category_id,
|
|
2863
|
+
product_type: options.product_type
|
|
2864
|
+
});
|
|
2865
|
+
if (!result.ok) throw result.error;
|
|
2866
|
+
return result.value;
|
|
2867
|
+
}
|
|
2868
|
+
});
|
|
2869
|
+
function usePropertyFacets(options = {}) {
|
|
2870
|
+
const { data, isLoading, error, refetch } = propertyFacetsQuery(options);
|
|
2871
|
+
return { facets: data ?? [], isLoading, error, refetch };
|
|
4635
2872
|
}
|
|
4636
|
-
function
|
|
2873
|
+
function useBillingPlans(productId, options = {}) {
|
|
4637
2874
|
const context = useOptionalCimplifyClient();
|
|
4638
2875
|
const client = options.client ?? context?.client;
|
|
4639
2876
|
if (!client) {
|
|
4640
|
-
throw new Error("
|
|
2877
|
+
throw new Error("useBillingPlans must be used within CimplifyProvider or passed { client }.");
|
|
4641
2878
|
}
|
|
4642
2879
|
const enabled = options.enabled ?? true;
|
|
4643
|
-
const
|
|
4644
|
-
const
|
|
4645
|
-
const [
|
|
4646
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
2880
|
+
const requestIdRef = useRef(0);
|
|
2881
|
+
const [plans, setPlans] = useState([]);
|
|
2882
|
+
const [isLoading, setIsLoading] = useState(enabled && !!productId);
|
|
4647
2883
|
const [error, setError] = useState(null);
|
|
2884
|
+
const customerId = options.customerId;
|
|
2885
|
+
const quantity = options.quantity;
|
|
2886
|
+
const orderValue = options.orderValue;
|
|
4648
2887
|
const load = useCallback(
|
|
4649
2888
|
async (force = false) => {
|
|
4650
|
-
if (!enabled) {
|
|
2889
|
+
if (!enabled || !productId) {
|
|
2890
|
+
setPlans([]);
|
|
4651
2891
|
setIsLoading(false);
|
|
4652
2892
|
return;
|
|
4653
2893
|
}
|
|
2894
|
+
const nextRequestId = ++requestIdRef.current;
|
|
4654
2895
|
setError(null);
|
|
4655
|
-
if (!force) {
|
|
4656
|
-
const cachedBootstrap = bootstrapCache.get(cacheKey);
|
|
4657
|
-
if (cachedBootstrap) {
|
|
4658
|
-
setBootstrap(cachedBootstrap);
|
|
4659
|
-
setIsLoading(false);
|
|
4660
|
-
return;
|
|
4661
|
-
}
|
|
4662
|
-
}
|
|
4663
2896
|
setIsLoading(true);
|
|
4664
2897
|
try {
|
|
4665
|
-
const
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
}
|
|
4673
|
-
if (
|
|
4674
|
-
|
|
4675
|
-
|
|
4676
|
-
promise.finally(() => {
|
|
4677
|
-
bootstrapInflight.delete(cacheKey);
|
|
4678
|
-
})
|
|
4679
|
-
);
|
|
2898
|
+
const result = await client.catalogue.getEligibleBillingPlans(productId, {
|
|
2899
|
+
customer_id: customerId,
|
|
2900
|
+
quantity,
|
|
2901
|
+
order_value: orderValue
|
|
2902
|
+
});
|
|
2903
|
+
if (!result.ok) {
|
|
2904
|
+
throw result.error;
|
|
2905
|
+
}
|
|
2906
|
+
if (nextRequestId === requestIdRef.current) {
|
|
2907
|
+
setPlans(result.value);
|
|
2908
|
+
setError(null);
|
|
4680
2909
|
}
|
|
4681
|
-
const value = await promise;
|
|
4682
|
-
bootstrapCache.set(cacheKey, value);
|
|
4683
|
-
setBootstrap(value);
|
|
4684
2910
|
} catch (loadError) {
|
|
4685
|
-
|
|
2911
|
+
if (nextRequestId === requestIdRef.current) {
|
|
2912
|
+
setError(loadError);
|
|
2913
|
+
}
|
|
4686
2914
|
} finally {
|
|
4687
|
-
|
|
2915
|
+
if (nextRequestId === requestIdRef.current) {
|
|
2916
|
+
setIsLoading(false);
|
|
2917
|
+
}
|
|
4688
2918
|
}
|
|
4689
2919
|
},
|
|
4690
|
-
[
|
|
2920
|
+
[client, enabled, productId, customerId, quantity, orderValue]
|
|
4691
2921
|
);
|
|
4692
2922
|
useEffect(() => {
|
|
4693
2923
|
void load(false);
|
|
4694
2924
|
}, [load]);
|
|
4695
2925
|
const refetch = useCallback(async () => {
|
|
4696
|
-
bootstrapCache.delete(cacheKey);
|
|
4697
2926
|
await load(true);
|
|
4698
|
-
}, [
|
|
4699
|
-
|
|
2927
|
+
}, [load]);
|
|
2928
|
+
const subscriptionPlans = useMemo(
|
|
2929
|
+
() => plans.filter((p) => p.plan_type === "subscription"),
|
|
2930
|
+
[plans]
|
|
2931
|
+
);
|
|
2932
|
+
const installmentPlans = useMemo(
|
|
2933
|
+
() => plans.filter((p) => p.plan_type === "installment"),
|
|
2934
|
+
[plans]
|
|
2935
|
+
);
|
|
2936
|
+
return { plans, subscriptionPlans, installmentPlans, isLoading, error, refetch };
|
|
2937
|
+
}
|
|
2938
|
+
function findMatchingVariant(variants, selections) {
|
|
2939
|
+
const axisCount = Object.keys(selections).length;
|
|
2940
|
+
if (axisCount === 0) return null;
|
|
2941
|
+
return variants.find((v) => {
|
|
2942
|
+
const sel = v.axis_selections;
|
|
2943
|
+
if (!sel) return false;
|
|
2944
|
+
return Object.entries(selections).every(([axisId, valueId]) => sel[axisId] === valueId);
|
|
2945
|
+
}) ?? null;
|
|
2946
|
+
}
|
|
2947
|
+
function computeAvailableValues(variants, axes, selections) {
|
|
2948
|
+
const result = {};
|
|
2949
|
+
for (const axis of axes) {
|
|
2950
|
+
const otherSelections = Object.entries(selections).filter(([id]) => id !== axis.id);
|
|
2951
|
+
const candidates = variants.filter((v) => {
|
|
2952
|
+
const sel = v.axis_selections;
|
|
2953
|
+
if (!sel) return false;
|
|
2954
|
+
return otherSelections.every(([axisId, valueId]) => sel[axisId] === valueId);
|
|
2955
|
+
});
|
|
2956
|
+
const available = /* @__PURE__ */ new Set();
|
|
2957
|
+
for (const v of candidates) {
|
|
2958
|
+
const val = v.axis_selections?.[axis.id];
|
|
2959
|
+
if (val) available.add(val);
|
|
2960
|
+
}
|
|
2961
|
+
result[axis.id] = available;
|
|
2962
|
+
}
|
|
2963
|
+
return result;
|
|
2964
|
+
}
|
|
2965
|
+
function useVariantSelector(options) {
|
|
2966
|
+
const { variants, axes } = options;
|
|
2967
|
+
const [selectedValues, setSelectedValues] = useState({});
|
|
2968
|
+
const selectValue = useCallback(
|
|
2969
|
+
(axisId, valueId) => {
|
|
2970
|
+
setSelectedValues((prev) => {
|
|
2971
|
+
if (prev[axisId] === valueId) {
|
|
2972
|
+
const next = { ...prev };
|
|
2973
|
+
delete next[axisId];
|
|
2974
|
+
return next;
|
|
2975
|
+
}
|
|
2976
|
+
return { ...prev, [axisId]: valueId };
|
|
2977
|
+
});
|
|
2978
|
+
},
|
|
2979
|
+
[]
|
|
2980
|
+
);
|
|
2981
|
+
const reset = useCallback(() => setSelectedValues({}), []);
|
|
2982
|
+
const selectedVariant = useMemo(
|
|
2983
|
+
() => findMatchingVariant(variants, selectedValues),
|
|
2984
|
+
[variants, selectedValues]
|
|
2985
|
+
);
|
|
2986
|
+
const variantImage = useMemo(
|
|
2987
|
+
() => selectedVariant?.images?.[0] ?? null,
|
|
2988
|
+
[selectedVariant]
|
|
2989
|
+
);
|
|
2990
|
+
const availableValues = useMemo(
|
|
2991
|
+
() => computeAvailableValues(variants, axes, selectedValues),
|
|
2992
|
+
[variants, axes, selectedValues]
|
|
2993
|
+
);
|
|
2994
|
+
return {
|
|
2995
|
+
selectedValues,
|
|
2996
|
+
selectedVariant,
|
|
2997
|
+
variantImage,
|
|
2998
|
+
availableValues,
|
|
2999
|
+
selectValue,
|
|
3000
|
+
reset
|
|
3001
|
+
};
|
|
3002
|
+
}
|
|
3003
|
+
var activityStateQuery = createCachedQuery({
|
|
3004
|
+
name: "useActivityState",
|
|
3005
|
+
key: (client) => cacheKey(client.getPublicKey()),
|
|
3006
|
+
fetch: async (client) => {
|
|
3007
|
+
const result = await client.activity.getState();
|
|
3008
|
+
if (!result.ok) throw result.error;
|
|
3009
|
+
return result.value;
|
|
3010
|
+
}
|
|
3011
|
+
});
|
|
3012
|
+
function useActivityState(options = {}) {
|
|
3013
|
+
const context = useOptionalCimplifyClient();
|
|
3014
|
+
const client = options.client ?? context?.client;
|
|
3015
|
+
const { data, isLoading, error, refetch } = activityStateQuery(options);
|
|
3016
|
+
const dismissMessage = useCallback(
|
|
3017
|
+
async (code) => {
|
|
3018
|
+
if (!client) return;
|
|
3019
|
+
const result = await client.activity.dismissMessage(code);
|
|
3020
|
+
if (!result.ok) return;
|
|
3021
|
+
activityStateQuery.clear();
|
|
3022
|
+
await refetch();
|
|
3023
|
+
},
|
|
3024
|
+
[client, refetch]
|
|
3025
|
+
);
|
|
3026
|
+
return {
|
|
3027
|
+
state: data,
|
|
3028
|
+
messages: data?.messages ?? [],
|
|
3029
|
+
intent: data?.intent ?? "",
|
|
3030
|
+
isLoading,
|
|
3031
|
+
error,
|
|
3032
|
+
refetch,
|
|
3033
|
+
dismissMessage
|
|
3034
|
+
};
|
|
3035
|
+
}
|
|
3036
|
+
|
|
3037
|
+
// src/react/hooks/use-recommendations.ts
|
|
3038
|
+
var recommendationsQuery = createCachedQuery({
|
|
3039
|
+
name: "useRecommendations",
|
|
3040
|
+
locationSensitive: true,
|
|
3041
|
+
key: (client, options) => {
|
|
3042
|
+
const locationId = options.locationId ?? client.getLocationId();
|
|
3043
|
+
return cacheKey(client.getPublicKey(), locationId, options.limit);
|
|
3044
|
+
},
|
|
3045
|
+
fetch: async (client, options) => {
|
|
3046
|
+
const locationId = options.locationId ?? client.getLocationId() ?? void 0;
|
|
3047
|
+
const result = await client.activity.getRecommendations({
|
|
3048
|
+
location_id: locationId,
|
|
3049
|
+
limit: options.limit
|
|
3050
|
+
});
|
|
3051
|
+
if (!result.ok) throw result.error;
|
|
3052
|
+
return result.value;
|
|
3053
|
+
}
|
|
3054
|
+
});
|
|
3055
|
+
function useRecommendations(options = {}) {
|
|
3056
|
+
const { data, isLoading, error, refetch } = recommendationsQuery(options);
|
|
3057
|
+
return {
|
|
3058
|
+
recommendations: data?.recommendations ?? [],
|
|
3059
|
+
intent: data?.intent ?? "",
|
|
3060
|
+
isLoading,
|
|
3061
|
+
error,
|
|
3062
|
+
refetch
|
|
3063
|
+
};
|
|
3064
|
+
}
|
|
3065
|
+
|
|
3066
|
+
// src/react/hooks/use-delivery-fee.ts
|
|
3067
|
+
var deliveryFeeQuery = createCachedQuery({
|
|
3068
|
+
name: "useDeliveryFee",
|
|
3069
|
+
key: (client, options) => cacheKey(client.getPublicKey(), options.latitude, options.longitude, options.country),
|
|
3070
|
+
fetch: async (client, options) => {
|
|
3071
|
+
const result = await client.delivery.getFee(options.latitude, options.longitude, options.country);
|
|
3072
|
+
if (!result.ok) throw result.error;
|
|
3073
|
+
return result.value;
|
|
3074
|
+
}
|
|
3075
|
+
});
|
|
3076
|
+
function useDeliveryFee(options) {
|
|
3077
|
+
const { data, isLoading, error, refetch } = deliveryFeeQuery(options);
|
|
3078
|
+
return { fee: data, isLoading, error, refetch };
|
|
3079
|
+
}
|
|
3080
|
+
|
|
3081
|
+
// src/react/hooks/use-fx-rate.ts
|
|
3082
|
+
var fxRateQuery = createCachedQuery({
|
|
3083
|
+
name: "useFxRate",
|
|
3084
|
+
key: (client, options) => cacheKey(client.getPublicKey(), options.from, options.to),
|
|
3085
|
+
fetch: async (client, options) => {
|
|
3086
|
+
const result = await client.fx.getRate(options.from, options.to);
|
|
3087
|
+
if (!result.ok) throw result.error;
|
|
3088
|
+
return result.value;
|
|
3089
|
+
}
|
|
3090
|
+
});
|
|
3091
|
+
function useFxRate(options) {
|
|
3092
|
+
const { data, isLoading, error, refetch } = fxRateQuery(options);
|
|
3093
|
+
return { rate: data, isLoading, error, refetch };
|
|
3094
|
+
}
|
|
3095
|
+
|
|
3096
|
+
// src/react/hooks/use-bootstrap.ts
|
|
3097
|
+
var bootstrapQuery = createCachedQuery({
|
|
3098
|
+
name: "useBootstrap",
|
|
3099
|
+
key: (client) => cacheKey(client.getPublicKey()),
|
|
3100
|
+
fetch: async (client) => {
|
|
3101
|
+
const result = await client.business.getBootstrap();
|
|
3102
|
+
if (!result.ok) throw result.error;
|
|
3103
|
+
return result.value;
|
|
3104
|
+
}
|
|
3105
|
+
});
|
|
3106
|
+
function useBootstrap(options = {}) {
|
|
3107
|
+
const { data, isLoading, error, refetch } = bootstrapQuery(options);
|
|
3108
|
+
return { bootstrap: data, isLoading, error, refetch };
|
|
4700
3109
|
}
|
|
4701
3110
|
var ElementsContext = createContext({
|
|
4702
3111
|
elements: null,
|
|
@@ -6877,11 +5286,8 @@ function ProductCard({
|
|
|
6877
5286
|
"div",
|
|
6878
5287
|
{
|
|
6879
5288
|
"data-cimplify-product-card-image-container": true,
|
|
6880
|
-
className: classNames?.imageContainer,
|
|
6881
|
-
style:
|
|
6882
|
-
overflow: "hidden",
|
|
6883
|
-
...ASPECT_STYLES2[aspectRatio]
|
|
6884
|
-
},
|
|
5289
|
+
className: cn("overflow-hidden rounded-t-xl", classNames?.imageContainer),
|
|
5290
|
+
style: ASPECT_STYLES2[aspectRatio],
|
|
6885
5291
|
children: renderImage ? renderImage({
|
|
6886
5292
|
src: imageUrl,
|
|
6887
5293
|
alt: product.name,
|
|
@@ -6891,8 +5297,7 @@ function ProductCard({
|
|
|
6891
5297
|
{
|
|
6892
5298
|
src: imageUrl,
|
|
6893
5299
|
alt: product.name,
|
|
6894
|
-
className: classNames?.image,
|
|
6895
|
-
style: { width: "100%", height: "100%", objectFit: "cover" },
|
|
5300
|
+
className: cn("w-full h-full object-cover transition-transform duration-300 group-hover:scale-105", classNames?.image),
|
|
6896
5301
|
"data-cimplify-product-card-image": true
|
|
6897
5302
|
}
|
|
6898
5303
|
)
|
|
@@ -6902,13 +5307,13 @@ function ProductCard({
|
|
|
6902
5307
|
"div",
|
|
6903
5308
|
{
|
|
6904
5309
|
"data-cimplify-product-card-body": true,
|
|
6905
|
-
className: classNames?.body,
|
|
5310
|
+
className: cn("p-4 flex flex-col gap-1", classNames?.body),
|
|
6906
5311
|
children: [
|
|
6907
5312
|
/* @__PURE__ */ jsx(
|
|
6908
5313
|
"span",
|
|
6909
5314
|
{
|
|
6910
5315
|
"data-cimplify-product-card-name": true,
|
|
6911
|
-
className: classNames?.name,
|
|
5316
|
+
className: cn("font-semibold text-foreground leading-tight", classNames?.name),
|
|
6912
5317
|
children: product.name
|
|
6913
5318
|
}
|
|
6914
5319
|
),
|
|
@@ -6916,13 +5321,7 @@ function ProductCard({
|
|
|
6916
5321
|
"span",
|
|
6917
5322
|
{
|
|
6918
5323
|
"data-cimplify-product-card-description": true,
|
|
6919
|
-
className: classNames?.description,
|
|
6920
|
-
style: {
|
|
6921
|
-
display: "-webkit-box",
|
|
6922
|
-
WebkitLineClamp: 2,
|
|
6923
|
-
WebkitBoxOrient: "vertical",
|
|
6924
|
-
overflow: "hidden"
|
|
6925
|
-
},
|
|
5324
|
+
className: cn("text-sm text-muted-foreground line-clamp-2", classNames?.description),
|
|
6926
5325
|
children: product.description
|
|
6927
5326
|
}
|
|
6928
5327
|
),
|
|
@@ -6930,7 +5329,7 @@ function ProductCard({
|
|
|
6930
5329
|
Price,
|
|
6931
5330
|
{
|
|
6932
5331
|
amount: product.default_price,
|
|
6933
|
-
className: classNames?.price
|
|
5332
|
+
className: cn("text-sm font-medium text-foreground mt-1", classNames?.price)
|
|
6934
5333
|
}
|
|
6935
5334
|
)
|
|
6936
5335
|
]
|
|
@@ -6939,7 +5338,7 @@ function ProductCard({
|
|
|
6939
5338
|
] });
|
|
6940
5339
|
if (mode === "page") {
|
|
6941
5340
|
const linkHref = href ?? `/menu/${product.slug}`;
|
|
6942
|
-
const linkClassName = cn("block no-underline text-[inherit]", className, classNames?.root);
|
|
5341
|
+
const linkClassName = cn("group block no-underline text-[inherit] rounded-xl border border-border bg-background transition-shadow duration-200 hover:shadow-md", className, classNames?.root);
|
|
6943
5342
|
if (renderLink) {
|
|
6944
5343
|
return renderLink({ href: linkHref, className: linkClassName, children: cardBody });
|
|
6945
5344
|
}
|
|
@@ -6962,7 +5361,7 @@ function ProductCard({
|
|
|
6962
5361
|
"data-cimplify-product-card": true,
|
|
6963
5362
|
"data-display-mode": "card",
|
|
6964
5363
|
className: cn(
|
|
6965
|
-
"block w-full text-left
|
|
5364
|
+
"group block w-full text-left p-0 cursor-pointer font-[inherit] text-[inherit] rounded-xl border border-border bg-background transition-shadow duration-200 hover:shadow-md",
|
|
6966
5365
|
className,
|
|
6967
5366
|
classNames?.root
|
|
6968
5367
|
),
|
|
@@ -8296,10 +6695,14 @@ function BookingCard({
|
|
|
8296
6695
|
{
|
|
8297
6696
|
"data-cimplify-booking-card": true,
|
|
8298
6697
|
"data-status": booking.status,
|
|
8299
|
-
className: cn(
|
|
6698
|
+
className: cn(
|
|
6699
|
+
"rounded-xl border border-border bg-background p-4 flex flex-col gap-3",
|
|
6700
|
+
className,
|
|
6701
|
+
classNames?.root
|
|
6702
|
+
),
|
|
8300
6703
|
children: [
|
|
8301
|
-
/* @__PURE__ */ jsxs("div", { "data-cimplify-booking-main": true, children: [
|
|
8302
|
-
/* @__PURE__ */ jsxs("span", { "data-cimplify-booking-service": true, className: classNames?.service, children: [
|
|
6704
|
+
/* @__PURE__ */ jsxs("div", { "data-cimplify-booking-main": true, className: "flex items-center justify-between gap-2", children: [
|
|
6705
|
+
/* @__PURE__ */ jsxs("span", { "data-cimplify-booking-service": true, className: cn("font-semibold text-foreground", classNames?.service), children: [
|
|
8303
6706
|
"Booking #",
|
|
8304
6707
|
booking.order_id.slice(0, 8)
|
|
8305
6708
|
] }),
|
|
@@ -8308,22 +6711,37 @@ function BookingCard({
|
|
|
8308
6711
|
{
|
|
8309
6712
|
"data-cimplify-booking-status": true,
|
|
8310
6713
|
"data-status": booking.status,
|
|
8311
|
-
className:
|
|
6714
|
+
className: cn(
|
|
6715
|
+
"text-xs font-medium px-2 py-0.5 rounded-full",
|
|
6716
|
+
active ? "bg-primary/10 text-primary" : "bg-muted text-muted-foreground",
|
|
6717
|
+
classNames?.status
|
|
6718
|
+
),
|
|
8312
6719
|
children: STATUS_LABELS3[booking.status] ?? booking.status
|
|
8313
6720
|
}
|
|
8314
6721
|
)
|
|
8315
6722
|
] }),
|
|
8316
|
-
firstItem?.confirmation_code && /* @__PURE__ */ jsx("span", { "data-cimplify-booking-code": true, className: classNames?.confirmationCode, children: firstItem.confirmation_code }),
|
|
8317
|
-
scheduledTime && /* @__PURE__ */ jsx(
|
|
8318
|
-
|
|
8319
|
-
|
|
6723
|
+
firstItem?.confirmation_code && /* @__PURE__ */ jsx("span", { "data-cimplify-booking-code": true, className: cn("text-xs font-mono text-muted-foreground tracking-wide", classNames?.confirmationCode), children: firstItem.confirmation_code }),
|
|
6724
|
+
scheduledTime && /* @__PURE__ */ jsx(
|
|
6725
|
+
"time",
|
|
6726
|
+
{
|
|
6727
|
+
"data-cimplify-booking-time": true,
|
|
6728
|
+
dateTime: firstItem?.scheduled_start ?? void 0,
|
|
6729
|
+
className: cn("text-sm text-foreground", classNames?.time),
|
|
6730
|
+
children: scheduledTime
|
|
6731
|
+
}
|
|
6732
|
+
),
|
|
6733
|
+
/* @__PURE__ */ jsx("span", { "data-cimplify-booking-total": true, className: cn("text-sm font-medium text-foreground", classNames?.total), children: /* @__PURE__ */ jsx(Price, { amount: booking.total_price }) }),
|
|
6734
|
+
active && (onCancel || onReschedule) && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-actions": true, className: cn("flex gap-2 pt-1 border-t border-border mt-1", classNames?.actions), children: [
|
|
8320
6735
|
onReschedule && /* @__PURE__ */ jsx(
|
|
8321
6736
|
"button",
|
|
8322
6737
|
{
|
|
8323
6738
|
type: "button",
|
|
8324
6739
|
onClick: () => onReschedule(booking),
|
|
8325
6740
|
"data-cimplify-booking-reschedule": true,
|
|
8326
|
-
className:
|
|
6741
|
+
className: cn(
|
|
6742
|
+
"flex-1 text-sm font-medium py-2 rounded-lg border border-border bg-background text-foreground transition-colors hover:bg-muted cursor-pointer",
|
|
6743
|
+
classNames?.rescheduleButton
|
|
6744
|
+
),
|
|
8327
6745
|
children: "Reschedule"
|
|
8328
6746
|
}
|
|
8329
6747
|
),
|
|
@@ -8333,7 +6751,10 @@ function BookingCard({
|
|
|
8333
6751
|
type: "button",
|
|
8334
6752
|
onClick: () => onCancel(booking),
|
|
8335
6753
|
"data-cimplify-booking-cancel": true,
|
|
8336
|
-
className:
|
|
6754
|
+
className: cn(
|
|
6755
|
+
"flex-1 text-sm font-medium py-2 rounded-lg border border-border bg-background text-destructive transition-colors hover:bg-destructive/10 cursor-pointer",
|
|
6756
|
+
classNames?.cancelButton
|
|
6757
|
+
),
|
|
8337
6758
|
children: "Cancel"
|
|
8338
6759
|
}
|
|
8339
6760
|
)
|
|
@@ -8446,11 +6867,8 @@ function ServiceCard({
|
|
|
8446
6867
|
"div",
|
|
8447
6868
|
{
|
|
8448
6869
|
"data-cimplify-service-card-image-container": true,
|
|
8449
|
-
className: classNames?.imageContainer,
|
|
8450
|
-
style:
|
|
8451
|
-
overflow: "hidden",
|
|
8452
|
-
...ASPECT_STYLES3[aspectRatio]
|
|
8453
|
-
},
|
|
6870
|
+
className: cn("overflow-hidden rounded-t-xl", classNames?.imageContainer),
|
|
6871
|
+
style: ASPECT_STYLES3[aspectRatio],
|
|
8454
6872
|
children: renderImage ? renderImage({
|
|
8455
6873
|
src: imageUrl,
|
|
8456
6874
|
alt: service.name,
|
|
@@ -8460,36 +6878,35 @@ function ServiceCard({
|
|
|
8460
6878
|
{
|
|
8461
6879
|
src: imageUrl,
|
|
8462
6880
|
alt: service.name,
|
|
8463
|
-
className: classNames?.image,
|
|
8464
|
-
style: { width: "100%", height: "100%", objectFit: "cover" },
|
|
6881
|
+
className: cn("w-full h-full object-cover transition-transform duration-300 group-hover:scale-105", classNames?.image),
|
|
8465
6882
|
"data-cimplify-service-card-image": true
|
|
8466
6883
|
}
|
|
8467
6884
|
)
|
|
8468
6885
|
}
|
|
8469
6886
|
),
|
|
8470
|
-
/* @__PURE__ */ jsxs("div", { "data-cimplify-service-card-body": true, className: classNames?.body, children: [
|
|
8471
|
-
/* @__PURE__ */ jsx("span", { "data-cimplify-service-card-name": true, className: classNames?.name, children: service.name }),
|
|
6887
|
+
/* @__PURE__ */ jsxs("div", { "data-cimplify-service-card-body": true, className: cn("p-4 flex flex-col gap-1.5", classNames?.body), children: [
|
|
6888
|
+
/* @__PURE__ */ jsx("span", { "data-cimplify-service-card-name": true, className: cn("font-semibold text-foreground leading-tight", classNames?.name), children: service.name }),
|
|
8472
6889
|
service.description && /* @__PURE__ */ jsx(
|
|
8473
6890
|
"span",
|
|
8474
6891
|
{
|
|
8475
6892
|
"data-cimplify-service-card-description": true,
|
|
8476
|
-
className: classNames?.description,
|
|
8477
|
-
style: {
|
|
8478
|
-
display: "-webkit-box",
|
|
8479
|
-
WebkitLineClamp: 2,
|
|
8480
|
-
WebkitBoxOrient: "vertical",
|
|
8481
|
-
overflow: "hidden"
|
|
8482
|
-
},
|
|
6893
|
+
className: cn("text-sm text-muted-foreground line-clamp-2", classNames?.description),
|
|
8483
6894
|
children: service.description
|
|
8484
6895
|
}
|
|
8485
6896
|
),
|
|
8486
|
-
/* @__PURE__ */ jsxs("div", { "data-cimplify-service-card-meta": true, className: classNames?.meta, children: [
|
|
8487
|
-
/* @__PURE__ */ jsx("span", { "data-cimplify-service-card-duration": true, className: classNames?.duration, children: formatDuration2(service.duration_minutes, service.duration_unit) }),
|
|
8488
|
-
service.price && /* @__PURE__ */ jsx("span", { "data-cimplify-service-card-price": true, className: classNames?.price, children: /* @__PURE__ */ jsx(Price, { amount: service.price }) })
|
|
6897
|
+
/* @__PURE__ */ jsxs("div", { "data-cimplify-service-card-meta": true, className: cn("flex items-center gap-2 mt-1 text-sm", classNames?.meta), children: [
|
|
6898
|
+
/* @__PURE__ */ jsx("span", { "data-cimplify-service-card-duration": true, className: cn("text-muted-foreground", classNames?.duration), children: formatDuration2(service.duration_minutes, service.duration_unit) }),
|
|
6899
|
+
service.price && /* @__PURE__ */ jsx("span", { "data-cimplify-service-card-price": true, className: cn("font-medium text-foreground", classNames?.price), children: /* @__PURE__ */ jsx(Price, { amount: service.price }) })
|
|
8489
6900
|
] })
|
|
8490
6901
|
] }),
|
|
8491
|
-
!href && onBook && /* @__PURE__ */ jsx("span", { "data-cimplify-service-card-action": true, className: classNames?.action, children: actionLabel })
|
|
6902
|
+
!href && onBook && /* @__PURE__ */ jsx("span", { "data-cimplify-service-card-action": true, className: cn("px-4 pb-4 pt-1 text-sm font-medium text-primary", classNames?.action), children: actionLabel })
|
|
8492
6903
|
] });
|
|
6904
|
+
const cardClasses = cn(
|
|
6905
|
+
"group block w-full rounded-xl border border-border bg-background text-left transition-shadow duration-200 hover:shadow-md",
|
|
6906
|
+
!service.is_available && "opacity-60",
|
|
6907
|
+
className,
|
|
6908
|
+
classNames?.root
|
|
6909
|
+
);
|
|
8493
6910
|
if (href) {
|
|
8494
6911
|
return /* @__PURE__ */ jsx(
|
|
8495
6912
|
"a",
|
|
@@ -8497,8 +6914,7 @@ function ServiceCard({
|
|
|
8497
6914
|
href,
|
|
8498
6915
|
"data-cimplify-service-card": true,
|
|
8499
6916
|
"data-available": service.is_available || void 0,
|
|
8500
|
-
className: cn(
|
|
8501
|
-
style: { display: "block", textDecoration: "none", color: "inherit" },
|
|
6917
|
+
className: cn(cardClasses, "no-underline text-[inherit]"),
|
|
8502
6918
|
children: cardBody
|
|
8503
6919
|
}
|
|
8504
6920
|
);
|
|
@@ -8511,18 +6927,7 @@ function ServiceCard({
|
|
|
8511
6927
|
disabled: !service.is_available,
|
|
8512
6928
|
"data-cimplify-service-card": true,
|
|
8513
6929
|
"data-available": service.is_available || void 0,
|
|
8514
|
-
className: cn(
|
|
8515
|
-
style: {
|
|
8516
|
-
display: "block",
|
|
8517
|
-
width: "100%",
|
|
8518
|
-
textAlign: "inherit",
|
|
8519
|
-
background: "none",
|
|
8520
|
-
border: "none",
|
|
8521
|
-
padding: 0,
|
|
8522
|
-
cursor: service.is_available ? "pointer" : "default",
|
|
8523
|
-
font: "inherit",
|
|
8524
|
-
color: "inherit"
|
|
8525
|
-
},
|
|
6930
|
+
className: cn(cardClasses, "cursor-pointer font-[inherit] p-0 border-border"),
|
|
8526
6931
|
children: cardBody
|
|
8527
6932
|
}
|
|
8528
6933
|
);
|
|
@@ -9258,10 +7663,114 @@ function DealsPage({
|
|
|
9258
7663
|
isEmpty && /* @__PURE__ */ jsx("div", { "data-cimplify-deals-empty": true, className: classNames?.empty, children: /* @__PURE__ */ jsx("p", { children: "No deals available right now. Check back soon!" }) })
|
|
9259
7664
|
] });
|
|
9260
7665
|
}
|
|
7666
|
+
var ANY_VALUE2 = "__any__";
|
|
7667
|
+
function roomToResource(room) {
|
|
7668
|
+
return {
|
|
7669
|
+
id: room.id,
|
|
7670
|
+
name: room.name,
|
|
7671
|
+
capacity: room.capacity,
|
|
7672
|
+
floor: room.floor,
|
|
7673
|
+
is_available: room.status === "available"
|
|
7674
|
+
};
|
|
7675
|
+
}
|
|
7676
|
+
function ResourcePicker({
|
|
7677
|
+
resources,
|
|
7678
|
+
selectedResourceId,
|
|
7679
|
+
onResourceSelect,
|
|
7680
|
+
showAnyOption = true,
|
|
7681
|
+
anyLabel = "Any available",
|
|
7682
|
+
renderImage,
|
|
7683
|
+
className,
|
|
7684
|
+
classNames
|
|
7685
|
+
}) {
|
|
7686
|
+
const groupValue = selectedResourceId === null ? ANY_VALUE2 : selectedResourceId ?? "";
|
|
7687
|
+
return /* @__PURE__ */ jsxs(
|
|
7688
|
+
RadioGroup,
|
|
7689
|
+
{
|
|
7690
|
+
"data-cimplify-resource-picker": true,
|
|
7691
|
+
className: cn("flex flex-col gap-2", className, classNames?.root),
|
|
7692
|
+
value: groupValue,
|
|
7693
|
+
onValueChange: (value) => {
|
|
7694
|
+
onResourceSelect?.(value === ANY_VALUE2 ? null : value);
|
|
7695
|
+
},
|
|
7696
|
+
children: [
|
|
7697
|
+
showAnyOption && /* @__PURE__ */ jsx(
|
|
7698
|
+
Radio.Root,
|
|
7699
|
+
{
|
|
7700
|
+
value: ANY_VALUE2,
|
|
7701
|
+
"data-cimplify-resource-option": true,
|
|
7702
|
+
"data-selected": selectedResourceId === null || void 0,
|
|
7703
|
+
"data-any": true,
|
|
7704
|
+
className: cn(
|
|
7705
|
+
"flex items-center gap-3 rounded-lg border border-border p-3 transition-colors cursor-pointer",
|
|
7706
|
+
"hover:bg-muted data-[checked]:border-primary data-[checked]:bg-primary/5",
|
|
7707
|
+
classNames?.option
|
|
7708
|
+
),
|
|
7709
|
+
children: /* @__PURE__ */ jsx("span", { "data-cimplify-resource-name": true, className: cn("font-medium text-foreground", classNames?.name), children: anyLabel })
|
|
7710
|
+
}
|
|
7711
|
+
),
|
|
7712
|
+
resources.map((resource) => {
|
|
7713
|
+
const unavailable = resource.is_available === false;
|
|
7714
|
+
return /* @__PURE__ */ jsxs(
|
|
7715
|
+
Radio.Root,
|
|
7716
|
+
{
|
|
7717
|
+
value: resource.id,
|
|
7718
|
+
disabled: unavailable,
|
|
7719
|
+
"data-cimplify-resource-option": true,
|
|
7720
|
+
"data-selected": selectedResourceId === resource.id || void 0,
|
|
7721
|
+
"data-unavailable": unavailable || void 0,
|
|
7722
|
+
className: cn(
|
|
7723
|
+
"flex items-center gap-3 rounded-lg border border-border p-3 transition-colors cursor-pointer",
|
|
7724
|
+
"hover:bg-muted data-[checked]:border-primary data-[checked]:bg-primary/5",
|
|
7725
|
+
unavailable && "opacity-50 cursor-not-allowed",
|
|
7726
|
+
classNames?.option,
|
|
7727
|
+
unavailable ? classNames?.unavailable : void 0
|
|
7728
|
+
),
|
|
7729
|
+
children: [
|
|
7730
|
+
resource.image_url && (renderImage ? renderImage({
|
|
7731
|
+
src: resource.image_url,
|
|
7732
|
+
alt: resource.name,
|
|
7733
|
+
className: classNames?.image
|
|
7734
|
+
}) : /* @__PURE__ */ jsx(
|
|
7735
|
+
"img",
|
|
7736
|
+
{
|
|
7737
|
+
src: resource.image_url,
|
|
7738
|
+
alt: resource.name,
|
|
7739
|
+
"data-cimplify-resource-image": true,
|
|
7740
|
+
className: cn("w-10 h-10 rounded-lg object-cover", classNames?.image)
|
|
7741
|
+
}
|
|
7742
|
+
)),
|
|
7743
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5 flex-1 min-w-0", children: [
|
|
7744
|
+
/* @__PURE__ */ jsx("span", { "data-cimplify-resource-name": true, className: cn("font-medium text-foreground", classNames?.name), children: resource.name }),
|
|
7745
|
+
resource.description && /* @__PURE__ */ jsx("span", { "data-cimplify-resource-description": true, className: cn("text-sm text-muted-foreground truncate", classNames?.description), children: resource.description }),
|
|
7746
|
+
/* @__PURE__ */ jsxs("div", { "data-cimplify-resource-meta": true, className: cn("flex items-center gap-2 text-xs text-muted-foreground", classNames?.meta), children: [
|
|
7747
|
+
resource.capacity !== void 0 && /* @__PURE__ */ jsxs("span", { "data-cimplify-resource-capacity": true, className: classNames?.capacity, children: [
|
|
7748
|
+
"Up to ",
|
|
7749
|
+
resource.capacity
|
|
7750
|
+
] }),
|
|
7751
|
+
resource.floor && /* @__PURE__ */ jsx("span", { "data-cimplify-resource-floor": true, className: classNames?.floor, children: resource.floor })
|
|
7752
|
+
] })
|
|
7753
|
+
] })
|
|
7754
|
+
]
|
|
7755
|
+
},
|
|
7756
|
+
resource.id
|
|
7757
|
+
);
|
|
7758
|
+
})
|
|
7759
|
+
]
|
|
7760
|
+
}
|
|
7761
|
+
);
|
|
7762
|
+
}
|
|
7763
|
+
var STEP = {
|
|
7764
|
+
SELECT_SLOT: "select-slot",
|
|
7765
|
+
SELECT_RESOURCE: "select-resource",
|
|
7766
|
+
SELECT_STAFF: "select-staff",
|
|
7767
|
+
CONFIRM: "confirm"
|
|
7768
|
+
};
|
|
9261
7769
|
function BookingPage({
|
|
9262
7770
|
service,
|
|
9263
7771
|
product,
|
|
9264
7772
|
staff,
|
|
7773
|
+
resources,
|
|
9265
7774
|
participantCount,
|
|
9266
7775
|
title,
|
|
9267
7776
|
onBooked,
|
|
@@ -9275,12 +7784,14 @@ function BookingPage({
|
|
|
9275
7784
|
const { addItem } = useCart();
|
|
9276
7785
|
const { client } = useCimplifyClient();
|
|
9277
7786
|
const isReschedule = existingBooking !== void 0;
|
|
9278
|
-
const [step, setStep] = useState(
|
|
7787
|
+
const [step, setStep] = useState(STEP.SELECT_SLOT);
|
|
9279
7788
|
const [selectedSlot, setSelectedSlot] = useState(null);
|
|
9280
7789
|
const [selectedDate, setSelectedDate] = useState(null);
|
|
9281
7790
|
const [selectedStaffId, setSelectedStaffId] = useState(null);
|
|
7791
|
+
const [selectedResourceId, setSelectedResourceId] = useState(null);
|
|
9282
7792
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
9283
7793
|
const [error, setError] = useState(null);
|
|
7794
|
+
const hasResourceStep = resources && resources.length > 0;
|
|
9284
7795
|
const hasStaffStep = staff && staff.length > 0;
|
|
9285
7796
|
const depositType = product?.deposit_type;
|
|
9286
7797
|
const depositAmount = product?.deposit_amount;
|
|
@@ -9292,28 +7803,45 @@ function BookingPage({
|
|
|
9292
7803
|
setSelectedSlot(slot);
|
|
9293
7804
|
setSelectedDate(date);
|
|
9294
7805
|
setError(null);
|
|
7806
|
+
if (hasResourceStep) {
|
|
7807
|
+
setStep(STEP.SELECT_RESOURCE);
|
|
7808
|
+
} else if (hasStaffStep) {
|
|
7809
|
+
setStep(STEP.SELECT_STAFF);
|
|
7810
|
+
} else {
|
|
7811
|
+
setStep(STEP.CONFIRM);
|
|
7812
|
+
}
|
|
7813
|
+
},
|
|
7814
|
+
[hasResourceStep, hasStaffStep]
|
|
7815
|
+
);
|
|
7816
|
+
const handleResourceSelect = useCallback(
|
|
7817
|
+
(resourceId) => {
|
|
7818
|
+
setSelectedResourceId(resourceId);
|
|
9295
7819
|
if (hasStaffStep) {
|
|
9296
|
-
setStep(
|
|
7820
|
+
setStep(STEP.SELECT_STAFF);
|
|
9297
7821
|
} else {
|
|
9298
|
-
setStep(
|
|
7822
|
+
setStep(STEP.CONFIRM);
|
|
9299
7823
|
}
|
|
9300
7824
|
},
|
|
9301
7825
|
[hasStaffStep]
|
|
9302
7826
|
);
|
|
9303
7827
|
const handleStaffSelect = useCallback((staffId) => {
|
|
9304
7828
|
setSelectedStaffId(staffId);
|
|
9305
|
-
setStep(
|
|
7829
|
+
setStep(STEP.CONFIRM);
|
|
9306
7830
|
}, []);
|
|
9307
7831
|
const handleBack = useCallback(() => {
|
|
9308
7832
|
setError(null);
|
|
9309
|
-
if (step ===
|
|
9310
|
-
setStep(
|
|
9311
|
-
} else if (step ===
|
|
9312
|
-
setStep(
|
|
7833
|
+
if (step === STEP.CONFIRM && hasStaffStep) {
|
|
7834
|
+
setStep(STEP.SELECT_STAFF);
|
|
7835
|
+
} else if (step === STEP.CONFIRM && hasResourceStep) {
|
|
7836
|
+
setStep(STEP.SELECT_RESOURCE);
|
|
7837
|
+
} else if (step === STEP.SELECT_STAFF && hasResourceStep) {
|
|
7838
|
+
setStep(STEP.SELECT_RESOURCE);
|
|
7839
|
+
} else if (step === STEP.CONFIRM || step === STEP.SELECT_STAFF || step === STEP.SELECT_RESOURCE) {
|
|
7840
|
+
setStep(STEP.SELECT_SLOT);
|
|
9313
7841
|
} else {
|
|
9314
7842
|
onBack?.();
|
|
9315
7843
|
}
|
|
9316
|
-
}, [step, hasStaffStep, onBack]);
|
|
7844
|
+
}, [step, hasStaffStep, hasResourceStep, onBack]);
|
|
9317
7845
|
const handleConfirm = useCallback(async () => {
|
|
9318
7846
|
if (!selectedSlot || !selectedDate) return;
|
|
9319
7847
|
setIsSubmitting(true);
|
|
@@ -9353,7 +7881,8 @@ function BookingPage({
|
|
|
9353
7881
|
await addItem(serviceProduct, 1, {
|
|
9354
7882
|
scheduledStart: selectedSlot.start_time,
|
|
9355
7883
|
scheduledEnd: selectedSlot.end_time,
|
|
9356
|
-
staffId: selectedStaffId || void 0
|
|
7884
|
+
staffId: selectedStaffId || void 0,
|
|
7885
|
+
resourceId: selectedResourceId || void 0
|
|
9357
7886
|
});
|
|
9358
7887
|
onBooked?.(selectedSlot, selectedStaffId);
|
|
9359
7888
|
}
|
|
@@ -9366,7 +7895,7 @@ function BookingPage({
|
|
|
9366
7895
|
}, [selectedSlot, selectedDate, selectedStaffId, service, addItem, onBooked, isReschedule, existingBooking, client, onRescheduled]);
|
|
9367
7896
|
return /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-page": true, className: cn(className, classNames?.root), children: [
|
|
9368
7897
|
/* @__PURE__ */ jsxs("div", { "data-cimplify-booking-page-header": true, className: classNames?.header, children: [
|
|
9369
|
-
onBack && step ===
|
|
7898
|
+
onBack && step === STEP.SELECT_SLOT && /* @__PURE__ */ jsx(
|
|
9370
7899
|
"button",
|
|
9371
7900
|
{
|
|
9372
7901
|
type: "button",
|
|
@@ -9376,7 +7905,7 @@ function BookingPage({
|
|
|
9376
7905
|
children: "Back"
|
|
9377
7906
|
}
|
|
9378
7907
|
),
|
|
9379
|
-
step !==
|
|
7908
|
+
step !== STEP.SELECT_SLOT && /* @__PURE__ */ jsx(
|
|
9380
7909
|
"button",
|
|
9381
7910
|
{
|
|
9382
7911
|
type: "button",
|
|
@@ -9411,7 +7940,7 @@ function BookingPage({
|
|
|
9411
7940
|
] })
|
|
9412
7941
|
] }),
|
|
9413
7942
|
error && /* @__PURE__ */ jsx("div", { "data-cimplify-booking-error": true, className: classNames?.error, children: error }),
|
|
9414
|
-
step ===
|
|
7943
|
+
step === STEP.SELECT_SLOT && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-step": "select-slot", className: classNames?.step, children: [
|
|
9415
7944
|
/* @__PURE__ */ jsx("h2", { "data-cimplify-booking-step-title": true, className: classNames?.stepTitle, children: "Select a date & time" }),
|
|
9416
7945
|
/* @__PURE__ */ jsx(
|
|
9417
7946
|
DateSlotPicker,
|
|
@@ -9424,7 +7953,18 @@ function BookingPage({
|
|
|
9424
7953
|
}
|
|
9425
7954
|
)
|
|
9426
7955
|
] }),
|
|
9427
|
-
step ===
|
|
7956
|
+
step === STEP.SELECT_RESOURCE && resources && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-step": "select-resource", className: cn(classNames?.step, classNames?.resourceStep), children: [
|
|
7957
|
+
/* @__PURE__ */ jsx("h2", { "data-cimplify-booking-step-title": true, className: classNames?.stepTitle, children: "Choose a room" }),
|
|
7958
|
+
/* @__PURE__ */ jsx(
|
|
7959
|
+
ResourcePicker,
|
|
7960
|
+
{
|
|
7961
|
+
resources,
|
|
7962
|
+
selectedResourceId,
|
|
7963
|
+
onResourceSelect: handleResourceSelect
|
|
7964
|
+
}
|
|
7965
|
+
)
|
|
7966
|
+
] }),
|
|
7967
|
+
step === STEP.SELECT_STAFF && staff && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-step": "select-staff", className: classNames?.step, children: [
|
|
9428
7968
|
/* @__PURE__ */ jsx("h2", { "data-cimplify-booking-step-title": true, className: classNames?.stepTitle, children: "Choose a provider" }),
|
|
9429
7969
|
/* @__PURE__ */ jsx(
|
|
9430
7970
|
StaffPicker,
|
|
@@ -9435,7 +7975,7 @@ function BookingPage({
|
|
|
9435
7975
|
}
|
|
9436
7976
|
)
|
|
9437
7977
|
] }),
|
|
9438
|
-
step ===
|
|
7978
|
+
step === STEP.CONFIRM && selectedSlot && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-step": "confirm", className: classNames?.step, children: [
|
|
9439
7979
|
/* @__PURE__ */ jsx("h2", { "data-cimplify-booking-step-title": true, className: classNames?.stepTitle, children: "Confirm your booking" }),
|
|
9440
7980
|
/* @__PURE__ */ jsxs("div", { "data-cimplify-booking-summary": true, className: classNames?.summary, children: [
|
|
9441
7981
|
/* @__PURE__ */ jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
|
|
@@ -9457,6 +7997,10 @@ function BookingPage({
|
|
|
9457
7997
|
/* @__PURE__ */ jsx("span", { children: "Duration" }),
|
|
9458
7998
|
/* @__PURE__ */ jsx("span", { children: formatDuration2(service.duration_minutes, service.duration_unit) })
|
|
9459
7999
|
] }),
|
|
8000
|
+
selectedResourceId && resources && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
|
|
8001
|
+
/* @__PURE__ */ jsx("span", { children: "Room" }),
|
|
8002
|
+
/* @__PURE__ */ jsx("span", { children: resources.find((r) => r.id === selectedResourceId)?.name ?? "Selected" })
|
|
8003
|
+
] }),
|
|
9460
8004
|
selectedStaffId && staff && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
|
|
9461
8005
|
/* @__PURE__ */ jsx("span", { children: "Provider" }),
|
|
9462
8006
|
/* @__PURE__ */ jsx("span", { children: staff.find((s) => s.id === selectedStaffId)?.name ?? "Selected" })
|
|
@@ -10025,4 +8569,4 @@ function CurrencySelector({
|
|
|
10025
8569
|
}) });
|
|
10026
8570
|
}
|
|
10027
8571
|
|
|
10028
|
-
export { Ad, AdProvider, AddOnSelector, AddressElement, AuthElement, AvailabilityBadge, BillingPlanSelector, BookingCard, BookingList, BookingPage, BookingsPage, BundleSelector, CartPage, CartSummary, CataloguePage, CategoryFilter, CategoryGrid, CheckoutPage, CimplifyCheckout, CimplifyProvider, CollectionPage, CompositeSelector, CurrencySelector, DateSlotPicker, DealBanner, DealsPage, DeliveryEstimate, DiscountInput, ElementsProvider, LocationPicker, OrderDetailPage, OrderHistory, OrderHistoryPage, OrderSummary, PaymentElement, Price, ProductCard, ProductCustomizer, ProductGrid, ProductImageGallery, ProductPage, ProductSheet, QuantitySelector, RecentlyViewed, RecommendationCarousel, SaleBadge, SearchInput, SearchPage, ServiceCard, ServiceGrid, SessionMessageBanner, SlotPicker, StaffPicker, StoreNav, VariantSelector, cn, useActivityState, useAds, useAttributeDefinitions, useAvailableSlots, useBillingPlans, useBookings, useBootstrap, useBundles, useCart, useCategories, useCheckout, useCimplify, useCimplifyClient, useCollection, useCollections, useDeals, useDeliveryFee, useElements, useElementsReady, useFxRate, useLocations, useOptionalCimplify, useOrder, useOrders, useProduct, useProductAvailability, useProductDeals, useProductPrice, useProductSchedules, useProducts, useProductsOnSale, usePropertyFacets, useQuote, useRecommendations, useSearch, useServiceAvailability, useServices, useTaxonomies, useTaxonomy, useTaxonomyPath, useValidateDiscount, useVariantSelector };
|
|
8572
|
+
export { Ad, AdProvider, AddOnSelector, AddressElement, AuthElement, AvailabilityBadge, BillingPlanSelector, BookingCard, BookingList, BookingPage, BookingsPage, BundleSelector, CartPage, CartSummary, CataloguePage, CategoryFilter, CategoryGrid, CheckoutPage, CimplifyCheckout, CimplifyProvider, CollectionPage, CompositeSelector, CurrencySelector, DateSlotPicker, DealBanner, DealsPage, DeliveryEstimate, DiscountInput, ElementsProvider, LocationPicker, OrderDetailPage, OrderHistory, OrderHistoryPage, OrderSummary, PaymentElement, Price, ProductCard, ProductCustomizer, ProductGrid, ProductImageGallery, ProductPage, ProductSheet, QuantitySelector, RecentlyViewed, RecommendationCarousel, ResourcePicker, SaleBadge, SearchInput, SearchPage, ServiceCard, ServiceGrid, SessionMessageBanner, SlotPicker, StaffPicker, StoreNav, VariantSelector, cn, roomToResource, useActivityState, useAds, useAttributeDefinitions, useAvailableSlots, useBillingPlans, useBookings, useBootstrap, useBundles, useCart, useCategories, useCheckout, useCimplify, useCimplifyClient, useCollection, useCollections, useDeals, useDeliveryFee, useElements, useElementsReady, useFxRate, useLocations, useOptionalCimplify, useOrder, useOrders, useProduct, useProductAvailability, useProductDeals, useProductPrice, useProductSchedules, useProducts, useProductsOnSale, usePropertyFacets, useQuote, useRecommendations, useSearch, useServiceAvailability, useServices, useTaxonomies, useTaxonomy, useTaxonomyPath, useValidateDiscount, useVariantSelector };
|