@burdenoff/microfe-store 2026.625.1 → 2026.625.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 (184) hide show
  1. package/dist/StoreRoutes.js +3 -3
  2. package/dist/StoreRoutes.js.map +1 -1
  3. package/dist/components/AccessDenied.js +3 -3
  4. package/dist/components/AccessDenied.js.map +1 -1
  5. package/dist/components/InstallAppModal.js +120 -107
  6. package/dist/components/InstallAppModal.js.map +1 -1
  7. package/dist/components/cart/CartDrawer.js +10 -10
  8. package/dist/components/cart/CartDrawer.js.map +1 -1
  9. package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/errors/CombinedGraphQLErrors.js +1 -1
  10. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/errors/CombinedGraphQLErrors.js.map +1 -0
  11. package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/errors/utils.js +1 -1
  12. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/errors/utils.js.map +1 -0
  13. package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/link/core/ApolloLink.js +2 -2
  14. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/link/core/ApolloLink.js.map +1 -0
  15. package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/link/subscriptions/index.js +2 -2
  16. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/link/subscriptions/index.js.map +1 -0
  17. package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/link/utils/createOperation.js +1 -1
  18. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/link/utils/createOperation.js.map +1 -0
  19. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/caching/sizes.js.map +1 -0
  20. package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/graphql/print.js +1 -1
  21. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/graphql/print.js.map +1 -0
  22. package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/caches.js +2 -2
  23. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/caches.js.map +1 -0
  24. package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/checkDocument.js +1 -1
  25. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/checkDocument.js.map +1 -0
  26. package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/getMainDefinition.js +1 -1
  27. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getMainDefinition.js.map +1 -0
  28. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js +9 -0
  29. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js.map +1 -0
  30. package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/getOperationDefinition.js +1 -1
  31. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getOperationDefinition.js.map +1 -0
  32. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getOperationName.js +8 -0
  33. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getOperationName.js.map +1 -0
  34. package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/globals/global.js +1 -1
  35. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/globals/global.js.map +1 -0
  36. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/globals/maybe.js +10 -0
  37. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/globals/maybe.js.map +1 -0
  38. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/isNonNullObject.js +8 -0
  39. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/isNonNullObject.js.map +1 -0
  40. package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/makeUniqueId.js +1 -1
  41. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/makeUniqueId.js.map +1 -0
  42. package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/memoize.js +2 -2
  43. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/memoize.js.map +1 -0
  44. package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/stringifyForDisplay.js +1 -1
  45. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/stringifyForDisplay.js.map +1 -0
  46. package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/invariant/index.js +1 -1
  47. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/invariant/index.js.map +1 -0
  48. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/version.js +6 -0
  49. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/version.js.map +1 -0
  50. package/dist/node_modules/{@wry → .bun/@wry_caches@1.0.1/node_modules/@wry}/caches/lib/weak.js +1 -1
  51. package/dist/node_modules/.bun/@wry_caches@1.0.1/node_modules/@wry/caches/lib/weak.js.map +1 -0
  52. package/dist/node_modules/{@wry → .bun/@wry_trie@0.5.0/node_modules/@wry}/trie/lib/index.js +1 -1
  53. package/dist/node_modules/.bun/@wry_trie@0.5.0/node_modules/@wry/trie/lib/index.js.map +1 -0
  54. package/dist/node_modules/{graphql-ws → .bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws}/dist/client.js +1 -1
  55. package/dist/node_modules/.bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws/dist/client.js.map +1 -0
  56. package/dist/node_modules/{graphql-ws → .bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws}/dist/common-CGW11Fyb.js +1 -1
  57. package/dist/node_modules/.bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws/dist/common-CGW11Fyb.js.map +1 -0
  58. package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/NotificationFactories.js +1 -1
  59. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/NotificationFactories.js.map +1 -0
  60. package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/Observable.js +1 -1
  61. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/Observable.js.map +1 -0
  62. package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/Subscriber.js +2 -2
  63. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/Subscriber.js.map +1 -0
  64. package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/Subscription.js +2 -2
  65. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/Subscription.js.map +1 -0
  66. package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/config.js +1 -1
  67. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/config.js.map +1 -0
  68. package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/observable/empty.js +1 -1
  69. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/observable/empty.js.map +1 -0
  70. package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/scheduler/timeoutProvider.js +2 -2
  71. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/scheduler/timeoutProvider.js.map +1 -0
  72. package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/symbol/observable.js +1 -1
  73. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/symbol/observable.js.map +1 -0
  74. package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/util/UnsubscriptionError.js +1 -1
  75. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/UnsubscriptionError.js.map +1 -0
  76. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js +11 -0
  77. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js.map +1 -0
  78. package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/util/createErrorClass.js +1 -1
  79. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/createErrorClass.js.map +1 -0
  80. package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/util/errorContext.js +1 -1
  81. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/errorContext.js.map +1 -0
  82. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/identity.js +8 -0
  83. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/identity.js.map +1 -0
  84. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/isFunction.js +8 -0
  85. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/isFunction.js.map +1 -0
  86. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/noop.js +6 -0
  87. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/noop.js.map +1 -0
  88. package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/util/pipe.js +1 -1
  89. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/pipe.js.map +1 -0
  90. package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/util/reportUnhandledError.js +1 -1
  91. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/reportUnhandledError.js.map +1 -0
  92. package/dist/node_modules/{rxjs → .bun/tslib@2.8.1}/node_modules/tslib/tslib.es6.js +1 -1
  93. package/dist/node_modules/.bun/tslib@2.8.1/node_modules/tslib/tslib.es6.js.map +1 -0
  94. package/dist/pages/AdminDashboardPage.js +89 -90
  95. package/dist/pages/AdminDashboardPage.js.map +1 -1
  96. package/dist/pages/AdminReviewModerationPage.js +56 -58
  97. package/dist/pages/AdminReviewModerationPage.js.map +1 -1
  98. package/dist/pages/AdminStoresPage.js +372 -391
  99. package/dist/pages/AdminStoresPage.js.map +1 -1
  100. package/dist/pages/AdminSubmissionsQueuePage.js +148 -134
  101. package/dist/pages/AdminSubmissionsQueuePage.js.map +1 -1
  102. package/dist/pages/AppDetailPage.js +120 -123
  103. package/dist/pages/AppDetailPage.js.map +1 -1
  104. package/dist/pages/AppSettingsPage.js +297 -70
  105. package/dist/pages/AppSettingsPage.js.map +1 -1
  106. package/dist/pages/CartPage.js +59 -60
  107. package/dist/pages/CartPage.js.map +1 -1
  108. package/dist/pages/InstalledAppsPage.js +100 -71
  109. package/dist/pages/InstalledAppsPage.js.map +1 -1
  110. package/dist/pages/MarketplaceHomePage.js +175 -176
  111. package/dist/pages/MarketplaceHomePage.js.map +1 -1
  112. package/dist/pages/MyLicensesPage.js +33 -34
  113. package/dist/pages/MyLicensesPage.js.map +1 -1
  114. package/dist/pages/OrderConfirmationPage.js +37 -38
  115. package/dist/pages/OrderConfirmationPage.js.map +1 -1
  116. package/dist/pages/OrdersPage.js +19 -20
  117. package/dist/pages/OrdersPage.js.map +1 -1
  118. package/dist/pages/ProductDetailPage.js +98 -101
  119. package/dist/pages/ProductDetailPage.js.map +1 -1
  120. package/dist/pages/ProductReviewsPage.js +2 -2
  121. package/dist/pages/ProductReviewsPage.js.map +1 -1
  122. package/dist/pages/PublisherDashboardPage.js +92 -93
  123. package/dist/pages/PublisherDashboardPage.js.map +1 -1
  124. package/dist/pages/PublisherRevenuePage.js +60 -61
  125. package/dist/pages/PublisherRevenuePage.js.map +1 -1
  126. package/dist/pages/PublisherSubmissionsPage.js +96 -97
  127. package/dist/pages/PublisherSubmissionsPage.js.map +1 -1
  128. package/dist/pages/PublisherSubmitPage.js +184 -189
  129. package/dist/pages/PublisherSubmitPage.js.map +1 -1
  130. package/dist/providers/StoreProvider.js +3 -3
  131. package/package.json +2 -2
  132. package/dist/node_modules/@apollo/client/errors/CombinedGraphQLErrors.js.map +0 -1
  133. package/dist/node_modules/@apollo/client/errors/utils.js.map +0 -1
  134. package/dist/node_modules/@apollo/client/link/core/ApolloLink.js.map +0 -1
  135. package/dist/node_modules/@apollo/client/link/subscriptions/index.js.map +0 -1
  136. package/dist/node_modules/@apollo/client/link/utils/createOperation.js.map +0 -1
  137. package/dist/node_modules/@apollo/client/utilities/caching/sizes.js.map +0 -1
  138. package/dist/node_modules/@apollo/client/utilities/graphql/print.js.map +0 -1
  139. package/dist/node_modules/@apollo/client/utilities/internal/caches.js.map +0 -1
  140. package/dist/node_modules/@apollo/client/utilities/internal/checkDocument.js.map +0 -1
  141. package/dist/node_modules/@apollo/client/utilities/internal/getMainDefinition.js.map +0 -1
  142. package/dist/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js +0 -9
  143. package/dist/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js.map +0 -1
  144. package/dist/node_modules/@apollo/client/utilities/internal/getOperationDefinition.js.map +0 -1
  145. package/dist/node_modules/@apollo/client/utilities/internal/getOperationName.js +0 -8
  146. package/dist/node_modules/@apollo/client/utilities/internal/getOperationName.js.map +0 -1
  147. package/dist/node_modules/@apollo/client/utilities/internal/globals/global.js.map +0 -1
  148. package/dist/node_modules/@apollo/client/utilities/internal/globals/maybe.js +0 -10
  149. package/dist/node_modules/@apollo/client/utilities/internal/globals/maybe.js.map +0 -1
  150. package/dist/node_modules/@apollo/client/utilities/internal/isNonNullObject.js +0 -8
  151. package/dist/node_modules/@apollo/client/utilities/internal/isNonNullObject.js.map +0 -1
  152. package/dist/node_modules/@apollo/client/utilities/internal/makeUniqueId.js.map +0 -1
  153. package/dist/node_modules/@apollo/client/utilities/internal/memoize.js.map +0 -1
  154. package/dist/node_modules/@apollo/client/utilities/internal/stringifyForDisplay.js.map +0 -1
  155. package/dist/node_modules/@apollo/client/utilities/invariant/index.js.map +0 -1
  156. package/dist/node_modules/@apollo/client/version.js +0 -6
  157. package/dist/node_modules/@apollo/client/version.js.map +0 -1
  158. package/dist/node_modules/@wry/caches/lib/weak.js.map +0 -1
  159. package/dist/node_modules/@wry/trie/lib/index.js.map +0 -1
  160. package/dist/node_modules/graphql-ws/dist/client.js.map +0 -1
  161. package/dist/node_modules/graphql-ws/dist/common-CGW11Fyb.js.map +0 -1
  162. package/dist/node_modules/rxjs/dist/esm5/internal/NotificationFactories.js.map +0 -1
  163. package/dist/node_modules/rxjs/dist/esm5/internal/Observable.js.map +0 -1
  164. package/dist/node_modules/rxjs/dist/esm5/internal/Subscriber.js.map +0 -1
  165. package/dist/node_modules/rxjs/dist/esm5/internal/Subscription.js.map +0 -1
  166. package/dist/node_modules/rxjs/dist/esm5/internal/config.js.map +0 -1
  167. package/dist/node_modules/rxjs/dist/esm5/internal/observable/empty.js.map +0 -1
  168. package/dist/node_modules/rxjs/dist/esm5/internal/scheduler/timeoutProvider.js.map +0 -1
  169. package/dist/node_modules/rxjs/dist/esm5/internal/symbol/observable.js.map +0 -1
  170. package/dist/node_modules/rxjs/dist/esm5/internal/util/UnsubscriptionError.js.map +0 -1
  171. package/dist/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js +0 -11
  172. package/dist/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js.map +0 -1
  173. package/dist/node_modules/rxjs/dist/esm5/internal/util/createErrorClass.js.map +0 -1
  174. package/dist/node_modules/rxjs/dist/esm5/internal/util/errorContext.js.map +0 -1
  175. package/dist/node_modules/rxjs/dist/esm5/internal/util/identity.js +0 -8
  176. package/dist/node_modules/rxjs/dist/esm5/internal/util/identity.js.map +0 -1
  177. package/dist/node_modules/rxjs/dist/esm5/internal/util/isFunction.js +0 -8
  178. package/dist/node_modules/rxjs/dist/esm5/internal/util/isFunction.js.map +0 -1
  179. package/dist/node_modules/rxjs/dist/esm5/internal/util/noop.js +0 -6
  180. package/dist/node_modules/rxjs/dist/esm5/internal/util/noop.js.map +0 -1
  181. package/dist/node_modules/rxjs/dist/esm5/internal/util/pipe.js.map +0 -1
  182. package/dist/node_modules/rxjs/dist/esm5/internal/util/reportUnhandledError.js.map +0 -1
  183. package/dist/node_modules/rxjs/node_modules/tslib/tslib.es6.js.map +0 -1
  184. /package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/caching/sizes.js +0 -0
