@fluid-app/portal-sdk 0.1.162 → 0.1.164

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/dist/{MySiteScreen-g8Esyofu.mjs → MySiteScreen-CG2DnzQH.mjs} +2 -2
  2. package/dist/{MySiteScreen-g8Esyofu.mjs.map → MySiteScreen-CG2DnzQH.mjs.map} +1 -1
  3. package/dist/{MySiteScreen-Cos0jTa_.cjs → MySiteScreen-DRMrEMEI.cjs} +2 -2
  4. package/dist/{MySiteScreen-Xcg07a3M.cjs → MySiteScreen-Lr2SbrXz.cjs} +2 -2
  5. package/dist/{MySiteScreen-Xcg07a3M.cjs.map → MySiteScreen-Lr2SbrXz.cjs.map} +1 -1
  6. package/dist/{OrdersScreen-DZyOBKmU.cjs → OrdersScreen-B6n41CbG.cjs} +1 -1
  7. package/dist/{OrdersScreen-ZGUm8buk.cjs → OrdersScreen-BKCQdz5A.cjs} +55 -56
  8. package/dist/OrdersScreen-BKCQdz5A.cjs.map +1 -0
  9. package/dist/{OrdersScreen-DeLoyVGI.mjs → OrdersScreen-CFRVfzez.mjs} +55 -56
  10. package/dist/OrdersScreen-CFRVfzez.mjs.map +1 -0
  11. package/dist/{use-portal-shareables-api-DRK9Y5dp.mjs → PortalContentApiProvider-CW0ADhPi.mjs} +285 -94
  12. package/dist/PortalContentApiProvider-CW0ADhPi.mjs.map +1 -0
  13. package/dist/{use-portal-shareables-api-DcjYlAOy.cjs → PortalContentApiProvider-Di5emtYd.cjs} +290 -129
  14. package/dist/PortalContentApiProvider-Di5emtYd.cjs.map +1 -0
  15. package/dist/PortalProductsApiProvider-BCXX9NGK.mjs +780 -0
  16. package/dist/PortalProductsApiProvider-BCXX9NGK.mjs.map +1 -0
  17. package/dist/PortalProductsApiProvider-BquMHwvt.cjs +816 -0
  18. package/dist/PortalProductsApiProvider-BquMHwvt.cjs.map +1 -0
  19. package/dist/{ProductsScreen-B2SKzTE4.cjs → ProductsScreen-C6eNgxjP.cjs} +4 -3
  20. package/dist/{ProductsScreen-D6eoU86k.mjs → ProductsScreen-CVNJudq9.mjs} +39 -44
  21. package/dist/ProductsScreen-CVNJudq9.mjs.map +1 -0
  22. package/dist/{ProductsScreen-DbwSCY7G.cjs → ProductsScreen-KjjhlDGo.cjs} +39 -44
  23. package/dist/ProductsScreen-KjjhlDGo.cjs.map +1 -0
  24. package/dist/{ProductsScreen-BGah2tcD.mjs → ProductsScreen-nHmUftQn.mjs} +4 -3
  25. package/dist/{ShareablesScreen-DRUT-yoi.mjs → ShareablesScreen-CdTyyDRO.mjs} +4 -3
  26. package/dist/{ShareablesScreen-Dy04EXe5.cjs → ShareablesScreen-DUzo8kRi.cjs} +4 -3
  27. package/dist/ShareablesScreen-DpEP_6u0.mjs +132 -0
  28. package/dist/ShareablesScreen-DpEP_6u0.mjs.map +1 -0
  29. package/dist/ShareablesScreen-Dz8w2l3e.cjs +144 -0
  30. package/dist/ShareablesScreen-Dz8w2l3e.cjs.map +1 -0
  31. package/dist/{ShopScreen-CQ48b1c8.mjs → ShopScreen-BH6zQndJ.mjs} +10 -724
  32. package/dist/ShopScreen-BH6zQndJ.mjs.map +1 -0
  33. package/dist/{ShopScreen-CFqoT4IC.cjs → ShopScreen-BUXUtEuj.cjs} +13 -727
  34. package/dist/ShopScreen-BUXUtEuj.cjs.map +1 -0
  35. package/dist/{ShopScreen-B7faQx84.cjs → ShopScreen-BbucUNI7.cjs} +2 -1
  36. package/dist/{SubscriptionsScreen-C2iORyT_.cjs → SubscriptionsScreen-BdGF5OLE.cjs} +408 -409
  37. package/dist/SubscriptionsScreen-BdGF5OLE.cjs.map +1 -0
  38. package/dist/{SubscriptionsScreen-ClWrrqPK.cjs → SubscriptionsScreen-Cwa2lR1D.cjs} +1 -1
  39. package/dist/{SubscriptionsScreen-BfdK8067.mjs → SubscriptionsScreen-Dn3AEUJi.mjs} +408 -409
  40. package/dist/SubscriptionsScreen-Dn3AEUJi.mjs.map +1 -0
  41. package/dist/{dist-lO2OG0T5.cjs → dist-BF_4vk1z.cjs} +1 -1
  42. package/dist/{dist-lO2OG0T5.cjs.map → dist-BF_4vk1z.cjs.map} +1 -1
  43. package/dist/index.cjs +21 -20
  44. package/dist/index.cjs.map +1 -1
  45. package/dist/index.d.cts.map +1 -1
  46. package/dist/index.d.mts.map +1 -1
  47. package/dist/index.mjs +21 -20
  48. package/dist/index.mjs.map +1 -1
  49. package/dist/{sortable.esm-DSrWP4x9.mjs → sortable.esm-E6JdQn7I.mjs} +1 -1
  50. package/dist/{sortable.esm-DSrWP4x9.mjs.map → sortable.esm-E6JdQn7I.mjs.map} +1 -1
  51. package/package.json +17 -17
  52. package/dist/OrdersScreen-DeLoyVGI.mjs.map +0 -1
  53. package/dist/OrdersScreen-ZGUm8buk.cjs.map +0 -1
  54. package/dist/ProductsScreen-D6eoU86k.mjs.map +0 -1
  55. package/dist/ProductsScreen-DbwSCY7G.cjs.map +0 -1
  56. package/dist/ShareablesScreen-DPHZMh-V.cjs +0 -391
  57. package/dist/ShareablesScreen-DPHZMh-V.cjs.map +0 -1
  58. package/dist/ShareablesScreen-DrQDQ1-U.mjs +0 -379
  59. package/dist/ShareablesScreen-DrQDQ1-U.mjs.map +0 -1
  60. package/dist/ShopScreen-CFqoT4IC.cjs.map +0 -1
  61. package/dist/ShopScreen-CQ48b1c8.mjs.map +0 -1
  62. package/dist/SubscriptionsScreen-BfdK8067.mjs.map +0 -1
  63. package/dist/SubscriptionsScreen-C2iORyT_.cjs.map +0 -1
  64. package/dist/use-portal-products-client-BUFD20ZY.mjs +0 -65
  65. package/dist/use-portal-products-client-BUFD20ZY.mjs.map +0 -1
  66. package/dist/use-portal-products-client-DTkFvOal.cjs +0 -71
  67. package/dist/use-portal-products-client-DTkFvOal.cjs.map +0 -1
  68. package/dist/use-portal-shareables-api-DRK9Y5dp.mjs.map +0 -1
  69. package/dist/use-portal-shareables-api-DcjYlAOy.cjs.map +0 -1
