@fluid-app/portal-sdk 0.1.185 → 0.1.186

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/dist/{PortalContentApiProvider-Cei2eKh_.mjs → PortalContentApiProvider-B8tHeIDR.mjs} +7 -6
  2. package/dist/PortalContentApiProvider-B8tHeIDR.mjs.map +1 -0
  3. package/dist/{PortalContentApiProvider-C2G-u4O2.cjs → PortalContentApiProvider-D6hzQ1aL.cjs} +7 -6
  4. package/dist/PortalContentApiProvider-D6hzQ1aL.cjs.map +1 -0
  5. package/dist/{ProductsScreen-BJBagajA.cjs → ProductsScreen-C8RdjP3N.cjs} +2 -2
  6. package/dist/{ProductsScreen-BNpjtlYx.mjs → ProductsScreen-CGkz7PDA.mjs} +4 -2
  7. package/dist/{ProductsScreen-ClOJgwBf.cjs → ProductsScreen-MVCgkjrh.cjs} +2 -2
  8. package/dist/{ProductsScreen-ClOJgwBf.cjs.map → ProductsScreen-MVCgkjrh.cjs.map} +1 -1
  9. package/dist/{ProductsScreen-Ba2wcgYy.mjs → ProductsScreen-oMPbhDAd.mjs} +2 -2
  10. package/dist/{ProductsScreen-Ba2wcgYy.mjs.map → ProductsScreen-oMPbhDAd.mjs.map} +1 -1
  11. package/dist/{ShareablesScreen-9j2YlYM5.cjs → ShareablesScreen-BxUL0r-6.cjs} +2 -2
  12. package/dist/{ShareablesScreen-yYzOCGaX.mjs → ShareablesScreen-Ci65hGFM.mjs} +4 -2
  13. package/dist/{ShareablesScreen-CkaXzERa.cjs → ShareablesScreen-DIo7EMlA.cjs} +30 -11
  14. package/dist/ShareablesScreen-DIo7EMlA.cjs.map +1 -0
  15. package/dist/{ShareablesScreen-lLzBYQ9u.mjs → ShareablesScreen-IMOvttqL.mjs} +30 -11
  16. package/dist/ShareablesScreen-IMOvttqL.mjs.map +1 -0
  17. package/dist/index.cjs +7 -7
  18. package/dist/index.d.cts.map +1 -1
  19. package/dist/index.d.mts.map +1 -1
  20. package/dist/index.mjs +7 -7
  21. package/package.json +8 -8
  22. package/dist/PortalContentApiProvider-C2G-u4O2.cjs.map +0 -1
  23. package/dist/PortalContentApiProvider-Cei2eKh_.mjs.map +0 -1
  24. package/dist/ShareablesScreen-CkaXzERa.cjs.map +0 -1
  25. package/dist/ShareablesScreen-lLzBYQ9u.mjs.map +0 -1
@@ -7,9 +7,9 @@ require("./dist-BRT-FAUb.cjs");
7
7
  require("./es-Dr47illR.cjs");
8
8
  require("./SearchSort-BgHSdG1l.cjs");
9
9
  require("./dist-DbiSKQz4.cjs");
10
- require("./PortalContentApiProvider-C2G-u4O2.cjs");
10
+ require("./PortalContentApiProvider-D6hzQ1aL.cjs");
11
11
  require("./dist-DWs3-WOI.cjs");
12
12
  require("./PortalProductsApiProvider-Duj-EjQj.cjs");
13
- const require_ProductsScreen = require("./ProductsScreen-ClOJgwBf.cjs");
13
+ const require_ProductsScreen = require("./ProductsScreen-MVCgkjrh.cjs");
14
14
  exports.ProductsScreen = require_ProductsScreen.ProductsScreen;
15
15
  exports.productsScreenPropertySchema = require_ProductsScreen.productsScreenPropertySchema;
@@ -1,13 +1,15 @@
1
1
  import "./es-I9usCQT-.mjs";
2
2
  import "./account-api-context-BIZ_aibJ.mjs";
3
3
  import "./store-api-context-C1lXT_3d.mjs";
4
+ import "./PortalTenantClientProvider-4ZmY6hac.mjs";
4
5
  import "./src-BZbWkXOU.mjs";
5
6
  import "./ScreenHeaderContext-FYyYk97y.mjs";
7
+ import "./AppNavigationContext-BW3lSpfT.mjs";
6
8
  import "./dist-BETEuYfn.mjs";
7
9
  import "./SearchSort-CFbJNJDL.mjs";
8
10
  import "./dist-DiBoTZfl.mjs";
9
- import "./PortalContentApiProvider-Cei2eKh_.mjs";
11
+ import "./PortalContentApiProvider-B8tHeIDR.mjs";
10
12
  import "./sortable.esm-CJLSD-Ce.mjs";
11
13
  import "./PortalProductsApiProvider-BALswRao.mjs";
12
- import { n as productsScreenPropertySchema, t as ProductsScreen } from "./ProductsScreen-Ba2wcgYy.mjs";
14
+ import { n as productsScreenPropertySchema, t as ProductsScreen } from "./ProductsScreen-oMPbhDAd.mjs";
13
15
  export { ProductsScreen, productsScreenPropertySchema };
@@ -3,7 +3,7 @@ const require_src = require("./src-CvtwdzKm.cjs");
3
3
  const require_use_account = require("./use-account-BWdcuCCW.cjs");
4
4
  const require_use_store = require("./use-store-DvtLtZ3f.cjs");
5
5
  const require_AppNavigationContext = require("./AppNavigationContext-BKszSW5R.cjs");
6
- const require_PortalContentApiProvider = require("./PortalContentApiProvider-C2G-u4O2.cjs");
6
+ const require_PortalContentApiProvider = require("./PortalContentApiProvider-D6hzQ1aL.cjs");
7
7
  const require_PortalProductsApiProvider = require("./PortalProductsApiProvider-Duj-EjQj.cjs");
8
8
  let react = require("react");
9
9
  let react_jsx_runtime = require("react/jsx-runtime");
@@ -99,4 +99,4 @@ Object.defineProperty(exports, "productsScreenPropertySchema", {
99
99
  }
100
100
  });
101
101
 
