@burdenoff/microfe-store 2026.912.3 → 2026.912.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.
@@ -8,18 +8,18 @@ import { useOrders as o } from "../hooks/useOrders.js";
8
8
  import { useCallback as s, useMemo as c, useState as l } from "react";
9
9
  import { useNavigate as u } from "react-router";
10
10
  import { useI18n as d } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
11
- import { ArrowLeft as f, CheckCircle as p, ChevronRight as m, Clock as h, Download as g, Loader2 as _, Package as v, RefreshCw as y, ShoppingBag as b, XCircle as x } from "lucide-react";
12
- import { jsx as S, jsxs as C } from "react/jsx-runtime";
13
- import { GlassCard as ee, IllustratedEmptyState as w, PagePurpose as T } from "@burdenoff/fe-libs/ui";
11
+ import { ArrowLeft as f, CheckCircle as p, ChevronRight as m, Clock as h, Download as ee, Loader2 as g, Package as _, RefreshCw as v, ShoppingBag as y, XCircle as b } from "lucide-react";
12
+ import { jsx as x, jsxs as S } from "react/jsx-runtime";
13
+ import { GlassCard as C, IllustratedEmptyState as w, PagePurpose as te } from "@burdenoff/fe-libs/ui";
14
14
  //#region src/pages/OrdersPage.tsx