@@ -4,723 +4,13 @@ const require_src = require("./src-BvDb-3SK.cjs");
4
4
  const require_ScreenHeaderContext = require("./ScreenHeaderContext-DRIKmM2G.cjs");
5
5
  const require_AppNavigationContext = require("./AppNavigationContext-BiYNDj_X.cjs");
6
6
  const require_SearchSort = require("./SearchSort-CYhjl8tC.cjs");
7
- const require_use_portal_products_client = require("./use-portal-products-client-DTkFvOal.cjs");
7
+ const require_PortalProductsApiProvider = require("./PortalProductsApiProvider-BquMHwvt.cjs");
8
8
  let react = require("react");
9
9
  react = require_chunk.__toESM(react);
10
10
  let _tanstack_react_query = require("@tanstack/react-query");
11
11
  let react_jsx_runtime = require("react/jsx-runtime");
12
12
  let lucide_react = require("lucide-react");
13
13
  let react_dom = require("react-dom");
14
- let zustand = require("zustand");
15
- let zustand_middleware = require("zustand/middleware");
16
- (0, react.createContext)(null);
17
- //#endregion
18
- //#region ../../products/core/src/portal-products-api-context.tsx
19
- const PortalProductsCoreContext = (0, react.createContext)(null);
20
- function PortalProductsCoreProvider({ api, children }) {
21
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PortalProductsCoreContext.Provider, {
22
- value: { api },
23
- children
24
- });
25
- }
26
- function usePortalProductsApi() {
27
- const ctx = (0, react.useContext)(PortalProductsCoreContext);
28
- if (!ctx) throw new Error("usePortalProductsApi must be used within a <PortalProductsCoreProvider>");
29
- return ctx.api;
30
- }
31
- //#endregion
32
- //#region ../../products/core/src/hooks/use-debounce.ts
33
- function useDebounce(value, delay) {
34
- const [debouncedValue, setDebouncedValue] = (0, react.useState)(value);
35
- (0, react.useEffect)(() => {
36
- const timer = setTimeout(() => {
37
- setDebouncedValue(value);
38
- }, delay);
39
- return () => {
40
- clearTimeout(timer);
41
- };
42
- }, [value, delay]);
43
- return debouncedValue;
44
- }
45
- //#endregion
46
- //#region ../../products/core/src/hooks/use-portal-products.ts
47
- const portalProductKeys = {
48
- all: ["portal-products"],
49
- list: (params) => [
50
- ...portalProductKeys.all,
51
- "list",
52
- params
53
- ],
54
- detail: (id) => [
55
- ...portalProductKeys.all,
56
- "detail",
57
- String(id)
58
- ],
59
- search: (query, params) => [
60
- ...portalProductKeys.all,
61
- "search",
62
- query,
63
- params
64
- ],
65
- media: (productId) => [
66
- ...portalProductKeys.all,
67
- "media",
68
- String(productId)
69
- ]
70
- };
71
- function usePortalProduct(id, options) {
72
- const api = usePortalProductsApi();
73
- return (0, _tanstack_react_query.useQuery)({
74
- queryKey: portalProductKeys.detail(id),
75
- queryFn: () => api.getProduct(id),
76
- enabled: options?.enabled
77
- });
78
- }
79
- //#endregion
80
- //#region ../../products/core/src/hooks/use-portal-product-catalog.ts
81
- function usePortalProductCatalog({ perPage = 25 } = {}) {
82
- const api = usePortalProductsApi();
83
- const [searchTerm, setSearchTerm] = (0, react.useState)("");
84
- const debouncedSearchTerm = useDebounce(searchTerm, 300);
85
- const [currentSort, setCurrentSort] = (0, react.useState)("created_at_desc");
86
- return {
87
- searchTerm,
88
- setSearchTerm,
89
- debouncedSearchTerm,
90
- currentSort,
91
- setCurrentSort,
92
- fetchProducts: (0, react.useCallback)(async (pageParam) => {
93
- const cursor = pageParam;
94
- if (debouncedSearchTerm) return api.searchProducts(debouncedSearchTerm, {
95
- cursor,
96
- limit: perPage,
97
- sort: currentSort
98
- });
99
- return api.listProducts({
100
- cursor,
101
- limit: perPage,
102
- sort: currentSort
103
- });
104
- }, [
105
- api,
106
- debouncedSearchTerm,
107
- perPage,
108
- currentSort
109
- ]),
110
- getNextPageParam: (0, react.useCallback)((lastPage, _allPages, lastPageParam) => {
111
- const nextCursor = lastPage.meta?.pagination?.next_cursor ?? void 0;
112
- if (nextCursor != null && nextCursor === lastPageParam) return;
113
- return nextCursor;
114
- }, []),
115
- queryKey: (0, react.useMemo)(() => [
116
- "portal-product-catalog",
117
- debouncedSearchTerm || "",
118
- perPage,
119
- currentSort
120
- ], [
121
- debouncedSearchTerm,
122
- perPage,
123
- currentSort
124
- ]),
125
- perPage
126
- };
127
- }
128
- //#endregion
129
- //#region ../../products/core/src/hooks/use-portal-product-detail.ts
130
- function usePortalProductDetail({ productId }) {
131
- const { data: productResponse, isLoading, error } = usePortalProduct(productId);
132
- const product = productResponse?.product;
133
- return {
134
- product,
135
- isLoading,
136
- error,
137
- images: (0, react.useMemo)(() => {
138
- if (!product?.images) return [];
139
- return product.images.map((img, idx) => ({
140
- id: idx,
141
- url: img.url ?? "",
142
- alt: img.alt ?? null
143
- }));
144
- }, [product?.images])
145
- };
146
- }
147
- //#endregion
148
- //#region ../../products/core/src/utils/subscription-plans.ts
149
- function ensureDefaultSubscriptionPlan(plans) {
150
- const activePlans = plans.filter((plan) => plan.active !== false);
151
- if (activePlans.length === 0) return plans.map((plan) => ({
152
- ...plan,
153
- default: false
154
- }));
155
- if (!activePlans.some((plan) => plan.default === true)) {
156
- const planWithLowestId = activePlans.reduce((lowest, current) => {
157
- const lowestId = lowest.subscription_plan?.id || Infinity;
158
- return (current.subscription_plan?.id || Infinity) < lowestId ? current : lowest;
159
- });
160
- return plans.map((plan) => ({
161
- ...plan,
162
- default: plan.subscription_plan?.id === planWithLowestId.subscription_plan?.id && plan.active !== false
163
- }));
164
- }
165
- return plans.map((plan) => ({
166
- ...plan,
167
- default: plan.active !== false ? plan.default : false
168
- }));
169
- }
170
- function plansToAttributes(plans) {
171
- return plans.map((plan) => ({
172
- id: plan.id ?? void 0,
173
- subscription_plan_id: plan.subscription_plan.id,
174
- default: plan.default || false,
175
- active: plan.active !== false
176
- }));
177
- }
178
- //#endregion
179
- //#region ../../products/core/src/stores/use-product-store.ts
180
- const defaultState = {
181
- id: void 0,
182
- title: "",
183
- description: "",
184
- introduction: "",
185
- stripped: "",
186
- feature_text: "",
187
- sku: "",
188
- slug: "",
189
- canonical_url: null,
190
- image_url: "",
191
- image_path: void 0,
192
- status: "draft",
193
- publish_at: null,
194
- price: "0",
195
- commission: 0,
196
- public: true,
197
- no_index: false,
198
- show_reviews: true,
199
- publish_to_retail_store: true,
200
- publish_to_rep_store: true,
201
- publish_to_share_tab: true,
202
- collection_ids: [],
203
- tag_ids: [],
204
- images_attributes: [],
205
- product_subscription_plans_attributes: [],
206
- product_subscription_plans: [],
207
- variants_attributes: [],
208
- bundle: false,
209
- track_inventory_on_bundle_items: false,
210
- product_bundles_attributes: [],
211
- option_attrs: [],
212
- options: [],
213
- metafields_attributes: [],
214
- metadata: {},
215
- search_engine_optimizer_attributes: {
216
- title: "",
217
- description: "",
218
- image_url: "",
219
- image_path: "",
220
- block_crawler: false
221
- }
222
- };
223
- function syncSubscriptionPlans(plans) {
224
- const plansWithDefault = plans.filter((plan) => plan.active !== false).length > 0 ? ensureDefaultSubscriptionPlan(plans) : plans;
225
- return {
226
- product_subscription_plans: plansWithDefault,
227
- product_subscription_plans_attributes: plansToAttributes(plansWithDefault)
228
- };
229
- }
230
- const extractFilenameFromUrl = (imageUrl) => {
231
- try {
232
- return new URL(imageUrl).pathname.split("/").pop() || "";
233
- } catch {
234
- return imageUrl.split("/").pop()?.split("?")[0] || "";
235
- }
236
- };
237
- const createProductStore = (set, get) => ({
238
- ...defaultState,
239
- track_inventory_on_bundle_items: false,
240
- translations: {},
241
- editedTranslations: {},
242
- translationErrors: {},
243
- translationLoading: {},
244
- translationsFetched: false,
245
- errors: {},
246
- isValid: false,
247
- isDirty: false,
248
- setProduct: (productData) => {
249
- set({
250
- id: productData.id || void 0,
251
- title: productData.title || "",
252
- description: productData.description || "",
253
- introduction: productData.introduction || "",
254
- stripped: productData.stripped || "",
255
- feature_text: productData.feature_text || "",
256
- sku: productData.sku || "",
257
- slug: productData.slug || "",
258
- canonical_url: productData.canonical_url || null,
259
- custom_slug: productData.custom_slug || false,
260
- image_url: productData.image_url || "",
261
- image_path: productData.image_path && !productData.image_path.includes("undefined") ? productData.image_path : productData.image_url ? extractFilenameFromUrl(productData.image_url) : void 0,
262
- status: productData.status || "draft",
263
- publish_at: productData.publish_at || null,
264
- commission: typeof productData.commission === "string" ? parseFloat(productData.commission) : productData.commission || 0,
265
- public: productData.public ?? true,
266
- no_index: productData.no_index ?? false,
267
- show_reviews: productData.show_reviews ?? true,
268
- publish_to_retail_store: productData.publish_to_retail_store,
269
- publish_to_rep_store: productData.publish_to_rep_store,
270
- publish_to_share_tab: productData.publish_to_share_tab,
271
- ...productData.tax_category_id && { tax_category_id: productData.tax_category_id },
272
- international_tax_type: productData.international_tax_type || void 0,
273
- category_id: productData.category_id ? parseInt(productData.category_id) : productData.category?.id ? productData.category.id : void 0,
274
- application_theme_template_id: productData.application_theme_template_id || void 0,
275
- collection_ids: productData.collections?.map((collection) => collection.id),
276
- tag_ids: Array.isArray(productData.tags) ? productData.tags.map((tag) => typeof tag === "number" ? tag : tag?.id).filter(Boolean) : [],
277
- search_engine_optimizer_attributes: {
278
- id: productData.search_engine_optimizer?.id,
279
- title: productData.search_engine_optimizer?.title || productData.title || void 0,
280
- description: productData.search_engine_optimizer?.description || "",
281
- image_url: productData.search_engine_optimizer?.image_url || productData.image_url || "",
282
- image_path: productData.search_engine_optimizer?.image_path || productData.image_path || "",
283
- block_crawler: productData.search_engine_optimizer?.block_crawler ?? false
284
- },
285
- images_attributes: productData.images?.map((img) => ({
286
- id: img.id,
287
- position: img.position || 0,
288
- image_url: img.image_url,
289
- image_path: img.image_path && !img.image_path.includes("undefined") ? img.image_path : img.image_url ? extractFilenameFromUrl(img.image_url) : void 0,
290
- _destroy: false
291
- })) || [],
292
- ...productData.images && productData.images.length > 0 && { image_path: (() => {
293
- if (productData.image_path && typeof productData.image_path === "string" && !productData.image_path.includes("undefined")) return productData.image_path;
294
- const firstImage = productData.images.find((img) => img.position === 0);
295
- if (firstImage?.image_path && typeof firstImage.image_path === "string" && !firstImage.image_path.includes("undefined")) return firstImage.image_path;
296
- return productData.image_url ? extractFilenameFromUrl(productData.image_url) : void 0;
297
- })() },
298
- product_subscription_plans: (() => {
299
- const plans = productData?.product_subscription_plans?.map((plan) => ({
300
- ...plan,
301
- active: plan?.active
302
- })) || [];
303
- return plans.length > 0 ? ensureDefaultSubscriptionPlan(plans) : plans;
304
- })(),
305
- product_subscription_plans_attributes: (() => {
306
- const plans = productData?.product_subscription_plans?.map((plan) => ({
307
- ...plan,
308
- active: plan?.active
309
- })) || [];
310
- return plansToAttributes(plans.length > 0 ? ensureDefaultSubscriptionPlan(plans) : plans);
311
- })(),
312
- variants_attributes: productData?.variants?.filter((variant) => variant.id !== null && variant.id !== void 0).map((variant) => ({
313
- id: variant.id,
314
- title: variant.title ?? productData?.title ?? "Untitled Variant",
315
- option_attrs: variant.option_attrs || [],
316
- sku: variant.sku || void 0,
317
- price: variant.price,
318
- track_quantity: variant.track_quantity ?? false,
319
- keep_selling: variant.keep_selling ?? false,
320
- bar_code: variant.bar_code ?? "",
321
- limit_subscription: variant.limit_subscription,
322
- subscription_max_qty: variant.subscription_max_qty ?? 0,
323
- customer_limit: variant.customer_limit ?? 0,
324
- is_master: variant.is_master,
325
- _destroy: false,
326
- images_attributes: variant?.images?.map((image) => ({
327
- id: image.id,
328
- position: image.position || 0,
329
- image_url: image.image_url,
330
- _destroy: false
331
- })),
332
- inventory_levels_attributes: variant?.inventory_levels?.filter((level) => (level.warehouse_id ?? level.warehouse?.id) != null).map((level) => ({
333
- id: level.id,
334
- available: level.available,
335
- committed: level.committed,
336
- on_hand: level.on_hand,
337
- unavailable: level.unavailable,
338
- warehouse_id: level.warehouse?.id || 0,
339
- _destroy: false
340
- })),
341
- variant_countries_attributes: variant?.variant_countries ? Object.entries(variant.variant_countries).map(([iso, country]) => ({
342
- id: country.id ?? 0,
343
- active: country.active ?? true,
344
- country_id: country.country_id,
345
- country_name: country.country_name ?? "",
346
- country_iso: iso,
347
- price: Number(country.price) || 0,
348
- subscription_price: Number(country.subscription_price) || 0,
349
- wholesale: Number(country.wholesale) || 0,
350
- wholesale_subscription_price: Number(country.wholesale_subscription_price) || 0,
351
- compare_price: Number(country.compare_price) || 0,
352
- cv: Number(country.cv) || 0,
353
- qv: Number(country.qv) || 0,
354
- pc_cv: Number(country.pc_cv) || 0,
355
- pc_qv: Number(country.pc_qv) || 0,
356
- cost_of_goods_sold: Number(country.cost_of_goods_sold) || 0,
357
- currency_code: country.currency_code || null,
358
- shipping: Number(country.shipping) || 0,
359
- points: country.points
360
- })) : []
361
- })),
362
- bundle: productData.product_bundles && productData.product_bundles.length > 0,
363
- track_inventory_on_bundle_items: productData.track_inventory_on_bundle_items ?? false,
364
- product_bundles_attributes: (productData.product_bundles || []).map((bundle) => ({
365
- id: bundle.id,
366
- bundled_variant_id: bundle.bundled_variant?.id || 0,
367
- bundled_variant: {
368
- title: bundle.bundled_variant?.title || "",
369
- sku: bundle.bundled_variant?.sku || null,
370
- price: String(bundle.bundled_variant?.price || "0"),
371
- price_in_currency: bundle.bundled_variant?.price_in_currency || "",
372
- currency_code: bundle.bundled_variant?.currency_code,
373
- product: {
374
- id: bundle.bundled_variant?.product.id || 0,
375
- title: bundle.bundled_variant?.product.title || "",
376
- image_url: bundle.bundled_variant?.product.image_url || "",
377
- price: bundle.bundled_variant?.product.price || "0",
378
- price_in_currency: bundle.bundled_variant?.product.price_in_currency || "",
379
- cv: bundle.bundled_variant?.product.cv || 0,
380
- qv: bundle.bundled_variant?.product.qv || 0
381
- }
382
- },
383
- cv: bundle.cv || 0,
384
- qv: bundle.qv || 0,
385
- quantity: bundle.quantity,
386
- display_externally: bundle.display_externally ?? true,
387
- _destroy: false
388
- })),
389
- option_attrs: productData.option_attrs || [],
390
- options: productData.options || [],
391
- metafields_attributes: (productData.metafields || []).map((metafield) => ({
392
- id: metafield.id,
393
- namespace: metafield.namespace,
394
- key: metafield.key,
395
- value: metafield.value,
396
- value_type: metafield.value_type,
397
- _destroy: false
398
- })),
399
- metadata: productData.metadata || {},
400
- errors: {},
401
- isValid: false,
402
- isDirty: false
403
- });
404
- },
405
- updateSlug: (slug, isManual = true) => {
406
- set((state) => ({
407
- slug,
408
- custom_slug: isManual,
409
- search_engine_optimizer_attributes: {
410
- ...state.search_engine_optimizer_attributes,
411
- title: state.search_engine_optimizer_attributes?.title || "",
412
- description: state.search_engine_optimizer_attributes?.description || "",
413
- image_url: state.search_engine_optimizer_attributes?.image_url || "",
414
- image_path: state.search_engine_optimizer_attributes?.image_path || "",
415
- block_crawler: state.search_engine_optimizer_attributes?.block_crawler ?? false
416
- },
417
- isDirty: true
418
- }));
419
- },
420
- updateSEO: (seo) => {
421
- set((state) => ({
422
- search_engine_optimizer_attributes: {
423
- ...state.search_engine_optimizer_attributes,
424
- title: seo.title !== void 0 ? seo.title : state.search_engine_optimizer_attributes?.title || "",
425
- description: seo.description !== void 0 ? seo.description : state.search_engine_optimizer_attributes?.description || "",
426
- image_url: seo.image_url !== void 0 ? seo.image_url : state.search_engine_optimizer_attributes?.image_url || "",
427
- image_path: seo.image_path !== void 0 ? seo.image_path : state.search_engine_optimizer_attributes?.image_path || "",
428
- block_crawler: seo.block_crawler !== void 0 ? seo.block_crawler : state.search_engine_optimizer_attributes?.block_crawler ?? false
429
- },
430
- isDirty: true
431
- }));
432
- },
433
- updateField: (key, value, options) => {
434
- const { shouldValidate = false, shouldClearError = true, markDirty = true } = options || {};
435
- set((state) => {
436
- if (key === "product_subscription_plans") return {
437
- ...state,
438
- ...syncSubscriptionPlans(value),
439
- errors: shouldClearError ? {
440
- ...state.errors,
441
- [key]: void 0
442
- } : state.errors,
443
- isDirty: markDirty ? true : state.isDirty
444
- };
445
- return {
446
- ...state,
447
- [key]: value,
448
- errors: shouldClearError ? {
449
- ...state.errors,
450
- [key]: void 0
451
- } : state.errors,
452
- isDirty: markDirty ? true : state.isDirty
453
- };
454
- });
455
- if (shouldValidate) get().validateField(key);
456
- },
457
- updatePartial: (updates) => {
458
- set((state) => {
459
- if (updates.product_subscription_plans) return {
460
- ...state,
461
- ...updates,
462
- ...syncSubscriptionPlans(updates.product_subscription_plans),
463
- errors: {
464
- ...state.errors,
465
- ...Object.keys(updates).reduce((acc, key) => {
466
- acc[key] = void 0;
467
- return acc;
468
- }, {})
469
- },
470
- isDirty: true
471
- };
472
- return {
473
- ...state,
474
- ...updates,
475
- errors: {
476
- ...state.errors,
477
- ...Object.keys(updates).reduce((acc, key) => {
478
- acc[key] = void 0;
479
- return acc;
480
- }, {})
481
- },
482
- isDirty: true
483
- };
484
- });
485
- },
486
- updateArrayItem: (arrayKey, itemId, updatedItem, idField = "id") => {
487
- set((state) => {
488
- const updatedArray = (Array.isArray(state[arrayKey]) ? state[arrayKey] : []).map((item) => {
489
- if (typeof item === "object" && item !== null && idField in item && item[idField] === itemId) return updatedItem;
490
- return item;
491
- });
492
- if (arrayKey === "product_subscription_plans") return {
493
- ...state,
494
- ...syncSubscriptionPlans(updatedArray),
495
- errors: {
496
- ...state.errors,
497
- [arrayKey]: void 0
498
- },
499
- isDirty: true
500
- };
501
- return {
502
- ...state,
503
- [arrayKey]: updatedArray,
504
- errors: {
505
- ...state.errors,
506
- [arrayKey]: void 0
507
- },
508
- isDirty: true
509
- };
510
- });
511
- },
512
- reset: () => {
513
- set({
514
- ...defaultState,
515
- track_inventory_on_bundle_items: false,
516
- custom_slug: false,
517
- errors: {},
518
- isValid: false,
519
- isDirty: false
520
- });
521
- },
522
- validateField: (field) => {
523
- const fieldValue = get()[field];
524
- const hasValue = fieldValue !== void 0 && fieldValue !== null && fieldValue !== "";
525
- set((state) => ({
526
- errors: {
527
- ...state.errors,
528
- [field]: hasValue ? void 0 : `${field} is required`
529
- },
530
- isValid: hasValue && Object.keys(state.errors).every((key) => key === field || !state.errors[key])
531
- }));
532
- },
533
- validateRequired: () => {
534
- const state = get();
535
- const errors = {};
536
- if (!state.title) errors.title = "Title is required";
537
- if (Object.keys(errors).length > 0) {
538
- set({
539
- errors,
540
- isValid: false
541
- });
542
- return false;
543
- }
544
- set({
545
- errors: {},
546
- isValid: true
547
- });
548
- return true;
549
- },
550
- clearErrors: () => {
551
- set({
552
- errors: {},
553
- isValid: false
554
- });
555
- },
556
- clearFieldError: (field) => {
557
- set((state) => ({ errors: {
558
- ...state.errors,
559
- [field]: void 0
560
- } }));
561
- },
562
- markClean: () => {
563
- set({ isDirty: false });
564
- },
565
- setTranslationLoading: (languageIso, loading) => {
566
- set((state) => ({ translationLoading: {
567
- ...state.translationLoading,
568
- [languageIso]: loading
569
- } }));
570
- },
571
- setTranslationData: (languageIso, data) => {
572
- set((state) => ({
573
- translations: {
574
- ...state.translations,
575
- [languageIso]: data
576
- },
577
- translationLoading: {
578
- ...state.translationLoading,
579
- [languageIso]: false
580
- }
581
- }));
582
- },
583
- updateTranslationField: (languageIso, field, value) => {
584
- set((state) => {
585
- const originalValue = state.translations[languageIso]?.[field];
586
- let error;
587
- if (field === "title" && value === "" && originalValue && originalValue.trim() !== "") error = "Title is required";
588
- return {
589
- editedTranslations: {
590
- ...state.editedTranslations,
591
- [languageIso]: {
592
- ...state.editedTranslations[languageIso],
593
- [field]: value
594
- }
595
- },
596
- translationErrors: {
597
- ...state.translationErrors,
598
- [languageIso]: {
599
- ...state.translationErrors[languageIso],
600
- [field]: error
601
- }
602
- }
603
- };
604
- });
605
- },
606
- getTranslation: (languageIso, field) => {
607
- const state = get();
608
- return state.editedTranslations[languageIso]?.[field] ?? state.translations[languageIso]?.[field];
609
- },
610
- getOriginalTranslation: (languageIso, field) => {
611
- return get().translations[languageIso]?.[field];
612
- },
613
- getEditedTranslation: (languageIso, field) => {
614
- return get().editedTranslations[languageIso]?.[field];
615
- },
616
- setTranslationError: (languageIso, field, error) => {
617
- set((state) => ({ translationErrors: {
618
- ...state.translationErrors,
619
- [languageIso]: {
620
- ...state.translationErrors[languageIso],
621
- [field]: error
622
- }
623
- } }));
624
- },
625
- getTranslationError: (languageIso, field) => {
626
- return get().translationErrors[languageIso]?.[field];
627
- },
628
- isTranslationLoading: (languageIso) => {
629
- return get().translationLoading[languageIso] ?? false;
630
- },
631
- resetTranslations: () => {
632
- set({
633
- translations: {},
634
- editedTranslations: {},
635
- translationErrors: {},
636
- translationLoading: {},
637
- translationsFetched: false
638
- });
639
- },
640
- setTranslationsFetched: (fetched) => {
641
- set({ translationsFetched: fetched });
642
- }
643
- });
644
- process.env.NODE_ENV === "development" ? (0, zustand.create)()((0, zustand_middleware.devtools)(createProductStore, { name: "product-store" })) : (0, zustand.create)()(createProductStore);
645
- (0, zustand.create)()((set, get) => ({
646
- draftData: null,
647
- isFromSettings: false,
648
- navigationTarget: null,
649
- saveDraft: (data) => {
650
- const formData = data;
651
- if (formData?.title || formData?.description || formData?.sku || formData?.product_subscription_plans && formData.product_subscription_plans.length > 0) set({ draftData: data });
652
- },
653
- getDraft: () => {
654
- const { draftData, isFromSettings, navigationTarget } = get();
655
- if (!draftData) return null;
656
- if (isFromSettings && navigationTarget) return draftData;
657
- set({ draftData: null });
658
- return null;
659
- },
660
- clearDraft: () => {
661
- const { draftData } = get();
662
- if (draftData) set({ draftData: null });
663
- },
664
- setFromSettings: (value) => {
665
- set({ isFromSettings: value });
666
- },
667
- setNavigationTarget: (target) => {
668
- set({ navigationTarget: target });
669
- },
670
- reset: () => {
671
- set({
672
- draftData: null,
673
- isFromSettings: false,
674
- navigationTarget: null
675
- });
676
- }
677
- }));
678
- //#endregion
679
- //#region ../../products/core/src/utils/product-helpers.ts
680
- function getProductImageUrl(product) {
681
- if (!product) return null;
682
- if (Array.isArray(product.images) && product.images.length > 0) {
683
- const primaryImage = [...product.images].sort((a, b) => (a.position ?? 0) - (b.position ?? 0))[0];
684
- if (primaryImage?.image_url) return primaryImage.image_url;
685
- }
686
- return product.image_url ?? null;
687
- }
688
- //#endregion
689
- //#region ../../products/core/src/utils/product-price.ts
690
- function stripParentheticalText(text) {
691
- if (!text) return null;
692
- return text.replace(/\s*\([^)]*\)/g, "").trim();
693
- }
694
- function isShopVariantCountry(vc) {
695
- return vc !== void 0 && "display_wholesale_subscription_price" in vc;
696
- }
697
- function isAdminProduct(product) {
698
- return "display_price" in product;
699
- }
700
- function isVariantCountriesRecord(vc) {
701
- return vc !== null && typeof vc === "object" && !Array.isArray(vc);
702
- }
703
- function determineProductPrice(product, countryIso) {
704
- const { variants } = product;
705
- const selectedVariant = variants?.find((v) => {
706
- if (isVariantCountriesRecord(v.variant_countries)) return v.variant_countries[countryIso]?.active;
707
- return false;
708
- }) || variants?.[0] || null;
709
- let variantCountry;
710
- if (countryIso && selectedVariant?.variant_countries) {
711
- const variantCountries = selectedVariant.variant_countries;
712
- if (Array.isArray(variantCountries)) variantCountry = variantCountries.find((v) => v?.country?.iso === countryIso);
713
- else if (isVariantCountriesRecord(variantCountries)) variantCountry = variantCountries[countryIso];
714
- }
715
- if (selectedVariant?.subscription_only) return { repPrice: isShopVariantCountry(variantCountry) ? variantCountry.display_wholesale_subscription_price : void 0 };
716
- const price = isShopVariantCountry(variantCountry) ? variantCountry.display_price : isAdminProduct(product) ? product.display_price : void 0;
717
- const repPrice = isShopVariantCountry(variantCountry) ? variantCountry.display_wholesale : void 0;
718
- return {
719
- repPrice: stripParentheticalText(repPrice),
720
- price: price === repPrice ? null : stripParentheticalText(price)
721
- };
722
- }
723
- //#endregion
724
14
  //#region ../../shop/ui/src/utils/media-helpers.ts
