@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,722 +4,12 @@ import { $ as DropdownMenuTrigger, A as SelectValue, D as SelectContent, E as Se
4
4
  import { n as useScreenHeaderActions, r as useScreenHeaderBreadcrumbs } from "./ScreenHeaderContext-DjSO5A8k.mjs";
5
5
  import { n as useAppNavigation } from "./AppNavigationContext-D29xW9Ua.mjs";
6
6
  import { t as SearchSort } from "./SearchSort-Br8J8JS8.mjs";
7
- import { t as usePortalProductsClient } from "./use-portal-products-client-BUFD20ZY.mjs";
8
- import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
9
- import { useInfiniteQuery, useQuery } from "@tanstack/react-query";
7
+ import { a as usePortalProductCatalog, i as usePortalProductDetail, n as determineProductPrice, r as getProductImageUrl, t as PortalProductsApiProvider } from "./PortalProductsApiProvider-BCXX9NGK.mjs";
8
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
9
+ import { useInfiniteQuery } from "@tanstack/react-query";
10
10
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
11
11
  import { ArrowUpDown, ChevronLeft, ChevronRight, CirclePlay, ShoppingCart } from "lucide-react";
12
12
  import { createPortal } from "react-dom";
13
- import { create } from "zustand";
14
- import "zustand/middleware";
15
- createContext(null);
16
- //#endregion
17
- //#region ../../products/core/src/portal-products-api-context.tsx
18
- const PortalProductsCoreContext = createContext(null);
19
- function PortalProductsCoreProvider({ api, children }) {
20
- return /* @__PURE__ */ jsx(PortalProductsCoreContext.Provider, {
21
- value: { api },
22
- children
23
- });
24
- }
25
- function usePortalProductsApi() {
26
- const ctx = useContext(PortalProductsCoreContext);
27
- if (!ctx) throw new Error("usePortalProductsApi must be used within a <PortalProductsCoreProvider>");
28
- return ctx.api;
29
- }
30
- //#endregion
31
- //#region ../../products/core/src/hooks/use-debounce.ts
32
- function useDebounce(value, delay) {
33
- const [debouncedValue, setDebouncedValue] = useState(value);
34
- useEffect(() => {
35
- const timer = setTimeout(() => {
36
- setDebouncedValue(value);
37
- }, delay);
38
- return () => {
39
- clearTimeout(timer);
40
- };
41
- }, [value, delay]);
42
- return debouncedValue;
43
- }
44
- //#endregion
45
- //#region ../../products/core/src/hooks/use-portal-products.ts
46
- const portalProductKeys = {
47
- all: ["portal-products"],
48
- list: (params) => [
49
- ...portalProductKeys.all,
50
- "list",
51
- params
52
- ],
53
- detail: (id) => [
54
- ...portalProductKeys.all,
55
- "detail",
56
- String(id)
57
- ],
58
- search: (query, params) => [
59
- ...portalProductKeys.all,
60
- "search",
61
- query,
62
- params
63
- ],
64
- media: (productId) => [
65
- ...portalProductKeys.all,
66
- "media",
67
- String(productId)
68
- ]
69
- };
70
- function usePortalProduct(id, options) {
71
- const api = usePortalProductsApi();
72
- return useQuery({
73
- queryKey: portalProductKeys.detail(id),
74
- queryFn: () => api.getProduct(id),
75
- enabled: options?.enabled
76
- });
77
- }
78
- //#endregion
79
- //#region ../../products/core/src/hooks/use-portal-product-catalog.ts
80
- function usePortalProductCatalog({ perPage = 25 } = {}) {
81
- const api = usePortalProductsApi();
82
- const [searchTerm, setSearchTerm] = useState("");
83
- const debouncedSearchTerm = useDebounce(searchTerm, 300);
84
- const [currentSort, setCurrentSort] = useState("created_at_desc");
85
- return {
86
- searchTerm,
87
- setSearchTerm,
88
- debouncedSearchTerm,
89
- currentSort,
90
- setCurrentSort,
91
- fetchProducts: useCallback(async (pageParam) => {
92
- const cursor = pageParam;
93
- if (debouncedSearchTerm) return api.searchProducts(debouncedSearchTerm, {
94
- cursor,
95
- limit: perPage,
96
- sort: currentSort
97
- });
98
- return api.listProducts({
99
- cursor,
100
- limit: perPage,
101
- sort: currentSort
102
- });
103
- }, [
104
- api,
105
- debouncedSearchTerm,
106
- perPage,
107
- currentSort
108
- ]),
109
- getNextPageParam: useCallback((lastPage, _allPages, lastPageParam) => {
110
- const nextCursor = lastPage.meta?.pagination?.next_cursor ?? void 0;
111
- if (nextCursor != null && nextCursor === lastPageParam) return;
112
- return nextCursor;
113
- }, []),
114
- queryKey: useMemo(() => [
115
- "portal-product-catalog",
116
- debouncedSearchTerm || "",
117
- perPage,
118
- currentSort
119
- ], [
120
- debouncedSearchTerm,
121
- perPage,
122
- currentSort
123
- ]),
124
- perPage
125
- };
126
- }
127
- //#endregion
128
- //#region ../../products/core/src/hooks/use-portal-product-detail.ts
129
- function usePortalProductDetail({ productId }) {
130
- const { data: productResponse, isLoading, error } = usePortalProduct(productId);
131
- const product = productResponse?.product;
132
- return {
133
- product,
134
- isLoading,
135
- error,
136
- images: useMemo(() => {
137
- if (!product?.images) return [];
138
- return product.images.map((img, idx) => ({
139
- id: idx,
140
- url: img.url ?? "",
141
- alt: img.alt ?? null
142
- }));
143
- }, [product?.images])
144
- };
145
- }
146
- //#endregion
147
- //#region ../../products/core/src/utils/subscription-plans.ts
148
- function ensureDefaultSubscriptionPlan(plans) {
149
- const activePlans = plans.filter((plan) => plan.active !== false);
150
- if (activePlans.length === 0) return plans.map((plan) => ({
151
- ...plan,
152
- default: false
153
- }));
154
- if (!activePlans.some((plan) => plan.default === true)) {
155
- const planWithLowestId = activePlans.reduce((lowest, current) => {
156
- const lowestId = lowest.subscription_plan?.id || Infinity;
157
- return (current.subscription_plan?.id || Infinity) < lowestId ? current : lowest;
158
- });
159
- return plans.map((plan) => ({
160
- ...plan,
161
- default: plan.subscription_plan?.id === planWithLowestId.subscription_plan?.id && plan.active !== false
162
- }));
163
- }
164
- return plans.map((plan) => ({
165
- ...plan,
166
- default: plan.active !== false ? plan.default : false
167
- }));
168
- }
169
- function plansToAttributes(plans) {
170
- return plans.map((plan) => ({
171
- id: plan.id ?? void 0,
172
- subscription_plan_id: plan.subscription_plan.id,
173
- default: plan.default || false,
174
- active: plan.active !== false
175
- }));
176
- }
177
- //#endregion
178
- //#region ../../products/core/src/stores/use-product-store.ts
179
- const defaultState = {
180
- id: void 0,
181
- title: "",
182
- description: "",
183
- introduction: "",
184
- stripped: "",
185
- feature_text: "",
186
- sku: "",
187
- slug: "",
188
- canonical_url: null,
189
- image_url: "",
190
- image_path: void 0,
191
- status: "draft",
192
- publish_at: null,
193
- price: "0",
194
- commission: 0,
195
- public: true,
196
- no_index: false,
197
- show_reviews: true,
198
- publish_to_retail_store: true,
199
- publish_to_rep_store: true,
200
- publish_to_share_tab: true,
201
- collection_ids: [],
202
- tag_ids: [],
203
- images_attributes: [],
204
- product_subscription_plans_attributes: [],
205
- product_subscription_plans: [],
206
- variants_attributes: [],
207
- bundle: false,
208
- track_inventory_on_bundle_items: false,
209
- product_bundles_attributes: [],
210
- option_attrs: [],
211
- options: [],
212
- metafields_attributes: [],
213
- metadata: {},
214
- search_engine_optimizer_attributes: {
215
- title: "",
216
- description: "",
217
- image_url: "",
218
- image_path: "",
219
- block_crawler: false
220
- }
221
- };
222
- function syncSubscriptionPlans(plans) {
223
- const plansWithDefault = plans.filter((plan) => plan.active !== false).length > 0 ? ensureDefaultSubscriptionPlan(plans) : plans;
224
- return {
225
- product_subscription_plans: plansWithDefault,
226
- product_subscription_plans_attributes: plansToAttributes(plansWithDefault)
227
- };
228
- }
229
- const extractFilenameFromUrl = (imageUrl) => {
230
- try {
231
- return new URL(imageUrl).pathname.split("/").pop() || "";
232
- } catch {
233
- return imageUrl.split("/").pop()?.split("?")[0] || "";
234
- }
235
- };
236
- const createProductStore = (set, get) => ({
237
- ...defaultState,
238
- track_inventory_on_bundle_items: false,
239
- translations: {},
240
- editedTranslations: {},
241
- translationErrors: {},
242
- translationLoading: {},
243
- translationsFetched: false,
244
- errors: {},
245
- isValid: false,
246
- isDirty: false,
247
- setProduct: (productData) => {
248
- set({
249
- id: productData.id || void 0,
250
- title: productData.title || "",
251
- description: productData.description || "",
252
- introduction: productData.introduction || "",
253
- stripped: productData.stripped || "",
254
- feature_text: productData.feature_text || "",
255
- sku: productData.sku || "",
256
- slug: productData.slug || "",
257
- canonical_url: productData.canonical_url || null,
258
- custom_slug: productData.custom_slug || false,
259
- image_url: productData.image_url || "",
260
- image_path: productData.image_path && !productData.image_path.includes("undefined") ? productData.image_path : productData.image_url ? extractFilenameFromUrl(productData.image_url) : void 0,
261
- status: productData.status || "draft",
262
- publish_at: productData.publish_at || null,
263
- commission: typeof productData.commission === "string" ? parseFloat(productData.commission) : productData.commission || 0,
264
- public: productData.public ?? true,
265
- no_index: productData.no_index ?? false,
266
- show_reviews: productData.show_reviews ?? true,
267
- publish_to_retail_store: productData.publish_to_retail_store,
268
- publish_to_rep_store: productData.publish_to_rep_store,
269
- publish_to_share_tab: productData.publish_to_share_tab,
270
- ...productData.tax_category_id && { tax_category_id: productData.tax_category_id },
271
- international_tax_type: productData.international_tax_type || void 0,
272
- category_id: productData.category_id ? parseInt(productData.category_id) : productData.category?.id ? productData.category.id : void 0,
273
- application_theme_template_id: productData.application_theme_template_id || void 0,
274
- collection_ids: productData.collections?.map((collection) => collection.id),
275
- tag_ids: Array.isArray(productData.tags) ? productData.tags.map((tag) => typeof tag === "number" ? tag : tag?.id).filter(Boolean) : [],
276
- search_engine_optimizer_attributes: {
277
- id: productData.search_engine_optimizer?.id,
278
- title: productData.search_engine_optimizer?.title || productData.title || void 0,
279
- description: productData.search_engine_optimizer?.description || "",
280
- image_url: productData.search_engine_optimizer?.image_url || productData.image_url || "",
281
- image_path: productData.search_engine_optimizer?.image_path || productData.image_path || "",
282
- block_crawler: productData.search_engine_optimizer?.block_crawler ?? false
283
- },
284
- images_attributes: productData.images?.map((img) => ({
285
- id: img.id,
286
- position: img.position || 0,
287
- image_url: img.image_url,
288
- image_path: img.image_path && !img.image_path.includes("undefined") ? img.image_path : img.image_url ? extractFilenameFromUrl(img.image_url) : void 0,
289
- _destroy: false
290
- })) || [],
291
- ...productData.images && productData.images.length > 0 && { image_path: (() => {
292
- if (productData.image_path && typeof productData.image_path === "string" && !productData.image_path.includes("undefined")) return productData.image_path;
293
- const firstImage = productData.images.find((img) => img.position === 0);
294
- if (firstImage?.image_path && typeof firstImage.image_path === "string" && !firstImage.image_path.includes("undefined")) return firstImage.image_path;
295
- return productData.image_url ? extractFilenameFromUrl(productData.image_url) : void 0;
296
- })() },
297
- product_subscription_plans: (() => {
298
- const plans = productData?.product_subscription_plans?.map((plan) => ({
299
- ...plan,
300
- active: plan?.active
301
- })) || [];
302
- return plans.length > 0 ? ensureDefaultSubscriptionPlan(plans) : plans;
303
- })(),
304
- product_subscription_plans_attributes: (() => {
305
- const plans = productData?.product_subscription_plans?.map((plan) => ({
306
- ...plan,
307
- active: plan?.active
308
- })) || [];
309
- return plansToAttributes(plans.length > 0 ? ensureDefaultSubscriptionPlan(plans) : plans);
310
- })(),
311
- variants_attributes: productData?.variants?.filter((variant) => variant.id !== null && variant.id !== void 0).map((variant) => ({
312
- id: variant.id,
313
- title: variant.title ?? productData?.title ?? "Untitled Variant",
314
- option_attrs: variant.option_attrs || [],
315
- sku: variant.sku || void 0,
316
- price: variant.price,
317
- track_quantity: variant.track_quantity ?? false,
318
- keep_selling: variant.keep_selling ?? false,
319
- bar_code: variant.bar_code ?? "",
320
- limit_subscription: variant.limit_subscription,
321
- subscription_max_qty: variant.subscription_max_qty ?? 0,
322
- customer_limit: variant.customer_limit ?? 0,
323
- is_master: variant.is_master,
324
- _destroy: false,
325
- images_attributes: variant?.images?.map((image) => ({
326
- id: image.id,
327
- position: image.position || 0,
328
- image_url: image.image_url,
329
- _destroy: false
330
- })),
331
- inventory_levels_attributes: variant?.inventory_levels?.filter((level) => (level.warehouse_id ?? level.warehouse?.id) != null).map((level) => ({
332
- id: level.id,
333
- available: level.available,
334
- committed: level.committed,
335
- on_hand: level.on_hand,
336
- unavailable: level.unavailable,
337
- warehouse_id: level.warehouse?.id || 0,
338
- _destroy: false
339
- })),
340
- variant_countries_attributes: variant?.variant_countries ? Object.entries(variant.variant_countries).map(([iso, country]) => ({
341
- id: country.id ?? 0,
342
- active: country.active ?? true,
343
- country_id: country.country_id,
344
- country_name: country.country_name ?? "",
345
- country_iso: iso,
346
- price: Number(country.price) || 0,
347
- subscription_price: Number(country.subscription_price) || 0,
348
- wholesale: Number(country.wholesale) || 0,
349
- wholesale_subscription_price: Number(country.wholesale_subscription_price) || 0,
350
- compare_price: Number(country.compare_price) || 0,
351
- cv: Number(country.cv) || 0,
352
- qv: Number(country.qv) || 0,
353
- pc_cv: Number(country.pc_cv) || 0,
354
- pc_qv: Number(country.pc_qv) || 0,
355
- cost_of_goods_sold: Number(country.cost_of_goods_sold) || 0,
356
- currency_code: country.currency_code || null,
357
- shipping: Number(country.shipping) || 0,
358
- points: country.points
359
- })) : []
360
- })),
361
- bundle: productData.product_bundles && productData.product_bundles.length > 0,
362
- track_inventory_on_bundle_items: productData.track_inventory_on_bundle_items ?? false,
363
- product_bundles_attributes: (productData.product_bundles || []).map((bundle) => ({
364
- id: bundle.id,
365
- bundled_variant_id: bundle.bundled_variant?.id || 0,
366
- bundled_variant: {
367
- title: bundle.bundled_variant?.title || "",
368
- sku: bundle.bundled_variant?.sku || null,
369
- price: String(bundle.bundled_variant?.price || "0"),
370
- price_in_currency: bundle.bundled_variant?.price_in_currency || "",
371
- currency_code: bundle.bundled_variant?.currency_code,
372
- product: {
373
- id: bundle.bundled_variant?.product.id || 0,
374
- title: bundle.bundled_variant?.product.title || "",
375
- image_url: bundle.bundled_variant?.product.image_url || "",
376
- price: bundle.bundled_variant?.product.price || "0",
377
- price_in_currency: bundle.bundled_variant?.product.price_in_currency || "",
378
- cv: bundle.bundled_variant?.product.cv || 0,
379
- qv: bundle.bundled_variant?.product.qv || 0
380
- }
381
- },
382
- cv: bundle.cv || 0,
383
- qv: bundle.qv || 0,
384
- quantity: bundle.quantity,
385
- display_externally: bundle.display_externally ?? true,
386
- _destroy: false
387
- })),
388
- option_attrs: productData.option_attrs || [],
389
- options: productData.options || [],
390
- metafields_attributes: (productData.metafields || []).map((metafield) => ({
391
- id: metafield.id,
392
- namespace: metafield.namespace,
393
- key: metafield.key,
394
- value: metafield.value,
395
- value_type: metafield.value_type,
396
- _destroy: false
397
- })),
398
- metadata: productData.metadata || {},
399
- errors: {},
400
- isValid: false,
401
- isDirty: false
402
- });
403
- },
404
- updateSlug: (slug, isManual = true) => {
405
- set((state) => ({
406
- slug,
407
- custom_slug: isManual,
408
- search_engine_optimizer_attributes: {
409
- ...state.search_engine_optimizer_attributes,
410
- title: state.search_engine_optimizer_attributes?.title || "",
411
- description: state.search_engine_optimizer_attributes?.description || "",
412
- image_url: state.search_engine_optimizer_attributes?.image_url || "",
413
- image_path: state.search_engine_optimizer_attributes?.image_path || "",
414
- block_crawler: state.search_engine_optimizer_attributes?.block_crawler ?? false
415
- },
416
- isDirty: true
417
- }));
418
- },
419
- updateSEO: (seo) => {
420
- set((state) => ({
421
- search_engine_optimizer_attributes: {
422
- ...state.search_engine_optimizer_attributes,
423
- title: seo.title !== void 0 ? seo.title : state.search_engine_optimizer_attributes?.title || "",
424
- description: seo.description !== void 0 ? seo.description : state.search_engine_optimizer_attributes?.description || "",
425
- image_url: seo.image_url !== void 0 ? seo.image_url : state.search_engine_optimizer_attributes?.image_url || "",
426
- image_path: seo.image_path !== void 0 ? seo.image_path : state.search_engine_optimizer_attributes?.image_path || "",
427
- block_crawler: seo.block_crawler !== void 0 ? seo.block_crawler : state.search_engine_optimizer_attributes?.block_crawler ?? false
428
- },
429
- isDirty: true
430
- }));
431
- },
432
- updateField: (key, value, options) => {
433
- const { shouldValidate = false, shouldClearError = true, markDirty = true } = options || {};
434
- set((state) => {
435
- if (key === "product_subscription_plans") return {
436
- ...state,
437
- ...syncSubscriptionPlans(value),
438
- errors: shouldClearError ? {
439
- ...state.errors,
440
- [key]: void 0
441
- } : state.errors,
442
- isDirty: markDirty ? true : state.isDirty
443
- };
444
- return {
445
- ...state,
446
- [key]: value,
447
- errors: shouldClearError ? {
448
- ...state.errors,
449
- [key]: void 0
450
- } : state.errors,
451
- isDirty: markDirty ? true : state.isDirty
452
- };
453
- });
454
- if (shouldValidate) get().validateField(key);
455
- },
456
- updatePartial: (updates) => {
457
- set((state) => {
458
- if (updates.product_subscription_plans) return {
459
- ...state,
460
- ...updates,
461
- ...syncSubscriptionPlans(updates.product_subscription_plans),
462
- errors: {
463
- ...state.errors,
464
- ...Object.keys(updates).reduce((acc, key) => {
465
- acc[key] = void 0;
466
- return acc;
467
- }, {})
468
- },
469
- isDirty: true
470
- };
471
- return {
472
- ...state,
473
- ...updates,
474
- errors: {
475
- ...state.errors,
476
- ...Object.keys(updates).reduce((acc, key) => {
477
- acc[key] = void 0;
478
- return acc;
479
- }, {})
480
- },
481
- isDirty: true
482
- };
483
- });
484
- },
485
- updateArrayItem: (arrayKey, itemId, updatedItem, idField = "id") => {
486
- set((state) => {
487
- const updatedArray = (Array.isArray(state[arrayKey]) ? state[arrayKey] : []).map((item) => {
488
- if (typeof item === "object" && item !== null && idField in item && item[idField] === itemId) return updatedItem;
489
- return item;
490
- });
491
- if (arrayKey === "product_subscription_plans") return {
492
- ...state,
493
- ...syncSubscriptionPlans(updatedArray),
494
- errors: {
495
- ...state.errors,
496
- [arrayKey]: void 0
497
- },
498
- isDirty: true
499
- };
500
- return {
501
- ...state,
502
- [arrayKey]: updatedArray,
503
- errors: {
504
- ...state.errors,
505
- [arrayKey]: void 0
506
- },
507
- isDirty: true
508
- };
509
- });
510
- },
511
- reset: () => {
512
- set({
513
- ...defaultState,
514
- track_inventory_on_bundle_items: false,
515
- custom_slug: false,
516
- errors: {},
517
- isValid: false,
518
- isDirty: false
519
- });
520
- },
521
- validateField: (field) => {
522
- const fieldValue = get()[field];
523
- const hasValue = fieldValue !== void 0 && fieldValue !== null && fieldValue !== "";
524
- set((state) => ({
525
- errors: {
526
- ...state.errors,
527
- [field]: hasValue ? void 0 : `${field} is required`
528
- },
529
- isValid: hasValue && Object.keys(state.errors).every((key) => key === field || !state.errors[key])
530
- }));
531
- },
532
- validateRequired: () => {
533
- const state = get();
534
- const errors = {};
535
- if (!state.title) errors.title = "Title is required";
536
- if (Object.keys(errors).length > 0) {
537
- set({
538
- errors,
539
- isValid: false
540
- });
541
- return false;
542
- }
543
- set({
544
- errors: {},
545
- isValid: true
546
- });
547
- return true;
548
- },
549
- clearErrors: () => {
550
- set({
551
- errors: {},
552
- isValid: false
553
- });
554
- },
555
- clearFieldError: (field) => {
556
- set((state) => ({ errors: {
557
- ...state.errors,
558
- [field]: void 0
559
- } }));
560
- },
561
- markClean: () => {
562
- set({ isDirty: false });
563
- },
564
- setTranslationLoading: (languageIso, loading) => {
565
- set((state) => ({ translationLoading: {
566
- ...state.translationLoading,
567
- [languageIso]: loading
568
- } }));
569
- },
570
- setTranslationData: (languageIso, data) => {
571
- set((state) => ({
572
- translations: {
573
- ...state.translations,
574
- [languageIso]: data
575
- },
576
- translationLoading: {
577
- ...state.translationLoading,
578
- [languageIso]: false
579
- }
580
- }));
581
- },
582
- updateTranslationField: (languageIso, field, value) => {
583
- set((state) => {
584
- const originalValue = state.translations[languageIso]?.[field];
585
- let error;
586
- if (field === "title" && value === "" && originalValue && originalValue.trim() !== "") error = "Title is required";
587
- return {
588
- editedTranslations: {
589
- ...state.editedTranslations,
590
- [languageIso]: {
591
- ...state.editedTranslations[languageIso],
592
- [field]: value
593
- }
594
- },
595
- translationErrors: {
596
- ...state.translationErrors,
597
- [languageIso]: {
598
- ...state.translationErrors[languageIso],
599
- [field]: error
600
- }
601
- }
602
- };
603
- });
604
- },
605
- getTranslation: (languageIso, field) => {
606
- const state = get();
607
- return state.editedTranslations[languageIso]?.[field] ?? state.translations[languageIso]?.[field];
608
- },
609
- getOriginalTranslation: (languageIso, field) => {
610
- return get().translations[languageIso]?.[field];
611
- },
612
- getEditedTranslation: (languageIso, field) => {
613
- return get().editedTranslations[languageIso]?.[field];
614
- },
615
- setTranslationError: (languageIso, field, error) => {
616
- set((state) => ({ translationErrors: {
617
- ...state.translationErrors,
618
- [languageIso]: {
619
- ...state.translationErrors[languageIso],
620
- [field]: error
621
- }
622
- } }));
623
- },
624
- getTranslationError: (languageIso, field) => {
625
- return get().translationErrors[languageIso]?.[field];
626
- },
627
- isTranslationLoading: (languageIso) => {
628
- return get().translationLoading[languageIso] ?? false;
629
- },
630
- resetTranslations: () => {
631
- set({
632
- translations: {},
633
- editedTranslations: {},
634
- translationErrors: {},
635
- translationLoading: {},
636
- translationsFetched: false
637
- });
638
- },
639
- setTranslationsFetched: (fetched) => {
640
- set({ translationsFetched: fetched });
641
- }
642
- });
643
- create()(createProductStore);
644
- create()((set, get) => ({
645
- draftData: null,
646
- isFromSettings: false,
647
- navigationTarget: null,
648
- saveDraft: (data) => {
649
- const formData = data;
650
- if (formData?.title || formData?.description || formData?.sku || formData?.product_subscription_plans && formData.product_subscription_plans.length > 0) set({ draftData: data });
651
- },
652
- getDraft: () => {
653
- const { draftData, isFromSettings, navigationTarget } = get();
654
- if (!draftData) return null;
655
- if (isFromSettings && navigationTarget) return draftData;
656
- set({ draftData: null });
657
- return null;
658
- },
659
- clearDraft: () => {
660
- const { draftData } = get();
661
- if (draftData) set({ draftData: null });
662
- },
663
- setFromSettings: (value) => {
664
- set({ isFromSettings: value });
665
- },
666
- setNavigationTarget: (target) => {
667
- set({ navigationTarget: target });
668
- },
669
- reset: () => {
670
- set({
671
- draftData: null,
672
- isFromSettings: false,
673
- navigationTarget: null
674
- });
675
- }
676
- }));
677
- //#endregion
678
- //#region ../../products/core/src/utils/product-helpers.ts
679
- function getProductImageUrl(product) {
680
- if (!product) return null;
681
- if (Array.isArray(product.images) && product.images.length > 0) {
682
- const primaryImage = [...product.images].sort((a, b) => (a.position ?? 0) - (b.position ?? 0))[0];
683
- if (primaryImage?.image_url) return primaryImage.image_url;
684
- }
685
- return product.image_url ?? null;
686
- }
687
- //#endregion
688
- //#region ../../products/core/src/utils/product-price.ts
689
- function stripParentheticalText(text) {
690
- if (!text) return null;
691
- return text.replace(/\s*\([^)]*\)/g, "").trim();
692
- }
693
- function isShopVariantCountry(vc) {
694
- return vc !== void 0 && "display_wholesale_subscription_price" in vc;
695
- }
696
- function isAdminProduct(product) {
697
- return "display_price" in product;
698
- }
699
- function isVariantCountriesRecord(vc) {
700
- return vc !== null && typeof vc === "object" && !Array.isArray(vc);
701
- }
702
- function determineProductPrice(product, countryIso) {
703
- const { variants } = product;
704
- const selectedVariant = variants?.find((v) => {
705
- if (isVariantCountriesRecord(v.variant_countries)) return v.variant_countries[countryIso]?.active;
706
- return false;
707
- }) || variants?.[0] || null;
708
- let variantCountry;
709
- if (countryIso && selectedVariant?.variant_countries) {
710
- const variantCountries = selectedVariant.variant_countries;
711
- if (Array.isArray(variantCountries)) variantCountry = variantCountries.find((v) => v?.country?.iso === countryIso);
712
- else if (isVariantCountriesRecord(variantCountries)) variantCountry = variantCountries[countryIso];
713
- }
714
- if (selectedVariant?.subscription_only) return { repPrice: isShopVariantCountry(variantCountry) ? variantCountry.display_wholesale_subscription_price : void 0 };
715
- const price = isShopVariantCountry(variantCountry) ? variantCountry.display_price : isAdminProduct(product) ? product.display_price : void 0;
716
- const repPrice = isShopVariantCountry(variantCountry) ? variantCountry.display_wholesale : void 0;
717
- return {
718
- repPrice: stripParentheticalText(repPrice),
719
- price: price === repPrice ? null : stripParentheticalText(price)
720
- };
721
- }
722
- //#endregion
723
13
  //#region ../../shop/ui/src/utils/media-helpers.ts
