@burdenoff/microfe-store 2026.625.5 → 2026.626.2

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 (189) hide show
  1. package/dist/StoreRoot.js +47 -90
  2. package/dist/StoreRoot.js.map +1 -1
  3. package/dist/StoreRoutes.js +93 -158
  4. package/dist/StoreRoutes.js.map +1 -1
  5. package/dist/components/AccessDenied.js +3 -3
  6. package/dist/components/AccessDenied.js.map +1 -1
  7. package/dist/components/InstallAppModal.js +175 -255
  8. package/dist/components/InstallAppModal.js.map +1 -1
  9. package/dist/components/cart/CartDrawer.js +10 -10
  10. package/dist/components/cart/CartDrawer.js.map +1 -1
  11. package/dist/hooks/useStoreGraphQL.js +107 -177
  12. package/dist/hooks/useStoreGraphQL.js.map +1 -1
  13. package/dist/index.js +3 -3
  14. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/errors/CombinedGraphQLErrors.js +1 -1
  15. package/dist/node_modules/@apollo/client/errors/CombinedGraphQLErrors.js.map +1 -0
  16. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/errors/utils.js +1 -1
  17. package/dist/node_modules/@apollo/client/errors/utils.js.map +1 -0
  18. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/link/core/ApolloLink.js +2 -2
  19. package/dist/node_modules/@apollo/client/link/core/ApolloLink.js.map +1 -0
  20. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/link/subscriptions/index.js +2 -2
  21. package/dist/node_modules/@apollo/client/link/subscriptions/index.js.map +1 -0
  22. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/link/utils/createOperation.js +1 -1
  23. package/dist/node_modules/@apollo/client/link/utils/createOperation.js.map +1 -0
  24. package/dist/node_modules/@apollo/client/utilities/caching/sizes.js.map +1 -0
  25. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/utilities/graphql/print.js +1 -1
  26. package/dist/node_modules/@apollo/client/utilities/graphql/print.js.map +1 -0
  27. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/utilities/internal/caches.js +2 -2
  28. package/dist/node_modules/@apollo/client/utilities/internal/caches.js.map +1 -0
  29. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/utilities/internal/checkDocument.js +1 -1
  30. package/dist/node_modules/@apollo/client/utilities/internal/checkDocument.js.map +1 -0
  31. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/utilities/internal/getMainDefinition.js +1 -1
  32. package/dist/node_modules/@apollo/client/utilities/internal/getMainDefinition.js.map +1 -0
  33. package/dist/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js +9 -0
  34. package/dist/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js.map +1 -0
  35. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/utilities/internal/getOperationDefinition.js +1 -1
  36. package/dist/node_modules/@apollo/client/utilities/internal/getOperationDefinition.js.map +1 -0
  37. package/dist/node_modules/@apollo/client/utilities/internal/getOperationName.js +8 -0
  38. package/dist/node_modules/@apollo/client/utilities/internal/getOperationName.js.map +1 -0
  39. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/utilities/internal/globals/global.js +1 -1
  40. package/dist/node_modules/@apollo/client/utilities/internal/globals/global.js.map +1 -0
  41. package/dist/node_modules/@apollo/client/utilities/internal/globals/maybe.js +10 -0
  42. package/dist/node_modules/@apollo/client/utilities/internal/globals/maybe.js.map +1 -0
  43. package/dist/node_modules/@apollo/client/utilities/internal/isNonNullObject.js +8 -0
  44. package/dist/node_modules/@apollo/client/utilities/internal/isNonNullObject.js.map +1 -0
  45. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/utilities/internal/makeUniqueId.js +1 -1
  46. package/dist/node_modules/@apollo/client/utilities/internal/makeUniqueId.js.map +1 -0
  47. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/utilities/internal/memoize.js +2 -2
  48. package/dist/node_modules/@apollo/client/utilities/internal/memoize.js.map +1 -0
  49. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/utilities/internal/stringifyForDisplay.js +1 -1
  50. package/dist/node_modules/@apollo/client/utilities/internal/stringifyForDisplay.js.map +1 -0
  51. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/utilities/invariant/index.js +1 -1
  52. package/dist/node_modules/@apollo/client/utilities/invariant/index.js.map +1 -0
  53. package/dist/node_modules/@apollo/client/version.js +6 -0
  54. package/dist/node_modules/@apollo/client/version.js.map +1 -0
  55. package/dist/node_modules/{.bun/@wry_caches@1.0.1/node_modules/@wry → @wry}/caches/lib/weak.js +1 -1
  56. package/dist/node_modules/@wry/caches/lib/weak.js.map +1 -0
  57. package/dist/node_modules/{.bun/@wry_trie@0.5.0/node_modules/@wry → @wry}/trie/lib/index.js +1 -1
  58. package/dist/node_modules/@wry/trie/lib/index.js.map +1 -0
  59. package/dist/node_modules/{.bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws → graphql-ws}/dist/client.js +1 -1
  60. package/dist/node_modules/graphql-ws/dist/client.js.map +1 -0
  61. package/dist/node_modules/{.bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws → graphql-ws}/dist/common-CGW11Fyb.js +1 -1
  62. package/dist/node_modules/graphql-ws/dist/common-CGW11Fyb.js.map +1 -0
  63. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/NotificationFactories.js +1 -1
  64. package/dist/node_modules/rxjs/dist/esm5/internal/NotificationFactories.js.map +1 -0
  65. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/Observable.js +1 -1
  66. package/dist/node_modules/rxjs/dist/esm5/internal/Observable.js.map +1 -0
  67. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/Subscriber.js +2 -2
  68. package/dist/node_modules/rxjs/dist/esm5/internal/Subscriber.js.map +1 -0
  69. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/Subscription.js +2 -2
  70. package/dist/node_modules/rxjs/dist/esm5/internal/Subscription.js.map +1 -0
  71. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/config.js +1 -1
  72. package/dist/node_modules/rxjs/dist/esm5/internal/config.js.map +1 -0
  73. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/observable/empty.js +1 -1
  74. package/dist/node_modules/rxjs/dist/esm5/internal/observable/empty.js.map +1 -0
  75. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/scheduler/timeoutProvider.js +2 -2
  76. package/dist/node_modules/rxjs/dist/esm5/internal/scheduler/timeoutProvider.js.map +1 -0
  77. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/symbol/observable.js +1 -1
  78. package/dist/node_modules/rxjs/dist/esm5/internal/symbol/observable.js.map +1 -0
  79. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/util/UnsubscriptionError.js +1 -1
  80. package/dist/node_modules/rxjs/dist/esm5/internal/util/UnsubscriptionError.js.map +1 -0
  81. package/dist/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js +11 -0
  82. package/dist/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js.map +1 -0
  83. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/util/createErrorClass.js +1 -1
  84. package/dist/node_modules/rxjs/dist/esm5/internal/util/createErrorClass.js.map +1 -0
  85. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/util/errorContext.js +1 -1
  86. package/dist/node_modules/rxjs/dist/esm5/internal/util/errorContext.js.map +1 -0
  87. package/dist/node_modules/rxjs/dist/esm5/internal/util/identity.js +8 -0
  88. package/dist/node_modules/rxjs/dist/esm5/internal/util/identity.js.map +1 -0
  89. package/dist/node_modules/rxjs/dist/esm5/internal/util/isFunction.js +8 -0
  90. package/dist/node_modules/rxjs/dist/esm5/internal/util/isFunction.js.map +1 -0
  91. package/dist/node_modules/rxjs/dist/esm5/internal/util/noop.js +6 -0
  92. package/dist/node_modules/rxjs/dist/esm5/internal/util/noop.js.map +1 -0
  93. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/util/pipe.js +1 -1
  94. package/dist/node_modules/rxjs/dist/esm5/internal/util/pipe.js.map +1 -0
  95. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/util/reportUnhandledError.js +1 -1
  96. package/dist/node_modules/rxjs/dist/esm5/internal/util/reportUnhandledError.js.map +1 -0
  97. package/dist/node_modules/{.bun/tslib@2.8.1 → rxjs}/node_modules/tslib/tslib.es6.js +1 -1
  98. package/dist/node_modules/rxjs/node_modules/tslib/tslib.es6.js.map +1 -0
  99. package/dist/pages/AdminDashboardPage.js +118 -91
  100. package/dist/pages/AdminDashboardPage.js.map +1 -1
  101. package/dist/pages/AdminReviewModerationPage.js +67 -61
  102. package/dist/pages/AdminReviewModerationPage.js.map +1 -1
  103. package/dist/pages/AdminStoresPage.js +424 -371
  104. package/dist/pages/AdminStoresPage.js.map +1 -1
  105. package/dist/pages/AdminSubmissionsQueuePage.js +303 -286
  106. package/dist/pages/AdminSubmissionsQueuePage.js.map +1 -1
  107. package/dist/pages/AppDetailPage.js +172 -135
  108. package/dist/pages/AppDetailPage.js.map +1 -1
  109. package/dist/pages/AppSettingsPage.js +83 -300
  110. package/dist/pages/AppSettingsPage.js.map +1 -1
  111. package/dist/pages/CartPage.js +71 -79
  112. package/dist/pages/CartPage.js.map +1 -1
  113. package/dist/pages/InstalledAppsPage.js +120 -337
  114. package/dist/pages/InstalledAppsPage.js.map +1 -1
  115. package/dist/pages/MarketplaceHomePage.js +196 -205
  116. package/dist/pages/MarketplaceHomePage.js.map +1 -1
  117. package/dist/pages/MyLicensesPage.js +70 -75
  118. package/dist/pages/MyLicensesPage.js.map +1 -1
  119. package/dist/pages/OrderConfirmationPage.js +70 -37
  120. package/dist/pages/OrderConfirmationPage.js.map +1 -1
  121. package/dist/pages/OrdersPage.js +60 -68
  122. package/dist/pages/OrdersPage.js.map +1 -1
  123. package/dist/pages/ProductDetailPage.js +794 -752
  124. package/dist/pages/ProductDetailPage.js.map +1 -1
  125. package/dist/providers/StoreProvider.js +3 -3
  126. package/package.json +2 -2
  127. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/errors/CombinedGraphQLErrors.js.map +0 -1
  128. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/errors/utils.js.map +0 -1
  129. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/link/core/ApolloLink.js.map +0 -1
  130. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/link/subscriptions/index.js.map +0 -1
  131. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/link/utils/createOperation.js.map +0 -1
  132. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/caching/sizes.js.map +0 -1
  133. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/graphql/print.js.map +0 -1
  134. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/caches.js.map +0 -1
  135. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/checkDocument.js.map +0 -1
  136. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getMainDefinition.js.map +0 -1
  137. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js +0 -9
  138. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js.map +0 -1
  139. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getOperationDefinition.js.map +0 -1
  140. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getOperationName.js +0 -8
  141. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getOperationName.js.map +0 -1
  142. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/globals/global.js.map +0 -1
  143. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/globals/maybe.js +0 -10
  144. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/globals/maybe.js.map +0 -1
  145. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/isNonNullObject.js +0 -8
  146. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/isNonNullObject.js.map +0 -1
  147. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/makeUniqueId.js.map +0 -1
  148. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/memoize.js.map +0 -1
  149. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/stringifyForDisplay.js.map +0 -1
  150. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/invariant/index.js.map +0 -1
  151. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/version.js +0 -6
  152. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/version.js.map +0 -1
  153. package/dist/node_modules/.bun/@wry_caches@1.0.1/node_modules/@wry/caches/lib/weak.js.map +0 -1
  154. package/dist/node_modules/.bun/@wry_trie@0.5.0/node_modules/@wry/trie/lib/index.js.map +0 -1
  155. package/dist/node_modules/.bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws/dist/client.js.map +0 -1
  156. package/dist/node_modules/.bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws/dist/common-CGW11Fyb.js.map +0 -1
  157. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/NotificationFactories.js.map +0 -1
  158. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/Observable.js.map +0 -1
  159. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/Subscriber.js.map +0 -1
  160. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/Subscription.js.map +0 -1
  161. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/config.js.map +0 -1
  162. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/observable/empty.js.map +0 -1
  163. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/scheduler/timeoutProvider.js.map +0 -1
  164. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/symbol/observable.js.map +0 -1
  165. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/UnsubscriptionError.js.map +0 -1
  166. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js +0 -11
  167. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js.map +0 -1
  168. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/createErrorClass.js.map +0 -1
  169. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/errorContext.js.map +0 -1
  170. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/identity.js +0 -8
  171. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/identity.js.map +0 -1
  172. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/isFunction.js +0 -8
  173. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/isFunction.js.map +0 -1
  174. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/noop.js +0 -6
  175. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/noop.js.map +0 -1
  176. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/pipe.js.map +0 -1
  177. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/reportUnhandledError.js.map +0 -1
  178. package/dist/node_modules/.bun/tslib@2.8.1/node_modules/tslib/tslib.es6.js.map +0 -1
  179. package/dist/pages/ProductReviewsPage.js +0 -87
  180. package/dist/pages/ProductReviewsPage.js.map +0 -1
  181. package/dist/pages/PublisherDashboardPage.js +0 -160
  182. package/dist/pages/PublisherDashboardPage.js.map +0 -1
  183. package/dist/pages/PublisherRevenuePage.js +0 -140
  184. package/dist/pages/PublisherRevenuePage.js.map +0 -1
  185. package/dist/pages/PublisherSubmissionsPage.js +0 -179
  186. package/dist/pages/PublisherSubmissionsPage.js.map +0 -1
  187. package/dist/pages/PublisherSubmitPage.js +0 -230
  188. package/dist/pages/PublisherSubmitPage.js.map +0 -1
  189. /package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/utilities/caching/sizes.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"InstallAppModal.js","names":[],"sources":["../../src/components/InstallAppModal.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useState, useEffect, useCallback, useReducer } from 'react';\nimport { X, Loader2, Building2, CheckCircle, AlertCircle, Info, ShieldCheck } from 'lucide-react';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport { useStore } from '../providers/StoreProvider';\n\n// Local type definitions for workspace operations\ninterface Workspace {\n id: string;\n name: string;\n slug: string;\n type?: string;\n status?: string;\n organizationId?: string;\n}\n\ninterface WorkspaceList {\n items: Workspace[];\n total: number;\n}\n\ninterface InstallWorkspaceAppsResult {\n successCount: number;\n failedCount: number;\n results: Array<{\n success: boolean;\n workspaceId: string;\n app?: unknown;\n error?: string;\n }>;\n}\n\n// String queries for graphqlFetch\nconst MY_WORKSPACES_STRING = `query MyWorkspaces { myWorkspaces { items { id name slug type status organizationId } total } }`;\nconst INSTALL_WORKSPACE_APPS_STRING = `mutation InstallWorkspaceApps($workspaceIds: [ID!]!, $input: InstallWorkspaceAppInput!) { installWorkspaceApps(workspaceIds: $workspaceIds, input: $input) { successCount failedCount results { success workspaceId error } } }`;\nconst RECORD_APP_INSTALLATION_STRING = `mutation RecordAppInstallation($input: RecordAppInstallationInput!) { recordAppInstallation(input: $input) { id status workspaceId version } }`;\nconst INSTALL_PURCHASED_APP_STRING = `mutation InstallPurchasedApp($orderId: ID, $productId: String!, $workspaceId: String!) { installPurchasedApp(orderId: $orderId, productId: $productId, workspaceId: $workspaceId) { success alreadyInstalled installation { id productId workspaceId status version } error message } }`;\nconst CREATE_PRODUCT_ENTITLEMENT_STRING = `mutation CreateProductEntitlement($input: CreateProductEntitlementInput!) { createProductEntitlement(input: $input) { id status productId workspaceId } }`;\nconst STORE_DISTRIBUTED_TYPES = new Set([\n 'VIBEMODULE',\n 'NODE',\n 'CONSOLE',\n 'DASHBOARD',\n 'PARSER',\n 'DATASINK',\n]);\n\nconst INSTALL_ERROR_MESSAGES: Record<string, string> = {\n ALREADY_INSTALLED: 'This app is already installed in the selected workspace.',\n QUOTA_EXCEEDED: 'Installation limit reached. Please upgrade your plan or contact support.',\n PERMISSION_DENIED: 'You do not have permission to install apps in this workspace.',\n NOT_FOUND: 'The app or workspace could not be found.',\n WORKSPACE_INACTIVE: 'The selected workspace is inactive.',\n ENTITLEMENT_EXPIRED: 'Your license for this app has expired.',\n UNSUPPORTED_TYPE: 'This product type cannot be installed in the selected workspace.',\n};\n\nfunction mapInstallError(raw: string): string {\n for (const [code, message] of Object.entries(INSTALL_ERROR_MESSAGES)) {\n if (raw.toUpperCase().includes(code)) return message;\n }\n return 'Installation failed. Please try again or contact support.';\n}\n\ninterface InstallState {\n selectedWorkspace: string | null;\n installing: boolean;\n installError: string | null;\n installInfo: string | null;\n}\n\ntype InstallAction =\n | { type: 'reset' }\n | { type: 'selectWorkspace'; workspaceId: string }\n | { type: 'startInstall' }\n | { type: 'finishInstall' }\n | { type: 'setError'; error: string }\n | { type: 'setInfo'; info: string };\n\nconst initialInstallState: InstallState = {\n selectedWorkspace: null,\n installing: false,\n installError: null,\n installInfo: null,\n};\n\nfunction installReducer(state: InstallState, action: InstallAction): InstallState {\n switch (action.type) {\n case 'reset':\n return initialInstallState;\n case 'selectWorkspace':\n return { ...state, selectedWorkspace: action.workspaceId };\n case 'startInstall':\n return { ...state, installing: true, installError: null, installInfo: null };\n case 'finishInstall':\n return { ...state, installing: false };\n case 'setError':\n return { ...state, installError: action.error };\n case 'setInfo':\n return { ...state, installInfo: action.info };\n default:\n return state;\n }\n}\n\nexport interface AppInfo {\n id: string;\n name: string;\n slug?: string;\n icon?: string;\n type?: string;\n version?: string;\n requiredPermissions?: string[];\n}\n\ninterface InstallAppModalProps {\n isOpen: boolean;\n onClose: () => void;\n app: AppInfo;\n orderId?: string | null; // For purchased apps from orders page\n purchaseState?: 'free' | 'purchased';\n onInstallSuccess?: (workspaceId: string, workspaceName: string) => void;\n onInstallError?: (error: Error) => void;\n}\n\ntype ModalStep = 'permissions' | 'workspace';\n\ninterface UseWorkspacesResult {\n workspaces: Workspace[];\n loading: boolean;\n error: Error | null;\n refetch: () => void;\n}\n\n// NOTE: Inline Apollo clients removed. All GraphQL calls now use graphqlFetch\n// from fe-libs which automatically resolves gateway URLs and injects auth + locale headers.\n\n/**\n * Hook to fetch user's workspaces using graphqlFetch from fe-libs\n */\nfunction useWorkspaces(skip: boolean): UseWorkspacesResult {\n const { authToken } = useStore();\n const [workspaces, setWorkspaces] = useState<Workspace[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchWorkspaces = useCallback(async () => {\n if (skip) return;\n\n setLoading(true);\n setError(null);\n\n try {\n const result = await graphqlFetch<{ myWorkspaces: WorkspaceList }>({\n gateway: 'global',\n query: MY_WORKSPACES_STRING,\n authToken: authToken || undefined,\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'GraphQL error');\n }\n\n setWorkspaces(result.data?.myWorkspaces?.items || []);\n } catch (err) {\n setError(err instanceof Error ? err : new Error('Failed to fetch workspaces'));\n } finally {\n setLoading(false);\n }\n }, [authToken, skip]);\n\n useEffect(() => {\n fetchWorkspaces();\n }, [fetchWorkspaces]);\n\n return {\n workspaces,\n loading,\n error,\n refetch: fetchWorkspaces,\n };\n}\n\n/**\n * InstallAppModal component\n *\n * Modal for selecting a workspace to install an app into\n */\nexport const InstallAppModal: FC<InstallAppModalProps> = ({\n isOpen,\n onClose,\n app,\n orderId,\n purchaseState = 'free',\n onInstallSuccess,\n onInstallError,\n}) => {\n const { authToken, user } = useStore();\n const [installState, dispatchInstall] = useReducer(installReducer, initialInstallState);\n const { selectedWorkspace, installing, installError, installInfo } = installState;\n\n // Two-step flow: show permissions first if any exist, then workspace selection\n const permissions = app.requiredPermissions ?? [];\n const [step, setStep] = useState<ModalStep>(permissions.length > 0 ? 'permissions' : 'workspace');\n\n // Reset step when modal opens\n useEffect(() => {\n if (isOpen) {\n setStep(permissions.length > 0 ? 'permissions' : 'workspace');\n dispatchInstall({ type: 'reset' });\n }\n }, [isOpen, permissions.length]);\n\n const { workspaces, loading, error } = useWorkspaces(!isOpen || step === 'permissions');\n\n // Filter workspaces by status (only show active)\n const filteredWorkspaces = workspaces.filter((ws) => ws.status === 'ACTIVE');\n\n /**\n * Install purchased app via Store Service (NEW FLOW)\n * Used when installing from orders page or any already-purchased product\n */\n const handleInstallFromStore = async () => {\n if (!selectedWorkspace) return;\n\n const workspace = filteredWorkspaces.find((ws) => ws.id === selectedWorkspace);\n if (!workspace) return;\n const purchasedBy = user?.id;\n\n dispatchInstall({ type: 'startInstall' });\n\n try {\n if (!orderId && purchaseState !== 'purchased') {\n if (!purchasedBy) {\n throw new Error('Unable to identify the current user for license creation');\n }\n\n await graphqlFetch({\n gateway: 'global',\n query: CREATE_PRODUCT_ENTITLEMENT_STRING,\n variables: {\n input: {\n productId: app.id,\n purchasedBy,\n workspaceId: workspace.id,\n metadata: {\n source: 'store-ui',\n productType: app.type,\n },\n },\n },\n authToken: authToken || undefined,\n });\n }\n\n // Call Store Service to install the purchased app\n const result = await graphqlFetch<{\n installPurchasedApp: {\n success: boolean;\n alreadyInstalled?: boolean;\n installation?: {\n id: string;\n productId: string;\n workspaceId: string;\n status: string;\n version: string;\n };\n error?: string;\n message?: string;\n };\n }>({\n gateway: 'global', // Store Service\n query: INSTALL_PURCHASED_APP_STRING,\n variables: {\n orderId: orderId ?? null,\n productId: app.id,\n workspaceId: workspace.id,\n },\n authToken: authToken || undefined,\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Installation failed');\n }\n\n const installResult = result.data?.installPurchasedApp;\n\n if (installResult?.success) {\n if (installResult.alreadyInstalled) {\n dispatchInstall({\n type: 'setInfo',\n info: installResult.message || 'Already installed on this workspace',\n });\n } else {\n onInstallSuccess?.(workspace.id, workspace.name);\n onClose();\n }\n } else {\n const rawMsg = installResult?.error || 'Installation failed';\n const errorMsg = mapInstallError(rawMsg);\n dispatchInstall({ type: 'setError', error: errorMsg });\n onInstallError?.(new Error(rawMsg));\n }\n } catch (err) {\n const rawMsg = err instanceof Error ? err.message : 'Installation failed';\n const errorMsg = mapInstallError(rawMsg);\n dispatchInstall({ type: 'setError', error: errorMsg });\n onInstallError?.(new Error(rawMsg));\n } finally {\n dispatchInstall({ type: 'finishInstall' });\n }\n };\n\n /**\n * Install app via Workspace Service (LEGACY FLOW)\n * Used for free apps or when installing without order\n */\n const handleInstallViaWorkspace = async () => {\n if (!selectedWorkspace) return;\n\n const workspace = filteredWorkspaces.find((ws) => ws.id === selectedWorkspace);\n if (!workspace) return;\n\n dispatchInstall({ type: 'startInstall' });\n\n try {\n // Step 1: Install to workspace service via graphqlFetch\n const installVars = {\n workspaceIds: [workspace.id],\n input: {\n appName: app.slug || app.name.toLowerCase().replace(/\\s+/g, '-'),\n displayName: app.name,\n version: app.version || '1.0.0',\n type: app.type || 'app',\n manifest: {\n productId: app.id,\n icon: app.icon,\n },\n },\n };\n\n const result = await graphqlFetch<{\n installWorkspaceApps: InstallWorkspaceAppsResult;\n }>({\n gateway: 'workspace',\n query: INSTALL_WORKSPACE_APPS_STRING,\n variables: installVars,\n authToken: authToken || undefined,\n workspaceId: workspace.id,\n workspaceToken: true,\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Installation failed');\n }\n\n const installResult = result.data?.installWorkspaceApps;\n if (installResult?.successCount && installResult.successCount > 0) {\n // Step 2: Record installation in store service (for tracking)\n try {\n await graphqlFetch({\n gateway: 'global',\n query: RECORD_APP_INSTALLATION_STRING,\n variables: {\n input: {\n productId: app.id,\n workspaceId: workspace.id,\n workspaceName: workspace.name,\n workspaceType: workspace.type,\n organizationId: workspace.organizationId,\n version: app.version || '1.0.0',\n manifest: {\n productId: app.id,\n icon: app.icon,\n slug: app.slug,\n type: app.type,\n },\n },\n },\n authToken: authToken || undefined,\n });\n } catch {\n // Non-fatal: workspace installation succeeded; store record will sync later.\n }\n\n onInstallSuccess?.(workspace.id, workspace.name);\n onClose();\n } else {\n const rawMsg = installResult?.results?.[0]?.error || 'Installation failed';\n const errorMsg = mapInstallError(rawMsg);\n dispatchInstall({ type: 'setError', error: errorMsg });\n onInstallError?.(new Error(rawMsg));\n }\n } catch (err) {\n const rawMsg = err instanceof Error ? err.message : 'Installation failed';\n const errorMsg = mapInstallError(rawMsg);\n dispatchInstall({ type: 'setError', error: errorMsg });\n onInstallError?.(new Error(rawMsg));\n } finally {\n dispatchInstall({ type: 'finishInstall' });\n }\n };\n\n /**\n * Main install handler - routes to appropriate install function\n */\n const handleInstall = async () => {\n const appType = app.type?.toUpperCase() ?? '';\n\n if (purchaseState === 'purchased' || orderId || STORE_DISTRIBUTED_TYPES.has(appType)) {\n // Purchased products install through the store service.\n await handleInstallFromStore();\n } else {\n // Free products install through the workspace service.\n await handleInstallViaWorkspace();\n }\n };\n\n if (!isOpen) return null;\n\n const modalTitle = step === 'permissions' ? 'Review Permissions' : 'Install App';\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n {/* Backdrop */}\n <button\n type=\"button\"\n aria-label=\"Close modal\"\n className=\"absolute inset-0 bg-bg-overlay/50 backdrop-blur-sm\"\n onClick={onClose}\n />\n\n {/* Modal */}\n <dialog\n open\n aria-modal=\"true\"\n aria-labelledby=\"install-app-modal-title\"\n className=\"relative z-10 mx-4 w-full max-w-lg rounded-2xl border border-border-default bg-bg-surface shadow-2xl\"\n >\n {/* Header */}\n <div className=\"flex items-center justify-between border-b border-border-default px-6 py-4\">\n <div className=\"flex items-center gap-3\">\n {app.icon ? (\n <img src={app.icon} alt={app.name} className=\"size-10 rounded-lg object-cover\" />\n ) : (\n <div className=\"flex size-10 items-center justify-center rounded-lg bg-bg-sunken text-lg font-bold text-text-muted\">\n {app.name.charAt(0)}\n </div>\n )}\n <div>\n <h2 id=\"install-app-modal-title\" className=\"text-lg font-semibold text-text-primary\">\n {modalTitle}\n </h2>\n <p className=\"text-sm text-text-muted\">{app.name}</p>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n aria-label=\"Close install dialog\"\n className=\"cursor-pointer rounded-lg p-2 text-text-muted transition-colors hover:bg-bg-sunken hover:text-text-primary\"\n >\n <X className=\"size-5\" />\n </button>\n </div>\n\n {/* Step 1: Permissions consent */}\n {step === 'permissions' && (\n <>\n <div className=\"px-6 py-4\">\n <p className=\"mb-1 text-sm text-text-secondary\">\n <span className=\"font-medium text-text-primary\">{app.name}</span> requests access to the following data in your workspace. You must accept to continue.\n </p>\n <div className=\"mt-4 max-h-72 overflow-y-auto space-y-2\">\n {permissions.map((perm) => (\n <div\n key={perm}\n className=\"flex items-center gap-3 rounded-lg bg-bg-sunken px-4 py-3\"\n >\n <ShieldCheck className=\"size-5 flex-shrink-0 text-status-success-text\" />\n <span className=\"text-sm text-text-primary\">{perm}</span>\n </div>\n ))}\n </div>\n <p className=\"mt-3 text-xs text-text-muted\">\n These permissions will be recorded. You will be notified if they change in a future version.\n </p>\n </div>\n <div className=\"border-t border-border-default px-6 py-4 flex items-center justify-end gap-3\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"cursor-pointer rounded-lg border border-border-default px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={() => setStep('workspace')}\n className=\"cursor-pointer rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-opacity hover:opacity-90 inline-flex items-center gap-2\"\n >\n <CheckCircle className=\"size-4\" />\n Accept & Continue\n </button>\n </div>\n </>\n )}\n\n {/* Step 2: Workspace selection */}\n {step === 'workspace' && (\n <>\n <div className=\"px-6 py-4\">\n {permissions.length > 0 && (\n <div className=\"mb-3 flex items-center gap-2 rounded-lg bg-status-success-bg-subtle px-3 py-2 text-sm text-status-success-text\">\n <CheckCircle className=\"size-4 flex-shrink-0\" />\n <span>Permissions accepted ({permissions.length} permission{permissions.length !== 1 ? 's' : ''})</span>\n </div>\n )}\n <p className=\"mb-4 text-text-secondary\">\n Select the workspace where you want to install this app:\n </p>\n\n {/* Workspace List */}\n <div className=\"max-h-64 overflow-y-auto rounded-lg border border-border-default\">\n {loading ? (\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"size-8 animate-spin text-text-muted\" />\n </div>\n ) : error ? (\n <div className=\"flex flex-col items-center justify-center py-12 text-center\">\n <AlertCircle className=\"mb-2 size-8 text-status-error-text\" />\n <p className=\"text-sm text-status-error-text\">Failed to load workspaces</p>\n <p className=\"text-xs text-text-muted mt-1\">{error.message}</p>\n </div>\n ) : filteredWorkspaces.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center py-12 text-center\">\n <Building2 className=\"mb-2 size-8 text-text-muted\" />\n <p className=\"text-sm text-text-muted\">No workspaces available</p>\n </div>\n ) : (\n <div className=\"divide-y divide-border-default\">\n {filteredWorkspaces.map((workspace) => (\n <button\n type=\"button\"\n key={workspace.id}\n onClick={() =>\n dispatchInstall({ type: 'selectWorkspace', workspaceId: workspace.id })\n }\n className={`w-full cursor-pointer flex items-center gap-3 px-4 py-3 text-left transition-colors ${\n selectedWorkspace === workspace.id\n ? 'bg-action-primary-bg/10'\n : 'transition-colors hover:bg-bg-sunken'\n }`}\n >\n <div className=\"flex size-10 items-center justify-center rounded-lg bg-action-primary-bg/10 text-text-link\">\n <Building2 className=\"size-5\" />\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"font-medium text-text-primary truncate\">{workspace.name}</p>\n {workspace.slug ? (\n <p className=\"text-xs text-text-muted truncate\">/{workspace.slug}</p>\n ) : null}\n </div>\n {selectedWorkspace === workspace.id && (\n <CheckCircle className=\"size-5 flex-shrink-0 text-action-primary-bg\" />\n )}\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n\n {/* Footer */}\n <div className=\"border-t border-border-default px-6 py-4\">\n {installInfo && (\n <div className=\"mb-3 flex items-center gap-2 rounded-lg bg-status-info-bg-subtle px-3 py-2 text-sm text-status-info-text\">\n <Info className=\"size-4 flex-shrink-0\" />\n <span>{installInfo}</span>\n </div>\n )}\n {installError && (\n <div className=\"mb-3 flex items-center gap-2 rounded-lg bg-status-error-bg-subtle/10 px-3 py-2 text-sm text-status-error-text\">\n <AlertCircle className=\"size-4 flex-shrink-0\" />\n <span>{installError}</span>\n </div>\n )}\n <div className=\"flex items-center justify-end gap-3\">\n {permissions.length > 0 && (\n <button\n type=\"button\"\n onClick={() => setStep('permissions')}\n disabled={installing}\n className=\"cursor-pointer rounded-lg border border-border-default px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken disabled:opacity-50\"\n >\n Back\n </button>\n )}\n <button\n type=\"button\"\n onClick={onClose}\n disabled={installing}\n className=\"cursor-pointer rounded-lg border border-border-default px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken disabled:opacity-50\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={handleInstall}\n disabled={!selectedWorkspace || installing}\n className=\"cursor-pointer rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-opacity hover:opacity-90 disabled:opacity-50 disabled:cursor-not-allowed inline-flex items-center gap-2\"\n >\n {installing ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n Installing…\n </>\n ) : (\n 'Install App'\n )}\n </button>\n </div>\n </div>\n </>\n )}\n </dialog>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"InstallAppModal.js","names":[],"sources":["../../src/components/InstallAppModal.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useState, useEffect, useCallback, useReducer } from 'react';\nimport { Loader2, Building2, CheckCircle, AlertCircle, Info } from 'lucide-react';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport { useStore } from '../providers/StoreProvider';\n\n// Local type definitions for workspace operations\ninterface Workspace {\n id: string;\n name: string;\n slug: string;\n type?: string;\n status?: string;\n organizationId?: string;\n}\n\ninterface WorkspaceList {\n items: Workspace[];\n total: number;\n}\n\ninterface InstallWorkspaceAppsResult {\n successCount: number;\n failedCount: number;\n results: Array<{\n success: boolean;\n workspaceId: string;\n app?: unknown;\n error?: string;\n }>;\n}\n\n// String queries for graphqlFetch\nconst MY_WORKSPACES_STRING = `query MyWorkspaces { myWorkspaces { items { id name slug type status organizationId } total } }`;\nconst INSTALL_WORKSPACE_APPS_STRING = `mutation InstallWorkspaceApps($workspaceIds: [ID!]!, $input: InstallWorkspaceAppInput!) { installWorkspaceApps(workspaceIds: $workspaceIds, input: $input) { successCount failedCount results { success workspaceId error } } }`;\nconst RECORD_APP_INSTALLATION_STRING = `mutation RecordAppInstallation($input: RecordAppInstallationInput!) { recordAppInstallation(input: $input) { id status workspaceId version } }`;\nconst INSTALL_PURCHASED_APP_STRING = `mutation InstallPurchasedApp($orderId: ID, $productId: String!, $workspaceId: String!) { installPurchasedApp(orderId: $orderId, productId: $productId, workspaceId: $workspaceId) { success alreadyInstalled installation { id productId workspaceId status version } error message } }`;\nconst CREATE_PRODUCT_ENTITLEMENT_STRING = `mutation CreateProductEntitlement($input: CreateProductEntitlementInput!) { createProductEntitlement(input: $input) { id status productId workspaceId } }`;\nconst STORE_DISTRIBUTED_TYPES = new Set([\n 'VIBEMODULE',\n 'NODE',\n 'CONSOLE',\n 'DASHBOARD',\n 'PARSER',\n 'DATASINK',\n]);\n\nconst INSTALL_ERROR_MESSAGES: Record<string, string> = {\n ALREADY_INSTALLED: 'This app is already installed in the selected workspace.',\n QUOTA_EXCEEDED: 'Installation limit reached. Please upgrade your plan or contact support.',\n PERMISSION_DENIED: 'You do not have permission to install apps in this workspace.',\n NOT_FOUND: 'The app or workspace could not be found.',\n WORKSPACE_INACTIVE: 'The selected workspace is inactive.',\n ENTITLEMENT_EXPIRED: 'Your license for this app has expired.',\n UNSUPPORTED_TYPE: 'This product type cannot be installed in the selected workspace.',\n};\n\nfunction mapInstallError(raw: string): string {\n for (const [code, message] of Object.entries(INSTALL_ERROR_MESSAGES)) {\n if (raw.toUpperCase().includes(code)) return message;\n }\n return 'Installation failed. Please try again or contact support.';\n}\n\ninterface InstallState {\n selectedWorkspace: string | null;\n installing: boolean;\n installError: string | null;\n installInfo: string | null;\n}\n\ntype InstallAction =\n | { type: 'reset' }\n | { type: 'selectWorkspace'; workspaceId: string }\n | { type: 'startInstall' }\n | { type: 'finishInstall' }\n | { type: 'setError'; error: string }\n | { type: 'setInfo'; info: string };\n\nconst initialInstallState: InstallState = {\n selectedWorkspace: null,\n installing: false,\n installError: null,\n installInfo: null,\n};\n\nfunction installReducer(state: InstallState, action: InstallAction): InstallState {\n switch (action.type) {\n case 'reset':\n return initialInstallState;\n case 'selectWorkspace':\n return { ...state, selectedWorkspace: action.workspaceId };\n case 'startInstall':\n return { ...state, installing: true, installError: null, installInfo: null };\n case 'finishInstall':\n return { ...state, installing: false };\n case 'setError':\n return { ...state, installError: action.error };\n case 'setInfo':\n return { ...state, installInfo: action.info };\n default:\n return state;\n }\n}\n\nexport interface AppInfo {\n id: string;\n name: string;\n slug?: string;\n icon?: string;\n type?: string;\n version?: string;\n}\n\ninterface InstallAppModalProps {\n isOpen: boolean;\n onClose: () => void;\n app: AppInfo;\n orderId?: string | null; // For purchased apps from orders page\n purchaseState?: 'free' | 'purchased';\n onInstallSuccess?: (workspaceId: string, workspaceName: string) => void;\n onInstallError?: (error: Error) => void;\n}\n\ninterface UseWorkspacesResult {\n workspaces: Workspace[];\n loading: boolean;\n error: Error | null;\n refetch: () => void;\n}\n\n// NOTE: Inline Apollo clients removed. All GraphQL calls now use graphqlFetch\n// from fe-libs which automatically resolves gateway URLs and injects auth + locale headers.\n\n/**\n * Hook to fetch user's workspaces using graphqlFetch from fe-libs\n */\nfunction useWorkspaces(skip: boolean): UseWorkspacesResult {\n const { authToken } = useStore();\n const [workspaces, setWorkspaces] = useState<Workspace[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchWorkspaces = useCallback(async () => {\n if (skip) return;\n\n setLoading(true);\n setError(null);\n\n try {\n const result = await graphqlFetch<{ myWorkspaces: WorkspaceList }>({\n gateway: 'global',\n query: MY_WORKSPACES_STRING,\n authToken: authToken || undefined,\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'GraphQL error');\n }\n\n setWorkspaces(result.data?.myWorkspaces?.items || []);\n } catch (err) {\n setError(err instanceof Error ? err : new Error('Failed to fetch workspaces'));\n } finally {\n setLoading(false);\n }\n }, [authToken, skip]);\n\n useEffect(() => {\n fetchWorkspaces();\n }, [fetchWorkspaces]);\n\n return {\n workspaces,\n loading,\n error,\n refetch: fetchWorkspaces,\n };\n}\n\n/**\n * InstallAppModal component\n *\n * Modal for selecting a workspace to install an app into\n */\nexport const InstallAppModal: FC<InstallAppModalProps> = ({\n isOpen,\n onClose,\n app,\n orderId,\n purchaseState = 'free',\n onInstallSuccess,\n onInstallError,\n}) => {\n const { authToken, user } = useStore();\n const [installState, dispatchInstall] = useReducer(installReducer, initialInstallState);\n const { selectedWorkspace, installing, installError, installInfo } = installState;\n\n const { workspaces, loading, error } = useWorkspaces(!isOpen);\n\n // Filter workspaces by status (only show active)\n const filteredWorkspaces = workspaces.filter((ws) => ws.status === 'ACTIVE');\n\n /**\n * Install purchased app via Store Service (NEW FLOW)\n * Used when installing from orders page or any already-purchased product\n */\n const handleInstallFromStore = async () => {\n if (!selectedWorkspace) return;\n\n const workspace = filteredWorkspaces.find((ws) => ws.id === selectedWorkspace);\n if (!workspace) return;\n const purchasedBy = user?.id;\n\n dispatchInstall({ type: 'startInstall' });\n\n try {\n if (!orderId && purchaseState !== 'purchased') {\n if (!purchasedBy) {\n throw new Error('Unable to identify the current user for license creation');\n }\n\n await graphqlFetch({\n gateway: 'global',\n query: CREATE_PRODUCT_ENTITLEMENT_STRING,\n variables: {\n input: {\n productId: app.id,\n purchasedBy,\n workspaceId: workspace.id,\n metadata: {\n source: 'store-ui',\n productType: app.type,\n },\n },\n },\n authToken: authToken || undefined,\n });\n }\n\n // Call Store Service to install the purchased app\n const result = await graphqlFetch<{\n installPurchasedApp: {\n success: boolean;\n alreadyInstalled?: boolean;\n installation?: {\n id: string;\n productId: string;\n workspaceId: string;\n status: string;\n version: string;\n };\n error?: string;\n message?: string;\n };\n }>({\n gateway: 'global', // Store Service\n query: INSTALL_PURCHASED_APP_STRING,\n variables: {\n orderId: orderId ?? null,\n productId: app.id,\n workspaceId: workspace.id,\n },\n authToken: authToken || undefined,\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Installation failed');\n }\n\n const installResult = result.data?.installPurchasedApp;\n\n if (installResult?.success) {\n if (installResult.alreadyInstalled) {\n dispatchInstall({\n type: 'setInfo',\n info: installResult.message || 'Already installed on this workspace',\n });\n } else {\n onInstallSuccess?.(workspace.id, workspace.name);\n onClose();\n }\n } else {\n const rawMsg = installResult?.error || 'Installation failed';\n const errorMsg = mapInstallError(rawMsg);\n dispatchInstall({ type: 'setError', error: errorMsg });\n onInstallError?.(new Error(rawMsg));\n }\n } catch (err) {\n const rawMsg = err instanceof Error ? err.message : 'Installation failed';\n const errorMsg = mapInstallError(rawMsg);\n dispatchInstall({ type: 'setError', error: errorMsg });\n onInstallError?.(new Error(rawMsg));\n } finally {\n dispatchInstall({ type: 'finishInstall' });\n }\n };\n\n /**\n * Install app via Workspace Service (LEGACY FLOW)\n * Used for free apps or when installing without order\n */\n const handleInstallViaWorkspace = async () => {\n if (!selectedWorkspace) return;\n\n const workspace = filteredWorkspaces.find((ws) => ws.id === selectedWorkspace);\n if (!workspace) return;\n\n dispatchInstall({ type: 'startInstall' });\n\n try {\n // Step 1: Install to workspace service via graphqlFetch\n const installVars = {\n workspaceIds: [workspace.id],\n input: {\n appName: app.slug || app.name.toLowerCase().replace(/\\s+/g, '-'),\n displayName: app.name,\n version: app.version || '1.0.0',\n type: app.type || 'app',\n manifest: {\n productId: app.id,\n icon: app.icon,\n },\n },\n };\n\n const result = await graphqlFetch<{\n installWorkspaceApps: InstallWorkspaceAppsResult;\n }>({\n gateway: 'workspace',\n query: INSTALL_WORKSPACE_APPS_STRING,\n variables: installVars,\n authToken: authToken || undefined,\n workspaceId: workspace.id,\n workspaceToken: true,\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Installation failed');\n }\n\n const installResult = result.data?.installWorkspaceApps;\n if (installResult?.successCount && installResult.successCount > 0) {\n // Step 2: Record installation in store service (for tracking)\n try {\n await graphqlFetch({\n gateway: 'global',\n query: RECORD_APP_INSTALLATION_STRING,\n variables: {\n input: {\n productId: app.id,\n workspaceId: workspace.id,\n workspaceName: workspace.name,\n workspaceType: workspace.type,\n organizationId: workspace.organizationId,\n version: app.version || '1.0.0',\n manifest: {\n productId: app.id,\n icon: app.icon,\n slug: app.slug,\n type: app.type,\n },\n },\n },\n authToken: authToken || undefined,\n });\n } catch {\n // Non-fatal: workspace installation succeeded; store record will sync later.\n }\n\n onInstallSuccess?.(workspace.id, workspace.name);\n onClose();\n } else {\n const rawMsg = installResult?.results?.[0]?.error || 'Installation failed';\n const errorMsg = mapInstallError(rawMsg);\n dispatchInstall({ type: 'setError', error: errorMsg });\n onInstallError?.(new Error(rawMsg));\n }\n } catch (err) {\n const rawMsg = err instanceof Error ? err.message : 'Installation failed';\n const errorMsg = mapInstallError(rawMsg);\n dispatchInstall({ type: 'setError', error: errorMsg });\n onInstallError?.(new Error(rawMsg));\n } finally {\n dispatchInstall({ type: 'finishInstall' });\n }\n };\n\n /**\n * Main install handler - routes to appropriate install function\n */\n const handleInstall = async () => {\n const appType = app.type?.toUpperCase() ?? '';\n\n if (purchaseState === 'purchased' || orderId || STORE_DISTRIBUTED_TYPES.has(appType)) {\n // Purchased products install through the store service.\n await handleInstallFromStore();\n } else {\n // Free products install through the workspace service.\n await handleInstallViaWorkspace();\n }\n };\n\n return (\n <Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>\n <DialogContent className=\"mx-4 w-full max-w-lg gap-0 p-0\">\n {/* Header */}\n <DialogHeader className=\"flex flex-row items-center justify-between space-y-0 border-b border-border-default px-6 py-4 text-left\">\n <div className=\"flex items-center gap-3\">\n {app.icon ? (\n <img src={app.icon} alt={app.name} className=\"size-10 rounded-lg object-cover\" />\n ) : (\n <div className=\"flex size-10 items-center justify-center rounded-lg bg-bg-sunken text-lg font-bold text-text-muted\">\n {app.name.charAt(0)}\n </div>\n )}\n <div>\n <DialogTitle className=\"text-lg font-semibold text-text-primary\">\n Install App\n </DialogTitle>\n <DialogDescription className=\"text-sm text-text-muted\">{app.name}</DialogDescription>\n </div>\n </div>\n </DialogHeader>\n\n {/* Content */}\n <div className=\"px-6 py-4\">\n <p className=\"mb-4 text-text-secondary\">\n Select the workspace where you want to install this app:\n </p>\n\n {/* Workspace List */}\n <div className=\"max-h-72 overflow-y-auto rounded-lg border border-border-seam\">\n {loading ? (\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"size-8 animate-spin text-text-muted\" />\n </div>\n ) : error ? (\n <div className=\"flex flex-col items-center justify-center py-12 text-center\">\n <AlertCircle className=\"mb-2 size-8 text-status-error-text\" />\n <p className=\"text-sm text-status-error-text\">Failed to load workspaces</p>\n <p className=\"text-xs text-text-muted mt-1\">{error.message}</p>\n </div>\n ) : filteredWorkspaces.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center py-12 text-center\">\n <Building2 className=\"mb-2 size-8 text-text-muted\" />\n <p className=\"text-sm text-text-muted\">No workspaces available</p>\n </div>\n ) : (\n <div className=\"divide-y divide-border-default\">\n {filteredWorkspaces.map((workspace) => (\n <button\n type=\"button\"\n key={workspace.id}\n onClick={() =>\n dispatchInstall({ type: 'selectWorkspace', workspaceId: workspace.id })\n }\n className={`w-full cursor-pointer flex items-center gap-3 px-4 py-3 text-left transition-colors ${\n selectedWorkspace === workspace.id\n ? 'bg-action-primary-bg/10'\n : 'transition-colors hover:bg-bg-sunken'\n }`}\n >\n {/* Workspace Icon */}\n <div className=\"flex size-10 items-center justify-center rounded-lg bg-action-primary-bg/10 text-text-link\">\n <Building2 className=\"size-5\" />\n </div>\n\n {/* Workspace Info */}\n <div className=\"flex-1 min-w-0\">\n <p className=\"font-medium text-text-primary truncate\">{workspace.name}</p>\n {workspace.slug ? (\n <p className=\"text-xs text-text-muted truncate\">/{workspace.slug}</p>\n ) : null}\n </div>\n\n {/* Selection Indicator */}\n {selectedWorkspace === workspace.id && (\n <CheckCircle className=\"size-5 flex-shrink-0 text-action-primary-bg\" />\n )}\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n\n {/* Footer */}\n <DialogFooter className=\"block border-t border-border-default px-6 py-4 sm:flex-col sm:items-stretch sm:space-x-0\">\n {/* Already-installed info */}\n {installInfo && (\n <div className=\"mb-3 flex items-center gap-2 rounded-lg bg-status-info-bg-subtle px-3 py-2 text-sm text-status-info-text\">\n <Info className=\"size-4 flex-shrink-0\" />\n <span>{installInfo}</span>\n </div>\n )}\n {/* Error message */}\n {installError && (\n <div className=\"mb-3 flex items-center gap-2 rounded-lg bg-status-error-bg-subtle/10 px-3 py-2 text-sm text-status-error-text\">\n <AlertCircle className=\"size-4 flex-shrink-0\" />\n <span>{installError}</span>\n </div>\n )}\n <div className=\"flex items-center justify-end gap-3\">\n <button\n type=\"button\"\n onClick={onClose}\n disabled={installing}\n className=\"cursor-pointer rounded-lg border border-border-default px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken disabled:opacity-50\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={handleInstall}\n disabled={!selectedWorkspace || installing}\n className=\"cursor-pointer rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-opacity hover:opacity-90 disabled:opacity-50 disabled:cursor-not-allowed inline-flex items-center gap-2\"\n >\n {installing ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n Installing…\n </>\n ) : (\n 'Install App'\n )}\n </button>\n </div>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n};\n"],"mappings":"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"}