725
15
  const VIDEO_EXTENSIONS = [
726
16
  ".mp4",
@@ -783,7 +73,7 @@ function formatPortalPrice(price, currency) {
783
73
  function ProductCardContent({ product, countryIso, companyLogoUrl, renderImage = defaultRenderImage$1 }) {
784
74
  const [isHovered, setIsHovered] = (0, react.useState)(false);
785
75
  const isPortal = isPortalProduct(product);
786
- const coverImage = isPortal ? getPortalProductCoverImage(product) : getProductImageUrl(product);
76
+ const coverImage = isPortal ? getPortalProductCoverImage(product) : require_PortalProductsApiProvider.getProductImageUrl(product);
787
77
  const isVideo = isVideoUrl(coverImage);
788
78
  const productName = isPortal ? product.name || "No title available" : product.title || "No title available";
789
79
  let repPrice = null;
@@ -794,7 +84,7 @@ function ProductCardContent({ product, countryIso, companyLogoUrl, renderImage =
794
84
  if (retailFormatted !== repPrice) price = retailFormatted;
795
85
  } else repPrice = formatPortalPrice(product.price, product.currency);
796
86
  else if (countryIso) {
797
- const prices = determineProductPrice(product, countryIso);
87
+ const prices = require_PortalProductsApiProvider.determineProductPrice(product, countryIso);
798
88
  repPrice = prices.repPrice;
799
89
  price = prices.price;
800
90
  }
@@ -1183,7 +473,7 @@ function SkeletonGrid({ count = 8 }) {
1183
473
  }
1184
474
  function ProductListing({ companyLogoUrl, renderImage, onSelectProduct, cartButton }) {
1185
475
  const observerTarget = (0, react.useRef)(null);
1186
- const catalog = usePortalProductCatalog({ perPage: PAGE_SIZE });
476
+ const catalog = require_PortalProductsApiProvider.usePortalProductCatalog({ perPage: PAGE_SIZE });
1187
477
  const { data, isLoading, isFetchingNextPage, hasNextPage, fetchNextPage, error, isFetched } = (0, _tanstack_react_query.useInfiniteQuery)({
1188
478
  queryKey: catalog.queryKey,
1189
479
  queryFn: ({ pageParam }) => catalog.fetchProducts(pageParam),
@@ -1356,7 +646,7 @@ function ProductDetail({ productId, renderImage }) {
1356
646
  const [selections, setSelections] = (0, react.useState)({});
1357
647
  const [userSelectedSubscribe, setUserSelectedSubscribe] = (0, react.useState)(false);
1358
648
  const [selectedSubscriptionPlan, setSelectedSubscriptionPlan] = (0, react.useState)(void 0);
1359
- const { product, isLoading, error, images } = usePortalProductDetail({ productId });
649
+ const { product, isLoading, error, images } = require_PortalProductsApiProvider.usePortalProductDetail({ productId });
1360
650
  const variants = (0, react.useMemo)(() => product?.variants ?? [], [product?.variants]);
1361
651
  const subscriptionPlans = (0, react.useMemo)(() => product?.subscription_plans ?? [], [product?.subscription_plans]);
1362
652
  const masterVariant = (0, react.useMemo)(() => variants.find((v) => v.is_master) ?? variants[0], [variants]);
@@ -1758,7 +1048,6 @@ function ShopContainer({ children, className = "", cartScript, cartWidget }) {
1758
1048
  //#region src/screens/ShopScreen.tsx
1759
1049
  function ShopScreen({ background, textColor, accentColor, padding, borderRadius, ...divProps }) {
1760
1050
  const { config } = require_FluidProvider.useFluidContext();
1761
- const portalProductsApi = require_use_portal_products_client.usePortalProductsClient();
1762
1051
  const { currentSlug, navigate } = require_AppNavigationContext.useAppNavigation();
1763
1052
  const countryCode = config.countryIso ?? "US";
1764
1053
  const subdomain = (0, react.useMemo)(() => {
@@ -1811,15 +1100,12 @@ function ShopScreen({ background, textColor, accentColor, padding, borderRadius,
1811
1100
  debug: {}.env.DEV
1812
1101
  }) : null,
1813
1102
  cartWidget: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CartWidget, {}),
1814
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(PortalProductsCoreProvider, {
1815
- api: portalProductsApi,
1816
- children: [productId && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProductBreadcrumb, { productId }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShopApp, {
1817
- companyLogoUrl: void 0,
1818
- productId,
1819
- onSelectProduct: (id) => navigate(`shop/${id}`),
1820
- onBack: () => navigate("shop")
1821
- })]
1822
- })
1103
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_PortalProductsApiProvider.PortalProductsApiProvider, { children: [productId && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProductBreadcrumb, { productId }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShopApp, {
1104
+ companyLogoUrl: void 0,
1105
+ productId,
1106
+ onSelectProduct: (id) => navigate(`shop/${id}`),
1107
+ onBack: () => navigate("shop")
1108
+ })] })
1823
1109
  })
1824
1110
  });
1825
1111
  }
@@ -1839,7 +1125,7 @@ const shopScreenPropertySchema = {
1839
1125
  */
1840
1126
  function ProductBreadcrumb({ productId }) {
1841
1127
  const { navigate } = require_AppNavigationContext.useAppNavigation();
1842
- const { product } = usePortalProductDetail({ productId });
1128
+ const { product } = require_PortalProductsApiProvider.usePortalProductDetail({ productId });
1843
1129
  const productName = product?.name ?? "Product";
1844
1130
  require_ScreenHeaderContext.useScreenHeaderBreadcrumbs((0, react.useMemo)(() => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Breadcrumb, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.BreadcrumbList, {
1845
1131
  className: "text-lg",
@@ -1872,4 +1158,4 @@ Object.defineProperty(exports, "shopScreenPropertySchema", {
1872
1158
  }
1873
1159
  });
1874
1160
 
1875
- //# sourceMappingURL=ShopScreen-CFqoT4IC.cjs.map
1161
+ //# sourceMappingURL=ShopScreen-BUXUtEuj.cjs.map