@fluid-app/portal-sdk 0.1.135 → 0.1.136

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 (31) hide show
  1. package/dist/ProductsScreen-C7cXqLN8.cjs +110 -0
  2. package/dist/ProductsScreen-C7cXqLN8.cjs.map +1 -0
  3. package/dist/{ProductsScreen-CbKT2maZ.mjs → ProductsScreen-CTUejNR0.mjs} +2 -2
  4. package/dist/{ProductsScreen-T1tGuiGy.cjs → ProductsScreen-CcF3f9VD.cjs} +2 -2
  5. package/dist/ProductsScreen-Di6uVQCx.mjs +98 -0
  6. package/dist/ProductsScreen-Di6uVQCx.mjs.map +1 -0
  7. package/dist/ShareablesScreen-B-uZ3B5d.cjs +430 -0
  8. package/dist/ShareablesScreen-B-uZ3B5d.cjs.map +1 -0
  9. package/dist/{ShareablesScreen-DSW36iS7.mjs → ShareablesScreen-BHyxG-oy.mjs} +2 -2
  10. package/dist/{ShareablesScreen-BLbzr0Jb.cjs → ShareablesScreen-DAM01cxf.cjs} +2 -2
  11. package/dist/ShareablesScreen-iBUd6p7M.mjs +412 -0
  12. package/dist/ShareablesScreen-iBUd6p7M.mjs.map +1 -0
  13. package/dist/index.cjs +7 -7
  14. package/dist/index.d.cts.map +1 -1
  15. package/dist/index.d.mts.map +1 -1
  16. package/dist/index.mjs +7 -7
  17. package/dist/{src-BbjxT3sc.mjs → portal-tenant-product-media-adapter-Co9Kw-US.mjs} +980 -4
  18. package/dist/portal-tenant-product-media-adapter-Co9Kw-US.mjs.map +1 -0
  19. package/dist/{src-DmzXXBVt.cjs → portal-tenant-product-media-adapter-DM94zJXA.cjs} +1039 -3
  20. package/dist/portal-tenant-product-media-adapter-DM94zJXA.cjs.map +1 -0
  21. package/package.json +16 -16
  22. package/dist/ProductsScreen-B1OAGNQx.cjs +0 -283
  23. package/dist/ProductsScreen-B1OAGNQx.cjs.map +0 -1
  24. package/dist/ProductsScreen-CL71MQNL.mjs +0 -271
  25. package/dist/ProductsScreen-CL71MQNL.mjs.map +0 -1
  26. package/dist/ShareablesScreen-CecBPoFO.mjs +0 -1360
  27. package/dist/ShareablesScreen-CecBPoFO.mjs.map +0 -1
  28. package/dist/ShareablesScreen-DDutXKpW.cjs +0 -1378
  29. package/dist/ShareablesScreen-DDutXKpW.cjs.map +0 -1
  30. package/dist/src-BbjxT3sc.mjs.map +0 -1
  31. package/dist/src-DmzXXBVt.cjs.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluid-app/portal-sdk",
3
- "version": "0.1.135",
3
+ "version": "0.1.136",
4
4
  "description": "SDK for building custom Fluid portals",
5
5
  "files": [
6
6
  "dist",
@@ -72,50 +72,50 @@
72
72
  "typescript": "^5",
73
73
  "zod": "4.3.5",
74
74
  "@fluid-app/api-client-core": "0.1.0",
75
- "@fluid-app/company-switcher-core": "0.1.0",
75
+ "@fluid-app/auth": "0.1.0",
76
76
  "@fluid-app/cart-ui": "0.1.13",
77
- "@fluid-app/contacts-api-client": "0.1.0",
78
77
  "@fluid-app/company-switcher-ui": "0.1.0",
79
- "@fluid-app/auth": "0.1.0",
78
+ "@fluid-app/company-switcher-core": "0.1.0",
79
+ "@fluid-app/contacts-api-client": "0.1.0",
80
80
  "@fluid-app/contacts-core": "0.1.0",
81
+ "@fluid-app/contacts-ui": "0.1.0",
81
82
  "@fluid-app/file-picker-api-client": "0.1.0",
82
83
  "@fluid-app/fluid-pay-api-client": "0.1.0",
83
- "@fluid-app/contacts-ui": "0.1.0",
84
84
  "@fluid-app/fluid-pay-core": "0.1.0",
85
85
  "@fluid-app/fluidos-api-client": "0.1.0",
86
- "@fluid-app/messaging-ui": "0.1.0",
87
- "@fluid-app/messaging-core": "0.1.0",
88
86
  "@fluid-app/messaging-api-client": "0.1.0",
87
+ "@fluid-app/messaging-core": "0.1.0",
88
+ "@fluid-app/messaging-ui": "0.1.0",
89
89
  "@fluid-app/mysite-ui": "0.1.0",
90
+ "@fluid-app/orders-core": "0.1.0",
91
+ "@fluid-app/orders-ui": "0.1.0",
90
92
  "@fluid-app/orders-api-client": "0.1.0",
91
93
  "@fluid-app/permissions": "0.1.0",
92
- "@fluid-app/orders-ui": "0.1.0",
93
94
  "@fluid-app/portal-app-download-ui": "0.1.0",
94
95
  "@fluid-app/portal-core": "0.1.23",
95
- "@fluid-app/portal-preview": "0.1.0",
96
96
  "@fluid-app/portal-pro-upgrade-ui": "0.1.0",
97
+ "@fluid-app/portal-preview": "0.1.0",
97
98
  "@fluid-app/portal-react": "0.1.0",
98
- "@fluid-app/orders-core": "0.1.0",
99
99
  "@fluid-app/portal-tenant-api-client": "0.1.0",
100
100
  "@fluid-app/portal-tenant-contacts-api-client": "0.1.0",
101
101
  "@fluid-app/portal-tenant-mysite-api-client": "0.1.0",
102
102
  "@fluid-app/portal-tenant-pay-api-client": "0.1.0",
103
103
  "@fluid-app/portal-widgets": "0.1.22",
104
+ "@fluid-app/products-api-client": "0.1.0",
104
105
  "@fluid-app/products-core": "0.1.0",
105
106
  "@fluid-app/profile-core": "0.1.0",
106
107
  "@fluid-app/query-persister": "0.1.0",
107
- "@fluid-app/profile-ui": "0.1.0",
108
108
  "@fluid-app/shareables-api-client": "0.1.0",
109
- "@fluid-app/shareables-core": "0.1.0",
110
- "@fluid-app/products-api-client": "0.1.0",
109
+ "@fluid-app/profile-ui": "0.1.0",
111
110
  "@fluid-app/shareables-ui": "0.1.0",
111
+ "@fluid-app/shareables-core": "0.1.0",
112
+ "@fluid-app/shop-ui": "0.1.0",
112
113
  "@fluid-app/store-api-client": "0.1.0",
113
114
  "@fluid-app/subscriptions-api-client": "0.1.0",
114
- "@fluid-app/shop-ui": "0.1.0",
115
115
  "@fluid-app/subscriptions-core": "0.1.0",
116
+ "@fluid-app/subscriptions-ui": "0.1.0",
116
117
  "@fluid-app/typescript-config": "0.0.0",
117
- "@fluid-app/ui-primitives": "0.1.13",
118
- "@fluid-app/subscriptions-ui": "0.1.0"
118
+ "@fluid-app/ui-primitives": "0.1.13"
119
119
  },