724
14
  const VIDEO_EXTENSIONS = [
725
15
  ".mp4",
@@ -1761,7 +1051,6 @@ var ShopScreen_exports = /* @__PURE__ */ __exportAll({
1761
1051
  });
1762
1052
  function ShopScreen({ background, textColor, accentColor, padding, borderRadius, ...divProps }) {
1763
1053
  const { config } = useFluidContext();
1764
- const portalProductsApi = usePortalProductsClient();
1765
1054
  const { currentSlug, navigate } = useAppNavigation();
1766
1055
  const countryCode = config.countryIso ?? "US";
1767
1056
  const subdomain = useMemo(() => {
@@ -1814,15 +1103,12 @@ function ShopScreen({ background, textColor, accentColor, padding, borderRadius,
1814
1103
  debug: import.meta.env.DEV
1815
1104
  }) : null,
1816
1105
  cartWidget: /* @__PURE__ */ jsx(CartWidget, {}),
1817
- children: /* @__PURE__ */ jsxs(PortalProductsCoreProvider, {
1818
- api: portalProductsApi,
1819
- children: [productId && /* @__PURE__ */ jsx(ProductBreadcrumb, { productId }), /* @__PURE__ */ jsx(ShopApp, {
1820
- companyLogoUrl: void 0,
1821
- productId,
1822
- onSelectProduct: (id) => navigate(`shop/${id}`),
1823
- onBack: () => navigate("shop")
1824
- })]
1825
- })
1106
+ children: /* @__PURE__ */ jsxs(PortalProductsApiProvider, { children: [productId && /* @__PURE__ */ jsx(ProductBreadcrumb, { productId }), /* @__PURE__ */ jsx(ShopApp, {
1107
+ companyLogoUrl: void 0,
1108
+ productId,
1109
+ onSelectProduct: (id) => navigate(`shop/${id}`),
1110
+ onBack: () => navigate("shop")
1111
+ })] })
1826
1112
  })
1827
1113
  });
1828
1114
  }
@@ -1864,4 +1150,4 @@ function ProductBreadcrumb({ productId }) {
1864
1150
  //#endregion
1865
1151
  export { ShopScreen_exports as n, shopScreenPropertySchema as r, ShopScreen as t };
1866
1152
 
1867
- //# sourceMappingURL=ShopScreen-CQ48b1c8.mjs.map
1153
+ //# sourceMappingURL=ShopScreen-BH6zQndJ.mjs.map