@burdenoff/microfe-store 2026.625.3 → 2026.625.4

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 +76 -65
  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 +378 -368
  111. package/dist/pages/MarketplaceHomePage.js.map +1 -1
  112. package/dist/pages/MyLicensesPage.js +75 -67
  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 +64 -53
  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
@@ -9,9 +9,8 @@ import { useI18n as c } from "@burdenoff/fe-libs/shared/providers/shell/I18nProv
9
9
  import { ArrowLeft as l, CheckCircle as u, Clock as d, Download as f, Loader2 as p, Package as m, RefreshCw as h, ShoppingBag as g, XCircle as _ } from "lucide-react";
10
10
  import { Fragment as v, jsx as y, jsxs as b } from "react/jsx-runtime";
11
11
  import { useNavigate as x } from "react-router-dom";
12
- import { GlassCard as S, IllustratedEmptyState as C } from "@burdenoff/fe-libs/ui";
13
12
  //#region src/pages/OrdersPage.tsx
14
- var w = (e) => {
13
+ var S = (e) => {
15
14
  switch (e) {
16
15
  case "COMPLETED":
17
16
  case "FULFILLED":
@@ -51,10 +50,10 @@ var w = (e) => {
51
50
  label: e
52
51
  };
53
52
  }
54
- }, T = ({ item: e, orderId: t, orderStatus: r, onOpenInstallModal: i, installing: a }) => {
53
+ }, C = ({ item: e, orderId: t, orderStatus: r, onOpenInstallModal: i, installing: a }) => {
55
54
  let o = r === "COMPLETED" || r === "FULFILLED" || r === "PROCESSED", s = e.productType !== "PHYSICAL" && e.productType !== "MERCHANDISE";
56
55
  return /* @__PURE__ */ b("div", {
57
- className: "flex items-center gap-4 rounded-lg border border-border-seam bg-bg-sunken/50 p-4",
56
+ className: "flex items-center gap-4 rounded-lg border border-border-default bg-bg-sunken/50 p-4",
58
57
  children: [
59
58
  /* @__PURE__ */ y("div", {
60
59
  className: "size-14 flex-shrink-0 overflow-hidden rounded-lg bg-bg-sunken",
@@ -90,7 +89,7 @@ var w = (e) => {
90
89
  /* @__PURE__ */ y("div", {
91
90
  className: "text-right",
92
91
  children: /* @__PURE__ */ y("p", {
93
- className: "font-semibold tabular-nums text-text-primary",
92
+ className: "font-semibold text-text-primary",
94
93
  children: n(e.totalPrice)
95
94
  })
96
95
  }),
@@ -109,10 +108,10 @@ var w = (e) => {
109
108
  })
110
109
  ]
111
110
  });
112
- }, E = ({ order: e, onOpenInstallModal: t, installingItem: r }) => {
113
- let i = w(e.status), a = i.icon;
114
- return /* @__PURE__ */ b(S, {
115
- className: "p-6",
111
+ }, w = ({ order: e, onOpenInstallModal: t, installingItem: r }) => {
112
+ let i = S(e.status), a = i.icon;
113
+ return /* @__PURE__ */ b("div", {
114
+ className: "rounded-xl border border-border-default bg-bg-surface p-6 transition-shadow hover:shadow-md",
116
115
  children: [
117
116
  /* @__PURE__ */ b("div", {
118
117
  className: "flex items-start justify-between mb-4",
@@ -137,7 +136,7 @@ var w = (e) => {
137
136
  })] }), /* @__PURE__ */ b("div", {
138
137
  className: "text-right",
139
138
  children: [/* @__PURE__ */ y("p", {
140
- className: "text-xl font-bold tabular-nums text-text-primary",
139
+ className: "text-xl font-bold text-text-primary",
141
140
  children: n(e.total)
142
141
  }), /* @__PURE__ */ b("p", {
143
142
  className: "text-xs text-text-muted",
@@ -151,7 +150,7 @@ var w = (e) => {
151
150
  }),
152
151
  /* @__PURE__ */ y("div", {
153
152
  className: "space-y-3",
154
- children: e.items.map((n) => /* @__PURE__ */ y(T, {
153
+ children: e.items.map((n) => /* @__PURE__ */ y(C, {
155
154
  item: n,
156
155
  orderId: e.id,
157
156
  orderStatus: e.status,
@@ -160,14 +159,14 @@ var w = (e) => {
160
159
  }, n.id))
161
160
  }),
162
161
  /* @__PURE__ */ b("div", {
163
- className: "mt-4 pt-4 border-t border-border-seam",
162
+ className: "mt-4 pt-4 border-t border-border-default",
164
163
  children: [/* @__PURE__ */ b("div", {
165
164
  className: "flex justify-between text-sm",
166
165
  children: [/* @__PURE__ */ y("span", {
167
166
  className: "text-text-muted",
168
167
  children: "Subtotal"
169
168
  }), /* @__PURE__ */ y("span", {
170
- className: "tabular-nums text-text-primary",
169
+ className: "text-text-primary",
171
170
  children: n(e.subtotal)
172
171
  })]
173
172
  }), /* @__PURE__ */ b("div", {
@@ -176,15 +175,15 @@ var w = (e) => {
176
175
  className: "text-text-muted",
177
176
  children: "Tax"
178
177
  }), /* @__PURE__ */ y("span", {
179
- className: "tabular-nums text-text-primary",
178
+ className: "text-text-primary",
180
179
  children: n(e.tax)
181
180
  })]
182
181
  })]
183
182
  })
184
183
  ]
185
184
  });
186
- }, D = () => {
187
- let n = x(), { basePath: u } = e(), { t: d } = c(), { orders: f, loading: h, error: v, refetchOrders: S, hasMore: w, loadMore: T } = i(), { installations: D, refetch: O } = r();
185
+ }, T = () => {
186
+ let n = x(), { basePath: u } = e(), { t: d } = c(), { orders: f, loading: h, error: v, refetchOrders: S, hasMore: C, loadMore: T } = i(), { installations: E, refetch: D } = r();
188
187
  t({
189
188
  onData: () => {
190
189
  S();
@@ -193,7 +192,7 @@ var w = (e) => {
193
192
  console.warn("OrderStatusUpdated subscription error:", e.message);
194
193
  }
195
194
  });
196
- let [k, A] = s(!1), [j, M] = s(null), [N, P] = s(null), [F, I] = s(null), L = o(() => new Set(D.flatMap((e) => e.status === "ACTIVE" ? [e.productId] : [])), [D]), R = f.map((e) => {
195
+ let [O, k] = s(!1), [A, j] = s(null), [M, N] = s(null), [P, F] = s(null), I = o(() => new Set(E.flatMap((e) => e.status === "ACTIVE" ? [e.productId] : [])), [E]), L = f.map((e) => {
197
196
  let t = e.lineItems || [], n = t.reduce((e, t) => e + t.subtotal, 0), r = e.total - n, i = t.map((t, n) => ({
198
197
  id: `${e.id}-${n}`,
199
198
  productId: t.productId,
@@ -204,7 +203,7 @@ var w = (e) => {
204
203
  quantity: t.quantity,
205
204
  unitPrice: t.unitPrice,
206
205
  totalPrice: t.subtotal,
207
- installed: L.has(t.productId)
206
+ installed: I.has(t.productId)
208
207
  }));
209
208
  return {
210
209
  id: e.id,
@@ -216,28 +215,28 @@ var w = (e) => {
216
215
  status: e.status,
217
216
  createdAt: e.createdAt
218
217
  };
219
- }), z = (e, t) => {
220
- M(e), I(t.id), P({
218
+ }), R = (e, t) => {
219
+ j(e), F(t.id), N({
221
220
  id: t.productId,
222
221
  name: t.productName,
223
222
  icon: t.productIcon,
224
223
  type: t.productType,
225
224
  version: t.version
226
- }), A(!0);
227
- }, B = () => {
228
- A(!1), M(null), P(null), I(null);
229
- }, V = (e, t) => {
230
- !j || !F || (console.log(`Successfully installed ${N?.name} to workspace ${t} (${e})`), B(), O());
231
- }, H = (e) => {
225
+ }), k(!0);
226
+ }, z = () => {
227
+ k(!1), j(null), N(null), F(null);
228
+ }, B = (e, t) => {
229
+ !A || !P || (console.log(`Successfully installed ${M?.name} to workspace ${t} (${e})`), z(), D());
230
+ }, V = (e) => {
232
231
  console.error("Installation failed:", e.message);
233
- }, U = () => {
232
+ }, H = () => {
234
233
  n(`${u}/marketplace`);
235
234
  };
236
235
  return /* @__PURE__ */ b("div", {
237
236
  className: "h-full overflow-y-auto",
238
237
  children: [
239
238
  /* @__PURE__ */ y("header", {
240
- className: "sticky top-0 z-10 border-b border-border-seam bg-bg-surface px-6 py-4",
239
+ className: "sticky top-0 z-10 border-b border-border-default bg-bg-surface px-6 py-4",
241
240
  children: /* @__PURE__ */ y("div", {
242
241
  className: "mx-auto max-w-4xl",
243
242
  children: /* @__PURE__ */ b("div", {
@@ -256,9 +255,9 @@ var w = (e) => {
256
255
  className: "text-xl font-bold text-text-primary",
257
256
  children: d("pages.orders.title", { defaultValue: "My Orders" })
258
257
  }),
259
- R.length > 0 && /* @__PURE__ */ y("span", {
258
+ L.length > 0 && /* @__PURE__ */ y("span", {
260
259
  className: "rounded-full bg-action-primary-bg px-2.5 py-0.5 text-sm font-medium text-action-primary-text",
261
- children: R.length
260
+ children: L.length
262
261
  })
263
262
  ]
264
263
  })]
@@ -295,28 +294,40 @@ var w = (e) => {
295
294
  }),
296
295
  /* @__PURE__ */ b("button", {
297
296
  type: "button",
298
- onClick: U,
297
+ onClick: H,
298
+ 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",
299
+ children: [/* @__PURE__ */ y(g, { className: "size-5" }), "Browse Marketplace"]
300
+ })
301
+ ]
302
+ }) : L.length === 0 ? /* @__PURE__ */ b("div", {
303
+ className: "flex flex-col items-center justify-center py-16 text-center",
304
+ children: [
305
+ /* @__PURE__ */ y("div", {
306
+ className: "mb-6 rounded-full bg-bg-sunken p-6",
307
+ children: /* @__PURE__ */ y(g, { className: "size-16 text-text-muted" })
308
+ }),
309
+ /* @__PURE__ */ y("h2", {
310
+ className: "mb-2 text-2xl font-bold text-text-primary",
311
+ children: d("pages.orders.emptyTitle", { defaultValue: "No orders yet" })
312
+ }),
313
+ /* @__PURE__ */ y("p", {
314
+ className: "mb-6 max-w-md text-text-muted",
315
+ children: "You have not placed any orders yet. Browse the marketplace to discover apps and products!"
316
+ }),
317
+ /* @__PURE__ */ b("button", {
318
+ type: "button",
319
+ onClick: H,
299
320
  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",
300
321
  children: [/* @__PURE__ */ y(g, { className: "size-5" }), "Browse Marketplace"]
301
322
  })
302
323
  ]
303
- }) : R.length === 0 ? /* @__PURE__ */ y(C, {
304
- illustration: "empty-data",
305
- title: d("pages.orders.emptyTitle", { defaultValue: "No orders yet" }),
306
- description: "You have not placed any orders yet. Browse the marketplace to discover apps and products!",
307
- action: /* @__PURE__ */ b("button", {
308
- type: "button",
309
- onClick: U,
310
- 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",
311
- children: [/* @__PURE__ */ y(g, { className: "size-5" }), "Browse Marketplace"]
312
- })
313
324
  }) : /* @__PURE__ */ b("ul", {
314
325
  className: "space-y-6",
315
- children: [R.map((e) => /* @__PURE__ */ y("li", { children: /* @__PURE__ */ y(E, {
326
+ children: [L.map((e) => /* @__PURE__ */ y("li", { children: /* @__PURE__ */ y(w, {
316
327
  order: e,
317
- onOpenInstallModal: z,
318
- installingItem: k ? F : null
319
- }) }, e.id)), w && /* @__PURE__ */ y("li", {
328
+ onOpenInstallModal: R,
329
+ installingItem: O ? P : null
330
+ }) }, e.id)), C && /* @__PURE__ */ y("li", {
320
331
  className: "flex justify-center pt-4 list-none",
321
332
  children: /* @__PURE__ */ b("button", {
322
333
  type: "button",
@@ -332,18 +343,18 @@ var w = (e) => {
332
343
  })]
333
344
  })
334
345
  }),
335
- N && /* @__PURE__ */ y(a, {
336
- isOpen: k,
337
- onClose: B,
338
- app: N,
339
- orderId: j,
340
- onInstallSuccess: V,
341
- onInstallError: H
346
+ M && /* @__PURE__ */ y(a, {
347
+ isOpen: O,
348
+ onClose: z,
349
+ app: M,
350
+ orderId: A,
351
+ onInstallSuccess: B,
352
+ onInstallError: V
342
353
  })
343
354
  ]
344
355
  });
345
356
  };
346
357
  //#endregion
347
- export { D as OrdersPage };
358
+ export { T as OrdersPage };
348
359
 
349
360
  //# sourceMappingURL=OrdersPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"OrdersPage.js","names":[],"sources":["../../src/pages/OrdersPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useMemo, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n Package,\n ArrowLeft,\n ShoppingBag,\n Download,\n CheckCircle,\n Clock,\n XCircle,\n RefreshCw,\n Loader2,\n} from 'lucide-react';\nimport { useStore } from '../providers/StoreProvider';\nimport { useInstallations } from '../hooks/useInstallations';\nimport { useOrders } from '../hooks/useOrders';\nimport { formatPrice } from '../utils';\nimport { InstallAppModal, type AppInfo } from '../components/InstallAppModal';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { GlassCard, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\nimport { useOrderStatusUpdatedSubscription } from '../generated/global-operations';\n\n// Local types for UI\ninterface OrderItem {\n id: string;\n productId: string;\n productName: string;\n productIcon?: string;\n productType: string;\n version?: string;\n quantity: number;\n unitPrice: number;\n totalPrice: number;\n installed?: boolean;\n}\n\ninterface UIOrder {\n id: string;\n orderNumber: string;\n items: OrderItem[];\n subtotal: number;\n tax: number;\n total: number;\n status:\n | 'PENDING'\n | 'PROCESSING'\n | 'COMPLETED'\n | 'FAILED'\n | 'CANCELLED'\n | 'FULFILLED'\n | 'PROCESSED'\n | 'REFUNDED';\n createdAt: string;\n}\n\n/**\n * Get status icon and color\n */\nconst getStatusDisplay = (status: UIOrder['status']) => {\n switch (status) {\n case 'COMPLETED':\n case 'FULFILLED':\n case 'PROCESSED':\n return {\n icon: CheckCircle,\n color: 'text-status-success-text bg-status-success-bg-subtle/10',\n label: 'Completed',\n };\n case 'PROCESSING':\n return {\n icon: Clock,\n color: 'text-status-warning-text bg-status-warning-bg-subtle/10',\n label: 'Processing',\n };\n case 'PENDING':\n return {\n icon: Clock,\n color: 'text-status-warning-text bg-status-warning-bg-subtle/10',\n label: 'Pending',\n };\n case 'FAILED':\n return {\n icon: XCircle,\n color: 'text-status-error-text bg-status-error-bg-subtle/10',\n label: 'Failed',\n };\n case 'REFUNDED':\n return {\n icon: RefreshCw,\n color: 'text-status-warning-text bg-status-warning-bg-subtle/10',\n label: 'Refunded',\n };\n case 'CANCELLED':\n return { icon: RefreshCw, color: 'text-text-muted bg-bg-sunken', label: 'Cancelled' };\n default:\n return { icon: Clock, color: 'text-text-muted', label: status };\n }\n};\n\n/**\n * Order item card with Install App button\n */\nconst OrderItemCard: FC<{\n item: OrderItem;\n orderId: string;\n orderStatus: UIOrder['status'];\n onOpenInstallModal: (orderId: string, item: OrderItem) => void;\n installing: boolean;\n}> = ({ item, orderId, orderStatus, onOpenInstallModal, installing }) => {\n const isOrderSuccessful =\n orderStatus === 'COMPLETED' || orderStatus === 'FULFILLED' || orderStatus === 'PROCESSED';\n const isInstallable = item.productType !== 'PHYSICAL' && item.productType !== 'MERCHANDISE';\n return (\n <div className=\"flex items-center gap-4 rounded-lg border border-border-seam bg-bg-sunken/50 p-4\">\n {/* Product Icon */}\n <div className=\"size-14 flex-shrink-0 overflow-hidden rounded-lg bg-bg-sunken\">\n {item.productIcon ? (\n <img src={item.productIcon} alt={item.productName} className=\"size-full object-cover\" />\n ) : (\n <div className=\"flex size-full items-center justify-center text-lg font-bold text-text-muted\">\n {item.productName.charAt(0)}\n </div>\n )}\n </div>\n\n {/* Product Info */}\n <div className=\"flex-1 min-w-0\">\n <h4 className=\"font-medium text-text-primary truncate\">{item.productName}</h4>\n <div className=\"flex items-center gap-2 mt-1\">\n <span className=\"inline-flex items-center rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-muted\">\n {item.productType}\n </span>\n <span className=\"text-sm text-text-muted\">\n {item.quantity} x {formatPrice(item.unitPrice)}\n </span>\n </div>\n </div>\n\n {/* Price */}\n <div className=\"text-right\">\n <p className=\"font-semibold tabular-nums text-text-primary\">\n {formatPrice(item.totalPrice)}\n </p>\n </div>\n\n {/* Install Button - only show when order is successfully processed */}\n <div className=\"flex-shrink-0\">\n {item.installed ? (\n <span className=\"inline-flex items-center gap-1.5 rounded-lg bg-status-success-bg-subtle/10 px-4 py-2 text-sm font-medium text-status-success-text\">\n <CheckCircle className=\"size-4\" />\n Installed\n </span>\n ) : isOrderSuccessful && isInstallable ? (\n <button\n type=\"button\"\n onClick={() => onOpenInstallModal(orderId, item)}\n disabled={installing}\n className=\"inline-flex cursor-pointer items-center gap-1.5 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\"\n >\n {installing ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n Installing…\n </>\n ) : (\n <>\n <Download className=\"size-4\" />\n Install App\n </>\n )}\n </button>\n ) : null}\n </div>\n </div>\n );\n};\n\n/**\n * Order card component\n */\nconst OrderCard: FC<{\n order: UIOrder;\n onOpenInstallModal: (orderId: string, item: OrderItem) => void;\n installingItem: string | null;\n}> = ({ order, onOpenInstallModal, installingItem }) => {\n const statusDisplay = getStatusDisplay(order.status);\n const StatusIcon = statusDisplay.icon;\n\n return (\n <GlassCard className=\"p-6\">\n {/* Order Header */}\n <div className=\"flex items-start justify-between mb-4\">\n <div>\n <div className=\"flex items-center gap-3\">\n <h3 className=\"text-lg font-semibold text-text-primary\">{order.orderNumber}</h3>\n <span\n className={`inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-sm font-semibold ${statusDisplay.color}`}\n >\n <StatusIcon className=\"size-4\" />\n {statusDisplay.label}\n </span>\n </div>\n <p className=\"text-sm text-text-muted mt-1\">\n {new Date(order.createdAt).toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n })}\n </p>\n </div>\n <div className=\"text-right\">\n <p className=\"text-xl font-bold tabular-nums text-text-primary\">\n {formatPrice(order.total)}\n </p>\n <p className=\"text-xs text-text-muted\">\n {order.items.length} {order.items.length === 1 ? 'item' : 'items'}\n </p>\n </div>\n </div>\n\n {/* Order Items */}\n <div className=\"space-y-3\">\n {order.items.map((item) => (\n <OrderItemCard\n key={item.id}\n item={item}\n orderId={order.id}\n orderStatus={order.status}\n onOpenInstallModal={onOpenInstallModal}\n installing={installingItem === item.id}\n />\n ))}\n </div>\n\n {/* Order Summary */}\n {/* TODO(ux-sweep): no order-details modal exists; tax + shipping live inline. When a modal lands, wrap \"Tax + shipping advanced\" in OptionalFields. */}\n <div className=\"mt-4 pt-4 border-t border-border-seam\">\n <div className=\"flex justify-between text-sm\">\n <span className=\"text-text-muted\">Subtotal</span>\n <span className=\"tabular-nums text-text-primary\">{formatPrice(order.subtotal)}</span>\n </div>\n <div className=\"flex justify-between text-sm mt-1\">\n <span className=\"text-text-muted\">Tax</span>\n <span className=\"tabular-nums text-text-primary\">{formatPrice(order.tax)}</span>\n </div>\n </div>\n </GlassCard>\n );\n};\n\n/**\n * OrdersPage component\n *\n * Displays a list of all orders with their items and Install App buttons\n */\nexport const OrdersPage: FC = () => {\n const navigate = useNavigate();\n const { basePath } = useStore();\n const { t } = useI18n();\n const { orders: backendOrders, loading, error, refetchOrders, hasMore, loadMore } = useOrders();\n const { installations, refetch: refetchInstallations } = useInstallations();\n\n useOrderStatusUpdatedSubscription({\n onData: () => {\n void refetchOrders();\n },\n onError: (err) => {\n console.warn('OrderStatusUpdated subscription error:', err.message);\n },\n });\n\n // Modal state\n const [isModalOpen, setIsModalOpen] = useState(false);\n const [selectedOrderId, setSelectedOrderId] = useState<string | null>(null);\n const [selectedApp, setSelectedApp] = useState<AppInfo | null>(null);\n const [selectedItemId, setSelectedItemId] = useState<string | null>(null);\n\n const installedProductIds = useMemo(\n () =>\n new Set(\n installations.flatMap((installation) =>\n installation.status === 'ACTIVE' ? [installation.productId] : []\n )\n ),\n [installations]\n );\n\n // Map backend orders to UI format\n const orders: UIOrder[] = backendOrders.map((order) => {\n // Calculate subtotal from line items (with safety check)\n const lineItems = order.lineItems || [];\n const subtotal = lineItems.reduce((sum, item) => sum + item.subtotal, 0);\n // Estimate tax (backend doesn't store separate tax amount)\n const tax = order.total - subtotal;\n\n // Map lineItems to items with unique IDs\n const items: OrderItem[] = lineItems.map((item, index) => ({\n id: `${order.id}-${index}`, // Generate unique ID for each line item\n productId: item.productId,\n productName: item.name, // Backend uses 'name', UI expects 'productName'\n productIcon: item.productIcon,\n productType:\n item.productType ||\n (typeof item.itemType === 'string' ? item.itemType.toUpperCase() : 'APP'),\n version: item.version,\n quantity: item.quantity,\n unitPrice: item.unitPrice,\n totalPrice: item.subtotal, // Backend uses 'subtotal', UI expects 'totalPrice'\n installed: installedProductIds.has(item.productId),\n }));\n\n return {\n id: order.id,\n orderNumber: `#${order.id.slice(-8).toUpperCase()}`, // Generate order number from ID\n items,\n subtotal,\n tax,\n total: order.total,\n status: order.status as UIOrder['status'], // Cast to union type\n createdAt: order.createdAt,\n };\n });\n\n const handleOpenInstallModal = (orderId: string, item: OrderItem) => {\n setSelectedOrderId(orderId);\n setSelectedItemId(item.id);\n setSelectedApp({\n id: item.productId,\n name: item.productName,\n icon: item.productIcon,\n type: item.productType,\n version: item.version,\n });\n setIsModalOpen(true);\n };\n\n const handleCloseModal = () => {\n setIsModalOpen(false);\n setSelectedOrderId(null);\n setSelectedApp(null);\n setSelectedItemId(null);\n };\n\n const handleInstallSuccess = (workspaceId: string, workspaceName: string) => {\n if (!selectedOrderId || !selectedItemId) return;\n\n console.log(\n `Successfully installed ${selectedApp?.name} to workspace ${workspaceName} (${workspaceId})`\n );\n\n // Reset modal state\n handleCloseModal();\n void refetchInstallations();\n };\n\n const handleInstallError = (error: Error) => {\n console.error('Installation failed:', error.message);\n // Error is displayed in modal, no need to close it\n };\n\n const handleBrowseMarketplace = () => {\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-4xl\">\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 <Package className=\"size-6 text-text-primary\" />\n <h1 className=\"text-xl font-bold text-text-primary\">\n {t('pages.orders.title', { defaultValue: 'My Orders' })}\n </h1>\n {orders.length > 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 {orders.length}\n </span>\n )}\n </div>\n </div>\n </div>\n </header>\n\n <main className=\"mx-auto max-w-4xl p-6\">\n {loading ? (\n // Loading State\n <output\n aria-label=\"Loading orders\"\n className=\"flex flex-col items-center justify-center py-16\"\n >\n <Loader2 className=\"size-12 animate-spin text-text-muted mb-4\" aria-hidden=\"true\" />\n <p className=\"text-text-muted\">Loading your orders…</p>\n </output>\n ) : error ? (\n // Error State\n <div role=\"alert\" className=\"flex flex-col items-center justify-center py-16 text-center\">\n <div className=\"mb-6 rounded-full bg-status-error-bg-subtle/10 p-6\">\n <XCircle className=\"size-16 text-status-error-text\" />\n </div>\n <h2 className=\"mb-2 text-2xl font-bold text-text-primary\">\n {t('pages.orders.failedToLoad', { defaultValue: 'Failed to load orders' })}\n </h2>\n <p className=\"mb-6 max-w-md text-text-muted\">\n {error.message || 'An error occurred while loading your orders. Please try again.'}\n </p>\n <button\n type=\"button\"\n onClick={handleBrowseMarketplace}\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 Browse Marketplace\n </button>\n </div>\n ) : orders.length === 0 ? (\n // Empty State\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={t('pages.orders.emptyTitle', { defaultValue: 'No orders yet' })}\n description=\"You have not placed any orders yet. Browse the marketplace to discover apps and products!\"\n action={\n <button\n type=\"button\"\n onClick={handleBrowseMarketplace}\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 Browse Marketplace\n </button>\n }\n />\n ) : (\n // Orders List\n <ul className=\"space-y-6\">\n {orders.map((order) => (\n <li key={order.id}>\n <OrderCard\n order={order}\n onOpenInstallModal={handleOpenInstallModal}\n installingItem={isModalOpen ? selectedItemId : null}\n />\n </li>\n ))}\n {hasMore && (\n <li className=\"flex justify-center pt-4 list-none\">\n <button\n type=\"button\"\n onClick={loadMore}\n disabled={loading}\n className=\"flex items-center gap-2 rounded-lg border border-border-default px-6 py-2.5 text-sm font-medium text-text-primary hover:bg-bg-subtle disabled:opacity-50\"\n aria-label={t('common.loadMore', { defaultValue: 'Load more' })}\n >\n {loading ? <Loader2 className=\"size-4 animate-spin\" aria-hidden=\"true\" /> : null}\n {t('common.loadMore', { defaultValue: 'Load more' })}\n </button>\n </li>\n )}\n </ul>\n )}\n </main>\n\n {/* Install App Modal */}\n {selectedApp && (\n <InstallAppModal\n isOpen={isModalOpen}\n onClose={handleCloseModal}\n app={selectedApp}\n orderId={selectedOrderId}\n onInstallSuccess={handleInstallSuccess}\n onInstallError={handleInstallError}\n />\n )}\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;;;;AA2DA,IAAM,KAAoB,MAA8B;AACtD,SAAQ,GAAR;EACE,KAAK;EACL,KAAK;EACL,KAAK,YACH,QAAO;GACL,MAAM;GACN,OAAO;GACP,OAAO;GACR;EACH,KAAK,aACH,QAAO;GACL,MAAM;GACN,OAAO;GACP,OAAO;GACR;EACH,KAAK,UACH,QAAO;GACL,MAAM;GACN,OAAO;GACP,OAAO;GACR;EACH,KAAK,SACH,QAAO;GACL,MAAM;GACN,OAAO;GACP,OAAO;GACR;EACH,KAAK,WACH,QAAO;GACL,MAAM;GACN,OAAO;GACP,OAAO;GACR;EACH,KAAK,YACH,QAAO;GAAE,MAAM;GAAW,OAAO;GAAgC,OAAO;GAAa;EACvF,QACE,QAAO;GAAE,MAAM;GAAO,OAAO;GAAmB,OAAO;GAAQ;;GAO/D,KAMA,EAAE,SAAM,YAAS,gBAAa,uBAAoB,oBAAiB;CACvE,IAAM,IACJ,MAAgB,eAAe,MAAgB,eAAe,MAAgB,aAC1E,IAAgB,EAAK,gBAAgB,cAAc,EAAK,gBAAgB;AAC9E,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GAEE,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAK,cACJ,kBAAC,OAAD;KAAK,KAAK,EAAK;KAAa,KAAK,EAAK;KAAa,WAAU;KAA2B,CAAA,GAExF,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAK,YAAY,OAAO,EAAE;KACvB,CAAA;IAEJ,CAAA;GAGN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,MAAD;KAAI,WAAU;eAA0C,EAAK;KAAiB,CAAA,EAC9E,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,QAAD;MAAM,WAAU;gBACb,EAAK;MACD,CAAA,EACP,kBAAC,QAAD;MAAM,WAAU;gBAAhB;OACG,EAAK;OAAS;OAAI,EAAY,EAAK,UAAU;OACzC;QACH;OACF;;GAGN,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,KAAD;KAAG,WAAU;eACV,EAAY,EAAK,WAAW;KAC3B,CAAA;IACA,CAAA;GAGN,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAK,YACJ,kBAAC,QAAD;KAAM,WAAU;eAAhB,CACE,kBAAC,GAAD,EAAa,WAAU,UAAW,CAAA,EAAA,YAE7B;SACL,KAAqB,IACvB,kBAAC,UAAD;KACE,MAAK;KACL,eAAe,EAAmB,GAAS,EAAK;KAChD,UAAU;KACV,WAAU;eAET,IACC,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD,EAAS,WAAU,uBAAwB,CAAA,EAAA,cAE1C,EAAA,CAAA,GAEH,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD,EAAU,WAAU,UAAW,CAAA,EAAA,cAE9B,EAAA,CAAA;KAEE,CAAA,GACP;IACA,CAAA;GACF;;GAOJ,KAIA,EAAE,UAAO,uBAAoB,wBAAqB;CACtD,IAAM,IAAgB,EAAiB,EAAM,OAAO,EAC9C,IAAa,EAAc;AAEjC,QACE,kBAAC,GAAD;EAAW,WAAU;YAArB;GAEE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBAA2C,EAAM;MAAiB,CAAA,EAChF,kBAAC,QAAD;MACE,WAAW,iFAAiF,EAAc;gBAD5G,CAGE,kBAAC,GAAD,EAAY,WAAU,UAAW,CAAA,EAChC,EAAc,MACV;QACH;QACN,kBAAC,KAAD;KAAG,WAAU;eACV,IAAI,KAAK,EAAM,UAAU,CAAC,mBAAmB,SAAS;MACrD,MAAM;MACN,OAAO;MACP,KAAK;MACL,MAAM;MACN,QAAQ;MACT,CAAC;KACA,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAY,EAAM,MAAM;MACvB,CAAA,EACJ,kBAAC,KAAD;MAAG,WAAU;gBAAb;OACG,EAAM,MAAM;OAAO;OAAE,EAAM,MAAM,WAAW,IAAI,SAAS;OACxD;QACA;OACF;;GAGN,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAM,MAAM,KAAK,MAChB,kBAAC,GAAD;KAEQ;KACN,SAAS,EAAM;KACf,aAAa,EAAM;KACC;KACpB,YAAY,MAAmB,EAAK;KACpC,EANK,EAAK,GAMV,CACF;IACE,CAAA;GAIN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,QAAD;MAAM,WAAU;gBAAkB;MAAe,CAAA,EACjD,kBAAC,QAAD;MAAM,WAAU;gBAAkC,EAAY,EAAM,SAAS;MAAQ,CAAA,CACjF;QACN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,QAAD;MAAM,WAAU;gBAAkB;MAAU,CAAA,EAC5C,kBAAC,QAAD;MAAM,WAAU;gBAAkC,EAAY,EAAM,IAAI;MAAQ,CAAA,CAC5E;OACF;;GACI;;GASH,UAAuB;CAClC,IAAM,IAAW,GAAa,EACxB,EAAE,gBAAa,GAAU,EACzB,EAAE,SAAM,GAAS,EACjB,EAAE,QAAQ,GAAe,YAAS,UAAO,kBAAe,YAAS,gBAAa,GAAW,EACzF,EAAE,kBAAe,SAAS,MAAyB,GAAkB;AAE3E,GAAkC;EAChC,cAAc;AACP,MAAe;;EAEtB,UAAU,MAAQ;AAChB,WAAQ,KAAK,0CAA0C,EAAI,QAAQ;;EAEtE,CAAC;CAGF,IAAM,CAAC,GAAa,KAAkB,EAAS,GAAM,EAC/C,CAAC,GAAiB,KAAsB,EAAwB,KAAK,EACrE,CAAC,GAAa,KAAkB,EAAyB,KAAK,EAC9D,CAAC,GAAgB,KAAqB,EAAwB,KAAK,EAEnE,IAAsB,QAExB,IAAI,IACF,EAAc,SAAS,MACrB,EAAa,WAAW,WAAW,CAAC,EAAa,UAAU,GAAG,EAAE,CACjE,CACF,EACH,CAAC,EAAc,CAChB,EAGK,IAAoB,EAAc,KAAK,MAAU;EAErD,IAAM,IAAY,EAAM,aAAa,EAAE,EACjC,IAAW,EAAU,QAAQ,GAAK,MAAS,IAAM,EAAK,UAAU,EAAE,EAElE,IAAM,EAAM,QAAQ,GAGpB,IAAqB,EAAU,KAAK,GAAM,OAAW;GACzD,IAAI,GAAG,EAAM,GAAG,GAAG;GACnB,WAAW,EAAK;GAChB,aAAa,EAAK;GAClB,aAAa,EAAK;GAClB,aACE,EAAK,gBACJ,OAAO,EAAK,YAAa,WAAW,EAAK,SAAS,aAAa,GAAG;GACrE,SAAS,EAAK;GACd,UAAU,EAAK;GACf,WAAW,EAAK;GAChB,YAAY,EAAK;GACjB,WAAW,EAAoB,IAAI,EAAK,UAAU;GACnD,EAAE;AAEH,SAAO;GACL,IAAI,EAAM;GACV,aAAa,IAAI,EAAM,GAAG,MAAM,GAAG,CAAC,aAAa;GACjD;GACA;GACA;GACA,OAAO,EAAM;GACb,QAAQ,EAAM;GACd,WAAW,EAAM;GAClB;GACD,EAEI,KAA0B,GAAiB,MAAoB;AAUnE,EATA,EAAmB,EAAQ,EAC3B,EAAkB,EAAK,GAAG,EAC1B,EAAe;GACb,IAAI,EAAK;GACT,MAAM,EAAK;GACX,MAAM,EAAK;GACX,MAAM,EAAK;GACX,SAAS,EAAK;GACf,CAAC,EACF,EAAe,GAAK;IAGhB,UAAyB;AAI7B,EAHA,EAAe,GAAM,EACrB,EAAmB,KAAK,EACxB,EAAe,KAAK,EACpB,EAAkB,KAAK;IAGnB,KAAwB,GAAqB,MAA0B;AACvE,GAAC,KAAmB,CAAC,MAEzB,QAAQ,IACN,0BAA0B,GAAa,KAAK,gBAAgB,EAAc,IAAI,EAAY,GAC3F,EAGD,GAAkB,EACb,GAAsB;IAGvB,KAAsB,MAAiB;AAC3C,UAAQ,MAAM,wBAAwB,EAAM,QAAQ;IAIhD,UAAgC;AACpC,IAAS,GAAG,EAAS,cAAc;;AAGrC,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GAEE,kBAAC,UAAD;IAAQ,WAAU;cAChB,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,UAAD;OACE,MAAK;OACL,eAAe,EAAS,GAAG;OAC3B,cAAW;OACX,WAAU;iBAEV,kBAAC,GAAD,EAAW,WAAU,UAAW,CAAA;OACzB,CAAA,EACT,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,GAAD,EAAS,WAAU,4BAA6B,CAAA;QAChD,kBAAC,MAAD;SAAI,WAAU;mBACX,EAAE,sBAAsB,EAAE,cAAc,aAAa,CAAC;SACpD,CAAA;QACJ,EAAO,SAAS,KACf,kBAAC,QAAD;SAAM,WAAU;mBACb,EAAO;SACH,CAAA;QAEL;SACF;;KACF,CAAA;IACC,CAAA;GAET,kBAAC,QAAD;IAAM,WAAU;cACb,IAEC,kBAAC,UAAD;KACE,cAAW;KACX,WAAU;eAFZ,CAIE,kBAAC,GAAD;MAAS,WAAU;MAA4C,eAAY;MAAS,CAAA,EACpF,kBAAC,KAAD;MAAG,WAAU;gBAAkB;MAAwB,CAAA,CAChD;SACP,IAEF,kBAAC,OAAD;KAAK,MAAK;KAAQ,WAAU;eAA5B;MACE,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD,EAAS,WAAU,kCAAmC,CAAA;OAClD,CAAA;MACN,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAE,6BAA6B,EAAE,cAAc,yBAAyB,CAAC;OACvE,CAAA;MACL,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAM,WAAW;OAChB,CAAA;MACJ,kBAAC,UAAD;OACE,MAAK;OACL,SAAS;OACT,WAAU;iBAHZ,CAKE,kBAAC,GAAD,EAAa,WAAU,UAAW,CAAA,EAAA,qBAE3B;;MACL;SACJ,EAAO,WAAW,IAEpB,kBAAC,GAAD;KACE,cAAa;KACb,OAAO,EAAE,2BAA2B,EAAE,cAAc,iBAAiB,CAAC;KACtE,aAAY;KACZ,QACE,kBAAC,UAAD;MACE,MAAK;MACL,SAAS;MACT,WAAU;gBAHZ,CAKE,kBAAC,GAAD,EAAa,WAAU,UAAW,CAAA,EAAA,qBAE3B;;KAEX,CAAA,GAGF,kBAAC,MAAD;KAAI,WAAU;eAAd,CACG,EAAO,KAAK,MACX,kBAAC,MAAD,EAAA,UACE,kBAAC,GAAD;MACS;MACP,oBAAoB;MACpB,gBAAgB,IAAc,IAAiB;MAC/C,CAAA,EACC,EANI,EAAM,GAMV,CACL,EACD,KACC,kBAAC,MAAD;MAAI,WAAU;gBACZ,kBAAC,UAAD;OACE,MAAK;OACL,SAAS;OACT,UAAU;OACV,WAAU;OACV,cAAY,EAAE,mBAAmB,EAAE,cAAc,aAAa,CAAC;iBALjE,CAOG,IAAU,kBAAC,GAAD;QAAS,WAAU;QAAsB,eAAY;QAAS,CAAA,GAAG,MAC3E,EAAE,mBAAmB,EAAE,cAAc,aAAa,CAAC,CAC7C;;MACN,CAAA,CAEJ;;IAEF,CAAA;GAGN,KACC,kBAAC,GAAD;IACE,QAAQ;IACR,SAAS;IACT,KAAK;IACL,SAAS;IACT,kBAAkB;IAClB,gBAAgB;IAChB,CAAA;GAEA"}
1
+ {"version":3,"file":"OrdersPage.js","names":[],"sources":["../../src/pages/OrdersPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useMemo, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n Package,\n ArrowLeft,\n ShoppingBag,\n Download,\n CheckCircle,\n Clock,\n XCircle,\n RefreshCw,\n Loader2,\n} from 'lucide-react';\nimport { useStore } from '../providers/StoreProvider';\nimport { useInstallations } from '../hooks/useInstallations';\nimport { useOrders } from '../hooks/useOrders';\nimport { formatPrice } from '../utils';\nimport { InstallAppModal, type AppInfo } from '../components/InstallAppModal';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useOrderStatusUpdatedSubscription } from '../generated/global-operations';\n\n// Local types for UI\ninterface OrderItem {\n id: string;\n productId: string;\n productName: string;\n productIcon?: string;\n productType: string;\n version?: string;\n quantity: number;\n unitPrice: number;\n totalPrice: number;\n installed?: boolean;\n}\n\ninterface UIOrder {\n id: string;\n orderNumber: string;\n items: OrderItem[];\n subtotal: number;\n tax: number;\n total: number;\n status:\n | 'PENDING'\n | 'PROCESSING'\n | 'COMPLETED'\n | 'FAILED'\n | 'CANCELLED'\n | 'FULFILLED'\n | 'PROCESSED'\n | 'REFUNDED';\n createdAt: string;\n}\n\n/**\n * Get status icon and color\n */\nconst getStatusDisplay = (status: UIOrder['status']) => {\n switch (status) {\n case 'COMPLETED':\n case 'FULFILLED':\n case 'PROCESSED':\n return {\n icon: CheckCircle,\n color: 'text-status-success-text bg-status-success-bg-subtle/10',\n label: 'Completed',\n };\n case 'PROCESSING':\n return {\n icon: Clock,\n color: 'text-status-warning-text bg-status-warning-bg-subtle/10',\n label: 'Processing',\n };\n case 'PENDING':\n return {\n icon: Clock,\n color: 'text-status-warning-text bg-status-warning-bg-subtle/10',\n label: 'Pending',\n };\n case 'FAILED':\n return {\n icon: XCircle,\n color: 'text-status-error-text bg-status-error-bg-subtle/10',\n label: 'Failed',\n };\n case 'REFUNDED':\n return {\n icon: RefreshCw,\n color: 'text-status-warning-text bg-status-warning-bg-subtle/10',\n label: 'Refunded',\n };\n case 'CANCELLED':\n return { icon: RefreshCw, color: 'text-text-muted bg-bg-sunken', label: 'Cancelled' };\n default:\n return { icon: Clock, color: 'text-text-muted', label: status };\n }\n};\n\n/**\n * Order item card with Install App button\n */\nconst OrderItemCard: FC<{\n item: OrderItem;\n orderId: string;\n orderStatus: UIOrder['status'];\n onOpenInstallModal: (orderId: string, item: OrderItem) => void;\n installing: boolean;\n}> = ({ item, orderId, orderStatus, onOpenInstallModal, installing }) => {\n const isOrderSuccessful =\n orderStatus === 'COMPLETED' || orderStatus === 'FULFILLED' || orderStatus === 'PROCESSED';\n const isInstallable = item.productType !== 'PHYSICAL' && item.productType !== 'MERCHANDISE';\n return (\n <div className=\"flex items-center gap-4 rounded-lg border border-border-default bg-bg-sunken/50 p-4\">\n {/* Product Icon */}\n <div className=\"size-14 flex-shrink-0 overflow-hidden rounded-lg bg-bg-sunken\">\n {item.productIcon ? (\n <img src={item.productIcon} alt={item.productName} className=\"size-full object-cover\" />\n ) : (\n <div className=\"flex size-full items-center justify-center text-lg font-bold text-text-muted\">\n {item.productName.charAt(0)}\n </div>\n )}\n </div>\n\n {/* Product Info */}\n <div className=\"flex-1 min-w-0\">\n <h4 className=\"font-medium text-text-primary truncate\">{item.productName}</h4>\n <div className=\"flex items-center gap-2 mt-1\">\n <span className=\"inline-flex items-center rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-muted\">\n {item.productType}\n </span>\n <span className=\"text-sm text-text-muted\">\n {item.quantity} x {formatPrice(item.unitPrice)}\n </span>\n </div>\n </div>\n\n {/* Price */}\n <div className=\"text-right\">\n <p className=\"font-semibold text-text-primary\">{formatPrice(item.totalPrice)}</p>\n </div>\n\n {/* Install Button - only show when order is successfully processed */}\n <div className=\"flex-shrink-0\">\n {item.installed ? (\n <span className=\"inline-flex items-center gap-1.5 rounded-lg bg-status-success-bg-subtle/10 px-4 py-2 text-sm font-medium text-status-success-text\">\n <CheckCircle className=\"size-4\" />\n Installed\n </span>\n ) : isOrderSuccessful && isInstallable ? (\n <button\n type=\"button\"\n onClick={() => onOpenInstallModal(orderId, item)}\n disabled={installing}\n className=\"inline-flex cursor-pointer items-center gap-1.5 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\"\n >\n {installing ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n Installing…\n </>\n ) : (\n <>\n <Download className=\"size-4\" />\n Install App\n </>\n )}\n </button>\n ) : null}\n </div>\n </div>\n );\n};\n\n/**\n * Order card component\n */\nconst OrderCard: FC<{\n order: UIOrder;\n onOpenInstallModal: (orderId: string, item: OrderItem) => void;\n installingItem: string | null;\n}> = ({ order, onOpenInstallModal, installingItem }) => {\n const statusDisplay = getStatusDisplay(order.status);\n const StatusIcon = statusDisplay.icon;\n\n return (\n <div className=\"rounded-xl border border-border-default bg-bg-surface p-6 transition-shadow hover:shadow-md\">\n {/* Order Header */}\n <div className=\"flex items-start justify-between mb-4\">\n <div>\n <div className=\"flex items-center gap-3\">\n <h3 className=\"text-lg font-semibold text-text-primary\">{order.orderNumber}</h3>\n <span\n className={`inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-sm font-semibold ${statusDisplay.color}`}\n >\n <StatusIcon className=\"size-4\" />\n {statusDisplay.label}\n </span>\n </div>\n <p className=\"text-sm text-text-muted mt-1\">\n {new Date(order.createdAt).toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n })}\n </p>\n </div>\n <div className=\"text-right\">\n <p className=\"text-xl font-bold text-text-primary\">{formatPrice(order.total)}</p>\n <p className=\"text-xs text-text-muted\">\n {order.items.length} {order.items.length === 1 ? 'item' : 'items'}\n </p>\n </div>\n </div>\n\n {/* Order Items */}\n <div className=\"space-y-3\">\n {order.items.map((item) => (\n <OrderItemCard\n key={item.id}\n item={item}\n orderId={order.id}\n orderStatus={order.status}\n onOpenInstallModal={onOpenInstallModal}\n installing={installingItem === item.id}\n />\n ))}\n </div>\n\n {/* Order Summary */}\n {/* TODO(ux-sweep): no order-details modal exists; tax + shipping live inline. When a modal lands, wrap \"Tax + shipping advanced\" in OptionalFields. */}\n <div className=\"mt-4 pt-4 border-t border-border-default\">\n <div className=\"flex justify-between text-sm\">\n <span className=\"text-text-muted\">Subtotal</span>\n <span className=\"text-text-primary\">{formatPrice(order.subtotal)}</span>\n </div>\n <div className=\"flex justify-between text-sm mt-1\">\n <span className=\"text-text-muted\">Tax</span>\n <span className=\"text-text-primary\">{formatPrice(order.tax)}</span>\n </div>\n </div>\n </div>\n );\n};\n\n/**\n * OrdersPage component\n *\n * Displays a list of all orders with their items and Install App buttons\n */\nexport const OrdersPage: FC = () => {\n const navigate = useNavigate();\n const { basePath } = useStore();\n const { t } = useI18n();\n const { orders: backendOrders, loading, error, refetchOrders, hasMore, loadMore } = useOrders();\n const { installations, refetch: refetchInstallations } = useInstallations();\n\n useOrderStatusUpdatedSubscription({\n onData: () => {\n void refetchOrders();\n },\n onError: (err) => {\n console.warn('OrderStatusUpdated subscription error:', err.message);\n },\n });\n\n // Modal state\n const [isModalOpen, setIsModalOpen] = useState(false);\n const [selectedOrderId, setSelectedOrderId] = useState<string | null>(null);\n const [selectedApp, setSelectedApp] = useState<AppInfo | null>(null);\n const [selectedItemId, setSelectedItemId] = useState<string | null>(null);\n\n const installedProductIds = useMemo(\n () =>\n new Set(\n installations.flatMap((installation) =>\n installation.status === 'ACTIVE' ? [installation.productId] : []\n )\n ),\n [installations]\n );\n\n // Map backend orders to UI format\n const orders: UIOrder[] = backendOrders.map((order) => {\n // Calculate subtotal from line items (with safety check)\n const lineItems = order.lineItems || [];\n const subtotal = lineItems.reduce((sum, item) => sum + item.subtotal, 0);\n // Estimate tax (backend doesn't store separate tax amount)\n const tax = order.total - subtotal;\n\n // Map lineItems to items with unique IDs\n const items: OrderItem[] = lineItems.map((item, index) => ({\n id: `${order.id}-${index}`, // Generate unique ID for each line item\n productId: item.productId,\n productName: item.name, // Backend uses 'name', UI expects 'productName'\n productIcon: item.productIcon,\n productType:\n item.productType ||\n (typeof item.itemType === 'string' ? item.itemType.toUpperCase() : 'APP'),\n version: item.version,\n quantity: item.quantity,\n unitPrice: item.unitPrice,\n totalPrice: item.subtotal, // Backend uses 'subtotal', UI expects 'totalPrice'\n installed: installedProductIds.has(item.productId),\n }));\n\n return {\n id: order.id,\n orderNumber: `#${order.id.slice(-8).toUpperCase()}`, // Generate order number from ID\n items,\n subtotal,\n tax,\n total: order.total,\n status: order.status as UIOrder['status'], // Cast to union type\n createdAt: order.createdAt,\n };\n });\n\n const handleOpenInstallModal = (orderId: string, item: OrderItem) => {\n setSelectedOrderId(orderId);\n setSelectedItemId(item.id);\n setSelectedApp({\n id: item.productId,\n name: item.productName,\n icon: item.productIcon,\n type: item.productType,\n version: item.version,\n });\n setIsModalOpen(true);\n };\n\n const handleCloseModal = () => {\n setIsModalOpen(false);\n setSelectedOrderId(null);\n setSelectedApp(null);\n setSelectedItemId(null);\n };\n\n const handleInstallSuccess = (workspaceId: string, workspaceName: string) => {\n if (!selectedOrderId || !selectedItemId) return;\n\n console.log(\n `Successfully installed ${selectedApp?.name} to workspace ${workspaceName} (${workspaceId})`\n );\n\n // Reset modal state\n handleCloseModal();\n void refetchInstallations();\n };\n\n const handleInstallError = (error: Error) => {\n console.error('Installation failed:', error.message);\n // Error is displayed in modal, no need to close it\n };\n\n const handleBrowseMarketplace = () => {\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-4xl\">\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 <Package className=\"size-6 text-text-primary\" />\n <h1 className=\"text-xl font-bold text-text-primary\">\n {t('pages.orders.title', { defaultValue: 'My Orders' })}\n </h1>\n {orders.length > 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 {orders.length}\n </span>\n )}\n </div>\n </div>\n </div>\n </header>\n\n <main className=\"mx-auto max-w-4xl p-6\">\n {loading ? (\n // Loading State\n <output\n aria-label=\"Loading orders\"\n className=\"flex flex-col items-center justify-center py-16\"\n >\n <Loader2 className=\"size-12 animate-spin text-text-muted mb-4\" aria-hidden=\"true\" />\n <p className=\"text-text-muted\">Loading your orders…</p>\n </output>\n ) : error ? (\n // Error State\n <div role=\"alert\" className=\"flex flex-col items-center justify-center py-16 text-center\">\n <div className=\"mb-6 rounded-full bg-status-error-bg-subtle/10 p-6\">\n <XCircle className=\"size-16 text-status-error-text\" />\n </div>\n <h2 className=\"mb-2 text-2xl font-bold text-text-primary\">\n {t('pages.orders.failedToLoad', { defaultValue: 'Failed to load orders' })}\n </h2>\n <p className=\"mb-6 max-w-md text-text-muted\">\n {error.message || 'An error occurred while loading your orders. Please try again.'}\n </p>\n <button\n type=\"button\"\n onClick={handleBrowseMarketplace}\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 Browse Marketplace\n </button>\n </div>\n ) : orders.length === 0 ? (\n // Empty 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('pages.orders.emptyTitle', { defaultValue: 'No orders yet' })}\n </h2>\n <p className=\"mb-6 max-w-md text-text-muted\">\n You have not placed any orders yet. Browse the marketplace to discover apps and\n products!\n </p>\n <button\n type=\"button\"\n onClick={handleBrowseMarketplace}\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 Browse Marketplace\n </button>\n </div>\n ) : (\n // Orders List\n <ul className=\"space-y-6\">\n {orders.map((order) => (\n <li key={order.id}>\n <OrderCard\n order={order}\n onOpenInstallModal={handleOpenInstallModal}\n installingItem={isModalOpen ? selectedItemId : null}\n />\n </li>\n ))}\n {hasMore && (\n <li className=\"flex justify-center pt-4 list-none\">\n <button\n type=\"button\"\n onClick={loadMore}\n disabled={loading}\n className=\"flex items-center gap-2 rounded-lg border border-border-default px-6 py-2.5 text-sm font-medium text-text-primary hover:bg-bg-subtle disabled:opacity-50\"\n aria-label={t('common.loadMore', { defaultValue: 'Load more' })}\n >\n {loading ? <Loader2 className=\"size-4 animate-spin\" aria-hidden=\"true\" /> : null}\n {t('common.loadMore', { defaultValue: 'Load more' })}\n </button>\n </li>\n )}\n </ul>\n )}\n </main>\n\n {/* Install App Modal */}\n {selectedApp && (\n <InstallAppModal\n isOpen={isModalOpen}\n onClose={handleCloseModal}\n app={selectedApp}\n orderId={selectedOrderId}\n onInstallSuccess={handleInstallSuccess}\n onInstallError={handleInstallError}\n />\n )}\n </div>\n );\n};\n"],"mappings":"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"}