@fluid-app/portal-sdk 0.1.132 → 0.1.133

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 (28) hide show
  1. package/dist/{ProductsScreen-C_dDt9WX.cjs → ProductsScreen-BPNdpsYm.cjs} +1 -1
  2. package/dist/{ProductsScreen-DYWdxMTa.cjs → ProductsScreen-BY285fh-.cjs} +2 -2
  3. package/dist/{ProductsScreen-DYWdxMTa.cjs.map → ProductsScreen-BY285fh-.cjs.map} +1 -1
  4. package/dist/{ProductsScreen-B0M7dCE5.mjs → ProductsScreen-DMldTDPg.mjs} +1 -2
  5. package/dist/{ProductsScreen-Bmxx8B0A.mjs → ProductsScreen-jdy2j9_J.mjs} +2 -2
  6. package/dist/{ProductsScreen-Bmxx8B0A.mjs.map → ProductsScreen-jdy2j9_J.mjs.map} +1 -1
  7. package/dist/{ShareablesScreen-C5l-N62w.mjs → ShareablesScreen-B6tMQzuX.mjs} +2 -2
  8. package/dist/{ShareablesScreen-C5l-N62w.mjs.map → ShareablesScreen-B6tMQzuX.mjs.map} +1 -1
  9. package/dist/{ShareablesScreen-D5SEdJmI.cjs → ShareablesScreen-DMBXIMMj.cjs} +1 -1
  10. package/dist/{ShareablesScreen-C9cjRd4O.mjs → ShareablesScreen-d_ThfnNQ.mjs} +1 -2
  11. package/dist/{ShareablesScreen-CRkuzf7k.cjs → ShareablesScreen-znVUD_OK.cjs} +2 -2
  12. package/dist/{ShareablesScreen-CRkuzf7k.cjs.map → ShareablesScreen-znVUD_OK.cjs.map} +1 -1
  13. package/dist/{ShopScreen-BDigR1JJ.cjs → ShopScreen-BVIT_QS-.cjs} +6 -4
  14. package/dist/ShopScreen-BVIT_QS-.cjs.map +1 -0
  15. package/dist/{ShopScreen-C7idALr7.cjs → ShopScreen-Bsjdn-E9.cjs} +1 -1
  16. package/dist/{ShopScreen-Ba-btuXQ.mjs → ShopScreen-C1bnhxpj.mjs} +6 -4
  17. package/dist/ShopScreen-C1bnhxpj.mjs.map +1 -0
  18. package/dist/index.cjs +9 -9
  19. package/dist/index.mjs +9 -9
  20. package/dist/{use-portal-products-client-Bl-yd0Tl.cjs → use-portal-products-client-CIrRGIxC.cjs} +5 -14
  21. package/dist/use-portal-products-client-CIrRGIxC.cjs.map +1 -0
  22. package/dist/{use-portal-products-client-DkzsuK_Y.mjs → use-portal-products-client-dV5jIXpp.mjs} +6 -15
  23. package/dist/use-portal-products-client-dV5jIXpp.mjs.map +1 -0
  24. package/package.json +17 -17
  25. package/dist/ShopScreen-BDigR1JJ.cjs.map +0 -1
  26. package/dist/ShopScreen-Ba-btuXQ.mjs.map +0 -1
  27. package/dist/use-portal-products-client-Bl-yd0Tl.cjs.map +0 -1
  28. package/dist/use-portal-products-client-DkzsuK_Y.mjs.map +0 -1
@@ -39,6 +39,6 @@ require("./es-BSkb3AZk.cjs");
39
39
  require("./dist-DkYXiQQ1.cjs");
40
40
  require("./src-C5GUPE_i.cjs");
41
41
  require("./dist-BSbac3uh.cjs");
42
- const require_ProductsScreen = require("./ProductsScreen-DYWdxMTa.cjs");
42
+ const require_ProductsScreen = require("./ProductsScreen-BY285fh-.cjs");
43
43
  exports.ProductsScreen = require_ProductsScreen.ProductsScreen;
44
44
  exports.productsScreenPropertySchema = require_ProductsScreen.productsScreenPropertySchema;
@@ -3,7 +3,7 @@ const require_use_current_user = require("./use-current-user-DISrPz9d.cjs");
3
3
  const require_AppNavigationContext = require("./AppNavigationContext-Agp0UkCQ.cjs");
4
4
  const require_use_account_clients = require("./use-account-clients-CH92XyHh.cjs");
5
5
  const require_src = require("./src-C5GUPE_i.cjs");
