@burdenoff/microfe-coolandlovely 2026.1027.2 → 2026.1028.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/coolandlovely/components/ReturnRequests.d.ts +15 -0
- package/dist/coolandlovely/components/ReturnRequests.d.ts.map +1 -0
- package/dist/coolandlovely/components/ReturnRequests.js +218 -0
- package/dist/coolandlovely/components/ReturnRequests.js.map +1 -0
- package/dist/coolandlovely/components/StatusBadge.d.ts.map +1 -1
- package/dist/coolandlovely/components/StatusBadge.js +5 -1
- package/dist/coolandlovely/components/StatusBadge.js.map +1 -1
- package/dist/coolandlovely/components/StoreListingCard.d.ts +9 -0
- package/dist/coolandlovely/components/StoreListingCard.d.ts.map +1 -0
- package/dist/coolandlovely/components/StoreListingCard.js +63 -0
- package/dist/coolandlovely/components/StoreListingCard.js.map +1 -0
- package/dist/coolandlovely/components/index.d.ts +1 -0
- package/dist/coolandlovely/components/index.d.ts.map +1 -1
- package/dist/coolandlovely/components/index.js +1 -0
- package/dist/coolandlovely/hooks/index.d.ts +1 -1
- package/dist/coolandlovely/hooks/index.d.ts.map +1 -1
- package/dist/coolandlovely/hooks/useBrandOrdersApi.d.ts +10 -1
- package/dist/coolandlovely/hooks/useBrandOrdersApi.d.ts.map +1 -1
- package/dist/coolandlovely/hooks/useBrandOrdersApi.js +99 -30
- package/dist/coolandlovely/hooks/useBrandOrdersApi.js.map +1 -1
- package/dist/coolandlovely/hooks/useCommerceApi.d.ts +8 -1
- package/dist/coolandlovely/hooks/useCommerceApi.d.ts.map +1 -1
- package/dist/coolandlovely/hooks/useCommerceApi.js +47 -31
- package/dist/coolandlovely/hooks/useCommerceApi.js.map +1 -1
- package/dist/coolandlovely/hooks/useCoolAndLovelyApi.d.ts +8 -0
- package/dist/coolandlovely/hooks/useCoolAndLovelyApi.d.ts.map +1 -1
- package/dist/coolandlovely/hooks/useCoolAndLovelyApi.js +109 -87
- package/dist/coolandlovely/hooks/useCoolAndLovelyApi.js.map +1 -1
- package/dist/coolandlovely/pages/commerce/BrandOrdersPage.d.ts +3 -1
- package/dist/coolandlovely/pages/commerce/BrandOrdersPage.d.ts.map +1 -1
- package/dist/coolandlovely/pages/commerce/BrandOrdersPage.js +129 -97
- package/dist/coolandlovely/pages/commerce/BrandOrdersPage.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 +124 -122
- package/dist/coolandlovely/pages/commerce/OrdersPage.js.map +1 -1
- package/dist/coolandlovely/pages/items/StyleItemDetailPage.d.ts +1 -1
- package/dist/coolandlovely/pages/items/StyleItemDetailPage.d.ts.map +1 -1
- package/dist/coolandlovely/pages/items/StyleItemDetailPage.js +113 -111
- package/dist/coolandlovely/pages/items/StyleItemDetailPage.js.map +1 -1
- package/dist/coolandlovely/types/commerce.d.ts +45 -0
- package/dist/coolandlovely/types/commerce.d.ts.map +1 -1
- package/dist/coolandlovely/types/index.d.ts +9 -0
- package/dist/coolandlovely/types/index.d.ts.map +1 -1
- package/dist/generated/global-types.d.ts +4944 -1626
- package/dist/generated/global-types.d.ts.map +1 -1
- package/dist/generated/wspace-types.d.ts +98128 -34631
- package/dist/generated/wspace-types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -11,15 +11,16 @@ import { formatDate as l, formatPrice as u } from "../../utils/formatters.js";
|
|
|
11
11
|
import { EmptyState as d } from "../../components/EmptyState.js";
|
|
12
12
|
import { SelectField as f, TextAreaField as p, TextField as m } from "../../components/Field.js";
|
|
13
13
|
import { FulfilmentTimeline as h } from "../../components/FulfilmentTimeline.js";
|
|
14
|
-
import { useBrandOrder as g, useBrandOrderSummary as _, useBrandOrders as v,
|
|
15
|
-
import { RefundPanel as
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
14
|
+
import { useBrandOrder as g, useBrandOrderSummary as _, useBrandOrders as v, useBrandReturnRequests as y, useUpdateOrderFulfilment as b } from "../../hooks/useBrandOrdersApi.js";
|
|
15
|
+
import { RefundPanel as x } from "../../components/RefundPanel.js";
|
|
16
|
+
import { ReturnRequestPanel as S } from "../../components/ReturnRequests.js";
|
|
17
|
+
import { useEffect as C, useMemo as w, useState as T } from "react";
|
|
18
|
+
import { ArrowLeft as E, CheckCircle2 as D, ChevronRight as O, Loader2 as k, Package as A, PackageCheck as j, Truck as M } from "lucide-react";
|
|
19
|
+
import { useParams as N, useSearchParams as P } from "react-router";
|
|
20
|
+
import { Fragment as F, jsx as I, jsxs as L } from "react/jsx-runtime";
|
|
21
|
+
import { GlassCard as R } from "@burdenoff/fe-libs/ui";
|
|
21
22
|
//#region src/coolandlovely/pages/commerce/BrandOrdersPage.tsx
|
|
22
|
-
var
|
|
23
|
+
var z = [
|
|
23
24
|
{
|
|
24
25
|
value: void 0,
|
|
25
26
|
key: "coolandlovely.brandOrders.filterAll",
|
|
@@ -50,72 +51,101 @@ var L = [
|
|
|
50
51
|
label: "Delivered",
|
|
51
52
|
count: (e) => e.delivered
|
|
52
53
|
}
|
|
53
|
-
],
|
|
54
|
-
function
|
|
55
|
-
let c = i(), { navigateTo: p } = e(), [m, h] =
|
|
54
|
+
], B = "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", V = "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";
|
|
55
|
+
function H() {
|
|
56
|
+
let c = i(), { navigateTo: p } = e(), [m, h] = P(), g = r({ pagination: {
|
|
56
57
|
limit: 100,
|
|
57
58
|
offset: 0
|
|
58
|
-
} }),
|
|
59
|
+
} }), b = w(() => (g.data?.items ?? []).map((e) => ({
|
|
59
60
|
value: e.id,
|
|
60
61
|
label: e.name
|
|
61
|
-
})), [g.data]),
|
|
62
|
-
return
|
|
63
|
-
title:
|
|
62
|
+
})), [g.data]), x = m.get("brand") ?? b[0]?.value, [S, E] = T(void 0), D = _(x), k = v(x, S), j = y(x, "REQUESTED"), M = c("coolandlovely.brandOrders.title", "Brand orders");
|
|
63
|
+
return C(() => E(void 0), [x]), /* @__PURE__ */ I(n, {
|
|
64
|
+
title: M,
|
|
64
65
|
description: c("coolandlovely.brandOrders.description", "Paid orders for your pieces. Confirm them, ship them with tracking and mark them delivered."),
|
|
65
|
-
children: g.isLoading ? /* @__PURE__ */
|
|
66
|
-
icon: /* @__PURE__ */
|
|
66
|
+
children: g.isLoading ? /* @__PURE__ */ I(s, {}) : b.length === 0 ? /* @__PURE__ */ I(d, {
|
|
67
|
+
icon: /* @__PURE__ */ I(A, { className: "h-8 w-8" }),
|
|
67
68
|
title: c("coolandlovely.brandOrders.noBrandsTitle", "No brands yet"),
|
|
68
69
|
description: c("coolandlovely.brandOrders.noBrandsDescription", "Create a brand storefront to start selling pieces.")
|
|
69
|
-
}) : /* @__PURE__ */ F
|
|
70
|
-
/* @__PURE__ */
|
|
70
|
+
}) : /* @__PURE__ */ L(F, { children: [
|
|
71
|
+
/* @__PURE__ */ I("div", {
|
|
71
72
|
className: "mb-4 max-w-sm",
|
|
72
|
-
children: /* @__PURE__ */
|
|
73
|
+
children: /* @__PURE__ */ I(f, {
|
|
73
74
|
id: "coo-brand-orders-brand",
|
|
74
75
|
label: c("coolandlovely.brandOrders.brand", "Brand"),
|
|
75
|
-
value:
|
|
76
|
+
value: x ?? "",
|
|
76
77
|
onChange: (e) => {
|
|
77
78
|
let t = new URLSearchParams(m);
|
|
78
79
|
t.set("brand", e), h(t, { replace: !0 });
|
|
79
80
|
},
|
|
80
|
-
options:
|
|
81
|
+
options: b
|
|
81
82
|
})
|
|
82
83
|
}),
|
|
83
|
-
/* @__PURE__ */
|
|
84
|
+
(j.data?.items.length ?? 0) > 0 && /* @__PURE__ */ L(R, {
|
|
85
|
+
treatment: "plain",
|
|
86
|
+
className: "mb-4 space-y-2 p-4",
|
|
87
|
+
"data-testid": "brand-pending-returns",
|
|
88
|
+
children: [/* @__PURE__ */ I("p", {
|
|
89
|
+
className: "text-xs font-medium uppercase tracking-wide text-text-secondary",
|
|
90
|
+
children: c("coolandlovely.returns.pendingTitle", "Return requests waiting for you")
|
|
91
|
+
}), j.data?.items.map((e) => /* @__PURE__ */ L("button", {
|
|
92
|
+
type: "button",
|
|
93
|
+
onClick: () => p(`/brand-orders/${e.brandId}/${e.orderId}`),
|
|
94
|
+
className: "flex w-full items-center gap-3 rounded-lg px-2 py-1.5 text-left transition-colors hover:bg-bg-sunken/50",
|
|
95
|
+
"data-testid": "brand-pending-return",
|
|
96
|
+
children: [
|
|
97
|
+
/* @__PURE__ */ I("span", {
|
|
98
|
+
className: "font-mono text-sm text-text-primary",
|
|
99
|
+
children: e.orderNumber ?? e.orderId
|
|
100
|
+
}),
|
|
101
|
+
/* @__PURE__ */ I("span", {
|
|
102
|
+
className: "min-w-0 flex-1 truncate text-xs text-text-secondary",
|
|
103
|
+
children: e.reason
|
|
104
|
+
}),
|
|
105
|
+
/* @__PURE__ */ I("span", {
|
|
106
|
+
className: "text-xs text-text-secondary",
|
|
107
|
+
children: l(e.createdAt)
|
|
108
|
+
}),
|
|
109
|
+
/* @__PURE__ */ I(O, { className: "h-4 w-4 text-text-secondary" })
|
|
110
|
+
]
|
|
111
|
+
}, e.id))]
|
|
112
|
+
}),
|
|
113
|
+
/* @__PURE__ */ I("div", {
|
|
84
114
|
className: "mb-4 flex flex-wrap gap-2",
|
|
85
115
|
role: "tablist",
|
|
86
|
-
children:
|
|
116
|
+
children: z.map((e) => /* @__PURE__ */ L("button", {
|
|
87
117
|
type: "button",
|
|
88
118
|
role: "tab",
|
|
89
|
-
"aria-selected":
|
|
90
|
-
onClick: () =>
|
|
91
|
-
className: t("inline-flex items-center gap-1.5 rounded-full border px-3 py-1 text-sm font-medium transition-colors",
|
|
92
|
-
children: [c(e.key, e.label), D.data && /* @__PURE__ */
|
|
119
|
+
"aria-selected": S === e.value,
|
|
120
|
+
onClick: () => E(e.value),
|
|
121
|
+
className: t("inline-flex items-center gap-1.5 rounded-full border px-3 py-1 text-sm font-medium transition-colors", S === e.value ? "border-action-primary-bg bg-action-primary-bg text-action-primary-text" : "border-border-seam text-text-primary hover:bg-bg-sunken"),
|
|
122
|
+
children: [c(e.key, e.label), D.data && /* @__PURE__ */ I("span", {
|
|
93
123
|
className: "tabular-nums opacity-80",
|
|
94
124
|
children: e.count(D.data)
|
|
95
125
|
})]
|
|
96
126
|
}, e.key))
|
|
97
127
|
}),
|
|
98
|
-
k.isLoading ? /* @__PURE__ */
|
|
128
|
+
k.isLoading ? /* @__PURE__ */ I(s, { label: c("coolandlovely.brandOrders.loading", "Loading orders…") }) : k.isError || !k.data ? /* @__PURE__ */ I(o, {
|
|
99
129
|
message: k.error?.message,
|
|
100
130
|
onRetry: () => void k.refetch()
|
|
101
|
-
}) : k.data.items.length === 0 ? /* @__PURE__ */
|
|
102
|
-
icon: /* @__PURE__ */
|
|
131
|
+
}) : k.data.items.length === 0 ? /* @__PURE__ */ I(d, {
|
|
132
|
+
icon: /* @__PURE__ */ I(A, { className: "h-8 w-8" }),
|
|
103
133
|
title: c("coolandlovely.brandOrders.emptyTitle", "No orders here"),
|
|
104
134
|
description: c("coolandlovely.brandOrders.emptyDescription", "Paid orders for this brand’s pieces appear here.")
|
|
105
|
-
}) : /* @__PURE__ */
|
|
135
|
+
}) : /* @__PURE__ */ I("div", {
|
|
106
136
|
className: "space-y-3",
|
|
107
137
|
"data-testid": "brand-orders-list",
|
|
108
|
-
children: k.data.items.map((e) => /* @__PURE__ */
|
|
138
|
+
children: k.data.items.map((e) => /* @__PURE__ */ L("button", {
|
|
109
139
|
type: "button",
|
|
110
140
|
onClick: () => p(`/brand-orders/${e.brandId}/${e.id}`),
|
|
111
141
|
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",
|
|
112
142
|
children: [
|
|
113
|
-
/* @__PURE__ */
|
|
143
|
+
/* @__PURE__ */ L("div", {
|
|
114
144
|
className: "min-w-0 flex-1",
|
|
115
|
-
children: [/* @__PURE__ */
|
|
145
|
+
children: [/* @__PURE__ */ I("p", {
|
|
116
146
|
className: "font-mono text-sm font-medium text-text-primary",
|
|
117
147
|
children: e.orderNumber
|
|
118
|
-
}), /* @__PURE__ */
|
|
148
|
+
}), /* @__PURE__ */ L("p", {
|
|
119
149
|
className: "truncate text-xs text-text-secondary",
|
|
120
150
|
children: [
|
|
121
151
|
l(e.paidAt ?? e.createdAt),
|
|
@@ -127,21 +157,22 @@ function B() {
|
|
|
127
157
|
]
|
|
128
158
|
})]
|
|
129
159
|
}),
|
|
130
|
-
/* @__PURE__ */
|
|
131
|
-
/* @__PURE__ */
|
|
160
|
+
e.returnRequest?.status === "REQUESTED" && /* @__PURE__ */ I(a, { status: "REQUESTED" }),
|
|
161
|
+
/* @__PURE__ */ I(a, { status: e.fulfilment.refunded ? "REFUNDED" : e.fulfilment.status }),
|
|
162
|
+
/* @__PURE__ */ I("span", {
|
|
132
163
|
className: "w-28 text-right text-sm font-semibold tabular-nums text-text-primary",
|
|
133
164
|
children: u(e.brandSubtotal, e.currency)
|
|
134
165
|
}),
|
|
135
|
-
/* @__PURE__ */
|
|
166
|
+
/* @__PURE__ */ I(O, { className: "h-4 w-4 text-text-secondary" })
|
|
136
167
|
]
|
|
137
168
|
}, e.id))
|
|
138
169
|
})
|
|
139
170
|
] })
|
|
140
171
|
});
|
|
141
172
|
}
|
|
142
|
-
function
|
|
143
|
-
let n = i(), r =
|
|
144
|
-
if (a.status === "DELIVERED") return /* @__PURE__ */
|
|
173
|
+
function U({ order: e }) {
|
|
174
|
+
let n = i(), r = b(), a = e.fulfilment, [o, s] = T(a.carrier ?? ""), [c, l] = T(a.trackingNumber ?? ""), [u, d] = T(a.trackingUrl ?? ""), [f, h] = T(a.note ?? "");
|
|
175
|
+
if (a.status === "DELIVERED") return /* @__PURE__ */ I("p", {
|
|
145
176
|
className: "text-sm text-status-success-text",
|
|
146
177
|
children: n("coolandlovely.fulfilment.complete", "Delivered. Nothing left to do for this order.")
|
|
147
178
|
});
|
|
@@ -153,23 +184,23 @@ function V({ order: e }) {
|
|
|
153
184
|
trackingUrl: u.trim() || null,
|
|
154
185
|
note: f.trim() || null
|
|
155
186
|
}, _ = !!g.carrier && !!g.trackingNumber;
|
|
156
|
-
return /* @__PURE__ */
|
|
187
|
+
return /* @__PURE__ */ L("div", {
|
|
157
188
|
className: "space-y-3 border-t border-border-seam pt-4",
|
|
158
189
|
children: [
|
|
159
|
-
/* @__PURE__ */
|
|
190
|
+
/* @__PURE__ */ I(m, {
|
|
160
191
|
id: "coo-fulfilment-carrier",
|
|
161
192
|
label: n("coolandlovely.fulfilment.carrier", "Carrier"),
|
|
162
193
|
value: o,
|
|
163
194
|
onChange: s,
|
|
164
195
|
placeholder: "Delhivery"
|
|
165
196
|
}),
|
|
166
|
-
/* @__PURE__ */
|
|
197
|
+
/* @__PURE__ */ I(m, {
|
|
167
198
|
id: "coo-fulfilment-tracking",
|
|
168
199
|
label: n("coolandlovely.fulfilment.trackingNumber", "Tracking number"),
|
|
169
200
|
value: c,
|
|
170
201
|
onChange: l
|
|
171
202
|
}),
|
|
172
|
-
/* @__PURE__ */
|
|
203
|
+
/* @__PURE__ */ I(m, {
|
|
173
204
|
id: "coo-fulfilment-tracking-url",
|
|
174
205
|
type: "url",
|
|
175
206
|
label: n("coolandlovely.fulfilment.trackingUrl", "Tracking link (optional)"),
|
|
@@ -177,60 +208,60 @@ function V({ order: e }) {
|
|
|
177
208
|
onChange: d,
|
|
178
209
|
placeholder: "https://"
|
|
179
210
|
}),
|
|
180
|
-
/* @__PURE__ */
|
|
211
|
+
/* @__PURE__ */ I(p, {
|
|
181
212
|
id: "coo-fulfilment-note",
|
|
182
213
|
label: n("coolandlovely.fulfilment.note", "Note for the buyer (optional)"),
|
|
183
214
|
value: f,
|
|
184
215
|
onChange: h,
|
|
185
216
|
rows: 2
|
|
186
217
|
}),
|
|
187
|
-
r.error && /* @__PURE__ */
|
|
218
|
+
r.error && /* @__PURE__ */ I("p", {
|
|
188
219
|
className: "text-sm text-status-error-text",
|
|
189
220
|
children: r.error.message
|
|
190
221
|
}),
|
|
191
|
-
/* @__PURE__ */
|
|
222
|
+
/* @__PURE__ */ L("div", {
|
|
192
223
|
className: "space-y-2",
|
|
193
224
|
children: [
|
|
194
|
-
a.status === "UNFULFILLED" && /* @__PURE__ */
|
|
225
|
+
a.status === "UNFULFILLED" && /* @__PURE__ */ L("button", {
|
|
195
226
|
type: "button",
|
|
196
227
|
disabled: r.isPending,
|
|
197
228
|
onClick: () => r.mutate({
|
|
198
229
|
...g,
|
|
199
230
|
status: "CONFIRMED"
|
|
200
231
|
}),
|
|
201
|
-
className: t(
|
|
202
|
-
children: [/* @__PURE__ */
|
|
232
|
+
className: t(B, "w-full justify-center"),
|
|
233
|
+
children: [/* @__PURE__ */ I(D, { className: "h-4 w-4" }), n("coolandlovely.fulfilment.confirm", "Confirm order")]
|
|
203
234
|
}),
|
|
204
|
-
(a.status === "UNFULFILLED" || a.status === "CONFIRMED") && /* @__PURE__ */
|
|
235
|
+
(a.status === "UNFULFILLED" || a.status === "CONFIRMED") && /* @__PURE__ */ L("button", {
|
|
205
236
|
type: "button",
|
|
206
237
|
disabled: r.isPending || !_,
|
|
207
238
|
onClick: () => r.mutate({
|
|
208
239
|
...g,
|
|
209
240
|
status: "SHIPPED"
|
|
210
241
|
}),
|
|
211
|
-
className:
|
|
212
|
-
children: [r.isPending ? /* @__PURE__ */
|
|
242
|
+
className: V,
|
|
243
|
+
children: [r.isPending ? /* @__PURE__ */ I(k, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ I(M, { className: "h-4 w-4" }), n("coolandlovely.fulfilment.markShipped", "Mark shipped")]
|
|
213
244
|
}),
|
|
214
|
-
a.status === "SHIPPED" && /* @__PURE__ */ F
|
|
245
|
+
a.status === "SHIPPED" && /* @__PURE__ */ L(F, { children: [/* @__PURE__ */ I("button", {
|
|
215
246
|
type: "button",
|
|
216
247
|
disabled: r.isPending || !_,
|
|
217
248
|
onClick: () => r.mutate({
|
|
218
249
|
...g,
|
|
219
250
|
status: "SHIPPED"
|
|
220
251
|
}),
|
|
221
|
-
className: t(
|
|
252
|
+
className: t(B, "w-full justify-center"),
|
|
222
253
|
children: n("coolandlovely.fulfilment.saveTracking", "Save tracking details")
|
|
223
|
-
}), /* @__PURE__ */
|
|
254
|
+
}), /* @__PURE__ */ L("button", {
|
|
224
255
|
type: "button",
|
|
225
256
|
disabled: r.isPending,
|
|
226
257
|
onClick: () => r.mutate({
|
|
227
258
|
...g,
|
|
228
259
|
status: "DELIVERED"
|
|
229
260
|
}),
|
|
230
|
-
className:
|
|
231
|
-
children: [r.isPending ? /* @__PURE__ */
|
|
261
|
+
className: V,
|
|
262
|
+
children: [r.isPending ? /* @__PURE__ */ I(k, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ I(j, { className: "h-4 w-4" }), n("coolandlovely.fulfilment.markDelivered", "Mark delivered")]
|
|
232
263
|
})] }),
|
|
233
|
-
!_ && a.status !== "SHIPPED" && /* @__PURE__ */
|
|
264
|
+
!_ && a.status !== "SHIPPED" && /* @__PURE__ */ I("p", {
|
|
234
265
|
className: "text-xs text-text-secondary",
|
|
235
266
|
children: n("coolandlovely.fulfilment.trackingHint", "Add a carrier and tracking number to mark the order shipped.")
|
|
236
267
|
})
|
|
@@ -239,55 +270,55 @@ function V({ order: e }) {
|
|
|
239
270
|
]
|
|
240
271
|
});
|
|
241
272
|
}
|
|
242
|
-
function
|
|
243
|
-
let t = i(), { brandId: r, orderId: d } =
|
|
244
|
-
if (p.isLoading) return /* @__PURE__ */
|
|
273
|
+
function W() {
|
|
274
|
+
let t = i(), { brandId: r, orderId: d } = N(), { navigateTo: f } = e(), p = g(r, d), m = t("coolandlovely.brandOrders.detailTitle", "Order"), _ = () => f(`/brand-orders?brand=${r ?? ""}`);
|
|
275
|
+
if (p.isLoading) return /* @__PURE__ */ I(n, {
|
|
245
276
|
title: m,
|
|
246
|
-
children: /* @__PURE__ */
|
|
277
|
+
children: /* @__PURE__ */ I(s, {})
|
|
247
278
|
});
|
|
248
|
-
if (p.isError || !p.data) return /* @__PURE__ */
|
|
279
|
+
if (p.isError || !p.data) return /* @__PURE__ */ I(n, {
|
|
249
280
|
title: m,
|
|
250
|
-
children: /* @__PURE__ */
|
|
281
|
+
children: /* @__PURE__ */ I(o, {
|
|
251
282
|
title: t("coolandlovely.orders.notFound", "Order not found"),
|
|
252
283
|
message: p.error?.message,
|
|
253
284
|
onRetry: () => void p.refetch()
|
|
254
285
|
})
|
|
255
286
|
});
|
|
256
287
|
let v = p.data, y = v.fulfilment.refunded || v.refund?.status === "PENDING" || v.refund?.status === "COMPLETED";
|
|
257
|
-
return /* @__PURE__ */
|
|
288
|
+
return /* @__PURE__ */ I(n, {
|
|
258
289
|
title: v.orderNumber,
|
|
259
290
|
description: t("coolandlovely.brandOrders.paidOn", "Paid {{date}}", { date: l(v.paidAt ?? v.createdAt) }),
|
|
260
|
-
actions: /* @__PURE__ */
|
|
291
|
+
actions: /* @__PURE__ */ L("button", {
|
|
261
292
|
type: "button",
|
|
262
293
|
onClick: _,
|
|
263
|
-
className:
|
|
294
|
+
className: B,
|
|
264
295
|
children: [
|
|
265
|
-
/* @__PURE__ */
|
|
296
|
+
/* @__PURE__ */ I(E, { className: "h-4 w-4" }),
|
|
266
297
|
" ",
|
|
267
298
|
t("coolandlovely.common.back", "Back")
|
|
268
299
|
]
|
|
269
300
|
}),
|
|
270
|
-
children: /* @__PURE__ */
|
|
301
|
+
children: /* @__PURE__ */ L("div", {
|
|
271
302
|
className: "grid grid-cols-1 gap-6 lg:grid-cols-3",
|
|
272
|
-
children: [/* @__PURE__ */
|
|
303
|
+
children: [/* @__PURE__ */ L("div", {
|
|
273
304
|
className: "space-y-3 lg:col-span-2",
|
|
274
|
-
children: [v.items.map((e) => /* @__PURE__ */
|
|
305
|
+
children: [v.items.map((e) => /* @__PURE__ */ L(R, {
|
|
275
306
|
treatment: "plain",
|
|
276
307
|
className: "flex items-center gap-4 p-4",
|
|
277
308
|
children: [
|
|
278
|
-
/* @__PURE__ */
|
|
279
|
-
icon: /* @__PURE__ */
|
|
309
|
+
/* @__PURE__ */ I(c, {
|
|
310
|
+
icon: /* @__PURE__ */ I(A, { className: "h-5 w-5" }),
|
|
280
311
|
seed: e.styleItemId,
|
|
281
312
|
fileId: e.image?.id,
|
|
282
313
|
alt: e.name,
|
|
283
314
|
className: "h-14 w-14 shrink-0"
|
|
284
315
|
}),
|
|
285
|
-
/* @__PURE__ */
|
|
316
|
+
/* @__PURE__ */ L("div", {
|
|
286
317
|
className: "min-w-0 flex-1",
|
|
287
|
-
children: [/* @__PURE__ */
|
|
318
|
+
children: [/* @__PURE__ */ I("p", {
|
|
288
319
|
className: "truncate text-sm font-medium text-text-primary",
|
|
289
320
|
children: e.name
|
|
290
|
-
}), /* @__PURE__ */
|
|
321
|
+
}), /* @__PURE__ */ I("p", {
|
|
291
322
|
className: "truncate text-xs text-text-secondary",
|
|
292
323
|
children: [
|
|
293
324
|
e.sku,
|
|
@@ -297,66 +328,67 @@ function H() {
|
|
|
297
328
|
].filter(Boolean).join(" · ")
|
|
298
329
|
})]
|
|
299
330
|
}),
|
|
300
|
-
/* @__PURE__ */
|
|
331
|
+
/* @__PURE__ */ I("span", {
|
|
301
332
|
className: "text-sm font-semibold tabular-nums text-text-primary",
|
|
302
333
|
children: u(e.lineTotal, v.currency)
|
|
303
334
|
})
|
|
304
335
|
]
|
|
305
|
-
}, e.id)), /* @__PURE__ */
|
|
336
|
+
}, e.id)), /* @__PURE__ */ L(R, {
|
|
306
337
|
treatment: "plain",
|
|
307
338
|
className: "space-y-1 p-4 text-sm",
|
|
308
339
|
children: [
|
|
309
|
-
/* @__PURE__ */
|
|
340
|
+
/* @__PURE__ */ I("p", {
|
|
310
341
|
className: "text-xs font-medium uppercase tracking-wide text-text-secondary",
|
|
311
342
|
children: t("coolandlovely.orders.shipTo", "Ship to")
|
|
312
343
|
}),
|
|
313
|
-
/* @__PURE__ */
|
|
344
|
+
/* @__PURE__ */ I("p", {
|
|
314
345
|
className: "text-text-primary",
|
|
315
346
|
children: v.shippingName
|
|
316
347
|
}),
|
|
317
|
-
/* @__PURE__ */
|
|
348
|
+
/* @__PURE__ */ I("p", {
|
|
318
349
|
className: "whitespace-pre-line text-text-secondary",
|
|
319
350
|
children: v.shippingAddress
|
|
320
351
|
}),
|
|
321
|
-
v.buyerNote && /* @__PURE__ */
|
|
352
|
+
v.buyerNote && /* @__PURE__ */ I("p", {
|
|
322
353
|
className: "pt-2 text-text-secondary",
|
|
323
354
|
children: t("coolandlovely.brandOrders.buyerNote", "Buyer note: {{note}}", { note: v.buyerNote })
|
|
324
355
|
})
|
|
325
356
|
]
|
|
326
357
|
})]
|
|
327
|
-
}), /* @__PURE__ */
|
|
358
|
+
}), /* @__PURE__ */ L(R, {
|
|
328
359
|
treatment: "glass",
|
|
329
360
|
className: "h-fit space-y-4 p-6",
|
|
330
361
|
children: [
|
|
331
|
-
/* @__PURE__ */
|
|
362
|
+
/* @__PURE__ */ L("div", {
|
|
332
363
|
className: "flex items-center justify-between",
|
|
333
|
-
children: [/* @__PURE__ */
|
|
364
|
+
children: [/* @__PURE__ */ I("span", {
|
|
334
365
|
className: "text-sm text-text-secondary",
|
|
335
366
|
children: t("coolandlovely.fulfilment.status", "Fulfilment")
|
|
336
|
-
}), /* @__PURE__ */
|
|
367
|
+
}), /* @__PURE__ */ I("span", {
|
|
337
368
|
"data-testid": "fulfilment-status",
|
|
338
|
-
children: /* @__PURE__ */
|
|
369
|
+
children: /* @__PURE__ */ I(a, { status: v.fulfilment.refunded ? "REFUNDED" : v.fulfilment.status })
|
|
339
370
|
})]
|
|
340
371
|
}),
|
|
341
|
-
/* @__PURE__ */
|
|
372
|
+
/* @__PURE__ */ L("div", {
|
|
342
373
|
className: "flex justify-between text-sm",
|
|
343
|
-
children: [/* @__PURE__ */
|
|
374
|
+
children: [/* @__PURE__ */ I("span", {
|
|
344
375
|
className: "text-text-secondary",
|
|
345
376
|
children: t("coolandlovely.brandOrders.brandSubtotal", "Your pieces")
|
|
346
|
-
}), /* @__PURE__ */
|
|
377
|
+
}), /* @__PURE__ */ I("span", {
|
|
347
378
|
className: "font-semibold tabular-nums text-text-primary",
|
|
348
379
|
children: u(v.brandSubtotal, v.currency)
|
|
349
380
|
})]
|
|
350
381
|
}),
|
|
351
|
-
/* @__PURE__ */
|
|
352
|
-
!y && /* @__PURE__ */
|
|
353
|
-
/* @__PURE__ */
|
|
382
|
+
/* @__PURE__ */ I(h, { fulfilment: v.fulfilment }),
|
|
383
|
+
!y && /* @__PURE__ */ I(U, { order: v }, v.fulfilment.updatedAt ?? "new"),
|
|
384
|
+
/* @__PURE__ */ I(S, { order: v }),
|
|
385
|
+
/* @__PURE__ */ I(x, { order: v })
|
|
354
386
|
]
|
|
355
387
|
})]
|
|
356
388
|
})
|
|
357
389
|
});
|
|
358
390
|
}
|
|
359
391
|
//#endregion
|
|
360
|
-
export {
|
|
392
|
+
export { W as BrandOrderDetailPage, H as BrandOrdersPage };
|
|
361
393
|
|
|
362
394
|
//# sourceMappingURL=BrandOrdersPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BrandOrdersPage.js","names":[],"sources":["../../../../src/coolandlovely/pages/commerce/BrandOrdersPage.tsx"],"sourcesContent":["/**\n * Brand orders + brand order detail (BOFF-9636)\n * @module coolandlovely/pages/commerce\n *\n * The brand side of CoolAndLovely orders: the paid orders that contain a brand's pieces\n * (`cooBrandOrders`, only that brand's lines), counts per fulfilment state\n * (`cooBrandOrderSummary`), and one order's fulfilment — confirm it, ship it with tracking,\n * mark it delivered (`cooUpdateOrderFulfilment`). Fulfilment only moves forward, and the\n * buyer is notified of every change. A brand can also refund all of its pieces of an order\n * (`cooRefundBrandOrder`, BOFF-9702); refunded pieces are no longer fulfilled.\n */\n\nimport { useEffect, useMemo, useState } from 'react';\nimport { useParams, useSearchParams } from 'react-router';\nimport {\n ArrowLeft,\n CheckCircle2,\n ChevronRight,\n Loader2,\n Package,\n PackageCheck,\n Truck,\n} from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\n\nimport { EmptyState } from '../../components/EmptyState';\nimport { FulfilmentTimeline } from '../../components/FulfilmentTimeline';\nimport { SelectField, TextAreaField, TextField } from '../../components/Field';\nimport { PageLayout } from '../../components/PageLayout';\nimport { RefundPanel } from '../../components/RefundPanel';\nimport { ErrorView, LoadingView } from '../../components/StateViews';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { Thumbnail } from '../../components/Thumbnail';\nimport { useCoolAndLovely } from '../../context/CoolAndLovelyContext';\nimport { useBrands, useTr } from '../../hooks';\nimport {\n useBrandOrder,\n useBrandOrderSummary,\n useBrandOrders,\n useUpdateOrderFulfilment,\n} from '../../hooks/useBrandOrdersApi';\nimport type { CooBrandOrder, CooBrandOrderSummary, CooFulfilmentStatus } from '../../types';\nimport { cn } from '../../utils/cn';\nimport { formatDate, formatPrice } from '../../utils/formatters';\n\nconst FILTERS: Array<{\n value: CooFulfilmentStatus | undefined;\n key: string;\n label: string;\n count: (summary: CooBrandOrderSummary) => number;\n}> = [\n {\n value: undefined,\n key: 'coolandlovely.brandOrders.filterAll',\n label: 'All',\n count: (s) => s.total,\n },\n {\n value: 'UNFULFILLED',\n key: 'coolandlovely.brandOrders.filterUnfulfilled',\n label: 'To confirm',\n count: (s) => s.unfulfilled,\n },\n {\n value: 'CONFIRMED',\n key: 'coolandlovely.brandOrders.filterConfirmed',\n label: 'Confirmed',\n count: (s) => s.confirmed,\n },\n {\n value: 'SHIPPED',\n key: 'coolandlovely.brandOrders.filterShipped',\n label: 'Shipped',\n count: (s) => s.shipped,\n },\n {\n value: 'DELIVERED',\n key: 'coolandlovely.brandOrders.filterDelivered',\n label: 'Delivered',\n count: (s) => s.delivered,\n },\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';\nconst primaryButton =\n '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\nexport function BrandOrdersPage() {\n const tr = useTr();\n const { navigateTo } = useCoolAndLovely();\n const [searchParams, setSearchParams] = useSearchParams();\n const brands = useBrands({ pagination: { limit: 100, offset: 0 } });\n const brandOptions = useMemo(\n () => (brands.data?.items ?? []).map((brand) => ({ value: brand.id, label: brand.name })),\n [brands.data]\n );\n const brandId = searchParams.get('brand') ?? brandOptions[0]?.value;\n const [status, setStatus] = useState<CooFulfilmentStatus | undefined>(undefined);\n const summary = useBrandOrderSummary(brandId);\n const orders = useBrandOrders(brandId, status);\n const title = tr('coolandlovely.brandOrders.title', 'Brand orders');\n\n useEffect(() => setStatus(undefined), [brandId]);\n\n const selectBrand = (value: string) => {\n const next = new URLSearchParams(searchParams);\n next.set('brand', value);\n setSearchParams(next, { replace: true });\n };\n\n return (\n <PageLayout\n title={title}\n description={tr(\n 'coolandlovely.brandOrders.description',\n 'Paid orders for your pieces. Confirm them, ship them with tracking and mark them delivered.'\n )}\n >\n {brands.isLoading ? (\n <LoadingView />\n ) : brandOptions.length === 0 ? (\n <EmptyState\n icon={<Package className=\"h-8 w-8\" />}\n title={tr('coolandlovely.brandOrders.noBrandsTitle', 'No brands yet')}\n description={tr(\n 'coolandlovely.brandOrders.noBrandsDescription',\n 'Create a brand storefront to start selling pieces.'\n )}\n />\n ) : (\n <>\n <div className=\"mb-4 max-w-sm\">\n <SelectField\n id=\"coo-brand-orders-brand\"\n label={tr('coolandlovely.brandOrders.brand', 'Brand')}\n value={brandId ?? ''}\n onChange={selectBrand}\n options={brandOptions}\n />\n </div>\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 'inline-flex items-center gap-1.5 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 {summary.data && (\n <span className=\"tabular-nums opacity-80\">{filter.count(summary.data)}</span>\n )}\n </button>\n ))}\n </div>\n {orders.isLoading ? (\n <LoadingView label={tr('coolandlovely.brandOrders.loading', 'Loading orders…')} />\n ) : orders.isError || !orders.data ? (\n <ErrorView message={orders.error?.message} onRetry={() => void orders.refetch()} />\n ) : orders.data.items.length === 0 ? (\n <EmptyState\n icon={<Package className=\"h-8 w-8\" />}\n title={tr('coolandlovely.brandOrders.emptyTitle', 'No orders here')}\n description={tr(\n 'coolandlovely.brandOrders.emptyDescription',\n 'Paid orders for this brand’s pieces appear here.'\n )}\n />\n ) : (\n <div className=\"space-y-3\" data-testid=\"brand-orders-list\">\n {orders.data.items.map((order) => (\n <button\n key={order.id}\n type=\"button\"\n onClick={() => navigateTo(`/brand-orders/${order.brandId}/${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.paidAt ?? order.createdAt)} · {order.shippingName ?? '—'} ·{' '}\n {tr('coolandlovely.orders.pieces', '{{count}} pieces', {\n count: order.itemCount,\n })}\n </p>\n </div>\n <StatusBadge\n status={order.fulfilment.refunded ? 'REFUNDED' : order.fulfilment.status}\n />\n <span className=\"w-28 text-right text-sm font-semibold tabular-nums text-text-primary\">\n {formatPrice(order.brandSubtotal, order.currency)}\n </span>\n <ChevronRight className=\"h-4 w-4 text-text-secondary\" />\n </button>\n ))}\n </div>\n )}\n </>\n )}\n </PageLayout>\n );\n}\n\nfunction FulfilmentForm({ order }: { order: CooBrandOrder }) {\n const tr = useTr();\n const update = useUpdateOrderFulfilment();\n const current = order.fulfilment;\n const [carrier, setCarrier] = useState(current.carrier ?? '');\n const [trackingNumber, setTrackingNumber] = useState(current.trackingNumber ?? '');\n const [trackingUrl, setTrackingUrl] = useState(current.trackingUrl ?? '');\n const [note, setNote] = useState(current.note ?? '');\n\n if (current.status === 'DELIVERED') {\n return (\n <p className=\"text-sm text-status-success-text\">\n {tr('coolandlovely.fulfilment.complete', 'Delivered. Nothing left to do for this order.')}\n </p>\n );\n }\n\n const details = {\n brandId: order.brandId,\n orderId: order.id,\n carrier: carrier.trim() || null,\n trackingNumber: trackingNumber.trim() || null,\n trackingUrl: trackingUrl.trim() || null,\n note: note.trim() || null,\n };\n const canShip = !!details.carrier && !!details.trackingNumber;\n\n return (\n <div className=\"space-y-3 border-t border-border-seam pt-4\">\n <TextField\n id=\"coo-fulfilment-carrier\"\n label={tr('coolandlovely.fulfilment.carrier', 'Carrier')}\n value={carrier}\n onChange={setCarrier}\n placeholder=\"Delhivery\"\n />\n <TextField\n id=\"coo-fulfilment-tracking\"\n label={tr('coolandlovely.fulfilment.trackingNumber', 'Tracking number')}\n value={trackingNumber}\n onChange={setTrackingNumber}\n />\n <TextField\n id=\"coo-fulfilment-tracking-url\"\n type=\"url\"\n label={tr('coolandlovely.fulfilment.trackingUrl', 'Tracking link (optional)')}\n value={trackingUrl}\n onChange={setTrackingUrl}\n placeholder=\"https://\"\n />\n <TextAreaField\n id=\"coo-fulfilment-note\"\n label={tr('coolandlovely.fulfilment.note', 'Note for the buyer (optional)')}\n value={note}\n onChange={setNote}\n rows={2}\n />\n {update.error && <p className=\"text-sm text-status-error-text\">{update.error.message}</p>}\n <div className=\"space-y-2\">\n {current.status === 'UNFULFILLED' && (\n <button\n type=\"button\"\n disabled={update.isPending}\n onClick={() => update.mutate({ ...details, status: 'CONFIRMED' })}\n className={cn(secondaryButton, 'w-full justify-center')}\n >\n <CheckCircle2 className=\"h-4 w-4\" />\n {tr('coolandlovely.fulfilment.confirm', 'Confirm order')}\n </button>\n )}\n {(current.status === 'UNFULFILLED' || current.status === 'CONFIRMED') && (\n <button\n type=\"button\"\n disabled={update.isPending || !canShip}\n onClick={() => update.mutate({ ...details, status: 'SHIPPED' })}\n className={primaryButton}\n >\n {update.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Truck className=\"h-4 w-4\" />\n )}\n {tr('coolandlovely.fulfilment.markShipped', 'Mark shipped')}\n </button>\n )}\n {current.status === 'SHIPPED' && (\n <>\n <button\n type=\"button\"\n disabled={update.isPending || !canShip}\n onClick={() => update.mutate({ ...details, status: 'SHIPPED' })}\n className={cn(secondaryButton, 'w-full justify-center')}\n >\n {tr('coolandlovely.fulfilment.saveTracking', 'Save tracking details')}\n </button>\n <button\n type=\"button\"\n disabled={update.isPending}\n onClick={() => update.mutate({ ...details, status: 'DELIVERED' })}\n className={primaryButton}\n >\n {update.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <PackageCheck className=\"h-4 w-4\" />\n )}\n {tr('coolandlovely.fulfilment.markDelivered', 'Mark delivered')}\n </button>\n </>\n )}\n {!canShip && current.status !== 'SHIPPED' && (\n <p className=\"text-xs text-text-secondary\">\n {tr(\n 'coolandlovely.fulfilment.trackingHint',\n 'Add a carrier and tracking number to mark the order shipped.'\n )}\n </p>\n )}\n </div>\n </div>\n );\n}\n\nexport function BrandOrderDetailPage() {\n const tr = useTr();\n const { brandId, orderId } = useParams<{ brandId: string; orderId: string }>();\n const { navigateTo } = useCoolAndLovely();\n const order = useBrandOrder(brandId, orderId);\n const title = tr('coolandlovely.brandOrders.detailTitle', 'Order');\n const back = () => navigateTo(`/brand-orders?brand=${brandId ?? ''}`);\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 message={order.error?.message}\n onRetry={() => void order.refetch()}\n />\n </PageLayout>\n );\n }\n\n const data = order.data;\n // Pieces the brand refunded, or is refunding, are not shipped.\n const refundBlocksFulfilment =\n data.fulfilment.refunded ||\n data.refund?.status === 'PENDING' ||\n data.refund?.status === 'COMPLETED';\n return (\n <PageLayout\n title={data.orderNumber}\n description={tr('coolandlovely.brandOrders.paidOn', 'Paid {{date}}', {\n date: formatDate(data.paidAt ?? data.createdAt),\n })}\n actions={\n <button type=\"button\" onClick={back} className={secondaryButton}>\n <ArrowLeft className=\"h-4 w-4\" /> {tr('coolandlovely.common.back', 'Back')}\n </button>\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.sku, item.size, item.colour, `× ${item.quantity}`]\n .filter(Boolean)\n .join(' · ')}\n </p>\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 <GlassCard treatment=\"plain\" className=\"space-y-1 p-4 text-sm\">\n <p className=\"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 {data.buyerNote && (\n <p className=\"pt-2 text-text-secondary\">\n {tr('coolandlovely.brandOrders.buyerNote', 'Buyer note: {{note}}', {\n note: data.buyerNote,\n })}\n </p>\n )}\n </GlassCard>\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.fulfilment.status', 'Fulfilment')}\n </span>\n <span data-testid=\"fulfilment-status\">\n <StatusBadge\n status={data.fulfilment.refunded ? 'REFUNDED' : data.fulfilment.status}\n />\n </span>\n </div>\n <div className=\"flex justify-between text-sm\">\n <span className=\"text-text-secondary\">\n {tr('coolandlovely.brandOrders.brandSubtotal', 'Your pieces')}\n </span>\n <span className=\"font-semibold tabular-nums text-text-primary\">\n {formatPrice(data.brandSubtotal, data.currency)}\n </span>\n </div>\n <FulfilmentTimeline fulfilment={data.fulfilment} />\n {!refundBlocksFulfilment && (\n <FulfilmentForm key={data.fulfilment.updatedAt ?? 'new'} order={data} />\n )}\n <RefundPanel order={data} />\n </GlassCard>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BrandOrdersPage.js","names":[],"sources":["../../../../src/coolandlovely/pages/commerce/BrandOrdersPage.tsx"],"sourcesContent":["/**\n * Brand orders + brand order detail (BOFF-9636)\n * @module coolandlovely/pages/commerce\n *\n * The brand side of CoolAndLovely orders: the paid orders that contain a brand's pieces\n * (`cooBrandOrders`, only that brand's lines), counts per fulfilment state\n * (`cooBrandOrderSummary`), and one order's fulfilment — confirm it, ship it with tracking,\n * mark it delivered (`cooUpdateOrderFulfilment`). Fulfilment only moves forward, and the\n * buyer is notified of every change. A brand can also refund all of its pieces of an order\n * (`cooRefundBrandOrder`, BOFF-9702); refunded pieces are no longer fulfilled. Shoppers' return\n * requests (BOFF-9900) are listed while pending, and the brand approves (which refunds) or\n * declines each one on the order detail.\n */\n\nimport { useEffect, useMemo, useState } from 'react';\nimport { useParams, useSearchParams } from 'react-router';\nimport {\n ArrowLeft,\n CheckCircle2,\n ChevronRight,\n Loader2,\n Package,\n PackageCheck,\n Truck,\n} from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\n\nimport { EmptyState } from '../../components/EmptyState';\nimport { FulfilmentTimeline } from '../../components/FulfilmentTimeline';\nimport { SelectField, TextAreaField, TextField } from '../../components/Field';\nimport { PageLayout } from '../../components/PageLayout';\nimport { RefundPanel } from '../../components/RefundPanel';\nimport { ReturnRequestPanel } from '../../components/ReturnRequests';\nimport { ErrorView, LoadingView } from '../../components/StateViews';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { Thumbnail } from '../../components/Thumbnail';\nimport { useCoolAndLovely } from '../../context/CoolAndLovelyContext';\nimport { useBrands, useTr } from '../../hooks';\nimport {\n useBrandOrder,\n useBrandOrderSummary,\n useBrandOrders,\n useBrandReturnRequests,\n useUpdateOrderFulfilment,\n} from '../../hooks/useBrandOrdersApi';\nimport type { CooBrandOrder, CooBrandOrderSummary, CooFulfilmentStatus } from '../../types';\nimport { cn } from '../../utils/cn';\nimport { formatDate, formatPrice } from '../../utils/formatters';\n\nconst FILTERS: Array<{\n value: CooFulfilmentStatus | undefined;\n key: string;\n label: string;\n count: (summary: CooBrandOrderSummary) => number;\n}> = [\n {\n value: undefined,\n key: 'coolandlovely.brandOrders.filterAll',\n label: 'All',\n count: (s) => s.total,\n },\n {\n value: 'UNFULFILLED',\n key: 'coolandlovely.brandOrders.filterUnfulfilled',\n label: 'To confirm',\n count: (s) => s.unfulfilled,\n },\n {\n value: 'CONFIRMED',\n key: 'coolandlovely.brandOrders.filterConfirmed',\n label: 'Confirmed',\n count: (s) => s.confirmed,\n },\n {\n value: 'SHIPPED',\n key: 'coolandlovely.brandOrders.filterShipped',\n label: 'Shipped',\n count: (s) => s.shipped,\n },\n {\n value: 'DELIVERED',\n key: 'coolandlovely.brandOrders.filterDelivered',\n label: 'Delivered',\n count: (s) => s.delivered,\n },\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';\nconst primaryButton =\n '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\nexport function BrandOrdersPage() {\n const tr = useTr();\n const { navigateTo } = useCoolAndLovely();\n const [searchParams, setSearchParams] = useSearchParams();\n const brands = useBrands({ pagination: { limit: 100, offset: 0 } });\n const brandOptions = useMemo(\n () => (brands.data?.items ?? []).map((brand) => ({ value: brand.id, label: brand.name })),\n [brands.data]\n );\n const brandId = searchParams.get('brand') ?? brandOptions[0]?.value;\n const [status, setStatus] = useState<CooFulfilmentStatus | undefined>(undefined);\n const summary = useBrandOrderSummary(brandId);\n const orders = useBrandOrders(brandId, status);\n const pendingReturns = useBrandReturnRequests(brandId, 'REQUESTED');\n const title = tr('coolandlovely.brandOrders.title', 'Brand orders');\n\n useEffect(() => setStatus(undefined), [brandId]);\n\n const selectBrand = (value: string) => {\n const next = new URLSearchParams(searchParams);\n next.set('brand', value);\n setSearchParams(next, { replace: true });\n };\n\n return (\n <PageLayout\n title={title}\n description={tr(\n 'coolandlovely.brandOrders.description',\n 'Paid orders for your pieces. Confirm them, ship them with tracking and mark them delivered.'\n )}\n >\n {brands.isLoading ? (\n <LoadingView />\n ) : brandOptions.length === 0 ? (\n <EmptyState\n icon={<Package className=\"h-8 w-8\" />}\n title={tr('coolandlovely.brandOrders.noBrandsTitle', 'No brands yet')}\n description={tr(\n 'coolandlovely.brandOrders.noBrandsDescription',\n 'Create a brand storefront to start selling pieces.'\n )}\n />\n ) : (\n <>\n <div className=\"mb-4 max-w-sm\">\n <SelectField\n id=\"coo-brand-orders-brand\"\n label={tr('coolandlovely.brandOrders.brand', 'Brand')}\n value={brandId ?? ''}\n onChange={selectBrand}\n options={brandOptions}\n />\n </div>\n {(pendingReturns.data?.items.length ?? 0) > 0 && (\n <GlassCard\n treatment=\"plain\"\n className=\"mb-4 space-y-2 p-4\"\n data-testid=\"brand-pending-returns\"\n >\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n {tr('coolandlovely.returns.pendingTitle', 'Return requests waiting for you')}\n </p>\n {pendingReturns.data?.items.map((request) => (\n <button\n key={request.id}\n type=\"button\"\n onClick={() => navigateTo(`/brand-orders/${request.brandId}/${request.orderId}`)}\n className=\"flex w-full items-center gap-3 rounded-lg px-2 py-1.5 text-left transition-colors hover:bg-bg-sunken/50\"\n data-testid=\"brand-pending-return\"\n >\n <span className=\"font-mono text-sm text-text-primary\">\n {request.orderNumber ?? request.orderId}\n </span>\n <span className=\"min-w-0 flex-1 truncate text-xs text-text-secondary\">\n {request.reason}\n </span>\n <span className=\"text-xs text-text-secondary\">\n {formatDate(request.createdAt)}\n </span>\n <ChevronRight className=\"h-4 w-4 text-text-secondary\" />\n </button>\n ))}\n </GlassCard>\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 'inline-flex items-center gap-1.5 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 {summary.data && (\n <span className=\"tabular-nums opacity-80\">{filter.count(summary.data)}</span>\n )}\n </button>\n ))}\n </div>\n {orders.isLoading ? (\n <LoadingView label={tr('coolandlovely.brandOrders.loading', 'Loading orders…')} />\n ) : orders.isError || !orders.data ? (\n <ErrorView message={orders.error?.message} onRetry={() => void orders.refetch()} />\n ) : orders.data.items.length === 0 ? (\n <EmptyState\n icon={<Package className=\"h-8 w-8\" />}\n title={tr('coolandlovely.brandOrders.emptyTitle', 'No orders here')}\n description={tr(\n 'coolandlovely.brandOrders.emptyDescription',\n 'Paid orders for this brand’s pieces appear here.'\n )}\n />\n ) : (\n <div className=\"space-y-3\" data-testid=\"brand-orders-list\">\n {orders.data.items.map((order) => (\n <button\n key={order.id}\n type=\"button\"\n onClick={() => navigateTo(`/brand-orders/${order.brandId}/${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.paidAt ?? order.createdAt)} · {order.shippingName ?? '—'} ·{' '}\n {tr('coolandlovely.orders.pieces', '{{count}} pieces', {\n count: order.itemCount,\n })}\n </p>\n </div>\n {order.returnRequest?.status === 'REQUESTED' && (\n <StatusBadge status=\"REQUESTED\" />\n )}\n <StatusBadge\n status={order.fulfilment.refunded ? 'REFUNDED' : order.fulfilment.status}\n />\n <span className=\"w-28 text-right text-sm font-semibold tabular-nums text-text-primary\">\n {formatPrice(order.brandSubtotal, order.currency)}\n </span>\n <ChevronRight className=\"h-4 w-4 text-text-secondary\" />\n </button>\n ))}\n </div>\n )}\n </>\n )}\n </PageLayout>\n );\n}\n\nfunction FulfilmentForm({ order }: { order: CooBrandOrder }) {\n const tr = useTr();\n const update = useUpdateOrderFulfilment();\n const current = order.fulfilment;\n const [carrier, setCarrier] = useState(current.carrier ?? '');\n const [trackingNumber, setTrackingNumber] = useState(current.trackingNumber ?? '');\n const [trackingUrl, setTrackingUrl] = useState(current.trackingUrl ?? '');\n const [note, setNote] = useState(current.note ?? '');\n\n if (current.status === 'DELIVERED') {\n return (\n <p className=\"text-sm text-status-success-text\">\n {tr('coolandlovely.fulfilment.complete', 'Delivered. Nothing left to do for this order.')}\n </p>\n );\n }\n\n const details = {\n brandId: order.brandId,\n orderId: order.id,\n carrier: carrier.trim() || null,\n trackingNumber: trackingNumber.trim() || null,\n trackingUrl: trackingUrl.trim() || null,\n note: note.trim() || null,\n };\n const canShip = !!details.carrier && !!details.trackingNumber;\n\n return (\n <div className=\"space-y-3 border-t border-border-seam pt-4\">\n <TextField\n id=\"coo-fulfilment-carrier\"\n label={tr('coolandlovely.fulfilment.carrier', 'Carrier')}\n value={carrier}\n onChange={setCarrier}\n placeholder=\"Delhivery\"\n />\n <TextField\n id=\"coo-fulfilment-tracking\"\n label={tr('coolandlovely.fulfilment.trackingNumber', 'Tracking number')}\n value={trackingNumber}\n onChange={setTrackingNumber}\n />\n <TextField\n id=\"coo-fulfilment-tracking-url\"\n type=\"url\"\n label={tr('coolandlovely.fulfilment.trackingUrl', 'Tracking link (optional)')}\n value={trackingUrl}\n onChange={setTrackingUrl}\n placeholder=\"https://\"\n />\n <TextAreaField\n id=\"coo-fulfilment-note\"\n label={tr('coolandlovely.fulfilment.note', 'Note for the buyer (optional)')}\n value={note}\n onChange={setNote}\n rows={2}\n />\n {update.error && <p className=\"text-sm text-status-error-text\">{update.error.message}</p>}\n <div className=\"space-y-2\">\n {current.status === 'UNFULFILLED' && (\n <button\n type=\"button\"\n disabled={update.isPending}\n onClick={() => update.mutate({ ...details, status: 'CONFIRMED' })}\n className={cn(secondaryButton, 'w-full justify-center')}\n >\n <CheckCircle2 className=\"h-4 w-4\" />\n {tr('coolandlovely.fulfilment.confirm', 'Confirm order')}\n </button>\n )}\n {(current.status === 'UNFULFILLED' || current.status === 'CONFIRMED') && (\n <button\n type=\"button\"\n disabled={update.isPending || !canShip}\n onClick={() => update.mutate({ ...details, status: 'SHIPPED' })}\n className={primaryButton}\n >\n {update.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Truck className=\"h-4 w-4\" />\n )}\n {tr('coolandlovely.fulfilment.markShipped', 'Mark shipped')}\n </button>\n )}\n {current.status === 'SHIPPED' && (\n <>\n <button\n type=\"button\"\n disabled={update.isPending || !canShip}\n onClick={() => update.mutate({ ...details, status: 'SHIPPED' })}\n className={cn(secondaryButton, 'w-full justify-center')}\n >\n {tr('coolandlovely.fulfilment.saveTracking', 'Save tracking details')}\n </button>\n <button\n type=\"button\"\n disabled={update.isPending}\n onClick={() => update.mutate({ ...details, status: 'DELIVERED' })}\n className={primaryButton}\n >\n {update.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <PackageCheck className=\"h-4 w-4\" />\n )}\n {tr('coolandlovely.fulfilment.markDelivered', 'Mark delivered')}\n </button>\n </>\n )}\n {!canShip && current.status !== 'SHIPPED' && (\n <p className=\"text-xs text-text-secondary\">\n {tr(\n 'coolandlovely.fulfilment.trackingHint',\n 'Add a carrier and tracking number to mark the order shipped.'\n )}\n </p>\n )}\n </div>\n </div>\n );\n}\n\nexport function BrandOrderDetailPage() {\n const tr = useTr();\n const { brandId, orderId } = useParams<{ brandId: string; orderId: string }>();\n const { navigateTo } = useCoolAndLovely();\n const order = useBrandOrder(brandId, orderId);\n const title = tr('coolandlovely.brandOrders.detailTitle', 'Order');\n const back = () => navigateTo(`/brand-orders?brand=${brandId ?? ''}`);\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 message={order.error?.message}\n onRetry={() => void order.refetch()}\n />\n </PageLayout>\n );\n }\n\n const data = order.data;\n // Pieces the brand refunded, or is refunding, are not shipped.\n const refundBlocksFulfilment =\n data.fulfilment.refunded ||\n data.refund?.status === 'PENDING' ||\n data.refund?.status === 'COMPLETED';\n return (\n <PageLayout\n title={data.orderNumber}\n description={tr('coolandlovely.brandOrders.paidOn', 'Paid {{date}}', {\n date: formatDate(data.paidAt ?? data.createdAt),\n })}\n actions={\n <button type=\"button\" onClick={back} className={secondaryButton}>\n <ArrowLeft className=\"h-4 w-4\" /> {tr('coolandlovely.common.back', 'Back')}\n </button>\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.sku, item.size, item.colour, `× ${item.quantity}`]\n .filter(Boolean)\n .join(' · ')}\n </p>\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 <GlassCard treatment=\"plain\" className=\"space-y-1 p-4 text-sm\">\n <p className=\"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 {data.buyerNote && (\n <p className=\"pt-2 text-text-secondary\">\n {tr('coolandlovely.brandOrders.buyerNote', 'Buyer note: {{note}}', {\n note: data.buyerNote,\n })}\n </p>\n )}\n </GlassCard>\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.fulfilment.status', 'Fulfilment')}\n </span>\n <span data-testid=\"fulfilment-status\">\n <StatusBadge\n status={data.fulfilment.refunded ? 'REFUNDED' : data.fulfilment.status}\n />\n </span>\n </div>\n <div className=\"flex justify-between text-sm\">\n <span className=\"text-text-secondary\">\n {tr('coolandlovely.brandOrders.brandSubtotal', 'Your pieces')}\n </span>\n <span className=\"font-semibold tabular-nums text-text-primary\">\n {formatPrice(data.brandSubtotal, data.currency)}\n </span>\n </div>\n <FulfilmentTimeline fulfilment={data.fulfilment} />\n {!refundBlocksFulfilment && (\n <FulfilmentForm key={data.fulfilment.updatedAt ?? 'new'} order={data} />\n )}\n <ReturnRequestPanel order={data} />\n <RefundPanel order={data} />\n </GlassCard>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAiDA,IAAM,IAKD;CACH;EACE,OAAO,KAAA;EACP,KAAK;EACL,OAAO;EACP,QAAQ,MAAM,EAAE;EACjB;CACD;EACE,OAAO;EACP,KAAK;EACL,OAAO;EACP,QAAQ,MAAM,EAAE;EACjB;CACD;EACE,OAAO;EACP,KAAK;EACL,OAAO;EACP,QAAQ,MAAM,EAAE;EACjB;CACD;EACE,OAAO;EACP,KAAK;EACL,OAAO;EACP,QAAQ,MAAM,EAAE;EACjB;CACD;EACE,OAAO;EACP,KAAK;EACL,OAAO;EACP,QAAQ,MAAM,EAAE;EACjB;CACF,EAEK,IACJ,kLACI,IACJ;AAEF,SAAgB,IAAkB;CAChC,IAAM,IAAK,GAAO,EACZ,EAAE,kBAAe,GAAkB,EACnC,CAAC,GAAc,KAAmB,GAAiB,EACnD,IAAS,EAAU,EAAE,YAAY;EAAE,OAAO;EAAK,QAAQ;EAAG,EAAE,CAAC,EAC7D,IAAe,SACZ,EAAO,MAAM,SAAS,EAAE,EAAE,KAAK,OAAW;EAAE,OAAO,EAAM;EAAI,OAAO,EAAM;EAAM,EAAE,EACzF,CAAC,EAAO,KAAK,CACd,EACK,IAAU,EAAa,IAAI,QAAQ,IAAI,EAAa,IAAI,OACxD,CAAC,GAAQ,KAAa,EAA0C,KAAA,EAAU,EAC1E,IAAU,EAAqB,EAAQ,EACvC,IAAS,EAAe,GAAS,EAAO,EACxC,IAAiB,EAAuB,GAAS,YAAY,EAC7D,IAAQ,EAAG,mCAAmC,eAAe;AAUnE,QARA,QAAgB,EAAU,KAAA,EAAU,EAAE,CAAC,EAAQ,CAAC,EAS9C,kBAAC,GAAD;EACS;EACP,aAAa,EACX,yCACA,8FACD;YAEA,EAAO,YACN,kBAAC,GAAD,EAAe,CAAA,GACb,EAAa,WAAW,IAC1B,kBAAC,GAAD;GACE,MAAM,kBAAC,GAAD,EAAS,WAAU,WAAY,CAAA;GACrC,OAAO,EAAG,2CAA2C,gBAAgB;GACrE,aAAa,EACX,iDACA,qDACD;GACD,CAAA,GAEF,kBAAA,GAAA,EAAA,UAAA;GACE,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,GAAD;KACE,IAAG;KACH,OAAO,EAAG,mCAAmC,QAAQ;KACrD,OAAO,KAAW;KAClB,WAhCS,MAAkB;MACrC,IAAM,IAAO,IAAI,gBAAgB,EAAa;AAE9C,MADA,EAAK,IAAI,SAAS,EAAM,EACxB,EAAgB,GAAM,EAAE,SAAS,IAAM,CAAC;;KA8B9B,SAAS;KACT,CAAA;IACE,CAAA;IACJ,EAAe,MAAM,MAAM,UAAU,KAAK,KAC1C,kBAAC,GAAD;IACE,WAAU;IACV,WAAU;IACV,eAAY;cAHd,CAKE,kBAAC,KAAD;KAAG,WAAU;eACV,EAAG,sCAAsC,kCAAkC;KAC1E,CAAA,EACH,EAAe,MAAM,MAAM,KAAK,MAC/B,kBAAC,UAAD;KAEE,MAAK;KACL,eAAe,EAAW,iBAAiB,EAAQ,QAAQ,GAAG,EAAQ,UAAU;KAChF,WAAU;KACV,eAAY;eALd;MAOE,kBAAC,QAAD;OAAM,WAAU;iBACb,EAAQ,eAAe,EAAQ;OAC3B,CAAA;MACP,kBAAC,QAAD;OAAM,WAAU;iBACb,EAAQ;OACJ,CAAA;MACP,kBAAC,QAAD;OAAM,WAAU;iBACb,EAAW,EAAQ,UAAU;OACzB,CAAA;MACP,kBAAC,GAAD,EAAc,WAAU,+BAAgC,CAAA;MACjD;OAhBF,EAAQ,GAgBN,CACT,CACQ;;GAEd,kBAAC,OAAD;IAAK,WAAU;IAA4B,MAAK;cAC7C,EAAQ,KAAK,MACZ,kBAAC,UAAD;KAEE,MAAK;KACL,MAAK;KACL,iBAAe,MAAW,EAAO;KACjC,eAAe,EAAU,EAAO,MAAM;KACtC,WAAW,EACT,wGACA,MAAW,EAAO,QACd,2EACA,0DACL;eAXH,CAaG,EAAG,EAAO,KAAK,EAAO,MAAM,EAC5B,EAAQ,QACP,kBAAC,QAAD;MAAM,WAAU;gBAA2B,EAAO,MAAM,EAAQ,KAAK;MAAQ,CAAA,CAExE;OAhBF,EAAO,IAgBL,CACT;IACE,CAAA;GACL,EAAO,YACN,kBAAC,GAAD,EAAa,OAAO,EAAG,qCAAqC,kBAAkB,EAAI,CAAA,GAChF,EAAO,WAAW,CAAC,EAAO,OAC5B,kBAAC,GAAD;IAAW,SAAS,EAAO,OAAO;IAAS,eAAe,KAAK,EAAO,SAAS;IAAI,CAAA,GACjF,EAAO,KAAK,MAAM,WAAW,IAC/B,kBAAC,GAAD;IACE,MAAM,kBAAC,GAAD,EAAS,WAAU,WAAY,CAAA;IACrC,OAAO,EAAG,wCAAwC,iBAAiB;IACnE,aAAa,EACX,8CACA,mDACD;IACD,CAAA,GAEF,kBAAC,OAAD;IAAK,WAAU;IAAY,eAAY;cACpC,EAAO,KAAK,MAAM,KAAK,MACtB,kBAAC,UAAD;KAEE,MAAK;KACL,eAAe,EAAW,iBAAiB,EAAM,QAAQ,GAAG,EAAM,KAAK;KACvE,WAAU;eAJZ;MAME,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAM;QACL,CAAA,EACJ,kBAAC,KAAD;QAAG,WAAU;kBAAb;SACG,EAAW,EAAM,UAAU,EAAM,UAAU;SAAC;SAAI,EAAM,gBAAgB;SAAI;SAAG;SAC7E,EAAG,+BAA+B,oBAAoB,EACrD,OAAO,EAAM,WACd,CAAC;SACA;UACA;;MACL,EAAM,eAAe,WAAW,eAC/B,kBAAC,GAAD,EAAa,QAAO,aAAc,CAAA;MAEpC,kBAAC,GAAD,EACE,QAAQ,EAAM,WAAW,WAAW,aAAa,EAAM,WAAW,QAClE,CAAA;MACF,kBAAC,QAAD;OAAM,WAAU;iBACb,EAAY,EAAM,eAAe,EAAM,SAAS;OAC5C,CAAA;MACP,kBAAC,GAAD,EAAc,WAAU,+BAAgC,CAAA;MACjD;OA1BF,EAAM,GA0BJ,CACT;IACE,CAAA;GAEP,EAAA,CAAA;EAEM,CAAA;;AAIjB,SAAS,EAAe,EAAE,YAAmC;CAC3D,IAAM,IAAK,GAAO,EACZ,IAAS,GAA0B,EACnC,IAAU,EAAM,YAChB,CAAC,GAAS,KAAc,EAAS,EAAQ,WAAW,GAAG,EACvD,CAAC,GAAgB,KAAqB,EAAS,EAAQ,kBAAkB,GAAG,EAC5E,CAAC,GAAa,KAAkB,EAAS,EAAQ,eAAe,GAAG,EACnE,CAAC,GAAM,KAAW,EAAS,EAAQ,QAAQ,GAAG;AAEpD,KAAI,EAAQ,WAAW,YACrB,QACE,kBAAC,KAAD;EAAG,WAAU;YACV,EAAG,qCAAqC,gDAAgD;EACvF,CAAA;CAIR,IAAM,IAAU;EACd,SAAS,EAAM;EACf,SAAS,EAAM;EACf,SAAS,EAAQ,MAAM,IAAI;EAC3B,gBAAgB,EAAe,MAAM,IAAI;EACzC,aAAa,EAAY,MAAM,IAAI;EACnC,MAAM,EAAK,MAAM,IAAI;EACtB,EACK,IAAU,CAAC,CAAC,EAAQ,WAAW,CAAC,CAAC,EAAQ;AAE/C,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,GAAD;IACE,IAAG;IACH,OAAO,EAAG,oCAAoC,UAAU;IACxD,OAAO;IACP,UAAU;IACV,aAAY;IACZ,CAAA;GACF,kBAAC,GAAD;IACE,IAAG;IACH,OAAO,EAAG,2CAA2C,kBAAkB;IACvE,OAAO;IACP,UAAU;IACV,CAAA;GACF,kBAAC,GAAD;IACE,IAAG;IACH,MAAK;IACL,OAAO,EAAG,wCAAwC,2BAA2B;IAC7E,OAAO;IACP,UAAU;IACV,aAAY;IACZ,CAAA;GACF,kBAAC,GAAD;IACE,IAAG;IACH,OAAO,EAAG,iCAAiC,gCAAgC;IAC3E,OAAO;IACP,UAAU;IACV,MAAM;IACN,CAAA;GACD,EAAO,SAAS,kBAAC,KAAD;IAAG,WAAU;cAAkC,EAAO,MAAM;IAAY,CAAA;GACzF,kBAAC,OAAD;IAAK,WAAU;cAAf;KACG,EAAQ,WAAW,iBAClB,kBAAC,UAAD;MACE,MAAK;MACL,UAAU,EAAO;MACjB,eAAe,EAAO,OAAO;OAAE,GAAG;OAAS,QAAQ;OAAa,CAAC;MACjE,WAAW,EAAG,GAAiB,wBAAwB;gBAJzD,CAME,kBAAC,GAAD,EAAc,WAAU,WAAY,CAAA,EACnC,EAAG,oCAAoC,gBAAgB,CACjD;;MAET,EAAQ,WAAW,iBAAiB,EAAQ,WAAW,gBACvD,kBAAC,UAAD;MACE,MAAK;MACL,UAAU,EAAO,aAAa,CAAC;MAC/B,eAAe,EAAO,OAAO;OAAE,GAAG;OAAS,QAAQ;OAAW,CAAC;MAC/D,WAAW;gBAJb,CAMG,EAAO,YACN,kBAAC,GAAD,EAAS,WAAU,wBAAyB,CAAA,GAE5C,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA,EAE9B,EAAG,wCAAwC,eAAe,CACpD;;KAEV,EAAQ,WAAW,aAClB,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,UAAD;MACE,MAAK;MACL,UAAU,EAAO,aAAa,CAAC;MAC/B,eAAe,EAAO,OAAO;OAAE,GAAG;OAAS,QAAQ;OAAW,CAAC;MAC/D,WAAW,EAAG,GAAiB,wBAAwB;gBAEtD,EAAG,yCAAyC,wBAAwB;MAC9D,CAAA,EACT,kBAAC,UAAD;MACE,MAAK;MACL,UAAU,EAAO;MACjB,eAAe,EAAO,OAAO;OAAE,GAAG;OAAS,QAAQ;OAAa,CAAC;MACjE,WAAW;gBAJb,CAMG,EAAO,YACN,kBAAC,GAAD,EAAS,WAAU,wBAAyB,CAAA,GAE5C,kBAAC,GAAD,EAAc,WAAU,WAAY,CAAA,EAErC,EAAG,0CAA0C,iBAAiB,CACxD;QACR,EAAA,CAAA;KAEJ,CAAC,KAAW,EAAQ,WAAW,aAC9B,kBAAC,KAAD;MAAG,WAAU;gBACV,EACC,yCACA,+DACD;MACC,CAAA;KAEF;;GACF;;;AAIV,SAAgB,IAAuB;CACrC,IAAM,IAAK,GAAO,EACZ,EAAE,YAAS,eAAY,GAAiD,EACxE,EAAE,kBAAe,GAAkB,EACnC,IAAQ,EAAc,GAAS,EAAQ,EACvC,IAAQ,EAAG,yCAAyC,QAAQ,EAC5D,UAAa,EAAW,uBAAuB,KAAW,KAAK;AAErE,KAAI,EAAM,UACR,QACE,kBAAC,GAAD;EAAmB;YACjB,kBAAC,GAAD,EAAe,CAAA;EACJ,CAAA;AAGjB,KAAI,EAAM,WAAW,CAAC,EAAM,KAC1B,QACE,kBAAC,GAAD;EAAmB;YACjB,kBAAC,GAAD;GACE,OAAO,EAAG,iCAAiC,kBAAkB;GAC7D,SAAS,EAAM,OAAO;GACtB,eAAe,KAAK,EAAM,SAAS;GACnC,CAAA;EACS,CAAA;CAIjB,IAAM,IAAO,EAAM,MAEb,IACJ,EAAK,WAAW,YAChB,EAAK,QAAQ,WAAW,aACxB,EAAK,QAAQ,WAAW;AAC1B,QACE,kBAAC,GAAD;EACE,OAAO,EAAK;EACZ,aAAa,EAAG,oCAAoC,iBAAiB,EACnE,MAAM,EAAW,EAAK,UAAU,EAAK,UAAU,EAChD,CAAC;EACF,SACE,kBAAC,UAAD;GAAQ,MAAK;GAAS,SAAS;GAAM,WAAW;aAAhD;IACE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA;;IAAE,EAAG,6BAA6B,OAAO;IACnE;;YAGX,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACG,EAAK,MAAM,KAAK,MACf,kBAAC,GAAD;KAAyB,WAAU;KAAQ,WAAU;eAArD;MACE,kBAAC,GAAD;OACE,MAAM,kBAAC,GAAD,EAAS,WAAU,WAAY,CAAA;OACrC,MAAM,EAAK;OACX,QAAQ,EAAK,OAAO;OACpB,KAAK,EAAK;OACV,WAAU;OACV,CAAA;MACF,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAkD,EAAK;QAAS,CAAA,EAC7E,kBAAC,KAAD;QAAG,WAAU;kBACV;SAAC,EAAK;SAAK,EAAK;SAAM,EAAK;SAAQ,KAAK,EAAK;SAAW,CACtD,OAAO,QAAQ,CACf,KAAK,MAAM;QACZ,CAAA,CACA;;MACN,kBAAC,QAAD;OAAM,WAAU;iBACb,EAAY,EAAK,WAAW,EAAK,SAAS;OACtC,CAAA;MACG;OAnBI,EAAK,GAmBT,CACZ,EACF,kBAAC,GAAD;KAAW,WAAU;KAAQ,WAAU;eAAvC;MACE,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAG,+BAA+B,UAAU;OAC3C,CAAA;MACJ,kBAAC,KAAD;OAAG,WAAU;iBAAqB,EAAK;OAAiB,CAAA;MACxD,kBAAC,KAAD;OAAG,WAAU;iBAA2C,EAAK;OAAoB,CAAA;MAChF,EAAK,aACJ,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAG,uCAAuC,wBAAwB,EACjE,MAAM,EAAK,WACZ,CAAC;OACA,CAAA;MAEI;OACR;OACN,kBAAC,GAAD;IAAW,WAAU;IAAQ,WAAU;cAAvC;KACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,QAAD;OAAM,WAAU;iBACb,EAAG,mCAAmC,aAAa;OAC/C,CAAA,EACP,kBAAC,QAAD;OAAM,eAAY;iBAChB,kBAAC,GAAD,EACE,QAAQ,EAAK,WAAW,WAAW,aAAa,EAAK,WAAW,QAChE,CAAA;OACG,CAAA,CACH;;KACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,QAAD;OAAM,WAAU;iBACb,EAAG,2CAA2C,cAAc;OACxD,CAAA,EACP,kBAAC,QAAD;OAAM,WAAU;iBACb,EAAY,EAAK,eAAe,EAAK,SAAS;OAC1C,CAAA,CACH;;KACN,kBAAC,GAAD,EAAoB,YAAY,EAAK,YAAc,CAAA;KAClD,CAAC,KACA,kBAAC,GAAD,EAAyD,OAAO,GAAQ,EAAnD,EAAK,WAAW,aAAa,MAAsB;KAE1E,kBAAC,GAAD,EAAoB,OAAO,GAAQ,CAAA;KACnC,kBAAC,GAAD,EAAa,OAAO,GAAQ,CAAA;KAClB;MACR;;EACK,CAAA"}
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* The shopper's own orders (`cooMyOrders` / `cooMyOrder`). An unpaid order can be paid
|
|
6
6
|
* (`cooResumeOrderPayment` re-uses its billing order), re-checked against billing
|
|
7
7
|
* (`cooSyncOrderPayment`) or cancelled (`cooCancelOrder`). Brand refunds (BOFF-9702) show on
|
|
8
|
-
* the order with their amount and reason.
|
|
8
|
+
* the order with their amount and reason. Inside the return window the shopper can ask a brand to
|
|
9
|
+
* take back its pieces (`cooRequestReturn`, BOFF-9900) and sees the brand's decision.
|
|
9
10
|
*/
|
|
10
11
|
export declare function OrdersPage(): import("react").JSX.Element;
|
|
11
12
|
export declare function OrderDetailPage(): import("react").JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OrdersPage.d.ts","sourceRoot":"","sources":["../../../../src/coolandlovely/pages/commerce/OrdersPage.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"OrdersPage.d.ts","sourceRoot":"","sources":["../../../../src/coolandlovely/pages/commerce/OrdersPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAwDH,wBAAgB,UAAU,gCAwEzB;AAED,wBAAgB,eAAe,gCAkQ9B"}
|