@burdenoff/microfe-coolandlovely 2026.1024.4 → 2026.1027.1
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.
- package/dist/coolandlovely/CoolAndLovelyRoutes.d.ts.map +1 -1
- package/dist/coolandlovely/CoolAndLovelyRoutes.js +20 -12
- package/dist/coolandlovely/CoolAndLovelyRoutes.js.map +1 -1
- package/dist/coolandlovely/components/FulfilmentTimeline.d.ts +7 -0
- package/dist/coolandlovely/components/FulfilmentTimeline.d.ts.map +1 -0
- package/dist/coolandlovely/components/FulfilmentTimeline.js +77 -0
- package/dist/coolandlovely/components/FulfilmentTimeline.js.map +1 -0
- package/dist/coolandlovely/components/RefundPanel.d.ts +8 -0
- package/dist/coolandlovely/components/RefundPanel.d.ts.map +1 -0
- package/dist/coolandlovely/components/RefundPanel.js +113 -0
- package/dist/coolandlovely/components/RefundPanel.js.map +1 -0
- package/dist/coolandlovely/components/StatusBadge.d.ts.map +1 -1
- package/dist/coolandlovely/components/StatusBadge.js +17 -1
- package/dist/coolandlovely/components/StatusBadge.js.map +1 -1
- package/dist/coolandlovely/hooks/useBrandOrdersApi.d.ts +12 -0
- package/dist/coolandlovely/hooks/useBrandOrdersApi.d.ts.map +1 -0
- package/dist/coolandlovely/hooks/useBrandOrdersApi.js +124 -0
- package/dist/coolandlovely/hooks/useBrandOrdersApi.js.map +1 -0
- package/dist/coolandlovely/hooks/useCommerceApi.d.ts +4 -0
- package/dist/coolandlovely/hooks/useCommerceApi.d.ts.map +1 -1
- package/dist/coolandlovely/hooks/useCommerceApi.js +28 -23
- package/dist/coolandlovely/hooks/useCommerceApi.js.map +1 -1
- package/dist/coolandlovely/pages/brands/BrandDetailPage.d.ts.map +1 -1
- package/dist/coolandlovely/pages/brands/BrandDetailPage.js +157 -148
- package/dist/coolandlovely/pages/brands/BrandDetailPage.js.map +1 -1
- package/dist/coolandlovely/pages/commerce/BrandOrdersPage.d.ts +14 -0
- package/dist/coolandlovely/pages/commerce/BrandOrdersPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/commerce/BrandOrdersPage.js +362 -0
- package/dist/coolandlovely/pages/commerce/BrandOrdersPage.js.map +1 -0
- package/dist/coolandlovely/pages/commerce/CartPage.js +4 -4
- package/dist/coolandlovely/pages/commerce/CreatorEarningsPage.d.ts.map +1 -1
- package/dist/coolandlovely/pages/commerce/CreatorEarningsPage.js +108 -106
- package/dist/coolandlovely/pages/commerce/CreatorEarningsPage.js.map +1 -1
- package/dist/coolandlovely/pages/commerce/OrdersPage.d.ts +2 -1
- package/dist/coolandlovely/pages/commerce/OrdersPage.d.ts.map +1 -1
- package/dist/coolandlovely/pages/commerce/OrdersPage.js +206 -123
- package/dist/coolandlovely/pages/commerce/OrdersPage.js.map +1 -1
- package/dist/coolandlovely/types/commerce.d.ts +98 -1
- package/dist/coolandlovely/types/commerce.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -8,15 +8,16 @@ import { ErrorView as a, LoadingView as o } from "../../components/StateViews.js
|
|
|
8
8
|
import { Thumbnail as s } from "../../components/Thumbnail.js";
|
|
9
9
|
import { formatDate as c, formatPrice as l } from "../../utils/formatters.js";
|
|
10
10
|
import { EmptyState as u } from "../../components/EmptyState.js";
|
|
11
|
-
import {
|
|
11
|
+
import { FulfilmentTimeline as d } from "../../components/FulfilmentTimeline.js";
|
|
12
12
|
import { useCancelOrder as f, useMyOrder as p, useMyOrders as m, useResumeOrderPayment as h, useSyncOrderPayment as g } from "../../hooks/useCommerceApi.js";
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
13
|
+
import { PayForOrder as _ } from "../../components/PayForOrder.js";
|
|
14
|
+
import { useState as v } from "react";
|
|
15
|
+
import { ArrowLeft as y, ChevronRight as b, Loader2 as x, Package as S, RefreshCw as C, Sparkles as w, XCircle as T } from "lucide-react";
|
|
16
|
+
import { useParams as E } from "react-router";
|
|
17
|
+
import { Fragment as D, jsx as O, jsxs as k } from "react/jsx-runtime";
|
|
18
|
+
import { GlassCard as A } from "@burdenoff/fe-libs/ui";
|
|
18
19
|
//#region src/coolandlovely/pages/commerce/OrdersPage.tsx
|
|
19
|
-
var
|
|
20
|
+
var j = [
|
|
20
21
|
{
|
|
21
22
|
value: void 0,
|
|
22
23
|
key: "coolandlovely.orders.filterAll",
|
|
@@ -32,21 +33,31 @@ var A = [
|
|
|
32
33
|
key: "coolandlovely.orders.filterPaid",
|
|
33
34
|
label: "Paid"
|
|
34
35
|
},
|
|
36
|
+
{
|
|
37
|
+
value: "PARTIALLY_REFUNDED",
|
|
38
|
+
key: "coolandlovely.orders.filterPartiallyRefunded",
|
|
39
|
+
label: "Partly refunded"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
value: "REFUNDED",
|
|
43
|
+
key: "coolandlovely.orders.filterRefunded",
|
|
44
|
+
label: "Refunded"
|
|
45
|
+
},
|
|
35
46
|
{
|
|
36
47
|
value: "CANCELLED",
|
|
37
48
|
key: "coolandlovely.orders.filterCancelled",
|
|
38
49
|
label: "Cancelled"
|
|
39
50
|
}
|
|
40
|
-
],
|
|
41
|
-
function
|
|
42
|
-
let s = r(), { navigateTo: d } = e(), [f, p] =
|
|
43
|
-
return /* @__PURE__ */
|
|
51
|
+
], M = "inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken disabled:opacity-50";
|
|
52
|
+
function N() {
|
|
53
|
+
let s = r(), { navigateTo: d } = e(), [f, p] = v(void 0), h = m(f);
|
|
54
|
+
return /* @__PURE__ */ k(n, {
|
|
44
55
|
title: s("coolandlovely.orders.title", "My orders"),
|
|
45
56
|
description: s("coolandlovely.orders.description", "Everything you have ordered."),
|
|
46
|
-
children: [/* @__PURE__ */
|
|
57
|
+
children: [/* @__PURE__ */ O("div", {
|
|
47
58
|
className: "mb-4 flex flex-wrap gap-2",
|
|
48
59
|
role: "tablist",
|
|
49
|
-
children:
|
|
60
|
+
children: j.map((e) => /* @__PURE__ */ O("button", {
|
|
50
61
|
type: "button",
|
|
51
62
|
role: "tab",
|
|
52
63
|
"aria-selected": f === e.value,
|
|
@@ -54,24 +65,24 @@ function M() {
|
|
|
54
65
|
className: t("rounded-full border px-3 py-1 text-sm font-medium transition-colors", f === e.value ? "border-action-primary-bg bg-action-primary-bg text-action-primary-text" : "border-border-seam text-text-primary hover:bg-bg-sunken"),
|
|
55
66
|
children: s(e.key, e.label)
|
|
56
67
|
}, e.key))
|
|
57
|
-
}), h.isLoading ? /* @__PURE__ */
|
|
58
|
-
icon: /* @__PURE__ */
|
|
68
|
+
}), h.isLoading ? /* @__PURE__ */ O(o, { label: s("coolandlovely.orders.loading", "Loading orders…") }) : h.isError || !h.data ? /* @__PURE__ */ O(a, { onRetry: () => void h.refetch() }) : h.data.items.length === 0 ? /* @__PURE__ */ O(u, {
|
|
69
|
+
icon: /* @__PURE__ */ O(S, { className: "h-8 w-8" }),
|
|
59
70
|
title: s("coolandlovely.orders.emptyTitle", "No orders yet"),
|
|
60
71
|
description: s("coolandlovely.orders.emptyDescription", "Orders you place appear here.")
|
|
61
|
-
}) : /* @__PURE__ */
|
|
72
|
+
}) : /* @__PURE__ */ O("div", {
|
|
62
73
|
className: "space-y-3",
|
|
63
74
|
"data-testid": "orders-list",
|
|
64
|
-
children: h.data.items.map((e) => /* @__PURE__ */
|
|
75
|
+
children: h.data.items.map((e) => /* @__PURE__ */ k("button", {
|
|
65
76
|
type: "button",
|
|
66
77
|
onClick: () => d(`/orders/${e.id}`),
|
|
67
78
|
className: "flex w-full items-center gap-4 rounded-xl border border-border-seam bg-bg-surface p-4 text-left transition-colors hover:bg-bg-sunken/50",
|
|
68
79
|
children: [
|
|
69
|
-
/* @__PURE__ */
|
|
80
|
+
/* @__PURE__ */ k("div", {
|
|
70
81
|
className: "min-w-0 flex-1",
|
|
71
|
-
children: [/* @__PURE__ */
|
|
82
|
+
children: [/* @__PURE__ */ O("p", {
|
|
72
83
|
className: "font-mono text-sm font-medium text-text-primary",
|
|
73
84
|
children: e.orderNumber
|
|
74
|
-
}), /* @__PURE__ */
|
|
85
|
+
}), /* @__PURE__ */ k("p", {
|
|
75
86
|
className: "truncate text-xs text-text-secondary",
|
|
76
87
|
children: [
|
|
77
88
|
c(e.createdAt),
|
|
@@ -81,193 +92,265 @@ function M() {
|
|
|
81
92
|
]
|
|
82
93
|
})]
|
|
83
94
|
}),
|
|
84
|
-
/* @__PURE__ */
|
|
85
|
-
/* @__PURE__ */
|
|
95
|
+
/* @__PURE__ */ O(i, { status: e.status }),
|
|
96
|
+
/* @__PURE__ */ O("span", {
|
|
86
97
|
className: "w-28 text-right text-sm font-semibold tabular-nums text-text-primary",
|
|
87
98
|
children: l(e.total, e.currency)
|
|
88
99
|
}),
|
|
89
|
-
/* @__PURE__ */
|
|
100
|
+
/* @__PURE__ */ O(b, { className: "h-4 w-4 text-text-secondary" })
|
|
90
101
|
]
|
|
91
102
|
}, e.id))
|
|
92
103
|
})]
|
|
93
104
|
});
|
|
94
105
|
}
|
|
95
|
-
function
|
|
96
|
-
let u = r(), { orderId: m } =
|
|
97
|
-
if (
|
|
98
|
-
title:
|
|
99
|
-
children: /* @__PURE__ */
|
|
106
|
+
function P() {
|
|
107
|
+
let u = r(), { orderId: m } = E(), { navigateTo: b } = e(), j = p(m), N = h(), P = g(), F = f(), [I, L] = v(null), R = u("coolandlovely.orders.detailTitle", "Order");
|
|
108
|
+
if (j.isLoading) return /* @__PURE__ */ O(n, {
|
|
109
|
+
title: R,
|
|
110
|
+
children: /* @__PURE__ */ O(o, {})
|
|
100
111
|
});
|
|
101
|
-
if (
|
|
102
|
-
title:
|
|
103
|
-
children: /* @__PURE__ */
|
|
112
|
+
if (j.isError || !j.data) return /* @__PURE__ */ O(n, {
|
|
113
|
+
title: R,
|
|
114
|
+
children: /* @__PURE__ */ O(a, {
|
|
104
115
|
title: u("coolandlovely.orders.notFound", "Order not found"),
|
|
105
|
-
onRetry: () => void
|
|
116
|
+
onRetry: () => void j.refetch()
|
|
106
117
|
})
|
|
107
118
|
});
|
|
108
|
-
let
|
|
109
|
-
return /* @__PURE__ */
|
|
110
|
-
title:
|
|
111
|
-
description: c(
|
|
112
|
-
actions: /* @__PURE__ */
|
|
119
|
+
let z = j.data, B = z.status === "PENDING_PAYMENT", V = N.error ?? P.error ?? F.error;
|
|
120
|
+
return /* @__PURE__ */ O(n, {
|
|
121
|
+
title: z.orderNumber,
|
|
122
|
+
description: c(z.createdAt),
|
|
123
|
+
actions: /* @__PURE__ */ k("div", {
|
|
113
124
|
className: "flex flex-wrap items-center gap-2",
|
|
114
|
-
children: [/* @__PURE__ */
|
|
125
|
+
children: [/* @__PURE__ */ k("button", {
|
|
115
126
|
type: "button",
|
|
116
|
-
onClick: () =>
|
|
117
|
-
className:
|
|
127
|
+
onClick: () => b("/orders"),
|
|
128
|
+
className: M,
|
|
118
129
|
children: [
|
|
119
|
-
/* @__PURE__ */
|
|
130
|
+
/* @__PURE__ */ O(y, { className: "h-4 w-4" }),
|
|
120
131
|
" ",
|
|
121
132
|
u("coolandlovely.common.back", "Back")
|
|
122
133
|
]
|
|
123
|
-
}),
|
|
124
|
-
type: "button",
|
|
125
|
-
disabled: N.isPending,
|
|
126
|
-
onClick: () => N.mutate(R.id),
|
|
127
|
-
className: j,
|
|
128
|
-
children: [N.isPending ? /* @__PURE__ */ D(b, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ D(S, { className: "h-4 w-4" }), u("coolandlovely.orders.checkPayment", "Check payment")]
|
|
129
|
-
}), /* @__PURE__ */ O("button", {
|
|
134
|
+
}), B && /* @__PURE__ */ k(D, { children: [/* @__PURE__ */ k("button", {
|
|
130
135
|
type: "button",
|
|
131
136
|
disabled: P.isPending,
|
|
132
|
-
onClick: () => P.mutate(
|
|
133
|
-
className:
|
|
137
|
+
onClick: () => P.mutate(z.id),
|
|
138
|
+
className: M,
|
|
139
|
+
children: [P.isPending ? /* @__PURE__ */ O(x, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ O(C, { className: "h-4 w-4" }), u("coolandlovely.orders.checkPayment", "Check payment")]
|
|
140
|
+
}), /* @__PURE__ */ k("button", {
|
|
141
|
+
type: "button",
|
|
142
|
+
disabled: F.isPending,
|
|
143
|
+
onClick: () => F.mutate(z.id),
|
|
144
|
+
className: t(M, "text-status-error-text hover:bg-status-error-bg-subtle"),
|
|
134
145
|
children: [
|
|
135
|
-
/* @__PURE__ */
|
|
146
|
+
/* @__PURE__ */ O(T, { className: "h-4 w-4" }),
|
|
136
147
|
" ",
|
|
137
148
|
u("coolandlovely.orders.cancel", "Cancel order")
|
|
138
149
|
]
|
|
139
150
|
})] })]
|
|
140
151
|
}),
|
|
141
|
-
children: /* @__PURE__ */
|
|
152
|
+
children: /* @__PURE__ */ k("div", {
|
|
142
153
|
className: "grid grid-cols-1 gap-6 lg:grid-cols-3",
|
|
143
|
-
children: [/* @__PURE__ */
|
|
154
|
+
children: [/* @__PURE__ */ k("div", {
|
|
144
155
|
className: "space-y-3 lg:col-span-2",
|
|
145
|
-
children:
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
className: "
|
|
155
|
-
|
|
156
|
-
/* @__PURE__ */ O("div", {
|
|
157
|
-
className: "min-w-0 flex-1",
|
|
156
|
+
children: [
|
|
157
|
+
(z.refunds?.length ?? 0) > 0 && /* @__PURE__ */ k(A, {
|
|
158
|
+
treatment: "plain",
|
|
159
|
+
className: "space-y-3 p-4",
|
|
160
|
+
"data-testid": "order-refunds",
|
|
161
|
+
children: [/* @__PURE__ */ O("p", {
|
|
162
|
+
className: "text-xs font-medium uppercase tracking-wide text-text-secondary",
|
|
163
|
+
children: u("coolandlovely.orders.refunds", "Refunds")
|
|
164
|
+
}), z.refunds?.map((e) => /* @__PURE__ */ k("div", {
|
|
165
|
+
className: "space-y-1",
|
|
166
|
+
"data-testid": "order-refund",
|
|
158
167
|
children: [
|
|
159
|
-
/* @__PURE__ */
|
|
160
|
-
className: "
|
|
161
|
-
children:
|
|
168
|
+
/* @__PURE__ */ k("div", {
|
|
169
|
+
className: "flex items-center justify-between gap-2",
|
|
170
|
+
children: [/* @__PURE__ */ O("span", {
|
|
171
|
+
className: "text-sm font-medium text-text-primary",
|
|
172
|
+
children: e.brandName ?? u("coolandlovely.orders.brand", "Brand")
|
|
173
|
+
}), /* @__PURE__ */ k("span", {
|
|
174
|
+
className: "flex items-center gap-2",
|
|
175
|
+
children: [/* @__PURE__ */ O("span", {
|
|
176
|
+
className: "text-sm font-semibold tabular-nums text-text-primary",
|
|
177
|
+
children: l(e.amount, e.currency)
|
|
178
|
+
}), /* @__PURE__ */ O(i, { status: e.status })]
|
|
179
|
+
})]
|
|
162
180
|
}),
|
|
163
|
-
/* @__PURE__ */
|
|
164
|
-
className: "
|
|
165
|
-
children:
|
|
166
|
-
e.size,
|
|
167
|
-
e.colour,
|
|
168
|
-
`× ${e.quantity}`
|
|
169
|
-
].filter(Boolean).join(" · ")
|
|
181
|
+
/* @__PURE__ */ O("p", {
|
|
182
|
+
className: "text-xs text-text-secondary",
|
|
183
|
+
children: e.reason
|
|
170
184
|
}),
|
|
171
|
-
e.
|
|
172
|
-
className: "
|
|
173
|
-
children:
|
|
185
|
+
e.status === "COMPLETED" && /* @__PURE__ */ O("p", {
|
|
186
|
+
className: "text-xs text-text-secondary",
|
|
187
|
+
children: u("coolandlovely.orders.refundedToMethod", "Refunded {{date}} to your original payment method.", { date: c(e.refundedAt ?? e.createdAt) })
|
|
174
188
|
})
|
|
175
189
|
]
|
|
176
|
-
})
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
190
|
+
}, e.id))]
|
|
191
|
+
}),
|
|
192
|
+
(z.status === "PAID" || z.status === "PARTIALLY_REFUNDED") && (z.fulfilments?.length ?? 0) > 0 && /* @__PURE__ */ k(A, {
|
|
193
|
+
treatment: "plain",
|
|
194
|
+
className: "space-y-4 p-4",
|
|
195
|
+
children: [/* @__PURE__ */ O("p", {
|
|
196
|
+
className: "text-xs font-medium uppercase tracking-wide text-text-secondary",
|
|
197
|
+
children: u("coolandlovely.orders.delivery", "Delivery")
|
|
198
|
+
}), z.fulfilments?.map((e) => /* @__PURE__ */ k("div", {
|
|
199
|
+
className: "space-y-2",
|
|
200
|
+
"data-testid": "order-fulfilment",
|
|
201
|
+
children: [/* @__PURE__ */ k("div", {
|
|
202
|
+
className: "flex items-center justify-between gap-2",
|
|
203
|
+
children: [/* @__PURE__ */ O("span", {
|
|
204
|
+
className: "text-sm font-medium text-text-primary",
|
|
205
|
+
children: e.brandName ?? u("coolandlovely.orders.brand", "Brand")
|
|
206
|
+
}), /* @__PURE__ */ O(i, { status: e.refunded ? "REFUNDED" : e.status })]
|
|
207
|
+
}), e.refunded ? /* @__PURE__ */ O("p", {
|
|
208
|
+
className: "text-xs text-text-secondary",
|
|
209
|
+
children: u("coolandlovely.orders.brandRefunded", "The brand refunded these pieces, so they will not be shipped.")
|
|
210
|
+
}) : e.status === "UNFULFILLED" ? /* @__PURE__ */ O("p", {
|
|
211
|
+
className: "text-xs text-text-secondary",
|
|
212
|
+
children: u("coolandlovely.orders.awaitingBrand", "Waiting for the brand to confirm your pieces.")
|
|
213
|
+
}) : /* @__PURE__ */ O(d, { fulfilment: e })]
|
|
214
|
+
}, e.brandId))]
|
|
215
|
+
}),
|
|
216
|
+
z.items.map((e) => /* @__PURE__ */ k(A, {
|
|
217
|
+
treatment: "plain",
|
|
218
|
+
className: "flex items-center gap-4 p-4",
|
|
219
|
+
children: [
|
|
220
|
+
/* @__PURE__ */ O(s, {
|
|
221
|
+
icon: /* @__PURE__ */ O(S, { className: "h-5 w-5" }),
|
|
222
|
+
seed: e.styleItemId,
|
|
223
|
+
fileId: e.image?.id,
|
|
224
|
+
alt: e.name,
|
|
225
|
+
className: "h-14 w-14 shrink-0"
|
|
226
|
+
}),
|
|
227
|
+
/* @__PURE__ */ k("div", {
|
|
228
|
+
className: "min-w-0 flex-1",
|
|
229
|
+
children: [
|
|
230
|
+
/* @__PURE__ */ O("p", {
|
|
231
|
+
className: "truncate text-sm font-medium text-text-primary",
|
|
232
|
+
children: e.name
|
|
233
|
+
}),
|
|
234
|
+
/* @__PURE__ */ O("p", {
|
|
235
|
+
className: "truncate text-xs text-text-secondary",
|
|
236
|
+
children: [
|
|
237
|
+
e.size,
|
|
238
|
+
e.colour,
|
|
239
|
+
`× ${e.quantity}`
|
|
240
|
+
].filter(Boolean).join(" · ")
|
|
241
|
+
}),
|
|
242
|
+
e.isCreatorAttributed && /* @__PURE__ */ k("p", {
|
|
243
|
+
className: "mt-0.5 inline-flex items-center gap-1 text-xs text-accent-primary",
|
|
244
|
+
children: [/* @__PURE__ */ O(w, { className: "h-3 w-3" }), u("coolandlovely.orders.supportsCreator", "Supports the creator of the look")]
|
|
245
|
+
})
|
|
246
|
+
]
|
|
247
|
+
}),
|
|
248
|
+
/* @__PURE__ */ O("span", {
|
|
249
|
+
className: "text-sm font-semibold tabular-nums text-text-primary",
|
|
250
|
+
children: l(e.lineTotal, z.currency)
|
|
251
|
+
})
|
|
252
|
+
]
|
|
253
|
+
}, e.id))
|
|
254
|
+
]
|
|
255
|
+
}), /* @__PURE__ */ k(A, {
|
|
184
256
|
treatment: "glass",
|
|
185
257
|
className: "h-fit space-y-4 p-6",
|
|
186
258
|
children: [
|
|
187
|
-
/* @__PURE__ */
|
|
259
|
+
/* @__PURE__ */ k("div", {
|
|
188
260
|
className: "flex items-center justify-between",
|
|
189
|
-
children: [/* @__PURE__ */
|
|
261
|
+
children: [/* @__PURE__ */ O("span", {
|
|
190
262
|
className: "text-sm text-text-secondary",
|
|
191
263
|
children: u("coolandlovely.orders.status", "Status")
|
|
192
|
-
}), /* @__PURE__ */
|
|
264
|
+
}), /* @__PURE__ */ O("span", {
|
|
193
265
|
"data-testid": "order-status",
|
|
194
|
-
children: /* @__PURE__ */
|
|
266
|
+
children: /* @__PURE__ */ O(i, { status: z.status })
|
|
195
267
|
})]
|
|
196
268
|
}),
|
|
197
|
-
/* @__PURE__ */
|
|
269
|
+
/* @__PURE__ */ k("dl", {
|
|
198
270
|
className: "space-y-2 text-sm",
|
|
199
271
|
children: [
|
|
200
|
-
/* @__PURE__ */
|
|
272
|
+
/* @__PURE__ */ k("div", {
|
|
201
273
|
className: "flex justify-between",
|
|
202
|
-
children: [/* @__PURE__ */
|
|
274
|
+
children: [/* @__PURE__ */ O("dt", {
|
|
203
275
|
className: "text-text-secondary",
|
|
204
276
|
children: u("coolandlovely.checkout.subtotal", "Subtotal")
|
|
205
|
-
}), /* @__PURE__ */
|
|
277
|
+
}), /* @__PURE__ */ O("dd", {
|
|
206
278
|
className: "tabular-nums text-text-primary",
|
|
207
|
-
children: l(
|
|
279
|
+
children: l(z.subtotal, z.currency)
|
|
208
280
|
})]
|
|
209
281
|
}),
|
|
210
|
-
/* @__PURE__ */
|
|
282
|
+
/* @__PURE__ */ k("div", {
|
|
211
283
|
className: "flex justify-between",
|
|
212
|
-
children: [/* @__PURE__ */
|
|
284
|
+
children: [/* @__PURE__ */ O("dt", {
|
|
213
285
|
className: "text-text-secondary",
|
|
214
286
|
children: u("coolandlovely.checkout.tax", "Tax")
|
|
215
|
-
}), /* @__PURE__ */
|
|
287
|
+
}), /* @__PURE__ */ O("dd", {
|
|
216
288
|
className: "tabular-nums text-text-primary",
|
|
217
|
-
children: l(
|
|
289
|
+
children: l(z.taxAmount, z.currency)
|
|
218
290
|
})]
|
|
219
291
|
}),
|
|
220
|
-
/* @__PURE__ */
|
|
292
|
+
/* @__PURE__ */ k("div", {
|
|
221
293
|
className: "flex justify-between border-t border-border-seam pt-2 text-base font-semibold",
|
|
222
|
-
children: [/* @__PURE__ */
|
|
294
|
+
children: [/* @__PURE__ */ O("dt", {
|
|
223
295
|
className: "text-text-primary",
|
|
224
296
|
children: u("coolandlovely.checkout.total", "Total")
|
|
225
|
-
}), /* @__PURE__ */
|
|
297
|
+
}), /* @__PURE__ */ O("dd", {
|
|
298
|
+
className: "tabular-nums text-text-primary",
|
|
299
|
+
children: l(z.total, z.currency)
|
|
300
|
+
})]
|
|
301
|
+
}),
|
|
302
|
+
z.refundedAmount > 0 && /* @__PURE__ */ k("div", {
|
|
303
|
+
className: "flex justify-between",
|
|
304
|
+
"data-testid": "order-refunded-amount",
|
|
305
|
+
children: [/* @__PURE__ */ O("dt", {
|
|
306
|
+
className: "text-text-secondary",
|
|
307
|
+
children: u("coolandlovely.orders.refunded", "Refunded")
|
|
308
|
+
}), /* @__PURE__ */ k("dd", {
|
|
226
309
|
className: "tabular-nums text-text-primary",
|
|
227
|
-
children: l(
|
|
310
|
+
children: ["− ", l(z.refundedAmount, z.currency)]
|
|
228
311
|
})]
|
|
229
312
|
})
|
|
230
313
|
]
|
|
231
314
|
}),
|
|
232
|
-
|
|
315
|
+
z.shippingAddress && /* @__PURE__ */ k("div", {
|
|
233
316
|
className: "border-t border-border-seam pt-3 text-sm",
|
|
234
317
|
children: [
|
|
235
|
-
/* @__PURE__ */
|
|
318
|
+
/* @__PURE__ */ O("p", {
|
|
236
319
|
className: "mb-1 text-xs font-medium uppercase tracking-wide text-text-secondary",
|
|
237
320
|
children: u("coolandlovely.orders.shipTo", "Ship to")
|
|
238
321
|
}),
|
|
239
|
-
/* @__PURE__ */
|
|
322
|
+
/* @__PURE__ */ O("p", {
|
|
240
323
|
className: "text-text-primary",
|
|
241
|
-
children:
|
|
324
|
+
children: z.shippingName
|
|
242
325
|
}),
|
|
243
|
-
/* @__PURE__ */
|
|
326
|
+
/* @__PURE__ */ O("p", {
|
|
244
327
|
className: "whitespace-pre-line text-text-secondary",
|
|
245
|
-
children:
|
|
328
|
+
children: z.shippingAddress
|
|
246
329
|
})
|
|
247
330
|
]
|
|
248
331
|
}),
|
|
249
|
-
|
|
332
|
+
z.paidAt && /* @__PURE__ */ O("p", {
|
|
250
333
|
className: "text-xs text-text-secondary",
|
|
251
334
|
children: u("coolandlovely.orders.paidOn", "Paid {{date}} via {{provider}}", {
|
|
252
|
-
date: c(
|
|
253
|
-
provider:
|
|
335
|
+
date: c(z.paidAt),
|
|
336
|
+
provider: z.paymentProvider ?? "—"
|
|
254
337
|
})
|
|
255
338
|
}),
|
|
256
|
-
|
|
339
|
+
V && /* @__PURE__ */ O("p", {
|
|
257
340
|
className: "text-sm text-status-error-text",
|
|
258
|
-
children:
|
|
341
|
+
children: V.message
|
|
259
342
|
}),
|
|
260
|
-
|
|
261
|
-
checkout:
|
|
343
|
+
B && (I ? /* @__PURE__ */ O(_, {
|
|
344
|
+
checkout: I,
|
|
262
345
|
onSettle: async () => {
|
|
263
|
-
await
|
|
346
|
+
await P.mutateAsync(z.id).catch(() => void 0), L(null);
|
|
264
347
|
}
|
|
265
|
-
}) : /* @__PURE__ */
|
|
348
|
+
}) : /* @__PURE__ */ k("button", {
|
|
266
349
|
type: "button",
|
|
267
|
-
disabled:
|
|
268
|
-
onClick: () =>
|
|
350
|
+
disabled: N.isPending,
|
|
351
|
+
onClick: () => N.mutate(z.id, { onSuccess: (e) => L(e) }),
|
|
269
352
|
className: "inline-flex w-full items-center justify-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2.5 text-sm font-semibold text-action-primary-text transition-colors hover:bg-action-primary-bg/90 disabled:opacity-50",
|
|
270
|
-
children: [
|
|
353
|
+
children: [N.isPending && /* @__PURE__ */ O(x, { className: "h-4 w-4 animate-spin" }), u("coolandlovely.orders.payNow", "Pay now")]
|
|
271
354
|
}))
|
|
272
355
|
]
|
|
273
356
|
})]
|
|
@@ -275,6 +358,6 @@ function N() {
|
|
|
275
358
|
});
|
|
276
359
|
}
|
|
277
360
|
//#endregion
|
|
278
|
-
export {
|
|
361
|
+
export { P as OrderDetailPage, N as OrdersPage };
|
|
279
362
|
|
|
280
363
|
//# sourceMappingURL=OrdersPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OrdersPage.js","names":[],"sources":["../../../../src/coolandlovely/pages/commerce/OrdersPage.tsx"],"sourcesContent":["/**\n * My Orders + Order detail (BOFF-3370)\n * @module coolandlovely/pages/commerce\n *\n * The shopper's own orders (`cooMyOrders` / `cooMyOrder`). An unpaid order can be paid\n * (`cooResumeOrderPayment` re-uses its billing order), re-checked against billing\n * (`cooSyncOrderPayment`) or cancelled (`cooCancelOrder`).\n */\n\nimport { useState } from 'react';\nimport { useParams } from 'react-router';\nimport {\n ArrowLeft,\n ChevronRight,\n Loader2,\n Package,\n RefreshCw,\n Sparkles,\n XCircle,\n} from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\n\nimport { EmptyState } from '../../components/EmptyState';\nimport { PageLayout } from '../../components/PageLayout';\nimport { PayForOrder } from '../../components/PayForOrder';\nimport { ErrorView, LoadingView } from '../../components/StateViews';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { Thumbnail } from '../../components/Thumbnail';\nimport { useCoolAndLovely } from '../../context/CoolAndLovelyContext';\nimport { useTr } from '../../hooks';\nimport {\n useCancelOrder,\n useMyOrder,\n useMyOrders,\n useResumeOrderPayment,\n useSyncOrderPayment,\n} from '../../hooks/useCommerceApi';\nimport type { CooOrderCheckout, CooOrderStatus } from '../../types';\nimport { cn } from '../../utils/cn';\nimport { formatDate, formatPrice } from '../../utils/formatters';\n\nconst FILTERS: Array<{ value: CooOrderStatus | undefined; key: string; label: string }> = [\n { value: undefined, key: 'coolandlovely.orders.filterAll', label: 'All' },\n {\n value: 'PENDING_PAYMENT',\n key: 'coolandlovely.orders.filterPending',\n label: 'Awaiting payment',\n },\n { value: 'PAID', key: 'coolandlovely.orders.filterPaid', label: 'Paid' },\n { value: 'CANCELLED', key: 'coolandlovely.orders.filterCancelled', label: 'Cancelled' },\n];\n\nconst secondaryButton =\n 'inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken disabled:opacity-50';\n\nexport function OrdersPage() {\n const tr = useTr();\n const { navigateTo } = useCoolAndLovely();\n const [status, setStatus] = useState<CooOrderStatus | undefined>(undefined);\n const orders = useMyOrders(status);\n const title = tr('coolandlovely.orders.title', 'My orders');\n\n return (\n <PageLayout\n title={title}\n description={tr('coolandlovely.orders.description', 'Everything you have ordered.')}\n >\n <div className=\"mb-4 flex flex-wrap gap-2\" role=\"tablist\">\n {FILTERS.map((filter) => (\n <button\n key={filter.key}\n type=\"button\"\n role=\"tab\"\n aria-selected={status === filter.value}\n onClick={() => setStatus(filter.value)}\n className={cn(\n 'rounded-full border px-3 py-1 text-sm font-medium transition-colors',\n status === filter.value\n ? 'border-action-primary-bg bg-action-primary-bg text-action-primary-text'\n : 'border-border-seam text-text-primary hover:bg-bg-sunken'\n )}\n >\n {tr(filter.key, filter.label)}\n </button>\n ))}\n </div>\n {orders.isLoading ? (\n <LoadingView label={tr('coolandlovely.orders.loading', 'Loading orders…')} />\n ) : orders.isError || !orders.data ? (\n <ErrorView onRetry={() => void orders.refetch()} />\n ) : orders.data.items.length === 0 ? (\n <EmptyState\n icon={<Package className=\"h-8 w-8\" />}\n title={tr('coolandlovely.orders.emptyTitle', 'No orders yet')}\n description={tr('coolandlovely.orders.emptyDescription', 'Orders you place appear here.')}\n />\n ) : (\n <div className=\"space-y-3\" data-testid=\"orders-list\">\n {orders.data.items.map((order) => (\n <button\n key={order.id}\n type=\"button\"\n onClick={() => navigateTo(`/orders/${order.id}`)}\n className=\"flex w-full items-center gap-4 rounded-xl border border-border-seam bg-bg-surface p-4 text-left transition-colors hover:bg-bg-sunken/50\"\n >\n <div className=\"min-w-0 flex-1\">\n <p className=\"font-mono text-sm font-medium text-text-primary\">\n {order.orderNumber}\n </p>\n <p className=\"truncate text-xs text-text-secondary\">\n {formatDate(order.createdAt)} ·{' '}\n {tr('coolandlovely.orders.pieces', '{{count}} pieces', {\n count: order.itemCount,\n })}\n </p>\n </div>\n <StatusBadge status={order.status} />\n <span className=\"w-28 text-right text-sm font-semibold tabular-nums text-text-primary\">\n {formatPrice(order.total, order.currency)}\n </span>\n <ChevronRight className=\"h-4 w-4 text-text-secondary\" />\n </button>\n ))}\n </div>\n )}\n </PageLayout>\n );\n}\n\nexport function OrderDetailPage() {\n const tr = useTr();\n const { orderId } = useParams<{ orderId: string }>();\n const { navigateTo } = useCoolAndLovely();\n const order = useMyOrder(orderId);\n const resume = useResumeOrderPayment();\n const sync = useSyncOrderPayment();\n const cancel = useCancelOrder();\n const [session, setSession] = useState<CooOrderCheckout | null>(null);\n const title = tr('coolandlovely.orders.detailTitle', 'Order');\n\n if (order.isLoading) {\n return (\n <PageLayout title={title}>\n <LoadingView />\n </PageLayout>\n );\n }\n if (order.isError || !order.data) {\n return (\n <PageLayout title={title}>\n <ErrorView\n title={tr('coolandlovely.orders.notFound', 'Order not found')}\n onRetry={() => void order.refetch()}\n />\n </PageLayout>\n );\n }\n\n const data = order.data;\n const pending = data.status === 'PENDING_PAYMENT';\n const actionError = resume.error ?? sync.error ?? cancel.error;\n\n const settle = async () => {\n await sync.mutateAsync(data.id).catch(() => undefined);\n setSession(null);\n };\n\n return (\n <PageLayout\n title={data.orderNumber}\n description={formatDate(data.createdAt)}\n actions={\n <div className=\"flex flex-wrap items-center gap-2\">\n <button type=\"button\" onClick={() => navigateTo('/orders')} className={secondaryButton}>\n <ArrowLeft className=\"h-4 w-4\" /> {tr('coolandlovely.common.back', 'Back')}\n </button>\n {pending && (\n <>\n <button\n type=\"button\"\n disabled={sync.isPending}\n onClick={() => sync.mutate(data.id)}\n className={secondaryButton}\n >\n {sync.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <RefreshCw className=\"h-4 w-4\" />\n )}\n {tr('coolandlovely.orders.checkPayment', 'Check payment')}\n </button>\n <button\n type=\"button\"\n disabled={cancel.isPending}\n onClick={() => cancel.mutate(data.id)}\n className={cn(\n secondaryButton,\n 'text-status-error-text hover:bg-status-error-bg-subtle'\n )}\n >\n <XCircle className=\"h-4 w-4\" /> {tr('coolandlovely.orders.cancel', 'Cancel order')}\n </button>\n </>\n )}\n </div>\n }\n >\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-3\">\n <div className=\"space-y-3 lg:col-span-2\">\n {data.items.map((item) => (\n <GlassCard key={item.id} treatment=\"plain\" className=\"flex items-center gap-4 p-4\">\n <Thumbnail\n icon={<Package className=\"h-5 w-5\" />}\n seed={item.styleItemId}\n fileId={item.image?.id}\n alt={item.name}\n className=\"h-14 w-14 shrink-0\"\n />\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-medium text-text-primary\">{item.name}</p>\n <p className=\"truncate text-xs text-text-secondary\">\n {[item.size, item.colour, `× ${item.quantity}`].filter(Boolean).join(' · ')}\n </p>\n {item.isCreatorAttributed && (\n <p className=\"mt-0.5 inline-flex items-center gap-1 text-xs text-accent-primary\">\n <Sparkles className=\"h-3 w-3\" />\n {tr('coolandlovely.orders.supportsCreator', 'Supports the creator of the look')}\n </p>\n )}\n </div>\n <span className=\"text-sm font-semibold tabular-nums text-text-primary\">\n {formatPrice(item.lineTotal, data.currency)}\n </span>\n </GlassCard>\n ))}\n </div>\n <GlassCard treatment=\"glass\" className=\"h-fit space-y-4 p-6\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {tr('coolandlovely.orders.status', 'Status')}\n </span>\n <span data-testid=\"order-status\">\n <StatusBadge status={data.status} />\n </span>\n </div>\n <dl className=\"space-y-2 text-sm\">\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">\n {tr('coolandlovely.checkout.subtotal', 'Subtotal')}\n </dt>\n <dd className=\"tabular-nums text-text-primary\">\n {formatPrice(data.subtotal, data.currency)}\n </dd>\n </div>\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">{tr('coolandlovely.checkout.tax', 'Tax')}</dt>\n <dd className=\"tabular-nums text-text-primary\">\n {formatPrice(data.taxAmount, data.currency)}\n </dd>\n </div>\n <div className=\"flex justify-between border-t border-border-seam pt-2 text-base font-semibold\">\n <dt className=\"text-text-primary\">{tr('coolandlovely.checkout.total', 'Total')}</dt>\n <dd className=\"tabular-nums text-text-primary\">\n {formatPrice(data.total, data.currency)}\n </dd>\n </div>\n </dl>\n {data.shippingAddress && (\n <div className=\"border-t border-border-seam pt-3 text-sm\">\n <p className=\"mb-1 text-xs font-medium uppercase tracking-wide text-text-secondary\">\n {tr('coolandlovely.orders.shipTo', 'Ship to')}\n </p>\n <p className=\"text-text-primary\">{data.shippingName}</p>\n <p className=\"whitespace-pre-line text-text-secondary\">{data.shippingAddress}</p>\n </div>\n )}\n {data.paidAt && (\n <p className=\"text-xs text-text-secondary\">\n {tr('coolandlovely.orders.paidOn', 'Paid {{date}} via {{provider}}', {\n date: formatDate(data.paidAt),\n provider: data.paymentProvider ?? '—',\n })}\n </p>\n )}\n {actionError && <p className=\"text-sm text-status-error-text\">{actionError.message}</p>}\n {pending &&\n (session ? (\n <PayForOrder checkout={session} onSettle={settle} />\n ) : (\n <button\n type=\"button\"\n disabled={resume.isPending}\n onClick={() =>\n resume.mutate(data.id, { onSuccess: (result) => setSession(result) })\n }\n className=\"inline-flex w-full items-center justify-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2.5 text-sm font-semibold text-action-primary-text transition-colors hover:bg-action-primary-bg/90 disabled:opacity-50\"\n >\n {resume.isPending && <Loader2 className=\"h-4 w-4 animate-spin\" />}\n {tr('coolandlovely.orders.payNow', 'Pay now')}\n </button>\n ))}\n </GlassCard>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"OrdersPage.js","names":[],"sources":["../../../../src/coolandlovely/pages/commerce/OrdersPage.tsx"],"sourcesContent":["/**\n * My Orders + Order detail (BOFF-3370)\n * @module coolandlovely/pages/commerce\n *\n * The shopper's own orders (`cooMyOrders` / `cooMyOrder`). An unpaid order can be paid\n * (`cooResumeOrderPayment` re-uses its billing order), re-checked against billing\n * (`cooSyncOrderPayment`) or cancelled (`cooCancelOrder`). Brand refunds (BOFF-9702) show on\n * the order with their amount and reason.\n */\n\nimport { useState } from 'react';\nimport { useParams } from 'react-router';\nimport {\n ArrowLeft,\n ChevronRight,\n Loader2,\n Package,\n RefreshCw,\n Sparkles,\n XCircle,\n} from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\n\nimport { EmptyState } from '../../components/EmptyState';\nimport { FulfilmentTimeline } from '../../components/FulfilmentTimeline';\nimport { PageLayout } from '../../components/PageLayout';\nimport { PayForOrder } from '../../components/PayForOrder';\nimport { ErrorView, LoadingView } from '../../components/StateViews';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { Thumbnail } from '../../components/Thumbnail';\nimport { useCoolAndLovely } from '../../context/CoolAndLovelyContext';\nimport { useTr } from '../../hooks';\nimport {\n useCancelOrder,\n useMyOrder,\n useMyOrders,\n useResumeOrderPayment,\n useSyncOrderPayment,\n} from '../../hooks/useCommerceApi';\nimport type { CooOrderCheckout, CooOrderStatus } from '../../types';\nimport { cn } from '../../utils/cn';\nimport { formatDate, formatPrice } from '../../utils/formatters';\n\nconst FILTERS: Array<{ value: CooOrderStatus | undefined; key: string; label: string }> = [\n { value: undefined, key: 'coolandlovely.orders.filterAll', label: 'All' },\n {\n value: 'PENDING_PAYMENT',\n key: 'coolandlovely.orders.filterPending',\n label: 'Awaiting payment',\n },\n { value: 'PAID', key: 'coolandlovely.orders.filterPaid', label: 'Paid' },\n {\n value: 'PARTIALLY_REFUNDED',\n key: 'coolandlovely.orders.filterPartiallyRefunded',\n label: 'Partly refunded',\n },\n { value: 'REFUNDED', key: 'coolandlovely.orders.filterRefunded', label: 'Refunded' },\n { value: 'CANCELLED', key: 'coolandlovely.orders.filterCancelled', label: 'Cancelled' },\n];\n\nconst secondaryButton =\n 'inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken disabled:opacity-50';\n\nexport function OrdersPage() {\n const tr = useTr();\n const { navigateTo } = useCoolAndLovely();\n const [status, setStatus] = useState<CooOrderStatus | undefined>(undefined);\n const orders = useMyOrders(status);\n const title = tr('coolandlovely.orders.title', 'My orders');\n\n return (\n <PageLayout\n title={title}\n description={tr('coolandlovely.orders.description', 'Everything you have ordered.')}\n >\n <div className=\"mb-4 flex flex-wrap gap-2\" role=\"tablist\">\n {FILTERS.map((filter) => (\n <button\n key={filter.key}\n type=\"button\"\n role=\"tab\"\n aria-selected={status === filter.value}\n onClick={() => setStatus(filter.value)}\n className={cn(\n 'rounded-full border px-3 py-1 text-sm font-medium transition-colors',\n status === filter.value\n ? 'border-action-primary-bg bg-action-primary-bg text-action-primary-text'\n : 'border-border-seam text-text-primary hover:bg-bg-sunken'\n )}\n >\n {tr(filter.key, filter.label)}\n </button>\n ))}\n </div>\n {orders.isLoading ? (\n <LoadingView label={tr('coolandlovely.orders.loading', 'Loading orders…')} />\n ) : orders.isError || !orders.data ? (\n <ErrorView onRetry={() => void orders.refetch()} />\n ) : orders.data.items.length === 0 ? (\n <EmptyState\n icon={<Package className=\"h-8 w-8\" />}\n title={tr('coolandlovely.orders.emptyTitle', 'No orders yet')}\n description={tr('coolandlovely.orders.emptyDescription', 'Orders you place appear here.')}\n />\n ) : (\n <div className=\"space-y-3\" data-testid=\"orders-list\">\n {orders.data.items.map((order) => (\n <button\n key={order.id}\n type=\"button\"\n onClick={() => navigateTo(`/orders/${order.id}`)}\n className=\"flex w-full items-center gap-4 rounded-xl border border-border-seam bg-bg-surface p-4 text-left transition-colors hover:bg-bg-sunken/50\"\n >\n <div className=\"min-w-0 flex-1\">\n <p className=\"font-mono text-sm font-medium text-text-primary\">\n {order.orderNumber}\n </p>\n <p className=\"truncate text-xs text-text-secondary\">\n {formatDate(order.createdAt)} ·{' '}\n {tr('coolandlovely.orders.pieces', '{{count}} pieces', {\n count: order.itemCount,\n })}\n </p>\n </div>\n <StatusBadge status={order.status} />\n <span className=\"w-28 text-right text-sm font-semibold tabular-nums text-text-primary\">\n {formatPrice(order.total, order.currency)}\n </span>\n <ChevronRight className=\"h-4 w-4 text-text-secondary\" />\n </button>\n ))}\n </div>\n )}\n </PageLayout>\n );\n}\n\nexport function OrderDetailPage() {\n const tr = useTr();\n const { orderId } = useParams<{ orderId: string }>();\n const { navigateTo } = useCoolAndLovely();\n const order = useMyOrder(orderId);\n const resume = useResumeOrderPayment();\n const sync = useSyncOrderPayment();\n const cancel = useCancelOrder();\n const [session, setSession] = useState<CooOrderCheckout | null>(null);\n const title = tr('coolandlovely.orders.detailTitle', 'Order');\n\n if (order.isLoading) {\n return (\n <PageLayout title={title}>\n <LoadingView />\n </PageLayout>\n );\n }\n if (order.isError || !order.data) {\n return (\n <PageLayout title={title}>\n <ErrorView\n title={tr('coolandlovely.orders.notFound', 'Order not found')}\n onRetry={() => void order.refetch()}\n />\n </PageLayout>\n );\n }\n\n const data = order.data;\n const pending = data.status === 'PENDING_PAYMENT';\n const actionError = resume.error ?? sync.error ?? cancel.error;\n\n const settle = async () => {\n await sync.mutateAsync(data.id).catch(() => undefined);\n setSession(null);\n };\n\n return (\n <PageLayout\n title={data.orderNumber}\n description={formatDate(data.createdAt)}\n actions={\n <div className=\"flex flex-wrap items-center gap-2\">\n <button type=\"button\" onClick={() => navigateTo('/orders')} className={secondaryButton}>\n <ArrowLeft className=\"h-4 w-4\" /> {tr('coolandlovely.common.back', 'Back')}\n </button>\n {pending && (\n <>\n <button\n type=\"button\"\n disabled={sync.isPending}\n onClick={() => sync.mutate(data.id)}\n className={secondaryButton}\n >\n {sync.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <RefreshCw className=\"h-4 w-4\" />\n )}\n {tr('coolandlovely.orders.checkPayment', 'Check payment')}\n </button>\n <button\n type=\"button\"\n disabled={cancel.isPending}\n onClick={() => cancel.mutate(data.id)}\n className={cn(\n secondaryButton,\n 'text-status-error-text hover:bg-status-error-bg-subtle'\n )}\n >\n <XCircle className=\"h-4 w-4\" /> {tr('coolandlovely.orders.cancel', 'Cancel order')}\n </button>\n </>\n )}\n </div>\n }\n >\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-3\">\n <div className=\"space-y-3 lg:col-span-2\">\n {(data.refunds?.length ?? 0) > 0 && (\n <GlassCard treatment=\"plain\" className=\"space-y-3 p-4\" data-testid=\"order-refunds\">\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n {tr('coolandlovely.orders.refunds', 'Refunds')}\n </p>\n {data.refunds?.map((refund) => (\n <div key={refund.id} className=\"space-y-1\" data-testid=\"order-refund\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-sm font-medium text-text-primary\">\n {refund.brandName ?? tr('coolandlovely.orders.brand', 'Brand')}\n </span>\n <span className=\"flex items-center gap-2\">\n <span className=\"text-sm font-semibold tabular-nums text-text-primary\">\n {formatPrice(refund.amount, refund.currency)}\n </span>\n <StatusBadge status={refund.status} />\n </span>\n </div>\n <p className=\"text-xs text-text-secondary\">{refund.reason}</p>\n {refund.status === 'COMPLETED' && (\n <p className=\"text-xs text-text-secondary\">\n {tr(\n 'coolandlovely.orders.refundedToMethod',\n 'Refunded {{date}} to your original payment method.',\n { date: formatDate(refund.refundedAt ?? refund.createdAt) }\n )}\n </p>\n )}\n </div>\n ))}\n </GlassCard>\n )}\n {(data.status === 'PAID' || data.status === 'PARTIALLY_REFUNDED') &&\n (data.fulfilments?.length ?? 0) > 0 && (\n <GlassCard treatment=\"plain\" className=\"space-y-4 p-4\">\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n {tr('coolandlovely.orders.delivery', 'Delivery')}\n </p>\n {data.fulfilments?.map((fulfilment) => (\n <div\n key={fulfilment.brandId}\n className=\"space-y-2\"\n data-testid=\"order-fulfilment\"\n >\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-sm font-medium text-text-primary\">\n {fulfilment.brandName ?? tr('coolandlovely.orders.brand', 'Brand')}\n </span>\n <StatusBadge status={fulfilment.refunded ? 'REFUNDED' : fulfilment.status} />\n </div>\n {fulfilment.refunded ? (\n <p className=\"text-xs text-text-secondary\">\n {tr(\n 'coolandlovely.orders.brandRefunded',\n 'The brand refunded these pieces, so they will not be shipped.'\n )}\n </p>\n ) : fulfilment.status === 'UNFULFILLED' ? (\n <p className=\"text-xs text-text-secondary\">\n {tr(\n 'coolandlovely.orders.awaitingBrand',\n 'Waiting for the brand to confirm your pieces.'\n )}\n </p>\n ) : (\n <FulfilmentTimeline fulfilment={fulfilment} />\n )}\n </div>\n ))}\n </GlassCard>\n )}\n {data.items.map((item) => (\n <GlassCard key={item.id} treatment=\"plain\" className=\"flex items-center gap-4 p-4\">\n <Thumbnail\n icon={<Package className=\"h-5 w-5\" />}\n seed={item.styleItemId}\n fileId={item.image?.id}\n alt={item.name}\n className=\"h-14 w-14 shrink-0\"\n />\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-medium text-text-primary\">{item.name}</p>\n <p className=\"truncate text-xs text-text-secondary\">\n {[item.size, item.colour, `× ${item.quantity}`].filter(Boolean).join(' · ')}\n </p>\n {item.isCreatorAttributed && (\n <p className=\"mt-0.5 inline-flex items-center gap-1 text-xs text-accent-primary\">\n <Sparkles className=\"h-3 w-3\" />\n {tr('coolandlovely.orders.supportsCreator', 'Supports the creator of the look')}\n </p>\n )}\n </div>\n <span className=\"text-sm font-semibold tabular-nums text-text-primary\">\n {formatPrice(item.lineTotal, data.currency)}\n </span>\n </GlassCard>\n ))}\n </div>\n <GlassCard treatment=\"glass\" className=\"h-fit space-y-4 p-6\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {tr('coolandlovely.orders.status', 'Status')}\n </span>\n <span data-testid=\"order-status\">\n <StatusBadge status={data.status} />\n </span>\n </div>\n <dl className=\"space-y-2 text-sm\">\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">\n {tr('coolandlovely.checkout.subtotal', 'Subtotal')}\n </dt>\n <dd className=\"tabular-nums text-text-primary\">\n {formatPrice(data.subtotal, data.currency)}\n </dd>\n </div>\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">{tr('coolandlovely.checkout.tax', 'Tax')}</dt>\n <dd className=\"tabular-nums text-text-primary\">\n {formatPrice(data.taxAmount, data.currency)}\n </dd>\n </div>\n <div className=\"flex justify-between border-t border-border-seam pt-2 text-base font-semibold\">\n <dt className=\"text-text-primary\">{tr('coolandlovely.checkout.total', 'Total')}</dt>\n <dd className=\"tabular-nums text-text-primary\">\n {formatPrice(data.total, data.currency)}\n </dd>\n </div>\n {data.refundedAmount > 0 && (\n <div className=\"flex justify-between\" data-testid=\"order-refunded-amount\">\n <dt className=\"text-text-secondary\">\n {tr('coolandlovely.orders.refunded', 'Refunded')}\n </dt>\n <dd className=\"tabular-nums text-text-primary\">\n − {formatPrice(data.refundedAmount, data.currency)}\n </dd>\n </div>\n )}\n </dl>\n {data.shippingAddress && (\n <div className=\"border-t border-border-seam pt-3 text-sm\">\n <p className=\"mb-1 text-xs font-medium uppercase tracking-wide text-text-secondary\">\n {tr('coolandlovely.orders.shipTo', 'Ship to')}\n </p>\n <p className=\"text-text-primary\">{data.shippingName}</p>\n <p className=\"whitespace-pre-line text-text-secondary\">{data.shippingAddress}</p>\n </div>\n )}\n {data.paidAt && (\n <p className=\"text-xs text-text-secondary\">\n {tr('coolandlovely.orders.paidOn', 'Paid {{date}} via {{provider}}', {\n date: formatDate(data.paidAt),\n provider: data.paymentProvider ?? '—',\n })}\n </p>\n )}\n {actionError && <p className=\"text-sm text-status-error-text\">{actionError.message}</p>}\n {pending &&\n (session ? (\n <PayForOrder checkout={session} onSettle={settle} />\n ) : (\n <button\n type=\"button\"\n disabled={resume.isPending}\n onClick={() =>\n resume.mutate(data.id, { onSuccess: (result) => setSession(result) })\n }\n className=\"inline-flex w-full items-center justify-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2.5 text-sm font-semibold text-action-primary-text transition-colors hover:bg-action-primary-bg/90 disabled:opacity-50\"\n >\n {resume.isPending && <Loader2 className=\"h-4 w-4 animate-spin\" />}\n {tr('coolandlovely.orders.payNow', 'Pay now')}\n </button>\n ))}\n </GlassCard>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|