@@ -7,21 +7,20 @@ import { ArrowLeft as a, Loader2 as o, Minus as s, Plus as c, ShoppingBag as l,
7
7
  import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
8
8
  import { useNavigate as _ } from "react-router-dom";
9
9
  import { isQuotaExhaustedError as v } from "@burdenoff/fe-libs/shared/utils";
10
- import { EmphasisPanel as y } from "@burdenoff/fe-libs/ui";
11
- import { useEventBus as b } from "@burdenoff/fe-libs/shared/events";
12
- import { useQuotaErrorToast as x } from "@burdenoff/fe-libs/shared/hooks";
10
+ import { useEventBus as y } from "@burdenoff/fe-libs/shared/events";
11
+ import { useQuotaErrorToast as b } from "@burdenoff/fe-libs/shared/hooks";
13
12
  //#region src/pages/CartPage.tsx
14
- var S = () => {
15
- let S = _(), { basePath: C } = e(), { cartItems: w, itemCount: T, total: E, updateQuantity: D, removeProduct: O, clearCart: k, createOrder: A } = t(), [j, M] = r(!1), [N, P] = r(null), { t: F } = i(), I = b(), { report: L } = x(), R = async () => {
13
+ var x = () => {
14
+ let x = _(), { basePath: S } = e(), { cartItems: C, itemCount: w, total: T, updateQuantity: E, removeProduct: D, clearCart: O, createOrder: k } = t(), [A, j] = r(!1), [M, N] = r(null), { t: P } = i(), F = y(), { report: I } = b(), L = async () => {
16
15
  try {
17
- M(!0), P(null), I.emit("store.cart.checkout_started", {
16
+ j(!0), N(null), F.emit("store.cart.checkout_started", {
18
17
  cartId: "",
19
- itemCount: T,
20
- total: E
18
+ itemCount: w,
19
+ total: T
21
20
  });
22
- let e = await A({
23
- total: E,
24
- lineItems: w.map((e) => ({
21
+ let e = await k({
22
+ total: T,
23
+ lineItems: C.map((e) => ({
25
24
  productId: e.productId,
26
25
  name: e.product?.displayName || "Product",
27
26
  quantity: e.quantity,
@@ -32,32 +31,32 @@ var S = () => {
32
31
  pricingModel: e.product?.pricingModel || "PAID_ONETIME"
33
32
  }))
34
33
  });
35
- e?.id ? (I.emit("store.order.placed", {
34
+ e?.id ? (F.emit("store.order.placed", {
36
35
  orderId: e.id,
37
- total: E,
38
- itemCount: T
39
- }), k().catch(() => {}), S(`/billing/checkout/store/${e.id}`)) : (P(F("pages.cart.failedToCreate", { defaultValue: "Failed to create order. Please try again." })), M(!1));
36
+ total: T,
37
+ itemCount: w
38
+ }), O().catch(() => {}), x(`/billing/checkout/store/${e.id}`)) : (N(P("pages.cart.failedToCreate", { defaultValue: "Failed to create order. Please try again." })), j(!1));
40
39
  } catch (e) {
41
40
  if (console.error("Checkout error:", e), v(e)) {
42
- L(e), M(!1);
41
+ I(e), j(!1);
43
42
  return;
44
43
  }
45
- P(e instanceof Error ? e.message : "An error occurred during checkout"), M(!1);
44
+ N(e instanceof Error ? e.message : "An error occurred during checkout"), j(!1);
46
45
  }
47
- }, z = () => {
48
- S(`${C}/marketplace`);
46
+ }, R = () => {
47
+ x(`${S}/marketplace`);
49
48
  };
50
49
  return /* @__PURE__ */ g("div", {
51
50
  className: "h-full overflow-y-auto",
52
51
  children: [/* @__PURE__ */ h("header", {
53
- className: "sticky top-0 z-10 border-b border-border-seam bg-bg-surface px-6 py-4",
52
+ className: "sticky top-0 z-10 border-b border-border-default bg-bg-surface px-6 py-4",
54
53
  children: /* @__PURE__ */ h("div", {
55
54
  className: "mx-auto max-w-6xl",
56
55
  children: /* @__PURE__ */ g("div", {
57
56
  className: "flex items-center gap-4",
58
57
  children: [/* @__PURE__ */ h("button", {
59
58
  type: "button",
60
- onClick: () => S(-1),
59
+ onClick: () => x(-1),
61
60
  "aria-label": "Go back",
62
61
  className: "cursor-pointer rounded-lg p-2 text-text-muted transition-colors hover:bg-bg-sunken hover:text-text-primary",
63
62
  children: /* @__PURE__ */ h(a, { className: "size-5" })
@@ -67,19 +66,19 @@ var S = () => {
67
66
  /* @__PURE__ */ h(u, { className: "size-6 text-text-primary" }),
68
67
  /* @__PURE__ */ h("h1", {
69
68
  className: "text-xl font-bold text-text-primary",
70
- children: F("cart.title", { defaultValue: "Shopping Cart" })
69
+ children: P("cart.title", { defaultValue: "Shopping Cart" })
71
70
  }),
72
- T > 0 && /* @__PURE__ */ g("span", {
71
+ w > 0 && /* @__PURE__ */ g("span", {
73
72
  className: "rounded-full bg-action-primary-bg px-2.5 py-0.5 text-sm font-medium text-action-primary-text",
74
73
  children: [
75
- T,
74
+ w,
76
75
  " ",
77
- T === 1 ? F("pages.cart.item", {
78
- defaultValue: `${T} item`,
79
- count: T
80
- }) : F("pages.cart.items", {
81
- defaultValue: `${T} items`,
82
- count: T
76
+ w === 1 ? P("pages.cart.item", {
77
+ defaultValue: `${w} item`,
78
+ count: w
79
+ }) : P("pages.cart.items", {
80
+ defaultValue: `${w} items`,
81
+ count: w
83
82
  })
84
83
  ]
85
84
  })
@@ -89,7 +88,7 @@ var S = () => {
89
88
  })
90
89
  }), /* @__PURE__ */ h("main", {
91
90
  className: "mx-auto max-w-6xl p-6",
92
- children: w.length === 0 ? /* @__PURE__ */ g("div", {
91
+ children: C.length === 0 ? /* @__PURE__ */ g("div", {
93
92
  className: "flex flex-col items-center justify-center py-16 text-center",
94
93
  children: [
95
94
  /* @__PURE__ */ h("div", {
@@ -98,17 +97,17 @@ var S = () => {
98
97
  }),
99
98
  /* @__PURE__ */ h("h2", {
100
99
  className: "mb-2 text-2xl font-bold text-text-primary",
101
- children: F("cart.empty", { defaultValue: "Your cart is empty" })
100
+ children: P("cart.empty", { defaultValue: "Your cart is empty" })
102
101
  }),
103
102
  /* @__PURE__ */ h("p", {
104
103
  className: "mb-6 max-w-md text-text-muted",
105
- children: F("pages.cart.emptyDescription", { defaultValue: "Looks like you have not added any apps or products to your cart yet. Start exploring the marketplace to find something you will love!" })
104
+ children: P("pages.cart.emptyDescription", { defaultValue: "Looks like you have not added any apps or products to your cart yet. Start exploring the marketplace to find something you will love!" })
106
105
  }),
107
106
  /* @__PURE__ */ g("button", {
108
107
  type: "button",
109
- onClick: z,
108
+ onClick: R,
110
109
  className: "cursor-pointer flex items-center gap-2 rounded-lg bg-action-primary-bg px-6 py-3 font-semibold text-action-primary-text transition-opacity hover:opacity-90",
111
- children: [/* @__PURE__ */ h(l, { className: "size-5" }), F("pages.cart.browseMarketplace", { defaultValue: "Browse Marketplace" })]
110
+ children: [/* @__PURE__ */ h(l, { className: "size-5" }), P("pages.cart.browseMarketplace", { defaultValue: "Browse Marketplace" })]
112
111
  })
113
112
  ]
114
113
  }) : /* @__PURE__ */ h("div", {
@@ -118,21 +117,21 @@ var S = () => {
118
117
  className: "mb-4 flex items-center justify-between",
119
118
  children: [/* @__PURE__ */ h("h2", {
120
119
  className: "text-lg font-semibold text-text-primary",
121
- children: F("pages.cart.cartItems", {
122
- defaultValue: `Cart Items (${T})`,
123
- count: T
120
+ children: P("pages.cart.cartItems", {
121
+ defaultValue: `Cart Items (${w})`,
122
+ count: w
124
123
  })
125
124
  }), /* @__PURE__ */ g("button", {
126
125
  type: "button",
127
- onClick: k,
126
+ onClick: O,
128
127
  className: "cursor-pointer flex items-center gap-1 text-sm text-text-muted transition-colors hover:text-status-error-text",
129
- children: [/* @__PURE__ */ h(f, { className: "size-4" }), F("cart.clearCart", { defaultValue: "Clear Cart" })]
128
+ children: [/* @__PURE__ */ h(f, { className: "size-4" }), P("cart.clearCart", { defaultValue: "Clear Cart" })]
130
129
  })]
131
130
  }),
132
131
  /* @__PURE__ */ h("ul", {
133
132
  className: "space-y-4",
134
- children: w.map((e) => /* @__PURE__ */ g("li", {
135
- className: "flex gap-4 rounded-xl border border-border-seam bg-bg-surface p-4 transition-[box-shadow,border-color] hover:border-border-strong hover:shadow-[var(--shadow-pop)]",
133
+ children: C.map((e) => /* @__PURE__ */ g("li", {
134
+ className: "flex gap-4 rounded-xl border border-border-default bg-bg-surface p-4 transition-shadow hover:shadow-md",
136
135
  children: [/* @__PURE__ */ h("div", {
137
136
  className: "size-24 flex-shrink-0 overflow-hidden rounded-lg bg-bg-sunken",
138
137
  children: e.product?.iconUrl ? /* @__PURE__ */ h("img", {
@@ -163,7 +162,7 @@ var S = () => {
163
162
  })
164
163
  ] }), /* @__PURE__ */ h("button", {
165
164
  type: "button",
166
- onClick: () => O(e.id),
165
+ onClick: () => D(e.id),
167
166
  className: "cursor-pointer rounded-lg p-2 text-text-muted transition-colors hover:bg-status-error-bg-subtle/10 hover:text-status-error-text",
168
167
  "aria-label": `Remove ${e.product?.displayName ?? "item"} from cart`,
169
168
  title: "Remove item",
@@ -174,10 +173,10 @@ var S = () => {
174
173
  className: "mt-2 flex items-center gap-2",
175
174
  children: [/* @__PURE__ */ h("span", {
176
175
  className: "inline-flex items-center gap-1 rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-muted",
177
- children: e.itemType === "digital" ? /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(p, { className: "size-3" }), F("pages.cart.digital", { defaultValue: "Digital" })] }) : /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(d, { className: "size-3" }), F("pages.cart.physical", { defaultValue: "Physical" })] })
176
+ children: e.itemType === "digital" ? /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(p, { className: "size-3" }), P("pages.cart.digital", { defaultValue: "Digital" })] }) : /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(d, { className: "size-3" }), P("pages.cart.physical", { defaultValue: "Physical" })] })
178
177
  }), e.product?.pricingModel === "SUBSCRIPTION" && /* @__PURE__ */ h("span", {
179
178
  className: "inline-flex items-center gap-1 rounded-full bg-bg-accent/10 px-2 py-0.5 text-xs font-medium text-text-link",
180
- children: F("store.pricingModels.subscription", { defaultValue: "Subscription" })
179
+ children: P("store.pricingModels.subscription", { defaultValue: "Subscription" })
181
180
  })]
182
181
  }),
183
182
  /* @__PURE__ */ g("div", {
@@ -192,7 +191,7 @@ var S = () => {
192
191
  children: [
193
192
  /* @__PURE__ */ h("button", {
194
193
  type: "button",
195
- onClick: () => D(e.id, e.quantity - 1),
194
+ onClick: () => E(e.id, e.quantity - 1),
196
195
  className: "cursor-pointer rounded-l-lg p-2 transition-colors hover:bg-bg-sunken disabled:cursor-not-allowed disabled:opacity-50",
197
196
  disabled: e.quantity <= 1,
198
197
  children: /* @__PURE__ */ h(s, { className: "size-4" })
@@ -203,7 +202,7 @@ var S = () => {
203
202
  }),
204
203
  /* @__PURE__ */ h("button", {
205
204
  type: "button",
206
- onClick: () => D(e.id, e.quantity + 1),
205
+ onClick: () => E(e.id, e.quantity + 1),
207
206
  className: "cursor-pointer rounded-r-lg p-2 transition-colors hover:bg-bg-sunken",
208
207
  children: /* @__PURE__ */ h(c, { className: "size-4" })
209
208
  })
@@ -211,7 +210,7 @@ var S = () => {
211
210
  })]
212
211
  }) : /* @__PURE__ */ h("div", {
213
212
  className: "text-sm text-text-muted",
214
- children: F("pages.cart.singleLicense", { defaultValue: "Single license" })
213
+ children: P("pages.cart.singleLicense", { defaultValue: "Single license" })
215
214
  }), /* @__PURE__ */ g("div", {
216
215
  className: "text-right",
217
216
  children: [/* @__PURE__ */ h("p", {
@@ -227,34 +226,34 @@ var S = () => {
227
226
  })]
228
227
  }, e.id))
229
228
  }),
230
- /* @__PURE__ */ g(y, {
231
- className: "mt-8",
232
- children: [N && /* @__PURE__ */ h("div", {
229
+ /* @__PURE__ */ g("div", {
230
+ className: "mt-8 rounded-xl border border-border-default bg-bg-surface p-5",
231
+ children: [M && /* @__PURE__ */ h("div", {
233
232
  role: "alert",
234
233
  className: "mb-4 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text",
235
- children: N
234
+ children: M
236
235
  }), /* @__PURE__ */ g("div", {
237
236
  className: "flex items-center justify-between",
238
237
  children: [/* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("p", {
239
238
  className: "text-sm text-text-muted",
240
239
  children: "Total"
241
240
  }), /* @__PURE__ */ h("p", {
242
- className: "text-2xl font-bold tabular-nums text-text-primary",
243
- children: n(E)
241
+ className: "text-2xl font-bold text-text-primary",
242
+ children: n(T)
244
243
  })] }), /* @__PURE__ */ h("button", {
245
244
  type: "button",
246
- onClick: R,
247
- disabled: j,
245
+ onClick: L,
246
+ disabled: A,
248
247
  className: "flex cursor-pointer items-center gap-2 rounded-lg bg-action-primary-bg px-6 py-3 font-semibold text-action-primary-text transition-opacity hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-70",
249
- children: j ? /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(o, { className: "size-4 animate-spin" }), F("pages.cart.processing", { defaultValue: "Processing..." })] }) : /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(p, { className: "size-4" }), F("pages.cart.proceedToCheckout", { defaultValue: "Proceed to Checkout" })] })
248
+ children: A ? /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(o, { className: "size-4 animate-spin" }), P("pages.cart.processing", { defaultValue: "Processing..." })] }) : /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(p, { className: "size-4" }), P("pages.cart.proceedToCheckout", { defaultValue: "Proceed to Checkout" })] })
250
249
  })]
251
250
  })]
252
251
  }),
253
252
  /* @__PURE__ */ g("button", {
254
253
  type: "button",
255
- onClick: z,
254
+ onClick: R,
256
255
  className: "cursor-pointer mt-4 flex items-center gap-2 text-sm font-medium text-text-link hover:underline",
257
- children: [/* @__PURE__ */ h(a, { className: "size-4" }), F("cart.continueShopping", { defaultValue: "Continue Shopping" })]
256
+ children: [/* @__PURE__ */ h(a, { className: "size-4" }), P("cart.continueShopping", { defaultValue: "Continue Shopping" })]
258
257
  })
259
258
  ] })
260
259
  })
@@ -262,6 +261,6 @@ var S = () => {
262
261
  });
263
262
  };
264
263
  //#endregion
265
- export { S as CartPage };
264
+ export { x as CartPage };
266
265
 
267
266
  //# sourceMappingURL=CartPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CartPage.js","names":[],"sources":["../../src/pages/CartPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { useEventBus } from '@burdenoff/fe-libs/shared/events';\nimport { useQuotaErrorToast } from '@burdenoff/fe-libs/shared/hooks';\nimport { isQuotaExhaustedError } from '@burdenoff/fe-libs/shared/utils';\nimport {\n ShoppingCart,\n Trash2,\n Plus,\n Minus,\n ArrowLeft,\n ShoppingBag,\n Zap,\n Tag,\n Loader2,\n} from 'lucide-react';\nimport { useStore } from '../providers/StoreProvider';\nimport { useCart } from '../hooks/useCart';\nimport { formatPrice } from '../utils';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { EmphasisPanel } from '@burdenoff/fe-libs/ui';\n\n/**\n * CartPage component\n *\n * Full page cart view with items, summary, and checkout\n */\nexport const CartPage: FC = () => {\n const navigate = useNavigate();\n const { basePath } = useStore();\n const { cartItems, itemCount, total, updateQuantity, removeProduct, clearCart, createOrder } =\n useCart();\n const [isCheckingOut, setIsCheckingOut] = useState(false);\n const [checkoutError, setCheckoutError] = useState<string | null>(null);\n const { t } = useI18n();\n const bus = useEventBus();\n // Surface QUOTA_EXHAUSTED gateway errors as a toast (e.g. when the\n // workspace has hit its store-purchases-per-month limit). The hook also\n // listens for the global `burdenoff:quota-exhausted` event so any other\n // mutation in the page that triggers it will toast as well.\n const { report: reportQuotaError } = useQuotaErrorToast();\n\n const handleCheckout = async () => {\n try {\n setIsCheckingOut(true);\n setCheckoutError(null);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n bus.emit('store.cart.checkout_started' as any, {\n cartId: '',\n itemCount,\n total,\n });\n\n // Build line items from cart\n const lineItems = cartItems.map((item) => ({\n productId: item.productId,\n name: item.product?.displayName || 'Product',\n quantity: item.quantity,\n unitPrice: item.unitPrice,\n subtotal: item.totalPrice,\n itemType: item.itemType.toLowerCase(),\n variantId: item.variantId,\n pricingModel: item.product?.pricingModel || 'PAID_ONETIME',\n }));\n\n // Create order input\n const orderInput = {\n total,\n lineItems,\n };\n\n // Call createStoreOrder mutation to create PENDING order\n const order = await createOrder(orderInput);\n\n if (order?.id) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n bus.emit('store.order.placed' as any, {\n orderId: order.id,\n total,\n itemCount,\n });\n // Clear cart now that the order is created — non-blocking so a\n // clear failure never prevents the user from reaching billing.\n clearCart().catch(() => {});\n // Navigate to billing page with the order ID\n navigate(`/billing/checkout/store/${order.id}`);\n } else {\n setCheckoutError(\n t('pages.cart.failedToCreate', {\n defaultValue: 'Failed to create order. Please try again.',\n })\n );\n setIsCheckingOut(false);\n }\n } catch (error) {\n console.error('Checkout error:', error);\n // Quota-exhausted errors surface a global toast via the shell's\n // GlobalUiProvider; suppress the inline checkout error so we don't\n // stack two error UIs on top of each other.\n if (isQuotaExhaustedError(error)) {\n reportQuotaError(error);\n setIsCheckingOut(false);\n return;\n }\n setCheckoutError(\n error instanceof Error ? error.message : 'An error occurred during checkout'\n );\n setIsCheckingOut(false);\n }\n };\n\n const handleContinueShopping = () => {\n navigate(`${basePath}/marketplace`);\n };\n\n return (\n <div className=\"h-full overflow-y-auto\">\n {/* Header */}\n <header className=\"sticky top-0 z-10 border-b border-border-seam bg-bg-surface px-6 py-4\">\n <div className=\"mx-auto max-w-6xl\">\n <div className=\"flex items-center gap-4\">\n <button\n type=\"button\"\n onClick={() => navigate(-1)}\n aria-label=\"Go back\"\n className=\"cursor-pointer rounded-lg p-2 text-text-muted transition-colors hover:bg-bg-sunken hover:text-text-primary\"\n >\n <ArrowLeft className=\"size-5\" />\n </button>\n <div className=\"flex items-center gap-3\">\n <ShoppingCart className=\"size-6 text-text-primary\" />\n <h1 className=\"text-xl font-bold text-text-primary\">\n {t('cart.title', { defaultValue: 'Shopping Cart' })}\n </h1>\n {itemCount > 0 && (\n <span className=\"rounded-full bg-action-primary-bg px-2.5 py-0.5 text-sm font-medium text-action-primary-text\">\n {itemCount}{' '}\n {itemCount === 1\n ? t('pages.cart.item', { defaultValue: `${itemCount} item`, count: itemCount })\n : t('pages.cart.items', {\n defaultValue: `${itemCount} items`,\n count: itemCount,\n })}\n </span>\n )}\n </div>\n </div>\n </div>\n </header>\n\n <main className=\"mx-auto max-w-6xl p-6\">\n {cartItems.length === 0 ? (\n // Empty Cart State\n <div className=\"flex flex-col items-center justify-center py-16 text-center\">\n <div className=\"mb-6 rounded-full bg-bg-sunken p-6\">\n <ShoppingBag className=\"size-16 text-text-muted\" />\n </div>\n <h2 className=\"mb-2 text-2xl font-bold text-text-primary\">\n {t('cart.empty', { defaultValue: 'Your cart is empty' })}\n </h2>\n <p className=\"mb-6 max-w-md text-text-muted\">\n {t('pages.cart.emptyDescription', {\n defaultValue:\n 'Looks like you have not added any apps or products to your cart yet. Start exploring the marketplace to find something you will love!',\n })}\n </p>\n <button\n type=\"button\"\n onClick={handleContinueShopping}\n className=\"cursor-pointer flex items-center gap-2 rounded-lg bg-action-primary-bg px-6 py-3 font-semibold text-action-primary-text transition-opacity hover:opacity-90\"\n >\n <ShoppingBag className=\"size-5\" />\n {t('pages.cart.browseMarketplace', { defaultValue: 'Browse Marketplace' })}\n </button>\n </div>\n ) : (\n // Cart with Items\n <div className=\"mx-auto max-w-3xl\">\n {/* Cart Items */}\n <div>\n {/* Cart Actions */}\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {t('pages.cart.cartItems', {\n defaultValue: `Cart Items (${itemCount})`,\n count: itemCount,\n })}\n </h2>\n <button\n type=\"button\"\n onClick={clearCart}\n className=\"cursor-pointer flex items-center gap-1 text-sm text-text-muted transition-colors hover:text-status-error-text\"\n >\n <Trash2 className=\"size-4\" />\n {t('cart.clearCart', { defaultValue: 'Clear Cart' })}\n </button>\n </div>\n\n {/* Items List */}\n <ul className=\"space-y-4\">\n {cartItems.map((item) => (\n <li\n key={item.id}\n className=\"flex gap-4 rounded-xl 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-24 flex-shrink-0 overflow-hidden rounded-lg bg-bg-sunken\">\n {item.product?.iconUrl ? (\n <img\n src={item.product.iconUrl}\n alt={item.product.displayName}\n className=\"size-full object-cover\"\n />\n ) : (\n <div className=\"flex size-full items-center justify-center text-2xl font-bold text-text-muted\">\n {item.product?.displayName?.charAt(0) || 'P'}\n </div>\n )}\n </div>\n\n {/* Product Info */}\n <div className=\"flex flex-1 flex-col\">\n <div className=\"flex items-start justify-between\">\n <div>\n <h3 className=\"font-semibold text-text-primary\">\n {item.product?.displayName || 'Product'}\n </h3>\n <p className=\"text-sm text-text-muted\">\n {item.product?.publisher?.displayName || 'Unknown Publisher'}\n </p>\n {item.variant && (\n <p className=\"mt-1 text-xs text-text-muted\">\n Version {item.variant.version}\n </p>\n )}\n </div>\n <button\n type=\"button\"\n onClick={() => removeProduct(item.id)}\n className=\"cursor-pointer rounded-lg p-2 text-text-muted transition-colors hover:bg-status-error-bg-subtle/10 hover:text-status-error-text\"\n aria-label={`Remove ${item.product?.displayName ?? 'item'} from cart`}\n title=\"Remove item\"\n >\n <Trash2 className=\"size-5\" />\n </button>\n </div>\n\n {/* Item Type Badge */}\n <div className=\"mt-2 flex items-center gap-2\">\n <span className=\"inline-flex items-center gap-1 rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-muted\">\n {item.itemType === 'digital' ? (\n <>\n <Zap className=\"size-3\" />\n {t('pages.cart.digital', { defaultValue: 'Digital' })}\n </>\n ) : (\n <>\n <Tag className=\"size-3\" />\n {t('pages.cart.physical', { defaultValue: 'Physical' })}\n </>\n )}\n </span>\n {item.product?.pricingModel === 'SUBSCRIPTION' && (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-bg-accent/10 px-2 py-0.5 text-xs font-medium text-text-link\">\n {t('store.pricingModels.subscription', {\n defaultValue: 'Subscription',\n })}\n </span>\n )}\n </div>\n\n {/* Quantity and Price Row */}\n <div className=\"mt-auto flex items-center justify-between pt-3\">\n {/* Quantity Controls - Only show for physical items */}\n {item.itemType === 'physical' ? (\n <div className=\"flex items-center gap-3\">\n <span className=\"text-sm text-text-muted\">Qty:</span>\n <div className=\"flex items-center rounded-lg border border-border-default\">\n <button\n type=\"button\"\n onClick={() => updateQuantity(item.id, item.quantity - 1)}\n className=\"cursor-pointer rounded-l-lg p-2 transition-colors hover:bg-bg-sunken disabled:cursor-not-allowed disabled:opacity-50\"\n disabled={item.quantity <= 1}\n >\n <Minus className=\"size-4\" />\n </button>\n <span className=\"min-w-[3rem] text-center font-medium\">\n {item.quantity}\n </span>\n <button\n type=\"button\"\n onClick={() => updateQuantity(item.id, item.quantity + 1)}\n className=\"cursor-pointer rounded-r-lg p-2 transition-colors hover:bg-bg-sunken\"\n >\n <Plus className=\"size-4\" />\n </button>\n </div>\n </div>\n ) : (\n <div className=\"text-sm text-text-muted\">\n {t('pages.cart.singleLicense', { defaultValue: 'Single license' })}\n </div>\n )}\n\n {/* Price */}\n <div className=\"text-right\">\n <p className=\"text-lg font-bold text-text-primary\">\n {formatPrice(item.totalPrice)}\n </p>\n {item.quantity > 1 && item.itemType === 'physical' && (\n <p className=\"text-xs text-text-muted\">\n {formatPrice(item.unitPrice)} each\n </p>\n )}\n </div>\n </div>\n </div>\n </li>\n ))}\n </ul>\n\n {/* Checkout Footer */}\n <EmphasisPanel className=\"mt-8\">\n {checkoutError && (\n <div\n role=\"alert\"\n className=\"mb-4 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text\"\n >\n {checkoutError}\n </div>\n )}\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"text-sm text-text-muted\">Total</p>\n <p className=\"text-2xl font-bold tabular-nums text-text-primary\">\n {formatPrice(total)}\n </p>\n </div>\n <button\n type=\"button\"\n onClick={handleCheckout}\n disabled={isCheckingOut}\n className=\"flex cursor-pointer items-center gap-2 rounded-lg bg-action-primary-bg px-6 py-3 font-semibold text-action-primary-text transition-opacity hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-70\"\n >\n {isCheckingOut ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n {t('pages.cart.processing', { defaultValue: 'Processing...' })}\n </>\n ) : (\n <>\n <Zap className=\"size-4\" />\n {t('pages.cart.proceedToCheckout', { defaultValue: 'Proceed to Checkout' })}\n </>\n )}\n </button>\n </div>\n </EmphasisPanel>\n\n {/* Continue Shopping */}\n <button\n type=\"button\"\n onClick={handleContinueShopping}\n className=\"cursor-pointer mt-4 flex items-center gap-2 text-sm font-medium text-text-link hover:underline\"\n >\n <ArrowLeft className=\"size-4\" />\n {t('cart.continueShopping', { defaultValue: 'Continue Shopping' })}\n </button>\n </div>\n </div>\n )}\n </main>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"CartPage.js","names":[],"sources":["../../src/pages/CartPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { useEventBus } from '@burdenoff/fe-libs/shared/events';\nimport { useQuotaErrorToast } from '@burdenoff/fe-libs/shared/hooks';\nimport { isQuotaExhaustedError } from '@burdenoff/fe-libs/shared/utils';\nimport {\n ShoppingCart,\n Trash2,\n Plus,\n Minus,\n ArrowLeft,\n ShoppingBag,\n Zap,\n Tag,\n Loader2,\n} from 'lucide-react';\nimport { useStore } from '../providers/StoreProvider';\nimport { useCart } from '../hooks/useCart';\nimport { formatPrice } from '../utils';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\n/**\n * CartPage component\n *\n * Full page cart view with items, summary, and checkout\n */\nexport const CartPage: FC = () => {\n const navigate = useNavigate();\n const { basePath } = useStore();\n const { cartItems, itemCount, total, updateQuantity, removeProduct, clearCart, createOrder } =\n useCart();\n const [isCheckingOut, setIsCheckingOut] = useState(false);\n const [checkoutError, setCheckoutError] = useState<string | null>(null);\n const { t } = useI18n();\n const bus = useEventBus();\n // Surface QUOTA_EXHAUSTED gateway errors as a toast (e.g. when the\n // workspace has hit its store-purchases-per-month limit). The hook also\n // listens for the global `burdenoff:quota-exhausted` event so any other\n // mutation in the page that triggers it will toast as well.\n const { report: reportQuotaError } = useQuotaErrorToast();\n\n const handleCheckout = async () => {\n try {\n setIsCheckingOut(true);\n setCheckoutError(null);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n bus.emit('store.cart.checkout_started' as any, {\n cartId: '',\n itemCount,\n total,\n });\n\n // Build line items from cart\n const lineItems = cartItems.map((item) => ({\n productId: item.productId,\n name: item.product?.displayName || 'Product',\n quantity: item.quantity,\n unitPrice: item.unitPrice,\n subtotal: item.totalPrice,\n itemType: item.itemType.toLowerCase(),\n variantId: item.variantId,\n pricingModel: item.product?.pricingModel || 'PAID_ONETIME',\n }));\n\n // Create order input\n const orderInput = {\n total,\n lineItems,\n };\n\n // Call createStoreOrder mutation to create PENDING order\n const order = await createOrder(orderInput);\n\n if (order?.id) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n bus.emit('store.order.placed' as any, {\n orderId: order.id,\n total,\n itemCount,\n });\n // Clear cart now that the order is created — non-blocking so a\n // clear failure never prevents the user from reaching billing.\n clearCart().catch(() => {});\n // Navigate to billing page with the order ID\n navigate(`/billing/checkout/store/${order.id}`);\n } else {\n setCheckoutError(\n t('pages.cart.failedToCreate', {\n defaultValue: 'Failed to create order. Please try again.',\n })\n );\n setIsCheckingOut(false);\n }\n } catch (error) {\n console.error('Checkout error:', error);\n // Quota-exhausted errors surface a global toast via the shell's\n // GlobalUiProvider; suppress the inline checkout error so we don't\n // stack two error UIs on top of each other.\n if (isQuotaExhaustedError(error)) {\n reportQuotaError(error);\n setIsCheckingOut(false);\n return;\n }\n setCheckoutError(\n error instanceof Error ? error.message : 'An error occurred during checkout'\n );\n setIsCheckingOut(false);\n }\n };\n\n const handleContinueShopping = () => {\n navigate(`${basePath}/marketplace`);\n };\n\n return (\n <div className=\"h-full overflow-y-auto\">\n {/* Header */}\n <header className=\"sticky top-0 z-10 border-b border-border-default bg-bg-surface px-6 py-4\">\n <div className=\"mx-auto max-w-6xl\">\n <div className=\"flex items-center gap-4\">\n <button\n type=\"button\"\n onClick={() => navigate(-1)}\n aria-label=\"Go back\"\n className=\"cursor-pointer rounded-lg p-2 text-text-muted transition-colors hover:bg-bg-sunken hover:text-text-primary\"\n >\n <ArrowLeft className=\"size-5\" />\n </button>\n <div className=\"flex items-center gap-3\">\n <ShoppingCart className=\"size-6 text-text-primary\" />\n <h1 className=\"text-xl font-bold text-text-primary\">\n {t('cart.title', { defaultValue: 'Shopping Cart' })}\n </h1>\n {itemCount > 0 && (\n <span className=\"rounded-full bg-action-primary-bg px-2.5 py-0.5 text-sm font-medium text-action-primary-text\">\n {itemCount}{' '}\n {itemCount === 1\n ? t('pages.cart.item', { defaultValue: `${itemCount} item`, count: itemCount })\n : t('pages.cart.items', {\n defaultValue: `${itemCount} items`,\n count: itemCount,\n })}\n </span>\n )}\n </div>\n </div>\n </div>\n </header>\n\n <main className=\"mx-auto max-w-6xl p-6\">\n {cartItems.length === 0 ? (\n // Empty Cart State\n <div className=\"flex flex-col items-center justify-center py-16 text-center\">\n <div className=\"mb-6 rounded-full bg-bg-sunken p-6\">\n <ShoppingBag className=\"size-16 text-text-muted\" />\n </div>\n <h2 className=\"mb-2 text-2xl font-bold text-text-primary\">\n {t('cart.empty', { defaultValue: 'Your cart is empty' })}\n </h2>\n <p className=\"mb-6 max-w-md text-text-muted\">\n {t('pages.cart.emptyDescription', {\n defaultValue:\n 'Looks like you have not added any apps or products to your cart yet. Start exploring the marketplace to find something you will love!',\n })}\n </p>\n <button\n type=\"button\"\n onClick={handleContinueShopping}\n className=\"cursor-pointer flex items-center gap-2 rounded-lg bg-action-primary-bg px-6 py-3 font-semibold text-action-primary-text transition-opacity hover:opacity-90\"\n >\n <ShoppingBag className=\"size-5\" />\n {t('pages.cart.browseMarketplace', { defaultValue: 'Browse Marketplace' })}\n </button>\n </div>\n ) : (\n // Cart with Items\n <div className=\"mx-auto max-w-3xl\">\n {/* Cart Items */}\n <div>\n {/* Cart Actions */}\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {t('pages.cart.cartItems', {\n defaultValue: `Cart Items (${itemCount})`,\n count: itemCount,\n })}\n </h2>\n <button\n type=\"button\"\n onClick={clearCart}\n className=\"cursor-pointer flex items-center gap-1 text-sm text-text-muted transition-colors hover:text-status-error-text\"\n >\n <Trash2 className=\"size-4\" />\n {t('cart.clearCart', { defaultValue: 'Clear Cart' })}\n </button>\n </div>\n\n {/* Items List */}\n <ul className=\"space-y-4\">\n {cartItems.map((item) => (\n <li\n key={item.id}\n className=\"flex gap-4 rounded-xl border border-border-default bg-bg-surface p-4 transition-shadow hover:shadow-md\"\n >\n {/* Product Image */}\n <div className=\"size-24 flex-shrink-0 overflow-hidden rounded-lg bg-bg-sunken\">\n {item.product?.iconUrl ? (\n <img\n src={item.product.iconUrl}\n alt={item.product.displayName}\n className=\"size-full object-cover\"\n />\n ) : (\n <div className=\"flex size-full items-center justify-center text-2xl font-bold text-text-muted\">\n {item.product?.displayName?.charAt(0) || 'P'}\n </div>\n )}\n </div>\n\n {/* Product Info */}\n <div className=\"flex flex-1 flex-col\">\n <div className=\"flex items-start justify-between\">\n <div>\n <h3 className=\"font-semibold text-text-primary\">\n {item.product?.displayName || 'Product'}\n </h3>\n <p className=\"text-sm text-text-muted\">\n {item.product?.publisher?.displayName || 'Unknown Publisher'}\n </p>\n {item.variant && (\n <p className=\"mt-1 text-xs text-text-muted\">\n Version {item.variant.version}\n </p>\n )}\n </div>\n <button\n type=\"button\"\n onClick={() => removeProduct(item.id)}\n className=\"cursor-pointer rounded-lg p-2 text-text-muted transition-colors hover:bg-status-error-bg-subtle/10 hover:text-status-error-text\"\n aria-label={`Remove ${item.product?.displayName ?? 'item'} from cart`}\n title=\"Remove item\"\n >\n <Trash2 className=\"size-5\" />\n </button>\n </div>\n\n {/* Item Type Badge */}\n <div className=\"mt-2 flex items-center gap-2\">\n <span className=\"inline-flex items-center gap-1 rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-muted\">\n {item.itemType === 'digital' ? (\n <>\n <Zap className=\"size-3\" />\n {t('pages.cart.digital', { defaultValue: 'Digital' })}\n </>\n ) : (\n <>\n <Tag className=\"size-3\" />\n {t('pages.cart.physical', { defaultValue: 'Physical' })}\n </>\n )}\n </span>\n {item.product?.pricingModel === 'SUBSCRIPTION' && (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-bg-accent/10 px-2 py-0.5 text-xs font-medium text-text-link\">\n {t('store.pricingModels.subscription', {\n defaultValue: 'Subscription',\n })}\n </span>\n )}\n </div>\n\n {/* Quantity and Price Row */}\n <div className=\"mt-auto flex items-center justify-between pt-3\">\n {/* Quantity Controls - Only show for physical items */}\n {item.itemType === 'physical' ? (\n <div className=\"flex items-center gap-3\">\n <span className=\"text-sm text-text-muted\">Qty:</span>\n <div className=\"flex items-center rounded-lg border border-border-default\">\n <button\n type=\"button\"\n onClick={() => updateQuantity(item.id, item.quantity - 1)}\n className=\"cursor-pointer rounded-l-lg p-2 transition-colors hover:bg-bg-sunken disabled:cursor-not-allowed disabled:opacity-50\"\n disabled={item.quantity <= 1}\n >\n <Minus className=\"size-4\" />\n </button>\n <span className=\"min-w-[3rem] text-center font-medium\">\n {item.quantity}\n </span>\n <button\n type=\"button\"\n onClick={() => updateQuantity(item.id, item.quantity + 1)}\n className=\"cursor-pointer rounded-r-lg p-2 transition-colors hover:bg-bg-sunken\"\n >\n <Plus className=\"size-4\" />\n </button>\n </div>\n </div>\n ) : (\n <div className=\"text-sm text-text-muted\">\n {t('pages.cart.singleLicense', { defaultValue: 'Single license' })}\n </div>\n )}\n\n {/* Price */}\n <div className=\"text-right\">\n <p className=\"text-lg font-bold text-text-primary\">\n {formatPrice(item.totalPrice)}\n </p>\n {item.quantity > 1 && item.itemType === 'physical' && (\n <p className=\"text-xs text-text-muted\">\n {formatPrice(item.unitPrice)} each\n </p>\n )}\n </div>\n </div>\n </div>\n </li>\n ))}\n </ul>\n\n {/* Checkout Footer */}\n <div className=\"mt-8 rounded-xl border border-border-default bg-bg-surface p-5\">\n {checkoutError && (\n <div\n role=\"alert\"\n className=\"mb-4 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text\"\n >\n {checkoutError}\n </div>\n )}\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"text-sm text-text-muted\">Total</p>\n <p className=\"text-2xl font-bold text-text-primary\">{formatPrice(total)}</p>\n </div>\n <button\n type=\"button\"\n onClick={handleCheckout}\n disabled={isCheckingOut}\n className=\"flex cursor-pointer items-center gap-2 rounded-lg bg-action-primary-bg px-6 py-3 font-semibold text-action-primary-text transition-opacity hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-70\"\n >\n {isCheckingOut ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n {t('pages.cart.processing', { defaultValue: 'Processing...' })}\n </>\n ) : (\n <>\n <Zap className=\"size-4\" />\n {t('pages.cart.proceedToCheckout', { defaultValue: 'Proceed to Checkout' })}\n </>\n )}\n </button>\n </div>\n </div>\n\n {/* Continue Shopping */}\n <button\n type=\"button\"\n onClick={handleContinueShopping}\n className=\"cursor-pointer mt-4 flex items-center gap-2 text-sm font-medium text-text-link hover:underline\"\n >\n <ArrowLeft className=\"size-4\" />\n {t('cart.continueShopping', { defaultValue: 'Continue Shopping' })}\n </button>\n </div>\n </div>\n )}\n </main>\n </div>\n );\n};\n"],"mappings":"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"}