15
- function E(e) {
15
+ function T(e) {
16
16
  return typeof e == "number" && Number.isFinite(e) ? e : null;
17
17
  }
18
- var D = [
18
+ var E = [
19
19
  "COMPLETED",
20
20
  "FULFILLED",
21
21
  "PROCESSED"
22
- ], O = (e, t) => {
22
+ ], D = (e, t) => {
23
23
  switch (e) {
24
24
  case "COMPLETED":
25
25
  case "FULFILLED":
@@ -39,17 +39,17 @@ var D = [
39
39
  label: t("pages.orders.statusPending", "Pending")
40
40
  };
41
41
  case "FAILED": return {
42
- icon: x,
42
+ icon: b,
43
43
  classes: "bg-status-error-bg-subtle/15 text-status-error-text border-status-error-text/20",
44
44
  label: t("pages.orders.statusFailed", "Failed")
45
45
  };
46
46
  case "REFUNDED": return {
47
- icon: y,
47
+ icon: v,
48
48
  classes: "bg-status-warning-bg-subtle/15 text-status-warning-text border-status-warning-text/20",
49
49
  label: t("pages.orders.statusRefunded", "Refunded")
50
50
  };
51
51
  case "CANCELLED": return {
52
- icon: y,
52
+ icon: v,
53
53
  classes: "bg-bg-sunken text-text-muted border-border-default",
54
54
  label: t("pages.orders.statusCancelled", "Cancelled")
55
55
  };
@@ -59,24 +59,24 @@ var D = [
59
59
  label: e
60
60
  };
61
61
  }
62
- }, te = ({ status: e, tr: t }) => {
63
- let n = O(e, t), r = n.icon;
64
- return /* @__PURE__ */ C("span", {
62
+ }, O = ({ status: e, tr: t }) => {
63
+ let n = D(e, t), r = n.icon;
64
+ return /* @__PURE__ */ S("span", {
65
65
  className: `inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs font-semibold ${n.classes}`,
66
- children: [/* @__PURE__ */ S(r, { className: "size-3.5" }), n.label]
66
+ children: [/* @__PURE__ */ x(r, { className: "size-3.5" }), n.label]
67
67
  });
68
68
  }, k = () => {
69
- let h = u(), { basePath: y } = e(), { t: O } = d(), k = r(), { orders: A, loading: j, error: M, refetchOrders: N, hasMore: P, loadMore: F } = o(), { installations: I, refetch: ne } = a();
69
+ let h = u(), { basePath: v } = e(), { t: D } = d(), k = r(), { orders: ne, loading: A, error: j, refetchOrders: M, hasMore: N, loadMore: P } = o(), { installations: F, refetch: I } = a();
70
70
  t({
71
71
  onData: () => {
72
- N();
72
+ M();
73
73
  },
74
74
  onError: (e) => {
75
75
  console.warn("OrderStatusUpdated subscription error:", e.message);
76
76
  }
77
77
  });
78
- let [re, ie] = l(/* @__PURE__ */ new Set()), [L, R] = l("completed"), [ae, z] = l(!1), [B, V] = l(null), [H, U] = l(null), [oe, W] = l(null), G = c(() => new Set(I.flatMap((e) => e.status === "ACTIVE" ? [e.productId] : [])), [I]), K = A.map((e) => {
79
- let t = e.lineItems || [], n = t.reduce((e, t) => e + t.subtotal, 0), r = e.transaction?.metadata, i = E(r?.subtotal), a = E(r?.taxAmount), o = E(r?.total), s = i != null && o != null && e.transaction?.currency != null, c = s ? e.transaction.currency : e.currency, l = s ? i : n, u = s ? a ?? 0 : 0, d = s ? o : e.total, f = t.map((t, n) => ({
78
+ let [re, ie] = l(/* @__PURE__ */ new Set()), [L, R] = l("completed"), [ae, z] = l(!1), [B, V] = l(null), [H, U] = l(null), [oe, W] = l(null), G = c(() => new Set(F.flatMap((e) => e.status === "ACTIVE" ? [e.productId] : [])), [F]), K = ne.map((e) => {
79
+ let t = e.lineItems || [], n = t.reduce((e, t) => e + t.subtotal, 0), r = e.transaction?.metadata, i = T(r?.subtotal), a = T(r?.taxAmount), o = T(r?.total), s = i != null && o != null && e.transaction?.currency != null, c = s ? e.transaction.currency : e.currency, l = s ? i : n, u = s ? a ?? 0 : 0, d = s ? o : e.total, f = r?.paymentMethod === "CREDITS" ? T(r?.creditsUsed) : null, p = t.map((t, n) => ({
80
80
  id: `${e.id}-${n}`,
81
81
  productId: t.productId,
82
82
  productName: t.name,
@@ -91,18 +91,19 @@ var D = [
91
91
  return {
92
92
  id: e.id,
93
93
  orderNumber: `#${e.id.slice(-8).toUpperCase()}`,
94
- items: f,
94
+ items: p,
95
95
  catalogCurrency: e.currency,
96
96
  currency: c,
97
97
  subtotal: l,
98
98
  tax: u,
99
99
  total: d,
100
100
  isActualCharge: s,
101
+ creditsUsed: f,
101
102
  status: e.status,
102
103
  createdAt: e.createdAt,
103
104
  fulfillment: e.fulfillment ?? null
104
105
  };
105
- }), q = c(() => K.filter((e) => D.includes(e.status)), [K]), J = c(() => K.filter((e) => !D.includes(e.status)), [K]), Y = L === "completed" ? q : J, se = s((e) => {
106
+ }), q = c(() => K.filter((e) => E.includes(e.status)), [K]), J = c(() => K.filter((e) => !E.includes(e.status)), [K]), Y = L === "completed" ? q : J, se = s((e) => {
106
107
  ie((t) => {
107
108
  let n = new Set(t);
108
109
  return n.has(e) ? n.delete(e) : n.add(e), n;
@@ -118,36 +119,36 @@ var D = [
118
119
  }, X = () => {
119
120
  z(!1), V(null), U(null), W(null);
120
121
  }, le = (e, t) => {
121
- X(), ne();
122
+ X(), I();
122
123
  }, ue = (e) => {}, Z = () => {
123
- h(`${y}/marketplace`);
124
+ h(`${v}/marketplace`);
124
125
  }, Q = "px-4 py-3 text-sm", $ = "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wider text-text-muted";
125
- return /* @__PURE__ */ C("div", {
126
+ return /* @__PURE__ */ S("div", {
126
127
  className: "flex h-full flex-col",
127
128
  children: [
128
- /* @__PURE__ */ S("header", {
129
+ /* @__PURE__ */ x("header", {
129
130
  className: "flex-shrink-0 border-b border-border-seam bg-bg-surface px-6 py-4",
130
- children: /* @__PURE__ */ S("div", {
131
+ children: /* @__PURE__ */ x("div", {
131
132
  className: "mx-auto max-w-6xl",
132
- children: /* @__PURE__ */ S("div", {
133
+ children: /* @__PURE__ */ x("div", {
133
134
  className: "flex items-center justify-between",
134
- children: /* @__PURE__ */ C("div", {
135
+ children: /* @__PURE__ */ S("div", {
135
136
  className: "flex items-center gap-4",
136
- children: [/* @__PURE__ */ S("button", {
137
+ children: [/* @__PURE__ */ x("button", {
137
138
  type: "button",
138
139
  onClick: () => h(-1),
139
140
  "aria-label": "Go back",
140
141
  className: "cursor-pointer rounded-lg p-2 text-text-muted transition-colors hover:bg-bg-sunken hover:text-text-primary",
141
- children: /* @__PURE__ */ S(f, { className: "size-5" })
142
- }), /* @__PURE__ */ C("div", {
142
+ children: /* @__PURE__ */ x(f, { className: "size-5" })
143
+ }), /* @__PURE__ */ S("div", {
143
144
  className: "flex items-center gap-3",
144
145
  children: [
145
- /* @__PURE__ */ S(v, { className: "size-6 text-text-primary" }),
146
- /* @__PURE__ */ S("h1", {
146
+ /* @__PURE__ */ x(_, { className: "size-6 text-text-primary" }),
147
+ /* @__PURE__ */ x("h1", {
147
148
  className: "text-xl font-bold text-text-primary",
148
- children: O("pages.orders.title", { defaultValue: "My Orders" })
149
+ children: D("pages.orders.title", { defaultValue: "My Orders" })
149
150
  }),
150
- K.length > 0 && /* @__PURE__ */ S("span", {
151
+ K.length > 0 && /* @__PURE__ */ x("span", {
151
152
  className: "rounded-full bg-action-primary-bg/10 px-2.5 py-0.5 text-sm font-medium text-action-primary-bg",
152
153
  children: K.length
153
154
  })
@@ -157,115 +158,115 @@ var D = [
157
158
  })
158
159
  })
159
160
  }),
160
- /* @__PURE__ */ S("div", {
161
+ /* @__PURE__ */ x("div", {
161
162
  className: "flex-1 overflow-y-auto",
162
- children: /* @__PURE__ */ C("div", {
163
+ children: /* @__PURE__ */ S("div", {
163
164
  className: "mx-auto max-w-6xl p-6",
164
- children: [/* @__PURE__ */ S(T, {
165
+ children: [/* @__PURE__ */ x(te, {
165
166
  className: "mb-6",
166
167
  children: k("pages.orders.purpose", "A record of everything you've purchased from the marketplace. Track each order's status, review what you paid, and — once an order is complete — install the apps you bought into a workspace right from here. Come back to re-install on a new workspace or check a past receipt.")
167
- }), j && K.length === 0 ? /* @__PURE__ */ C("div", {
168
+ }), A && K.length === 0 ? /* @__PURE__ */ S("div", {
168
169
  className: "flex flex-col items-center justify-center py-24",
169
- children: [/* @__PURE__ */ S(_, {
170
+ children: [/* @__PURE__ */ x(g, {
170
171
  className: "size-12 animate-spin text-text-muted mb-4",
171
172
  "aria-hidden": "true"
172
- }), /* @__PURE__ */ S("p", {
173
+ }), /* @__PURE__ */ x("p", {
173
174
  className: "text-text-muted",
174
175
  children: k("pages.orders.loading", "Loading your orders…")
175
176
  })]
176
- }) : M ? /* @__PURE__ */ C("div", {
177
+ }) : j ? /* @__PURE__ */ S("div", {
177
178
  className: "flex flex-col items-center justify-center py-24 text-center",
178
179
  children: [
179
- /* @__PURE__ */ S("div", {
180
+ /* @__PURE__ */ x("div", {
180
181
  className: "mb-6 rounded-full bg-status-error-bg-subtle/10 p-6",
181
- children: /* @__PURE__ */ S(x, { className: "size-16 text-status-error-text" })
182
+ children: /* @__PURE__ */ x(b, { className: "size-16 text-status-error-text" })
182
183
  }),
183
- /* @__PURE__ */ S("h2", {
184
+ /* @__PURE__ */ x("h2", {
184
185
  className: "mb-2 text-2xl font-bold text-text-primary",
185
- children: O("pages.orders.failedToLoad", { defaultValue: "Failed to load orders" })
186
+ children: D("pages.orders.failedToLoad", { defaultValue: "Failed to load orders" })
186
187
  }),
187
- /* @__PURE__ */ S("p", {
188
+ /* @__PURE__ */ x("p", {
188
189
  className: "mb-6 max-w-md text-text-muted",
189
- children: M.message || k("pages.orders.errorDescription", "An error occurred while loading your orders. Please try again.")
190
+ children: j.message || k("pages.orders.errorDescription", "An error occurred while loading your orders. Please try again.")
190
191
  }),
191
- /* @__PURE__ */ C("button", {
192
+ /* @__PURE__ */ S("button", {
192
193
  type: "button",
193
194
  onClick: Z,
194
195
  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",
195
- children: [/* @__PURE__ */ S(b, { className: "size-5" }), k("pages.orders.browseMarketplace", "Browse Marketplace")]
196
+ children: [/* @__PURE__ */ x(y, { className: "size-5" }), k("pages.orders.browseMarketplace", "Browse Marketplace")]
196
197
  })
197
198
  ]
198
- }) : K.length === 0 ? /* @__PURE__ */ S(w, {
199
+ }) : K.length === 0 ? /* @__PURE__ */ x(w, {
199
200
  illustration: "empty-data",
200
- title: O("pages.orders.emptyTitle", { defaultValue: "No orders yet" }),
201
+ title: D("pages.orders.emptyTitle", { defaultValue: "No orders yet" }),
201
202
  description: k("pages.orders.emptyDescription", "You have not placed any orders yet. Browse the marketplace to discover apps and products!"),
202
- action: /* @__PURE__ */ C("button", {
203
+ action: /* @__PURE__ */ S("button", {
203
204
  type: "button",
204
205
  onClick: Z,
205
206
  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",
206
- children: [/* @__PURE__ */ S(b, { className: "size-5" }), k("pages.orders.browseMarketplace", "Browse Marketplace")]
207
+ children: [/* @__PURE__ */ x(y, { className: "size-5" }), k("pages.orders.browseMarketplace", "Browse Marketplace")]
207
208
  })
208
- }) : /* @__PURE__ */ C("div", {
209
+ }) : /* @__PURE__ */ S("div", {
209
210
  className: "space-y-4",
210
- children: [/* @__PURE__ */ C("div", {
211
+ children: [/* @__PURE__ */ S("div", {
211
212
  className: "inline-flex rounded-xl border border-border-seam bg-bg-surface p-1",
212
- children: [/* @__PURE__ */ C("button", {
213
+ children: [/* @__PURE__ */ S("button", {
213
214
  type: "button",
214
215
  onClick: () => R("completed"),
215
216
  className: `rounded-lg px-4 py-2 text-sm font-medium transition-colors ${L === "completed" ? "bg-action-primary-bg text-action-primary-text" : "text-text-muted hover:bg-bg-sunken hover:text-text-primary"}`,
216
- children: [k("pages.orders.tabCompleted", "Completed"), /* @__PURE__ */ S("span", {
217
+ children: [k("pages.orders.tabCompleted", "Completed"), /* @__PURE__ */ x("span", {
217
218
  className: "ml-2 rounded-full bg-black/10 px-2 py-0.5 text-xs",
218
219
  children: q.length
219
220
  })]
220
- }), /* @__PURE__ */ C("button", {
221
+ }), /* @__PURE__ */ S("button", {
221
222
  type: "button",
222
223
  onClick: () => R("pending"),
223
224
  className: `rounded-lg px-4 py-2 text-sm font-medium transition-colors ${L === "pending" ? "bg-action-primary-bg text-action-primary-text" : "text-text-muted hover:bg-bg-sunken hover:text-text-primary"}`,
224
- children: [k("pages.orders.tabPending", "Pending"), /* @__PURE__ */ S("span", {
225
+ children: [k("pages.orders.tabPending", "Pending"), /* @__PURE__ */ x("span", {
225
226
  className: "ml-2 rounded-full bg-black/10 px-2 py-0.5 text-xs",
226
227
  children: J.length
227
228
  })]
228
229
  })]
229
- }), Y.length === 0 ? /* @__PURE__ */ C(ee, {
230
+ }), Y.length === 0 ? /* @__PURE__ */ S(C, {
230
231
  className: "p-10 text-center",
231
232
  children: [
232
- /* @__PURE__ */ S("div", {
233
+ /* @__PURE__ */ x("div", {
233
234
  className: "mx-auto mb-4 flex size-14 items-center justify-center rounded-full bg-bg-sunken text-text-muted",
234
- children: /* @__PURE__ */ S(v, { className: "size-6" })
235
+ children: /* @__PURE__ */ x(_, { className: "size-6" })
235
236
  }),
236
- /* @__PURE__ */ S("h2", {
237
+ /* @__PURE__ */ x("h2", {
237
238
  className: "mb-2 text-lg font-semibold text-text-primary",
238
239
  children: L === "completed" ? k("pages.orders.noCompletedTitle", "No completed orders yet") : k("pages.orders.noPendingTitle", "No pending orders")
239
240
  }),
240
- /* @__PURE__ */ S("p", {
241
+ /* @__PURE__ */ x("p", {
241
242
  className: "text-sm text-text-muted",
242
243
  children: L === "completed" ? k("pages.orders.noCompletedDescription", "Completed purchases will appear here once payment is successful.") : k("pages.orders.noPendingDescription", "Orders that are pending, processing, failed, refunded, or cancelled will appear here.")
243
244
  })
244
245
  ]
245
- }) : /* @__PURE__ */ C("div", {
246
+ }) : /* @__PURE__ */ S("div", {
246
247
  className: "overflow-hidden rounded-xl border border-border-seam bg-bg-surface",
247
248
  children: [
248
- /* @__PURE__ */ C("div", {
249
+ /* @__PURE__ */ S("div", {
249
250
  className: "hidden border-b border-border-seam bg-bg-sunken/50 md:grid md:grid-cols-[40px_130px_140px_1fr_120px_140px]",
250
251
  children: [
251
- /* @__PURE__ */ S("div", { className: $ }),
252
- /* @__PURE__ */ S("div", {
252
+ /* @__PURE__ */ x("div", { className: $ }),
253
+ /* @__PURE__ */ x("div", {
253
254
  className: $,
254
255
  children: k("pages.orders.colOrder", "Order")
255
256
  }),
256
- /* @__PURE__ */ S("div", {
257
+ /* @__PURE__ */ x("div", {
257
258
  className: $,
258
259
  children: k("pages.orders.colDate", "Date")
259
260
  }),
260
- /* @__PURE__ */ S("div", {
261
+ /* @__PURE__ */ x("div", {
261
262
  className: $,
262
263
  children: k("pages.orders.colItems", "Items")
263
264
  }),
264
- /* @__PURE__ */ S("div", {
265
+ /* @__PURE__ */ x("div", {
265
266
  className: `${$} text-right`,
266
267
  children: k("pages.orders.colTotal", "Total")
267
268
  }),
268
- /* @__PURE__ */ S("div", {
269
+ /* @__PURE__ */ x("div", {
269
270
  className: `${$} text-center`,
270
271
  children: k("pages.orders.colStatus", "Status")
271
272
  })
@@ -273,22 +274,22 @@ var D = [
273
274
  }),
274
275
  Y.map((e) => {
275
276
  let t = re.has(e.id), r = e.status === "COMPLETED" || e.status === "FULFILLED" || e.status === "PROCESSED";
276
- return /* @__PURE__ */ C("div", {
277
+ return /* @__PURE__ */ S("div", {
277
278
  className: "border-b border-border-seam last:border-b-0",
278
- children: [/* @__PURE__ */ C("button", {
279
+ children: [/* @__PURE__ */ S("button", {
279
280
  type: "button",
280
281
  onClick: () => se(e.id),
281
282
  className: "grid w-full cursor-pointer grid-cols-[40px_130px_140px_1fr_120px_140px] items-center transition-colors hover:bg-bg-sunken/50 md:grid",
282
283
  children: [
283
- /* @__PURE__ */ S("div", {
284
+ /* @__PURE__ */ x("div", {
284
285
  className: `${Q} flex justify-center`,
285
- children: /* @__PURE__ */ S(m, { className: `size-4 text-text-muted transition-transform duration-200 ${t ? "rotate-90" : ""}` })
286
+ children: /* @__PURE__ */ x(m, { className: `size-4 text-text-muted transition-transform duration-200 ${t ? "rotate-90" : ""}` })
286
287
  }),
287
- /* @__PURE__ */ S("div", {
288
+ /* @__PURE__ */ x("div", {
288
289
  className: `${Q} font-medium text-text-primary`,
289
290
  children: e.orderNumber
290
291
  }),
291
- /* @__PURE__ */ S("div", {
292
+ /* @__PURE__ */ x("div", {
292
293
  className: `${Q} text-text-muted`,
293
294
  children: new Date(e.createdAt).toLocaleDateString("en-US", {
294
295
  year: "numeric",
@@ -296,61 +297,61 @@ var D = [
296
297
  day: "numeric"
297
298
  })
298
299
  }),
299
- /* @__PURE__ */ C("div", {
300
+ /* @__PURE__ */ S("div", {
300
301
  className: `${Q} text-text-muted`,
301
302
  children: [
302
303
  e.items.length,
303
304
  " ",
304
305
  e.items.length === 1 ? k("pages.orders.item", "item") : k("pages.orders.items", "items"),
305
- /* @__PURE__ */ S("span", {
306
+ /* @__PURE__ */ x("span", {
306
307
  className: "block text-xs text-text-muted/70",
307
308
  children: e.items.map((e) => e.productName).join(", ")
308
309
  })
309
310
  ]
310
311
  }),
311
- /* @__PURE__ */ S("div", {
312
+ /* @__PURE__ */ x("div", {
312
313
  className: `${Q} text-right font-semibold tabular-nums text-text-primary`,
313
314
  children: n(e.total, e.currency)
314
315
  }),
315
- /* @__PURE__ */ S("div", {
316
+ /* @__PURE__ */ x("div", {
316
317
  className: `${Q} flex justify-center`,
317
- children: /* @__PURE__ */ S(te, {
318
+ children: /* @__PURE__ */ x(O, {
318
319
  status: e.status,
319
320
  tr: k
320
321
  })
321
322
  })
322
323
  ]
323
- }), t && /* @__PURE__ */ C("div", {
324
+ }), t && /* @__PURE__ */ S("div", {
324
325
  className: "border-t border-border-seam bg-bg-sunken/30",
325
326
  children: [
326
- e.fulfillment && /* @__PURE__ */ C("div", {
327
+ e.fulfillment && /* @__PURE__ */ S("div", {
327
328
  className: "mx-4 mt-4 rounded-xl border border-border-seam bg-bg-surface px-4 py-4 md:mx-12",
328
- children: [/* @__PURE__ */ C("div", {
329
+ children: [/* @__PURE__ */ S("div", {
329
330
  className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between",
330
- children: [/* @__PURE__ */ C("div", { children: [/* @__PURE__ */ S("div", {
331
+ children: [/* @__PURE__ */ S("div", { children: [/* @__PURE__ */ x("div", {
331
332
  className: "text-sm font-semibold text-text-primary",
332
333
  children: k("pages.orders.orderTracking", "Order tracking")
333
- }), /* @__PURE__ */ C("div", {
334
+ }), /* @__PURE__ */ S("div", {
334
335
  className: "mt-1 text-xs text-text-muted",
335
336
  children: [
336
337
  e.fulfillment.status || k("pages.orders.statusPending", "Pending"),
337
338
  e.fulfillment.carrier ? ` · ${e.fulfillment.carrier}` : "",
338
339
  e.fulfillment.estimatedDeliveryDate ? ` · ${k("pages.orders.estimatedDelivery", "Est. delivery {{date}}", { date: new Date(e.fulfillment.estimatedDeliveryDate).toLocaleDateString() })}` : ""
339
340
  ]
340
- })] }), /* @__PURE__ */ C("div", {
341
+ })] }), /* @__PURE__ */ S("div", {
341
342
  className: "flex flex-col items-start gap-2 md:items-end",
342
- children: [e.fulfillment.trackingNumber && /* @__PURE__ */ S("div", {
343
+ children: [e.fulfillment.trackingNumber && /* @__PURE__ */ x("div", {
343
344
  className: "text-xs text-text-muted",
344
345
  children: k("pages.orders.trackingNumber", "Tracking #: {{number}}", { number: e.fulfillment.trackingNumber })
345
- }), e.fulfillment.trackingUrl && /* @__PURE__ */ C("a", {
346
+ }), e.fulfillment.trackingUrl && /* @__PURE__ */ S("a", {
346
347
  href: e.fulfillment.trackingUrl,
347
348
  target: "_blank",
348
349
  rel: "noreferrer",
349
350
  className: "inline-flex items-center gap-1 rounded-md border border-border-default px-3 py-1.5 text-xs font-medium text-text-primary hover:bg-bg-sunken",
350
- children: [k("pages.orders.trackPackage", "Track package"), /* @__PURE__ */ S(m, { className: "size-3.5" })]
351
+ children: [k("pages.orders.trackPackage", "Track package"), /* @__PURE__ */ x(m, { className: "size-3.5" })]
351
352
  })]
352
353
  })]
353
- }), /* @__PURE__ */ S("div", {
354
+ }), /* @__PURE__ */ x("div", {
354
355
  className: "mt-4 grid gap-2 sm:grid-cols-4",
355
356
  children: [
356
357
  {
@@ -371,7 +372,7 @@ var D = [
371
372
  }
372
373
  ].map((t) => {
373
374
  let n = e.fulfillment?.status || "PENDING";
374
- return /* @__PURE__ */ S("div", {
375
+ return /* @__PURE__ */ x("div", {
375
376
  className: `rounded-lg border px-3 py-2 text-xs font-medium ${[
376
377
  "PROCESSING",
377
378
  "READY_TO_SHIP",
@@ -390,22 +391,22 @@ var D = [
390
391
  })
391
392
  })]
392
393
  }),
393
- /* @__PURE__ */ C("div", {
394
+ /* @__PURE__ */ S("div", {
394
395
  className: "hidden grid-cols-[1fr_100px_120px_160px] gap-4 px-12 py-2 md:grid",
395
396
  children: [
396
- /* @__PURE__ */ S("span", {
397
+ /* @__PURE__ */ x("span", {
397
398
  className: "text-xs font-medium text-text-muted",
398
399
  children: k("pages.orders.colProduct", "Product")
399
400
  }),
400
- /* @__PURE__ */ S("span", {
401
+ /* @__PURE__ */ x("span", {
401
402
  className: "text-xs font-medium text-text-muted text-right",
402
403
  children: k("pages.orders.colQty", "Qty")
403
404
  }),
404
- /* @__PURE__ */ S("span", {
405
+ /* @__PURE__ */ x("span", {
405
406
  className: "text-xs font-medium text-text-muted text-right",
406
407
  children: k("pages.orders.colPrice", "Price")
407
408
  }),
408
- /* @__PURE__ */ S("span", {
409
+ /* @__PURE__ */ x("span", {
409
410
  className: "text-xs font-medium text-text-muted text-center",
410
411
  children: k("pages.orders.colAction", "Action")
411
412
  })
@@ -413,43 +414,43 @@ var D = [
413
414
  }),
414
415
  e.items.map((t) => {
415
416
  let i = t.productType !== "PHYSICAL" && t.productType !== "MERCHANDISE";
416
- return /* @__PURE__ */ C("div", {
417
+ return /* @__PURE__ */ S("div", {
417
418
  className: "grid grid-cols-[auto_1fr_auto] items-center gap-3 px-4 py-3 md:px-12 md:grid-cols-[1fr_100px_120px_160px]",
418
419
  children: [
419
- /* @__PURE__ */ C("div", {
420
+ /* @__PURE__ */ S("div", {
420
421
  className: "flex items-center gap-3 min-w-0",
421
- children: [/* @__PURE__ */ S("div", {
422
+ children: [/* @__PURE__ */ x("div", {
422
423
  className: "size-10 flex-shrink-0 overflow-hidden rounded-lg bg-bg-sunken",
423
- children: t.productIcon ? /* @__PURE__ */ S("img", {
424
+ children: t.productIcon ? /* @__PURE__ */ x("img", {
424
425
  src: t.productIcon,
425
426
  alt: t.productName,
426
427
  className: "size-full object-cover"
427
- }) : /* @__PURE__ */ S("div", {
428
+ }) : /* @__PURE__ */ x("div", {
428
429
  className: "flex size-full items-center justify-center text-sm font-bold text-text-muted",
429
430
  children: t.productName.charAt(0)
430
431
  })
431
- }), /* @__PURE__ */ C("div", {
432
+ }), /* @__PURE__ */ S("div", {
432
433
  className: "min-w-0",
433
- children: [/* @__PURE__ */ S("p", {
434
+ children: [/* @__PURE__ */ x("p", {
434
435
  className: "truncate text-sm font-medium text-text-primary",
435
436
  children: t.productName
436
- }), /* @__PURE__ */ S("span", {
437
+ }), /* @__PURE__ */ x("span", {
437
438
  className: "inline-flex items-center rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-muted",
438
439
  children: t.productType
439
440
  })]
440
441
  })]
441
442
  }),
442
- /* @__PURE__ */ S("div", {
443
+ /* @__PURE__ */ x("div", {
443
444
  className: "hidden text-right text-sm text-text-muted md:block",
444
445
  children: t.quantity
445
446
  }),
446
- /* @__PURE__ */ S("div", {
447
+ /* @__PURE__ */ x("div", {
447
448
  className: "hidden text-right text-sm font-semibold tabular-nums text-text-primary md:block",
448
449
  children: n(t.totalPrice, e.catalogCurrency)
449
450
  }),
450
- /* @__PURE__ */ S("div", {
451
+ /* @__PURE__ */ x("div", {
451
452
  className: "text-right text-sm text-text-muted md:hidden",
452
- children: /* @__PURE__ */ S("span", {
453
+ children: /* @__PURE__ */ x("span", {
453
454
  className: "tabular-nums",
454
455
  children: k("pages.orders.qtyTimesPrice", "{{qty}} × {{price}}", {
455
456
  qty: t.quantity,
@@ -457,80 +458,87 @@ var D = [
457
458
  })
458
459
  })
459
460
  }),
460
- /* @__PURE__ */ S("div", {
461
+ /* @__PURE__ */ x("div", {
461
462
  className: "flex justify-end md:justify-center",
462
- children: t.installed ? /* @__PURE__ */ C("span", {
463
+ children: t.installed ? /* @__PURE__ */ S("span", {
463
464
  className: "inline-flex items-center gap-1 rounded-lg px-3 py-1.5 text-xs font-medium text-status-success-text",
464
- children: [/* @__PURE__ */ S(p, { className: "size-3.5" }), k("pages.orders.installed", "Installed")]
465
- }) : r && i ? /* @__PURE__ */ C("button", {
465
+ children: [/* @__PURE__ */ x(p, { className: "size-3.5" }), k("pages.orders.installed", "Installed")]
466
+ }) : r && i ? /* @__PURE__ */ S("button", {
466
467
  type: "button",
467
468
  onClick: (n) => {
468
469
  n.stopPropagation(), ce(e.id, t);
469
470
  },
470
471
  className: "inline-flex cursor-pointer items-center gap-1.5 rounded-lg bg-action-primary-bg px-3 py-1.5 text-xs font-medium text-action-primary-text transition-all hover:opacity-90 active:scale-95",
471
- children: [/* @__PURE__ */ S(g, { className: "size-3.5" }), k("pages.orders.installApp", "Install App")]
472
+ children: [/* @__PURE__ */ x(ee, { className: "size-3.5" }), k("pages.orders.installApp", "Install App")]
472
473
  }) : null
473
474
  })
474
475
  ]
475
476
  }, t.id);
476
477
  }),
477
- /* @__PURE__ */ C("div", {
478
+ /* @__PURE__ */ S("div", {
478
479
  className: "border-t border-border-seam/50 px-4 py-2 md:px-12",
479
- children: [e.isActualCharge && e.currency !== e.catalogCurrency && /* @__PURE__ */ S("p", {
480
- className: "mb-1 text-right text-xs text-text-muted",
481
- children: k("pages.orders.paidInCurrency", "Listed in {{catalogCurrency}}, actually charged in {{currency}}", {
482
- catalogCurrency: e.catalogCurrency,
483
- currency: e.currency
484
- })
485
- }), /* @__PURE__ */ C("div", {
486
- className: "flex justify-end gap-6 text-xs text-text-muted",
487
- children: [
488
- /* @__PURE__ */ C("span", { children: [
489
- k("pages.orders.subtotal", "Subtotal:"),
490
- " ",
491
- /* @__PURE__ */ S("span", {
492
- className: "tabular-nums text-text-primary",
493
- children: n(e.subtotal, e.currency)
494
- })
495
- ] }),
496
- /* @__PURE__ */ C("span", { children: [
497
- k("pages.orders.tax", "Tax:"),
498
- " ",
499
- /* @__PURE__ */ S("span", {
500
- className: "tabular-nums text-text-primary",
501
- children: n(e.tax, e.currency)
502
- })
503
- ] }),
504
- /* @__PURE__ */ C("span", {
505
- className: "font-semibold",
506
- children: [
507
- k("pages.orders.total", "Total:"),
480
+ children: [
481
+ e.isActualCharge && e.currency !== e.catalogCurrency && /* @__PURE__ */ x("p", {
482
+ className: "mb-1 text-right text-xs text-text-muted",
483
+ children: k("pages.orders.paidInCurrency", "Listed in {{catalogCurrency}}, actually charged in {{currency}}", {
484
+ catalogCurrency: e.catalogCurrency,
485
+ currency: e.currency
486
+ })
487
+ }),
488
+ /* @__PURE__ */ S("div", {
489
+ className: "flex justify-end gap-6 text-xs text-text-muted",
490
+ children: [
491
+ /* @__PURE__ */ S("span", { children: [
492
+ k("pages.orders.subtotal", "Subtotal:"),
508
493
  " ",
509
- /* @__PURE__ */ S("span", {
494
+ /* @__PURE__ */ x("span", {
510
495
  className: "tabular-nums text-text-primary",
511
- children: n(e.total, e.currency)
496
+ children: n(e.subtotal, e.currency)
512
497
  })
513
- ]
514
- })
515
- ]
516
- })]
498
+ ] }),
499
+ /* @__PURE__ */ S("span", { children: [
500
+ k("pages.orders.tax", "Tax:"),
501
+ " ",
502
+ /* @__PURE__ */ x("span", {
503
+ className: "tabular-nums text-text-primary",
504
+ children: n(e.tax, e.currency)
505
+ })
506
+ ] }),
507
+ /* @__PURE__ */ S("span", {
508
+ className: "font-semibold",
509
+ children: [
510
+ k("pages.orders.total", "Total:"),
511
+ " ",
512
+ /* @__PURE__ */ x("span", {
513
+ className: "tabular-nums text-text-primary",
514
+ children: n(e.total, e.currency)
515
+ })
516
+ ]
517
+ })
518
+ ]
519
+ }),
520
+ e.creditsUsed != null && /* @__PURE__ */ x("p", {
521
+ className: "mt-1 text-right text-xs text-text-muted",
522
+ children: k("pages.orders.paidWithCredits", "Paid with {{credits}} credits", { credits: e.creditsUsed.toLocaleString() })
523
+ })
524
+ ]
517
525
  })
518
526
  ]
519
527
  })]
520
528
  }, e.id);
521
529
  }),
522
- P && /* @__PURE__ */ S("div", {
530
+ N && /* @__PURE__ */ x("div", {
523
531
  className: "flex justify-center px-4 py-5",
524
- children: /* @__PURE__ */ C("button", {
532
+ children: /* @__PURE__ */ S("button", {
525
533
  type: "button",
526
- onClick: F,
527
- disabled: j,
534
+ onClick: P,
535
+ disabled: A,
528
536
  className: "flex items-center gap-2 rounded-lg border border-border-default px-6 py-2.5 text-sm font-medium text-text-primary transition-colors hover:bg-bg-subtle disabled:opacity-50",
529
- "aria-label": O("common.loadMore", { defaultValue: "Load more" }),
530
- children: [j ? /* @__PURE__ */ S(_, {
537
+ "aria-label": D("common.loadMore", { defaultValue: "Load more" }),
538
+ children: [A ? /* @__PURE__ */ x(g, {
531
539
  className: "size-4 animate-spin",
532
540
  "aria-hidden": "true"
533
- }) : null, O("common.loadMore", { defaultValue: "Load more" })]
541
+ }) : null, D("common.loadMore", { defaultValue: "Load more" })]
534
542
  })
535
543
  })
536
544
  ]
@@ -538,7 +546,7 @@ var D = [
538
546
  })]
539
547
  })
540
548
  }),
541
- H && /* @__PURE__ */ S(i, {
549
+ H && /* @__PURE__ */ x(i, {
542
550
  isOpen: ae,
543
551
  onClose: X,
544
552
  app: H,
@@ -1 +1 @@
1
- {"version":3,"file":"OrdersPage.js","names":[],"sources":["../../src/pages/OrdersPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useMemo, useState, useCallback } from 'react';\nimport { useNavigate } from 'react-router';\nimport {\n Package,\n ArrowLeft,\n ShoppingBag,\n Download,\n CheckCircle,\n Clock,\n XCircle,\n RefreshCw,\n Loader2,\n ChevronRight,\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 { useTr } from '../shared/hooks/useTr';\nimport { GlassCard, IllustratedEmptyState, PagePurpose } 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 /** The order's own catalog-native currency — what item unitPrice/totalPrice\n * below are denominated in (the listed price), regardless of what was\n * actually charged. */\n catalogCurrency: string;\n /** Currency of subtotal/tax/total below — the actually-charged currency\n * when a payment transaction exists, otherwise catalogCurrency (e.g. an\n * unpaid order, or one paid entirely with credits). */\n currency: string;\n subtotal: number;\n tax: number;\n total: number;\n /** True when subtotal/tax/total reflect the real gateway charge\n * (transaction.metadata) rather than the order's catalog-native amounts. */\n isActualCharge: boolean;\n status:\n | 'PENDING'\n | 'PROCESSING'\n | 'COMPLETED'\n | 'FAILED'\n | 'CANCELLED'\n | 'FULFILLED'\n | 'PROCESSED'\n | 'REFUNDED';\n createdAt: string;\n fulfillment?: {\n status?: string | null;\n trackingNumber?: string | null;\n trackingUrl?: string | null;\n carrier?: string | null;\n estimatedDeliveryDate?: string | null;\n } | null;\n}\n\ntype OrdersTab = 'completed' | 'pending';\n\n/** Safely reads a finite number out of an untyped JSON metadata field. */\nfunction toFiniteNumber(value: unknown): number | null {\n return typeof value === 'number' && Number.isFinite(value) ? value : null;\n}\n\nconst SUCCESSFUL_ORDER_STATUSES: UIOrder['status'][] = ['COMPLETED', 'FULFILLED', 'PROCESSED'];\n\n/**\n * Get status badge config\n */\nconst getStatusDisplay = (\n status: UIOrder['status'],\n tr: (key: string, fallback: string) => string\n) => {\n switch (status) {\n case 'COMPLETED':\n case 'FULFILLED':\n case 'PROCESSED':\n return {\n icon: CheckCircle,\n classes:\n 'bg-status-success-bg-subtle/15 text-status-success-text border-status-success-text/20',\n label: tr('pages.orders.statusCompleted', 'Completed'),\n };\n case 'PROCESSING':\n return {\n icon: Clock,\n classes:\n 'bg-status-warning-bg-subtle/15 text-status-warning-text border-status-warning-text/20',\n label: tr('pages.orders.statusProcessing', 'Processing'),\n };\n case 'PENDING':\n return {\n icon: Clock,\n classes:\n 'bg-status-warning-bg-subtle/15 text-status-warning-text border-status-warning-text/20',\n label: tr('pages.orders.statusPending', 'Pending'),\n };\n case 'FAILED':\n return {\n icon: XCircle,\n classes: 'bg-status-error-bg-subtle/15 text-status-error-text border-status-error-text/20',\n label: tr('pages.orders.statusFailed', 'Failed'),\n };\n case 'REFUNDED':\n return {\n icon: RefreshCw,\n classes:\n 'bg-status-warning-bg-subtle/15 text-status-warning-text border-status-warning-text/20',\n label: tr('pages.orders.statusRefunded', 'Refunded'),\n };\n case 'CANCELLED':\n return {\n icon: RefreshCw,\n classes: 'bg-bg-sunken text-text-muted border-border-default',\n label: tr('pages.orders.statusCancelled', 'Cancelled'),\n };\n default:\n return {\n icon: Clock,\n classes: 'bg-bg-sunken text-text-muted border-border-default',\n label: status,\n };\n }\n};\n\n/**\n * Status badge component\n */\nconst StatusBadge: FC<{\n status: UIOrder['status'];\n tr: (key: string, fallback: string) => string;\n}> = ({ status, tr }) => {\n const display = getStatusDisplay(status, tr);\n const Icon = display.icon;\n return (\n <span\n className={`inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs font-semibold ${display.classes}`}\n >\n <Icon className=\"size-3.5\" />\n {display.label}\n </span>\n );\n};\n\n/**\n * OrdersPage component\n *\n * Displays a table of all orders with expandable rows showing line items\n * and Install App buttons for digital products.\n */\nexport const OrdersPage: FC = () => {\n const navigate = useNavigate();\n const { basePath } = useStore();\n const { t } = useI18n();\n const tr = useTr();\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 // Expanded rows tracking\n const [expandedOrders, setExpandedOrders] = useState<Set<string>>(new Set());\n const [activeTab, setActiveTab] = useState<OrdersTab>('completed');\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 const lineItems = order.lineItems || [];\n const catalogSubtotal = lineItems.reduce((sum, item) => sum + item.subtotal, 0);\n\n // Prefer the real gateway charge (BOFF-7192): order.total/currency are\n // the order's own catalog-native bookkeeping, which can differ from\n // what was actually charged — e.g. a USD-listed item charged in INR via\n // Razorpay, with GST added. The actual subtotal/tax/total live in the\n // paired transaction's metadata (see webhook handlers for how it's\n // written); transaction.amount/currency alone is only the pre-tax\n // gateway amount, not the full charge.\n const gatewayMeta = order.transaction?.metadata;\n const gatewaySubtotal = toFiniteNumber(gatewayMeta?.subtotal);\n const gatewayTax = toFiniteNumber(gatewayMeta?.taxAmount);\n const gatewayTotal = toFiniteNumber(gatewayMeta?.total);\n const hasActualCharge =\n gatewaySubtotal != null && gatewayTotal != null && order.transaction?.currency != null;\n\n const currency = hasActualCharge ? order.transaction!.currency : order.currency;\n const subtotal = hasActualCharge ? gatewaySubtotal! : catalogSubtotal;\n const tax = hasActualCharge ? (gatewayTax ?? 0) : 0;\n const total = hasActualCharge ? gatewayTotal! : order.total;\n\n const items: OrderItem[] = lineItems.map((item, index) => ({\n id: `${order.id}-${index}`,\n productId: item.productId,\n productName: item.name,\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,\n installed: installedProductIds.has(item.productId),\n }));\n\n return {\n id: order.id,\n orderNumber: `#${order.id.slice(-8).toUpperCase()}`,\n items,\n catalogCurrency: order.currency,\n currency,\n subtotal,\n tax,\n total,\n isActualCharge: hasActualCharge,\n status: order.status as UIOrder['status'],\n createdAt: order.createdAt,\n fulfillment: order.fulfillment ?? null,\n };\n });\n\n const completedOrders = useMemo(\n () => orders.filter((order) => SUCCESSFUL_ORDER_STATUSES.includes(order.status)),\n [orders]\n );\n\n const pendingOrders = useMemo(\n () => orders.filter((order) => !SUCCESSFUL_ORDER_STATUSES.includes(order.status)),\n [orders]\n );\n\n const visibleOrders = activeTab === 'completed' ? completedOrders : pendingOrders;\n\n const toggleExpand = useCallback((orderId: string) => {\n setExpandedOrders((prev) => {\n const next = new Set(prev);\n if (next.has(orderId)) {\n next.delete(orderId);\n } else {\n next.add(orderId);\n }\n return next;\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 handleCloseModal();\n void refetchInstallations();\n };\n\n const handleInstallError = (_error: Error) => {\n // Error is displayed in modal\n };\n\n const handleBrowseMarketplace = () => {\n navigate(`${basePath}/marketplace`);\n };\n\n // ──── Shared table cell classes ────\n const cellCls = 'px-4 py-3 text-sm';\n const headerCls =\n 'px-4 py-3 text-left text-xs font-semibold uppercase tracking-wider text-text-muted';\n\n return (\n <div className=\"flex h-full flex-col\">\n {/* Header */}\n <header className=\"flex-shrink-0 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 justify-between\">\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/10 px-2.5 py-0.5 text-sm font-medium text-action-primary-bg\">\n {orders.length}\n </span>\n )}\n </div>\n </div>\n </div>\n </div>\n </header>\n\n {/* Scrollable content area */}\n <div className=\"flex-1 overflow-y-auto\">\n <div className=\"mx-auto max-w-6xl p-6\">\n <PagePurpose className=\"mb-6\">\n {tr(\n 'pages.orders.purpose',\n \"A record of everything you've purchased from the marketplace. Track each order's status, review what you paid, and — once an order is complete — install the apps you bought into a workspace right from here. Come back to re-install on a new workspace or check a past receipt.\"\n )}\n </PagePurpose>\n\n {loading && orders.length === 0 ? (\n // ── Loading state ──\n <div className=\"flex flex-col items-center justify-center py-24\">\n <Loader2 className=\"size-12 animate-spin text-text-muted mb-4\" aria-hidden=\"true\" />\n <p className=\"text-text-muted\">\n {tr('pages.orders.loading', 'Loading your orders…')}\n </p>\n </div>\n ) : error ? (\n // ── Error state ──\n <div className=\"flex flex-col items-center justify-center py-24 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 ||\n tr(\n 'pages.orders.errorDescription',\n 'An error occurred while loading your orders. Please try again.'\n )}\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 {tr('pages.orders.browseMarketplace', '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={tr(\n 'pages.orders.emptyDescription',\n 'You have not placed any orders yet. Browse the marketplace to discover apps and products!'\n )}\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 {tr('pages.orders.browseMarketplace', 'Browse Marketplace')}\n </button>\n }\n />\n ) : (\n // ── Table ──\n <div className=\"space-y-4\">\n <div className=\"inline-flex rounded-xl border border-border-seam bg-bg-surface p-1\">\n <button\n type=\"button\"\n onClick={() => setActiveTab('completed')}\n className={`rounded-lg px-4 py-2 text-sm font-medium transition-colors ${\n activeTab === 'completed'\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'text-text-muted hover:bg-bg-sunken hover:text-text-primary'\n }`}\n >\n {tr('pages.orders.tabCompleted', 'Completed')}\n <span className=\"ml-2 rounded-full bg-black/10 px-2 py-0.5 text-xs\">\n {completedOrders.length}\n </span>\n </button>\n <button\n type=\"button\"\n onClick={() => setActiveTab('pending')}\n className={`rounded-lg px-4 py-2 text-sm font-medium transition-colors ${\n activeTab === 'pending'\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'text-text-muted hover:bg-bg-sunken hover:text-text-primary'\n }`}\n >\n {tr('pages.orders.tabPending', 'Pending')}\n <span className=\"ml-2 rounded-full bg-black/10 px-2 py-0.5 text-xs\">\n {pendingOrders.length}\n </span>\n </button>\n </div>\n\n {visibleOrders.length === 0 ? (\n <GlassCard className=\"p-10 text-center\">\n <div className=\"mx-auto mb-4 flex size-14 items-center justify-center rounded-full bg-bg-sunken text-text-muted\">\n <Package className=\"size-6\" />\n </div>\n <h2 className=\"mb-2 text-lg font-semibold text-text-primary\">\n {activeTab === 'completed'\n ? tr('pages.orders.noCompletedTitle', 'No completed orders yet')\n : tr('pages.orders.noPendingTitle', 'No pending orders')}\n </h2>\n <p className=\"text-sm text-text-muted\">\n {activeTab === 'completed'\n ? tr(\n 'pages.orders.noCompletedDescription',\n 'Completed purchases will appear here once payment is successful.'\n )\n : tr(\n 'pages.orders.noPendingDescription',\n 'Orders that are pending, processing, failed, refunded, or cancelled will appear here.'\n )}\n </p>\n </GlassCard>\n ) : (\n <div className=\"overflow-hidden rounded-xl border border-border-seam bg-bg-surface\">\n {/* Table Header */}\n <div className=\"hidden border-b border-border-seam bg-bg-sunken/50 md:grid md:grid-cols-[40px_130px_140px_1fr_120px_140px]\">\n <div className={headerCls} />\n <div className={headerCls}>{tr('pages.orders.colOrder', 'Order')}</div>\n <div className={headerCls}>{tr('pages.orders.colDate', 'Date')}</div>\n <div className={headerCls}>{tr('pages.orders.colItems', 'Items')}</div>\n <div className={`${headerCls} text-right`}>\n {tr('pages.orders.colTotal', 'Total')}\n </div>\n <div className={`${headerCls} text-center`}>\n {tr('pages.orders.colStatus', 'Status')}\n </div>\n </div>\n\n {/* Table Body */}\n {visibleOrders.map((order) => {\n const isExpanded = expandedOrders.has(order.id);\n const isSuccessful =\n order.status === 'COMPLETED' ||\n order.status === 'FULFILLED' ||\n order.status === 'PROCESSED';\n\n return (\n <div key={order.id} className=\"border-b border-border-seam last:border-b-0\">\n {/* Order Row */}\n <button\n type=\"button\"\n onClick={() => toggleExpand(order.id)}\n className=\"grid w-full cursor-pointer grid-cols-[40px_130px_140px_1fr_120px_140px] items-center transition-colors hover:bg-bg-sunken/50 md:grid\"\n >\n {/* Expand/collapse chevron */}\n <div className={`${cellCls} flex justify-center`}>\n <ChevronRight\n className={`size-4 text-text-muted transition-transform duration-200 ${\n isExpanded ? 'rotate-90' : ''\n }`}\n />\n </div>\n\n {/* Order number */}\n <div className={`${cellCls} font-medium text-text-primary`}>\n {order.orderNumber}\n </div>\n\n {/* Date */}\n <div className={`${cellCls} text-text-muted`}>\n {new Date(order.createdAt).toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n })}\n </div>\n\n {/* Items summary */}\n <div className={`${cellCls} text-text-muted`}>\n {order.items.length}{' '}\n {order.items.length === 1\n ? tr('pages.orders.item', 'item')\n : tr('pages.orders.items', 'items')}\n <span className=\"block text-xs text-text-muted/70\">\n {order.items.map((i) => i.productName).join(', ')}\n </span>\n </div>\n\n {/* Total */}\n <div\n className={`${cellCls} text-right font-semibold tabular-nums text-text-primary`}\n >\n {formatPrice(order.total, order.currency)}\n </div>\n\n {/* Status */}\n <div className={`${cellCls} flex justify-center`}>\n <StatusBadge status={order.status} tr={tr} />\n </div>\n </button>\n\n {/* Expanded: Line items */}\n {isExpanded && (\n <div className=\"border-t border-border-seam bg-bg-sunken/30\">\n {order.fulfillment && (\n <div className=\"mx-4 mt-4 rounded-xl border border-border-seam bg-bg-surface px-4 py-4 md:mx-12\">\n <div className=\"flex flex-col gap-3 md:flex-row md:items-center md:justify-between\">\n <div>\n <div className=\"text-sm font-semibold text-text-primary\">\n {tr('pages.orders.orderTracking', 'Order tracking')}\n </div>\n <div className=\"mt-1 text-xs text-text-muted\">\n {order.fulfillment.status ||\n tr('pages.orders.statusPending', 'Pending')}\n {order.fulfillment.carrier\n ? ` · ${order.fulfillment.carrier}`\n : ''}\n {order.fulfillment.estimatedDeliveryDate\n ? ` · ${tr('pages.orders.estimatedDelivery', 'Est. delivery {{date}}', { date: new Date(order.fulfillment.estimatedDeliveryDate).toLocaleDateString() })}`\n : ''}\n </div>\n </div>\n\n <div className=\"flex flex-col items-start gap-2 md:items-end\">\n {order.fulfillment.trackingNumber && (\n <div className=\"text-xs text-text-muted\">\n {tr(\n 'pages.orders.trackingNumber',\n 'Tracking #: {{number}}',\n { number: order.fulfillment.trackingNumber }\n )}\n </div>\n )}\n {order.fulfillment.trackingUrl && (\n <a\n href={order.fulfillment.trackingUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"inline-flex items-center gap-1 rounded-md border border-border-default px-3 py-1.5 text-xs font-medium text-text-primary hover:bg-bg-sunken\"\n >\n {tr('pages.orders.trackPackage', 'Track package')}\n <ChevronRight className=\"size-3.5\" />\n </a>\n )}\n </div>\n </div>\n\n <div className=\"mt-4 grid gap-2 sm:grid-cols-4\">\n {[\n {\n key: 'PROCESSING',\n label: tr('pages.orders.stepProcessing', 'Processing'),\n },\n {\n key: 'SHIPPED',\n label: tr('pages.orders.stepShipped', 'Shipped'),\n },\n {\n key: 'OUT_FOR_DELIVERY',\n label: tr(\n 'pages.orders.stepOutForDelivery',\n 'Out for delivery'\n ),\n },\n {\n key: 'DELIVERED',\n label: tr('pages.orders.stepDelivered', 'Delivered'),\n },\n ].map((step) => {\n const current = order.fulfillment?.status || 'PENDING';\n const reached =\n [\n 'PROCESSING',\n 'READY_TO_SHIP',\n 'SHIPPED',\n 'IN_TRANSIT',\n 'OUT_FOR_DELIVERY',\n 'DELIVERED',\n ].indexOf(current) >=\n [\n 'PROCESSING',\n 'SHIPPED',\n 'OUT_FOR_DELIVERY',\n 'DELIVERED',\n ].indexOf(step.key);\n return (\n <div\n key={step.key}\n className={`rounded-lg border px-3 py-2 text-xs font-medium ${\n reached\n ? 'border-status-success-border bg-status-success-bg-subtle text-status-success-text'\n : 'border-border-seam bg-bg-sunken/40 text-text-muted'\n }`}\n >\n {step.label}\n </div>\n );\n })}\n </div>\n </div>\n )}\n\n {/* Column headers for items */}\n <div className=\"hidden grid-cols-[1fr_100px_120px_160px] gap-4 px-12 py-2 md:grid\">\n <span className=\"text-xs font-medium text-text-muted\">\n {tr('pages.orders.colProduct', 'Product')}\n </span>\n <span className=\"text-xs font-medium text-text-muted text-right\">\n {tr('pages.orders.colQty', 'Qty')}\n </span>\n <span className=\"text-xs font-medium text-text-muted text-right\">\n {tr('pages.orders.colPrice', 'Price')}\n </span>\n <span className=\"text-xs font-medium text-text-muted text-center\">\n {tr('pages.orders.colAction', 'Action')}\n </span>\n </div>\n\n {order.items.map((item) => {\n const isInstallable =\n item.productType !== 'PHYSICAL' &&\n item.productType !== 'MERCHANDISE';\n\n return (\n <div\n key={item.id}\n className=\"grid grid-cols-[auto_1fr_auto] items-center gap-3 px-4 py-3 md:px-12 md:grid-cols-[1fr_100px_120px_160px]\"\n >\n {/* Product info */}\n <div className=\"flex items-center gap-3 min-w-0\">\n <div className=\"size-10 flex-shrink-0 overflow-hidden rounded-lg bg-bg-sunken\">\n {item.productIcon ? (\n <img\n src={item.productIcon}\n alt={item.productName}\n className=\"size-full object-cover\"\n />\n ) : (\n <div className=\"flex size-full items-center justify-center text-sm font-bold text-text-muted\">\n {item.productName.charAt(0)}\n </div>\n )}\n </div>\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-text-primary\">\n {item.productName}\n </p>\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 </div>\n </div>\n\n {/* Quantity */}\n <div className=\"hidden text-right text-sm text-text-muted md:block\">\n {item.quantity}\n </div>\n\n {/* Price */}\n <div className=\"hidden text-right text-sm font-semibold tabular-nums text-text-primary md:block\">\n {formatPrice(item.totalPrice, order.catalogCurrency)}\n </div>\n\n {/* Mobile price + qty */}\n <div className=\"text-right text-sm text-text-muted md:hidden\">\n <span className=\"tabular-nums\">\n {tr('pages.orders.qtyTimesPrice', '{{qty}} × {{price}}', {\n qty: item.quantity,\n price: formatPrice(item.unitPrice, order.catalogCurrency),\n })}\n </span>\n </div>\n\n {/* Install button */}\n <div className=\"flex justify-end md:justify-center\">\n {item.installed ? (\n <span className=\"inline-flex items-center gap-1 rounded-lg px-3 py-1.5 text-xs font-medium text-status-success-text\">\n <CheckCircle className=\"size-3.5\" />\n {tr('pages.orders.installed', 'Installed')}\n </span>\n ) : isSuccessful && isInstallable ? (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n handleOpenInstallModal(order.id, item);\n }}\n className=\"inline-flex cursor-pointer items-center gap-1.5 rounded-lg bg-action-primary-bg px-3 py-1.5 text-xs font-medium text-action-primary-text transition-all hover:opacity-90 active:scale-95\"\n >\n <Download className=\"size-3.5\" />\n {tr('pages.orders.installApp', 'Install App')}\n </button>\n ) : null}\n </div>\n </div>\n );\n })}\n\n {/* Order summary footer */}\n <div className=\"border-t border-border-seam/50 px-4 py-2 md:px-12\">\n {order.isActualCharge && order.currency !== order.catalogCurrency && (\n <p className=\"mb-1 text-right text-xs text-text-muted\">\n {tr(\n 'pages.orders.paidInCurrency',\n 'Listed in {{catalogCurrency}}, actually charged in {{currency}}',\n {\n catalogCurrency: order.catalogCurrency,\n currency: order.currency,\n }\n )}\n </p>\n )}\n <div className=\"flex justify-end gap-6 text-xs text-text-muted\">\n <span>\n {tr('pages.orders.subtotal', 'Subtotal:')}{' '}\n <span className=\"tabular-nums text-text-primary\">\n {formatPrice(order.subtotal, order.currency)}\n </span>\n </span>\n <span>\n {tr('pages.orders.tax', 'Tax:')}{' '}\n <span className=\"tabular-nums text-text-primary\">\n {formatPrice(order.tax, order.currency)}\n </span>\n </span>\n <span className=\"font-semibold\">\n {tr('pages.orders.total', 'Total:')}{' '}\n <span className=\"tabular-nums text-text-primary\">\n {formatPrice(order.total, order.currency)}\n </span>\n </span>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n })}\n\n {/* Load More */}\n {hasMore && (\n <div className=\"flex justify-center px-4 py-5\">\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 transition-colors hover:bg-bg-subtle disabled:opacity-50\"\n aria-label={t('common.loadMore', { defaultValue: 'Load more' })}\n >\n {loading ? (\n <Loader2 className=\"size-4 animate-spin\" aria-hidden=\"true\" />\n ) : null}\n {t('common.loadMore', { defaultValue: 'Load more' })}\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n )}\n </div>\n </div>\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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"}
1
+ {"version":3,"file":"OrdersPage.js","names":[],"sources":["../../src/pages/OrdersPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useMemo, useState, useCallback } from 'react';\nimport { useNavigate } from 'react-router';\nimport {\n Package,\n ArrowLeft,\n ShoppingBag,\n Download,\n CheckCircle,\n Clock,\n XCircle,\n RefreshCw,\n Loader2,\n ChevronRight,\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 { useTr } from '../shared/hooks/useTr';\nimport { GlassCard, IllustratedEmptyState, PagePurpose } 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 /** The order's own catalog-native currency — what item unitPrice/totalPrice\n * below are denominated in (the listed price), regardless of what was\n * actually charged. */\n catalogCurrency: string;\n /** Currency of subtotal/tax/total below — the actually-charged currency\n * when a payment transaction exists, otherwise catalogCurrency (e.g. an\n * unpaid order, or one paid entirely with credits). */\n currency: string;\n subtotal: number;\n tax: number;\n total: number;\n /** True when subtotal/tax/total reflect the real gateway charge\n * (transaction.metadata) rather than the order's catalog-native amounts. */\n isActualCharge: boolean;\n /** Credits actually spent, when this order was paid with credits\n * (transaction.metadata.paymentMethod === 'CREDITS'). null otherwise. */\n creditsUsed: number | null;\n status:\n | 'PENDING'\n | 'PROCESSING'\n | 'COMPLETED'\n | 'FAILED'\n | 'CANCELLED'\n | 'FULFILLED'\n | 'PROCESSED'\n | 'REFUNDED';\n createdAt: string;\n fulfillment?: {\n status?: string | null;\n trackingNumber?: string | null;\n trackingUrl?: string | null;\n carrier?: string | null;\n estimatedDeliveryDate?: string | null;\n } | null;\n}\n\ntype OrdersTab = 'completed' | 'pending';\n\n/** Safely reads a finite number out of an untyped JSON metadata field. */\nfunction toFiniteNumber(value: unknown): number | null {\n return typeof value === 'number' && Number.isFinite(value) ? value : null;\n}\n\nconst SUCCESSFUL_ORDER_STATUSES: UIOrder['status'][] = ['COMPLETED', 'FULFILLED', 'PROCESSED'];\n\n/**\n * Get status badge config\n */\nconst getStatusDisplay = (\n status: UIOrder['status'],\n tr: (key: string, fallback: string) => string\n) => {\n switch (status) {\n case 'COMPLETED':\n case 'FULFILLED':\n case 'PROCESSED':\n return {\n icon: CheckCircle,\n classes:\n 'bg-status-success-bg-subtle/15 text-status-success-text border-status-success-text/20',\n label: tr('pages.orders.statusCompleted', 'Completed'),\n };\n case 'PROCESSING':\n return {\n icon: Clock,\n classes:\n 'bg-status-warning-bg-subtle/15 text-status-warning-text border-status-warning-text/20',\n label: tr('pages.orders.statusProcessing', 'Processing'),\n };\n case 'PENDING':\n return {\n icon: Clock,\n classes:\n 'bg-status-warning-bg-subtle/15 text-status-warning-text border-status-warning-text/20',\n label: tr('pages.orders.statusPending', 'Pending'),\n };\n case 'FAILED':\n return {\n icon: XCircle,\n classes: 'bg-status-error-bg-subtle/15 text-status-error-text border-status-error-text/20',\n label: tr('pages.orders.statusFailed', 'Failed'),\n };\n case 'REFUNDED':\n return {\n icon: RefreshCw,\n classes:\n 'bg-status-warning-bg-subtle/15 text-status-warning-text border-status-warning-text/20',\n label: tr('pages.orders.statusRefunded', 'Refunded'),\n };\n case 'CANCELLED':\n return {\n icon: RefreshCw,\n classes: 'bg-bg-sunken text-text-muted border-border-default',\n label: tr('pages.orders.statusCancelled', 'Cancelled'),\n };\n default:\n return {\n icon: Clock,\n classes: 'bg-bg-sunken text-text-muted border-border-default',\n label: status,\n };\n }\n};\n\n/**\n * Status badge component\n */\nconst StatusBadge: FC<{\n status: UIOrder['status'];\n tr: (key: string, fallback: string) => string;\n}> = ({ status, tr }) => {\n const display = getStatusDisplay(status, tr);\n const Icon = display.icon;\n return (\n <span\n className={`inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs font-semibold ${display.classes}`}\n >\n <Icon className=\"size-3.5\" />\n {display.label}\n </span>\n );\n};\n\n/**\n * OrdersPage component\n *\n * Displays a table of all orders with expandable rows showing line items\n * and Install App buttons for digital products.\n */\nexport const OrdersPage: FC = () => {\n const navigate = useNavigate();\n const { basePath } = useStore();\n const { t } = useI18n();\n const tr = useTr();\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 // Expanded rows tracking\n const [expandedOrders, setExpandedOrders] = useState<Set<string>>(new Set());\n const [activeTab, setActiveTab] = useState<OrdersTab>('completed');\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 const lineItems = order.lineItems || [];\n const catalogSubtotal = lineItems.reduce((sum, item) => sum + item.subtotal, 0);\n\n // Prefer the real gateway charge (BOFF-7192): order.total/currency are\n // the order's own catalog-native bookkeeping, which can differ from\n // what was actually charged — e.g. a USD-listed item charged in INR via\n // Razorpay, with GST added. The actual subtotal/tax/total live in the\n // paired transaction's metadata (see webhook handlers for how it's\n // written); transaction.amount/currency alone is only the pre-tax\n // gateway amount, not the full charge.\n const gatewayMeta = order.transaction?.metadata;\n const gatewaySubtotal = toFiniteNumber(gatewayMeta?.subtotal);\n const gatewayTax = toFiniteNumber(gatewayMeta?.taxAmount);\n const gatewayTotal = toFiniteNumber(gatewayMeta?.total);\n const hasActualCharge =\n gatewaySubtotal != null && gatewayTotal != null && order.transaction?.currency != null;\n\n const currency = hasActualCharge ? order.transaction!.currency : order.currency;\n const subtotal = hasActualCharge ? gatewaySubtotal! : catalogSubtotal;\n const tax = hasActualCharge ? (gatewayTax ?? 0) : 0;\n const total = hasActualCharge ? gatewayTotal! : order.total;\n\n const creditsUsed =\n gatewayMeta?.paymentMethod === 'CREDITS' ? toFiniteNumber(gatewayMeta?.creditsUsed) : null;\n\n const items: OrderItem[] = lineItems.map((item, index) => ({\n id: `${order.id}-${index}`,\n productId: item.productId,\n productName: item.name,\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,\n installed: installedProductIds.has(item.productId),\n }));\n\n return {\n id: order.id,\n orderNumber: `#${order.id.slice(-8).toUpperCase()}`,\n items,\n catalogCurrency: order.currency,\n currency,\n subtotal,\n tax,\n total,\n isActualCharge: hasActualCharge,\n creditsUsed,\n status: order.status as UIOrder['status'],\n createdAt: order.createdAt,\n fulfillment: order.fulfillment ?? null,\n };\n });\n\n const completedOrders = useMemo(\n () => orders.filter((order) => SUCCESSFUL_ORDER_STATUSES.includes(order.status)),\n [orders]\n );\n\n const pendingOrders = useMemo(\n () => orders.filter((order) => !SUCCESSFUL_ORDER_STATUSES.includes(order.status)),\n [orders]\n );\n\n const visibleOrders = activeTab === 'completed' ? completedOrders : pendingOrders;\n\n const toggleExpand = useCallback((orderId: string) => {\n setExpandedOrders((prev) => {\n const next = new Set(prev);\n if (next.has(orderId)) {\n next.delete(orderId);\n } else {\n next.add(orderId);\n }\n return next;\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 handleCloseModal();\n void refetchInstallations();\n };\n\n const handleInstallError = (_error: Error) => {\n // Error is displayed in modal\n };\n\n const handleBrowseMarketplace = () => {\n navigate(`${basePath}/marketplace`);\n };\n\n // ──── Shared table cell classes ────\n const cellCls = 'px-4 py-3 text-sm';\n const headerCls =\n 'px-4 py-3 text-left text-xs font-semibold uppercase tracking-wider text-text-muted';\n\n return (\n <div className=\"flex h-full flex-col\">\n {/* Header */}\n <header className=\"flex-shrink-0 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 justify-between\">\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/10 px-2.5 py-0.5 text-sm font-medium text-action-primary-bg\">\n {orders.length}\n </span>\n )}\n </div>\n </div>\n </div>\n </div>\n </header>\n\n {/* Scrollable content area */}\n <div className=\"flex-1 overflow-y-auto\">\n <div className=\"mx-auto max-w-6xl p-6\">\n <PagePurpose className=\"mb-6\">\n {tr(\n 'pages.orders.purpose',\n \"A record of everything you've purchased from the marketplace. Track each order's status, review what you paid, and — once an order is complete — install the apps you bought into a workspace right from here. Come back to re-install on a new workspace or check a past receipt.\"\n )}\n </PagePurpose>\n\n {loading && orders.length === 0 ? (\n // ── Loading state ──\n <div className=\"flex flex-col items-center justify-center py-24\">\n <Loader2 className=\"size-12 animate-spin text-text-muted mb-4\" aria-hidden=\"true\" />\n <p className=\"text-text-muted\">\n {tr('pages.orders.loading', 'Loading your orders…')}\n </p>\n </div>\n ) : error ? (\n // ── Error state ──\n <div className=\"flex flex-col items-center justify-center py-24 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 ||\n tr(\n 'pages.orders.errorDescription',\n 'An error occurred while loading your orders. Please try again.'\n )}\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 {tr('pages.orders.browseMarketplace', '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={tr(\n 'pages.orders.emptyDescription',\n 'You have not placed any orders yet. Browse the marketplace to discover apps and products!'\n )}\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 {tr('pages.orders.browseMarketplace', 'Browse Marketplace')}\n </button>\n }\n />\n ) : (\n // ── Table ──\n <div className=\"space-y-4\">\n <div className=\"inline-flex rounded-xl border border-border-seam bg-bg-surface p-1\">\n <button\n type=\"button\"\n onClick={() => setActiveTab('completed')}\n className={`rounded-lg px-4 py-2 text-sm font-medium transition-colors ${\n activeTab === 'completed'\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'text-text-muted hover:bg-bg-sunken hover:text-text-primary'\n }`}\n >\n {tr('pages.orders.tabCompleted', 'Completed')}\n <span className=\"ml-2 rounded-full bg-black/10 px-2 py-0.5 text-xs\">\n {completedOrders.length}\n </span>\n </button>\n <button\n type=\"button\"\n onClick={() => setActiveTab('pending')}\n className={`rounded-lg px-4 py-2 text-sm font-medium transition-colors ${\n activeTab === 'pending'\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'text-text-muted hover:bg-bg-sunken hover:text-text-primary'\n }`}\n >\n {tr('pages.orders.tabPending', 'Pending')}\n <span className=\"ml-2 rounded-full bg-black/10 px-2 py-0.5 text-xs\">\n {pendingOrders.length}\n </span>\n </button>\n </div>\n\n {visibleOrders.length === 0 ? (\n <GlassCard className=\"p-10 text-center\">\n <div className=\"mx-auto mb-4 flex size-14 items-center justify-center rounded-full bg-bg-sunken text-text-muted\">\n <Package className=\"size-6\" />\n </div>\n <h2 className=\"mb-2 text-lg font-semibold text-text-primary\">\n {activeTab === 'completed'\n ? tr('pages.orders.noCompletedTitle', 'No completed orders yet')\n : tr('pages.orders.noPendingTitle', 'No pending orders')}\n </h2>\n <p className=\"text-sm text-text-muted\">\n {activeTab === 'completed'\n ? tr(\n 'pages.orders.noCompletedDescription',\n 'Completed purchases will appear here once payment is successful.'\n )\n : tr(\n 'pages.orders.noPendingDescription',\n 'Orders that are pending, processing, failed, refunded, or cancelled will appear here.'\n )}\n </p>\n </GlassCard>\n ) : (\n <div className=\"overflow-hidden rounded-xl border border-border-seam bg-bg-surface\">\n {/* Table Header */}\n <div className=\"hidden border-b border-border-seam bg-bg-sunken/50 md:grid md:grid-cols-[40px_130px_140px_1fr_120px_140px]\">\n <div className={headerCls} />\n <div className={headerCls}>{tr('pages.orders.colOrder', 'Order')}</div>\n <div className={headerCls}>{tr('pages.orders.colDate', 'Date')}</div>\n <div className={headerCls}>{tr('pages.orders.colItems', 'Items')}</div>\n <div className={`${headerCls} text-right`}>\n {tr('pages.orders.colTotal', 'Total')}\n </div>\n <div className={`${headerCls} text-center`}>\n {tr('pages.orders.colStatus', 'Status')}\n </div>\n </div>\n\n {/* Table Body */}\n {visibleOrders.map((order) => {\n const isExpanded = expandedOrders.has(order.id);\n const isSuccessful =\n order.status === 'COMPLETED' ||\n order.status === 'FULFILLED' ||\n order.status === 'PROCESSED';\n\n return (\n <div key={order.id} className=\"border-b border-border-seam last:border-b-0\">\n {/* Order Row */}\n <button\n type=\"button\"\n onClick={() => toggleExpand(order.id)}\n className=\"grid w-full cursor-pointer grid-cols-[40px_130px_140px_1fr_120px_140px] items-center transition-colors hover:bg-bg-sunken/50 md:grid\"\n >\n {/* Expand/collapse chevron */}\n <div className={`${cellCls} flex justify-center`}>\n <ChevronRight\n className={`size-4 text-text-muted transition-transform duration-200 ${\n isExpanded ? 'rotate-90' : ''\n }`}\n />\n </div>\n\n {/* Order number */}\n <div className={`${cellCls} font-medium text-text-primary`}>\n {order.orderNumber}\n </div>\n\n {/* Date */}\n <div className={`${cellCls} text-text-muted`}>\n {new Date(order.createdAt).toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n })}\n </div>\n\n {/* Items summary */}\n <div className={`${cellCls} text-text-muted`}>\n {order.items.length}{' '}\n {order.items.length === 1\n ? tr('pages.orders.item', 'item')\n : tr('pages.orders.items', 'items')}\n <span className=\"block text-xs text-text-muted/70\">\n {order.items.map((i) => i.productName).join(', ')}\n </span>\n </div>\n\n {/* Total */}\n <div\n className={`${cellCls} text-right font-semibold tabular-nums text-text-primary`}\n >\n {formatPrice(order.total, order.currency)}\n </div>\n\n {/* Status */}\n <div className={`${cellCls} flex justify-center`}>\n <StatusBadge status={order.status} tr={tr} />\n </div>\n </button>\n\n {/* Expanded: Line items */}\n {isExpanded && (\n <div className=\"border-t border-border-seam bg-bg-sunken/30\">\n {order.fulfillment && (\n <div className=\"mx-4 mt-4 rounded-xl border border-border-seam bg-bg-surface px-4 py-4 md:mx-12\">\n <div className=\"flex flex-col gap-3 md:flex-row md:items-center md:justify-between\">\n <div>\n <div className=\"text-sm font-semibold text-text-primary\">\n {tr('pages.orders.orderTracking', 'Order tracking')}\n </div>\n <div className=\"mt-1 text-xs text-text-muted\">\n {order.fulfillment.status ||\n tr('pages.orders.statusPending', 'Pending')}\n {order.fulfillment.carrier\n ? ` · ${order.fulfillment.carrier}`\n : ''}\n {order.fulfillment.estimatedDeliveryDate\n ? ` · ${tr('pages.orders.estimatedDelivery', 'Est. delivery {{date}}', { date: new Date(order.fulfillment.estimatedDeliveryDate).toLocaleDateString() })}`\n : ''}\n </div>\n </div>\n\n <div className=\"flex flex-col items-start gap-2 md:items-end\">\n {order.fulfillment.trackingNumber && (\n <div className=\"text-xs text-text-muted\">\n {tr(\n 'pages.orders.trackingNumber',\n 'Tracking #: {{number}}',\n { number: order.fulfillment.trackingNumber }\n )}\n </div>\n )}\n {order.fulfillment.trackingUrl && (\n <a\n href={order.fulfillment.trackingUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"inline-flex items-center gap-1 rounded-md border border-border-default px-3 py-1.5 text-xs font-medium text-text-primary hover:bg-bg-sunken\"\n >\n {tr('pages.orders.trackPackage', 'Track package')}\n <ChevronRight className=\"size-3.5\" />\n </a>\n )}\n </div>\n </div>\n\n <div className=\"mt-4 grid gap-2 sm:grid-cols-4\">\n {[\n {\n key: 'PROCESSING',\n label: tr('pages.orders.stepProcessing', 'Processing'),\n },\n {\n key: 'SHIPPED',\n label: tr('pages.orders.stepShipped', 'Shipped'),\n },\n {\n key: 'OUT_FOR_DELIVERY',\n label: tr(\n 'pages.orders.stepOutForDelivery',\n 'Out for delivery'\n ),\n },\n {\n key: 'DELIVERED',\n label: tr('pages.orders.stepDelivered', 'Delivered'),\n },\n ].map((step) => {\n const current = order.fulfillment?.status || 'PENDING';\n const reached =\n [\n 'PROCESSING',\n 'READY_TO_SHIP',\n 'SHIPPED',\n 'IN_TRANSIT',\n 'OUT_FOR_DELIVERY',\n 'DELIVERED',\n ].indexOf(current) >=\n [\n 'PROCESSING',\n 'SHIPPED',\n 'OUT_FOR_DELIVERY',\n 'DELIVERED',\n ].indexOf(step.key);\n return (\n <div\n key={step.key}\n className={`rounded-lg border px-3 py-2 text-xs font-medium ${\n reached\n ? 'border-status-success-border bg-status-success-bg-subtle text-status-success-text'\n : 'border-border-seam bg-bg-sunken/40 text-text-muted'\n }`}\n >\n {step.label}\n </div>\n );\n })}\n </div>\n </div>\n )}\n\n {/* Column headers for items */}\n <div className=\"hidden grid-cols-[1fr_100px_120px_160px] gap-4 px-12 py-2 md:grid\">\n <span className=\"text-xs font-medium text-text-muted\">\n {tr('pages.orders.colProduct', 'Product')}\n </span>\n <span className=\"text-xs font-medium text-text-muted text-right\">\n {tr('pages.orders.colQty', 'Qty')}\n </span>\n <span className=\"text-xs font-medium text-text-muted text-right\">\n {tr('pages.orders.colPrice', 'Price')}\n </span>\n <span className=\"text-xs font-medium text-text-muted text-center\">\n {tr('pages.orders.colAction', 'Action')}\n </span>\n </div>\n\n {order.items.map((item) => {\n const isInstallable =\n item.productType !== 'PHYSICAL' &&\n item.productType !== 'MERCHANDISE';\n\n return (\n <div\n key={item.id}\n className=\"grid grid-cols-[auto_1fr_auto] items-center gap-3 px-4 py-3 md:px-12 md:grid-cols-[1fr_100px_120px_160px]\"\n >\n {/* Product info */}\n <div className=\"flex items-center gap-3 min-w-0\">\n <div className=\"size-10 flex-shrink-0 overflow-hidden rounded-lg bg-bg-sunken\">\n {item.productIcon ? (\n <img\n src={item.productIcon}\n alt={item.productName}\n className=\"size-full object-cover\"\n />\n ) : (\n <div className=\"flex size-full items-center justify-center text-sm font-bold text-text-muted\">\n {item.productName.charAt(0)}\n </div>\n )}\n </div>\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-text-primary\">\n {item.productName}\n </p>\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 </div>\n </div>\n\n {/* Quantity */}\n <div className=\"hidden text-right text-sm text-text-muted md:block\">\n {item.quantity}\n </div>\n\n {/* Price */}\n <div className=\"hidden text-right text-sm font-semibold tabular-nums text-text-primary md:block\">\n {formatPrice(item.totalPrice, order.catalogCurrency)}\n </div>\n\n {/* Mobile price + qty */}\n <div className=\"text-right text-sm text-text-muted md:hidden\">\n <span className=\"tabular-nums\">\n {tr('pages.orders.qtyTimesPrice', '{{qty}} × {{price}}', {\n qty: item.quantity,\n price: formatPrice(item.unitPrice, order.catalogCurrency),\n })}\n </span>\n </div>\n\n {/* Install button */}\n <div className=\"flex justify-end md:justify-center\">\n {item.installed ? (\n <span className=\"inline-flex items-center gap-1 rounded-lg px-3 py-1.5 text-xs font-medium text-status-success-text\">\n <CheckCircle className=\"size-3.5\" />\n {tr('pages.orders.installed', 'Installed')}\n </span>\n ) : isSuccessful && isInstallable ? (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n handleOpenInstallModal(order.id, item);\n }}\n className=\"inline-flex cursor-pointer items-center gap-1.5 rounded-lg bg-action-primary-bg px-3 py-1.5 text-xs font-medium text-action-primary-text transition-all hover:opacity-90 active:scale-95\"\n >\n <Download className=\"size-3.5\" />\n {tr('pages.orders.installApp', 'Install App')}\n </button>\n ) : null}\n </div>\n </div>\n );\n })}\n\n {/* Order summary footer */}\n <div className=\"border-t border-border-seam/50 px-4 py-2 md:px-12\">\n {order.isActualCharge && order.currency !== order.catalogCurrency && (\n <p className=\"mb-1 text-right text-xs text-text-muted\">\n {tr(\n 'pages.orders.paidInCurrency',\n 'Listed in {{catalogCurrency}}, actually charged in {{currency}}',\n {\n catalogCurrency: order.catalogCurrency,\n currency: order.currency,\n }\n )}\n </p>\n )}\n <div className=\"flex justify-end gap-6 text-xs text-text-muted\">\n <span>\n {tr('pages.orders.subtotal', 'Subtotal:')}{' '}\n <span className=\"tabular-nums text-text-primary\">\n {formatPrice(order.subtotal, order.currency)}\n </span>\n </span>\n <span>\n {tr('pages.orders.tax', 'Tax:')}{' '}\n <span className=\"tabular-nums text-text-primary\">\n {formatPrice(order.tax, order.currency)}\n </span>\n </span>\n <span className=\"font-semibold\">\n {tr('pages.orders.total', 'Total:')}{' '}\n <span className=\"tabular-nums text-text-primary\">\n {formatPrice(order.total, order.currency)}\n </span>\n </span>\n </div>\n {order.creditsUsed != null && (\n <p className=\"mt-1 text-right text-xs text-text-muted\">\n {tr(\n 'pages.orders.paidWithCredits',\n 'Paid with {{credits}} credits',\n { credits: order.creditsUsed.toLocaleString() }\n )}\n </p>\n )}\n </div>\n </div>\n )}\n </div>\n );\n })}\n\n {/* Load More */}\n {hasMore && (\n <div className=\"flex justify-center px-4 py-5\">\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 transition-colors hover:bg-bg-subtle disabled:opacity-50\"\n aria-label={t('common.loadMore', { defaultValue: 'Load more' })}\n >\n {loading ? (\n <Loader2 className=\"size-4 animate-spin\" aria-hidden=\"true\" />\n ) : null}\n {t('common.loadMore', { defaultValue: 'Load more' })}\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n )}\n </div>\n </div>\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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-store",
3
- "version": "2026.912.3",
3
+ "version": "2026.912.4",
4
4
  "description": "Store microfrontend for Burdenoff products",
5
5
  "type": "module",
6
6
  "files": [