120
120
  "peerDependencies": {
121
121
  "@hookform/resolvers": "^5.2.2",
@@ -1,283 +0,0 @@
1
- require("./chunk-9hOWP6kD.cjs");
2
- const require_use_current_user = require("./use-current-user-C4oXzxPk.cjs");
3
- const require_AppNavigationContext = require("./AppNavigationContext-Agp0UkCQ.cjs");
4
- const require_use_account_clients = require("./use-account-clients-C6QS6yk6.cjs");
5
- const require_src = require("./src-DmzXXBVt.cjs");
6
- const require_use_portal_products_client = require("./use-portal-products-client-CTaxgbMq.cjs");
7
- let react = require("react");
8
- let react_jsx_runtime = require("react/jsx-runtime");
9
- //#region ../../shareables/api-client/src/namespaces/media.ts
10
- function transformMediaListItem(item) {
11
- return {
12
- ...item,
13
- description: item.description,
14
- created_at: item.description?.created_at || item.created_at
15
- };
16
- }
17
- async function getMedia(client, options = {}, repContext) {
18
- if (repContext) {
19
- const response = await client.get("/users/v2025-06/media", options);
20
- const transformedItems = response.media.map(transformMediaListItem);
21
- const perPage = options.per_page || 10;
22
- return {
23
- data: transformedItems,
24
- status: "success",
25
- media: transformedItems,
26
- meta: {
27
- total_count: response.meta.total_count,
28
- current: response.meta.current_page,
29
- per_page: perPage,
30
- pages: response.meta.total_pages,
31
- next: response.meta.current_page < response.meta.total_pages ? response.meta.current_page + 1 : null,
32
- previous: response.meta.current_page > 1 ? response.meta.current_page - 1 : null
33
- }
34
- };
35
- }
36
- const response = await client.get("/company/media", options);
37
- let mediaItems = [];
38
- let pagination = {
39
- count: 0,
40
- previous: null,
41
- next: null,
42
- pages: 0,
43
- per_page: 10,
44
- current: 1
45
- };
46
- response.forEach((item) => {
47
- if ("items" in item && Array.isArray(item.items)) mediaItems = item.items;
48
- if ("pagination" in item && item.pagination?.count) pagination = item.pagination;
49
- });
50
- const transformedItems = mediaItems.map(transformMediaListItem);
51
- return {
52
- data: transformedItems,
53
- status: "success",
54
- media: transformedItems,
55
- meta: {
56
- ...pagination,
57
- total_count: pagination.count || mediaItems.length
58
- }
59
- };
60
- }
61
- async function getMediaById(client, id, language_iso, repContext) {
62
- if (repContext) {
63
- const response = await client.get(`/users/v2025-06/media/${id}`);
64
- return {
65
- data: response.medium,
66
- status: "success",
67
- media: response.medium
68
- };
69
- }
70
- const endpoint = language_iso ? `/company/media/${id}?language_iso=${language_iso}` : `/company/media/${id}`;
71
- const response = await client.get(endpoint);
72
- return {
73
- data: response,
74
- status: "success",
75
- media: response
76
- };
77
- }
78
- async function createMedia(client, mediaData, repContext) {
79
- if (repContext) return (await client.post("/users/v2025-06/media", mediaData)).medium;
80
- return (await client.post("/company/media", mediaData)).medium;
81
- }
82
- async function updateMedia(client, id, mediaData, language_iso, repContext) {
83
- if (repContext) return (await client.request(`/users/v2025-06/media/${id}`, {
84
- method: "PATCH",
85
- body: mediaData
86
- })).medium;
87
- const endpoint = language_iso ? `/company/media/${id}?language_iso=${language_iso}` : `/company/media/${id}`;
88
- const response = await client.put(endpoint, { medium: mediaData });
89
- if (response && typeof response === "object" && "data" in response && response.data) return response.data;
90
- return response;
91
- }
92
- /**
93
- * Delete a media item. The API returns a text response, so we use
94
- * client.delete and ignore the response body.
95
- */
96
- async function deleteMedia(client, id, repContext) {
97
- if (repContext) await client.delete(`/users/v2025-06/media/${id}`);
98
- else await client.delete(`/company/media/${id}`);
99
- return { success: true };
100
- }
101
- //#endregion
102
- //#region ../../shareables/api-client/src/namespaces/playlists.ts
103
- const PLAYLISTS_URL = "/v2025-06/playlists";
104
- async function getPlaylists(client, options) {
105
- const input = options ? Object.fromEntries(Object.entries(options).filter(([, value]) => value !== void 0)) : void 0;
106
- return client.get(PLAYLISTS_URL, input);
107
- }
108
- async function getPlaylistById(client, id) {
109
- return client.get(`${PLAYLISTS_URL}/${id}`);
110
- }
111
- async function createPlaylist(client, data) {
112
- return client.post(PLAYLISTS_URL, data);
113
- }
114
- async function updatePlaylist(client, id, data) {
115
- return client.patch(`${PLAYLISTS_URL}/${id}`, data);
116
- }
117
- async function addItemToPlaylist(client, id, data) {
118
- return client.post(`${PLAYLISTS_URL}/${id}/items`, data);
119
- }
120
- async function removeItemsFromPlaylist(client, playlistId, data) {
121
- return client.request(`${PLAYLISTS_URL}/${playlistId}/items`, {
122
- method: "DELETE",
123
- body: data
124
- });
125
- }
126
- //#endregion
127
- //#region ../../shareables/api-client/src/namespaces/file-resources.ts
128
- async function getFileResources(client, params) {
129
- const qp = new URLSearchParams({
130
- ...params.search_query && { search_query: params.search_query },
131
- ...params.pageParam && { page: params.pageParam },
132
- ...params.pageSize && { per_page: params.pageSize },
133
- ...params.sizeGreaterThan && { size_greater_than: params.sizeGreaterThan.toString() },
134
- ...params.sizeLessThan && { size_less_than: params.sizeLessThan.toString() },
135
- ...params.sortedBy && { sorted_by: params.sortedBy }
136
- });
137
- params.fileTypes?.forEach((type) => {
138
- qp.append("with_types[]", type);
139
- });
140
- return client.get(`/file_resources?${qp.toString()}`);
141
- }
142
- //#endregion
143
- //#region ../../shareables/api-client/src/namespaces/product-media.ts
144
- async function getProductMedia(client, productId) {
145
- return client.get(`/v2025-06/products/${productId}/media`);
146
- }
147
- //#endregion
148
- //#region ../../shareables/api-client/src/namespaces/share.ts
149
- async function createShareLink(client, input) {
150
- const requestBody = {
151
- locale: input.locale,
152
- relateable_type: input.relateableType,
153
- ...input.contactId && { contact_id: input.contactId },
154
- ...input.relateableId && { relateable_id: input.relateableId }
155
- };
156
- return (await client.post("/shares.json", requestBody)).link;
157
- }
158
- //#endregion
159
- //#region ../../shareables/api-client/src/adapter.ts
160
- /**
161
- * Creates a ShareablesApi-compatible adapter backed by the real API client
162
- * namespace functions. The returned object satisfies the ShareablesApi interface
163
- * from @fluid-app/shareables-core via structural typing.
164
- *
165
- * @param client - The FetchClient instance for making HTTP requests.
166
- * @param options - Provider-level configuration (e.g. repContext).
167
- */
168
- function createShareablesApiAdapter(client, options) {
169
- const repContext = options?.repContext ?? false;
170
- return {
171
- media: {
172
- getMedia: (opts) => getMedia(client, opts, repContext),
173
- getMediaById: (id, language_iso) => getMediaById(client, id, language_iso, repContext),
174
- createMedia: (mediaData) => createMedia(client, mediaData, repContext),
175
- updateMedia: (id, mediaData, language_iso) => updateMedia(client, id, mediaData, language_iso, repContext),
176
- deleteMedia: (id) => deleteMedia(client, id, repContext)
177
- },
178
- playlists: {
179
- getPlaylists: (opts) => getPlaylists(client, opts),
180
- getPlaylistById: (id) => getPlaylistById(client, id),
181
- createPlaylist: (data) => createPlaylist(client, data),
182
- updatePlaylist: (id, data) => updatePlaylist(client, id, data),
183
- addItemToPlaylist: (id, data) => addItemToPlaylist(client, id, data),
184
- removeItemsFromPlaylist: (playlistId, data) => removeItemsFromPlaylist(client, playlistId, data)
185
- },
186
- fileResources: { getFileResources: (params) => getFileResources(client, params) },
187
- productMedia: { getProductMedia: (productId) => getProductMedia(client, productId) },
188
- share: { createShareLink: (input) => createShareLink(client, input) }
189
- };
190
- }
191
- //#endregion
192
- //#region src/screens/ProductsScreen.tsx
193
- function ProductsScreen({ background, textColor, accentColor, padding, borderRadius, ...divProps }) {
194
- const domainClient = require_use_account_clients.useSdkClient();
195
- const portalProductsApi = require_use_portal_products_client.usePortalProductsClient();
196
- const { data: userData } = require_use_current_user.useCurrentUser();
197
- const { currentSlug, navigate } = require_AppNavigationContext.useAppNavigation();
198
- const fetchProducts = (0, react.useCallback)(async (search, cursor, limit) => {
199
- if (search) return portalProductsApi.searchProducts(search, {
200
- cursor,
201
- limit
202
- });
203
- return portalProductsApi.listProducts({
204
- cursor,
205
- limit
206
- });
207
- }, [portalProductsApi]);
208
- const fetchProduct = (0, react.useCallback)(async (id) => portalProductsApi.getProduct(id), [portalProductsApi]);
209
- const productId = (0, react.useMemo)(() => {
210
- return currentSlug.match(/^products\/(.+)/)?.[1] ?? null;
211
- }, [currentSlug]);
212
- const handleSelectProduct = (0, react.useCallback)((id) => {
213
- navigate(`products/${id}`);
214
- }, [navigate]);
215
- const handleBack = (0, react.useCallback)(() => {
216
- navigate("products");
217
- }, [navigate]);
218
- const coreConfig = (0, react.useMemo)(() => ({
219
- client: domainClient,
220
- user: userData ? { id: userData.id } : null,
221
- repContext: true
222
- }), [domainClient, userData]);
223
- const shareablesApi = (0, react.useMemo)(() => createShareablesApiAdapter(domainClient, { repContext: true }), [domainClient]);
224
- const uiConfig = (0, react.useMemo)(() => ({
225
- user: userData ? {
226
- id: userData.id,
227
- company: userData.company ? { logo_url: userData.company.logo_url } : null
228
- } : void 0,
229
- basePath: "",
230
- navigate: (path) => {
231
- navigate(path);
232
- },
233
- showToast: (opts) => {
234
- console.log(`[Products] ${opts.type}: ${opts.title}`);
235
- }
236
- }), [userData, navigate]);
237
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
238
- ...divProps,
239
- className: `h-full ${divProps.className ?? ""}`,
240
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.ShareablesCoreProvider, {
241
- config: coreConfig,
242
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.ShareablesApiProvider, {
243
- api: shareablesApi,
244
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.ShareablesUIProvider, {
245
- config: uiConfig,
246
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.ProductsApp, {
247
- countryCode: userData?.country?.iso,
248
- companyLogoUrl: userData?.company?.logo_url,
249
- fetchProducts,
250
- fetchProduct,
251
- productId,
252
- onSelectProduct: handleSelectProduct,
253
- onBack: handleBack
254
- })
255
- })
256
- })
257
- })
258
- });
259
- }
260
- const productsScreenPropertySchema = {
261
- widgetType: "ProductsScreen",
262
- displayName: "Products Screen",
263
- tabsConfig: [{
264
- id: "styling",
265
- label: "Styling"
266
- }],
267
- fields: []
268
- };
269
- //#endregion
270
- Object.defineProperty(exports, "ProductsScreen", {
271
- enumerable: true,
272
- get: function() {
273
- return ProductsScreen;
274
- }
275
- });
276
- Object.defineProperty(exports, "productsScreenPropertySchema", {
277
- enumerable: true,
278
- get: function() {
279
- return productsScreenPropertySchema;
280
- }
281
- });
282
-
283
- //# sourceMappingURL=ProductsScreen-B1OAGNQx.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ProductsScreen-B1OAGNQx.cjs","names":["mediaNs.getMedia","mediaNs.getMediaById","mediaNs.createMedia","mediaNs.updateMedia","mediaNs.deleteMedia","playlistsNs.getPlaylists","playlistsNs.getPlaylistById","playlistsNs.createPlaylist","playlistsNs.updatePlaylist","playlistsNs.addItemToPlaylist","playlistsNs.removeItemsFromPlaylist","fileResourcesNs.getFileResources","productMediaNs.getProductMedia","shareNs.createShareLink","useSdkClient","usePortalProductsClient","useCurrentUser","useAppNavigation","ShareablesCoreProvider","ShareablesApiProvider","ShareablesUIProvider","ProductsApp"],"sources":["../../../shareables/api-client/src/namespaces/media.ts","../../../shareables/api-client/src/namespaces/playlists.ts","../../../shareables/api-client/src/namespaces/file-resources.ts","../../../shareables/api-client/src/namespaces/product-media.ts","../../../shareables/api-client/src/namespaces/share.ts","../../../shareables/api-client/src/adapter.ts","../src/screens/ProductsScreen.tsx"],"sourcesContent":["import type { FetchClient } from \"../lib/fetch-client\";\nimport type { shareables } from \"../generated/shareables\";\n\n// ============================================================================\n// Media - Helper\n// ============================================================================\n\nfunction transformMediaListItem(\n item: shareables.MediaListItem,\n): shareables.MediumResponse {\n return {\n ...item,\n description: item.description,\n created_at: item.description?.created_at || item.created_at,\n };\n}\n\n// ============================================================================\n// Media - List & Get\n// ============================================================================\n\ninterface RepMediaResponse {\n media: shareables.MediaListItem[];\n meta: {\n request_id: string;\n timestamp: string;\n current_page: number;\n total_pages: number;\n total_count: number;\n };\n}\n\nexport async function getMedia(\n client: FetchClient,\n options: shareables.MediaFilters = {},\n repContext?: boolean,\n): Promise<shareables.MediaListResponseWithMeta> {\n if (repContext) {\n const response = await client.get<RepMediaResponse>(\n \"/users/v2025-06/media\",\n options as Record<string, unknown>,\n );\n\n const transformedItems = response.media.map(transformMediaListItem);\n const perPage = options.per_page || 10;\n\n return {\n data: transformedItems,\n status: \"success\",\n media: transformedItems,\n meta: {\n total_count: response.meta.total_count,\n current: response.meta.current_page,\n per_page: perPage,\n pages: response.meta.total_pages,\n next:\n response.meta.current_page < response.meta.total_pages\n ? response.meta.current_page + 1\n : null,\n previous:\n response.meta.current_page > 1\n ? response.meta.current_page - 1\n : null,\n },\n };\n }\n\n const response = await client.get<shareables.MediaListResponseNew>(\n \"/company/media\",\n options as Record<string, unknown>,\n );\n\n let mediaItems: shareables.MediaListItem[] = [];\n let pagination: shareables.MediaPagination = {\n count: 0,\n previous: null,\n next: null,\n pages: 0,\n per_page: 10,\n current: 1,\n };\n\n response.forEach((item) => {\n if (\"items\" in item && Array.isArray(item.items)) {\n mediaItems = item.items;\n }\n if (\"pagination\" in item && item.pagination?.count) {\n pagination = item.pagination;\n }\n });\n\n const transformedItems = mediaItems.map(transformMediaListItem);\n\n return {\n data: transformedItems,\n status: \"success\",\n media: transformedItems,\n meta: {\n ...pagination,\n total_count: pagination.count || mediaItems.length,\n },\n };\n}\n\nexport async function getMediaById(\n client: FetchClient,\n id: number,\n language_iso?: string,\n repContext?: boolean,\n): Promise<shareables.MediaResponseWithMeta> {\n if (repContext) {\n const response = await client.get<{ medium: shareables.MediumResponse }>(\n `/users/v2025-06/media/${id}`,\n );\n return {\n data: response.medium,\n status: \"success\",\n media: response.medium,\n };\n }\n\n const endpoint = language_iso\n ? `/company/media/${id}?language_iso=${language_iso}`\n : `/company/media/${id}`;\n\n const response = await client.get<shareables.MediumResponse>(endpoint);\n\n return {\n data: response,\n status: \"success\",\n media: response,\n };\n}\n\nexport async function getAnnouncementById(\n client: FetchClient,\n id: number,\n): Promise<shareables.AnnouncementResponse> {\n return client.get(`/company/announcements/${id}`);\n}\n\nexport async function getTrainings(\n client: FetchClient,\n options: {\n category_id?: number;\n page?: number;\n per_page?: number;\n } = {},\n): Promise<shareables.MediaListResponseWithMeta> {\n const params: Record<string, string> = {};\n\n if (options.category_id) {\n params[\"filterrific[with_category_id]\"] = options.category_id.toString();\n }\n if (options.page) {\n params.page = options.page.toString();\n }\n if (options.per_page) {\n params.per_page = options.per_page.toString();\n }\n\n const response = await client.get<shareables.MediaListResponseNew>(\n \"/v1/trainings\",\n params,\n );\n\n let mediaItems: shareables.MediaListItem[] = [];\n let pagination: shareables.MediaPagination = {\n count: 0,\n previous: null,\n next: null,\n pages: 0,\n per_page: 20,\n current: 1,\n };\n\n response.forEach((item) => {\n if (\"items\" in item && Array.isArray(item.items)) {\n mediaItems = item.items;\n }\n if (\"pagination\" in item && item.pagination?.count) {\n pagination = item.pagination;\n }\n });\n\n const transformedItems = mediaItems.map(transformMediaListItem);\n\n return {\n data: transformedItems,\n status: \"success\",\n media: transformedItems,\n meta: {\n ...pagination,\n total_count: pagination.count || mediaItems.length,\n },\n };\n}\n\n// ============================================================================\n// Media - Create\n// ============================================================================\n\nexport async function createMedia(\n client: FetchClient,\n mediaData: shareables.MediumUpdate,\n repContext?: boolean,\n): Promise<shareables.MediumResponse> {\n if (repContext) {\n const response = await client.post<{ medium: shareables.MediumResponse }>(\n \"/users/v2025-06/media\",\n mediaData,\n );\n return response.medium;\n }\n\n const response = await client.post<shareables.NewCreateMediaResponse>(\n \"/company/media\",\n mediaData,\n );\n return response.medium;\n}\n\nexport async function createAnnouncement(\n client: FetchClient,\n announcementData: shareables.AnnouncementUpdate,\n): Promise<shareables.AnnouncementResponse> {\n return client.post(\"/company/announcements\", announcementData);\n}\n\n// ============================================================================\n// Media - Update\n// ============================================================================\n\nexport async function updateMedia(\n client: FetchClient,\n id: number,\n mediaData: shareables.MediumUpdate,\n language_iso?: string,\n repContext?: boolean,\n): Promise<shareables.MediumResponse> {\n if (repContext) {\n const response = await client.request<{\n medium: shareables.MediumResponse;\n }>(`/users/v2025-06/media/${id}`, {\n method: \"PATCH\",\n body: mediaData,\n });\n return response.medium;\n }\n\n const endpoint = language_iso\n ? `/company/media/${id}?language_iso=${language_iso}`\n : `/company/media/${id}`;\n\n const response = await client.put<shareables.MediaResponse>(endpoint, {\n medium: mediaData,\n });\n\n if (\n response &&\n typeof response === \"object\" &&\n \"data\" in response &&\n response.data\n ) {\n return response.data as shareables.MediumResponse;\n }\n return response as shareables.MediumResponse;\n}\n\nexport async function updateAnnouncement(\n client: FetchClient,\n id: number,\n announcementData: shareables.AnnouncementUpdate,\n): Promise<shareables.AnnouncementResponse> {\n const response = await client.put<shareables.AnnouncementResponse>(\n `/company/announcements/${id}`,\n announcementData,\n );\n\n if (\n response &&\n typeof response === \"object\" &&\n \"data\" in response &&\n response.data\n ) {\n return response.data as shareables.AnnouncementResponse;\n }\n return response;\n}\n\n// ============================================================================\n// Media - Delete\n// ============================================================================\n\n/**\n * Delete a media item. The API returns a text response, so we use\n * client.delete and ignore the response body.\n */\nexport async function deleteMedia(\n client: FetchClient,\n id: number,\n repContext?: boolean,\n): Promise<{ success: boolean }> {\n if (repContext) {\n await client.delete(`/users/v2025-06/media/${id}`);\n } else {\n await client.delete(`/company/media/${id}`);\n }\n return { success: true };\n}\n\nexport async function deleteAnnouncement(\n client: FetchClient,\n id: number,\n): Promise<{ success: boolean }> {\n await client.delete(`/company/announcements/${id}`);\n return { success: true };\n}\n\nexport async function bulkDeleteAnnouncements(\n client: FetchClient,\n ids: number[],\n): Promise<{ success: boolean }> {\n await client.request(`/company/announcements/bulk_destroy`, {\n method: \"DELETE\",\n body: { ids },\n });\n return { success: true };\n}\n","import type { FetchClient } from \"../lib/fetch-client\";\nimport type { shareables } from \"../generated/shareables\";\n\nconst PLAYLISTS_URL = \"/v2025-06/playlists\";\n\n// ============================================================================\n// Playlists - List & Get\n// ============================================================================\n\nexport type PlaylistsQuery = {\n \"filter[title]\"?: string;\n \"filter[status]\"?: string;\n \"page[cursor]\"?: string;\n \"page[limit]\"?: number;\n sort?: string;\n};\n\nexport async function getPlaylists(\n client: FetchClient,\n options?: PlaylistsQuery,\n): Promise<shareables.GetPlaylistsResponse> {\n const input = options\n ? Object.fromEntries(\n Object.entries(options).filter(([, value]) => value !== undefined),\n )\n : undefined;\n return client.get(PLAYLISTS_URL, input);\n}\n\nexport async function getPlaylistById(\n client: FetchClient,\n id: number,\n): Promise<shareables.GetPlaylistResponse> {\n return client.get(`${PLAYLISTS_URL}/${id}`);\n}\n\n// ============================================================================\n// Playlists - Create & Update\n// ============================================================================\n\nexport async function createPlaylist(\n client: FetchClient,\n data: shareables.CreatePlaylistInput,\n): Promise<shareables.GetPlaylistResponse> {\n return client.post(PLAYLISTS_URL, data);\n}\n\nexport async function updatePlaylist(\n client: FetchClient,\n id: number,\n data: shareables.UpdatePlaylistInput,\n): Promise<shareables.GetPlaylistResponse> {\n return client.patch(`${PLAYLISTS_URL}/${id}`, data);\n}\n\nexport async function addItemToPlaylist(\n client: FetchClient,\n id: number,\n data: shareables.AddItemToPlaylistInput,\n): Promise<shareables.Playlist> {\n return client.post(`${PLAYLISTS_URL}/${id}/items`, data);\n}\n\n// ============================================================================\n// Playlists - Delete\n// ============================================================================\n\nexport async function deletePlaylist(\n client: FetchClient,\n id: number,\n): Promise<void> {\n return client.delete(`${PLAYLISTS_URL}/${id}`);\n}\n\nexport async function deletePlaylists(\n client: FetchClient,\n ids: number[],\n): Promise<void[]> {\n return Promise.all(ids.map((id) => deletePlaylist(client, id)));\n}\n\nexport async function deletePlaylistItem(\n client: FetchClient,\n id: number,\n item_ids: number[],\n): Promise<{\n deleted_at: string;\n meta: { request_id: string; timestamp: string };\n}> {\n return client.request(`${PLAYLISTS_URL}/${id}/items`, {\n method: \"DELETE\",\n body: item_ids,\n });\n}\n\n// ============================================================================\n// Playlists - Remove Items\n// ============================================================================\n\nexport async function removeItemsFromPlaylist(\n client: FetchClient,\n playlistId: number,\n data: shareables.RemoveItemsFromPlaylistInput,\n): Promise<shareables.Playlist> {\n return client.request(`${PLAYLISTS_URL}/${playlistId}/items`, {\n method: \"DELETE\",\n body: data,\n });\n}\n","import type { FetchClient } from \"../lib/fetch-client\";\nimport type { shareables } from \"../generated/shareables\";\n\n// ============================================================================\n// File Resources - List\n// ============================================================================\n\nexport async function getFileResources(\n client: FetchClient,\n params: {\n search_query?: string;\n pageParam?: string;\n pageSize?: string;\n fileTypes?: string[];\n sizeGreaterThan?: number;\n sizeLessThan?: number;\n sortedBy?: string;\n },\n): Promise<shareables.FileResourcesResponse> {\n const qp = new URLSearchParams({\n ...(params.search_query && { search_query: params.search_query }),\n ...(params.pageParam && { page: params.pageParam }),\n ...(params.pageSize && { per_page: params.pageSize }),\n ...(params.sizeGreaterThan && {\n size_greater_than: params.sizeGreaterThan.toString(),\n }),\n ...(params.sizeLessThan && {\n size_less_than: params.sizeLessThan.toString(),\n }),\n ...(params.sortedBy && { sorted_by: params.sortedBy }),\n });\n params.fileTypes?.forEach((type) => {\n qp.append(\"with_types[]\", type);\n });\n\n return client.get(`/file_resources?${qp.toString()}`);\n}\n\n// ============================================================================\n// File Resources - Create\n// ============================================================================\n\nexport async function createFileResource(\n client: FetchClient,\n data: shareables.CreateFileResourceInput,\n): Promise<shareables.CreateFileResourceResponse> {\n return client.post(\"/file_resources\", data);\n}\n\n// ============================================================================\n// File Resources - Update\n// ============================================================================\n\nexport async function updateFileResource(\n client: FetchClient,\n id: number,\n fileResource: shareables.UpdateFileResourceInput,\n): Promise<shareables.FileResource> {\n return client.patch(`/file_resources/${id}`, {\n id: id.toString(),\n file_resource: fileResource,\n });\n}\n\n// ============================================================================\n// File Resources - Delete\n// ============================================================================\n\nexport async function deleteFileResource(\n client: FetchClient,\n id: number,\n): Promise<{ id: number; meta: { request_id: string; timestamp: string } }> {\n return client.delete(`/file_resources/${id}`);\n}\n","import type { FetchClient } from \"../lib/fetch-client\";\nimport type { shareables } from \"../generated/shareables\";\n\n// ============================================================================\n// Product Media - Get\n// ============================================================================\n\nexport async function getProductMedia(\n client: FetchClient,\n productId: number,\n): Promise<shareables.ProductMediaResponse> {\n return client.get(`/v2025-06/products/${productId}/media`);\n}\n\n// ============================================================================\n// Product Media - Type Guards\n// ============================================================================\n\nexport const isWidgetItem = (\n item: shareables.ModalItem,\n): item is { type: \"widget\"; data: shareables.ShareableItem } => {\n return item.type === \"widget\";\n};\n\nexport const isProductItem = (\n item: shareables.ModalItem,\n): item is { type: \"product\"; data: shareables.ProductRef } => {\n return item.type === \"product\";\n};\n\nexport const isMediaItem = (\n item: shareables.ModalItem,\n): item is { type: \"media\"; data: shareables.ProductMedia } => {\n return item.type === \"media\";\n};\n\n// ============================================================================\n// Product Media - Display Helpers\n// ============================================================================\n\nexport const getDisplayTitle = (item: shareables.ModalItem): string => {\n switch (item.type) {\n case \"widget\":\n return item.data.relateable?.title || item.data.title || \"Untitled\";\n case \"product\":\n return item.data.title;\n case \"media\":\n return item.data.title;\n default:\n return \"Untitled\";\n }\n};\n\nexport const getDisplayImage = (item: shareables.ModalItem): string => {\n switch (item.type) {\n case \"widget\":\n return item.data.relateable?.image_url || item.data.image_url || \"\";\n case \"product\":\n return item.data.image_url || \"\";\n case \"media\":\n return item.data.image_url || \"\";\n default:\n return \"\";\n }\n};\n\nexport const getDisplayVideo = (\n item: shareables.ModalItem,\n): string | undefined => {\n switch (item.type) {\n case \"widget\":\n return item.data.relateable?.video_url || item.data.video || undefined;\n case \"product\":\n return undefined;\n case \"media\":\n return item.data.video_url || undefined;\n default:\n return undefined;\n }\n};\n\ntype DescriptionField = string | { body: string } | null | undefined;\n\nexport const getDisplayDescription = (item: shareables.ModalItem): string => {\n switch (item.type) {\n case \"widget\": {\n const widgetDesc = item.data.relateable?.description as DescriptionField;\n if (typeof widgetDesc === \"object\" && widgetDesc?.body) {\n return widgetDesc.body;\n }\n return (\n (typeof widgetDesc === \"string\" ? widgetDesc : \"\") ||\n item.data.description ||\n \"\"\n );\n }\n case \"product\": {\n const productDesc = item.data.description as DescriptionField;\n if (typeof productDesc === \"object\" && productDesc?.body) {\n return productDesc.body;\n }\n return (\n (typeof productDesc === \"string\" ? productDesc : \"\") ||\n item.data.stripped ||\n \"\"\n );\n }\n case \"media\":\n return item.data.description || \"\";\n default:\n return \"\";\n }\n};\n\nexport const isProductType = (item: shareables.ModalItem): boolean => {\n if (isProductItem(item)) {\n return true;\n }\n\n if (isWidgetItem(item)) {\n const relateableType = item.data.relateable_type?.toLowerCase();\n return (\n relateableType === \"product\" ||\n relateableType === \"products\" ||\n relateableType === \"enrollmentpack\" ||\n relateableType === \"enrollment_packs\"\n );\n }\n\n return false;\n};\n\nexport const getProductIds = (item: shareables.ModalItem): number[] => {\n if (isProductItem(item)) {\n return [item.data.id];\n }\n\n if (isWidgetItem(item)) {\n const data = item.data;\n\n const type = data.relateable_type?.toLowerCase();\n if (\n (type === \"enrollmentpack\" || type === \"enrollment_packs\") &&\n data.relateable\n ) {\n const membershipIds =\n data.relateable.membership_products?.map((p) => p.id) || [];\n const subscriptionIds =\n data.relateable.subscription_products?.map((p) => p.id) || [];\n return [...membershipIds, ...subscriptionIds];\n }\n\n if (data.id && data.id !== 0) {\n return [data.id];\n } else if (data.relateable?.id && typeof data.relateable.id === \"number\") {\n return [data.relateable.id];\n }\n return [];\n }\n\n return [];\n};\n","import type { FetchClient } from \"../lib/fetch-client\";\nimport type { shareables } from \"../generated/shareables\";\n\n// ============================================================================\n// Share - List\n// ============================================================================\n\nexport async function getShares(\n client: FetchClient,\n input?: shareables.GetSharesInput,\n): Promise<shareables.SharesListResponse> {\n return client.get(\"/shares.json\", (input || {}) as Record<string, unknown>);\n}\n\n// ============================================================================\n// Share - Create Link\n// ============================================================================\n\nexport async function createShareLink(\n client: FetchClient,\n input: shareables.CreateShareLinkInput,\n): Promise<string> {\n const requestBody = {\n locale: input.locale,\n relateable_type: input.relateableType,\n ...(input.contactId && { contact_id: input.contactId }),\n ...(input.relateableId && { relateable_id: input.relateableId }),\n };\n\n const result = await client.post<shareables.ShareLinkResponse>(\n \"/shares.json\",\n requestBody,\n );\n\n return result.link;\n}\n","import type { FetchClient } from \"./lib/fetch-client\";\nimport * as mediaNs from \"./namespaces/media\";\nimport * as playlistsNs from \"./namespaces/playlists\";\nimport * as fileResourcesNs from \"./namespaces/file-resources\";\nimport * as productMediaNs from \"./namespaces/product-media\";\nimport * as shareNs from \"./namespaces/share\";\n\n/**\n * Creates a ShareablesApi-compatible adapter backed by the real API client\n * namespace functions. The returned object satisfies the ShareablesApi interface\n * from @fluid-app/shareables-core via structural typing.\n *\n * @param client - The FetchClient instance for making HTTP requests.\n * @param options - Provider-level configuration (e.g. repContext).\n */\nexport function createShareablesApiAdapter(\n client: FetchClient,\n options?: { repContext?: boolean },\n) {\n const repContext = options?.repContext ?? false;\n\n return {\n media: {\n getMedia: (opts?: Parameters<typeof mediaNs.getMedia>[1]) =>\n mediaNs.getMedia(client, opts, repContext),\n getMediaById: (id: number, language_iso?: string) =>\n mediaNs.getMediaById(client, id, language_iso, repContext),\n createMedia: (mediaData: Parameters<typeof mediaNs.createMedia>[1]) =>\n mediaNs.createMedia(client, mediaData, repContext),\n updateMedia: (\n id: number,\n mediaData: Parameters<typeof mediaNs.updateMedia>[2],\n language_iso?: string,\n ) => mediaNs.updateMedia(client, id, mediaData, language_iso, repContext),\n deleteMedia: (id: number) => mediaNs.deleteMedia(client, id, repContext),\n },\n playlists: {\n getPlaylists: (opts?: Parameters<typeof playlistsNs.getPlaylists>[1]) =>\n playlistsNs.getPlaylists(client, opts),\n getPlaylistById: (id: number) => playlistsNs.getPlaylistById(client, id),\n createPlaylist: (\n data: Parameters<typeof playlistsNs.createPlaylist>[1],\n ) => playlistsNs.createPlaylist(client, data),\n updatePlaylist: (\n id: number,\n data: Parameters<typeof playlistsNs.updatePlaylist>[2],\n ) => playlistsNs.updatePlaylist(client, id, data),\n addItemToPlaylist: (\n id: number,\n data: Parameters<typeof playlistsNs.addItemToPlaylist>[2],\n ) => playlistsNs.addItemToPlaylist(client, id, data),\n removeItemsFromPlaylist: (\n playlistId: number,\n data: Parameters<typeof playlistsNs.removeItemsFromPlaylist>[2],\n ) => playlistsNs.removeItemsFromPlaylist(client, playlistId, data),\n },\n fileResources: {\n getFileResources: (\n params: Parameters<typeof fileResourcesNs.getFileResources>[1],\n ) => fileResourcesNs.getFileResources(client, params),\n },\n productMedia: {\n getProductMedia: (productId: number) =>\n productMediaNs.getProductMedia(client, productId),\n },\n share: {\n createShareLink: (input: Parameters<typeof shareNs.createShareLink>[1]) =>\n shareNs.createShareLink(client, input),\n },\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, ProductsApp } from \"@fluid-app/shareables-ui\";\nimport { createShareablesApiAdapter } from \"@fluid-app/shareables-api-client\";\nimport { useCurrentUser } from \"../hooks/use-current-user\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { useSdkClient } from \"../account/use-account-clients\";\nimport { usePortalProductsClient } from \"../products/use-portal-products-client\";\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 const domainClient = useSdkClient();\n const portalProductsApi = usePortalProductsClient();\n const { data: userData } = useCurrentUser();\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 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 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 basePath: \"\",\n navigate: (path: string) => {\n navigate(path);\n },\n showToast: (opts: {\n title: string;\n type: \"success\" | \"error\" | \"warning\";\n }) => {\n console.log(`[Products] ${opts.type}: ${opts.title}`);\n },\n }),\n [userData, navigate],\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 <ProductsApp\n countryCode={userData?.country?.iso}\n companyLogoUrl={userData?.company?.logo_url}\n fetchProducts={fetchProducts}\n fetchProduct={fetchProduct}\n productId={productId}\n onSelectProduct={handleSelectProduct}\n onBack={handleBack}\n />\n </ShareablesUIProvider>\n </ShareablesApiProvider>\n </ShareablesCoreProvider>\n </div>\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":"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"}