@fluid-app/portal-sdk 0.1.91 → 0.1.93
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/{AppDownloadScreen-BtvcE4pE.cjs → AppDownloadScreen-D-lPD090.cjs} +2 -2
- package/dist/{AppDownloadScreen-BtvcE4pE.cjs.map → AppDownloadScreen-D-lPD090.cjs.map} +1 -1
- package/dist/{AppDownloadScreen-Dx2nilnX.cjs → AppDownloadScreen-D4CtPMfZ.cjs} +2 -2
- package/dist/{AppDownloadScreen-RX8GSAyq.mjs → AppDownloadScreen-RGClSpeA.mjs} +2 -2
- package/dist/{AppDownloadScreen-RX8GSAyq.mjs.map → AppDownloadScreen-RGClSpeA.mjs.map} +1 -1
- package/dist/{ContactsScreen-DttcI388.cjs → ContactsScreen-0h6EW-5L.cjs} +2 -2
- package/dist/{ContactsScreen-DttcI388.cjs.map → ContactsScreen-0h6EW-5L.cjs.map} +1 -1
- package/dist/{ContactsScreen-DOz11uQ_.mjs → ContactsScreen-B5mf_3YF.mjs} +2 -2
- package/dist/{ContactsScreen-DOz11uQ_.mjs.map → ContactsScreen-B5mf_3YF.mjs.map} +1 -1
- package/dist/{ContactsScreen-CKMZIQlF.cjs → ContactsScreen-CCvizFdr.cjs} +2 -2
- package/dist/{FluidProvider-Sc51VlLw.cjs → FluidProvider-C27-ijsq.cjs} +58 -12
- package/dist/FluidProvider-C27-ijsq.cjs.map +1 -0
- package/dist/{FluidProvider-Eohedipr.mjs → FluidProvider-Nd7xkDWq.mjs} +47 -13
- package/dist/FluidProvider-Nd7xkDWq.mjs.map +1 -0
- package/dist/{MessagingScreen-CdHBUykK.cjs → MessagingScreen-8myurYB8.cjs} +2 -2
- package/dist/{MessagingScreen-r67FUDf1.cjs → MessagingScreen-B8u8kkH-.cjs} +3 -3
- package/dist/{MessagingScreen-r67FUDf1.cjs.map → MessagingScreen-B8u8kkH-.cjs.map} +1 -1
- package/dist/{MessagingScreen-CMxjIURw.mjs → MessagingScreen-CJO9b5Do.mjs} +3 -3
- package/dist/{MessagingScreen-CMxjIURw.mjs.map → MessagingScreen-CJO9b5Do.mjs.map} +1 -1
- package/dist/{MessagingScreen-Cx0bbvfs.mjs → MessagingScreen-oGxMJtNT.mjs} +2 -2
- package/dist/{MySiteScreen-BhdmPFar.mjs → MySiteScreen-Cz-KTIDH.mjs} +3 -3
- package/dist/{MySiteScreen-BhdmPFar.mjs.map → MySiteScreen-Cz-KTIDH.mjs.map} +1 -1
- package/dist/{MySiteScreen-Cy7HpS3z.cjs → MySiteScreen-DHtQ-nrj.cjs} +3 -3
- package/dist/{MySiteScreen-Cy7HpS3z.cjs.map → MySiteScreen-DHtQ-nrj.cjs.map} +1 -1
- package/dist/{MySiteScreen-8lZTZzo0.cjs → MySiteScreen-DxKXda65.cjs} +3 -3
- package/dist/{OrdersScreen-D0TnBQc5.mjs → OrdersScreen-CRhvTsZX.mjs} +3 -3
- package/dist/{OrdersScreen-D0TnBQc5.mjs.map → OrdersScreen-CRhvTsZX.mjs.map} +1 -1
- package/dist/{OrdersScreen-DCOzHNIy.cjs → OrdersScreen-DDqDubNG.cjs} +2 -2
- package/dist/{OrdersScreen-BaqQzT1F.cjs → OrdersScreen-DGWU9MKQ.cjs} +3 -3
- package/dist/{OrdersScreen-BaqQzT1F.cjs.map → OrdersScreen-DGWU9MKQ.cjs.map} +1 -1
- package/dist/{ProductsScreen-2tlHXemg.mjs → ProductsScreen-28vbEj_q.mjs} +4 -4
- package/dist/{ProductsScreen-Ch6f5P2w.cjs → ProductsScreen-BCKYCxLP.cjs} +4 -4
- package/dist/{ProductsScreen-2pUHZJop.mjs → ProductsScreen-CUQi-Rj5.mjs} +7 -6
- package/dist/ProductsScreen-CUQi-Rj5.mjs.map +1 -0
- package/dist/{ProductsScreen-ueEJP0MJ.cjs → ProductsScreen-TQGuItSe.cjs} +7 -6
- package/dist/ProductsScreen-TQGuItSe.cjs.map +1 -0
- package/dist/{ProfileScreen-C8fpr9c3.cjs → ProfileScreen-C-WEgl6I.cjs} +3 -3
- package/dist/{ProfileScreen-C8fpr9c3.cjs.map → ProfileScreen-C-WEgl6I.cjs.map} +1 -1
- package/dist/{ProfileScreen-Age0TtEY.mjs → ProfileScreen-CSyji2kX.mjs} +3 -3
- package/dist/{ProfileScreen-Age0TtEY.mjs.map → ProfileScreen-CSyji2kX.mjs.map} +1 -1
- package/dist/{ProfileScreen-DEtgeBnE.cjs → ProfileScreen-mbsYsvbX.cjs} +2 -2
- package/dist/{ShareablesScreen-vFbWhVGF.mjs → ShareablesScreen-B3LWG6Vd.mjs} +7 -7
- package/dist/{ShareablesScreen-vFbWhVGF.mjs.map → ShareablesScreen-B3LWG6Vd.mjs.map} +1 -1
- package/dist/{ShareablesScreen-B6uPSvvK.cjs → ShareablesScreen-DDDnyfpn.cjs} +7 -7
- package/dist/{ShareablesScreen-B6uPSvvK.cjs.map → ShareablesScreen-DDDnyfpn.cjs.map} +1 -1
- package/dist/{ShareablesScreen-DBdNgtV1.mjs → ShareablesScreen-DWlRD2yD.mjs} +4 -4
- package/dist/{ShareablesScreen-CoPFz5ZB.cjs → ShareablesScreen-Du70lYZA.cjs} +4 -4
- package/dist/{ShopScreen-BKBaNPsG.cjs → ShopScreen-CWuSRymK.cjs} +67 -51
- package/dist/ShopScreen-CWuSRymK.cjs.map +1 -0
- package/dist/{ShopScreen-D-TXRWZR.mjs → ShopScreen-CzY8rJg9.mjs} +67 -51
- package/dist/ShopScreen-CzY8rJg9.mjs.map +1 -0
- package/dist/{ShopScreen-DPZSXS99.cjs → ShopScreen-DQzt93BK.cjs} +2 -2
- package/dist/{SubscriptionsScreen-CBqgpat5.mjs → SubscriptionsScreen-CViYObw9.mjs} +3 -3
- package/dist/{SubscriptionsScreen-CBqgpat5.mjs.map → SubscriptionsScreen-CViYObw9.mjs.map} +1 -1
- package/dist/{SubscriptionsScreen-BvS7o_XP.cjs → SubscriptionsScreen-CjxanPLb.cjs} +3 -3
- package/dist/{SubscriptionsScreen-BvS7o_XP.cjs.map → SubscriptionsScreen-CjxanPLb.cjs.map} +1 -1
- package/dist/{SubscriptionsScreen-IbsNz0Ki.cjs → SubscriptionsScreen-Dc4JwfWg.cjs} +2 -2
- package/dist/{dist-BF_4vk1z.cjs → dist-BSbac3uh.cjs} +1 -1
- package/dist/{dist-BF_4vk1z.cjs.map → dist-BSbac3uh.cjs.map} +1 -1
- package/dist/index.cjs +43 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -352
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +38 -352
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +43 -39
- package/dist/index.mjs.map +1 -1
- package/dist/products-BAtIML76.cjs +114 -0
- package/dist/{products-BKZ1siXg.cjs.map → products-BAtIML76.cjs.map} +1 -1
- package/dist/products-StJIeia3.mjs +61 -0
- package/dist/{products-DOO1TBcm.mjs.map → products-StJIeia3.mjs.map} +1 -1
- package/dist/{sortable.esm-Cz-CP2N8.mjs → sortable.esm-DSrWP4x9.mjs} +1 -1
- package/dist/{sortable.esm-Cz-CP2N8.mjs.map → sortable.esm-DSrWP4x9.mjs.map} +1 -1
- package/dist/{src-Zv3-NSUf.cjs → src-CMByt6YP.cjs} +1 -1
- package/dist/{src-CN7diUEw.mjs.map → src-CMByt6YP.cjs.map} +1 -1
- package/dist/{src-Ih5vEO6p.mjs → src-CyrJPIY1.mjs} +3 -3
- package/dist/{src-Ih5vEO6p.mjs.map → src-CyrJPIY1.mjs.map} +1 -1
- package/dist/{src-CN7diUEw.mjs → src-DryOJTBW.mjs} +1 -1
- package/dist/{src-Zv3-NSUf.cjs.map → src-DryOJTBW.mjs.map} +1 -1
- package/dist/{src-BbJs882O.cjs → src-t3t8YW1J.cjs} +3 -3
- package/dist/{src-BbJs882O.cjs.map → src-t3t8YW1J.cjs.map} +1 -1
- package/dist/{use-account-clients-DaliJYMa.cjs → use-account-clients-CF79cijO.cjs} +2 -2
- package/dist/{use-account-clients-DaliJYMa.cjs.map → use-account-clients-CF79cijO.cjs.map} +1 -1
- package/dist/{use-account-clients-CSWgrCKK.mjs → use-account-clients-CaLsedpw.mjs} +2 -2
- package/dist/{use-account-clients-CSWgrCKK.mjs.map → use-account-clients-CaLsedpw.mjs.map} +1 -1
- package/dist/{use-current-user-5erIFUd6.cjs → use-current-user-CNyndpb0.cjs} +3 -3
- package/dist/{use-current-user-5erIFUd6.cjs.map → use-current-user-CNyndpb0.cjs.map} +1 -1
- package/dist/{use-current-user-BBQg1iYf.mjs → use-current-user-Cv4FHFqm.mjs} +3 -3
- package/dist/{use-current-user-BBQg1iYf.mjs.map → use-current-user-Cv4FHFqm.mjs.map} +1 -1
- package/dist/{use-customer-account-Dzdps4By.cjs → use-customer-account-9HqKnQx5.cjs} +3 -3
- package/dist/{use-customer-account-Dzdps4By.cjs.map → use-customer-account-9HqKnQx5.cjs.map} +1 -1
- package/dist/{use-customer-account-CRYpHpFM.mjs → use-customer-account-CewcODTd.mjs} +3 -3
- package/dist/{use-customer-account-CRYpHpFM.mjs.map → use-customer-account-CewcODTd.mjs.map} +1 -1
- package/dist/{use-fluid-api-C5ZLs2TP.mjs → use-fluid-api-D1QuzLw0.mjs} +2 -2
- package/dist/{use-fluid-api-C5ZLs2TP.mjs.map → use-fluid-api-D1QuzLw0.mjs.map} +1 -1
- package/dist/{use-fluid-api-BUitsoDu.cjs → use-fluid-api-zeOS14jg.cjs} +2 -2
- package/dist/{use-fluid-api-BUitsoDu.cjs.map → use-fluid-api-zeOS14jg.cjs.map} +1 -1
- package/package.json +12 -12
- package/dist/FluidProvider-Eohedipr.mjs.map +0 -1
- package/dist/FluidProvider-Sc51VlLw.cjs.map +0 -1
- package/dist/ProductsScreen-2pUHZJop.mjs.map +0 -1
- package/dist/ProductsScreen-ueEJP0MJ.cjs.map +0 -1
- package/dist/ShopScreen-BKBaNPsG.cjs.map +0 -1
- package/dist/ShopScreen-D-TXRWZR.mjs.map +0 -1
- package/dist/products-BKZ1siXg.cjs +0 -29
- package/dist/products-DOO1TBcm.mjs +0 -18
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require("./chunk-9hOWP6kD.cjs");
|
|
2
|
-
require("./FluidProvider-
|
|
3
|
-
const require_ProfileScreen = require("./ProfileScreen-
|
|
2
|
+
require("./FluidProvider-C27-ijsq.cjs");
|
|
3
|
+
const require_ProfileScreen = require("./ProfileScreen-C-WEgl6I.cjs");
|
|
4
4
|
require("./PointsWidget-Bgl95R-6.cjs");
|
|
5
5
|
require("./error-state-BDBF2JrB.cjs");
|
|
6
6
|
require("./ScreenRenderer-D65AsKjr.cjs");
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { i as useSdkClient, o as useFluidAuth } from "./use-account-clients-
|
|
3
|
-
import { n as useCurrentUser } from "./use-current-user-
|
|
1
|
+
import { mt as USER_TYPES } from "./FluidProvider-Nd7xkDWq.mjs";
|
|
2
|
+
import { i as useSdkClient, o as useFluidAuth } from "./use-account-clients-CaLsedpw.mjs";
|
|
3
|
+
import { n as useCurrentUser } from "./use-current-user-Cv4FHFqm.mjs";
|
|
4
4
|
import { n as useAppNavigation } from "./AppNavigationContext-BSnbFILQ.mjs";
|
|
5
|
-
import { a as ShareablesCoreProvider, i as ShareablesApiProvider, n as ShareablesApp, r as ShareablesUIProvider } from "./src-
|
|
6
|
-
import { n as createShareablesApiAdapter } from "./src-
|
|
5
|
+
import { a as ShareablesCoreProvider, i as ShareablesApiProvider, n as ShareablesApp, r as ShareablesUIProvider } from "./src-CyrJPIY1.mjs";
|
|
6
|
+
import { n as createShareablesApiAdapter } from "./src-DryOJTBW.mjs";
|
|
7
7
|
import { useCallback, useMemo } from "react";
|
|
8
8
|
import { jsx } from "react/jsx-runtime";
|
|
9
9
|
//#region src/hooks/use-user-type.ts
|
|
@@ -110,7 +110,7 @@ function ShareablesScreen({ background, textColor, accentColor, padding, borderR
|
|
|
110
110
|
});
|
|
111
111
|
},
|
|
112
112
|
onDeletePlaylist: isCustomer ? void 0 : async (playlistId) => {
|
|
113
|
-
const { playlists: playlistsApi } = await import("./src-
|
|
113
|
+
const { playlists: playlistsApi } = await import("./src-DryOJTBW.mjs").then((n) => n.t);
|
|
114
114
|
await playlistsApi.deletePlaylist(domainClient, playlistId);
|
|
115
115
|
},
|
|
116
116
|
readOnly: isCustomer
|
|
@@ -156,4 +156,4 @@ const shareablesScreenPropertySchema = {
|
|
|
156
156
|
//#endregion
|
|
157
157
|
export { shareablesScreenPropertySchema as n, useUserType as r, ShareablesScreen as t };
|
|
158
158
|
|
|
159
|
-
//# sourceMappingURL=ShareablesScreen-
|
|
159
|
+
//# sourceMappingURL=ShareablesScreen-B3LWG6Vd.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShareablesScreen-vFbWhVGF.mjs","names":[],"sources":["../src/hooks/use-user-type.ts","../../../file-picker/api-client/src/client.ts","../src/screens/ShareablesScreen.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useFluidAuth } from \"./use-fluid-auth\";\nimport { USER_TYPES, type UserType } from \"../auth/types\";\n\nexport interface UseUserTypeResult {\n userType: UserType | null;\n isCustomer: boolean;\n isRep: boolean;\n isAdmin: boolean;\n}\n\n/**\n * Convenience hook for user-type checks in the portal SDK.\n */\nexport function useUserType(): UseUserTypeResult {\n const { user } = useFluidAuth();\n\n return useMemo(() => {\n const userType = user?.user_type ?? null;\n return {\n userType,\n isCustomer: userType === USER_TYPES.customer,\n isRep: userType === USER_TYPES.rep,\n isAdmin:\n userType === USER_TYPES.admin || userType === USER_TYPES.root_admin,\n };\n }, [user?.user_type]);\n}\n","import type { FetchClientInstance } from \"@fluid-app/api-client-core\";\nimport type { DamAssetCreateResponse } from \"@fluid-app/file-picker-core\";\n\nexport interface DamUploadStrategy {\n uploadFile(params: {\n file: File;\n name: string;\n description?: string;\n tags?: string[];\n onProgress?: (progress: number) => void;\n companyId?: number;\n }): Promise<DamAssetCreateResponse>;\n}\n\nexport interface FilePickerClientConfig {\n fetchClient: FetchClientInstance;\n uploadStrategy?: DamUploadStrategy;\n unsplashAccessKey?: string;\n proxyEndpoint?: string; // defaults to \"/api/proxy-url\"\n}\n\nexport interface FilePickerClient {\n fetchClient: FetchClientInstance;\n uploadStrategy?: DamUploadStrategy;\n unsplashAccessKey?: string;\n proxyEndpoint: string;\n}\n\nexport function createFilePickerClient(\n config: FilePickerClientConfig,\n): FilePickerClient {\n return {\n fetchClient: config.fetchClient,\n uploadStrategy: config.uploadStrategy,\n unsplashAccessKey: config.unsplashAccessKey,\n proxyEndpoint: config.proxyEndpoint ?? \"/api/proxy-url\",\n };\n}\n","import { useCallback, useMemo, type ComponentProps } from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport {\n ShareablesCoreProvider,\n ShareablesApiProvider,\n type ShareablesApi,\n} from \"@fluid-app/shareables-core\";\nimport { ShareablesUIProvider, ShareablesApp } from \"@fluid-app/shareables-ui\";\nimport { createShareablesApiAdapter } from \"@fluid-app/shareables-api-client\";\nimport { createFilePickerClient } from \"@fluid-app/file-picker-api-client\";\nimport { useCurrentUser } from \"../hooks/use-current-user\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { useSdkClient } from \"../account/use-account-clients\";\nimport { useUserType } from \"../hooks/use-user-type\";\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 const domainClient = useSdkClient();\n const { data: userData } = useCurrentUser();\n const { currentSlug, navigate } = useAppNavigation();\n const { isCustomer } = useUserType();\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 back to the listing for the current screen\n navigate(`share/${screen}`);\n } else {\n // Navigate to the default shareables screen\n navigate(\"share/products\");\n }\n }, [navigate, detailId, screen]);\n\n const coreConfig = useMemo(\n () => ({\n client: domainClient,\n user: userData ? { id: userData.id } : null,\n repContext: true,\n }),\n [domainClient, userData],\n );\n\n const shareablesApi = useMemo<ShareablesApi>(\n () => createShareablesApiAdapter(domainClient, { repContext: true }),\n [domainClient],\n );\n\n const filePickerClient = useMemo(\n () => createFilePickerClient({ fetchClient: domainClient }),\n [domainClient],\n );\n\n const uiConfig = useMemo(\n () => ({\n user: userData\n ? {\n id: userData.id,\n company: userData.company\n ? { logo_url: userData.company.logo_url }\n : null,\n }\n : undefined,\n affiliateId:\n (userData as { affiliate_id?: number } | undefined)?.affiliate_id ??\n null,\n basePath: \"\",\n navigate: (path: string) => {\n // Strip leading slash — cards generate paths like \"/share/product/123\"\n const cleanPath = path.replace(/^\\//, \"\");\n // Ensure share/ prefix — screen components pass relative paths like \"media/new\"\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 }) => {\n console.warn(`[Shareables] ${opts.type}: ${opts.title}`);\n },\n filePickerClient,\n onToggleFavorite: async (params: {\n favoriteableId: number;\n favoriteableType: string;\n }) => {\n const affiliateId = (userData as { affiliate_id?: number } | undefined)\n ?.affiliate_id;\n if (!affiliateId) throw new Error(\"No affiliate ID\");\n return domainClient.post<{ is_favorited: boolean }>(\n `/user_companies/${affiliateId}/favorites/toggle.json`,\n {\n favoriteable_id: params.favoriteableId,\n favoriteable_type: params.favoriteableType,\n },\n );\n },\n onDeletePlaylist: isCustomer\n ? undefined\n : async (playlistId: number) => {\n const { playlists: playlistsApi } =\n await import(\"@fluid-app/shareables-api-client\");\n await playlistsApi.deletePlaylist(domainClient, playlistId);\n },\n readOnly: isCustomer,\n }),\n [userData, navigate, filePickerClient, domainClient, isCustomer],\n );\n\n return (\n <div {...divProps} className={`h-full ${divProps.className ?? \"\"}`}>\n <ShareablesCoreProvider config={coreConfig}>\n <ShareablesApiProvider api={shareablesApi}>\n <ShareablesUIProvider config={uiConfig}>\n <ShareablesApp\n screen={screen}\n detailId={detailId}\n action={action}\n companyLogoUrl={userData?.company?.logo_url}\n countryCode={userData?.country?.iso}\n onNavigate={handleNavigate}\n onBack={handleBack}\n />\n </ShareablesUIProvider>\n </ShareablesApiProvider>\n </ShareablesCoreProvider>\n </div>\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
|
+
{"version":3,"file":"ShareablesScreen-B3LWG6Vd.mjs","names":[],"sources":["../src/hooks/use-user-type.ts","../../../file-picker/api-client/src/client.ts","../src/screens/ShareablesScreen.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useFluidAuth } from \"./use-fluid-auth\";\nimport { USER_TYPES, type UserType } from \"../auth/types\";\n\nexport interface UseUserTypeResult {\n userType: UserType | null;\n isCustomer: boolean;\n isRep: boolean;\n isAdmin: boolean;\n}\n\n/**\n * Convenience hook for user-type checks in the portal SDK.\n */\nexport function useUserType(): UseUserTypeResult {\n const { user } = useFluidAuth();\n\n return useMemo(() => {\n const userType = user?.user_type ?? null;\n return {\n userType,\n isCustomer: userType === USER_TYPES.customer,\n isRep: userType === USER_TYPES.rep,\n isAdmin:\n userType === USER_TYPES.admin || userType === USER_TYPES.root_admin,\n };\n }, [user?.user_type]);\n}\n","import type { FetchClientInstance } from \"@fluid-app/api-client-core\";\nimport type { DamAssetCreateResponse } from \"@fluid-app/file-picker-core\";\n\nexport interface DamUploadStrategy {\n uploadFile(params: {\n file: File;\n name: string;\n description?: string;\n tags?: string[];\n onProgress?: (progress: number) => void;\n companyId?: number;\n }): Promise<DamAssetCreateResponse>;\n}\n\nexport interface FilePickerClientConfig {\n fetchClient: FetchClientInstance;\n uploadStrategy?: DamUploadStrategy;\n unsplashAccessKey?: string;\n proxyEndpoint?: string; // defaults to \"/api/proxy-url\"\n}\n\nexport interface FilePickerClient {\n fetchClient: FetchClientInstance;\n uploadStrategy?: DamUploadStrategy;\n unsplashAccessKey?: string;\n proxyEndpoint: string;\n}\n\nexport function createFilePickerClient(\n config: FilePickerClientConfig,\n): FilePickerClient {\n return {\n fetchClient: config.fetchClient,\n uploadStrategy: config.uploadStrategy,\n unsplashAccessKey: config.unsplashAccessKey,\n proxyEndpoint: config.proxyEndpoint ?? \"/api/proxy-url\",\n };\n}\n","import { useCallback, useMemo, type ComponentProps } from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport {\n ShareablesCoreProvider,\n ShareablesApiProvider,\n type ShareablesApi,\n} from \"@fluid-app/shareables-core\";\nimport { ShareablesUIProvider, ShareablesApp } from \"@fluid-app/shareables-ui\";\nimport { createShareablesApiAdapter } from \"@fluid-app/shareables-api-client\";\nimport { createFilePickerClient } from \"@fluid-app/file-picker-api-client\";\nimport { useCurrentUser } from \"../hooks/use-current-user\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { useSdkClient } from \"../account/use-account-clients\";\nimport { useUserType } from \"../hooks/use-user-type\";\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 const domainClient = useSdkClient();\n const { data: userData } = useCurrentUser();\n const { currentSlug, navigate } = useAppNavigation();\n const { isCustomer } = useUserType();\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 back to the listing for the current screen\n navigate(`share/${screen}`);\n } else {\n // Navigate to the default shareables screen\n navigate(\"share/products\");\n }\n }, [navigate, detailId, screen]);\n\n const coreConfig = useMemo(\n () => ({\n client: domainClient,\n user: userData ? { id: userData.id } : null,\n repContext: true,\n }),\n [domainClient, userData],\n );\n\n const shareablesApi = useMemo<ShareablesApi>(\n () => createShareablesApiAdapter(domainClient, { repContext: true }),\n [domainClient],\n );\n\n const filePickerClient = useMemo(\n () => createFilePickerClient({ fetchClient: domainClient }),\n [domainClient],\n );\n\n const uiConfig = useMemo(\n () => ({\n user: userData\n ? {\n id: userData.id,\n company: userData.company\n ? { logo_url: userData.company.logo_url }\n : null,\n }\n : undefined,\n affiliateId:\n (userData as { affiliate_id?: number } | undefined)?.affiliate_id ??\n null,\n basePath: \"\",\n navigate: (path: string) => {\n // Strip leading slash — cards generate paths like \"/share/product/123\"\n const cleanPath = path.replace(/^\\//, \"\");\n // Ensure share/ prefix — screen components pass relative paths like \"media/new\"\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 }) => {\n console.warn(`[Shareables] ${opts.type}: ${opts.title}`);\n },\n filePickerClient,\n onToggleFavorite: async (params: {\n favoriteableId: number;\n favoriteableType: string;\n }) => {\n const affiliateId = (userData as { affiliate_id?: number } | undefined)\n ?.affiliate_id;\n if (!affiliateId) throw new Error(\"No affiliate ID\");\n return domainClient.post<{ is_favorited: boolean }>(\n `/user_companies/${affiliateId}/favorites/toggle.json`,\n {\n favoriteable_id: params.favoriteableId,\n favoriteable_type: params.favoriteableType,\n },\n );\n },\n onDeletePlaylist: isCustomer\n ? undefined\n : async (playlistId: number) => {\n const { playlists: playlistsApi } =\n await import(\"@fluid-app/shareables-api-client\");\n await playlistsApi.deletePlaylist(domainClient, playlistId);\n },\n readOnly: isCustomer,\n }),\n [userData, navigate, filePickerClient, domainClient, isCustomer],\n );\n\n return (\n <div {...divProps} className={`h-full ${divProps.className ?? \"\"}`}>\n <ShareablesCoreProvider config={coreConfig}>\n <ShareablesApiProvider api={shareablesApi}>\n <ShareablesUIProvider config={uiConfig}>\n <ShareablesApp\n screen={screen}\n detailId={detailId}\n action={action}\n companyLogoUrl={userData?.company?.logo_url}\n countryCode={userData?.country?.iso}\n onNavigate={handleNavigate}\n onBack={handleBack}\n />\n </ShareablesUIProvider>\n </ShareablesApiProvider>\n </ShareablesCoreProvider>\n </div>\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":";;;;;;;;;;;;AAcA,SAAgB,cAAiC;CAC/C,MAAM,EAAE,SAAS,cAAc;AAE/B,QAAO,cAAc;EACnB,MAAM,WAAW,MAAM,aAAa;AACpC,SAAO;GACL;GACA,YAAY,aAAa,WAAW;GACpC,OAAO,aAAa,WAAW;GAC/B,SACE,aAAa,WAAW,SAAS,aAAa,WAAW;GAC5D;IACA,CAAC,MAAM,UAAU,CAAC;;;;ACEvB,SAAgB,uBACd,QACkB;AAClB,QAAO;EACL,aAAa,OAAO;EACpB,gBAAgB,OAAO;EACvB,mBAAmB,OAAO;EAC1B,eAAe,OAAO,iBAAiB;EACxC;;;;;;;;;;;;;;;;;;ACOH,SAAS,qBAAqB,aAI5B;CAEA,MAAM,oBAAoB,YAAY,QAAQ,aAAa,GAAG;AAC9D,KAAI,CAAC,kBACH,QAAO;EAAE,QAAQ;EAAM,UAAU;EAAM,QAAQ;EAAM;CAGvD,MAAM,QAAQ,kBAAkB,MAAM,IAAI;AAI1C,QAAO;EAAE,QAHM,MAAM,MAAM;EAGV,UAFA,MAAM,MAAM;EAEF,QADZ,MAAM,MAAM;EACQ;;AAGrC,SAAgB,iBAAiB,EAE/B,YACA,WACA,aACA,SACA,cAEA,GAAG,YACwC;CAC3C,MAAM,eAAe,cAAc;CACnC,MAAM,EAAE,MAAM,aAAa,gBAAgB;CAC3C,MAAM,EAAE,aAAa,aAAa,kBAAkB;CACpD,MAAM,EAAE,eAAe,aAAa;CAEpC,MAAM,EAAE,QAAQ,UAAU,WAAW,qBAAqB,YAAY;CAEtE,MAAM,iBAAiB,aACpB,WAAmB,OAAgB;AAElC,WADa,KAAK,SAAS,UAAU,GAAG,OAAO,SAAS,YAC1C;IAEhB,CAAC,SAAS,CACX;CAED,MAAM,aAAa,kBAAkB;AACnC,MAAI,YAAY,OAEd,UAAS,SAAS,SAAS;MAG3B,UAAS,iBAAiB;IAE3B;EAAC;EAAU;EAAU;EAAO,CAAC;CAEhC,MAAM,aAAa,eACV;EACL,QAAQ;EACR,MAAM,WAAW,EAAE,IAAI,SAAS,IAAI,GAAG;EACvC,YAAY;EACb,GACD,CAAC,cAAc,SAAS,CACzB;CAED,MAAM,gBAAgB,cACd,2BAA2B,cAAc,EAAE,YAAY,MAAM,CAAC,EACpE,CAAC,aAAa,CACf;CAED,MAAM,mBAAmB,cACjB,uBAAuB,EAAE,aAAa,cAAc,CAAC,EAC3D,CAAC,aAAa,CACf;CAED,MAAM,WAAW,eACR;EACL,MAAM,WACF;GACE,IAAI,SAAS;GACb,SAAS,SAAS,UACd,EAAE,UAAU,SAAS,QAAQ,UAAU,GACvC;GACL,GACD,KAAA;EACJ,aACG,UAAoD,gBACrD;EACF,UAAU;EACV,WAAW,SAAiB;GAE1B,MAAM,YAAY,KAAK,QAAQ,OAAO,GAAG;AAKzC,YAHiB,UAAU,WAAW,SAAS,GAC3C,YACA,SAAS,YACK;;EAEpB,YAAY,SAGN;AACJ,WAAQ,KAAK,gBAAgB,KAAK,KAAK,IAAI,KAAK,QAAQ;;EAE1D;EACA,kBAAkB,OAAO,WAGnB;GACJ,MAAM,cAAe,UACjB;AACJ,OAAI,CAAC,YAAa,OAAM,IAAI,MAAM,kBAAkB;AACpD,UAAO,aAAa,KAClB,mBAAmB,YAAY,yBAC/B;IACE,iBAAiB,OAAO;IACxB,mBAAmB,OAAO;IAC3B,CACF;;EAEH,kBAAkB,aACd,KAAA,IACA,OAAO,eAAuB;GAC5B,MAAM,EAAE,WAAW,iBACjB,MAAM,OAAO,sBAAA,MAAA,MAAA,EAAA,EAAA;AACf,SAAM,aAAa,eAAe,cAAc,WAAW;;EAEjE,UAAU;EACX,GACD;EAAC;EAAU;EAAU;EAAkB;EAAc;EAAW,CACjE;AAED,QACE,oBAAC,OAAD;EAAK,GAAI;EAAU,WAAW,UAAU,SAAS,aAAa;YAC5D,oBAAC,wBAAD;GAAwB,QAAQ;aAC9B,oBAAC,uBAAD;IAAuB,KAAK;cAC1B,oBAAC,sBAAD;KAAsB,QAAQ;eAC5B,oBAAC,eAAD;MACU;MACE;MACF;MACR,gBAAgB,UAAU,SAAS;MACnC,aAAa,UAAU,SAAS;MAChC,YAAY;MACZ,QAAQ;MACR,CAAA;KACmB,CAAA;IACD,CAAA;GACD,CAAA;EACrB,CAAA;;AAIV,MAAa,iCAAuD;CAClE,YAAY;CACZ,aAAa;CACb,YAAY,CAAC;EAAE,IAAI;EAAW,OAAO;EAAW,CAAC;CACjD,QAAQ,EAAE;CACX"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
require("./chunk-9hOWP6kD.cjs");
|
|
2
|
-
const require_FluidProvider = require("./FluidProvider-
|
|
3
|
-
const require_use_account_clients = require("./use-account-clients-
|
|
4
|
-
const require_use_current_user = require("./use-current-user-
|
|
2
|
+
const require_FluidProvider = require("./FluidProvider-C27-ijsq.cjs");
|
|
3
|
+
const require_use_account_clients = require("./use-account-clients-CF79cijO.cjs");
|
|
4
|
+
const require_use_current_user = require("./use-current-user-CNyndpb0.cjs");
|
|
5
5
|
const require_AppNavigationContext = require("./AppNavigationContext-DnwdUAjn.cjs");
|
|
6
|
-
const require_src = require("./src-
|
|
7
|
-
const require_src$1 = require("./src-
|
|
6
|
+
const require_src = require("./src-t3t8YW1J.cjs");
|
|
7
|
+
const require_src$1 = require("./src-CMByt6YP.cjs");
|
|
8
8
|
let react = require("react");
|
|
9
9
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
10
10
|
//#region src/hooks/use-user-type.ts
|
|
@@ -111,7 +111,7 @@ function ShareablesScreen({ background, textColor, accentColor, padding, borderR
|
|
|
111
111
|
});
|
|
112
112
|
},
|
|
113
113
|
onDeletePlaylist: isCustomer ? void 0 : async (playlistId) => {
|
|
114
|
-
const { playlists: playlistsApi } = await Promise.resolve().then(() => require("./src-
|
|
114
|
+
const { playlists: playlistsApi } = await Promise.resolve().then(() => require("./src-CMByt6YP.cjs")).then((n) => n.src_exports);
|
|
115
115
|
await playlistsApi.deletePlaylist(domainClient, playlistId);
|
|
116
116
|
},
|
|
117
117
|
readOnly: isCustomer
|
|
@@ -174,4 +174,4 @@ Object.defineProperty(exports, "useUserType", {
|
|
|
174
174
|
}
|
|
175
175
|
});
|
|
176
176
|
|
|
177
|
-
//# sourceMappingURL=ShareablesScreen-
|
|
177
|
+
//# sourceMappingURL=ShareablesScreen-DDDnyfpn.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShareablesScreen-B6uPSvvK.cjs","names":["useFluidAuth","USER_TYPES","useSdkClient","useCurrentUser","useAppNavigation","createShareablesApiAdapter","ShareablesCoreProvider","ShareablesApiProvider","ShareablesUIProvider","ShareablesApp"],"sources":["../src/hooks/use-user-type.ts","../../../file-picker/api-client/src/client.ts","../src/screens/ShareablesScreen.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useFluidAuth } from \"./use-fluid-auth\";\nimport { USER_TYPES, type UserType } from \"../auth/types\";\n\nexport interface UseUserTypeResult {\n userType: UserType | null;\n isCustomer: boolean;\n isRep: boolean;\n isAdmin: boolean;\n}\n\n/**\n * Convenience hook for user-type checks in the portal SDK.\n */\nexport function useUserType(): UseUserTypeResult {\n const { user } = useFluidAuth();\n\n return useMemo(() => {\n const userType = user?.user_type ?? null;\n return {\n userType,\n isCustomer: userType === USER_TYPES.customer,\n isRep: userType === USER_TYPES.rep,\n isAdmin:\n userType === USER_TYPES.admin || userType === USER_TYPES.root_admin,\n };\n }, [user?.user_type]);\n}\n","import type { FetchClientInstance } from \"@fluid-app/api-client-core\";\nimport type { DamAssetCreateResponse } from \"@fluid-app/file-picker-core\";\n\nexport interface DamUploadStrategy {\n uploadFile(params: {\n file: File;\n name: string;\n description?: string;\n tags?: string[];\n onProgress?: (progress: number) => void;\n companyId?: number;\n }): Promise<DamAssetCreateResponse>;\n}\n\nexport interface FilePickerClientConfig {\n fetchClient: FetchClientInstance;\n uploadStrategy?: DamUploadStrategy;\n unsplashAccessKey?: string;\n proxyEndpoint?: string; // defaults to \"/api/proxy-url\"\n}\n\nexport interface FilePickerClient {\n fetchClient: FetchClientInstance;\n uploadStrategy?: DamUploadStrategy;\n unsplashAccessKey?: string;\n proxyEndpoint: string;\n}\n\nexport function createFilePickerClient(\n config: FilePickerClientConfig,\n): FilePickerClient {\n return {\n fetchClient: config.fetchClient,\n uploadStrategy: config.uploadStrategy,\n unsplashAccessKey: config.unsplashAccessKey,\n proxyEndpoint: config.proxyEndpoint ?? \"/api/proxy-url\",\n };\n}\n","import { useCallback, useMemo, type ComponentProps } from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport {\n ShareablesCoreProvider,\n ShareablesApiProvider,\n type ShareablesApi,\n} from \"@fluid-app/shareables-core\";\nimport { ShareablesUIProvider, ShareablesApp } from \"@fluid-app/shareables-ui\";\nimport { createShareablesApiAdapter } from \"@fluid-app/shareables-api-client\";\nimport { createFilePickerClient } from \"@fluid-app/file-picker-api-client\";\nimport { useCurrentUser } from \"../hooks/use-current-user\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { useSdkClient } from \"../account/use-account-clients\";\nimport { useUserType } from \"../hooks/use-user-type\";\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 const domainClient = useSdkClient();\n const { data: userData } = useCurrentUser();\n const { currentSlug, navigate } = useAppNavigation();\n const { isCustomer } = useUserType();\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 back to the listing for the current screen\n navigate(`share/${screen}`);\n } else {\n // Navigate to the default shareables screen\n navigate(\"share/products\");\n }\n }, [navigate, detailId, screen]);\n\n const coreConfig = useMemo(\n () => ({\n client: domainClient,\n user: userData ? { id: userData.id } : null,\n repContext: true,\n }),\n [domainClient, userData],\n );\n\n const shareablesApi = useMemo<ShareablesApi>(\n () => createShareablesApiAdapter(domainClient, { repContext: true }),\n [domainClient],\n );\n\n const filePickerClient = useMemo(\n () => createFilePickerClient({ fetchClient: domainClient }),\n [domainClient],\n );\n\n const uiConfig = useMemo(\n () => ({\n user: userData\n ? {\n id: userData.id,\n company: userData.company\n ? { logo_url: userData.company.logo_url }\n : null,\n }\n : undefined,\n affiliateId:\n (userData as { affiliate_id?: number } | undefined)?.affiliate_id ??\n null,\n basePath: \"\",\n navigate: (path: string) => {\n // Strip leading slash — cards generate paths like \"/share/product/123\"\n const cleanPath = path.replace(/^\\//, \"\");\n // Ensure share/ prefix — screen components pass relative paths like \"media/new\"\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 }) => {\n console.warn(`[Shareables] ${opts.type}: ${opts.title}`);\n },\n filePickerClient,\n onToggleFavorite: async (params: {\n favoriteableId: number;\n favoriteableType: string;\n }) => {\n const affiliateId = (userData as { affiliate_id?: number } | undefined)\n ?.affiliate_id;\n if (!affiliateId) throw new Error(\"No affiliate ID\");\n return domainClient.post<{ is_favorited: boolean }>(\n `/user_companies/${affiliateId}/favorites/toggle.json`,\n {\n favoriteable_id: params.favoriteableId,\n favoriteable_type: params.favoriteableType,\n },\n );\n },\n onDeletePlaylist: isCustomer\n ? undefined\n : async (playlistId: number) => {\n const { playlists: playlistsApi } =\n await import(\"@fluid-app/shareables-api-client\");\n await playlistsApi.deletePlaylist(domainClient, playlistId);\n },\n readOnly: isCustomer,\n }),\n [userData, navigate, filePickerClient, domainClient, isCustomer],\n );\n\n return (\n <div {...divProps} className={`h-full ${divProps.className ?? \"\"}`}>\n <ShareablesCoreProvider config={coreConfig}>\n <ShareablesApiProvider api={shareablesApi}>\n <ShareablesUIProvider config={uiConfig}>\n <ShareablesApp\n screen={screen}\n detailId={detailId}\n action={action}\n companyLogoUrl={userData?.company?.logo_url}\n countryCode={userData?.country?.iso}\n onNavigate={handleNavigate}\n onBack={handleBack}\n />\n </ShareablesUIProvider>\n </ShareablesApiProvider>\n </ShareablesCoreProvider>\n </div>\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
|
+
{"version":3,"file":"ShareablesScreen-DDDnyfpn.cjs","names":["useFluidAuth","USER_TYPES","useSdkClient","useCurrentUser","useAppNavigation","createShareablesApiAdapter","ShareablesCoreProvider","ShareablesApiProvider","ShareablesUIProvider","ShareablesApp"],"sources":["../src/hooks/use-user-type.ts","../../../file-picker/api-client/src/client.ts","../src/screens/ShareablesScreen.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useFluidAuth } from \"./use-fluid-auth\";\nimport { USER_TYPES, type UserType } from \"../auth/types\";\n\nexport interface UseUserTypeResult {\n userType: UserType | null;\n isCustomer: boolean;\n isRep: boolean;\n isAdmin: boolean;\n}\n\n/**\n * Convenience hook for user-type checks in the portal SDK.\n */\nexport function useUserType(): UseUserTypeResult {\n const { user } = useFluidAuth();\n\n return useMemo(() => {\n const userType = user?.user_type ?? null;\n return {\n userType,\n isCustomer: userType === USER_TYPES.customer,\n isRep: userType === USER_TYPES.rep,\n isAdmin:\n userType === USER_TYPES.admin || userType === USER_TYPES.root_admin,\n };\n }, [user?.user_type]);\n}\n","import type { FetchClientInstance } from \"@fluid-app/api-client-core\";\nimport type { DamAssetCreateResponse } from \"@fluid-app/file-picker-core\";\n\nexport interface DamUploadStrategy {\n uploadFile(params: {\n file: File;\n name: string;\n description?: string;\n tags?: string[];\n onProgress?: (progress: number) => void;\n companyId?: number;\n }): Promise<DamAssetCreateResponse>;\n}\n\nexport interface FilePickerClientConfig {\n fetchClient: FetchClientInstance;\n uploadStrategy?: DamUploadStrategy;\n unsplashAccessKey?: string;\n proxyEndpoint?: string; // defaults to \"/api/proxy-url\"\n}\n\nexport interface FilePickerClient {\n fetchClient: FetchClientInstance;\n uploadStrategy?: DamUploadStrategy;\n unsplashAccessKey?: string;\n proxyEndpoint: string;\n}\n\nexport function createFilePickerClient(\n config: FilePickerClientConfig,\n): FilePickerClient {\n return {\n fetchClient: config.fetchClient,\n uploadStrategy: config.uploadStrategy,\n unsplashAccessKey: config.unsplashAccessKey,\n proxyEndpoint: config.proxyEndpoint ?? \"/api/proxy-url\",\n };\n}\n","import { useCallback, useMemo, type ComponentProps } from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport {\n ShareablesCoreProvider,\n ShareablesApiProvider,\n type ShareablesApi,\n} from \"@fluid-app/shareables-core\";\nimport { ShareablesUIProvider, ShareablesApp } from \"@fluid-app/shareables-ui\";\nimport { createShareablesApiAdapter } from \"@fluid-app/shareables-api-client\";\nimport { createFilePickerClient } from \"@fluid-app/file-picker-api-client\";\nimport { useCurrentUser } from \"../hooks/use-current-user\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { useSdkClient } from \"../account/use-account-clients\";\nimport { useUserType } from \"../hooks/use-user-type\";\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 const domainClient = useSdkClient();\n const { data: userData } = useCurrentUser();\n const { currentSlug, navigate } = useAppNavigation();\n const { isCustomer } = useUserType();\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 back to the listing for the current screen\n navigate(`share/${screen}`);\n } else {\n // Navigate to the default shareables screen\n navigate(\"share/products\");\n }\n }, [navigate, detailId, screen]);\n\n const coreConfig = useMemo(\n () => ({\n client: domainClient,\n user: userData ? { id: userData.id } : null,\n repContext: true,\n }),\n [domainClient, userData],\n );\n\n const shareablesApi = useMemo<ShareablesApi>(\n () => createShareablesApiAdapter(domainClient, { repContext: true }),\n [domainClient],\n );\n\n const filePickerClient = useMemo(\n () => createFilePickerClient({ fetchClient: domainClient }),\n [domainClient],\n );\n\n const uiConfig = useMemo(\n () => ({\n user: userData\n ? {\n id: userData.id,\n company: userData.company\n ? { logo_url: userData.company.logo_url }\n : null,\n }\n : undefined,\n affiliateId:\n (userData as { affiliate_id?: number } | undefined)?.affiliate_id ??\n null,\n basePath: \"\",\n navigate: (path: string) => {\n // Strip leading slash — cards generate paths like \"/share/product/123\"\n const cleanPath = path.replace(/^\\//, \"\");\n // Ensure share/ prefix — screen components pass relative paths like \"media/new\"\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 }) => {\n console.warn(`[Shareables] ${opts.type}: ${opts.title}`);\n },\n filePickerClient,\n onToggleFavorite: async (params: {\n favoriteableId: number;\n favoriteableType: string;\n }) => {\n const affiliateId = (userData as { affiliate_id?: number } | undefined)\n ?.affiliate_id;\n if (!affiliateId) throw new Error(\"No affiliate ID\");\n return domainClient.post<{ is_favorited: boolean }>(\n `/user_companies/${affiliateId}/favorites/toggle.json`,\n {\n favoriteable_id: params.favoriteableId,\n favoriteable_type: params.favoriteableType,\n },\n );\n },\n onDeletePlaylist: isCustomer\n ? undefined\n : async (playlistId: number) => {\n const { playlists: playlistsApi } =\n await import(\"@fluid-app/shareables-api-client\");\n await playlistsApi.deletePlaylist(domainClient, playlistId);\n },\n readOnly: isCustomer,\n }),\n [userData, navigate, filePickerClient, domainClient, isCustomer],\n );\n\n return (\n <div {...divProps} className={`h-full ${divProps.className ?? \"\"}`}>\n <ShareablesCoreProvider config={coreConfig}>\n <ShareablesApiProvider api={shareablesApi}>\n <ShareablesUIProvider config={uiConfig}>\n <ShareablesApp\n screen={screen}\n detailId={detailId}\n action={action}\n companyLogoUrl={userData?.company?.logo_url}\n countryCode={userData?.country?.iso}\n onNavigate={handleNavigate}\n onBack={handleBack}\n />\n </ShareablesUIProvider>\n </ShareablesApiProvider>\n </ShareablesCoreProvider>\n </div>\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,4 +1,4 @@
|
|
|
1
|
-
import "./FluidProvider-
|
|
1
|
+
import "./FluidProvider-Nd7xkDWq.mjs";
|
|
2
2
|
import "./PointsWidget-C05iCMne.mjs";
|
|
3
3
|
import "./error-state-C9MqwdW7.mjs";
|
|
4
4
|
import "./ScreenRenderer-DoVfmxCl.mjs";
|
|
@@ -33,10 +33,10 @@ import "./TableWidget-Nkzz38xS.mjs";
|
|
|
33
33
|
import "./ToDoWidget-D52-GT7f.mjs";
|
|
34
34
|
import "./VideoWidget-4DRASBWA.mjs";
|
|
35
35
|
import "./ScreenHeaderContext-NdrJ58Mg.mjs";
|
|
36
|
-
import { n as shareablesScreenPropertySchema, t as ShareablesScreen } from "./ShareablesScreen-
|
|
36
|
+
import { n as shareablesScreenPropertySchema, t as ShareablesScreen } from "./ShareablesScreen-B3LWG6Vd.mjs";
|
|
37
37
|
import "./dist-CkIGP8my.mjs";
|
|
38
38
|
import "./es-Dlib2eNY.mjs";
|
|
39
39
|
import "./dist-C9vpl_rR.mjs";
|
|
40
|
-
import "./src-
|
|
41
|
-
import "./sortable.esm-
|
|
40
|
+
import "./src-CyrJPIY1.mjs";
|
|
41
|
+
import "./sortable.esm-DSrWP4x9.mjs";
|
|
42
42
|
export { ShareablesScreen, shareablesScreenPropertySchema };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
require("./chunk-9hOWP6kD.cjs");
|
|
2
|
-
require("./FluidProvider-
|
|
2
|
+
require("./FluidProvider-C27-ijsq.cjs");
|
|
3
3
|
require("./PointsWidget-Bgl95R-6.cjs");
|
|
4
4
|
require("./error-state-BDBF2JrB.cjs");
|
|
5
5
|
require("./ScreenRenderer-D65AsKjr.cjs");
|
|
@@ -34,11 +34,11 @@ require("./TableWidget-Duw_7iyh.cjs");
|
|
|
34
34
|
require("./ToDoWidget-eGB9cfou.cjs");
|
|
35
35
|
require("./VideoWidget-CNHJrY7I.cjs");
|
|
36
36
|
require("./ScreenHeaderContext-wrJlkhgN.cjs");
|
|
37
|
-
const require_ShareablesScreen = require("./ShareablesScreen-
|
|
37
|
+
const require_ShareablesScreen = require("./ShareablesScreen-DDDnyfpn.cjs");
|
|
38
38
|
require("./dist-thaj08s5.cjs");
|
|
39
39
|
require("./es-xQF-WIMq.cjs");
|
|
40
40
|
require("./dist-BK4mvUPm.cjs");
|
|
41
|
-
require("./src-
|
|
42
|
-
require("./dist-
|
|
41
|
+
require("./src-t3t8YW1J.cjs");
|
|
42
|
+
require("./dist-BSbac3uh.cjs");
|
|
43
43
|
exports.ShareablesScreen = require_ShareablesScreen.ShareablesScreen;
|
|
44
44
|
exports.shareablesScreenPropertySchema = require_ShareablesScreen.shareablesScreenPropertySchema;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
const require_chunk = require("./chunk-9hOWP6kD.cjs");
|
|
2
|
-
const require_FluidProvider = require("./FluidProvider-
|
|
2
|
+
const require_FluidProvider = require("./FluidProvider-C27-ijsq.cjs");
|
|
3
3
|
const require_src = require("./src-DGjAAfmN.cjs");
|
|
4
|
-
const require_use_account_clients = require("./use-account-clients-
|
|
4
|
+
const require_use_account_clients = require("./use-account-clients-CF79cijO.cjs");
|
|
5
5
|
const require_ScreenHeaderContext = require("./ScreenHeaderContext-wrJlkhgN.cjs");
|
|
6
|
-
const require_use_current_user = require("./use-current-user-
|
|
6
|
+
const require_use_current_user = require("./use-current-user-CNyndpb0.cjs");
|
|
7
7
|
const require_AppNavigationContext = require("./AppNavigationContext-DnwdUAjn.cjs");
|
|
8
|
-
const require_products = require("./products-
|
|
8
|
+
const require_products = require("./products-BAtIML76.cjs");
|
|
9
9
|
let react = require("react");
|
|
10
10
|
react = require_chunk.__toESM(react);
|
|
11
11
|
let _tanstack_react_query = require("@tanstack/react-query");
|
|
@@ -14,53 +14,18 @@ let lucide_react = require("lucide-react");
|
|
|
14
14
|
let react_dom = require("react-dom");
|
|
15
15
|
let zustand = require("zustand");
|
|
16
16
|
let zustand_middleware = require("zustand/middleware");
|
|
17
|
-
//#region ../../products/api-client/src/utils/product-price.ts
|
|
18
|
-
function stripParentheticalText(text) {
|
|
19
|
-
if (!text) return null;
|
|
20
|
-
return text.replace(/\s*\([^)]*\)/g, "").trim();
|
|
21
|
-
}
|
|
22
|
-
function isShopVariantCountry(vc) {
|
|
23
|
-
return vc !== void 0 && "display_wholesale_subscription_price" in vc;
|
|
24
|
-
}
|
|
25
|
-
function isAdminProduct(product) {
|
|
26
|
-
return "display_price" in product;
|
|
27
|
-
}
|
|
28
|
-
function isVariantCountriesRecord(vc) {
|
|
29
|
-
return vc !== null && typeof vc === "object" && !Array.isArray(vc);
|
|
30
|
-
}
|
|
31
|
-
function determineProductPrice(product, countryIso) {
|
|
32
|
-
const { variants } = product;
|
|
33
|
-
const selectedVariant = variants?.find((v) => {
|
|
34
|
-
if (isVariantCountriesRecord(v.variant_countries)) return v.variant_countries[countryIso]?.active;
|
|
35
|
-
return false;
|
|
36
|
-
}) || variants?.[0] || null;
|
|
37
|
-
let variantCountry;
|
|
38
|
-
if (countryIso && selectedVariant?.variant_countries) {
|
|
39
|
-
const variantCountries = selectedVariant.variant_countries;
|
|
40
|
-
if (Array.isArray(variantCountries)) variantCountry = variantCountries.find((v) => v?.country?.iso === countryIso);
|
|
41
|
-
else if (isVariantCountriesRecord(variantCountries)) variantCountry = variantCountries[countryIso];
|
|
42
|
-
}
|
|
43
|
-
if (selectedVariant?.subscription_only) return { repPrice: isShopVariantCountry(variantCountry) ? variantCountry.display_wholesale_subscription_price : void 0 };
|
|
44
|
-
const price = isShopVariantCountry(variantCountry) ? variantCountry.display_price : isAdminProduct(product) ? product.display_price : void 0;
|
|
45
|
-
const repPrice = isShopVariantCountry(variantCountry) ? variantCountry.display_wholesale : void 0;
|
|
46
|
-
return {
|
|
47
|
-
repPrice: stripParentheticalText(repPrice),
|
|
48
|
-
price: price === repPrice ? null : stripParentheticalText(price)
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
//#endregion
|
|
52
17
|
//#region ../../products/core/src/context.tsx
|
|
53
18
|
const ProductsCoreContext = (0, react.createContext)(null);
|
|
54
|
-
function ProductsCoreProvider({
|
|
19
|
+
function ProductsCoreProvider({ api, children }) {
|
|
55
20
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProductsCoreContext.Provider, {
|
|
56
|
-
value: {
|
|
21
|
+
value: { api },
|
|
57
22
|
children
|
|
58
23
|
});
|
|
59
24
|
}
|
|
60
|
-
function
|
|
25
|
+
function useProductsApi() {
|
|
61
26
|
const ctx = (0, react.useContext)(ProductsCoreContext);
|
|
62
|
-
if (!ctx) throw new Error("
|
|
63
|
-
return ctx.
|
|
27
|
+
if (!ctx) throw new Error("useProductsApi must be used within a <ProductsCoreProvider>");
|
|
28
|
+
return ctx.api;
|
|
64
29
|
}
|
|
65
30
|
//#endregion
|
|
66
31
|
//#region ../../products/core/src/query-keys.ts
|
|
@@ -103,13 +68,13 @@ const productKeys = {
|
|
|
103
68
|
//#endregion
|
|
104
69
|
//#region ../../products/core/src/hooks/use-products.ts
|
|
105
70
|
function useGetProduct(id, options) {
|
|
106
|
-
const
|
|
71
|
+
const api = useProductsApi();
|
|
107
72
|
return (0, _tanstack_react_query.useQuery)({
|
|
108
73
|
queryKey: productKeys.products.detail(id, {
|
|
109
74
|
lang: options?.lang,
|
|
110
75
|
country_code: options?.country_code
|
|
111
76
|
}),
|
|
112
|
-
queryFn: () =>
|
|
77
|
+
queryFn: () => api.getProduct(id, {
|
|
113
78
|
lang: options?.lang,
|
|
114
79
|
country_code: options?.country_code
|
|
115
80
|
}),
|
|
@@ -247,7 +212,7 @@ function useProductDetail({ productId, countryCode, lang = "en" }) {
|
|
|
247
212
|
//#endregion
|
|
248
213
|
//#region ../../products/core/src/hooks/use-product-catalog.ts
|
|
249
214
|
function useProductCatalog({ initialCountryCode = null, perPage = 25, publishedStores = ["rep"], statusFilter = ["active"] } = {}) {
|
|
250
|
-
const
|
|
215
|
+
const api = useProductsApi();
|
|
251
216
|
const [searchTerm, setSearchTerm] = (0, react.useState)("");
|
|
252
217
|
const debouncedSearchTerm = useDebounce(searchTerm, 300);
|
|
253
218
|
const [countryCode, setCountryCode] = (0, react.useState)(initialCountryCode);
|
|
@@ -275,14 +240,14 @@ function useProductCatalog({ initialCountryCode = null, perPage = 25, publishedS
|
|
|
275
240
|
countryCode,
|
|
276
241
|
setCountryCode,
|
|
277
242
|
fetchProducts: (0, react.useCallback)(async (page) => {
|
|
278
|
-
return (await
|
|
243
|
+
return (await api.listProducts({
|
|
279
244
|
...queryParams,
|
|
280
245
|
page,
|
|
281
246
|
search_query: debouncedSearchTerm || "",
|
|
282
247
|
sorting: currentSort
|
|
283
248
|
})).products;
|
|
284
249
|
}, [
|
|
285
|
-
|
|
250
|
+
api,
|
|
286
251
|
queryParams,
|
|
287
252
|
debouncedSearchTerm,
|
|
288
253
|
currentSort
|
|
@@ -841,6 +806,41 @@ function getProductImageUrl(product) {
|
|
|
841
806
|
return product.image_url ?? null;
|
|
842
807
|
}
|
|
843
808
|
//#endregion
|
|
809
|
+
//#region ../../products/core/src/utils/product-price.ts
|
|
810
|
+
function stripParentheticalText(text) {
|
|
811
|
+
if (!text) return null;
|
|
812
|
+
return text.replace(/\s*\([^)]*\)/g, "").trim();
|
|
813
|
+
}
|
|
814
|
+
function isShopVariantCountry(vc) {
|
|
815
|
+
return vc !== void 0 && "display_wholesale_subscription_price" in vc;
|
|
816
|
+
}
|
|
817
|
+
function isAdminProduct(product) {
|
|
818
|
+
return "display_price" in product;
|
|
819
|
+
}
|
|
820
|
+
function isVariantCountriesRecord(vc) {
|
|
821
|
+
return vc !== null && typeof vc === "object" && !Array.isArray(vc);
|
|
822
|
+
}
|
|
823
|
+
function determineProductPrice(product, countryIso) {
|
|
824
|
+
const { variants } = product;
|
|
825
|
+
const selectedVariant = variants?.find((v) => {
|
|
826
|
+
if (isVariantCountriesRecord(v.variant_countries)) return v.variant_countries[countryIso]?.active;
|
|
827
|
+
return false;
|
|
828
|
+
}) || variants?.[0] || null;
|
|
829
|
+
let variantCountry;
|
|
830
|
+
if (countryIso && selectedVariant?.variant_countries) {
|
|
831
|
+
const variantCountries = selectedVariant.variant_countries;
|
|
832
|
+
if (Array.isArray(variantCountries)) variantCountry = variantCountries.find((v) => v?.country?.iso === countryIso);
|
|
833
|
+
else if (isVariantCountriesRecord(variantCountries)) variantCountry = variantCountries[countryIso];
|
|
834
|
+
}
|
|
835
|
+
if (selectedVariant?.subscription_only) return { repPrice: isShopVariantCountry(variantCountry) ? variantCountry.display_wholesale_subscription_price : void 0 };
|
|
836
|
+
const price = isShopVariantCountry(variantCountry) ? variantCountry.display_price : isAdminProduct(product) ? product.display_price : void 0;
|
|
837
|
+
const repPrice = isShopVariantCountry(variantCountry) ? variantCountry.display_wholesale : void 0;
|
|
838
|
+
return {
|
|
839
|
+
repPrice: stripParentheticalText(repPrice),
|
|
840
|
+
price: price === repPrice ? null : stripParentheticalText(price)
|
|
841
|
+
};
|
|
842
|
+
}
|
|
843
|
+
//#endregion
|
|
844
844
|
//#region ../../shop/ui/src/utils/media-helpers.ts
|
|
845
845
|
const VIDEO_EXTENSIONS = [
|
|
846
846
|
".mp4",
|
|
@@ -1570,6 +1570,21 @@ function ShopApp({ countryCode, companyLogoUrl, renderImage, onAddToCart, produc
|
|
|
1570
1570
|
});
|
|
1571
1571
|
}
|
|
1572
1572
|
//#endregion
|
|
1573
|
+
//#region src/products/create-products-api.ts
|
|
1574
|
+
function createProductsApi(client) {
|
|
1575
|
+
return {
|
|
1576
|
+
listProducts: (params) => require_products.listProducts(client, params),
|
|
1577
|
+
listProductsV2: (params) => require_products.listProductsV2(client, params),
|
|
1578
|
+
getProduct: (id, options) => require_products.getProduct(client, id, options),
|
|
1579
|
+
deleteProduct: (id) => require_products.deleteProduct(client, id),
|
|
1580
|
+
duplicateProduct: (id) => require_products.duplicateProduct(client, id),
|
|
1581
|
+
archiveProduct: (product) => require_products.archiveProduct(client, product),
|
|
1582
|
+
unarchiveProduct: (product) => require_products.unarchiveProduct(client, product),
|
|
1583
|
+
draftProduct: (product) => require_products.draftProduct(client, product),
|
|
1584
|
+
sendProductToTop: (id) => require_products.sendProductToTop(client, id)
|
|
1585
|
+
};
|
|
1586
|
+
}
|
|
1587
|
+
//#endregion
|
|
1573
1588
|
//#region ../../cart/ui/src/components/cart-script.tsx
|
|
1574
1589
|
const SCRIPT_ID = "fluid-cdn-script";
|
|
1575
1590
|
const LEAD_CAPTURE_ID = "fluid-lead-capture-suppress";
|
|
@@ -1724,6 +1739,7 @@ function ShopContainer({ children, className = "", cartScript, cartWidget }) {
|
|
|
1724
1739
|
function ShopScreen({ background, textColor, accentColor, padding, borderRadius, ...divProps }) {
|
|
1725
1740
|
const { config } = require_FluidProvider.useFluidContext();
|
|
1726
1741
|
const domainClient = require_use_account_clients.useSdkClient();
|
|
1742
|
+
const productsApi = (0, react.useMemo)(() => createProductsApi(domainClient), [domainClient]);
|
|
1727
1743
|
const { token } = require_use_account_clients.useFluidAuth();
|
|
1728
1744
|
const { data: userData } = require_use_current_user.useCurrentUser();
|
|
1729
1745
|
const { currentSlug, navigate } = require_AppNavigationContext.useAppNavigation();
|
|
@@ -1751,7 +1767,7 @@ function ShopScreen({ background, textColor, accentColor, padding, borderRadius,
|
|
|
1751
1767
|
}) : null,
|
|
1752
1768
|
cartWidget: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CartWidget, {}),
|
|
1753
1769
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProductsCoreProvider, {
|
|
1754
|
-
|
|
1770
|
+
api: productsApi,
|
|
1755
1771
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShopApp, {
|
|
1756
1772
|
countryCode,
|
|
1757
1773
|
companyLogoUrl: userData?.company?.logo_url,
|
|
@@ -1787,4 +1803,4 @@ Object.defineProperty(exports, "shopScreenPropertySchema", {
|
|
|
1787
1803
|
}
|
|
1788
1804
|
});
|
|
1789
1805
|
|
|
1790
|
-
//# sourceMappingURL=ShopScreen-
|
|
1806
|
+
//# sourceMappingURL=ShopScreen-CWuSRymK.cjs.map
|