@@ -13,7 +13,7 @@ var l = ({ isOpen: l, onClose: u, onCheckout: d, cartItems: f, itemCount: p, sub
13
13
  className: "flex h-full flex-col",
14
14
  children: [
15
15
  /* @__PURE__ */ c("div", {
16
- className: "flex items-center justify-between border-b border-border-default px-4 sm:px-6 py-4",
16
+ className: "flex items-center justify-between border-b border-border-seam px-4 sm:px-6 py-4",
17
17
  children: [/* @__PURE__ */ c("div", {
18
18
  className: "flex items-center gap-2",
19
19
  children: [
@@ -23,7 +23,7 @@ var l = ({ isOpen: l, onClose: u, onCheckout: d, cartItems: f, itemCount: p, sub
23
23
  children: "Shopping Cart"
24
24
  }),
25
25
  p > 0 && /* @__PURE__ */ s("span", {
26
- className: "rounded-full bg-bg-accent px-2 py-0.5 text-xs font-medium text-text-link",
26
+ className: "rounded-full bg-bg-accent px-2 py-0.5 text-xs font-medium tabular-nums text-text-link",
27
27
  children: p
28
28
  })
29
29
  ]
@@ -57,7 +57,7 @@ var l = ({ isOpen: l, onClose: u, onCheckout: d, cartItems: f, itemCount: p, sub
57
57
  }) : /* @__PURE__ */ s("div", {
58
58
  className: "space-y-4",
59
59
  children: f.map((a) => /* @__PURE__ */ c("div", {
60
- className: "flex gap-4 rounded-lg border border-border-default p-4",
60
+ className: "flex gap-4 rounded-lg border border-border-seam bg-bg-surface p-4 transition-[box-shadow,border-color] hover:border-border-strong hover:shadow-[var(--shadow-pop)]",
61
61
  children: [/* @__PURE__ */ s("div", {
62
62
  className: "size-20 flex-shrink-0 overflow-hidden rounded bg-bg-sunken",
63
63
  children: a.productIcon || a.product?.icon ? /* @__PURE__ */ s("img", {
@@ -125,7 +125,7 @@ var l = ({ isOpen: l, onClose: u, onCheckout: d, cartItems: f, itemCount: p, sub
125
125
  /* @__PURE__ */ s("div", {
126
126
  className: "mt-2 text-right",
127
127
  children: /* @__PURE__ */ s("span", {
128
- className: "font-semibold text-text-primary",
128
+ className: "font-semibold tabular-nums text-text-primary",
129
129
  children: e(a.subtotal)
130
130
  })
131
131
  })
@@ -135,7 +135,7 @@ var l = ({ isOpen: l, onClose: u, onCheckout: d, cartItems: f, itemCount: p, sub
135
135
  })
136
136
  }),
137
137
  f.length > 0 && /* @__PURE__ */ c("div", {
138
- className: "border-t border-border-default bg-bg-sunken px-4 sm:px-6 py-4",
138
+ className: "border-t border-border-seam bg-accent-wash px-4 sm:px-6 py-4",
139
139
  children: [/* @__PURE__ */ c("div", {
140
140
  className: "space-y-2",
141
141
  children: [
@@ -145,7 +145,7 @@ var l = ({ isOpen: l, onClose: u, onCheckout: d, cartItems: f, itemCount: p, sub
145
145
  className: "text-text-muted",
146
146
  children: "Subtotal"
147
147
  }), /* @__PURE__ */ s("span", {
148
- className: "font-medium text-text-primary",
148
+ className: "font-medium tabular-nums text-text-primary",
149
149
  children: e(m)
150
150
  })]
151
151
  }),
@@ -155,17 +155,17 @@ var l = ({ isOpen: l, onClose: u, onCheckout: d, cartItems: f, itemCount: p, sub
155
155
  className: "text-text-muted",
156
156
  children: "Tax"
157
157
  }), /* @__PURE__ */ s("span", {
158
- className: "font-medium text-text-primary",
158
+ className: "font-medium tabular-nums text-text-primary",
159
159
  children: e(h)
160
160
  })]
161
161
  }),
162
162
  /* @__PURE__ */ c("div", {
163
- className: "flex justify-between border-t border-border-default pt-2",
163
+ className: "flex justify-between border-t border-border-seam pt-2",
164
164
  children: [/* @__PURE__ */ s("span", {
165
165
  className: "font-semibold text-text-primary",
166
166
  children: "Total"
167
167
  }), /* @__PURE__ */ s("span", {
168
- className: "text-lg font-bold text-text-primary",
168
+ className: "text-lg font-bold tabular-nums text-text-primary",
169
169
  children: e(g)
170
170
  })]
171
171
  })
@@ -173,7 +173,7 @@ var l = ({ isOpen: l, onClose: u, onCheckout: d, cartItems: f, itemCount: p, sub
173
173
  }), /* @__PURE__ */ s("button", {
174
174
  type: "button",
175
175
  onClick: d,
176
- className: "cursor-pointer mt-4 w-full rounded-lg bg-action-primary-bg py-3 font-bold text-action-primary-text shadow-lg transition-all hover:opacity-90 hover:shadow-xl active:scale-[0.98]",
176
+ className: "cursor-pointer mt-4 w-full rounded-lg bg-action-primary-bg py-3 font-bold text-action-primary-text shadow-elevation-1 transition-[opacity,box-shadow] hover:opacity-90 hover:shadow-[var(--shadow-pop)]",
177
177
  children: "Proceed to Checkout"
178
178
  })]
179
179
  })
@@ -1 +1 @@
1
- {"version":3,"file":"CartDrawer.js","names":[],"sources":["../../../src/components/cart/CartDrawer.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { X, ShoppingCart, Trash2, Plus, Minus } from 'lucide-react';\nimport { formatPrice } from '../../utils';\n\n/**\n * Props for CartDrawer\n */\ninterface CartDrawerProps {\n isOpen: boolean;\n onClose: () => void;\n onCheckout: () => void;\n cartItems: Array<{\n id: string;\n quantity: number;\n subtotal: number;\n productName?: string;\n productIcon?: string;\n variantName?: string;\n product?: { icon?: string; name?: string };\n }>;\n itemCount: number;\n subtotal: number;\n tax: number;\n total: number;\n updateQuantity: (cartItemId: string, quantity: number) => Promise<void>;\n removeProduct: (cartItemId: string) => Promise<void>;\n}\n\n/**\n * CartDrawer component\n *\n * Sliding drawer for cart management\n */\nexport const CartDrawer: FC<CartDrawerProps> = ({\n isOpen,\n onClose,\n onCheckout,\n cartItems,\n itemCount,\n subtotal,\n tax,\n total,\n updateQuantity,\n removeProduct,\n}) => {\n if (!isOpen) return null;\n\n return (\n <>\n {/* Backdrop */}\n <button\n type=\"button\"\n aria-label=\"Close cart\"\n className=\"fixed inset-0 z-40 bg-bg-overlay/50 transition-opacity\"\n onClick={onClose}\n />\n\n {/* Drawer */}\n <div className=\"fixed right-0 top-0 z-50 size-full sm:max-w-md bg-bg-surface shadow-xl\">\n <div className=\"flex h-full flex-col\">\n {/* Header */}\n <div className=\"flex items-center justify-between border-b border-border-default px-4 sm:px-6 py-4\">\n <div className=\"flex items-center gap-2\">\n <ShoppingCart className=\"size-5 text-text-primary\" />\n <h2 className=\"text-lg font-semibold text-text-primary\">Shopping Cart</h2>\n {itemCount > 0 && (\n <span className=\"rounded-full bg-bg-accent px-2 py-0.5 text-xs font-medium text-text-link\">\n {itemCount}\n </span>\n )}\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n aria-label=\"Close cart\"\n className=\"cursor-pointer rounded-lg p-2 text-text-muted transition-colors hover:bg-bg-sunken hover:text-text-primary\"\n >\n <X className=\"size-5\" />\n </button>\n </div>\n\n {/* Cart Items */}\n <div className=\"flex-1 overflow-y-auto px-4 sm:px-6 py-4\">\n {cartItems.length === 0 ? (\n <output\n aria-label=\"Your cart is empty\"\n className=\"flex h-full flex-col items-center justify-center text-center\"\n >\n <ShoppingCart className=\"mb-4 size-16 text-text-muted\" aria-hidden=\"true\" />\n <h3 className=\"mb-2 text-lg font-semibold text-text-primary\">Your cart is empty</h3>\n <p className=\"text-sm text-text-muted\">Start shopping to add items to your cart</p>\n </output>\n ) : (\n <div className=\"space-y-4\">\n {cartItems.map((item) => (\n <div\n key={item.id}\n className=\"flex gap-4 rounded-lg border border-border-default p-4\"\n >\n {/* Product Image */}\n <div className=\"size-20 flex-shrink-0 overflow-hidden rounded bg-bg-sunken\">\n {item.productIcon || item.product?.icon ? (\n <img\n src={item.productIcon || item.product?.icon}\n alt={item.productName || item.product?.name}\n className=\"size-full object-cover\"\n />\n ) : (\n <div className=\"flex size-full items-center justify-center\">\n <ShoppingCart className=\"size-8 text-text-muted\" />\n </div>\n )}\n </div>\n\n {/* Product Info */}\n <div className=\"flex flex-1 flex-col\">\n <h4 className=\"mb-1 font-semibold text-text-primary\">\n {item.productName || item.product?.name || 'Product'}\n </h4>\n {item.variantName && (\n <p className=\"mb-2 text-xs text-text-muted\">{item.variantName}</p>\n )}\n\n {/* Quantity Controls */}\n <div className=\"flex items-center gap-3\">\n <div className=\"flex items-center rounded border border-border-default\">\n <button\n type=\"button\"\n onClick={() => updateQuantity(item.id, item.quantity - 1)}\n aria-label={`Decrease quantity of ${item.productName || item.product?.name || 'item'}`}\n className=\"cursor-pointer p-1.5 transition-colors hover:bg-bg-sunken disabled:cursor-not-allowed disabled:opacity-50\"\n disabled={item.quantity <= 1}\n >\n <Minus className=\"size-4\" aria-hidden=\"true\" />\n </button>\n <span\n className=\"min-w-[2rem] text-center text-sm font-medium\"\n aria-label={`Quantity: ${item.quantity}`}\n >\n {item.quantity}\n </span>\n <button\n type=\"button\"\n onClick={() => updateQuantity(item.id, item.quantity + 1)}\n aria-label={`Increase quantity of ${item.productName || item.product?.name || 'item'}`}\n className=\"cursor-pointer p-1.5 transition-colors hover:bg-bg-sunken\"\n >\n <Plus className=\"size-4\" aria-hidden=\"true\" />\n </button>\n </div>\n\n <button\n type=\"button\"\n onClick={() => removeProduct(item.id)}\n aria-label={`Remove ${item.productName || item.product?.name || 'item'} from cart`}\n className=\"cursor-pointer ml-auto text-status-error-text transition-colors hover:text-status-error-text-emphasis\"\n >\n <Trash2 className=\"size-4\" aria-hidden=\"true\" />\n </button>\n </div>\n\n {/* Price */}\n <div className=\"mt-2 text-right\">\n <span className=\"font-semibold text-text-primary\">\n {formatPrice(item.subtotal)}\n </span>\n </div>\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n\n {/* Footer with Summary */}\n {cartItems.length > 0 && (\n <div className=\"border-t border-border-default bg-bg-sunken px-4 sm:px-6 py-4\">\n <div className=\"space-y-2\">\n <div className=\"flex justify-between text-sm\">\n <span className=\"text-text-muted\">Subtotal</span>\n <span className=\"font-medium text-text-primary\">{formatPrice(subtotal)}</span>\n </div>\n <div className=\"flex justify-between text-sm\">\n <span className=\"text-text-muted\">Tax</span>\n <span className=\"font-medium text-text-primary\">{formatPrice(tax)}</span>\n </div>\n <div className=\"flex justify-between border-t border-border-default pt-2\">\n <span className=\"font-semibold text-text-primary\">Total</span>\n <span className=\"text-lg font-bold text-text-primary\">{formatPrice(total)}</span>\n </div>\n </div>\n\n <button\n type=\"button\"\n onClick={onCheckout}\n className=\"cursor-pointer mt-4 w-full rounded-lg bg-action-primary-bg py-3 font-bold text-action-primary-text shadow-lg transition-all hover:opacity-90 hover:shadow-xl active:scale-[0.98]\"\n >\n Proceed to Checkout\n </button>\n </div>\n )}\n </div>\n </div>\n </>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"CartDrawer.js","names":[],"sources":["../../../src/components/cart/CartDrawer.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { X, ShoppingCart, Trash2, Plus, Minus } from 'lucide-react';\nimport { formatPrice } from '../../utils';\n\n/**\n * Props for CartDrawer\n */\ninterface CartDrawerProps {\n isOpen: boolean;\n onClose: () => void;\n onCheckout: () => void;\n cartItems: Array<{\n id: string;\n quantity: number;\n subtotal: number;\n productName?: string;\n productIcon?: string;\n variantName?: string;\n product?: { icon?: string; name?: string };\n }>;\n itemCount: number;\n subtotal: number;\n tax: number;\n total: number;\n updateQuantity: (cartItemId: string, quantity: number) => Promise<void>;\n removeProduct: (cartItemId: string) => Promise<void>;\n}\n\n/**\n * CartDrawer component\n *\n * Sliding drawer for cart management\n */\nexport const CartDrawer: FC<CartDrawerProps> = ({\n isOpen,\n onClose,\n onCheckout,\n cartItems,\n itemCount,\n subtotal,\n tax,\n total,\n updateQuantity,\n removeProduct,\n}) => {\n if (!isOpen) return null;\n\n return (\n <>\n {/* Backdrop */}\n <button\n type=\"button\"\n aria-label=\"Close cart\"\n className=\"fixed inset-0 z-40 bg-bg-overlay/50 transition-opacity\"\n onClick={onClose}\n />\n\n {/* Drawer */}\n <div className=\"fixed right-0 top-0 z-50 size-full sm:max-w-md bg-bg-surface shadow-xl\">\n <div className=\"flex h-full flex-col\">\n {/* Header */}\n <div className=\"flex items-center justify-between border-b border-border-seam px-4 sm:px-6 py-4\">\n <div className=\"flex items-center gap-2\">\n <ShoppingCart className=\"size-5 text-text-primary\" />\n <h2 className=\"text-lg font-semibold text-text-primary\">Shopping Cart</h2>\n {itemCount > 0 && (\n <span className=\"rounded-full bg-bg-accent px-2 py-0.5 text-xs font-medium tabular-nums text-text-link\">\n {itemCount}\n </span>\n )}\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n aria-label=\"Close cart\"\n className=\"cursor-pointer rounded-lg p-2 text-text-muted transition-colors hover:bg-bg-sunken hover:text-text-primary\"\n >\n <X className=\"size-5\" />\n </button>\n </div>\n\n {/* Cart Items */}\n <div className=\"flex-1 overflow-y-auto px-4 sm:px-6 py-4\">\n {cartItems.length === 0 ? (\n <output\n aria-label=\"Your cart is empty\"\n className=\"flex h-full flex-col items-center justify-center text-center\"\n >\n <ShoppingCart className=\"mb-4 size-16 text-text-muted\" aria-hidden=\"true\" />\n <h3 className=\"mb-2 text-lg font-semibold text-text-primary\">Your cart is empty</h3>\n <p className=\"text-sm text-text-muted\">Start shopping to add items to your cart</p>\n </output>\n ) : (\n <div className=\"space-y-4\">\n {cartItems.map((item) => (\n <div\n key={item.id}\n className=\"flex gap-4 rounded-lg border border-border-seam bg-bg-surface p-4 transition-[box-shadow,border-color] hover:border-border-strong hover:shadow-[var(--shadow-pop)]\"\n >\n {/* Product Image */}\n <div className=\"size-20 flex-shrink-0 overflow-hidden rounded bg-bg-sunken\">\n {item.productIcon || item.product?.icon ? (\n <img\n src={item.productIcon || item.product?.icon}\n alt={item.productName || item.product?.name}\n className=\"size-full object-cover\"\n />\n ) : (\n <div className=\"flex size-full items-center justify-center\">\n <ShoppingCart className=\"size-8 text-text-muted\" />\n </div>\n )}\n </div>\n\n {/* Product Info */}\n <div className=\"flex flex-1 flex-col\">\n <h4 className=\"mb-1 font-semibold text-text-primary\">\n {item.productName || item.product?.name || 'Product'}\n </h4>\n {item.variantName && (\n <p className=\"mb-2 text-xs text-text-muted\">{item.variantName}</p>\n )}\n\n {/* Quantity Controls */}\n <div className=\"flex items-center gap-3\">\n <div className=\"flex items-center rounded border border-border-default\">\n <button\n type=\"button\"\n onClick={() => updateQuantity(item.id, item.quantity - 1)}\n aria-label={`Decrease quantity of ${item.productName || item.product?.name || 'item'}`}\n className=\"cursor-pointer p-1.5 transition-colors hover:bg-bg-sunken disabled:cursor-not-allowed disabled:opacity-50\"\n disabled={item.quantity <= 1}\n >\n <Minus className=\"size-4\" aria-hidden=\"true\" />\n </button>\n <span\n className=\"min-w-[2rem] text-center text-sm font-medium\"\n aria-label={`Quantity: ${item.quantity}`}\n >\n {item.quantity}\n </span>\n <button\n type=\"button\"\n onClick={() => updateQuantity(item.id, item.quantity + 1)}\n aria-label={`Increase quantity of ${item.productName || item.product?.name || 'item'}`}\n className=\"cursor-pointer p-1.5 transition-colors hover:bg-bg-sunken\"\n >\n <Plus className=\"size-4\" aria-hidden=\"true\" />\n </button>\n </div>\n\n <button\n type=\"button\"\n onClick={() => removeProduct(item.id)}\n aria-label={`Remove ${item.productName || item.product?.name || 'item'} from cart`}\n className=\"cursor-pointer ml-auto text-status-error-text transition-colors hover:text-status-error-text-emphasis\"\n >\n <Trash2 className=\"size-4\" aria-hidden=\"true\" />\n </button>\n </div>\n\n {/* Price */}\n <div className=\"mt-2 text-right\">\n <span className=\"font-semibold tabular-nums text-text-primary\">\n {formatPrice(item.subtotal)}\n </span>\n </div>\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n\n {/* Footer with Summary */}\n {cartItems.length > 0 && (\n <div className=\"border-t border-border-seam bg-accent-wash px-4 sm:px-6 py-4\">\n <div className=\"space-y-2\">\n <div className=\"flex justify-between text-sm\">\n <span className=\"text-text-muted\">Subtotal</span>\n <span className=\"font-medium tabular-nums text-text-primary\">\n {formatPrice(subtotal)}\n </span>\n </div>\n <div className=\"flex justify-between text-sm\">\n <span className=\"text-text-muted\">Tax</span>\n <span className=\"font-medium tabular-nums text-text-primary\">\n {formatPrice(tax)}\n </span>\n </div>\n <div className=\"flex justify-between border-t border-border-seam pt-2\">\n <span className=\"font-semibold text-text-primary\">Total</span>\n <span className=\"text-lg font-bold tabular-nums text-text-primary\">\n {formatPrice(total)}\n </span>\n </div>\n </div>\n\n <button\n type=\"button\"\n onClick={onCheckout}\n className=\"cursor-pointer mt-4 w-full rounded-lg bg-action-primary-bg py-3 font-bold text-action-primary-text shadow-elevation-1 transition-[opacity,box-shadow] hover:opacity-90 hover:shadow-[var(--shadow-pop)]\"\n >\n Proceed to Checkout\n </button>\n </div>\n )}\n </div>\n </div>\n </>\n );\n};\n"],"mappings":"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"}