@fluid-app/portal-sdk 0.1.320 → 0.1.321
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/{AddressAutocompleteInput-C31qk240.cjs → AddressAutocompleteInput-CQLCLiwR.cjs} +2 -2
- package/dist/{AddressAutocompleteInput-C31qk240.cjs.map → AddressAutocompleteInput-CQLCLiwR.cjs.map} +1 -1
- package/dist/{AddressAutocompleteInput-nDO_zgjC.mjs → AddressAutocompleteInput-PJBI9E5E.mjs} +2 -2
- package/dist/{AddressAutocompleteInput-nDO_zgjC.mjs.map → AddressAutocompleteInput-PJBI9E5E.mjs.map} +1 -1
- package/dist/{FluidProvider-Chbpn0ap.cjs → FluidProvider-BIeO1i4r.cjs} +3 -3
- package/dist/{FluidProvider-Chbpn0ap.cjs.map → FluidProvider-BIeO1i4r.cjs.map} +1 -1
- package/dist/{FluidProvider-LaSwSmTW.mjs → FluidProvider-LqejfvZ-.mjs} +3 -3
- package/dist/{FluidProvider-LaSwSmTW.mjs.map → FluidProvider-LqejfvZ-.mjs.map} +1 -1
- package/dist/{MessagingScreen-BmMxZyCu.cjs → MessagingScreen-BBkqLkcx.cjs} +2 -2
- package/dist/{MessagingScreen-BmMxZyCu.cjs.map → MessagingScreen-BBkqLkcx.cjs.map} +1 -1
- package/dist/{MessagingScreen-C_Dldq9j.mjs → MessagingScreen-BRcAo9ux.mjs} +2 -2
- package/dist/{MessagingScreen-C_Dldq9j.mjs.map → MessagingScreen-BRcAo9ux.mjs.map} +1 -1
- package/dist/{MessagingScreen-Drs5HxPr.cjs → MessagingScreen-CQNNI4RN.cjs} +4 -4
- package/dist/{MessagingScreen-B87K9iF3.mjs → MessagingScreen-y3AG96Gi.mjs} +4 -4
- package/dist/{OrdersScreen-TDe2UOUi.cjs → OrdersScreen-BgcQi5Re.cjs} +4 -4
- package/dist/{OrdersScreen-DspQqyEz.cjs → OrdersScreen-CZIlrF_M.cjs} +2 -2
- package/dist/{OrdersScreen-DspQqyEz.cjs.map → OrdersScreen-CZIlrF_M.cjs.map} +1 -1
- package/dist/{OrdersScreen-B4duS3OO.mjs → OrdersScreen-DISwVljS.mjs} +4 -4
- package/dist/{OrdersScreen-YNgcoQpy.mjs → OrdersScreen-Do7YtBiu.mjs} +2 -2
- package/dist/{OrdersScreen-YNgcoQpy.mjs.map → OrdersScreen-Do7YtBiu.mjs.map} +1 -1
- package/dist/{ProfileScreen-CQEyBQry.mjs → ProfileScreen-C7scpZZH.mjs} +3 -3
- package/dist/{ProfileScreen-CQEyBQry.mjs.map → ProfileScreen-C7scpZZH.mjs.map} +1 -1
- package/dist/{ProfileScreen-DeZx4ciZ.cjs → ProfileScreen-C9aqx1sO.cjs} +5 -5
- package/dist/{ProfileScreen-B8mHSoqF.cjs → ProfileScreen-DyLQihOW.cjs} +3 -3
- package/dist/{ProfileScreen-B8mHSoqF.cjs.map → ProfileScreen-DyLQihOW.cjs.map} +1 -1
- package/dist/{ProfileScreen-C_nvpK7g.mjs → ProfileScreen-imlOJIjC.mjs} +5 -5
- package/dist/{SearchSort-DwJt03by.mjs → SearchSort-BeYMXXIi.mjs} +90 -85
- package/dist/SearchSort-BeYMXXIi.mjs.map +1 -0
- package/dist/{SearchSort-CJawuuXz.cjs → SearchSort-Bi9QWJQQ.cjs} +90 -85
- package/dist/SearchSort-Bi9QWJQQ.cjs.map +1 -0
- package/dist/{ShareablesScreen-DOc_ZAI-.mjs → ShareablesScreen-BFQDn8Kt.mjs} +2 -2
- package/dist/{ShareablesScreen-DOc_ZAI-.mjs.map → ShareablesScreen-BFQDn8Kt.mjs.map} +1 -1
- package/dist/{ShareablesScreen-C4bUqDzj.mjs → ShareablesScreen-Bex7UIm5.mjs} +2 -2
- package/dist/{ShareablesScreen-CAkzv2_g.cjs → ShareablesScreen-D91gLWOB.cjs} +2 -2
- package/dist/{ShareablesScreen-BasjkQFL.cjs → ShareablesScreen-HHPFsN7t.cjs} +2 -2
- package/dist/{ShareablesScreen-BasjkQFL.cjs.map → ShareablesScreen-HHPFsN7t.cjs.map} +1 -1
- package/dist/{ShopScreen-Bl7vWdBj.mjs → ShopScreen-C4vXayCp.mjs} +4 -4
- package/dist/{ShopScreen-Ckjp_gW9.cjs → ShopScreen-CjrEStJc.cjs} +14 -14
- package/dist/ShopScreen-CjrEStJc.cjs.map +1 -0
- package/dist/{ShopScreen-Chmsr4Yy.cjs → ShopScreen-DM9jxl3w.cjs} +4 -4
- package/dist/{ShopScreen-Dpr0HCvm.mjs → ShopScreen-uOMi-jFD.mjs} +14 -14
- package/dist/ShopScreen-uOMi-jFD.mjs.map +1 -0
- package/dist/{ShopWidget-BUdYOcxc.cjs → ShopWidget-B56mIngl.cjs} +2 -2
- package/dist/{ShopWidget-CAmy3cDU.mjs → ShopWidget-BKTYcwx_.mjs} +5 -5
- package/dist/ShopWidget-BKTYcwx_.mjs.map +1 -0
- package/dist/{ShopWidget-mx04X_Wx.cjs → ShopWidget-BRx2rblg.cjs} +5 -5
- package/dist/{ShopWidget-CAmy3cDU.mjs.map → ShopWidget-BRx2rblg.cjs.map} +1 -1
- package/dist/{SubscriptionsScreen-IJ1SwsFS.cjs → SubscriptionsScreen-B3kKkAuA.cjs} +5 -5
- package/dist/{SubscriptionsScreen-BYYfJS33.mjs → SubscriptionsScreen-BP-sSa__.mjs} +5 -5
- package/dist/{SubscriptionsScreen-CZyXIwt_.mjs → SubscriptionsScreen-CQ3L8wDE.mjs} +3 -3
- package/dist/{SubscriptionsScreen-CZyXIwt_.mjs.map → SubscriptionsScreen-CQ3L8wDE.mjs.map} +1 -1
- package/dist/{SubscriptionsScreen-CUEFFJ3A.cjs → SubscriptionsScreen-D0BtuCfM.cjs} +3 -3
- package/dist/{SubscriptionsScreen-CUEFFJ3A.cjs.map → SubscriptionsScreen-D0BtuCfM.cjs.map} +1 -1
- package/dist/index.cjs +22 -22
- package/dist/index.mjs +22 -22
- package/package.json +14 -14
- package/dist/SearchSort-CJawuuXz.cjs.map +0 -1
- package/dist/SearchSort-DwJt03by.mjs.map +0 -1
- package/dist/ShopScreen-Ckjp_gW9.cjs.map +0 -1
- package/dist/ShopScreen-Dpr0HCvm.mjs.map +0 -1
- package/dist/ShopWidget-mx04X_Wx.cjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("./chunk-9hOWP6kD.cjs");
|
|
3
|
-
const require_FluidProvider = require("./FluidProvider-
|
|
3
|
+
const require_FluidProvider = require("./FluidProvider-BIeO1i4r.cjs");
|
|
4
4
|
const require_ScreenRenderer = require("./ScreenRenderer-D_eEc6S4.cjs");
|
|
5
5
|
const require_PortalTenantClientProvider = require("./PortalTenantClientProvider-D-QE-YzB.cjs");
|
|
6
6
|
require("./store-api-context-D1gZn22Z.cjs");
|
|
@@ -43,28 +43,28 @@ const require_SpacerWidget = require("./SpacerWidget-CYHjTF38.cjs");
|
|
|
43
43
|
const require_TableWidget = require("./TableWidget-DfKZhS1Y.cjs");
|
|
44
44
|
const require_ToDoWidget = require("./ToDoWidget-CImAWF3O.cjs");
|
|
45
45
|
const require_VideoWidget = require("./VideoWidget-Ddt85ZZg.cjs");
|
|
46
|
-
const require_SearchSort = require("./SearchSort-
|
|
47
|
-
const require_ShopWidget = require("./ShopWidget-
|
|
46
|
+
const require_SearchSort = require("./SearchSort-Bi9QWJQQ.cjs");
|
|
47
|
+
const require_ShopWidget = require("./ShopWidget-BRx2rblg.cjs");
|
|
48
48
|
const require_ScreenHeaderContext = require("./ScreenHeaderContext-DWDN0-mb.cjs");
|
|
49
49
|
const require_CustomersScreen = require("./CustomersScreen-DtDU7jkB.cjs");
|
|
50
50
|
const require_use_store = require("./use-store-D2S1FywW.cjs");
|
|
51
51
|
const require_use_account = require("./use-account-BS0vV-sW.cjs");
|
|
52
52
|
const require_AppNavigationContext = require("./AppNavigationContext-CDowN9gd.cjs");
|
|
53
|
-
const require_MessagingScreen = require("./MessagingScreen-
|
|
54
|
-
require("./AddressAutocompleteInput-
|
|
53
|
+
const require_MessagingScreen = require("./MessagingScreen-BBkqLkcx.cjs");
|
|
54
|
+
require("./AddressAutocompleteInput-CQLCLiwR.cjs");
|
|
55
55
|
require("./Combobox-D9lqcqeg.cjs");
|
|
56
56
|
require("./use-mysite-portal-BmrDScmS.cjs");
|
|
57
|
-
const require_ProfileScreen = require("./ProfileScreen-
|
|
58
|
-
const require_SubscriptionsScreen = require("./SubscriptionsScreen-
|
|
57
|
+
const require_ProfileScreen = require("./ProfileScreen-DyLQihOW.cjs");
|
|
58
|
+
const require_SubscriptionsScreen = require("./SubscriptionsScreen-D0BtuCfM.cjs");
|
|
59
59
|
require("./dist-BPZPs7SF.cjs");
|
|
60
60
|
require("./es-CtTr3tb5.cjs");
|
|
61
61
|
const require_ContactsScreen = require("./ContactsScreen-Cf0ShCew.cjs");
|
|
62
62
|
require("./dist-C-U7FKrp.cjs");
|
|
63
|
-
const require_OrdersScreen = require("./OrdersScreen-
|
|
63
|
+
const require_OrdersScreen = require("./OrdersScreen-CZIlrF_M.cjs");
|
|
64
64
|
const require_MySiteScreen = require("./MySiteScreen-D95Kir2t.cjs");
|
|
65
65
|
require("./dist-DSufwDW6.cjs");
|
|
66
|
-
const require_ShareablesScreen = require("./ShareablesScreen-
|
|
67
|
-
const require_ShopScreen = require("./ShopScreen-
|
|
66
|
+
const require_ShareablesScreen = require("./ShareablesScreen-HHPFsN7t.cjs");
|
|
67
|
+
const require_ShopScreen = require("./ShopScreen-CjrEStJc.cjs");
|
|
68
68
|
require("./UpgradeScreen-B8G83QW_.cjs");
|
|
69
69
|
require("./AppDownloadScreen-Cn1gi2aM.cjs");
|
|
70
70
|
let react = require("react");
|
|
@@ -2131,14 +2131,14 @@ function BuilderScreenViewImpl({ screen, className }) {
|
|
|
2131
2131
|
const BuilderScreenView = (0, react.memo)(BuilderScreenViewImpl);
|
|
2132
2132
|
//#endregion
|
|
2133
2133
|
//#region src/shell/system-screen-map.ts
|
|
2134
|
-
const ProfileScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./ProfileScreen-
|
|
2135
|
-
const OrdersScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./OrdersScreen-
|
|
2136
|
-
const SubscriptionsScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./SubscriptionsScreen-
|
|
2137
|
-
const MessagingScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./MessagingScreen-
|
|
2134
|
+
const ProfileScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./ProfileScreen-C9aqx1sO.cjs")).then((m) => ({ default: m.ProfileScreen })));
|
|
2135
|
+
const OrdersScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./OrdersScreen-BgcQi5Re.cjs")).then((m) => ({ default: m.OrdersScreen })));
|
|
2136
|
+
const SubscriptionsScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./SubscriptionsScreen-B3kKkAuA.cjs")).then((m) => ({ default: m.SubscriptionsScreen })));
|
|
2137
|
+
const MessagingScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./MessagingScreen-CQNNI4RN.cjs")).then((m) => ({ default: m.MessagingScreen })));
|
|
2138
2138
|
const ContactsScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./ContactsScreen-DiGrOlwx.cjs")).then((m) => ({ default: m.ContactsScreen })));
|
|
2139
|
-
const ShopScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./ShopScreen-
|
|
2139
|
+
const ShopScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./ShopScreen-DM9jxl3w.cjs")).then((m) => ({ default: m.ShopScreen })));
|
|
2140
2140
|
const CustomersScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./CustomersScreen-DtDU7jkB.cjs")).then((n) => n.CustomersScreen_exports).then((m) => ({ default: m.CustomersScreen })));
|
|
2141
|
-
const ShareablesScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./ShareablesScreen-
|
|
2141
|
+
const ShareablesScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./ShareablesScreen-D91gLWOB.cjs")).then((m) => ({ default: m.ShareablesScreen })));
|
|
2142
2142
|
const MySiteScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./MySiteScreen-f8zAVWT-.cjs")).then((m) => ({ default: m.MySiteScreen })));
|
|
2143
2143
|
const UpgradeScreen = (0, react.lazy)(() => Promise.resolve().then(() => require("./UpgradeScreen-ayWak9W9.cjs")).then((m) => ({ default: m.UpgradeScreen })));
|
|
2144
2144
|
const AppDownloadScreen = (0, react.lazy)(() => Promise.resolve().then(() => require("./AppDownloadScreen-Cn1gi2aM.cjs")).then((n) => n.AppDownloadScreen_exports).then((m) => ({ default: m.AppDownloadScreen })));
|
|
@@ -4041,15 +4041,15 @@ zod.z.object({
|
|
|
4041
4041
|
//#endregion
|
|
4042
4042
|
//#region src/screens/index.ts
|
|
4043
4043
|
const screenPropertySchemas = {
|
|
4044
|
-
ProfileScreen: () => Promise.resolve().then(() => require("./ProfileScreen-
|
|
4045
|
-
MessagingScreen: () => Promise.resolve().then(() => require("./MessagingScreen-
|
|
4044
|
+
ProfileScreen: () => Promise.resolve().then(() => require("./ProfileScreen-C9aqx1sO.cjs")).then((m) => m.profileScreenPropertySchema),
|
|
4045
|
+
MessagingScreen: () => Promise.resolve().then(() => require("./MessagingScreen-CQNNI4RN.cjs")).then((m) => m.messagingScreenPropertySchema),
|
|
4046
4046
|
ContactsScreen: () => Promise.resolve().then(() => require("./ContactsScreen-DiGrOlwx.cjs")).then((m) => m.contactsScreenPropertySchema),
|
|
4047
|
-
OrdersScreen: () => Promise.resolve().then(() => require("./OrdersScreen-
|
|
4048
|
-
SubscriptionsScreen: () => Promise.resolve().then(() => require("./SubscriptionsScreen-
|
|
4047
|
+
OrdersScreen: () => Promise.resolve().then(() => require("./OrdersScreen-BgcQi5Re.cjs")).then((m) => m.ordersScreenPropertySchema),
|
|
4048
|
+
SubscriptionsScreen: () => Promise.resolve().then(() => require("./SubscriptionsScreen-B3kKkAuA.cjs")).then((m) => m.subscriptionsScreenPropertySchema),
|
|
4049
4049
|
CustomersScreen: () => Promise.resolve().then(() => require("./CustomersScreen-DtDU7jkB.cjs")).then((n) => n.CustomersScreen_exports).then((m) => m.customersScreenPropertySchema),
|
|
4050
4050
|
MySiteScreen: () => Promise.resolve().then(() => require("./MySiteScreen-f8zAVWT-.cjs")).then((m) => m.mySiteScreenPropertySchema),
|
|
4051
|
-
ShareablesScreen: () => Promise.resolve().then(() => require("./ShareablesScreen-
|
|
4052
|
-
ShopScreen: () => Promise.resolve().then(() => require("./ShopScreen-
|
|
4051
|
+
ShareablesScreen: () => Promise.resolve().then(() => require("./ShareablesScreen-D91gLWOB.cjs")).then((m) => m.shareablesScreenPropertySchema),
|
|
4052
|
+
ShopScreen: () => Promise.resolve().then(() => require("./ShopScreen-DM9jxl3w.cjs")).then((m) => m.shopScreenPropertySchema),
|
|
4053
4053
|
UpgradeScreen: () => Promise.resolve().then(() => require("./UpgradeScreen-ayWak9W9.cjs")).then((m) => m.upgradeScreenPropertySchema),
|
|
4054
4054
|
AppDownloadScreen: () => Promise.resolve().then(() => require("./AppDownloadScreen-Cn1gi2aM.cjs")).then((n) => n.AppDownloadScreen_exports).then((m) => m.appDownloadScreenPropertySchema)
|
|
4055
4055
|
};
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { $ as products_search, Q as products_media_list, X as product_by_visits, Y as product_by_shares, Z as products_list, et as products_show, n as usePortalTenantClient } from "./PortalTenantClientProvider-CqW6ae2M.mjs";
|
|
2
|
-
import { A as mergeDarkOverrides, C as DEFAULT_SPACING, D as generateThemeCSS, E as getDefaultThemeDefinition, F as RADIUS_KEYS, H as useAppDefinitionApi, I as SEMANTIC_COLOR_NAMES, M as resolveTheme, N as FONT_FAMILY_KEYS, O as deriveDarkVariant, P as FONT_SIZE_KEYS, S as DEFAULT_RADII, T as DEFAULT_THEME_NAME, U as createPersister, W as deleteDatabase, _ as deserialiseTheme, a as widgetPropertySchemas, b as DEFAULT_FONT_FAMILIES, c as createWidgetRegistry, d as applyTheme, f as removeAllThemes, g as transformThemes, h as getActiveThemeId, i as DEFAULT_SDK_WIDGET_REGISTRY, j as parseColor, k as getForegroundColor, l as FluidThemeProvider, m as buildThemeDefinition, n as useFluidContext, o as createScreen, p as removeTheme, r as SUPPORTED_LANGUAGES, s as createWidgetFromShareable, t as FluidProvider, u as useThemeContext, v as serialiseTheme, w as DEFAULT_THEME_ID, x as DEFAULT_FONT_SIZES, y as DEFAULT_COLORS } from "./FluidProvider-
|
|
2
|
+
import { A as mergeDarkOverrides, C as DEFAULT_SPACING, D as generateThemeCSS, E as getDefaultThemeDefinition, F as RADIUS_KEYS, H as useAppDefinitionApi, I as SEMANTIC_COLOR_NAMES, M as resolveTheme, N as FONT_FAMILY_KEYS, O as deriveDarkVariant, P as FONT_SIZE_KEYS, S as DEFAULT_RADII, T as DEFAULT_THEME_NAME, U as createPersister, W as deleteDatabase, _ as deserialiseTheme, a as widgetPropertySchemas, b as DEFAULT_FONT_FAMILIES, c as createWidgetRegistry, d as applyTheme, f as removeAllThemes, g as transformThemes, h as getActiveThemeId, i as DEFAULT_SDK_WIDGET_REGISTRY, j as parseColor, k as getForegroundColor, l as FluidThemeProvider, m as buildThemeDefinition, n as useFluidContext, o as createScreen, p as removeTheme, r as SUPPORTED_LANGUAGES, s as createWidgetFromShareable, t as FluidProvider, u as useThemeContext, v as serialiseTheme, w as DEFAULT_THEME_ID, x as DEFAULT_FONT_SIZES, y as DEFAULT_COLORS } from "./FluidProvider-LqejfvZ-.mjs";
|
|
3
3
|
import { a as assertNever, i as assertDefined, n as DataAwareWidget, o as isWidgetType, r as WIDGET_TYPE_NAMES, s as isWidgetTypeName, u as useRegistry } from "./ScreenRenderer-BszshjZg.mjs";
|
|
4
4
|
import "./store-api-context-DViwxyG4.mjs";
|
|
5
5
|
import "./mysite-api-context-kUTM3GNG.mjs";
|
|
@@ -25,8 +25,8 @@ import "./MediaRenderer-CLmBOrvK.mjs";
|
|
|
25
25
|
import { r as carouselWidgetPropertySchema, t as CarouselWidget } from "./CarouselWidget-2fu0NYxd.mjs";
|
|
26
26
|
import { r as catchUpWidgetPropertySchema, t as CatchUpWidget } from "./CatchUpWidget-DxeBgueZ.mjs";
|
|
27
27
|
import { Dt as CardHeader, Et as CardFooter, Ot as CardTitle, St as Card, Tt as CardDescription, at as Popover, ct as PopoverTrigger, gt as CollapsibleTrigger, h as Skeleton$1, ht as CollapsibleContent, kn as cn$1, mt as Collapsible, p as Toaster, st as PopoverContent, wn as Button } from "./src-DC5QoBhR.mjs";
|
|
28
|
-
import { a as useMessagingAuth, i as useMessagingConfig, n as messagingScreenPropertySchema, r as createFluidFileUploader, t as MessagingScreen } from "./MessagingScreen-
|
|
29
|
-
import { n as subscriptionsScreenPropertySchema, t as SubscriptionsScreen } from "./SubscriptionsScreen-
|
|
28
|
+
import { a as useMessagingAuth, i as useMessagingConfig, n as messagingScreenPropertySchema, r as createFluidFileUploader, t as MessagingScreen } from "./MessagingScreen-BRcAo9ux.mjs";
|
|
29
|
+
import { n as subscriptionsScreenPropertySchema, t as SubscriptionsScreen } from "./SubscriptionsScreen-CQ3L8wDE.mjs";
|
|
30
30
|
import { r as chartWidgetPropertySchema, t as ChartWidget } from "./ChartWidget-DfQQU2w2.mjs";
|
|
31
31
|
import { r as containerWidgetPropertySchema, t as ContainerWidget } from "./ContainerWidget-CPacdtRy.mjs";
|
|
32
32
|
import { r as imageWidgetPropertySchema, t as ImageWidget } from "./ImageWidget-BOFNCjT1.mjs";
|
|
@@ -43,26 +43,26 @@ import { r as spacerWidgetPropertySchema, t as SpacerWidget } from "./SpacerWidg
|
|
|
43
43
|
import { r as tableWidgetPropertySchema, t as TableWidget } from "./TableWidget-Cef29Su9.mjs";
|
|
44
44
|
import { r as toDoWidgetPropertySchema, t as ToDoWidget } from "./ToDoWidget-sLWwJJ_g.mjs";
|
|
45
45
|
import { r as videoWidgetPropertySchema, t as VideoWidget } from "./VideoWidget-CjOhc8KW.mjs";
|
|
46
|
-
import { o as PortalProductsCoreProvider } from "./SearchSort-
|
|
47
|
-
import { o as ShopTranslationProvider } from "./ShopWidget-
|
|
46
|
+
import { o as PortalProductsCoreProvider } from "./SearchSort-BeYMXXIi.mjs";
|
|
47
|
+
import { o as ShopTranslationProvider } from "./ShopWidget-BKTYcwx_.mjs";
|
|
48
48
|
import { i as useScreenHeaderSlotRefs, r as ScreenHeaderProvider } from "./ScreenHeaderContext-Dn12BZyj.mjs";
|
|
49
49
|
import { a as ShellTranslationContext, i as CoreScreenPlaceholder, o as ShellTranslationProvider, r as customersScreenPropertySchema, s as useShellTranslation, t as CustomersScreen } from "./CustomersScreen-D4KRUhQz.mjs";
|
|
50
50
|
import { t as useStore } from "./use-store-fLSf5hUc.mjs";
|
|
51
51
|
import { t as useAccount } from "./use-account-BqNRv6m6.mjs";
|
|
52
52
|
import { n as useAppNavigation, t as AppNavigationProvider } from "./AppNavigationContext-DNomMUij.mjs";
|
|
53
|
-
import "./AddressAutocompleteInput-
|
|
53
|
+
import "./AddressAutocompleteInput-PJBI9E5E.mjs";
|
|
54
54
|
import "./Combobox-B-rNFLTr.mjs";
|
|
55
55
|
import "./use-mysite-portal-DyB9666K.mjs";
|
|
56
|
-
import { n as profileScreenPropertySchema, t as ProfileScreen } from "./ProfileScreen-
|
|
56
|
+
import { n as profileScreenPropertySchema, t as ProfileScreen } from "./ProfileScreen-C7scpZZH.mjs";
|
|
57
57
|
import "./dist-PbA1vxAz.mjs";
|
|
58
58
|
import "./es-C5E79_gn.mjs";
|
|
59
59
|
import { r as contactsScreenPropertySchema, t as ContactsScreen } from "./ContactsScreen-FELUSAZ_.mjs";
|
|
60
60
|
import "./dist-o2cjwzIa.mjs";
|
|
61
|
-
import { n as ordersScreenPropertySchema, t as OrdersScreen } from "./OrdersScreen-
|
|
61
|
+
import { n as ordersScreenPropertySchema, t as OrdersScreen } from "./OrdersScreen-Do7YtBiu.mjs";
|
|
62
62
|
import { r as mySiteScreenPropertySchema, t as MySiteScreen } from "./MySiteScreen-D57JrpWL.mjs";
|
|
63
63
|
import "./sortable.esm-BdhSkRKn.mjs";
|
|
64
|
-
import { n as shareablesScreenPropertySchema, t as ShareablesScreen } from "./ShareablesScreen-
|
|
65
|
-
import { n as shopScreenPropertySchema, t as ShopScreen } from "./ShopScreen-
|
|
64
|
+
import { n as shareablesScreenPropertySchema, t as ShareablesScreen } from "./ShareablesScreen-BFQDn8Kt.mjs";
|
|
65
|
+
import { n as shopScreenPropertySchema, t as ShopScreen } from "./ShopScreen-uOMi-jFD.mjs";
|
|
66
66
|
import "./UpgradeScreen-3tMWotmq.mjs";
|
|
67
67
|
import "./AppDownloadScreen-CUSgeG2w.mjs";
|
|
68
68
|
import * as React$1 from "react";
|
|
@@ -2129,14 +2129,14 @@ function BuilderScreenViewImpl({ screen, className }) {
|
|
|
2129
2129
|
const BuilderScreenView = memo(BuilderScreenViewImpl);
|
|
2130
2130
|
//#endregion
|
|
2131
2131
|
//#region src/shell/system-screen-map.ts
|
|
2132
|
-
const ProfileScreen$1 = lazy(() => import("./ProfileScreen-
|
|
2133
|
-
const OrdersScreen$1 = lazy(() => import("./OrdersScreen-
|
|
2134
|
-
const SubscriptionsScreen$1 = lazy(() => import("./SubscriptionsScreen-
|
|
2135
|
-
const MessagingScreen$1 = lazy(() => import("./MessagingScreen-
|
|
2132
|
+
const ProfileScreen$1 = lazy(() => import("./ProfileScreen-imlOJIjC.mjs").then((m) => ({ default: m.ProfileScreen })));
|
|
2133
|
+
const OrdersScreen$1 = lazy(() => import("./OrdersScreen-DISwVljS.mjs").then((m) => ({ default: m.OrdersScreen })));
|
|
2134
|
+
const SubscriptionsScreen$1 = lazy(() => import("./SubscriptionsScreen-BP-sSa__.mjs").then((m) => ({ default: m.SubscriptionsScreen })));
|
|
2135
|
+
const MessagingScreen$1 = lazy(() => import("./MessagingScreen-y3AG96Gi.mjs").then((m) => ({ default: m.MessagingScreen })));
|
|
2136
2136
|
const ContactsScreen$1 = lazy(() => import("./ContactsScreen-FELUSAZ_.mjs").then((n) => n.n).then((m) => ({ default: m.ContactsScreen })));
|
|
2137
|
-
const ShopScreen$1 = lazy(() => import("./ShopScreen-
|
|
2137
|
+
const ShopScreen$1 = lazy(() => import("./ShopScreen-C4vXayCp.mjs").then((m) => ({ default: m.ShopScreen })));
|
|
2138
2138
|
const CustomersScreen$1 = lazy(() => import("./CustomersScreen-D4KRUhQz.mjs").then((n) => n.n).then((m) => ({ default: m.CustomersScreen })));
|
|
2139
|
-
const ShareablesScreen$1 = lazy(() => import("./ShareablesScreen-
|
|
2139
|
+
const ShareablesScreen$1 = lazy(() => import("./ShareablesScreen-Bex7UIm5.mjs").then((m) => ({ default: m.ShareablesScreen })));
|
|
2140
2140
|
const MySiteScreen$1 = lazy(() => import("./MySiteScreen-D57JrpWL.mjs").then((n) => n.n).then((m) => ({ default: m.MySiteScreen })));
|
|
2141
2141
|
const UpgradeScreen = lazy(() => import("./UpgradeScreen-3tMWotmq.mjs").then((n) => n.t).then((m) => ({ default: m.UpgradeScreen })));
|
|
2142
2142
|
const AppDownloadScreen = lazy(() => import("./AppDownloadScreen-CUSgeG2w.mjs").then((n) => n.t).then((m) => ({ default: m.AppDownloadScreen })));
|
|
@@ -4039,15 +4039,15 @@ z.object({
|
|
|
4039
4039
|
//#endregion
|
|
4040
4040
|
//#region src/screens/index.ts
|
|
4041
4041
|
const screenPropertySchemas = {
|
|
4042
|
-
ProfileScreen: () => import("./ProfileScreen-
|
|
4043
|
-
MessagingScreen: () => import("./MessagingScreen-
|
|
4042
|
+
ProfileScreen: () => import("./ProfileScreen-imlOJIjC.mjs").then((m) => m.profileScreenPropertySchema),
|
|
4043
|
+
MessagingScreen: () => import("./MessagingScreen-y3AG96Gi.mjs").then((m) => m.messagingScreenPropertySchema),
|
|
4044
4044
|
ContactsScreen: () => import("./ContactsScreen-FELUSAZ_.mjs").then((n) => n.n).then((m) => m.contactsScreenPropertySchema),
|
|
4045
|
-
OrdersScreen: () => import("./OrdersScreen-
|
|
4046
|
-
SubscriptionsScreen: () => import("./SubscriptionsScreen-
|
|
4045
|
+
OrdersScreen: () => import("./OrdersScreen-DISwVljS.mjs").then((m) => m.ordersScreenPropertySchema),
|
|
4046
|
+
SubscriptionsScreen: () => import("./SubscriptionsScreen-BP-sSa__.mjs").then((m) => m.subscriptionsScreenPropertySchema),
|
|
4047
4047
|
CustomersScreen: () => import("./CustomersScreen-D4KRUhQz.mjs").then((n) => n.n).then((m) => m.customersScreenPropertySchema),
|
|
4048
4048
|
MySiteScreen: () => import("./MySiteScreen-D57JrpWL.mjs").then((n) => n.n).then((m) => m.mySiteScreenPropertySchema),
|
|
4049
|
-
ShareablesScreen: () => import("./ShareablesScreen-
|
|
4050
|
-
ShopScreen: () => import("./ShopScreen-
|
|
4049
|
+
ShareablesScreen: () => import("./ShareablesScreen-Bex7UIm5.mjs").then((m) => m.shareablesScreenPropertySchema),
|
|
4050
|
+
ShopScreen: () => import("./ShopScreen-C4vXayCp.mjs").then((m) => m.shopScreenPropertySchema),
|
|
4051
4051
|
UpgradeScreen: () => import("./UpgradeScreen-3tMWotmq.mjs").then((n) => n.t).then((m) => m.upgradeScreenPropertySchema),
|
|
4052
4052
|
AppDownloadScreen: () => import("./AppDownloadScreen-CUSgeG2w.mjs").then((n) => n.t).then((m) => m.appDownloadScreenPropertySchema)
|
|
4053
4053
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluid-app/portal-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.321",
|
|
4
4
|
"description": "SDK for building custom Fluid portals",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -72,16 +72,16 @@
|
|
|
72
72
|
"typescript": "^5",
|
|
73
73
|
"zod": "4.3.5",
|
|
74
74
|
"@fluid-app/address-autocomplete": "0.1.0",
|
|
75
|
-
"@fluid-app/auth": "0.1.0",
|
|
76
|
-
"@fluid-app/cart-ui": "0.1.22",
|
|
77
75
|
"@fluid-app/api-client-core": "0.1.0",
|
|
76
|
+
"@fluid-app/cart-ui": "0.1.22",
|
|
77
|
+
"@fluid-app/auth": "0.1.0",
|
|
78
78
|
"@fluid-app/company-switcher-core": "0.1.0",
|
|
79
79
|
"@fluid-app/company-switcher-ui": "0.1.0",
|
|
80
80
|
"@fluid-app/contacts-core": "0.1.0",
|
|
81
81
|
"@fluid-app/contacts-ui": "0.1.0",
|
|
82
82
|
"@fluid-app/file-picker-api-client": "0.1.0",
|
|
83
|
-
"@fluid-app/file-picker-core": "0.1.0",
|
|
84
83
|
"@fluid-app/fluid-pay-core": "0.1.0",
|
|
84
|
+
"@fluid-app/file-picker-core": "0.1.0",
|
|
85
85
|
"@fluid-app/fluid-pay-ui": "0.1.0",
|
|
86
86
|
"@fluid-app/fluidos-api-client": "0.1.0",
|
|
87
87
|
"@fluid-app/i18n": "0.1.0",
|
|
@@ -89,35 +89,35 @@
|
|
|
89
89
|
"@fluid-app/messaging-core": "0.1.0",
|
|
90
90
|
"@fluid-app/messaging-ui": "0.1.0",
|
|
91
91
|
"@fluid-app/mysite-core": "0.1.0",
|
|
92
|
-
"@fluid-app/mysite-ui": "0.1.0",
|
|
93
92
|
"@fluid-app/orders-core": "0.1.0",
|
|
94
|
-
"@fluid-app/permissions": "0.1.0",
|
|
95
93
|
"@fluid-app/orders-ui": "0.1.0",
|
|
94
|
+
"@fluid-app/mysite-ui": "0.1.0",
|
|
95
|
+
"@fluid-app/permissions": "0.1.0",
|
|
96
96
|
"@fluid-app/portal-app-download-ui": "0.1.0",
|
|
97
|
-
"@fluid-app/portal-preview": "0.1.0",
|
|
98
97
|
"@fluid-app/portal-core": "0.1.23",
|
|
98
|
+
"@fluid-app/portal-preview": "0.1.0",
|
|
99
|
+
"@fluid-app/portal-react": "0.1.0",
|
|
99
100
|
"@fluid-app/portal-pro-upgrade-ui": "0.1.0",
|
|
100
101
|
"@fluid-app/portal-tenant-api-client": "0.1.0",
|
|
101
|
-
"@fluid-app/portal-react": "0.1.0",
|
|
102
102
|
"@fluid-app/portal-tenant-contacts-api-client": "0.1.0",
|
|
103
|
-
"@fluid-app/portal-tenant-mysite-api-client": "0.1.0",
|
|
104
103
|
"@fluid-app/portal-tenant-content-api-client": "0.1.0",
|
|
104
|
+
"@fluid-app/portal-tenant-mysite-api-client": "0.1.0",
|
|
105
105
|
"@fluid-app/portal-tenant-pay-api-client": "0.1.0",
|
|
106
|
+
"@fluid-app/portal-widgets": "0.1.22",
|
|
106
107
|
"@fluid-app/portal-tenant-store-api-client": "0.1.0",
|
|
107
108
|
"@fluid-app/products-api-client": "0.1.0",
|
|
108
|
-
"@fluid-app/portal-widgets": "0.1.22",
|
|
109
109
|
"@fluid-app/products-core": "0.1.0",
|
|
110
|
-
"@fluid-app/profile-ui": "0.1.0",
|
|
111
110
|
"@fluid-app/profile-core": "0.1.0",
|
|
112
|
-
"@fluid-app/
|
|
111
|
+
"@fluid-app/profile-ui": "0.1.0",
|
|
113
112
|
"@fluid-app/shareables-core": "0.1.0",
|
|
114
|
-
"@fluid-app/
|
|
113
|
+
"@fluid-app/query-persister": "0.1.0",
|
|
115
114
|
"@fluid-app/shareables-ui": "0.1.0",
|
|
116
115
|
"@fluid-app/shop-ui": "0.1.0",
|
|
117
116
|
"@fluid-app/store-api-client": "0.1.0",
|
|
117
|
+
"@fluid-app/shop-core": "0.1.0",
|
|
118
118
|
"@fluid-app/store-core": "0.1.0",
|
|
119
|
-
"@fluid-app/subscriptions-ui": "0.1.0",
|
|
120
119
|
"@fluid-app/subscriptions-core": "0.1.0",
|
|
120
|
+
"@fluid-app/subscriptions-ui": "0.1.0",
|
|
121
121
|
"@fluid-app/typescript-config": "0.0.0",
|
|
122
122
|
"@fluid-app/ui-primitives": "0.1.13"
|
|
123
123
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SearchSort-CJawuuXz.cjs","names":["Search","Input","Button","X","DropdownMenu","DropdownMenuTrigger","ArrowUpDown","DropdownMenuContent","DropdownMenuItem","Check"],"sources":["../../../products/core/src/products-core-api-context.tsx","../../../products/core/src/portal-products-api-context.tsx","../../../products/core/src/hooks/use-debounce.ts","../../../products/core/src/hooks/use-portal-products.ts","../../../products/core/src/hooks/use-portal-product-catalog.ts","../../../products/core/src/hooks/use-portal-product-detail.ts","../../../products/core/src/utils/subscription-plans.ts","../../../products/core/src/stores/use-product-store.ts","../../../products/core/src/stores/use-draft-store.ts","../../../products/core/src/utils/product-helpers.ts","../../../products/core/src/utils/product-price.ts","../../../platform/ui-components/src/components/SearchSort.tsx"],"sourcesContent":["import { createContext, useContext, type JSX, type ReactNode } from \"react\";\nimport type { ProductsApi } from \"./products-api\";\n\ninterface ProductsCoreConfig {\n api: ProductsApi;\n}\n\nconst ProductsCoreContext = createContext<ProductsCoreConfig | null>(null);\n\nexport function ProductsCoreProvider({\n api,\n children,\n}: ProductsCoreConfig & { children: ReactNode }): JSX.Element {\n return (\n <ProductsCoreContext.Provider value={{ api }}>\n {children}\n </ProductsCoreContext.Provider>\n );\n}\n\nexport function useProductsApi(): ProductsApi {\n const ctx = useContext(ProductsCoreContext);\n if (!ctx) {\n throw new Error(\n \"useProductsApi must be used within a <ProductsCoreProvider>\",\n );\n }\n return ctx.api;\n}\n","import { createContext, useContext, type JSX, type ReactNode } from \"react\";\nimport type { PortalProductsApi } from \"./portal-products-api\";\n\ninterface PortalProductsCoreConfig {\n api: PortalProductsApi;\n}\n\nconst PortalProductsCoreContext =\n createContext<PortalProductsCoreConfig | null>(null);\n\nexport function PortalProductsCoreProvider({\n api,\n children,\n}: PortalProductsCoreConfig & { children: ReactNode }): JSX.Element {\n return (\n <PortalProductsCoreContext.Provider value={{ api }}>\n {children}\n </PortalProductsCoreContext.Provider>\n );\n}\n\nexport function usePortalProductsApi(): PortalProductsApi {\n const ctx = useContext(PortalProductsCoreContext);\n if (!ctx) {\n throw new Error(\n \"usePortalProductsApi must be used within a <PortalProductsCoreProvider>\",\n );\n }\n return ctx.api;\n}\n","import { useState, useEffect } from \"react\";\n\nexport function useDebounce<T>(value: T, delay: number): T {\n const [debouncedValue, setDebouncedValue] = useState<T>(value);\n\n useEffect(() => {\n const timer = setTimeout(() => {\n setDebouncedValue(value);\n }, delay);\n\n return () => {\n clearTimeout(timer);\n };\n }, [value, delay]);\n\n return debouncedValue;\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport type { portalProducts } from \"../portal-products-api\";\nimport { usePortalProductsApi } from \"../portal-products-api-context\";\n\nconst portalProductKeys = {\n all: [\"portal-products\"] as const,\n list: (params?: portalProducts.CursorPaginationParams) =>\n [...portalProductKeys.all, \"list\", params] as const,\n detail: (id: string | number) =>\n [...portalProductKeys.all, \"detail\", String(id)] as const,\n search: (query: string, params?: portalProducts.CursorPaginationParams) =>\n [...portalProductKeys.all, \"search\", query, params] as const,\n media: (productId: string | number) =>\n [...portalProductKeys.all, \"media\", String(productId)] as const,\n};\n\nexport { portalProductKeys };\n\nexport function usePortalProducts(\n params?: portalProducts.CursorPaginationParams,\n) {\n const api = usePortalProductsApi();\n return useQuery({\n queryKey: portalProductKeys.list(params),\n queryFn: () => api.listProducts(params),\n });\n}\n\nexport function usePortalProduct(\n id: string | number,\n options?: { enabled?: boolean },\n) {\n const api = usePortalProductsApi();\n return useQuery({\n queryKey: portalProductKeys.detail(id),\n queryFn: () => api.getProduct(id),\n enabled: options?.enabled,\n });\n}\n\nexport function usePortalProductSearch(\n query: string,\n params?: portalProducts.CursorPaginationParams & { enabled?: boolean },\n) {\n const api = usePortalProductsApi();\n const { enabled, ...paginationParams } = params ?? {};\n return useQuery({\n queryKey: portalProductKeys.search(query, paginationParams),\n queryFn: () => api.searchProducts(query, paginationParams),\n enabled: enabled ?? query.length > 0,\n });\n}\n\nexport function usePortalProductMedia(\n productId: string | number,\n options?: { enabled?: boolean },\n) {\n const api = usePortalProductsApi();\n return useQuery({\n queryKey: portalProductKeys.media(productId),\n queryFn: () => api.getProductMedia(productId),\n enabled: options?.enabled,\n });\n}\n","import { useState, useMemo, useCallback } from \"react\";\nimport type { portalProducts } from \"../portal-products-api\";\nimport { usePortalProductsApi } from \"../portal-products-api-context\";\nimport { useDebounce } from \"./use-debounce\";\n\nexport interface UsePortalProductCatalogParams {\n perPage?: number;\n}\n\n/** Page param is a cursor string from the BFF, or undefined for the first page. */\nexport type PortalProductPageParam = string | undefined;\n\nexport function usePortalProductCatalog({\n perPage = 25,\n}: UsePortalProductCatalogParams = {}) {\n const api = usePortalProductsApi();\n const [searchTerm, setSearchTerm] = useState(\"\");\n const debouncedSearchTerm = useDebounce(searchTerm, 300);\n const [currentSort, setCurrentSort] = useState<string>(\"created_at_desc\");\n\n const fetchProducts = useCallback(\n async (\n pageParam?: PortalProductPageParam,\n signal?: AbortSignal,\n ): Promise<portalProducts.PortalProductsResponse> => {\n const params: portalProducts.CursorPaginationParams = {\n limit: perPage,\n sort: currentSort,\n };\n if (pageParam !== undefined) params.cursor = pageParam;\n if (signal !== undefined) params.signal = signal;\n\n if (debouncedSearchTerm) {\n return api.searchProducts(debouncedSearchTerm, params);\n }\n return api.listProducts(params);\n },\n [api, debouncedSearchTerm, perPage, currentSort],\n );\n\n const getNextPageParam = useCallback(\n (\n lastPage: portalProducts.PortalProductsResponse,\n _allPages: portalProducts.PortalProductsResponse[],\n lastPageParam: PortalProductPageParam,\n ): PortalProductPageParam => {\n const nextCursor = lastPage.meta?.pagination?.next_cursor ?? undefined;\n // Stop if the API returned the same cursor we just sent (prevents\n // infinite refetch loops when the backend doesn't advance).\n if (nextCursor != null && nextCursor === lastPageParam) {\n return undefined;\n }\n return nextCursor;\n },\n [],\n );\n\n const queryKey = useMemo(\n () => [\n \"portal-product-catalog\",\n debouncedSearchTerm || \"\",\n perPage,\n currentSort,\n ],\n [debouncedSearchTerm, perPage, currentSort],\n );\n\n return {\n searchTerm,\n setSearchTerm,\n debouncedSearchTerm,\n currentSort,\n setCurrentSort,\n fetchProducts,\n getNextPageParam,\n queryKey,\n perPage,\n };\n}\n","import { useMemo } from \"react\";\nimport { usePortalProduct } from \"./use-portal-products\";\n\nexport interface UsePortalProductDetailParams {\n productId: string;\n}\n\nexport function usePortalProductDetail({\n productId,\n}: UsePortalProductDetailParams) {\n const {\n data: productResponse,\n isLoading,\n error,\n } = usePortalProduct(productId);\n\n const product = productResponse?.product;\n\n const images = useMemo(() => {\n if (!product?.images) return [];\n return product.images.map((img, idx) => ({\n id: idx,\n url: img.url ?? \"\",\n alt: img.alt ?? null,\n }));\n }, [product?.images]);\n\n return {\n product,\n isLoading,\n error,\n images,\n };\n}\n","import type { products } from \"../types\";\n\nexport function ensureDefaultSubscriptionPlan(\n plans: readonly products.ProductSubscriptionPlan[],\n): products.ProductSubscriptionPlan[] {\n const activePlans = plans.filter((plan) => plan.active !== false);\n\n if (activePlans.length === 0) {\n return plans.map((plan) => ({ ...plan, default: false }));\n }\n\n const hasActiveDefault = activePlans.some((plan) => plan.default === true);\n\n if (!hasActiveDefault) {\n const planWithLowestId = activePlans.reduce((lowest, current) => {\n const lowestId = lowest.subscription_plan?.id || Infinity;\n const currentId = current.subscription_plan?.id || Infinity;\n return currentId < lowestId ? current : lowest;\n });\n\n return plans.map((plan) => ({\n ...plan,\n default:\n plan.subscription_plan?.id === planWithLowestId.subscription_plan?.id &&\n plan.active !== false,\n }));\n }\n\n return plans.map((plan) => ({\n ...plan,\n default: plan.active !== false ? plan.default : false,\n }));\n}\n\nexport function plansToAttributes(\n plans: readonly products.ProductSubscriptionPlan[],\n): products.ProductSubscriptionPlanAttribute[] {\n return plans.map((plan) => ({\n id: plan.id ?? undefined,\n subscription_plan_id: plan.subscription_plan.id,\n default: plan.default || false,\n active: plan.active !== false,\n }));\n}\n","import { create, type StateCreator } from \"zustand\";\nimport { devtools } from \"zustand/middleware\";\nimport type { products } from \"../types\";\nimport {\n ensureDefaultSubscriptionPlan,\n plansToAttributes,\n} from \"../utils/subscription-plans\";\n\n// Default state\nconst defaultState = {\n id: undefined,\n title: \"\",\n description: \"\",\n introduction: \"\",\n stripped: \"\",\n feature_text: \"\",\n sku: \"\",\n slug: \"\",\n canonical_url: null as string | null,\n image_url: \"\",\n image_path: undefined,\n status: \"draft\",\n publish_at: null,\n price: \"0\",\n commission: 0,\n public: true,\n no_index: false,\n show_reviews: true,\n publish_to_retail_store: true,\n publish_to_rep_store: true,\n publish_to_share_tab: true,\n collection_ids: [],\n tag_ids: [],\n images_attributes: [],\n product_subscription_plans_attributes: [],\n product_subscription_plans: [],\n variants_attributes: [],\n bundle: false,\n track_inventory_on_bundle_items: false,\n product_bundles_attributes: [],\n option_attrs: [],\n options: [],\n metafields_attributes: [],\n metadata: {},\n search_engine_optimizer_attributes: {\n title: \"\",\n description: \"\",\n image_url: \"\",\n image_path: \"\",\n block_crawler: false,\n },\n};\n\ntype ValidationErrors = Partial<Record<string, string>>;\n\nexport type TranslationData = {\n title?: string;\n introduction?: string;\n description?: string;\n feature_text?: string;\n};\n\ntype LanguageTranslations = Record<string, TranslationData>;\ntype TranslationLoadingState = Record<string, boolean>;\n\ninterface UpdateFieldOptions {\n shouldValidate?: boolean;\n shouldClearError?: boolean;\n markDirty?: boolean;\n}\n\ntype ArrayItemType<T> = T extends (infer U)[] ? U : unknown;\n\ntype ProductStoreFields = products.UpdateProduct & {\n product_subscription_plans: products.ProductSubscriptionPlan[];\n track_inventory_on_bundle_items: boolean;\n canonical_url: string | null;\n publish_at: string | null;\n};\n\nexport type ProductStoreState = ProductStoreFields & {\n errors: ValidationErrors;\n isValid: boolean;\n isDirty: boolean;\n translations: LanguageTranslations;\n editedTranslations: LanguageTranslations;\n translationErrors: Record<string, Record<string, string | undefined>>;\n translationLoading: TranslationLoadingState;\n translationsFetched: boolean;\n\n setProduct: (productData: products.Product) => void;\n updateField: <K extends keyof ProductStoreFields>(\n key: K,\n value: ProductStoreFields[K],\n options?: UpdateFieldOptions,\n ) => void;\n updatePartial: (updates: Partial<ProductStoreFields>) => void;\n updateSlug: (slug: string, isManual?: boolean) => void;\n updateSEO: (seo: {\n title?: string;\n description?: string;\n image_url?: string;\n image_path?: string;\n block_crawler?: boolean;\n }) => void;\n updateArrayItem: <K extends keyof ProductStoreFields>(\n arrayKey: K,\n itemId: number | string,\n updatedItem: ArrayItemType<ProductStoreFields[K]>,\n idField?: string,\n ) => void;\n reset: () => void;\n validateField: (field: string) => void;\n validateRequired: () => boolean;\n clearErrors: () => void;\n clearFieldError: (field: string) => void;\n markClean: () => void;\n\n setTranslationLoading: (languageIso: string, loading: boolean) => void;\n setTranslationData: (languageIso: string, data: TranslationData) => void;\n updateTranslationField: (\n languageIso: string,\n field: keyof TranslationData,\n value: string,\n ) => void;\n getOriginalTranslation: (\n languageIso: string,\n field: keyof TranslationData,\n ) => string | undefined;\n getEditedTranslation: (\n languageIso: string,\n field: keyof TranslationData,\n ) => string | undefined;\n setTranslationError: (\n languageIso: string,\n field: keyof TranslationData,\n error?: string,\n ) => void;\n getTranslationError: (\n languageIso: string,\n field: keyof TranslationData,\n ) => string | undefined;\n getTranslation: (\n languageIso: string,\n field: keyof TranslationData,\n ) => string | undefined;\n isTranslationLoading: (languageIso: string) => boolean;\n resetTranslations: () => void;\n setTranslationsFetched: (fetched: boolean) => void;\n};\n\nfunction syncSubscriptionPlans(plans: products.ProductSubscriptionPlan[]): {\n product_subscription_plans: products.ProductSubscriptionPlan[];\n product_subscription_plans_attributes: products.ProductSubscriptionPlanAttribute[];\n} {\n const activePlans = plans.filter((plan) => plan.active !== false);\n const plansWithDefault =\n activePlans.length > 0 ? ensureDefaultSubscriptionPlan(plans) : plans;\n return {\n product_subscription_plans: plansWithDefault,\n product_subscription_plans_attributes: plansToAttributes(plansWithDefault),\n };\n}\n\nconst extractFilenameFromUrl = (imageUrl: string): string => {\n try {\n const url = new URL(imageUrl);\n return url.pathname.split(\"/\").pop() || \"\";\n } catch {\n return imageUrl.split(\"/\").pop()?.split(\"?\")[0] || \"\";\n }\n};\n\nconst createProductStore: StateCreator<ProductStoreState> = (set, get) => ({\n ...defaultState,\n track_inventory_on_bundle_items: false,\n translations: {},\n editedTranslations: {},\n translationErrors: {},\n translationLoading: {},\n translationsFetched: false,\n errors: {},\n isValid: false,\n isDirty: false,\n\n setProduct: (productData: products.Product) => {\n const transformedData: ProductStoreFields = {\n id: productData.id || undefined,\n title: productData.title || \"\",\n description: productData.description || \"\",\n introduction: productData.introduction || \"\",\n stripped: productData.stripped || \"\",\n feature_text: productData.feature_text || \"\",\n sku: productData.sku || \"\",\n slug: productData.slug || \"\",\n canonical_url: productData.canonical_url || null,\n custom_slug: productData.custom_slug || false,\n image_url: productData.image_url || \"\",\n image_path:\n productData.image_path && !productData.image_path.includes(\"undefined\")\n ? productData.image_path\n : productData.image_url\n ? extractFilenameFromUrl(productData.image_url)\n : undefined,\n status: productData.status || \"draft\",\n publish_at: productData.publish_at || null,\n commission:\n typeof productData.commission === \"string\"\n ? parseFloat(productData.commission)\n : productData.commission || 0,\n public: productData.public ?? true,\n no_index: productData.no_index ?? false,\n show_reviews: productData.show_reviews ?? true,\n publish_to_retail_store: productData.publish_to_retail_store,\n publish_to_rep_store: productData.publish_to_rep_store,\n publish_to_share_tab: productData.publish_to_share_tab,\n ...(productData.tax_category_id && {\n tax_category_id: productData.tax_category_id,\n }),\n international_tax_type: productData.international_tax_type || undefined,\n category_id: productData.category_id\n ? parseInt(productData.category_id)\n : productData.category?.id\n ? productData.category.id\n : undefined,\n application_theme_template_id:\n productData.application_theme_template_id || undefined,\n collection_ids: (\n productData.collections as Array<{ id: number }> | undefined\n )?.map((collection) => collection.id),\n tag_ids: Array.isArray(productData.tags)\n ? (productData.tags as Array<{ id: number } | number>)\n .map((tag) => (typeof tag === \"number\" ? tag : tag?.id))\n .filter(Boolean)\n : [],\n search_engine_optimizer_attributes: {\n id: productData.search_engine_optimizer?.id,\n title:\n productData.search_engine_optimizer?.title ||\n productData.title ||\n undefined,\n description: productData.search_engine_optimizer?.description || \"\",\n image_url:\n productData.search_engine_optimizer?.image_url ||\n productData.image_url ||\n \"\",\n image_path:\n productData.search_engine_optimizer?.image_path ||\n productData.image_path ||\n \"\",\n block_crawler:\n productData.search_engine_optimizer?.block_crawler ?? false,\n },\n images_attributes:\n (productData.images as products.ImageAttribute[] | undefined)?.map(\n (img) => ({\n id: img.id,\n position: img.position || 0,\n image_url: img.image_url,\n image_path:\n img.image_path && !img.image_path.includes(\"undefined\")\n ? img.image_path\n : img.image_url\n ? extractFilenameFromUrl(img.image_url)\n : undefined,\n _destroy: false,\n }),\n ) || [],\n ...(productData.images &&\n productData.images.length > 0 && {\n image_path: (() => {\n if (\n productData.image_path &&\n typeof productData.image_path === \"string\" &&\n !productData.image_path.includes(\"undefined\")\n ) {\n return productData.image_path;\n }\n const firstImage = (\n productData.images as products.ImageAttribute[]\n ).find((img) => img.position === 0);\n if (\n firstImage?.image_path &&\n typeof firstImage.image_path === \"string\" &&\n !firstImage.image_path.includes(\"undefined\")\n ) {\n return firstImage.image_path;\n }\n return productData.image_url\n ? extractFilenameFromUrl(productData.image_url)\n : undefined;\n })(),\n }),\n product_subscription_plans: (() => {\n const plans =\n productData?.product_subscription_plans?.map(\n (plan: products.ProductSubscriptionPlan) => ({\n ...plan,\n active: plan?.active,\n }),\n ) || [];\n return plans.length > 0 ? ensureDefaultSubscriptionPlan(plans) : plans;\n })(),\n product_subscription_plans_attributes: (() => {\n const plans =\n productData?.product_subscription_plans?.map(\n (plan: products.ProductSubscriptionPlan) => ({\n ...plan,\n active: plan?.active,\n }),\n ) || [];\n const finalPlans =\n plans.length > 0 ? ensureDefaultSubscriptionPlan(plans) : plans;\n return plansToAttributes(finalPlans);\n })(),\n variants_attributes: productData?.variants\n ?.filter(\n (\n variant: products.Variant,\n ): variant is products.Variant & { id: number } =>\n variant.id !== null && variant.id !== undefined,\n )\n .map((variant) => ({\n id: variant.id,\n title: variant.title ?? productData?.title ?? \"Untitled Variant\",\n option_attrs: variant.option_attrs || [],\n sku: variant.sku || undefined,\n price: variant.price,\n track_quantity: variant.track_quantity ?? false,\n keep_selling: variant.keep_selling ?? false,\n bar_code: variant.bar_code ?? \"\",\n limit_subscription: variant.limit_subscription,\n subscription_max_qty: variant.subscription_max_qty ?? 0,\n customer_limit: variant.customer_limit ?? 0,\n is_master: variant.is_master,\n _destroy: false,\n images_attributes: variant?.images?.map(\n (image: { id?: number; position: number; image_url: string }) => ({\n id: image.id,\n position: image.position || 0,\n image_url: image.image_url,\n _destroy: false,\n }),\n ),\n inventory_levels_attributes: variant?.inventory_levels\n ?.filter(\n (level: products.InventoryLevel) =>\n (level.warehouse_id ?? level.warehouse?.id) != null,\n )\n .map((level: products.InventoryLevel) => ({\n id: level.id,\n available: level.available,\n committed: level.committed,\n on_hand: level.on_hand,\n unavailable: level.unavailable,\n warehouse_id: level.warehouse?.id || 0,\n _destroy: false,\n })),\n variant_countries_attributes: variant?.variant_countries\n ? Object.entries(\n variant.variant_countries as Record<\n string,\n products.VariantCountry\n >,\n ).map(([iso, country]) => ({\n id: country.id ?? 0,\n active: country.active ?? true,\n country_id: country.country_id,\n country_name: country.country_name ?? \"\",\n country_iso: iso,\n price: Number(country.price) || 0,\n subscription_price: Number(country.subscription_price) || 0,\n wholesale: Number(country.wholesale) || 0,\n wholesale_subscription_price:\n Number(country.wholesale_subscription_price) || 0,\n compare_price: Number(country.compare_price) || 0,\n cv: Number(country.cv) || 0,\n qv: Number(country.qv) || 0,\n pc_cv: Number(country.pc_cv) || 0,\n pc_qv: Number(country.pc_qv) || 0,\n cost_of_goods_sold: Number(country.cost_of_goods_sold) || 0,\n currency_code: country.currency_code || null,\n shipping: Number(country.shipping) || 0,\n points: country.points,\n }))\n : [],\n })),\n bundle:\n productData.product_bundles && productData.product_bundles.length > 0,\n track_inventory_on_bundle_items:\n productData.track_inventory_on_bundle_items ?? false,\n product_bundles_attributes: (productData.product_bundles || []).map(\n (bundle: products.ProductBundle) => ({\n id: bundle.id,\n bundled_variant_id: bundle.bundled_variant?.id || 0,\n bundled_variant: {\n title: bundle.bundled_variant?.title || \"\",\n sku: bundle.bundled_variant?.sku || null,\n price: String(bundle.bundled_variant?.price || \"0\"),\n price_in_currency: bundle.bundled_variant?.price_in_currency || \"\",\n currency_code: bundle.bundled_variant?.currency_code,\n product: {\n id: bundle.bundled_variant?.product.id || 0,\n title: bundle.bundled_variant?.product.title || \"\",\n image_url: bundle.bundled_variant?.product.image_url || \"\",\n price: bundle.bundled_variant?.product.price || \"0\",\n price_in_currency:\n bundle.bundled_variant?.product.price_in_currency || \"\",\n cv: bundle.bundled_variant?.product.cv || 0,\n qv: bundle.bundled_variant?.product.qv || 0,\n },\n },\n cv: bundle.cv || 0,\n qv: bundle.qv || 0,\n quantity: bundle.quantity,\n display_externally: bundle.display_externally ?? true,\n _destroy: false,\n }),\n ),\n option_attrs: productData.option_attrs || [],\n options: productData.options || [],\n metafields_attributes: (productData.metafields || []).map(\n (metafield: products.Metafield) => ({\n id: metafield.id,\n namespace: metafield.namespace,\n key: metafield.key,\n value: metafield.value,\n value_type: metafield.value_type,\n _destroy: false,\n }),\n ),\n metadata: productData.metadata || {},\n };\n\n set({\n ...transformedData,\n errors: {},\n isValid: false,\n isDirty: false,\n });\n },\n\n updateSlug: (slug, isManual = true) => {\n set((state: ProductStoreState) => ({\n slug,\n custom_slug: isManual,\n search_engine_optimizer_attributes: {\n ...state.search_engine_optimizer_attributes,\n title: state.search_engine_optimizer_attributes?.title || \"\",\n description:\n state.search_engine_optimizer_attributes?.description || \"\",\n image_url: state.search_engine_optimizer_attributes?.image_url || \"\",\n image_path: state.search_engine_optimizer_attributes?.image_path || \"\",\n block_crawler:\n state.search_engine_optimizer_attributes?.block_crawler ?? false,\n },\n isDirty: true,\n }));\n },\n\n updateSEO: (seo) => {\n set((state: ProductStoreState) => ({\n search_engine_optimizer_attributes: {\n ...state.search_engine_optimizer_attributes,\n title:\n seo.title !== undefined\n ? seo.title\n : state.search_engine_optimizer_attributes?.title || \"\",\n description:\n seo.description !== undefined\n ? seo.description\n : state.search_engine_optimizer_attributes?.description || \"\",\n image_url:\n seo.image_url !== undefined\n ? seo.image_url\n : state.search_engine_optimizer_attributes?.image_url || \"\",\n image_path:\n seo.image_path !== undefined\n ? seo.image_path\n : state.search_engine_optimizer_attributes?.image_path || \"\",\n block_crawler:\n seo.block_crawler !== undefined\n ? seo.block_crawler\n : (state.search_engine_optimizer_attributes?.block_crawler ??\n false),\n },\n isDirty: true,\n }));\n },\n\n updateField: <K extends keyof ProductStoreFields>(\n key: K,\n value: ProductStoreFields[K],\n options?: UpdateFieldOptions,\n ) => {\n const {\n shouldValidate = false,\n shouldClearError = true,\n markDirty = true,\n } = options || {};\n\n set((state: ProductStoreState) => {\n if (key === \"product_subscription_plans\") {\n return {\n ...state,\n ...syncSubscriptionPlans(value as products.ProductSubscriptionPlan[]),\n errors: shouldClearError\n ? { ...state.errors, [key]: undefined }\n : state.errors,\n isDirty: markDirty ? true : state.isDirty,\n };\n }\n\n return {\n ...state,\n [key]: value,\n errors: shouldClearError\n ? { ...state.errors, [key]: undefined }\n : state.errors,\n isDirty: markDirty ? true : state.isDirty,\n };\n });\n\n if (shouldValidate) {\n get().validateField(key as string);\n }\n },\n\n updatePartial: (updates: Partial<ProductStoreFields>) => {\n set((state: ProductStoreState) => {\n if (updates.product_subscription_plans) {\n return {\n ...state,\n ...updates,\n ...syncSubscriptionPlans(updates.product_subscription_plans),\n errors: {\n ...state.errors,\n ...Object.keys(updates).reduce(\n (acc, key) => {\n acc[key] = undefined;\n return acc;\n },\n {} as Record<string, undefined>,\n ),\n },\n isDirty: true,\n };\n }\n\n return {\n ...state,\n ...updates,\n errors: {\n ...state.errors,\n ...Object.keys(updates).reduce(\n (acc, key) => {\n acc[key] = undefined;\n return acc;\n },\n {} as Record<string, undefined>,\n ),\n },\n isDirty: true,\n };\n });\n },\n\n updateArrayItem: <K extends keyof ProductStoreFields>(\n arrayKey: K,\n itemId: number | string,\n updatedItem: ArrayItemType<ProductStoreFields[K]>,\n idField: string = \"id\",\n ) => {\n set((state: ProductStoreState) => {\n const currentArray = Array.isArray(state[arrayKey])\n ? (state[arrayKey] as unknown[])\n : [];\n\n const updatedArray = currentArray.map((item) => {\n if (\n typeof item === \"object\" &&\n item !== null &&\n idField in item &&\n (item as Record<string, unknown>)[idField] === itemId\n ) {\n return updatedItem;\n }\n return item;\n });\n\n if (arrayKey === \"product_subscription_plans\") {\n return {\n ...state,\n ...syncSubscriptionPlans(\n updatedArray as products.ProductSubscriptionPlan[],\n ),\n errors: { ...state.errors, [arrayKey]: undefined },\n isDirty: true,\n };\n }\n\n return {\n ...state,\n [arrayKey]: updatedArray,\n errors: { ...state.errors, [arrayKey]: undefined },\n isDirty: true,\n };\n });\n },\n\n reset: () => {\n set({\n ...defaultState,\n track_inventory_on_bundle_items: false,\n custom_slug: false,\n errors: {},\n isValid: false,\n isDirty: false,\n });\n },\n\n // Validation methods — these provide basic field-level validation.\n // For full schema validation (e.g. Zod), the consumer should call\n // their own validation function against the store state.\n validateField: (field: string) => {\n const fieldValue = get()[field as keyof ProductStoreState];\n const hasValue =\n fieldValue !== undefined && fieldValue !== null && fieldValue !== \"\";\n\n set((state: ProductStoreState) => ({\n errors: {\n ...state.errors,\n [field]: hasValue ? undefined : `${field} is required`,\n },\n isValid:\n hasValue &&\n Object.keys(state.errors).every(\n (key) => key === field || !state.errors[key],\n ),\n }));\n },\n\n validateRequired: () => {\n // Basic validation: check that title exists\n const state = get();\n const errors: ValidationErrors = {};\n\n if (!state.title) {\n errors.title = \"Title is required\";\n }\n\n if (Object.keys(errors).length > 0) {\n set({ errors, isValid: false });\n return false;\n }\n\n set({ errors: {}, isValid: true });\n return true;\n },\n\n clearErrors: () => {\n set({ errors: {}, isValid: false });\n },\n\n clearFieldError: (field: string) => {\n set((state: ProductStoreState) => ({\n errors: { ...state.errors, [field]: undefined },\n }));\n },\n\n markClean: () => {\n set({ isDirty: false });\n },\n\n // Translation methods\n setTranslationLoading: (languageIso: string, loading: boolean) => {\n set((state: ProductStoreState) => ({\n translationLoading: {\n ...state.translationLoading,\n [languageIso]: loading,\n },\n }));\n },\n\n setTranslationData: (languageIso: string, data: TranslationData) => {\n set((state: ProductStoreState) => ({\n translations: {\n ...state.translations,\n [languageIso]: data,\n },\n translationLoading: {\n ...state.translationLoading,\n [languageIso]: false,\n },\n }));\n },\n\n updateTranslationField: (\n languageIso: string,\n field: keyof TranslationData,\n value: string,\n ) => {\n set((state: ProductStoreState) => {\n const originalValue = state.translations[languageIso]?.[field];\n let error: string | undefined;\n\n if (\n field === \"title\" &&\n value === \"\" &&\n originalValue &&\n originalValue.trim() !== \"\"\n ) {\n error = \"Title is required\";\n }\n\n return {\n editedTranslations: {\n ...state.editedTranslations,\n [languageIso]: {\n ...state.editedTranslations[languageIso],\n [field]: value,\n },\n },\n translationErrors: {\n ...state.translationErrors,\n [languageIso]: {\n ...state.translationErrors[languageIso],\n [field]: error,\n },\n },\n };\n });\n },\n\n getTranslation: (languageIso: string, field: keyof TranslationData) => {\n const state = get();\n return (\n state.editedTranslations[languageIso]?.[field] ??\n state.translations[languageIso]?.[field]\n );\n },\n\n getOriginalTranslation: (\n languageIso: string,\n field: keyof TranslationData,\n ) => {\n return get().translations[languageIso]?.[field];\n },\n\n getEditedTranslation: (languageIso: string, field: keyof TranslationData) => {\n return get().editedTranslations[languageIso]?.[field];\n },\n\n setTranslationError: (\n languageIso: string,\n field: keyof TranslationData,\n error?: string,\n ) => {\n set((state: ProductStoreState) => ({\n translationErrors: {\n ...state.translationErrors,\n [languageIso]: {\n ...state.translationErrors[languageIso],\n [field]: error,\n },\n },\n }));\n },\n\n getTranslationError: (languageIso: string, field: keyof TranslationData) => {\n return get().translationErrors[languageIso]?.[field];\n },\n\n isTranslationLoading: (languageIso: string) => {\n return get().translationLoading[languageIso] ?? false;\n },\n\n resetTranslations: () => {\n set({\n translations: {},\n editedTranslations: {},\n translationErrors: {},\n translationLoading: {},\n translationsFetched: false,\n });\n },\n\n setTranslationsFetched: (fetched: boolean) => {\n set({ translationsFetched: fetched });\n },\n});\n\n// Local declare so consumers don't need @types/node while keeping the literal\n// `process.env.NODE_ENV` AST that bundlers (Webpack/Turbopack/Vite) replace.\ndeclare const process: { env?: { NODE_ENV?: string } } | undefined;\nconst isDevEnv =\n typeof process !== \"undefined\" && process.env?.NODE_ENV === \"development\";\n\nexport const useProductStore = isDevEnv\n ? create<ProductStoreState>()(\n devtools(createProductStore, { name: \"product-store\" }),\n )\n : create<ProductStoreState>()(createProductStore);\n","import { create } from \"zustand\";\n\ninterface DraftStore {\n draftData: unknown | null;\n isFromSettings: boolean;\n navigationTarget: string | null;\n\n saveDraft: (data: unknown) => void;\n getDraft: () => unknown | null;\n clearDraft: () => void;\n setFromSettings: (value: boolean) => void;\n setNavigationTarget: (target: string | null) => void;\n reset: () => void;\n}\n\nexport const useDraftStore = create<DraftStore>()((set, get) => ({\n draftData: null,\n isFromSettings: false,\n navigationTarget: null,\n\n saveDraft: (data: unknown) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const formData = data as any;\n const hasContent =\n formData?.title ||\n formData?.description ||\n formData?.sku ||\n (formData?.product_subscription_plans &&\n formData.product_subscription_plans.length > 0);\n\n if (hasContent) {\n set({ draftData: data });\n }\n },\n\n getDraft: () => {\n const { draftData, isFromSettings, navigationTarget } = get();\n\n if (!draftData) {\n return null;\n }\n\n if (isFromSettings && navigationTarget) {\n return draftData;\n }\n\n set({ draftData: null });\n return null;\n },\n\n clearDraft: () => {\n const { draftData } = get();\n if (draftData) {\n set({ draftData: null });\n }\n },\n\n setFromSettings: (value: boolean) => {\n set({ isFromSettings: value });\n },\n\n setNavigationTarget: (target: string | null) => {\n set({ navigationTarget: target });\n },\n\n reset: () => {\n set({ draftData: null, isFromSettings: false, navigationTarget: null });\n },\n}));\n","import type { products } from \"../types\";\n\nexport function createSlug(title: string): string {\n return title\n .trim()\n .toLowerCase()\n .replace(/[^\\w\\s-]/g, \"\")\n .replace(/\\s+/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\n\nexport function stripHtmlTags(html: string): string {\n return html\n .replace(/<[^>]*>/g, \"\")\n .replace(/&[^;]+;/g, \" \")\n .trim();\n}\n\nexport function getVariantImageUrl(\n variant?: {\n primary_image?: string | null;\n image_url?: string | null;\n images?: Array<{ image_url: string }> | null;\n } | null,\n product?: { image_url?: string | null } | null,\n): string {\n if (!variant) return product?.image_url || \"\";\n if (variant.primary_image) return variant.primary_image;\n if (variant.image_url) return variant.image_url;\n if (Array.isArray(variant.images) && variant.images.length > 0) {\n const firstImage = variant.images[0];\n if (firstImage?.image_url) return firstImage.image_url;\n }\n return product?.image_url || \"\";\n}\n\nexport function getProductImageUrl(\n product?: {\n image_url?: string | null;\n images?: Array<{ image_url: string; position?: number }> | null;\n } | null,\n): string | null {\n if (!product) return null;\n if (Array.isArray(product.images) && product.images.length > 0) {\n const sortedImages = [...product.images].sort(\n (a, b) => (a.position ?? 0) - (b.position ?? 0),\n );\n const primaryImage = sortedImages[0];\n if (primaryImage?.image_url) return primaryImage.image_url;\n }\n return product.image_url ?? null;\n}\n\nexport function sanitizeBundleData<\n T extends products.CreateProduct | products.UpdateProduct,\n>(productData: T): T {\n const activeVariants = (productData.variants_attributes || []).filter(\n (variant) => !variant._destroy,\n );\n const hasMultipleVariants = activeVariants.length > 1;\n\n const activeOptions = (productData.options || []).filter(\n (opt) => !opt._destroy,\n );\n const derivedOptionAttrs = [\n ...new Set(activeOptions.map((opt) => opt.title.toLowerCase())),\n ];\n\n // We spread the original data and override specific fields, preserving the\n // runtime shape. The cast to T is safe because we only narrow/replace fields\n // that exist on the base type.\n if (hasMultipleVariants) {\n return {\n ...productData,\n options: undefined,\n option_attrs: derivedOptionAttrs,\n bundle: false,\n product_bundles_attributes: [],\n track_inventory_on_bundle_items: false,\n } as T;\n }\n\n return {\n ...productData,\n options: undefined,\n option_attrs: derivedOptionAttrs,\n } as T;\n}\n\nexport interface ApiErrorShape {\n message?: string;\n error_message?: string;\n status?: number;\n data?: unknown;\n errors?: Record<string, string[]>;\n}\n\nfunction getErrorsFromApiError(\n error: ApiErrorShape,\n): Record<string, string[]> | undefined {\n if (error?.errors && typeof error.errors === \"object\") {\n return error.errors;\n }\n if (error?.data && typeof error.data === \"object\") {\n const data = error.data as Record<string, unknown>;\n const firstKey = Object.keys(data)[0];\n if (firstKey && Array.isArray(data[firstKey])) {\n return data as Record<string, string[]>;\n }\n }\n return undefined;\n}\n\nfunction formatFieldName(fieldName: string): string {\n const SEO_FIELD_LABELS: Record<string, string> = {\n \"search_engine_optimizer.title\": \"SEO Title\",\n \"search_engine_optimizer.description\": \"SEO Description\",\n \"search_engine_optimizer.image_url\": \"SEO Image\",\n };\n\n if (SEO_FIELD_LABELS[fieldName]) return SEO_FIELD_LABELS[fieldName];\n\n const parts = fieldName.split(\".\");\n if (parts.length > 1) {\n return parts\n .map((part, index) =>\n part\n .split(\"_\")\n .map((word, wordIndex) => {\n if (\n (index === 0 && wordIndex === 0) ||\n (index > 0 && wordIndex > 0)\n )\n return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();\n return word.toLowerCase();\n })\n .join(\" \"),\n )\n .join(\" \");\n }\n\n return fieldName\n .split(\"_\")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(\" \");\n}\n\nexport function getErrorMessage(\n error: ApiErrorShape,\n fallbackMessage: string,\n): string {\n if (error?.message && error.message !== \"unprocessable entity\") {\n return error.message;\n }\n\n const errorsObj = getErrorsFromApiError(error);\n if (errorsObj) {\n const firstField = Object.keys(errorsObj)[0];\n if (firstField && errorsObj[firstField]) {\n const fieldErrors = errorsObj[firstField];\n if (\n Array.isArray(fieldErrors) &&\n fieldErrors.length > 0 &&\n fieldErrors[0]\n ) {\n return `${formatFieldName(firstField)} ${fieldErrors[0]}`;\n }\n }\n }\n\n return fallbackMessage;\n}\n\nexport function isSeoError(fieldName: string): boolean {\n return (\n fieldName.startsWith(\"search_engine_optimizer\") || fieldName === \"slug\"\n );\n}\n\nexport function extractSeoErrors(\n error: ApiErrorShape,\n): Array<{ field: string; message: string }> {\n const seoErrors: Array<{ field: string; message: string }> = [];\n const errorsObj = getErrorsFromApiError(error);\n if (errorsObj) {\n for (const fieldName of Object.keys(errorsObj)) {\n if (isSeoError(fieldName) && errorsObj[fieldName]) {\n const fieldErrors = errorsObj[fieldName];\n if (\n Array.isArray(fieldErrors) &&\n fieldErrors.length > 0 &&\n fieldErrors[0]\n ) {\n seoErrors.push({\n field: fieldName,\n message: `${formatFieldName(fieldName)} ${fieldErrors[0].charAt(0).toUpperCase() + fieldErrors[0].slice(1)}`,\n });\n }\n }\n }\n }\n return seoErrors;\n}\n","import type { products } from \"../types\";\n\ntype ProductPriceInput = products.Product | products.ShopProduct;\n\nfunction stripParentheticalText(text: string | undefined): string | null {\n if (!text) return null;\n return text.replace(/\\s*\\([^)]*\\)/g, \"\").trim();\n}\n\nfunction isShopVariantCountry(\n vc: products.VariantCountry | products.ShopVariantCountry | undefined,\n): vc is products.ShopVariantCountry {\n return vc !== undefined && \"display_wholesale_subscription_price\" in vc;\n}\n\nfunction isAdminProduct(\n product: ProductPriceInput,\n): product is products.Product {\n return \"display_price\" in product;\n}\n\nfunction isVariantCountriesRecord(\n vc: unknown,\n): vc is Record<string, products.VariantCountry> {\n return vc !== null && typeof vc === \"object\" && !Array.isArray(vc);\n}\n\nexport function determineProductPrice(\n product: ProductPriceInput,\n countryIso: string,\n): { repPrice: string | null | undefined; price?: string | null } {\n const { variants } = product;\n\n // Get the first active variant for the country, or fall back to first variant\n const selectedVariant =\n variants?.find((v) => {\n if (isVariantCountriesRecord(v.variant_countries)) {\n return v.variant_countries[countryIso]?.active;\n }\n return false;\n }) ||\n variants?.[0] ||\n null;\n\n let variantCountry:\n | products.VariantCountry\n | products.ShopVariantCountry\n | undefined;\n if (countryIso && selectedVariant?.variant_countries) {\n const variantCountries = selectedVariant.variant_countries;\n\n if (Array.isArray(variantCountries)) {\n variantCountry = variantCountries.find(\n (v: products.ShopVariantCountry) => v?.country?.iso === countryIso,\n );\n } else if (isVariantCountriesRecord(variantCountries)) {\n variantCountry = variantCountries[countryIso];\n }\n }\n\n if (selectedVariant?.subscription_only)\n return {\n repPrice: isShopVariantCountry(variantCountry)\n ? variantCountry.display_wholesale_subscription_price\n : undefined,\n };\n\n const price = isShopVariantCountry(variantCountry)\n ? variantCountry.display_price\n : isAdminProduct(product)\n ? product.display_price\n : undefined;\n\n const repPrice = isShopVariantCountry(variantCountry)\n ? variantCountry.display_wholesale\n : undefined;\n return {\n repPrice: stripParentheticalText(repPrice),\n price: price === repPrice ? null : stripParentheticalText(price),\n };\n}\n\nexport function extractPriceFromString(priceString: string): number | null {\n if (!priceString) return null;\n const strippedString = priceString.replace(/[^\\d.]/g, \"\");\n return parseFloat(strippedString);\n}\n","import type React from \"react\";\nimport { ArrowUpDown, Check, Search, X } from \"lucide-react\";\nimport { Input } from \"@fluid-app/ui-primitives\";\nimport { Button } from \"@fluid-app/ui-primitives\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@fluid-app/ui-primitives\";\n\ntype SortOption = {\n label: string;\n value: string;\n};\n\ntype BaseSearchProps = {\n /** Current search value (controlled). */\n searchValue: string;\n /** Called on every keystroke with the new value. */\n onSearchChange: (value: string) => void;\n /** Placeholder text for the search input. */\n placeholder?: string;\n};\n\ntype SearchOnlyProps = BaseSearchProps & {\n sortOptions?: never;\n sortValue?: never;\n onSortChange?: never;\n};\n\ntype WithSortProps = BaseSearchProps & {\n /** Sort options to display in the dropdown. */\n sortOptions: ReadonlyArray<SortOption>;\n /** Currently selected sort value. */\n sortValue: string;\n /** Called when a sort option is selected. */\n onSortChange: (value: string) => void;\n};\n\ntype SearchSortProps = SearchOnlyProps | WithSortProps;\n\nexport type {\n SortOption,\n BaseSearchProps,\n SearchOnlyProps,\n WithSortProps,\n SearchSortProps,\n};\n\nexport function SearchSort({\n searchValue,\n onSearchChange,\n placeholder = \"Search...\",\n sortOptions,\n sortValue,\n onSortChange,\n}: SearchSortProps): React.JSX.Element {\n const activeSort = sortOptions?.find((o) => o.value === sortValue);\n\n return (\n <div className=\"flex items-center gap-2\">\n <div className=\"relative min-w-0 flex-1\">\n <Search className=\"text-muted-foreground pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2\" />\n <Input\n type=\"search\"\n value={searchValue}\n onChange={(e) => onSearchChange(e.target.value)}\n placeholder={placeholder}\n className=\"pl-9 [&::-webkit-search-cancel-button]:hidden\"\n />\n {searchValue.length > 0 && (\n <Button\n variant=\"ghost\"\n size=\"icon-xs\"\n onClick={() => onSearchChange(\"\")}\n aria-label=\"Clear search\"\n className=\"absolute top-1/2 right-2 -translate-y-1/2\"\n >\n <X className=\"size-3\" />\n </Button>\n )}\n </div>\n {sortOptions && sortOptions.length > 0 && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"outline\"\n aria-label={\n activeSort ? `Sort: ${activeSort.label}` : \"Sort options\"\n }\n >\n <ArrowUpDown className=\"size-4\" />\n {activeSort && (\n <span className=\"hidden sm:inline\">{activeSort.label}</span>\n )}\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {sortOptions.map((option) => {\n const isActive = option.value === sortValue;\n return (\n <DropdownMenuItem\n key={option.value}\n onClick={() => onSortChange(option.value)}\n >\n <span className=\"flex-1\">{option.label}</span>\n {isActive && (\n <Check className=\"text-muted-foreground size-4\" />\n )}\n </DropdownMenuItem>\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SearchSort-DwJt03by.mjs","names":[],"sources":["../../../products/core/src/products-core-api-context.tsx","../../../products/core/src/portal-products-api-context.tsx","../../../products/core/src/hooks/use-debounce.ts","../../../products/core/src/hooks/use-portal-products.ts","../../../products/core/src/hooks/use-portal-product-catalog.ts","../../../products/core/src/hooks/use-portal-product-detail.ts","../../../products/core/src/utils/subscription-plans.ts","../../../products/core/src/stores/use-product-store.ts","../../../products/core/src/stores/use-draft-store.ts","../../../products/core/src/utils/product-helpers.ts","../../../products/core/src/utils/product-price.ts","../../../platform/ui-components/src/components/SearchSort.tsx"],"sourcesContent":["import { createContext, useContext, type JSX, type ReactNode } from \"react\";\nimport type { ProductsApi } from \"./products-api\";\n\ninterface ProductsCoreConfig {\n api: ProductsApi;\n}\n\nconst ProductsCoreContext = createContext<ProductsCoreConfig | null>(null);\n\nexport function ProductsCoreProvider({\n api,\n children,\n}: ProductsCoreConfig & { children: ReactNode }): JSX.Element {\n return (\n <ProductsCoreContext.Provider value={{ api }}>\n {children}\n </ProductsCoreContext.Provider>\n );\n}\n\nexport function useProductsApi(): ProductsApi {\n const ctx = useContext(ProductsCoreContext);\n if (!ctx) {\n throw new Error(\n \"useProductsApi must be used within a <ProductsCoreProvider>\",\n );\n }\n return ctx.api;\n}\n","import { createContext, useContext, type JSX, type ReactNode } from \"react\";\nimport type { PortalProductsApi } from \"./portal-products-api\";\n\ninterface PortalProductsCoreConfig {\n api: PortalProductsApi;\n}\n\nconst PortalProductsCoreContext =\n createContext<PortalProductsCoreConfig | null>(null);\n\nexport function PortalProductsCoreProvider({\n api,\n children,\n}: PortalProductsCoreConfig & { children: ReactNode }): JSX.Element {\n return (\n <PortalProductsCoreContext.Provider value={{ api }}>\n {children}\n </PortalProductsCoreContext.Provider>\n );\n}\n\nexport function usePortalProductsApi(): PortalProductsApi {\n const ctx = useContext(PortalProductsCoreContext);\n if (!ctx) {\n throw new Error(\n \"usePortalProductsApi must be used within a <PortalProductsCoreProvider>\",\n );\n }\n return ctx.api;\n}\n","import { useState, useEffect } from \"react\";\n\nexport function useDebounce<T>(value: T, delay: number): T {\n const [debouncedValue, setDebouncedValue] = useState<T>(value);\n\n useEffect(() => {\n const timer = setTimeout(() => {\n setDebouncedValue(value);\n }, delay);\n\n return () => {\n clearTimeout(timer);\n };\n }, [value, delay]);\n\n return debouncedValue;\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport type { portalProducts } from \"../portal-products-api\";\nimport { usePortalProductsApi } from \"../portal-products-api-context\";\n\nconst portalProductKeys = {\n all: [\"portal-products\"] as const,\n list: (params?: portalProducts.CursorPaginationParams) =>\n [...portalProductKeys.all, \"list\", params] as const,\n detail: (id: string | number) =>\n [...portalProductKeys.all, \"detail\", String(id)] as const,\n search: (query: string, params?: portalProducts.CursorPaginationParams) =>\n [...portalProductKeys.all, \"search\", query, params] as const,\n media: (productId: string | number) =>\n [...portalProductKeys.all, \"media\", String(productId)] as const,\n};\n\nexport { portalProductKeys };\n\nexport function usePortalProducts(\n params?: portalProducts.CursorPaginationParams,\n) {\n const api = usePortalProductsApi();\n return useQuery({\n queryKey: portalProductKeys.list(params),\n queryFn: () => api.listProducts(params),\n });\n}\n\nexport function usePortalProduct(\n id: string | number,\n options?: { enabled?: boolean },\n) {\n const api = usePortalProductsApi();\n return useQuery({\n queryKey: portalProductKeys.detail(id),\n queryFn: () => api.getProduct(id),\n enabled: options?.enabled,\n });\n}\n\nexport function usePortalProductSearch(\n query: string,\n params?: portalProducts.CursorPaginationParams & { enabled?: boolean },\n) {\n const api = usePortalProductsApi();\n const { enabled, ...paginationParams } = params ?? {};\n return useQuery({\n queryKey: portalProductKeys.search(query, paginationParams),\n queryFn: () => api.searchProducts(query, paginationParams),\n enabled: enabled ?? query.length > 0,\n });\n}\n\nexport function usePortalProductMedia(\n productId: string | number,\n options?: { enabled?: boolean },\n) {\n const api = usePortalProductsApi();\n return useQuery({\n queryKey: portalProductKeys.media(productId),\n queryFn: () => api.getProductMedia(productId),\n enabled: options?.enabled,\n });\n}\n","import { useState, useMemo, useCallback } from \"react\";\nimport type { portalProducts } from \"../portal-products-api\";\nimport { usePortalProductsApi } from \"../portal-products-api-context\";\nimport { useDebounce } from \"./use-debounce\";\n\nexport interface UsePortalProductCatalogParams {\n perPage?: number;\n}\n\n/** Page param is a cursor string from the BFF, or undefined for the first page. */\nexport type PortalProductPageParam = string | undefined;\n\nexport function usePortalProductCatalog({\n perPage = 25,\n}: UsePortalProductCatalogParams = {}) {\n const api = usePortalProductsApi();\n const [searchTerm, setSearchTerm] = useState(\"\");\n const debouncedSearchTerm = useDebounce(searchTerm, 300);\n const [currentSort, setCurrentSort] = useState<string>(\"created_at_desc\");\n\n const fetchProducts = useCallback(\n async (\n pageParam?: PortalProductPageParam,\n signal?: AbortSignal,\n ): Promise<portalProducts.PortalProductsResponse> => {\n const params: portalProducts.CursorPaginationParams = {\n limit: perPage,\n sort: currentSort,\n };\n if (pageParam !== undefined) params.cursor = pageParam;\n if (signal !== undefined) params.signal = signal;\n\n if (debouncedSearchTerm) {\n return api.searchProducts(debouncedSearchTerm, params);\n }\n return api.listProducts(params);\n },\n [api, debouncedSearchTerm, perPage, currentSort],\n );\n\n const getNextPageParam = useCallback(\n (\n lastPage: portalProducts.PortalProductsResponse,\n _allPages: portalProducts.PortalProductsResponse[],\n lastPageParam: PortalProductPageParam,\n ): PortalProductPageParam => {\n const nextCursor = lastPage.meta?.pagination?.next_cursor ?? undefined;\n // Stop if the API returned the same cursor we just sent (prevents\n // infinite refetch loops when the backend doesn't advance).\n if (nextCursor != null && nextCursor === lastPageParam) {\n return undefined;\n }\n return nextCursor;\n },\n [],\n );\n\n const queryKey = useMemo(\n () => [\n \"portal-product-catalog\",\n debouncedSearchTerm || \"\",\n perPage,\n currentSort,\n ],\n [debouncedSearchTerm, perPage, currentSort],\n );\n\n return {\n searchTerm,\n setSearchTerm,\n debouncedSearchTerm,\n currentSort,\n setCurrentSort,\n fetchProducts,\n getNextPageParam,\n queryKey,\n perPage,\n };\n}\n","import { useMemo } from \"react\";\nimport { usePortalProduct } from \"./use-portal-products\";\n\nexport interface UsePortalProductDetailParams {\n productId: string;\n}\n\nexport function usePortalProductDetail({\n productId,\n}: UsePortalProductDetailParams) {\n const {\n data: productResponse,\n isLoading,\n error,\n } = usePortalProduct(productId);\n\n const product = productResponse?.product;\n\n const images = useMemo(() => {\n if (!product?.images) return [];\n return product.images.map((img, idx) => ({\n id: idx,\n url: img.url ?? \"\",\n alt: img.alt ?? null,\n }));\n }, [product?.images]);\n\n return {\n product,\n isLoading,\n error,\n images,\n };\n}\n","import type { products } from \"../types\";\n\nexport function ensureDefaultSubscriptionPlan(\n plans: readonly products.ProductSubscriptionPlan[],\n): products.ProductSubscriptionPlan[] {\n const activePlans = plans.filter((plan) => plan.active !== false);\n\n if (activePlans.length === 0) {\n return plans.map((plan) => ({ ...plan, default: false }));\n }\n\n const hasActiveDefault = activePlans.some((plan) => plan.default === true);\n\n if (!hasActiveDefault) {\n const planWithLowestId = activePlans.reduce((lowest, current) => {\n const lowestId = lowest.subscription_plan?.id || Infinity;\n const currentId = current.subscription_plan?.id || Infinity;\n return currentId < lowestId ? current : lowest;\n });\n\n return plans.map((plan) => ({\n ...plan,\n default:\n plan.subscription_plan?.id === planWithLowestId.subscription_plan?.id &&\n plan.active !== false,\n }));\n }\n\n return plans.map((plan) => ({\n ...plan,\n default: plan.active !== false ? plan.default : false,\n }));\n}\n\nexport function plansToAttributes(\n plans: readonly products.ProductSubscriptionPlan[],\n): products.ProductSubscriptionPlanAttribute[] {\n return plans.map((plan) => ({\n id: plan.id ?? undefined,\n subscription_plan_id: plan.subscription_plan.id,\n default: plan.default || false,\n active: plan.active !== false,\n }));\n}\n","import { create, type StateCreator } from \"zustand\";\nimport { devtools } from \"zustand/middleware\";\nimport type { products } from \"../types\";\nimport {\n ensureDefaultSubscriptionPlan,\n plansToAttributes,\n} from \"../utils/subscription-plans\";\n\n// Default state\nconst defaultState = {\n id: undefined,\n title: \"\",\n description: \"\",\n introduction: \"\",\n stripped: \"\",\n feature_text: \"\",\n sku: \"\",\n slug: \"\",\n canonical_url: null as string | null,\n image_url: \"\",\n image_path: undefined,\n status: \"draft\",\n publish_at: null,\n price: \"0\",\n commission: 0,\n public: true,\n no_index: false,\n show_reviews: true,\n publish_to_retail_store: true,\n publish_to_rep_store: true,\n publish_to_share_tab: true,\n collection_ids: [],\n tag_ids: [],\n images_attributes: [],\n product_subscription_plans_attributes: [],\n product_subscription_plans: [],\n variants_attributes: [],\n bundle: false,\n track_inventory_on_bundle_items: false,\n product_bundles_attributes: [],\n option_attrs: [],\n options: [],\n metafields_attributes: [],\n metadata: {},\n search_engine_optimizer_attributes: {\n title: \"\",\n description: \"\",\n image_url: \"\",\n image_path: \"\",\n block_crawler: false,\n },\n};\n\ntype ValidationErrors = Partial<Record<string, string>>;\n\nexport type TranslationData = {\n title?: string;\n introduction?: string;\n description?: string;\n feature_text?: string;\n};\n\ntype LanguageTranslations = Record<string, TranslationData>;\ntype TranslationLoadingState = Record<string, boolean>;\n\ninterface UpdateFieldOptions {\n shouldValidate?: boolean;\n shouldClearError?: boolean;\n markDirty?: boolean;\n}\n\ntype ArrayItemType<T> = T extends (infer U)[] ? U : unknown;\n\ntype ProductStoreFields = products.UpdateProduct & {\n product_subscription_plans: products.ProductSubscriptionPlan[];\n track_inventory_on_bundle_items: boolean;\n canonical_url: string | null;\n publish_at: string | null;\n};\n\nexport type ProductStoreState = ProductStoreFields & {\n errors: ValidationErrors;\n isValid: boolean;\n isDirty: boolean;\n translations: LanguageTranslations;\n editedTranslations: LanguageTranslations;\n translationErrors: Record<string, Record<string, string | undefined>>;\n translationLoading: TranslationLoadingState;\n translationsFetched: boolean;\n\n setProduct: (productData: products.Product) => void;\n updateField: <K extends keyof ProductStoreFields>(\n key: K,\n value: ProductStoreFields[K],\n options?: UpdateFieldOptions,\n ) => void;\n updatePartial: (updates: Partial<ProductStoreFields>) => void;\n updateSlug: (slug: string, isManual?: boolean) => void;\n updateSEO: (seo: {\n title?: string;\n description?: string;\n image_url?: string;\n image_path?: string;\n block_crawler?: boolean;\n }) => void;\n updateArrayItem: <K extends keyof ProductStoreFields>(\n arrayKey: K,\n itemId: number | string,\n updatedItem: ArrayItemType<ProductStoreFields[K]>,\n idField?: string,\n ) => void;\n reset: () => void;\n validateField: (field: string) => void;\n validateRequired: () => boolean;\n clearErrors: () => void;\n clearFieldError: (field: string) => void;\n markClean: () => void;\n\n setTranslationLoading: (languageIso: string, loading: boolean) => void;\n setTranslationData: (languageIso: string, data: TranslationData) => void;\n updateTranslationField: (\n languageIso: string,\n field: keyof TranslationData,\n value: string,\n ) => void;\n getOriginalTranslation: (\n languageIso: string,\n field: keyof TranslationData,\n ) => string | undefined;\n getEditedTranslation: (\n languageIso: string,\n field: keyof TranslationData,\n ) => string | undefined;\n setTranslationError: (\n languageIso: string,\n field: keyof TranslationData,\n error?: string,\n ) => void;\n getTranslationError: (\n languageIso: string,\n field: keyof TranslationData,\n ) => string | undefined;\n getTranslation: (\n languageIso: string,\n field: keyof TranslationData,\n ) => string | undefined;\n isTranslationLoading: (languageIso: string) => boolean;\n resetTranslations: () => void;\n setTranslationsFetched: (fetched: boolean) => void;\n};\n\nfunction syncSubscriptionPlans(plans: products.ProductSubscriptionPlan[]): {\n product_subscription_plans: products.ProductSubscriptionPlan[];\n product_subscription_plans_attributes: products.ProductSubscriptionPlanAttribute[];\n} {\n const activePlans = plans.filter((plan) => plan.active !== false);\n const plansWithDefault =\n activePlans.length > 0 ? ensureDefaultSubscriptionPlan(plans) : plans;\n return {\n product_subscription_plans: plansWithDefault,\n product_subscription_plans_attributes: plansToAttributes(plansWithDefault),\n };\n}\n\nconst extractFilenameFromUrl = (imageUrl: string): string => {\n try {\n const url = new URL(imageUrl);\n return url.pathname.split(\"/\").pop() || \"\";\n } catch {\n return imageUrl.split(\"/\").pop()?.split(\"?\")[0] || \"\";\n }\n};\n\nconst createProductStore: StateCreator<ProductStoreState> = (set, get) => ({\n ...defaultState,\n track_inventory_on_bundle_items: false,\n translations: {},\n editedTranslations: {},\n translationErrors: {},\n translationLoading: {},\n translationsFetched: false,\n errors: {},\n isValid: false,\n isDirty: false,\n\n setProduct: (productData: products.Product) => {\n const transformedData: ProductStoreFields = {\n id: productData.id || undefined,\n title: productData.title || \"\",\n description: productData.description || \"\",\n introduction: productData.introduction || \"\",\n stripped: productData.stripped || \"\",\n feature_text: productData.feature_text || \"\",\n sku: productData.sku || \"\",\n slug: productData.slug || \"\",\n canonical_url: productData.canonical_url || null,\n custom_slug: productData.custom_slug || false,\n image_url: productData.image_url || \"\",\n image_path:\n productData.image_path && !productData.image_path.includes(\"undefined\")\n ? productData.image_path\n : productData.image_url\n ? extractFilenameFromUrl(productData.image_url)\n : undefined,\n status: productData.status || \"draft\",\n publish_at: productData.publish_at || null,\n commission:\n typeof productData.commission === \"string\"\n ? parseFloat(productData.commission)\n : productData.commission || 0,\n public: productData.public ?? true,\n no_index: productData.no_index ?? false,\n show_reviews: productData.show_reviews ?? true,\n publish_to_retail_store: productData.publish_to_retail_store,\n publish_to_rep_store: productData.publish_to_rep_store,\n publish_to_share_tab: productData.publish_to_share_tab,\n ...(productData.tax_category_id && {\n tax_category_id: productData.tax_category_id,\n }),\n international_tax_type: productData.international_tax_type || undefined,\n category_id: productData.category_id\n ? parseInt(productData.category_id)\n : productData.category?.id\n ? productData.category.id\n : undefined,\n application_theme_template_id:\n productData.application_theme_template_id || undefined,\n collection_ids: (\n productData.collections as Array<{ id: number }> | undefined\n )?.map((collection) => collection.id),\n tag_ids: Array.isArray(productData.tags)\n ? (productData.tags as Array<{ id: number } | number>)\n .map((tag) => (typeof tag === \"number\" ? tag : tag?.id))\n .filter(Boolean)\n : [],\n search_engine_optimizer_attributes: {\n id: productData.search_engine_optimizer?.id,\n title:\n productData.search_engine_optimizer?.title ||\n productData.title ||\n undefined,\n description: productData.search_engine_optimizer?.description || \"\",\n image_url:\n productData.search_engine_optimizer?.image_url ||\n productData.image_url ||\n \"\",\n image_path:\n productData.search_engine_optimizer?.image_path ||\n productData.image_path ||\n \"\",\n block_crawler:\n productData.search_engine_optimizer?.block_crawler ?? false,\n },\n images_attributes:\n (productData.images as products.ImageAttribute[] | undefined)?.map(\n (img) => ({\n id: img.id,\n position: img.position || 0,\n image_url: img.image_url,\n image_path:\n img.image_path && !img.image_path.includes(\"undefined\")\n ? img.image_path\n : img.image_url\n ? extractFilenameFromUrl(img.image_url)\n : undefined,\n _destroy: false,\n }),\n ) || [],\n ...(productData.images &&\n productData.images.length > 0 && {\n image_path: (() => {\n if (\n productData.image_path &&\n typeof productData.image_path === \"string\" &&\n !productData.image_path.includes(\"undefined\")\n ) {\n return productData.image_path;\n }\n const firstImage = (\n productData.images as products.ImageAttribute[]\n ).find((img) => img.position === 0);\n if (\n firstImage?.image_path &&\n typeof firstImage.image_path === \"string\" &&\n !firstImage.image_path.includes(\"undefined\")\n ) {\n return firstImage.image_path;\n }\n return productData.image_url\n ? extractFilenameFromUrl(productData.image_url)\n : undefined;\n })(),\n }),\n product_subscription_plans: (() => {\n const plans =\n productData?.product_subscription_plans?.map(\n (plan: products.ProductSubscriptionPlan) => ({\n ...plan,\n active: plan?.active,\n }),\n ) || [];\n return plans.length > 0 ? ensureDefaultSubscriptionPlan(plans) : plans;\n })(),\n product_subscription_plans_attributes: (() => {\n const plans =\n productData?.product_subscription_plans?.map(\n (plan: products.ProductSubscriptionPlan) => ({\n ...plan,\n active: plan?.active,\n }),\n ) || [];\n const finalPlans =\n plans.length > 0 ? ensureDefaultSubscriptionPlan(plans) : plans;\n return plansToAttributes(finalPlans);\n })(),\n variants_attributes: productData?.variants\n ?.filter(\n (\n variant: products.Variant,\n ): variant is products.Variant & { id: number } =>\n variant.id !== null && variant.id !== undefined,\n )\n .map((variant) => ({\n id: variant.id,\n title: variant.title ?? productData?.title ?? \"Untitled Variant\",\n option_attrs: variant.option_attrs || [],\n sku: variant.sku || undefined,\n price: variant.price,\n track_quantity: variant.track_quantity ?? false,\n keep_selling: variant.keep_selling ?? false,\n bar_code: variant.bar_code ?? \"\",\n limit_subscription: variant.limit_subscription,\n subscription_max_qty: variant.subscription_max_qty ?? 0,\n customer_limit: variant.customer_limit ?? 0,\n is_master: variant.is_master,\n _destroy: false,\n images_attributes: variant?.images?.map(\n (image: { id?: number; position: number; image_url: string }) => ({\n id: image.id,\n position: image.position || 0,\n image_url: image.image_url,\n _destroy: false,\n }),\n ),\n inventory_levels_attributes: variant?.inventory_levels\n ?.filter(\n (level: products.InventoryLevel) =>\n (level.warehouse_id ?? level.warehouse?.id) != null,\n )\n .map((level: products.InventoryLevel) => ({\n id: level.id,\n available: level.available,\n committed: level.committed,\n on_hand: level.on_hand,\n unavailable: level.unavailable,\n warehouse_id: level.warehouse?.id || 0,\n _destroy: false,\n })),\n variant_countries_attributes: variant?.variant_countries\n ? Object.entries(\n variant.variant_countries as Record<\n string,\n products.VariantCountry\n >,\n ).map(([iso, country]) => ({\n id: country.id ?? 0,\n active: country.active ?? true,\n country_id: country.country_id,\n country_name: country.country_name ?? \"\",\n country_iso: iso,\n price: Number(country.price) || 0,\n subscription_price: Number(country.subscription_price) || 0,\n wholesale: Number(country.wholesale) || 0,\n wholesale_subscription_price:\n Number(country.wholesale_subscription_price) || 0,\n compare_price: Number(country.compare_price) || 0,\n cv: Number(country.cv) || 0,\n qv: Number(country.qv) || 0,\n pc_cv: Number(country.pc_cv) || 0,\n pc_qv: Number(country.pc_qv) || 0,\n cost_of_goods_sold: Number(country.cost_of_goods_sold) || 0,\n currency_code: country.currency_code || null,\n shipping: Number(country.shipping) || 0,\n points: country.points,\n }))\n : [],\n })),\n bundle:\n productData.product_bundles && productData.product_bundles.length > 0,\n track_inventory_on_bundle_items:\n productData.track_inventory_on_bundle_items ?? false,\n product_bundles_attributes: (productData.product_bundles || []).map(\n (bundle: products.ProductBundle) => ({\n id: bundle.id,\n bundled_variant_id: bundle.bundled_variant?.id || 0,\n bundled_variant: {\n title: bundle.bundled_variant?.title || \"\",\n sku: bundle.bundled_variant?.sku || null,\n price: String(bundle.bundled_variant?.price || \"0\"),\n price_in_currency: bundle.bundled_variant?.price_in_currency || \"\",\n currency_code: bundle.bundled_variant?.currency_code,\n product: {\n id: bundle.bundled_variant?.product.id || 0,\n title: bundle.bundled_variant?.product.title || \"\",\n image_url: bundle.bundled_variant?.product.image_url || \"\",\n price: bundle.bundled_variant?.product.price || \"0\",\n price_in_currency:\n bundle.bundled_variant?.product.price_in_currency || \"\",\n cv: bundle.bundled_variant?.product.cv || 0,\n qv: bundle.bundled_variant?.product.qv || 0,\n },\n },\n cv: bundle.cv || 0,\n qv: bundle.qv || 0,\n quantity: bundle.quantity,\n display_externally: bundle.display_externally ?? true,\n _destroy: false,\n }),\n ),\n option_attrs: productData.option_attrs || [],\n options: productData.options || [],\n metafields_attributes: (productData.metafields || []).map(\n (metafield: products.Metafield) => ({\n id: metafield.id,\n namespace: metafield.namespace,\n key: metafield.key,\n value: metafield.value,\n value_type: metafield.value_type,\n _destroy: false,\n }),\n ),\n metadata: productData.metadata || {},\n };\n\n set({\n ...transformedData,\n errors: {},\n isValid: false,\n isDirty: false,\n });\n },\n\n updateSlug: (slug, isManual = true) => {\n set((state: ProductStoreState) => ({\n slug,\n custom_slug: isManual,\n search_engine_optimizer_attributes: {\n ...state.search_engine_optimizer_attributes,\n title: state.search_engine_optimizer_attributes?.title || \"\",\n description:\n state.search_engine_optimizer_attributes?.description || \"\",\n image_url: state.search_engine_optimizer_attributes?.image_url || \"\",\n image_path: state.search_engine_optimizer_attributes?.image_path || \"\",\n block_crawler:\n state.search_engine_optimizer_attributes?.block_crawler ?? false,\n },\n isDirty: true,\n }));\n },\n\n updateSEO: (seo) => {\n set((state: ProductStoreState) => ({\n search_engine_optimizer_attributes: {\n ...state.search_engine_optimizer_attributes,\n title:\n seo.title !== undefined\n ? seo.title\n : state.search_engine_optimizer_attributes?.title || \"\",\n description:\n seo.description !== undefined\n ? seo.description\n : state.search_engine_optimizer_attributes?.description || \"\",\n image_url:\n seo.image_url !== undefined\n ? seo.image_url\n : state.search_engine_optimizer_attributes?.image_url || \"\",\n image_path:\n seo.image_path !== undefined\n ? seo.image_path\n : state.search_engine_optimizer_attributes?.image_path || \"\",\n block_crawler:\n seo.block_crawler !== undefined\n ? seo.block_crawler\n : (state.search_engine_optimizer_attributes?.block_crawler ??\n false),\n },\n isDirty: true,\n }));\n },\n\n updateField: <K extends keyof ProductStoreFields>(\n key: K,\n value: ProductStoreFields[K],\n options?: UpdateFieldOptions,\n ) => {\n const {\n shouldValidate = false,\n shouldClearError = true,\n markDirty = true,\n } = options || {};\n\n set((state: ProductStoreState) => {\n if (key === \"product_subscription_plans\") {\n return {\n ...state,\n ...syncSubscriptionPlans(value as products.ProductSubscriptionPlan[]),\n errors: shouldClearError\n ? { ...state.errors, [key]: undefined }\n : state.errors,\n isDirty: markDirty ? true : state.isDirty,\n };\n }\n\n return {\n ...state,\n [key]: value,\n errors: shouldClearError\n ? { ...state.errors, [key]: undefined }\n : state.errors,\n isDirty: markDirty ? true : state.isDirty,\n };\n });\n\n if (shouldValidate) {\n get().validateField(key as string);\n }\n },\n\n updatePartial: (updates: Partial<ProductStoreFields>) => {\n set((state: ProductStoreState) => {\n if (updates.product_subscription_plans) {\n return {\n ...state,\n ...updates,\n ...syncSubscriptionPlans(updates.product_subscription_plans),\n errors: {\n ...state.errors,\n ...Object.keys(updates).reduce(\n (acc, key) => {\n acc[key] = undefined;\n return acc;\n },\n {} as Record<string, undefined>,\n ),\n },\n isDirty: true,\n };\n }\n\n return {\n ...state,\n ...updates,\n errors: {\n ...state.errors,\n ...Object.keys(updates).reduce(\n (acc, key) => {\n acc[key] = undefined;\n return acc;\n },\n {} as Record<string, undefined>,\n ),\n },\n isDirty: true,\n };\n });\n },\n\n updateArrayItem: <K extends keyof ProductStoreFields>(\n arrayKey: K,\n itemId: number | string,\n updatedItem: ArrayItemType<ProductStoreFields[K]>,\n idField: string = \"id\",\n ) => {\n set((state: ProductStoreState) => {\n const currentArray = Array.isArray(state[arrayKey])\n ? (state[arrayKey] as unknown[])\n : [];\n\n const updatedArray = currentArray.map((item) => {\n if (\n typeof item === \"object\" &&\n item !== null &&\n idField in item &&\n (item as Record<string, unknown>)[idField] === itemId\n ) {\n return updatedItem;\n }\n return item;\n });\n\n if (arrayKey === \"product_subscription_plans\") {\n return {\n ...state,\n ...syncSubscriptionPlans(\n updatedArray as products.ProductSubscriptionPlan[],\n ),\n errors: { ...state.errors, [arrayKey]: undefined },\n isDirty: true,\n };\n }\n\n return {\n ...state,\n [arrayKey]: updatedArray,\n errors: { ...state.errors, [arrayKey]: undefined },\n isDirty: true,\n };\n });\n },\n\n reset: () => {\n set({\n ...defaultState,\n track_inventory_on_bundle_items: false,\n custom_slug: false,\n errors: {},\n isValid: false,\n isDirty: false,\n });\n },\n\n // Validation methods — these provide basic field-level validation.\n // For full schema validation (e.g. Zod), the consumer should call\n // their own validation function against the store state.\n validateField: (field: string) => {\n const fieldValue = get()[field as keyof ProductStoreState];\n const hasValue =\n fieldValue !== undefined && fieldValue !== null && fieldValue !== \"\";\n\n set((state: ProductStoreState) => ({\n errors: {\n ...state.errors,\n [field]: hasValue ? undefined : `${field} is required`,\n },\n isValid:\n hasValue &&\n Object.keys(state.errors).every(\n (key) => key === field || !state.errors[key],\n ),\n }));\n },\n\n validateRequired: () => {\n // Basic validation: check that title exists\n const state = get();\n const errors: ValidationErrors = {};\n\n if (!state.title) {\n errors.title = \"Title is required\";\n }\n\n if (Object.keys(errors).length > 0) {\n set({ errors, isValid: false });\n return false;\n }\n\n set({ errors: {}, isValid: true });\n return true;\n },\n\n clearErrors: () => {\n set({ errors: {}, isValid: false });\n },\n\n clearFieldError: (field: string) => {\n set((state: ProductStoreState) => ({\n errors: { ...state.errors, [field]: undefined },\n }));\n },\n\n markClean: () => {\n set({ isDirty: false });\n },\n\n // Translation methods\n setTranslationLoading: (languageIso: string, loading: boolean) => {\n set((state: ProductStoreState) => ({\n translationLoading: {\n ...state.translationLoading,\n [languageIso]: loading,\n },\n }));\n },\n\n setTranslationData: (languageIso: string, data: TranslationData) => {\n set((state: ProductStoreState) => ({\n translations: {\n ...state.translations,\n [languageIso]: data,\n },\n translationLoading: {\n ...state.translationLoading,\n [languageIso]: false,\n },\n }));\n },\n\n updateTranslationField: (\n languageIso: string,\n field: keyof TranslationData,\n value: string,\n ) => {\n set((state: ProductStoreState) => {\n const originalValue = state.translations[languageIso]?.[field];\n let error: string | undefined;\n\n if (\n field === \"title\" &&\n value === \"\" &&\n originalValue &&\n originalValue.trim() !== \"\"\n ) {\n error = \"Title is required\";\n }\n\n return {\n editedTranslations: {\n ...state.editedTranslations,\n [languageIso]: {\n ...state.editedTranslations[languageIso],\n [field]: value,\n },\n },\n translationErrors: {\n ...state.translationErrors,\n [languageIso]: {\n ...state.translationErrors[languageIso],\n [field]: error,\n },\n },\n };\n });\n },\n\n getTranslation: (languageIso: string, field: keyof TranslationData) => {\n const state = get();\n return (\n state.editedTranslations[languageIso]?.[field] ??\n state.translations[languageIso]?.[field]\n );\n },\n\n getOriginalTranslation: (\n languageIso: string,\n field: keyof TranslationData,\n ) => {\n return get().translations[languageIso]?.[field];\n },\n\n getEditedTranslation: (languageIso: string, field: keyof TranslationData) => {\n return get().editedTranslations[languageIso]?.[field];\n },\n\n setTranslationError: (\n languageIso: string,\n field: keyof TranslationData,\n error?: string,\n ) => {\n set((state: ProductStoreState) => ({\n translationErrors: {\n ...state.translationErrors,\n [languageIso]: {\n ...state.translationErrors[languageIso],\n [field]: error,\n },\n },\n }));\n },\n\n getTranslationError: (languageIso: string, field: keyof TranslationData) => {\n return get().translationErrors[languageIso]?.[field];\n },\n\n isTranslationLoading: (languageIso: string) => {\n return get().translationLoading[languageIso] ?? false;\n },\n\n resetTranslations: () => {\n set({\n translations: {},\n editedTranslations: {},\n translationErrors: {},\n translationLoading: {},\n translationsFetched: false,\n });\n },\n\n setTranslationsFetched: (fetched: boolean) => {\n set({ translationsFetched: fetched });\n },\n});\n\n// Local declare so consumers don't need @types/node while keeping the literal\n// `process.env.NODE_ENV` AST that bundlers (Webpack/Turbopack/Vite) replace.\ndeclare const process: { env?: { NODE_ENV?: string } } | undefined;\nconst isDevEnv =\n typeof process !== \"undefined\" && process.env?.NODE_ENV === \"development\";\n\nexport const useProductStore = isDevEnv\n ? create<ProductStoreState>()(\n devtools(createProductStore, { name: \"product-store\" }),\n )\n : create<ProductStoreState>()(createProductStore);\n","import { create } from \"zustand\";\n\ninterface DraftStore {\n draftData: unknown | null;\n isFromSettings: boolean;\n navigationTarget: string | null;\n\n saveDraft: (data: unknown) => void;\n getDraft: () => unknown | null;\n clearDraft: () => void;\n setFromSettings: (value: boolean) => void;\n setNavigationTarget: (target: string | null) => void;\n reset: () => void;\n}\n\nexport const useDraftStore = create<DraftStore>()((set, get) => ({\n draftData: null,\n isFromSettings: false,\n navigationTarget: null,\n\n saveDraft: (data: unknown) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const formData = data as any;\n const hasContent =\n formData?.title ||\n formData?.description ||\n formData?.sku ||\n (formData?.product_subscription_plans &&\n formData.product_subscription_plans.length > 0);\n\n if (hasContent) {\n set({ draftData: data });\n }\n },\n\n getDraft: () => {\n const { draftData, isFromSettings, navigationTarget } = get();\n\n if (!draftData) {\n return null;\n }\n\n if (isFromSettings && navigationTarget) {\n return draftData;\n }\n\n set({ draftData: null });\n return null;\n },\n\n clearDraft: () => {\n const { draftData } = get();\n if (draftData) {\n set({ draftData: null });\n }\n },\n\n setFromSettings: (value: boolean) => {\n set({ isFromSettings: value });\n },\n\n setNavigationTarget: (target: string | null) => {\n set({ navigationTarget: target });\n },\n\n reset: () => {\n set({ draftData: null, isFromSettings: false, navigationTarget: null });\n },\n}));\n","import type { products } from \"../types\";\n\nexport function createSlug(title: string): string {\n return title\n .trim()\n .toLowerCase()\n .replace(/[^\\w\\s-]/g, \"\")\n .replace(/\\s+/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\n\nexport function stripHtmlTags(html: string): string {\n return html\n .replace(/<[^>]*>/g, \"\")\n .replace(/&[^;]+;/g, \" \")\n .trim();\n}\n\nexport function getVariantImageUrl(\n variant?: {\n primary_image?: string | null;\n image_url?: string | null;\n images?: Array<{ image_url: string }> | null;\n } | null,\n product?: { image_url?: string | null } | null,\n): string {\n if (!variant) return product?.image_url || \"\";\n if (variant.primary_image) return variant.primary_image;\n if (variant.image_url) return variant.image_url;\n if (Array.isArray(variant.images) && variant.images.length > 0) {\n const firstImage = variant.images[0];\n if (firstImage?.image_url) return firstImage.image_url;\n }\n return product?.image_url || \"\";\n}\n\nexport function getProductImageUrl(\n product?: {\n image_url?: string | null;\n images?: Array<{ image_url: string; position?: number }> | null;\n } | null,\n): string | null {\n if (!product) return null;\n if (Array.isArray(product.images) && product.images.length > 0) {\n const sortedImages = [...product.images].sort(\n (a, b) => (a.position ?? 0) - (b.position ?? 0),\n );\n const primaryImage = sortedImages[0];\n if (primaryImage?.image_url) return primaryImage.image_url;\n }\n return product.image_url ?? null;\n}\n\nexport function sanitizeBundleData<\n T extends products.CreateProduct | products.UpdateProduct,\n>(productData: T): T {\n const activeVariants = (productData.variants_attributes || []).filter(\n (variant) => !variant._destroy,\n );\n const hasMultipleVariants = activeVariants.length > 1;\n\n const activeOptions = (productData.options || []).filter(\n (opt) => !opt._destroy,\n );\n const derivedOptionAttrs = [\n ...new Set(activeOptions.map((opt) => opt.title.toLowerCase())),\n ];\n\n // We spread the original data and override specific fields, preserving the\n // runtime shape. The cast to T is safe because we only narrow/replace fields\n // that exist on the base type.\n if (hasMultipleVariants) {\n return {\n ...productData,\n options: undefined,\n option_attrs: derivedOptionAttrs,\n bundle: false,\n product_bundles_attributes: [],\n track_inventory_on_bundle_items: false,\n } as T;\n }\n\n return {\n ...productData,\n options: undefined,\n option_attrs: derivedOptionAttrs,\n } as T;\n}\n\nexport interface ApiErrorShape {\n message?: string;\n error_message?: string;\n status?: number;\n data?: unknown;\n errors?: Record<string, string[]>;\n}\n\nfunction getErrorsFromApiError(\n error: ApiErrorShape,\n): Record<string, string[]> | undefined {\n if (error?.errors && typeof error.errors === \"object\") {\n return error.errors;\n }\n if (error?.data && typeof error.data === \"object\") {\n const data = error.data as Record<string, unknown>;\n const firstKey = Object.keys(data)[0];\n if (firstKey && Array.isArray(data[firstKey])) {\n return data as Record<string, string[]>;\n }\n }\n return undefined;\n}\n\nfunction formatFieldName(fieldName: string): string {\n const SEO_FIELD_LABELS: Record<string, string> = {\n \"search_engine_optimizer.title\": \"SEO Title\",\n \"search_engine_optimizer.description\": \"SEO Description\",\n \"search_engine_optimizer.image_url\": \"SEO Image\",\n };\n\n if (SEO_FIELD_LABELS[fieldName]) return SEO_FIELD_LABELS[fieldName];\n\n const parts = fieldName.split(\".\");\n if (parts.length > 1) {\n return parts\n .map((part, index) =>\n part\n .split(\"_\")\n .map((word, wordIndex) => {\n if (\n (index === 0 && wordIndex === 0) ||\n (index > 0 && wordIndex > 0)\n )\n return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();\n return word.toLowerCase();\n })\n .join(\" \"),\n )\n .join(\" \");\n }\n\n return fieldName\n .split(\"_\")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(\" \");\n}\n\nexport function getErrorMessage(\n error: ApiErrorShape,\n fallbackMessage: string,\n): string {\n if (error?.message && error.message !== \"unprocessable entity\") {\n return error.message;\n }\n\n const errorsObj = getErrorsFromApiError(error);\n if (errorsObj) {\n const firstField = Object.keys(errorsObj)[0];\n if (firstField && errorsObj[firstField]) {\n const fieldErrors = errorsObj[firstField];\n if (\n Array.isArray(fieldErrors) &&\n fieldErrors.length > 0 &&\n fieldErrors[0]\n ) {\n return `${formatFieldName(firstField)} ${fieldErrors[0]}`;\n }\n }\n }\n\n return fallbackMessage;\n}\n\nexport function isSeoError(fieldName: string): boolean {\n return (\n fieldName.startsWith(\"search_engine_optimizer\") || fieldName === \"slug\"\n );\n}\n\nexport function extractSeoErrors(\n error: ApiErrorShape,\n): Array<{ field: string; message: string }> {\n const seoErrors: Array<{ field: string; message: string }> = [];\n const errorsObj = getErrorsFromApiError(error);\n if (errorsObj) {\n for (const fieldName of Object.keys(errorsObj)) {\n if (isSeoError(fieldName) && errorsObj[fieldName]) {\n const fieldErrors = errorsObj[fieldName];\n if (\n Array.isArray(fieldErrors) &&\n fieldErrors.length > 0 &&\n fieldErrors[0]\n ) {\n seoErrors.push({\n field: fieldName,\n message: `${formatFieldName(fieldName)} ${fieldErrors[0].charAt(0).toUpperCase() + fieldErrors[0].slice(1)}`,\n });\n }\n }\n }\n }\n return seoErrors;\n}\n","import type { products } from \"../types\";\n\ntype ProductPriceInput = products.Product | products.ShopProduct;\n\nfunction stripParentheticalText(text: string | undefined): string | null {\n if (!text) return null;\n return text.replace(/\\s*\\([^)]*\\)/g, \"\").trim();\n}\n\nfunction isShopVariantCountry(\n vc: products.VariantCountry | products.ShopVariantCountry | undefined,\n): vc is products.ShopVariantCountry {\n return vc !== undefined && \"display_wholesale_subscription_price\" in vc;\n}\n\nfunction isAdminProduct(\n product: ProductPriceInput,\n): product is products.Product {\n return \"display_price\" in product;\n}\n\nfunction isVariantCountriesRecord(\n vc: unknown,\n): vc is Record<string, products.VariantCountry> {\n return vc !== null && typeof vc === \"object\" && !Array.isArray(vc);\n}\n\nexport function determineProductPrice(\n product: ProductPriceInput,\n countryIso: string,\n): { repPrice: string | null | undefined; price?: string | null } {\n const { variants } = product;\n\n // Get the first active variant for the country, or fall back to first variant\n const selectedVariant =\n variants?.find((v) => {\n if (isVariantCountriesRecord(v.variant_countries)) {\n return v.variant_countries[countryIso]?.active;\n }\n return false;\n }) ||\n variants?.[0] ||\n null;\n\n let variantCountry:\n | products.VariantCountry\n | products.ShopVariantCountry\n | undefined;\n if (countryIso && selectedVariant?.variant_countries) {\n const variantCountries = selectedVariant.variant_countries;\n\n if (Array.isArray(variantCountries)) {\n variantCountry = variantCountries.find(\n (v: products.ShopVariantCountry) => v?.country?.iso === countryIso,\n );\n } else if (isVariantCountriesRecord(variantCountries)) {\n variantCountry = variantCountries[countryIso];\n }\n }\n\n if (selectedVariant?.subscription_only)\n return {\n repPrice: isShopVariantCountry(variantCountry)\n ? variantCountry.display_wholesale_subscription_price\n : undefined,\n };\n\n const price = isShopVariantCountry(variantCountry)\n ? variantCountry.display_price\n : isAdminProduct(product)\n ? product.display_price\n : undefined;\n\n const repPrice = isShopVariantCountry(variantCountry)\n ? variantCountry.display_wholesale\n : undefined;\n return {\n repPrice: stripParentheticalText(repPrice),\n price: price === repPrice ? null : stripParentheticalText(price),\n };\n}\n\nexport function extractPriceFromString(priceString: string): number | null {\n if (!priceString) return null;\n const strippedString = priceString.replace(/[^\\d.]/g, \"\");\n return parseFloat(strippedString);\n}\n","import type React from \"react\";\nimport { ArrowUpDown, Check, Search, X } from \"lucide-react\";\nimport { Input } from \"@fluid-app/ui-primitives\";\nimport { Button } from \"@fluid-app/ui-primitives\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@fluid-app/ui-primitives\";\n\ntype SortOption = {\n label: string;\n value: string;\n};\n\ntype BaseSearchProps = {\n /** Current search value (controlled). */\n searchValue: string;\n /** Called on every keystroke with the new value. */\n onSearchChange: (value: string) => void;\n /** Placeholder text for the search input. */\n placeholder?: string;\n};\n\ntype SearchOnlyProps = BaseSearchProps & {\n sortOptions?: never;\n sortValue?: never;\n onSortChange?: never;\n};\n\ntype WithSortProps = BaseSearchProps & {\n /** Sort options to display in the dropdown. */\n sortOptions: ReadonlyArray<SortOption>;\n /** Currently selected sort value. */\n sortValue: string;\n /** Called when a sort option is selected. */\n onSortChange: (value: string) => void;\n};\n\ntype SearchSortProps = SearchOnlyProps | WithSortProps;\n\nexport type {\n SortOption,\n BaseSearchProps,\n SearchOnlyProps,\n WithSortProps,\n SearchSortProps,\n};\n\nexport function SearchSort({\n searchValue,\n onSearchChange,\n placeholder = \"Search...\",\n sortOptions,\n sortValue,\n onSortChange,\n}: SearchSortProps): React.JSX.Element {\n const activeSort = sortOptions?.find((o) => o.value === sortValue);\n\n return (\n <div className=\"flex items-center gap-2\">\n <div className=\"relative min-w-0 flex-1\">\n <Search className=\"text-muted-foreground pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2\" />\n <Input\n type=\"search\"\n value={searchValue}\n onChange={(e) => onSearchChange(e.target.value)}\n placeholder={placeholder}\n className=\"pl-9 [&::-webkit-search-cancel-button]:hidden\"\n />\n {searchValue.length > 0 && (\n <Button\n variant=\"ghost\"\n size=\"icon-xs\"\n onClick={() => onSearchChange(\"\")}\n aria-label=\"Clear search\"\n className=\"absolute top-1/2 right-2 -translate-y-1/2\"\n >\n <X className=\"size-3\" />\n </Button>\n )}\n </div>\n {sortOptions && sortOptions.length > 0 && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"outline\"\n aria-label={\n activeSort ? `Sort: ${activeSort.label}` : \"Sort options\"\n }\n >\n <ArrowUpDown className=\"size-4\" />\n {activeSort && (\n <span className=\"hidden sm:inline\">{activeSort.label}</span>\n )}\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {sortOptions.map((option) => {\n const isActive = option.value === sortValue;\n return (\n <DropdownMenuItem\n key={option.value}\n onClick={() => onSortChange(option.value)}\n >\n <span className=\"flex-1\">{option.label}</span>\n {isActive && (\n <Check className=\"text-muted-foreground size-4\" />\n )}\n </DropdownMenuItem>\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|