6
- const require_use_portal_products_client = require("./use-portal-products-client-Bl-yd0Tl.cjs");
6
+ const require_use_portal_products_client = require("./use-portal-products-client-CIrRGIxC.cjs");
7
7
  let react = require("react");
8
8
  let react_jsx_runtime = require("react/jsx-runtime");
9
9
  //#region ../../shareables/api-client/src/namespaces/media.ts
@@ -280,4 +280,4 @@ Object.defineProperty(exports, "productsScreenPropertySchema", {
280
280
  }
281
281
  });
282
282
 
283
- //# sourceMappingURL=ProductsScreen-DYWdxMTa.cjs.map
283
+ //# sourceMappingURL=ProductsScreen-BY285fh-.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ProductsScreen-DYWdxMTa.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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"}
1
+ {"version":3,"file":"ProductsScreen-BY285fh-.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":";;;;;;;;;AAOA,SAAS,uBACP,MAC2B;AAC3B,QAAO;EACL,GAAG;EACH,aAAa,KAAK;EAClB,YAAY,KAAK,aAAa,cAAc,KAAK;EAClD;;AAkBH,eAAsB,SACpB,QACA,UAAmC,EAAE,EACrC,YAC+C;AAC/C,KAAI,YAAY;EACd,MAAM,WAAW,MAAM,OAAO,IAC5B,yBACA,QACD;EAED,MAAM,mBAAmB,SAAS,MAAM,IAAI,uBAAuB;EACnE,MAAM,UAAU,QAAQ,YAAY;AAEpC,SAAO;GACL,MAAM;GACN,QAAQ;GACR,OAAO;GACP,MAAM;IACJ,aAAa,SAAS,KAAK;IAC3B,SAAS,SAAS,KAAK;IACvB,UAAU;IACV,OAAO,SAAS,KAAK;IACrB,MACE,SAAS,KAAK,eAAe,SAAS,KAAK,cACvC,SAAS,KAAK,eAAe,IAC7B;IACN,UACE,SAAS,KAAK,eAAe,IACzB,SAAS,KAAK,eAAe,IAC7B;IACP;GACF;;CAGH,MAAM,WAAW,MAAM,OAAO,IAC5B,kBACA,QACD;CAED,IAAI,aAAyC,EAAE;CAC/C,IAAI,aAAyC;EAC3C,OAAO;EACP,UAAU;EACV,MAAM;EACN,OAAO;EACP,UAAU;EACV,SAAS;EACV;AAED,UAAS,SAAS,SAAS;AACzB,MAAI,WAAW,QAAQ,MAAM,QAAQ,KAAK,MAAM,CAC9C,cAAa,KAAK;AAEpB,MAAI,gBAAgB,QAAQ,KAAK,YAAY,MAC3C,cAAa,KAAK;GAEpB;CAEF,MAAM,mBAAmB,WAAW,IAAI,uBAAuB;AAE/D,QAAO;EACL,MAAM;EACN,QAAQ;EACR,OAAO;EACP,MAAM;GACJ,GAAG;GACH,aAAa,WAAW,SAAS,WAAW;GAC7C;EACF;;AAGH,eAAsB,aACpB,QACA,IACA,cACA,YAC2C;AAC3C,KAAI,YAAY;EACd,MAAM,WAAW,MAAM,OAAO,IAC5B,yBAAyB,KAC1B;AACD,SAAO;GACL,MAAM,SAAS;GACf,QAAQ;GACR,OAAO,SAAS;GACjB;;CAGH,MAAM,WAAW,eACb,kBAAkB,GAAG,gBAAgB,iBACrC,kBAAkB;CAEtB,MAAM,WAAW,MAAM,OAAO,IAA+B,SAAS;AAEtE,QAAO;EACL,MAAM;EACN,QAAQ;EACR,OAAO;EACR;;AAuEH,eAAsB,YACpB,QACA,WACA,YACoC;AACpC,KAAI,WAKF,SAJiB,MAAM,OAAO,KAC5B,yBACA,UACD,EACe;AAOlB,SAJiB,MAAM,OAAO,KAC5B,kBACA,UACD,EACe;;AAclB,eAAsB,YACpB,QACA,IACA,WACA,cACA,YACoC;AACpC,KAAI,WAOF,SANiB,MAAM,OAAO,QAE3B,yBAAyB,MAAM;EAChC,QAAQ;EACR,MAAM;EACP,CAAC,EACc;CAGlB,MAAM,WAAW,eACb,kBAAkB,GAAG,gBAAgB,iBACrC,kBAAkB;CAEtB,MAAM,WAAW,MAAM,OAAO,IAA8B,UAAU,EACpE,QAAQ,WACT,CAAC;AAEF,KACE,YACA,OAAO,aAAa,YACpB,UAAU,YACV,SAAS,KAET,QAAO,SAAS;AAElB,QAAO;;;;;;AAgCT,eAAsB,YACpB,QACA,IACA,YAC+B;AAC/B,KAAI,WACF,OAAM,OAAO,OAAO,yBAAyB,KAAK;KAElD,OAAM,OAAO,OAAO,kBAAkB,KAAK;AAE7C,QAAO,EAAE,SAAS,MAAM;;;;ACjT1B,MAAM,gBAAgB;AActB,eAAsB,aACpB,QACA,SAC0C;CAC1C,MAAM,QAAQ,UACV,OAAO,YACL,OAAO,QAAQ,QAAQ,CAAC,QAAQ,GAAG,WAAW,UAAU,KAAA,EAAU,CACnE,GACD,KAAA;AACJ,QAAO,OAAO,IAAI,eAAe,MAAM;;AAGzC,eAAsB,gBACpB,QACA,IACyC;AACzC,QAAO,OAAO,IAAI,GAAG,cAAc,GAAG,KAAK;;AAO7C,eAAsB,eACpB,QACA,MACyC;AACzC,QAAO,OAAO,KAAK,eAAe,KAAK;;AAGzC,eAAsB,eACpB,QACA,IACA,MACyC;AACzC,QAAO,OAAO,MAAM,GAAG,cAAc,GAAG,MAAM,KAAK;;AAGrD,eAAsB,kBACpB,QACA,IACA,MAC8B;AAC9B,QAAO,OAAO,KAAK,GAAG,cAAc,GAAG,GAAG,SAAS,KAAK;;AAuC1D,eAAsB,wBACpB,QACA,YACA,MAC8B;AAC9B,QAAO,OAAO,QAAQ,GAAG,cAAc,GAAG,WAAW,SAAS;EAC5D,QAAQ;EACR,MAAM;EACP,CAAC;;;;ACpGJ,eAAsB,iBACpB,QACA,QAS2C;CAC3C,MAAM,KAAK,IAAI,gBAAgB;EAC7B,GAAI,OAAO,gBAAgB,EAAE,cAAc,OAAO,cAAc;EAChE,GAAI,OAAO,aAAa,EAAE,MAAM,OAAO,WAAW;EAClD,GAAI,OAAO,YAAY,EAAE,UAAU,OAAO,UAAU;EACpD,GAAI,OAAO,mBAAmB,EAC5B,mBAAmB,OAAO,gBAAgB,UAAU,EACrD;EACD,GAAI,OAAO,gBAAgB,EACzB,gBAAgB,OAAO,aAAa,UAAU,EAC/C;EACD,GAAI,OAAO,YAAY,EAAE,WAAW,OAAO,UAAU;EACtD,CAAC;AACF,QAAO,WAAW,SAAS,SAAS;AAClC,KAAG,OAAO,gBAAgB,KAAK;GAC/B;AAEF,QAAO,OAAO,IAAI,mBAAmB,GAAG,UAAU,GAAG;;;;AC5BvD,eAAsB,gBACpB,QACA,WAC0C;AAC1C,QAAO,OAAO,IAAI,sBAAsB,UAAU,QAAQ;;;;ACO5D,eAAsB,gBACpB,QACA,OACiB;CACjB,MAAM,cAAc;EAClB,QAAQ,MAAM;EACd,iBAAiB,MAAM;EACvB,GAAI,MAAM,aAAa,EAAE,YAAY,MAAM,WAAW;EACtD,GAAI,MAAM,gBAAgB,EAAE,eAAe,MAAM,cAAc;EAChE;AAOD,SALe,MAAM,OAAO,KAC1B,gBACA,YACD,EAEa;;;;;;;;;;;;ACnBhB,SAAgB,2BACd,QACA,SACA;CACA,MAAM,aAAa,SAAS,cAAc;AAE1C,QAAO;EACL,OAAO;GACL,WAAW,SACTA,SAAiB,QAAQ,MAAM,WAAW;GAC5C,eAAe,IAAY,iBACzBC,aAAqB,QAAQ,IAAI,cAAc,WAAW;GAC5D,cAAc,cACZC,YAAoB,QAAQ,WAAW,WAAW;GACpD,cACE,IACA,WACA,iBACGC,YAAoB,QAAQ,IAAI,WAAW,cAAc,WAAW;GACzE,cAAc,OAAeC,YAAoB,QAAQ,IAAI,WAAW;GACzE;EACD,WAAW;GACT,eAAe,SACbC,aAAyB,QAAQ,KAAK;GACxC,kBAAkB,OAAeC,gBAA4B,QAAQ,GAAG;GACxE,iBACE,SACGC,eAA2B,QAAQ,KAAK;GAC7C,iBACE,IACA,SACGC,eAA2B,QAAQ,IAAI,KAAK;GACjD,oBACE,IACA,SACGC,kBAA8B,QAAQ,IAAI,KAAK;GACpD,0BACE,YACA,SACGC,wBAAoC,QAAQ,YAAY,KAAK;GACnE;EACD,eAAe,EACb,mBACE,WACGC,iBAAiC,QAAQ,OAAO,EACtD;EACD,cAAc,EACZ,kBAAkB,cAChBC,gBAA+B,QAAQ,UAAU,EACpD;EACD,OAAO,EACL,kBAAkB,UAChBC,gBAAwB,QAAQ,MAAM,EACzC;EACF;;;;ACzCH,SAAgB,eAAe,EAE7B,YACA,WACA,aACA,SACA,cAEA,GAAG,YACsC;CACzC,MAAM,eAAeC,4BAAAA,cAAc;CACnC,MAAM,oBAAoBC,mCAAAA,yBAAyB;CACnD,MAAM,EAAE,MAAM,aAAaC,yBAAAA,gBAAgB;CAC3C,MAAM,EAAE,aAAa,aAAaC,6BAAAA,kBAAkB;CAEpD,MAAM,iBAAA,GAAA,MAAA,aACJ,OAAO,QAAgB,QAAiB,UAAmB;AACzD,MAAI,OACF,QAAO,kBAAkB,eAAe,QAAQ;GAAE;GAAQ;GAAO,CAAC;AAEpE,SAAO,kBAAkB,aAAa;GAAE;GAAQ;GAAO,CAAC;IAE1D,CAAC,kBAAkB,CACpB;CAED,MAAM,gBAAA,GAAA,MAAA,aACJ,OAAO,OAAwB,kBAAkB,WAAW,GAAG,EAC/D,CAAC,kBAAkB,CACpB;CAGD,MAAM,aAAA,GAAA,MAAA,eAA0B;AAE9B,SADc,YAAY,MAAM,kBAAkB,GACnC,MAAM;IACpB,CAAC,YAAY,CAAC;CAEjB,MAAM,uBAAA,GAAA,MAAA,cACH,OAAe;AACd,WAAS,YAAY,KAAK;IAE5B,CAAC,SAAS,CACX;CAED,MAAM,cAAA,GAAA,MAAA,mBAA+B;AACnC,WAAS,WAAW;IACnB,CAAC,SAAS,CAAC;CAEd,MAAM,cAAA,GAAA,MAAA,gBACG;EACL,QAAQ;EACR,MAAM,WAAW,EAAE,IAAI,SAAS,IAAI,GAAG;EACvC,YAAY;EACb,GACD,CAAC,cAAc,SAAS,CACzB;CAED,MAAM,iBAAA,GAAA,MAAA,eACE,2BAA2B,cAAc,EAAE,YAAY,MAAM,CAAC,EACpE,CAAC,aAAa,CACf;CAED,MAAM,YAAA,GAAA,MAAA,gBACG;EACL,MAAM,WACF;GACE,IAAI,SAAS;GACb,SAAS,SAAS,UACd,EAAE,UAAU,SAAS,QAAQ,UAAU,GACvC;GACL,GACD,KAAA;EACJ,UAAU;EACV,WAAW,SAAiB;AAC1B,YAAS,KAAK;;EAEhB,YAAY,SAGN;AACJ,WAAQ,IAAI,cAAc,KAAK,KAAK,IAAI,KAAK,QAAQ;;EAExD,GACD,CAAC,UAAU,SAAS,CACrB;AAED,QACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EAAK,GAAI;EAAU,WAAW,UAAU,SAAS,aAAa;YAC5D,iBAAA,GAAA,kBAAA,KAACC,YAAAA,wBAAD;GAAwB,QAAQ;aAC9B,iBAAA,GAAA,kBAAA,KAACC,YAAAA,uBAAD;IAAuB,KAAK;cAC1B,iBAAA,GAAA,kBAAA,KAACC,YAAAA,sBAAD;KAAsB,QAAQ;eAC5B,iBAAA,GAAA,kBAAA,KAACC,YAAAA,aAAD;MACE,aAAa,UAAU,SAAS;MAChC,gBAAgB,UAAU,SAAS;MACpB;MACD;MACH;MACX,iBAAiB;MACjB,QAAQ;MACR,CAAA;KACmB,CAAA;IACD,CAAA;GACD,CAAA;EACrB,CAAA;;AAIV,MAAa,+BAAqD;CAChE,YAAY;CACZ,aAAa;CACb,YAAY,CAAC;EAAE,IAAI;EAAW,OAAO;EAAW,CAAC;CACjD,QAAQ,EAAE;CACX"}
@@ -34,10 +34,9 @@ import "./TableWidget-CfSqeNQj.mjs";
34
34
  import "./ToDoWidget-DaxkgCEl.mjs";
