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