102
- //# sourceMappingURL=ProductsScreen-ClOJgwBf.cjs.map
102
+ //# sourceMappingURL=ProductsScreen-MVCgkjrh.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ProductsScreen-ClOJgwBf.cjs","names":["PortalProductsApiProvider","PortalContentApiProvider","usePortalContentContext","useAccount","useStore","useAppNavigation","ShareablesCoreProvider","ShareablesUIProvider","ProductsApp"],"sources":["../src/screens/ProductsScreen.tsx"],"sourcesContent":["import { useCallback, useMemo, type ComponentProps } from \"react\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport { ShareablesCoreProvider } from \"@fluid-app/shareables-core\";\nimport { ShareablesUIProvider, ProductsApp } from \"@fluid-app/shareables-ui\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { useAccount } from \"../hooks/use-account\";\nimport { useStore } from \"../hooks/use-store\";\nimport { PortalProductsApiProvider } from \"../products/PortalProductsApiProvider\";\nimport {\n PortalContentApiProvider,\n usePortalContentContext,\n} from \"../content/PortalContentApiProvider\";\n\ntype ProductsScreenProps = ComponentProps<\"div\"> & {\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n};\n\nexport function ProductsScreen({\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: ProductsScreenProps): React.JSX.Element {\n return (\n <div {...divProps} className={`h-full ${divProps.className ?? \"\"}`}>\n <PortalProductsApiProvider>\n <PortalContentApiProvider>\n <ProductsScreenContent />\n </PortalContentApiProvider>\n </PortalProductsApiProvider>\n </div>\n );\n}\n\n/** Inner component rendered inside providers so hooks can access context. */\nfunction ProductsScreenContent(): React.JSX.Element {\n const { productsApi: portalProductsApi } = usePortalContentContext();\n const { data: account } = useAccount();\n const { data: store } = useStore();\n const { currentSlug, navigate } = useAppNavigation();\n\n const fetchProducts = useCallback(\n async (search: string, cursor?: string, limit?: number) => {\n if (search) {\n return portalProductsApi.searchProducts(search, { cursor, limit });\n }\n return portalProductsApi.listProducts({ cursor, limit });\n },\n [portalProductsApi],\n );\n\n const fetchProduct = useCallback(\n async (id: string | number) => portalProductsApi.getProduct(id),\n [portalProductsApi],\n );\n\n // Extract product ID from slug: \"products/123\" → \"123\"\n const productId = useMemo(() => {\n const match = currentSlug.match(/^products\\/(.+)/);\n return match?.[1] ?? null;\n }, [currentSlug]);\n\n const handleSelectProduct = useCallback(\n (id: string) => {\n navigate(`products/${id}`);\n },\n [navigate],\n );\n\n const handleBack = useCallback(() => {\n navigate(\"products\");\n }, [navigate]);\n\n const coreConfig = useMemo(\n () => ({\n user: account ? { id: account.id } : null,\n repContext: true,\n }),\n [account],\n );\n\n const uiConfig = useMemo(\n () => ({\n user: account\n ? {\n id: account.id,\n company: { logo_url: store?.logo_url ?? null },\n }\n : undefined,\n basePath: \"\",\n navigate: (path: string) => {\n navigate(path);\n },\n showToast: (opts: {\n title: string;\n type: \"success\" | \"error\" | \"warning\";\n }) => {\n fluidToast(opts);\n },\n }),\n [account, store, navigate],\n );\n\n return (\n <ShareablesCoreProvider config={coreConfig}>\n <ShareablesUIProvider config={uiConfig}>\n <ProductsApp\n countryCode={undefined}\n companyLogoUrl={store?.logo_url ?? undefined}\n fetchProducts={fetchProducts}\n fetchProduct={fetchProduct}\n productId={productId}\n onSelectProduct={handleSelectProduct}\n onBack={handleBack}\n />\n </ShareablesUIProvider>\n </ShareablesCoreProvider>\n );\n}\n\nexport const productsScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"ProductsScreen\",\n displayName: \"Products Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":";;;;;;;;;;AA4BA,SAAgB,eAAe,EAE7B,YACA,WACA,aACA,SACA,cAEA,GAAG,YACsC;AACzC,QACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EAAK,GAAI;EAAU,WAAW,UAAU,SAAS,aAAa;YAC5D,iBAAA,GAAA,kBAAA,KAACA,kCAAAA,2BAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,KAACC,iCAAAA,0BAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,KAAC,uBAAD,EAAyB,CAAA,EACA,CAAA,EACD,CAAA;EACxB,CAAA;;;AAKV,SAAS,wBAA2C;CAClD,MAAM,EAAE,aAAa,sBAAsBC,iCAAAA,yBAAyB;CACpE,MAAM,EAAE,MAAM,YAAYC,oBAAAA,YAAY;CACtC,MAAM,EAAE,MAAM,UAAUC,kBAAAA,UAAU;CAClC,MAAM,EAAE,aAAa,aAAaC,6BAAAA,kBAAkB;CAEpD,MAAM,iBAAA,GAAA,MAAA,aACJ,OAAO,QAAgB,QAAiB,UAAmB;AACzD,MAAI,OACF,QAAO,kBAAkB,eAAe,QAAQ;GAAE;GAAQ;GAAO,CAAC;AAEpE,SAAO,kBAAkB,aAAa;GAAE;GAAQ;GAAO,CAAC;IAE1D,CAAC,kBAAkB,CACpB;CAED,MAAM,gBAAA,GAAA,MAAA,aACJ,OAAO,OAAwB,kBAAkB,WAAW,GAAG,EAC/D,CAAC,kBAAkB,CACpB;CAGD,MAAM,aAAA,GAAA,MAAA,eAA0B;AAE9B,SADc,YAAY,MAAM,kBAAkB,GACnC,MAAM;IACpB,CAAC,YAAY,CAAC;CAEjB,MAAM,uBAAA,GAAA,MAAA,cACH,OAAe;AACd,WAAS,YAAY,KAAK;IAE5B,CAAC,SAAS,CACX;CAED,MAAM,cAAA,GAAA,MAAA,mBAA+B;AACnC,WAAS,WAAW;IACnB,CAAC,SAAS,CAAC;AAgCd,QACE,iBAAA,GAAA,kBAAA,KAACC,iCAAAA,wBAAD;EAAwB,SAAA,GAAA,MAAA,gBA9BjB;GACL,MAAM,UAAU,EAAE,IAAI,QAAQ,IAAI,GAAG;GACrC,YAAY;GACb,GACD,CAAC,QAAQ,CACV;YA0BG,iBAAA,GAAA,kBAAA,KAACC,iCAAAA,sBAAD;GAAsB,SAAA,GAAA,MAAA,gBAvBjB;IACL,MAAM,UACF;KACE,IAAI,QAAQ;KACZ,SAAS,EAAE,UAAU,OAAO,YAAY,MAAM;KAC/C,GACD,KAAA;IACJ,UAAU;IACV,WAAW,SAAiB;AAC1B,cAAS,KAAK;;IAEhB,YAAY,SAGN;AACJ,iBAAA,WAAW,KAAK;;IAEnB,GACD;IAAC;IAAS;IAAO;IAAS,CAC3B;aAKK,iBAAA,GAAA,kBAAA,KAACC,iCAAAA,aAAD;IACE,aAAa,KAAA;IACb,gBAAgB,OAAO,YAAY,KAAA;IACpB;IACD;IACH;IACX,iBAAiB;IACjB,QAAQ;IACR,CAAA;GACmB,CAAA;EACA,CAAA;;AAI7B,MAAa,+BAAqD;CAChE,YAAY;CACZ,aAAa;CACb,YAAY,CAAC;EAAE,IAAI;EAAW,OAAO;EAAW,CAAC;CACjD,QAAQ,EAAE;CACX"}
1
+ {"version":3,"file":"ProductsScreen-MVCgkjrh.cjs","names":["PortalProductsApiProvider","PortalContentApiProvider","usePortalContentContext","useAccount","useStore","useAppNavigation","ShareablesCoreProvider","ShareablesUIProvider","ProductsApp"],"sources":["../src/screens/ProductsScreen.tsx"],"sourcesContent":["import { useCallback, useMemo, type ComponentProps } from \"react\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport { ShareablesCoreProvider } from \"@fluid-app/shareables-core\";\nimport { ShareablesUIProvider, ProductsApp } from \"@fluid-app/shareables-ui\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { useAccount } from \"../hooks/use-account\";\nimport { useStore } from \"../hooks/use-store\";\nimport { PortalProductsApiProvider } from \"../products/PortalProductsApiProvider\";\nimport {\n PortalContentApiProvider,\n usePortalContentContext,\n} from \"../content/PortalContentApiProvider\";\n\ntype ProductsScreenProps = ComponentProps<\"div\"> & {\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n};\n\nexport function ProductsScreen({\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: ProductsScreenProps): React.JSX.Element {\n return (\n <div {...divProps} className={`h-full ${divProps.className ?? \"\"}`}>\n <PortalProductsApiProvider>\n <PortalContentApiProvider>\n <ProductsScreenContent />\n </PortalContentApiProvider>\n </PortalProductsApiProvider>\n </div>\n );\n}\n\n/** Inner component rendered inside providers so hooks can access context. */\nfunction ProductsScreenContent(): React.JSX.Element {\n const { productsApi: portalProductsApi } = usePortalContentContext();\n const { data: account } = useAccount();\n const { data: store } = useStore();\n const { currentSlug, navigate } = useAppNavigation();\n\n const fetchProducts = useCallback(\n async (search: string, cursor?: string, limit?: number) => {\n if (search) {\n return portalProductsApi.searchProducts(search, { cursor, limit });\n }\n return portalProductsApi.listProducts({ cursor, limit });\n },\n [portalProductsApi],\n );\n\n const fetchProduct = useCallback(\n async (id: string | number) => portalProductsApi.getProduct(id),\n [portalProductsApi],\n );\n\n // Extract product ID from slug: \"products/123\" → \"123\"\n const productId = useMemo(() => {\n const match = currentSlug.match(/^products\\/(.+)/);\n return match?.[1] ?? null;\n }, [currentSlug]);\n\n const handleSelectProduct = useCallback(\n (id: string) => {\n navigate(`products/${id}`);\n },\n [navigate],\n );\n\n const handleBack = useCallback(() => {\n navigate(\"products\");\n }, [navigate]);\n\n const coreConfig = useMemo(\n () => ({\n user: account ? { id: account.id } : null,\n repContext: true,\n }),\n [account],\n );\n\n const uiConfig = useMemo(\n () => ({\n user: account\n ? {\n id: account.id,\n company: { logo_url: store?.logo_url ?? null },\n }\n : undefined,\n basePath: \"\",\n navigate: (path: string) => {\n navigate(path);\n },\n showToast: (opts: {\n title: string;\n type: \"success\" | \"error\" | \"warning\";\n }) => {\n fluidToast(opts);\n },\n }),\n [account, store, navigate],\n );\n\n return (\n <ShareablesCoreProvider config={coreConfig}>\n <ShareablesUIProvider config={uiConfig}>\n <ProductsApp\n countryCode={undefined}\n companyLogoUrl={store?.logo_url ?? undefined}\n fetchProducts={fetchProducts}\n fetchProduct={fetchProduct}\n productId={productId}\n onSelectProduct={handleSelectProduct}\n onBack={handleBack}\n />\n </ShareablesUIProvider>\n </ShareablesCoreProvider>\n );\n}\n\nexport const productsScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"ProductsScreen\",\n displayName: \"Products Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":";;;;;;;;;;AA4BA,SAAgB,eAAe,EAE7B,YACA,WACA,aACA,SACA,cAEA,GAAG,YACsC;AACzC,QACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EAAK,GAAI;EAAU,WAAW,UAAU,SAAS,aAAa;YAC5D,iBAAA,GAAA,kBAAA,KAACA,kCAAAA,2BAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,KAACC,iCAAAA,0BAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,KAAC,uBAAD,EAAyB,CAAA,EACA,CAAA,EACD,CAAA;EACxB,CAAA;;;AAKV,SAAS,wBAA2C;CAClD,MAAM,EAAE,aAAa,sBAAsBC,iCAAAA,yBAAyB;CACpE,MAAM,EAAE,MAAM,YAAYC,oBAAAA,YAAY;CACtC,MAAM,EAAE,MAAM,UAAUC,kBAAAA,UAAU;CAClC,MAAM,EAAE,aAAa,aAAaC,6BAAAA,kBAAkB;CAEpD,MAAM,iBAAA,GAAA,MAAA,aACJ,OAAO,QAAgB,QAAiB,UAAmB;AACzD,MAAI,OACF,QAAO,kBAAkB,eAAe,QAAQ;GAAE;GAAQ;GAAO,CAAC;AAEpE,SAAO,kBAAkB,aAAa;GAAE;GAAQ;GAAO,CAAC;IAE1D,CAAC,kBAAkB,CACpB;CAED,MAAM,gBAAA,GAAA,MAAA,aACJ,OAAO,OAAwB,kBAAkB,WAAW,GAAG,EAC/D,CAAC,kBAAkB,CACpB;CAGD,MAAM,aAAA,GAAA,MAAA,eAA0B;AAE9B,SADc,YAAY,MAAM,kBAAkB,GACnC,MAAM;IACpB,CAAC,YAAY,CAAC;CAEjB,MAAM,uBAAA,GAAA,MAAA,cACH,OAAe;AACd,WAAS,YAAY,KAAK;IAE5B,CAAC,SAAS,CACX;CAED,MAAM,cAAA,GAAA,MAAA,mBAA+B;AACnC,WAAS,WAAW;IACnB,CAAC,SAAS,CAAC;AAgCd,QACE,iBAAA,GAAA,kBAAA,KAACC,iCAAAA,wBAAD;EAAwB,SAAA,GAAA,MAAA,gBA9BjB;GACL,MAAM,UAAU,EAAE,IAAI,QAAQ,IAAI,GAAG;GACrC,YAAY;GACb,GACD,CAAC,QAAQ,CACV;YA0BG,iBAAA,GAAA,kBAAA,KAACC,iCAAAA,sBAAD;GAAsB,SAAA,GAAA,MAAA,gBAvBjB;IACL,MAAM,UACF;KACE,IAAI,QAAQ;KACZ,SAAS,EAAE,UAAU,OAAO,YAAY,MAAM;KAC/C,GACD,KAAA;IACJ,UAAU;IACV,WAAW,SAAiB;AAC1B,cAAS,KAAK;;IAEhB,YAAY,SAGN;AACJ,iBAAA,WAAW,KAAK;;IAEnB,GACD;IAAC;IAAS;IAAO;IAAS,CAC3B;aAKK,iBAAA,GAAA,kBAAA,KAACC,iCAAAA,aAAD;IACE,aAAa,KAAA;IACb,gBAAgB,OAAO,YAAY,KAAA;IACpB;IACD;IACH;IACX,iBAAiB;IACjB,QAAQ;IACR,CAAA;GACmB,CAAA;EACA,CAAA;;AAI7B,MAAa,+BAAqD;CAChE,YAAY;CACZ,aAAa;CACb,YAAY,CAAC;EAAE,IAAI;EAAW,OAAO;EAAW,CAAC;CACjD,QAAQ,EAAE;CACX"}
@@ -2,7 +2,7 @@ import { _ as fluidToast } from "./src-BZbWkXOU.mjs";
2
2
  import { t as useAccount } from "./use-account-B16Tor2Q.mjs";
3
3
  import { t as useStore } from "./use-store-BnHhQDYo.mjs";
4
4
  import { n as useAppNavigation } from "./AppNavigationContext-BW3lSpfT.mjs";
5
- import { c as ShareablesCoreProvider, i as ProductsApp, n as usePortalContentContext, s as ShareablesUIProvider, t as PortalContentApiProvider } from "./PortalContentApiProvider-Cei2eKh_.mjs";
5
+ import { c as ShareablesCoreProvider, i as ProductsApp, n as usePortalContentContext, s as ShareablesUIProvider, t as PortalContentApiProvider } from "./PortalContentApiProvider-B8tHeIDR.mjs";
6
6
  import { t as PortalProductsApiProvider } from "./PortalProductsApiProvider-BALswRao.mjs";
7
7
  import { useCallback, useMemo } from "react";
8
8
  import { jsx } from "react/jsx-runtime";
@@ -87,4 +87,4 @@ const productsScreenPropertySchema = {
87
87
  //#endregion
88
88
  export { productsScreenPropertySchema as n, ProductsScreen as t };
89
89
 
90
- //# sourceMappingURL=ProductsScreen-Ba2wcgYy.mjs.map
90
+ //# sourceMappingURL=ProductsScreen-oMPbhDAd.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ProductsScreen-Ba2wcgYy.mjs","names":[],"sources":["../src/screens/ProductsScreen.tsx"],"sourcesContent":["import { useCallback, useMemo, type ComponentProps } from \"react\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport { ShareablesCoreProvider } from \"@fluid-app/shareables-core\";\nimport { ShareablesUIProvider, ProductsApp } from \"@fluid-app/shareables-ui\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { useAccount } from \"../hooks/use-account\";\nimport { useStore } from \"../hooks/use-store\";\nimport { PortalProductsApiProvider } from \"../products/PortalProductsApiProvider\";\nimport {\n PortalContentApiProvider,\n usePortalContentContext,\n} from \"../content/PortalContentApiProvider\";\n\ntype ProductsScreenProps = ComponentProps<\"div\"> & {\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n};\n\nexport function ProductsScreen({\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: ProductsScreenProps): React.JSX.Element {\n return (\n <div {...divProps} className={`h-full ${divProps.className ?? \"\"}`}>\n <PortalProductsApiProvider>\n <PortalContentApiProvider>\n <ProductsScreenContent />\n </PortalContentApiProvider>\n </PortalProductsApiProvider>\n </div>\n );\n}\n\n/** Inner component rendered inside providers so hooks can access context. */\nfunction ProductsScreenContent(): React.JSX.Element {\n const { productsApi: portalProductsApi } = usePortalContentContext();\n const { data: account } = useAccount();\n const { data: store } = useStore();\n const { currentSlug, navigate } = useAppNavigation();\n\n const fetchProducts = useCallback(\n async (search: string, cursor?: string, limit?: number) => {\n if (search) {\n return portalProductsApi.searchProducts(search, { cursor, limit });\n }\n return portalProductsApi.listProducts({ cursor, limit });\n },\n [portalProductsApi],\n );\n\n const fetchProduct = useCallback(\n async (id: string | number) => portalProductsApi.getProduct(id),\n [portalProductsApi],\n );\n\n // Extract product ID from slug: \"products/123\" → \"123\"\n const productId = useMemo(() => {\n const match = currentSlug.match(/^products\\/(.+)/);\n return match?.[1] ?? null;\n }, [currentSlug]);\n\n const handleSelectProduct = useCallback(\n (id: string) => {\n navigate(`products/${id}`);\n },\n [navigate],\n );\n\n const handleBack = useCallback(() => {\n navigate(\"products\");\n }, [navigate]);\n\n const coreConfig = useMemo(\n () => ({\n user: account ? { id: account.id } : null,\n repContext: true,\n }),\n [account],\n );\n\n const uiConfig = useMemo(\n () => ({\n user: account\n ? {\n id: account.id,\n company: { logo_url: store?.logo_url ?? null },\n }\n : undefined,\n basePath: \"\",\n navigate: (path: string) => {\n navigate(path);\n },\n showToast: (opts: {\n title: string;\n type: \"success\" | \"error\" | \"warning\";\n }) => {\n fluidToast(opts);\n },\n }),\n [account, store, navigate],\n );\n\n return (\n <ShareablesCoreProvider config={coreConfig}>\n <ShareablesUIProvider config={uiConfig}>\n <ProductsApp\n countryCode={undefined}\n companyLogoUrl={store?.logo_url ?? undefined}\n fetchProducts={fetchProducts}\n fetchProduct={fetchProduct}\n productId={productId}\n onSelectProduct={handleSelectProduct}\n onBack={handleBack}\n />\n </ShareablesUIProvider>\n </ShareablesCoreProvider>\n );\n}\n\nexport const productsScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"ProductsScreen\",\n displayName: \"Products Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":";;;;;;;;;AA4BA,SAAgB,eAAe,EAE7B,YACA,WACA,aACA,SACA,cAEA,GAAG,YACsC;AACzC,QACE,oBAAC,OAAD;EAAK,GAAI;EAAU,WAAW,UAAU,SAAS,aAAa;YAC5D,oBAAC,2BAAD,EAAA,UACE,oBAAC,0BAAD,EAAA,UACE,oBAAC,uBAAD,EAAyB,CAAA,EACA,CAAA,EACD,CAAA;EACxB,CAAA;;;AAKV,SAAS,wBAA2C;CAClD,MAAM,EAAE,aAAa,sBAAsB,yBAAyB;CACpE,MAAM,EAAE,MAAM,YAAY,YAAY;CACtC,MAAM,EAAE,MAAM,UAAU,UAAU;CAClC,MAAM,EAAE,aAAa,aAAa,kBAAkB;CAEpD,MAAM,gBAAgB,YACpB,OAAO,QAAgB,QAAiB,UAAmB;AACzD,MAAI,OACF,QAAO,kBAAkB,eAAe,QAAQ;GAAE;GAAQ;GAAO,CAAC;AAEpE,SAAO,kBAAkB,aAAa;GAAE;GAAQ;GAAO,CAAC;IAE1D,CAAC,kBAAkB,CACpB;CAED,MAAM,eAAe,YACnB,OAAO,OAAwB,kBAAkB,WAAW,GAAG,EAC/D,CAAC,kBAAkB,CACpB;CAGD,MAAM,YAAY,cAAc;AAE9B,SADc,YAAY,MAAM,kBAAkB,GACnC,MAAM;IACpB,CAAC,YAAY,CAAC;CAEjB,MAAM,sBAAsB,aACzB,OAAe;AACd,WAAS,YAAY,KAAK;IAE5B,CAAC,SAAS,CACX;CAED,MAAM,aAAa,kBAAkB;AACnC,WAAS,WAAW;IACnB,CAAC,SAAS,CAAC;AAgCd,QACE,oBAAC,wBAAD;EAAwB,QA/BP,eACV;GACL,MAAM,UAAU,EAAE,IAAI,QAAQ,IAAI,GAAG;GACrC,YAAY;GACb,GACD,CAAC,QAAQ,CACV;YA0BG,oBAAC,sBAAD;GAAsB,QAxBT,eACR;IACL,MAAM,UACF;KACE,IAAI,QAAQ;KACZ,SAAS,EAAE,UAAU,OAAO,YAAY,MAAM;KAC/C,GACD,KAAA;IACJ,UAAU;IACV,WAAW,SAAiB;AAC1B,cAAS,KAAK;;IAEhB,YAAY,SAGN;AACJ,gBAAW,KAAK;;IAEnB,GACD;IAAC;IAAS;IAAO;IAAS,CAC3B;aAKK,oBAAC,aAAD;IACE,aAAa,KAAA;IACb,gBAAgB,OAAO,YAAY,KAAA;IACpB;IACD;IACH;IACX,iBAAiB;IACjB,QAAQ;IACR,CAAA;GACmB,CAAA;EACA,CAAA;;AAI7B,MAAa,+BAAqD;CAChE,YAAY;CACZ,aAAa;CACb,YAAY,CAAC;EAAE,IAAI;EAAW,OAAO;EAAW,CAAC;CACjD,QAAQ,EAAE;CACX"}
1
+ {"version":3,"file":"ProductsScreen-oMPbhDAd.mjs","names":[],"sources":["../src/screens/ProductsScreen.tsx"],"sourcesContent":["import { useCallback, useMemo, type ComponentProps } from \"react\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport { ShareablesCoreProvider } from \"@fluid-app/shareables-core\";\nimport { ShareablesUIProvider, ProductsApp } from \"@fluid-app/shareables-ui\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { useAccount } from \"../hooks/use-account\";\nimport { useStore } from \"../hooks/use-store\";\nimport { PortalProductsApiProvider } from \"../products/PortalProductsApiProvider\";\nimport {\n PortalContentApiProvider,\n usePortalContentContext,\n} from \"../content/PortalContentApiProvider\";\n\ntype ProductsScreenProps = ComponentProps<\"div\"> & {\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n};\n\nexport function ProductsScreen({\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: ProductsScreenProps): React.JSX.Element {\n return (\n <div {...divProps} className={`h-full ${divProps.className ?? \"\"}`}>\n <PortalProductsApiProvider>\n <PortalContentApiProvider>\n <ProductsScreenContent />\n </PortalContentApiProvider>\n </PortalProductsApiProvider>\n </div>\n );\n}\n\n/** Inner component rendered inside providers so hooks can access context. */\nfunction ProductsScreenContent(): React.JSX.Element {\n const { productsApi: portalProductsApi } = usePortalContentContext();\n const { data: account } = useAccount();\n const { data: store } = useStore();\n const { currentSlug, navigate } = useAppNavigation();\n\n const fetchProducts = useCallback(\n async (search: string, cursor?: string, limit?: number) => {\n if (search) {\n return portalProductsApi.searchProducts(search, { cursor, limit });\n }\n return portalProductsApi.listProducts({ cursor, limit });\n },\n [portalProductsApi],\n );\n\n const fetchProduct = useCallback(\n async (id: string | number) => portalProductsApi.getProduct(id),\n [portalProductsApi],\n );\n\n // Extract product ID from slug: \"products/123\" → \"123\"\n const productId = useMemo(() => {\n const match = currentSlug.match(/^products\\/(.+)/);\n return match?.[1] ?? null;\n }, [currentSlug]);\n\n const handleSelectProduct = useCallback(\n (id: string) => {\n navigate(`products/${id}`);\n },\n [navigate],\n );\n\n const handleBack = useCallback(() => {\n navigate(\"products\");\n }, [navigate]);\n\n const coreConfig = useMemo(\n () => ({\n user: account ? { id: account.id } : null,\n repContext: true,\n }),\n [account],\n );\n\n const uiConfig = useMemo(\n () => ({\n user: account\n ? {\n id: account.id,\n company: { logo_url: store?.logo_url ?? null },\n }\n : undefined,\n basePath: \"\",\n navigate: (path: string) => {\n navigate(path);\n },\n showToast: (opts: {\n title: string;\n type: \"success\" | \"error\" | \"warning\";\n }) => {\n fluidToast(opts);\n },\n }),\n [account, store, navigate],\n );\n\n return (\n <ShareablesCoreProvider config={coreConfig}>\n <ShareablesUIProvider config={uiConfig}>\n <ProductsApp\n countryCode={undefined}\n companyLogoUrl={store?.logo_url ?? undefined}\n fetchProducts={fetchProducts}\n fetchProduct={fetchProduct}\n productId={productId}\n onSelectProduct={handleSelectProduct}\n onBack={handleBack}\n />\n </ShareablesUIProvider>\n </ShareablesCoreProvider>\n );\n}\n\nexport const productsScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"ProductsScreen\",\n displayName: \"Products Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":";;;;;;;;;AA4BA,SAAgB,eAAe,EAE7B,YACA,WACA,aACA,SACA,cAEA,GAAG,YACsC;AACzC,QACE,oBAAC,OAAD;EAAK,GAAI;EAAU,WAAW,UAAU,SAAS,aAAa;YAC5D,oBAAC,2BAAD,EAAA,UACE,oBAAC,0BAAD,EAAA,UACE,oBAAC,uBAAD,EAAyB,CAAA,EACA,CAAA,EACD,CAAA;EACxB,CAAA;;;AAKV,SAAS,wBAA2C;CAClD,MAAM,EAAE,aAAa,sBAAsB,yBAAyB;CACpE,MAAM,EAAE,MAAM,YAAY,YAAY;CACtC,MAAM,EAAE,MAAM,UAAU,UAAU;CAClC,MAAM,EAAE,aAAa,aAAa,kBAAkB;CAEpD,MAAM,gBAAgB,YACpB,OAAO,QAAgB,QAAiB,UAAmB;AACzD,MAAI,OACF,QAAO,kBAAkB,eAAe,QAAQ;GAAE;GAAQ;GAAO,CAAC;AAEpE,SAAO,kBAAkB,aAAa;GAAE;GAAQ;GAAO,CAAC;IAE1D,CAAC,kBAAkB,CACpB;CAED,MAAM,eAAe,YACnB,OAAO,OAAwB,kBAAkB,WAAW,GAAG,EAC/D,CAAC,kBAAkB,CACpB;CAGD,MAAM,YAAY,cAAc;AAE9B,SADc,YAAY,MAAM,kBAAkB,GACnC,MAAM;IACpB,CAAC,YAAY,CAAC;CAEjB,MAAM,sBAAsB,aACzB,OAAe;AACd,WAAS,YAAY,KAAK;IAE5B,CAAC,SAAS,CACX;CAED,MAAM,aAAa,kBAAkB;AACnC,WAAS,WAAW;IACnB,CAAC,SAAS,CAAC;AAgCd,QACE,oBAAC,wBAAD;EAAwB,QA/BP,eACV;GACL,MAAM,UAAU,EAAE,IAAI,QAAQ,IAAI,GAAG;GACrC,YAAY;GACb,GACD,CAAC,QAAQ,CACV;YA0BG,oBAAC,sBAAD;GAAsB,QAxBT,eACR;IACL,MAAM,UACF;KACE,IAAI,QAAQ;KACZ,SAAS,EAAE,UAAU,OAAO,YAAY,MAAM;KAC/C,GACD,KAAA;IACJ,UAAU;IACV,WAAW,SAAiB;AAC1B,cAAS,KAAK;;IAEhB,YAAY,SAGN;AACJ,gBAAW,KAAK;;IAEnB,GACD;IAAC;IAAS;IAAO;IAAS,CAC3B;aAKK,oBAAC,aAAD;IACE,aAAa,KAAA;IACb,gBAAgB,OAAO,YAAY,KAAA;IACpB;IACD;IACH;IACX,iBAAiB;IACjB,QAAQ;IACR,CAAA;GACmB,CAAA;EACA,CAAA;;AAI7B,MAAa,+BAAqD;CAChE,YAAY;CACZ,aAAa;CACb,YAAY,CAAC;EAAE,IAAI;EAAW,OAAO;EAAW,CAAC;CACjD,QAAQ,EAAE;CACX"}
@@ -7,10 +7,10 @@ require("./dist-BRT-FAUb.cjs");
7
7
  require("./es-Dr47illR.cjs");
8
8
  require("./SearchSort-BgHSdG1l.cjs");
9
9
  require("./dist-DbiSKQz4.cjs");
10
- require("./PortalContentApiProvider-C2G-u4O2.cjs");
10
+ require("./PortalContentApiProvider-D6hzQ1aL.cjs");
11
11
  require("./dist-DWs3-WOI.cjs");
12
12
  require("./PortalProductsApiProvider-Duj-EjQj.cjs");
13
13
  require("./use-mysite-portal-DzDYRU0u.cjs");
14
- const require_ShareablesScreen = require("./ShareablesScreen-CkaXzERa.cjs");
14
+ const require_ShareablesScreen = require("./ShareablesScreen-DIo7EMlA.cjs");
15
15
  exports.ShareablesScreen = require_ShareablesScreen.ShareablesScreen;
16
16
  exports.shareablesScreenPropertySchema = require_ShareablesScreen.shareablesScreenPropertySchema;
@@ -1,14 +1,16 @@
1
1
  import "./es-I9usCQT-.mjs";
2
2
  import "./account-api-context-BIZ_aibJ.mjs";
3
3
  import "./mysite-api-context-bXtZ8Gbm.mjs";
4
+ import "./PortalTenantClientProvider-4ZmY6hac.mjs";
4
5
  import "./src-BZbWkXOU.mjs";
5
6
  import "./ScreenHeaderContext-FYyYk97y.mjs";
7
+ import "./AppNavigationContext-BW3lSpfT.mjs";
6
8
  import "./dist-BETEuYfn.mjs";
7
9
  import "./SearchSort-CFbJNJDL.mjs";
8
10
  import "./dist-DiBoTZfl.mjs";
9
- import "./PortalContentApiProvider-Cei2eKh_.mjs";
11
+ import "./PortalContentApiProvider-B8tHeIDR.mjs";
10
12
  import "./sortable.esm-CJLSD-Ce.mjs";
11
13
  import "./PortalProductsApiProvider-BALswRao.mjs";
12
14
  import "./use-mysite-portal-BV-BP3CE.mjs";
13
- import { n as shareablesScreenPropertySchema, t as ShareablesScreen } from "./ShareablesScreen-lLzBYQ9u.mjs";
15
+ import { n as shareablesScreenPropertySchema, t as ShareablesScreen } from "./ShareablesScreen-IMOvttqL.mjs";
14
16
  export { ShareablesScreen, shareablesScreenPropertySchema };
@@ -1,8 +1,9 @@
1
1
  require("./chunk-9hOWP6kD.cjs");
2
2
  const require_PortalTenantClientProvider = require("./PortalTenantClientProvider-CVv-4rQ9.cjs");
3
+ const require_src = require("./src-CvtwdzKm.cjs");
3
4
  const require_use_account = require("./use-account-BWdcuCCW.cjs");
4
5
  const require_AppNavigationContext = require("./AppNavigationContext-BKszSW5R.cjs");
5
- const require_PortalContentApiProvider = require("./PortalContentApiProvider-C2G-u4O2.cjs");
6
+ const require_PortalContentApiProvider = require("./PortalContentApiProvider-D6hzQ1aL.cjs");
6
7
  const require_PortalProductsApiProvider = require("./PortalProductsApiProvider-Duj-EjQj.cjs");
7
8
  const require_use_mysite_portal = require("./use-mysite-portal-DzDYRU0u.cjs");
8
9
  let react = require("react");
@@ -95,7 +96,11 @@ function ShareablesScreenContent() {
95
96
  navigate(cleanPath.startsWith("share/") ? cleanPath : `share/${cleanPath}`);
96
97
  },
97
98
  showToast: (opts) => {
98
- console.warn(`[Shareables] ${opts.type}: ${opts.title}`);
99
+ require_src.fluidToast({
100
+ title: opts.title,
101
+ type: opts.type
102
+ });
103
+ if (opts.error) console.error("[Shareables]", opts.error);
99
104
  },
100
105
  filePickerApi,
101
106
  onToggleFavorite: async (params) => {
@@ -107,20 +112,34 @@ function ShareablesScreenContent() {
107
112
  await shareablesCtx.playlistsAdapter.deletePlaylist(playlistId);
108
113
  },
109
114
  mediaProductsApi: isCustomer ? void 0 : shareablesCtx.mediaProductsAdapter,
110
- searchProducts: isCustomer ? void 0 : async (query) => {
111
- return ((await portalProductsApi.searchProducts(query)).products ?? []).map((p) => ({
112
- id: p.id ?? 0,
113
- name: p.name ?? p.title ?? "Untitled",
114
- image_url: p.image_url ?? null,
115
- price: p.price ?? null
116
- }));
115
+ searchProducts: isCustomer ? void 0 : async (query, options) => {
116
+ const limit = options?.limit ?? 25;
117
+ const cursor = options?.cursor ?? void 0;
118
+ const result = query.trim().length > 0 ? await portalProductsApi.searchProducts(query, {
119
+ cursor,
120
+ limit
121
+ }) : await portalProductsApi.listProducts({
122
+ cursor,
123
+ limit
124
+ });
125
+ return {
126
+ products: (result.products ?? []).map((p) => p.id != null ? {
127
+ id: p.id,
128
+ name: p.name ?? p.title ?? "Untitled",
129
+ image_url: p.image_url ?? null,
130
+ price: p.price ?? null
131
+ } : null).filter((p) => p !== null),
132
+ nextCursor: result.meta?.pagination?.next_cursor ?? null
133
+ };
117
134
  },
118
135
  readOnly: isCustomer,
119
136
  uploadThumbnail: isCustomer ? void 0 : async (blob, filename) => {
120
137
  const formData = new FormData();
121
138
  formData.append("asset[name]", filename);
122
139
  formData.append("asset[file]", blob, filename);
123
- return (await client.requestWithFormData("/api/content/dam/assets", formData)).asset?.default_variant_url ?? "";
140
+ const url = (await client.requestWithFormData("/api/content/dam/assets", formData)).asset?.default_variant_url;
141
+ if (!url) throw new Error("Thumbnail upload succeeded but no URL returned");
142
+ return url;
124
143
  }
125
144
  }), [
126
145
  account,
@@ -170,4 +189,4 @@ Object.defineProperty(exports, "shareablesScreenPropertySchema", {
170
189
  }
171
190
  });
172
191
 
173
- //# sourceMappingURL=ShareablesScreen-CkaXzERa.cjs.map
192
+ //# sourceMappingURL=ShareablesScreen-DIo7EMlA.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShareablesScreen-DIo7EMlA.cjs","names":["PortalProductsApiProvider","PortalContentApiProvider","usePortalContentContext","useFilePickerApi","useAccount","useAppNavigation","usePortalTenantClient","ShareablesCoreProvider","ShareablesUIProvider","toggleFavorite","PORTAL_MYSITE_KEYS","ShareablesApp"],"sources":["../src/screens/ShareablesScreen.tsx"],"sourcesContent":["import { useCallback, useMemo, type ComponentProps } from \"react\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { PORTAL_MYSITE_KEYS } from \"@fluid-app/mysite-ui/portal/hooks/use-mysite-portal\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport { ShareablesCoreProvider } from \"@fluid-app/shareables-core\";\nimport { ShareablesUIProvider, ShareablesApp } from \"@fluid-app/shareables-ui\";\nimport { useFilePickerApi } from \"@fluid-app/file-picker-core\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { useAccount } from \"../hooks/use-account\";\nimport { PortalProductsApiProvider } from \"../products/PortalProductsApiProvider\";\nimport {\n PortalContentApiProvider,\n usePortalContentContext,\n} from \"../content/PortalContentApiProvider\";\nimport { toggleFavorite } from \"../adapters/content-api-adapter\";\nimport { usePortalTenantClient } from \"../providers/PortalTenantClientProvider\";\n\ntype ShareablesScreenProps = ComponentProps<\"div\"> & {\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n};\n\n/**\n * Parse the current shareables sub-route from the full slug.\n *\n * System nav slugs are \"share/products\", \"share/media\", \"share/playlists\".\n * Detail pages append an ID: \"share/products/123\", \"share/media/456\".\n *\n * \"share/products\" → screen=\"products\", detailId=null\n * \"share/products/123\" → screen=\"products\", detailId=\"123\"\n * \"share/media/456\" → screen=\"media\", detailId=\"456\"\n * \"share/playlists\" → screen=\"playlists\", detailId=null\n * \"share/playlists/789\" → screen=\"playlists\", detailId=\"789\"\n * \"share/files\" → screen=\"files\", detailId=null\n * \"share\" → screen=null (default to products)\n */\nfunction parseShareablesRoute(currentSlug: string): {\n screen: string | null;\n detailId: string | null;\n action: string | null;\n} {\n // Strip the \"share\" prefix\n const slugWithoutPrefix = currentSlug.replace(/^share\\/?/, \"\");\n if (!slugWithoutPrefix) {\n return { screen: null, detailId: null, action: null };\n }\n\n const parts = slugWithoutPrefix.split(\"/\");\n const screen = parts[0] || null;\n const detailId = parts[1] || null;\n const action = parts[2] || null;\n return { screen, detailId, action };\n}\n\nexport function ShareablesScreen({\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: ShareablesScreenProps): React.JSX.Element {\n return (\n <div {...divProps} className={`h-full ${divProps.className ?? \"\"}`}>\n <PortalProductsApiProvider>\n <PortalContentApiProvider>\n <ShareablesScreenContent />\n </PortalContentApiProvider>\n </PortalProductsApiProvider>\n </div>\n );\n}\n\n/** Inner component rendered inside providers so hooks can access context. */\nfunction ShareablesScreenContent(): React.JSX.Element {\n const shareablesCtx = usePortalContentContext();\n const { productsApi: portalProductsApi } = shareablesCtx;\n const filePickerApi = useFilePickerApi();\n const { data: account } = useAccount();\n const { currentSlug, navigate } = useAppNavigation();\n const isCustomer = account?.member_type === \"customer\";\n const client = usePortalTenantClient();\n const queryClient = useQueryClient();\n\n const fetchProducts = useCallback(\n async (search: string, cursor?: string, limit?: number) => {\n if (search) {\n return portalProductsApi.searchProducts(search, { cursor, limit });\n }\n return portalProductsApi.listProducts({ cursor, limit });\n },\n [portalProductsApi],\n );\n\n const fetchProduct = useCallback(\n async (id: string | number) => portalProductsApi.getProduct(id),\n [portalProductsApi],\n );\n\n const { screen, detailId, action } = parseShareablesRoute(currentSlug);\n\n const handleNavigate = useCallback(\n (subScreen: string, id?: string) => {\n const path = id ? `share/${subScreen}/${id}` : `share/${subScreen}`;\n navigate(path);\n },\n [navigate],\n );\n\n const handleBack = useCallback(() => {\n if (detailId && screen) {\n navigate(`share/${screen}`);\n } else {\n navigate(\"share/products\");\n }\n }, [navigate, detailId, screen]);\n\n const coreConfig = useMemo(\n () => ({\n user: account ? { id: account.id } : null,\n repContext: true,\n }),\n [account],\n );\n\n const uiConfig = useMemo(\n () => ({\n user: account\n ? {\n id: account.id,\n company: null, // TODO(portal-tenant): company branding not available from /api/account\n }\n : undefined,\n // TODO(portal-tenant): affiliate_id not available from /api/account\n affiliateId: null,\n basePath: \"\",\n navigate: (path: string) => {\n const cleanPath = path.replace(/^\\//, \"\");\n const prefixed = cleanPath.startsWith(\"share/\")\n ? cleanPath\n : `share/${cleanPath}`;\n navigate(prefixed);\n },\n showToast: (opts: {\n title: string;\n type: \"success\" | \"error\" | \"warning\";\n error?: unknown;\n }) => {\n fluidToast({ title: opts.title, type: opts.type });\n if (opts.error) console.error(\"[Shareables]\", opts.error);\n },\n filePickerApi,\n onToggleFavorite: async (params: {\n favoriteableId: number;\n favoriteableType: string;\n }) => {\n const result = await toggleFavorite(\n client,\n params.favoriteableId,\n params.favoriteableType,\n );\n void queryClient.invalidateQueries({\n queryKey: PORTAL_MYSITE_KEYS.favorites(),\n });\n return result;\n },\n onDeletePlaylist: isCustomer\n ? undefined\n : async (playlistId: number) => {\n await shareablesCtx.playlistsAdapter.deletePlaylist(playlistId);\n },\n mediaProductsApi: isCustomer\n ? undefined\n : shareablesCtx.mediaProductsAdapter,\n searchProducts: isCustomer\n ? undefined\n : async (\n query: string,\n options?: { cursor?: string | null; limit?: number },\n ) => {\n // Empty query → listProducts so the tag modal opens with\n // suggestions instead of a blank state. Non-empty → real search.\n // Both APIs forward cursor/limit so the tag modal can paginate.\n const limit = options?.limit ?? 25;\n const cursor = options?.cursor ?? undefined;\n const result =\n query.trim().length > 0\n ? await portalProductsApi.searchProducts(query, {\n cursor,\n limit,\n })\n : await portalProductsApi.listProducts({ cursor, limit });\n // Filter out products without an id — mapping an id-less record\n // to `id: 0` would let a subsequent add/remove tag operation\n // silently run on id=0 (confusing 404/422 at best, incorrect\n // mutation at worst).\n const mapped = (result.products ?? [])\n .map(\n (p: {\n id?: number;\n title?: string;\n name?: string;\n image_url?: string | null;\n price?: string | null;\n }) =>\n p.id != null\n ? {\n id: p.id,\n name: p.name ?? p.title ?? \"Untitled\",\n image_url: p.image_url ?? null,\n price: p.price ?? null,\n }\n : null,\n )\n .filter((p): p is NonNullable<typeof p> => p !== null);\n return {\n products: mapped,\n nextCursor: result.meta?.pagination?.next_cursor ?? null,\n };\n },\n readOnly: isCustomer,\n uploadThumbnail: isCustomer\n ? undefined\n : async (blob: Blob, filename: string) => {\n const formData = new FormData();\n formData.append(\"asset[name]\", filename);\n formData.append(\"asset[file]\", blob, filename);\n const response = await client.requestWithFormData<{\n asset?: { default_variant_url?: string | null };\n }>(\"/api/content/dam/assets\", formData);\n const url = response.asset?.default_variant_url;\n if (!url) {\n // DAM accepted the upload but didn't return a playable URL.\n // Throwing here lets the caller (MediaEditScreen catch handler)\n // surface a toast and keeps the pending thumbnail state clean —\n // returning \"\" silently would corrupt the save payload with an\n // empty thumbnail URL.\n throw new Error(\"Thumbnail upload succeeded but no URL returned\");\n }\n return url;\n },\n }),\n [\n account,\n navigate,\n filePickerApi,\n isCustomer,\n shareablesCtx.playlistsAdapter,\n shareablesCtx.mediaProductsAdapter,\n portalProductsApi,\n client,\n queryClient,\n ],\n );\n\n return (\n <ShareablesCoreProvider config={coreConfig}>\n <ShareablesUIProvider config={uiConfig}>\n <ShareablesApp\n screen={screen}\n detailId={detailId}\n action={action}\n companyLogoUrl={undefined}\n countryCode={undefined}\n fetchProducts={fetchProducts}\n fetchProduct={fetchProduct}\n onNavigate={handleNavigate}\n onBack={handleBack}\n />\n </ShareablesUIProvider>\n </ShareablesCoreProvider>\n );\n}\n\nexport const shareablesScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"ShareablesScreen\",\n displayName: \"Shareables Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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"}
@@ -1,7 +1,8 @@
1
1
  import { n as usePortalTenantClient } from "./PortalTenantClientProvider-4ZmY6hac.mjs";
2
+ import { _ as fluidToast } from "./src-BZbWkXOU.mjs";
2
3
  import { t as useAccount } from "./use-account-B16Tor2Q.mjs";
3
4
  import { n as useAppNavigation } from "./AppNavigationContext-BW3lSpfT.mjs";
4
- import { a as ShareablesApp, c as ShareablesCoreProvider, n as usePortalContentContext, o as useFilePickerApi, r as toggleFavorite, s as ShareablesUIProvider, t as PortalContentApiProvider } from "./PortalContentApiProvider-Cei2eKh_.mjs";
5
+ import { a as ShareablesApp, c as ShareablesCoreProvider, n as usePortalContentContext, o as useFilePickerApi, r as toggleFavorite, s as ShareablesUIProvider, t as PortalContentApiProvider } from "./PortalContentApiProvider-B8tHeIDR.mjs";
5
6
  import { t as PortalProductsApiProvider } from "./PortalProductsApiProvider-BALswRao.mjs";
6
7
  import { t as PORTAL_MYSITE_KEYS } from "./use-mysite-portal-BV-BP3CE.mjs";
7
8
  import { useCallback, useMemo } from "react";
@@ -94,7 +95,11 @@ function ShareablesScreenContent() {
94
95
  navigate(cleanPath.startsWith("share/") ? cleanPath : `share/${cleanPath}`);
95
96
  },
96
97
  showToast: (opts) => {
97
- console.warn(`[Shareables] ${opts.type}: ${opts.title}`);
98
+ fluidToast({
99
+ title: opts.title,
100
+ type: opts.type
101
+ });
102
+ if (opts.error) console.error("[Shareables]", opts.error);
98
103
  },
99
104
  filePickerApi,
100
105
  onToggleFavorite: async (params) => {
@@ -106,20 +111,34 @@ function ShareablesScreenContent() {
106
111
  await shareablesCtx.playlistsAdapter.deletePlaylist(playlistId);
107
112
  },
108
113
  mediaProductsApi: isCustomer ? void 0 : shareablesCtx.mediaProductsAdapter,
109
- searchProducts: isCustomer ? void 0 : async (query) => {
110
- return ((await portalProductsApi.searchProducts(query)).products ?? []).map((p) => ({
111
- id: p.id ?? 0,
112
- name: p.name ?? p.title ?? "Untitled",
113
- image_url: p.image_url ?? null,
114
- price: p.price ?? null
115
- }));
114
+ searchProducts: isCustomer ? void 0 : async (query, options) => {
115
+ const limit = options?.limit ?? 25;
116
+ const cursor = options?.cursor ?? void 0;
117
+ const result = query.trim().length > 0 ? await portalProductsApi.searchProducts(query, {
118
+ cursor,
119
+ limit
120
+ }) : await portalProductsApi.listProducts({
121
+ cursor,
122
+ limit
123
+ });
124
+ return {
125
+ products: (result.products ?? []).map((p) => p.id != null ? {
126
+ id: p.id,
127
+ name: p.name ?? p.title ?? "Untitled",
128
+ image_url: p.image_url ?? null,
129
+ price: p.price ?? null
130
+ } : null).filter((p) => p !== null),
131
+ nextCursor: result.meta?.pagination?.next_cursor ?? null
132
+ };
116
133
  },
117
134
  readOnly: isCustomer,
118
135
  uploadThumbnail: isCustomer ? void 0 : async (blob, filename) => {
119
136
  const formData = new FormData();
120
137
  formData.append("asset[name]", filename);
121
138
  formData.append("asset[file]", blob, filename);
122
- return (await client.requestWithFormData("/api/content/dam/assets", formData)).asset?.default_variant_url ?? "";
139
+ const url = (await client.requestWithFormData("/api/content/dam/assets", formData)).asset?.default_variant_url;
140
+ if (!url) throw new Error("Thumbnail upload succeeded but no URL returned");
141
+ return url;
123
142
  }
124
143
  }), [
125
144
  account,
@@ -158,4 +177,4 @@ const shareablesScreenPropertySchema = {
158
177
  //#endregion
159
178
  export { shareablesScreenPropertySchema as n, ShareablesScreen as t };
160
179
 
161
- //# sourceMappingURL=ShareablesScreen-lLzBYQ9u.mjs.map
180
+ //# sourceMappingURL=ShareablesScreen-IMOvttqL.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShareablesScreen-IMOvttqL.mjs","names":[],"sources":["../src/screens/ShareablesScreen.tsx"],"sourcesContent":["import { useCallback, useMemo, type ComponentProps } from \"react\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { PORTAL_MYSITE_KEYS } from \"@fluid-app/mysite-ui/portal/hooks/use-mysite-portal\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport { ShareablesCoreProvider } from \"@fluid-app/shareables-core\";\nimport { ShareablesUIProvider, ShareablesApp } from \"@fluid-app/shareables-ui\";\nimport { useFilePickerApi } from \"@fluid-app/file-picker-core\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { useAccount } from \"../hooks/use-account\";\nimport { PortalProductsApiProvider } from \"../products/PortalProductsApiProvider\";\nimport {\n PortalContentApiProvider,\n usePortalContentContext,\n} from \"../content/PortalContentApiProvider\";\nimport { toggleFavorite } from \"../adapters/content-api-adapter\";\nimport { usePortalTenantClient } from \"../providers/PortalTenantClientProvider\";\n\ntype ShareablesScreenProps = ComponentProps<\"div\"> & {\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n};\n\n/**\n * Parse the current shareables sub-route from the full slug.\n *\n * System nav slugs are \"share/products\", \"share/media\", \"share/playlists\".\n * Detail pages append an ID: \"share/products/123\", \"share/media/456\".\n *\n * \"share/products\" → screen=\"products\", detailId=null\n * \"share/products/123\" → screen=\"products\", detailId=\"123\"\n * \"share/media/456\" → screen=\"media\", detailId=\"456\"\n * \"share/playlists\" → screen=\"playlists\", detailId=null\n * \"share/playlists/789\" → screen=\"playlists\", detailId=\"789\"\n * \"share/files\" → screen=\"files\", detailId=null\n * \"share\" → screen=null (default to products)\n */\nfunction parseShareablesRoute(currentSlug: string): {\n screen: string | null;\n detailId: string | null;\n action: string | null;\n} {\n // Strip the \"share\" prefix\n const slugWithoutPrefix = currentSlug.replace(/^share\\/?/, \"\");\n if (!slugWithoutPrefix) {\n return { screen: null, detailId: null, action: null };\n }\n\n const parts = slugWithoutPrefix.split(\"/\");\n const screen = parts[0] || null;\n const detailId = parts[1] || null;\n const action = parts[2] || null;\n return { screen, detailId, action };\n}\n\nexport function ShareablesScreen({\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: ShareablesScreenProps): React.JSX.Element {\n return (\n <div {...divProps} className={`h-full ${divProps.className ?? \"\"}`}>\n <PortalProductsApiProvider>\n <PortalContentApiProvider>\n <ShareablesScreenContent />\n </PortalContentApiProvider>\n </PortalProductsApiProvider>\n </div>\n );\n}\n\n/** Inner component rendered inside providers so hooks can access context. */\nfunction ShareablesScreenContent(): React.JSX.Element {\n const shareablesCtx = usePortalContentContext();\n const { productsApi: portalProductsApi } = shareablesCtx;\n const filePickerApi = useFilePickerApi();\n const { data: account } = useAccount();\n const { currentSlug, navigate } = useAppNavigation();\n const isCustomer = account?.member_type === \"customer\";\n const client = usePortalTenantClient();\n const queryClient = useQueryClient();\n\n const fetchProducts = useCallback(\n async (search: string, cursor?: string, limit?: number) => {\n if (search) {\n return portalProductsApi.searchProducts(search, { cursor, limit });\n }\n return portalProductsApi.listProducts({ cursor, limit });\n },\n [portalProductsApi],\n );\n\n const fetchProduct = useCallback(\n async (id: string | number) => portalProductsApi.getProduct(id),\n [portalProductsApi],\n );\n\n const { screen, detailId, action } = parseShareablesRoute(currentSlug);\n\n const handleNavigate = useCallback(\n (subScreen: string, id?: string) => {\n const path = id ? `share/${subScreen}/${id}` : `share/${subScreen}`;\n navigate(path);\n },\n [navigate],\n );\n\n const handleBack = useCallback(() => {\n if (detailId && screen) {\n navigate(`share/${screen}`);\n } else {\n navigate(\"share/products\");\n }\n }, [navigate, detailId, screen]);\n\n const coreConfig = useMemo(\n () => ({\n user: account ? { id: account.id } : null,\n repContext: true,\n }),\n [account],\n );\n\n const uiConfig = useMemo(\n () => ({\n user: account\n ? {\n id: account.id,\n company: null, // TODO(portal-tenant): company branding not available from /api/account\n }\n : undefined,\n // TODO(portal-tenant): affiliate_id not available from /api/account\n affiliateId: null,\n basePath: \"\",\n navigate: (path: string) => {\n const cleanPath = path.replace(/^\\//, \"\");\n const prefixed = cleanPath.startsWith(\"share/\")\n ? cleanPath\n : `share/${cleanPath}`;\n navigate(prefixed);\n },\n showToast: (opts: {\n title: string;\n type: \"success\" | \"error\" | \"warning\";\n error?: unknown;\n }) => {\n fluidToast({ title: opts.title, type: opts.type });\n if (opts.error) console.error(\"[Shareables]\", opts.error);\n },\n filePickerApi,\n onToggleFavorite: async (params: {\n favoriteableId: number;\n favoriteableType: string;\n }) => {\n const result = await toggleFavorite(\n client,\n params.favoriteableId,\n params.favoriteableType,\n );\n void queryClient.invalidateQueries({\n queryKey: PORTAL_MYSITE_KEYS.favorites(),\n });\n return result;\n },\n onDeletePlaylist: isCustomer\n ? undefined\n : async (playlistId: number) => {\n await shareablesCtx.playlistsAdapter.deletePlaylist(playlistId);\n },\n mediaProductsApi: isCustomer\n ? undefined\n : shareablesCtx.mediaProductsAdapter,\n searchProducts: isCustomer\n ? undefined\n : async (\n query: string,\n options?: { cursor?: string | null; limit?: number },\n ) => {\n // Empty query → listProducts so the tag modal opens with\n // suggestions instead of a blank state. Non-empty → real search.\n // Both APIs forward cursor/limit so the tag modal can paginate.\n const limit = options?.limit ?? 25;\n const cursor = options?.cursor ?? undefined;\n const result =\n query.trim().length > 0\n ? await portalProductsApi.searchProducts(query, {\n cursor,\n limit,\n })\n : await portalProductsApi.listProducts({ cursor, limit });\n // Filter out products without an id — mapping an id-less record\n // to `id: 0` would let a subsequent add/remove tag operation\n // silently run on id=0 (confusing 404/422 at best, incorrect\n // mutation at worst).\n const mapped = (result.products ?? [])\n .map(\n (p: {\n id?: number;\n title?: string;\n name?: string;\n image_url?: string | null;\n price?: string | null;\n }) =>\n p.id != null\n ? {\n id: p.id,\n name: p.name ?? p.title ?? \"Untitled\",\n image_url: p.image_url ?? null,\n price: p.price ?? null,\n }\n : null,\n )\n .filter((p): p is NonNullable<typeof p> => p !== null);\n return {\n products: mapped,\n nextCursor: result.meta?.pagination?.next_cursor ?? null,\n };\n },\n readOnly: isCustomer,\n uploadThumbnail: isCustomer\n ? undefined\n : async (blob: Blob, filename: string) => {\n const formData = new FormData();\n formData.append(\"asset[name]\", filename);\n formData.append(\"asset[file]\", blob, filename);\n const response = await client.requestWithFormData<{\n asset?: { default_variant_url?: string | null };\n }>(\"/api/content/dam/assets\", formData);\n const url = response.asset?.default_variant_url;\n if (!url) {\n // DAM accepted the upload but didn't return a playable URL.\n // Throwing here lets the caller (MediaEditScreen catch handler)\n // surface a toast and keeps the pending thumbnail state clean —\n // returning \"\" silently would corrupt the save payload with an\n // empty thumbnail URL.\n throw new Error(\"Thumbnail upload succeeded but no URL returned\");\n }\n return url;\n },\n }),\n [\n account,\n navigate,\n filePickerApi,\n isCustomer,\n shareablesCtx.playlistsAdapter,\n shareablesCtx.mediaProductsAdapter,\n portalProductsApi,\n client,\n queryClient,\n ],\n );\n\n return (\n <ShareablesCoreProvider config={coreConfig}>\n <ShareablesUIProvider config={uiConfig}>\n <ShareablesApp\n screen={screen}\n detailId={detailId}\n action={action}\n companyLogoUrl={undefined}\n countryCode={undefined}\n fetchProducts={fetchProducts}\n fetchProduct={fetchProduct}\n onNavigate={handleNavigate}\n onBack={handleBack}\n />\n </ShareablesUIProvider>\n </ShareablesCoreProvider>\n );\n}\n\nexport const shareablesScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"ShareablesScreen\",\n displayName: \"Shareables Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -57,13 +57,13 @@ require("./src-BukXixXu.cjs");
57
57
  require("./dist-DbiSKQz4.cjs");
58
58
  const require_OrdersScreen = require("./OrdersScreen-tEz4rZn_.cjs");
59
59
  const require_SubscriptionsScreen = require("./SubscriptionsScreen-Dr0FmZZH.cjs");
60
- require("./PortalContentApiProvider-C2G-u4O2.cjs");
60
+ require("./PortalContentApiProvider-D6hzQ1aL.cjs");
61
61
  require("./dist-DWs3-WOI.cjs");
62
62
  require("./PortalProductsApiProvider-Duj-EjQj.cjs");
63
- const require_ProductsScreen = require("./ProductsScreen-ClOJgwBf.cjs");
63
+ const require_ProductsScreen = require("./ProductsScreen-MVCgkjrh.cjs");
64
64
  require("./use-mysite-portal-DzDYRU0u.cjs");
65
65
  const require_MySiteScreen = require("./MySiteScreen-B_ue0dF6.cjs");
66
- const require_ShareablesScreen = require("./ShareablesScreen-CkaXzERa.cjs");
66
+ const require_ShareablesScreen = require("./ShareablesScreen-DIo7EMlA.cjs");
67
67
  const require_ShopScreen = require("./ShopScreen-BojtrxZ9.cjs");
68
68
  require("./UpgradeScreen-BwWZYjrw.cjs");
69
69
  require("./AppDownloadScreen-DXkRe6MQ.cjs");
@@ -2142,8 +2142,8 @@ const MessagingScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => req
2142
2142
  const ContactsScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./ContactsScreen-f9MvO-hX.cjs")).then((m) => ({ default: m.ContactsScreen })));
2143
2143
  const ShopScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./ShopScreen-DkDh2aGx.cjs")).then((m) => ({ default: m.ShopScreen })));
2144
2144
  const CustomersScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./CustomersScreen-DRcCBHkL.cjs")).then((n) => n.CustomersScreen_exports).then((m) => ({ default: m.CustomersScreen })));
2145
- const ProductsScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./ProductsScreen-BJBagajA.cjs")).then((m) => ({ default: m.ProductsScreen })));
2146
- const ShareablesScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./ShareablesScreen-9j2YlYM5.cjs")).then((m) => ({ default: m.ShareablesScreen })));
2145
+ const ProductsScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./ProductsScreen-C8RdjP3N.cjs")).then((m) => ({ default: m.ProductsScreen })));
2146
+ const ShareablesScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./ShareablesScreen-BxUL0r-6.cjs")).then((m) => ({ default: m.ShareablesScreen })));
2147
2147
  const MySiteScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./MySiteScreen-W907mNoB.cjs")).then((m) => ({ default: m.MySiteScreen })));
2148
2148
  const UpgradeScreen = (0, react.lazy)(() => Promise.resolve().then(() => require("./UpgradeScreen-DqpdSO-F.cjs")).then((m) => ({ default: m.UpgradeScreen })));
2149
2149
  const AppDownloadScreen = (0, react.lazy)(() => Promise.resolve().then(() => require("./AppDownloadScreen-DXkRe6MQ.cjs")).then((n) => n.AppDownloadScreen_exports).then((m) => ({ default: m.AppDownloadScreen })));
@@ -3636,9 +3636,9 @@ const screenPropertySchemas = {
3636
3636
  OrdersScreen: () => Promise.resolve().then(() => require("./OrdersScreen-COGBqaif.cjs")).then((m) => m.ordersScreenPropertySchema),
3637
3637
  SubscriptionsScreen: () => Promise.resolve().then(() => require("./SubscriptionsScreen-CYIUXxrJ.cjs")).then((m) => m.subscriptionsScreenPropertySchema),
3638
3638
  CustomersScreen: () => Promise.resolve().then(() => require("./CustomersScreen-DRcCBHkL.cjs")).then((n) => n.CustomersScreen_exports).then((m) => m.customersScreenPropertySchema),
3639
- ProductsScreen: () => Promise.resolve().then(() => require("./ProductsScreen-BJBagajA.cjs")).then((m) => m.productsScreenPropertySchema),
3639
+ ProductsScreen: () => Promise.resolve().then(() => require("./ProductsScreen-C8RdjP3N.cjs")).then((m) => m.productsScreenPropertySchema),
3640
3640
  MySiteScreen: () => Promise.resolve().then(() => require("./MySiteScreen-W907mNoB.cjs")).then((m) => m.mySiteScreenPropertySchema),
3641
- ShareablesScreen: () => Promise.resolve().then(() => require("./ShareablesScreen-9j2YlYM5.cjs")).then((m) => m.shareablesScreenPropertySchema),
3641
+ ShareablesScreen: () => Promise.resolve().then(() => require("./ShareablesScreen-BxUL0r-6.cjs")).then((m) => m.shareablesScreenPropertySchema),
3642
3642
  ShopScreen: () => Promise.resolve().then(() => require("./ShopScreen-DkDh2aGx.cjs")).then((m) => m.shopScreenPropertySchema),
3643
3643
  UpgradeScreen: () => Promise.resolve().then(() => require("./UpgradeScreen-DqpdSO-F.cjs")).then((m) => m.upgradeScreenPropertySchema),
3644
3644
  AppDownloadScreen: () => Promise.resolve().then(() => require("./AppDownloadScreen-DXkRe6MQ.cjs")).then((n) => n.AppDownloadScreen_exports).then((m) => m.appDownloadScreenPropertySchema)