35
35
  import "./VideoWidget-CHktk3hs.mjs";
36
36
  import "./ScreenHeaderContext-CrdfLGKk.mjs";
37
- import "./use-current-user-BP_GJuQe.mjs";
38
37
  import "./dist-CMGXkSgZ.mjs";
39
38
  import "./dist-CayuD99K.mjs";
40
39
  import "./src-DcIV4Mpe.mjs";
41
40
  import "./sortable.esm-BzPsVjTI.mjs";
42
- import { n as productsScreenPropertySchema, t as ProductsScreen } from "./ProductsScreen-Bmxx8B0A.mjs";
41
+ import { n as productsScreenPropertySchema, t as ProductsScreen } from "./ProductsScreen-jdy2j9_J.mjs";
43
42
  export { ProductsScreen, productsScreenPropertySchema };
@@ -2,7 +2,7 @@ import { n as useCurrentUser } from "./use-current-user-BP_GJuQe.mjs";
2
2
  import { n as useAppNavigation } from "./AppNavigationContext-Du3Qq0yc.mjs";
3
3
  import { i as useSdkClient } from "./use-account-clients-BjK5QVYl.mjs";
4
4
  import { a as ShareablesApiProvider, i as ShareablesUIProvider, o as ShareablesCoreProvider, t as ProductsApp } from "./src-DcIV4Mpe.mjs";
5
- import { t as usePortalProductsClient } from "./use-portal-products-client-DkzsuK_Y.mjs";
5
+ import { t as usePortalProductsClient } from "./use-portal-products-client-dV5jIXpp.mjs";
6
6
  import { useCallback, useMemo } from "react";
7
7
  import { jsx } from "react/jsx-runtime";
8
8
  //#region ../../shareables/api-client/src/namespaces/media.ts
@@ -268,4 +268,4 @@ const productsScreenPropertySchema = {
268
268
  //#endregion
269
269
  export { productsScreenPropertySchema as n, ProductsScreen as t };
270
270
 
271
- //# sourceMappingURL=ProductsScreen-Bmxx8B0A.mjs.map
271
+ //# sourceMappingURL=ProductsScreen-jdy2j9_J.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ProductsScreen-Bmxx8B0A.mjs","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"],"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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"}
1
+ {"version":3,"file":"ProductsScreen-jdy2j9_J.mjs","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"],"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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"}
@@ -4,7 +4,7 @@ import { n as useCurrentUser } from "./use-current-user-BP_GJuQe.mjs";
4
4
  import { n as useAppNavigation } from "./AppNavigationContext-Du3Qq0yc.mjs";
5
5
  import { i as useSdkClient } from "./use-account-clients-BjK5QVYl.mjs";
6
6
  import { a as ShareablesApiProvider, i as ShareablesUIProvider, n as ShareablesApp, o as ShareablesCoreProvider, r as getFileMimeType } from "./src-DcIV4Mpe.mjs";
7
- import { t as usePortalProductsClient } from "./use-portal-products-client-DkzsuK_Y.mjs";
7
+ import { t as usePortalProductsClient } from "./use-portal-products-client-dV5jIXpp.mjs";
8
8
  import { useCallback, useMemo } from "react";
9
9
  import { jsx } from "react/jsx-runtime";
10
10
  import { z } from "zod";
@@ -1311,4 +1311,4 @@ const shareablesScreenPropertySchema = {
1311
1311
  //#endregion
1312
1312
  export { shareablesScreenPropertySchema as n, useUserType as r, ShareablesScreen as t };
1313
1313
 
1314
- //# sourceMappingURL=ShareablesScreen-C5l-N62w.mjs.map
1314
+ //# sourceMappingURL=ShareablesScreen-B6tMQzuX.mjs.map