@burdenoff/microfe-store 2026.805.1 → 2026.819.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/StoreAdminRoutes.js +27 -27
  2. package/dist/StoreRoot.js +78 -45
  3. package/dist/StoreRoot.js.map +1 -1
  4. package/dist/StoreRoutes.js +163 -85
  5. package/dist/StoreRoutes.js.map +1 -1
  6. package/dist/components/sourcing/SourcingConfirmationDialog.d.ts +15 -0
  7. package/dist/components/sourcing/SourcingConfirmationDialog.js +61 -0
  8. package/dist/components/sourcing/SourcingConfirmationDialog.js.map +1 -0
  9. package/dist/components/sourcing/SourcingUi.d.ts +51 -0
  10. package/dist/components/sourcing/SourcingUi.js +176 -0
  11. package/dist/components/sourcing/SourcingUi.js.map +1 -0
  12. package/dist/generated/global-operations.d.ts +713 -0
  13. package/dist/generated/global-operations.js +557 -175
  14. package/dist/generated/global-operations.js.map +1 -1
  15. package/dist/generated/global-types.d.ts +2152 -2159
  16. package/dist/generated/global-types.js +8 -2
  17. package/dist/generated/global-types.js.map +1 -1
  18. package/dist/hooks/useBackendCart.js +17 -17
  19. package/dist/hooks/useInstallations.js +32 -32
  20. package/dist/hooks/useOrders.js +7 -7
  21. package/dist/hooks/useSourcing.d.ts +319 -0
  22. package/dist/hooks/useSourcing.js +87 -0
  23. package/dist/hooks/useSourcing.js.map +1 -0
  24. package/dist/hooks/useStoreGraphQL.js +163 -163
  25. package/dist/index.js +12 -12
  26. package/dist/pages/AdminDashboardPage.js +132 -132
  27. package/dist/pages/AdminReviewModerationPage.js +55 -55
  28. package/dist/pages/AdminStoresPage.js +95 -95
  29. package/dist/pages/AdminSubmissionsQueuePage.js +297 -297
  30. package/dist/pages/AdminSubmissionsQueuePage.js.map +1 -1
  31. package/dist/pages/AppDetailPage.js +65 -65
  32. package/dist/pages/AppSettingsPage.js +32 -32
  33. package/dist/pages/CartPage.js +66 -66
  34. package/dist/pages/CreateSourcingRequestPage.d.ts +3 -0
  35. package/dist/pages/CreateSourcingRequestPage.js +439 -0
  36. package/dist/pages/CreateSourcingRequestPage.js.map +1 -0
  37. package/dist/pages/InstalledAppsPage.js +15 -15
  38. package/dist/pages/InstalledAppsPage.js.map +1 -1
  39. package/dist/pages/MarketplaceHomePage.js +384 -384
  40. package/dist/pages/MarketplaceHomePage.js.map +1 -1
  41. package/dist/pages/MyLicensesPage.js +39 -39
  42. package/dist/pages/OrderConfirmationPage.js +57 -57
  43. package/dist/pages/OrdersPage.js +3 -3
  44. package/dist/pages/OrdersPage.js.map +1 -1
  45. package/dist/pages/ProductDetailPage.js +6 -6
  46. package/dist/pages/SellerSourcingOffersPage.d.ts +3 -0
  47. package/dist/pages/SellerSourcingOffersPage.js +284 -0
  48. package/dist/pages/SellerSourcingOffersPage.js.map +1 -0
  49. package/dist/pages/SellerSourcingOpportunitiesPage.d.ts +3 -0
  50. package/dist/pages/SellerSourcingOpportunitiesPage.js +272 -0
  51. package/dist/pages/SellerSourcingOpportunitiesPage.js.map +1 -0
  52. package/dist/pages/SellerSourcingOpportunityDetailPage.d.ts +3 -0
  53. package/dist/pages/SellerSourcingOpportunityDetailPage.js +465 -0
  54. package/dist/pages/SellerSourcingOpportunityDetailPage.js.map +1 -0
  55. package/dist/pages/SourcingRequestDetailPage.d.ts +3 -0
  56. package/dist/pages/SourcingRequestDetailPage.js +447 -0
  57. package/dist/pages/SourcingRequestDetailPage.js.map +1 -0
  58. package/dist/pages/SourcingRequestsPage.d.ts +3 -0
  59. package/dist/pages/SourcingRequestsPage.js +272 -0
  60. package/dist/pages/SourcingRequestsPage.js.map +1 -0
  61. package/dist/providers/SourcingAccessProvider.d.ts +21 -0
  62. package/dist/providers/SourcingAccessProvider.js +95 -0
  63. package/dist/providers/SourcingAccessProvider.js.map +1 -0
  64. package/dist/translations/en.d.ts +3 -0
  65. package/dist/translations/en.js +3 -0
  66. package/dist/translations/en.js.map +1 -1
  67. package/package.json +1 -1
@@ -0,0 +1,465 @@
1
+ import { useStore as e } from "../providers/StoreProvider.js";
2
+ import { useSourcingApi as t } from "../hooks/useSourcing.js";
3
+ import { usePublisherSourcingAccess as n } from "../providers/SourcingAccessProvider.js";
4
+ import { SourcingOfferStatus as r } from "../generated/global-types.js";
5
+ import { ContextRequiredPanel as i, SourcingErrorState as a, SourcingLoadingState as o, SourcingPageHeader as ee, SourcingStatusBadge as te, formatDateTime as s, formatLocation as ne, formatMoney as c, formatSourcingUnit as l, helpClassName as u, inputClassName as d, joinStorePath as f, labelClassName as p, primaryButtonClassName as re, secondaryButtonClassName as ie, toDateTimeLocal as m, toErrorMessage as h } from "../components/sourcing/SourcingUi.js";
6
+ import { useCallback as ae, useEffect as oe, useMemo as se, useState as g } from "react";
7
+ import { useNavigate as ce, useParams as le } from "react-router";
8
+ import { BadgeCheck as ue, CalendarDays as de, Check as fe, CircleDollarSign as pe, Loader2 as me, MapPin as he, PackageSearch as ge, Save as _e, TicketCheck as _ } from "lucide-react";
9
+ import { Fragment as v, jsx as y, jsxs as b } from "react/jsx-runtime";
10
+ import { EmphasisPanel as ve, GlassCard as x, PagePurpose as ye } from "@burdenoff/fe-libs/ui";
11
+ //#region src/pages/SellerSourcingOpportunityDetailPage.tsx
12
+ var be = {
13
+ unitPrice: "",
14
+ deliveryDate: "",
15
+ storeProductId: "",
16
+ message: ""
17
+ }, S = /^(?:0|[1-9]\d{0,15})(?:\.\d{1,2})?$/;
18
+ function xe(e, t) {
19
+ let n = {}, r = e.unitPrice.trim(), i = new Date(e.deliveryDate), a = new Date(t.deliveryWindowStart), o = new Date(t.deliveryWindowEnd);
20
+ return (!S.test(r) || Number(r) <= 0) && (n.unitPrice = "Enter a positive unit price with no more than two decimal places."), (!e.deliveryDate || Number.isNaN(i.getTime()) || i < a || i > o) && (n.deliveryDate = "Choose a delivery date within the buyer’s requested window."), e.message.trim().length > 1e3 && (n.message = "Offer message cannot exceed 1,000 characters."), n;
21
+ }
22
+ var C = () => {
23
+ let S = ce(), { requestId: C } = le(), { basePath: w } = e(), { profile: T, products: E, productsLoading: D, productsError: O, loading: k, error: A, isEligible: j, refresh: M, refreshProducts: Se } = n(), { getOpportunity: N, upsertOffer: Ce } = t(), [P, we] = g(null), [F, I] = g(null), [L, Te] = g(!1), [R, z] = g(be), [B, V] = g({}), [Ee, H] = g(!1), [U, W] = g(null), [G, K] = g(null), [q, J] = g(null), [Y, X] = g(!1), De = f(w, "publisher/sourcing/opportunities"), Z = ae(async (e = !1) => {
24
+ if (!(!j || !C)) {
25
+ H(!0), W(null);
26
+ try {
27
+ let t = await N(C);
28
+ we(t.opportunity), I(t.offer), Te(t.isOpen), t.opportunity ? e && z({
29
+ unitPrice: t.offer?.unitPrice ?? "",
30
+ deliveryDate: t.offer ? m(t.offer.deliveryDate) : m(t.opportunity.deliveryWindowStart),
31
+ storeProductId: t.offer?.storeProductId ?? "",
32
+ message: t.offer?.message ?? ""
33
+ }) : W("This sourcing opportunity is no longer available.");
34
+ } catch (e) {
35
+ W(h(e, "The sourcing opportunity could not be loaded."));
36
+ } finally {
37
+ H(!1);
38
+ }
39
+ }
40
+ }, [
41
+ N,
42
+ j,
43
+ C
44
+ ]);
45
+ oe(() => {
46
+ Z(!0);
47
+ }, [Z]);
48
+ let Oe = se(() => [...E].filter((e) => e.status === "PUBLISHED").sort((e, t) => e.name.localeCompare(t.name)), [E]), Q = (e) => (t) => {
49
+ z((n) => ({
50
+ ...n,
51
+ [e]: t.target.value
52
+ })), V((t) => ({
53
+ ...t,
54
+ [e]: void 0
55
+ })), J(null);
56
+ }, ke = async (e) => {
57
+ if (e.preventDefault(), !P || !C || !L || Y) return;
58
+ let t = xe(R, P);
59
+ if (V(t), K(null), J(null), Object.keys(t).length > 0) return;
60
+ let n = {
61
+ requestId: C,
62
+ quantity: P.quantity,
63
+ unit: P.unit,
64
+ unitPrice: R.unitPrice.trim(),
65
+ currency: "USD",
66
+ deliveryDate: new Date(R.deliveryDate).toISOString(),
67
+ storeProductId: R.storeProductId || void 0,
68
+ message: R.message.trim() || void 0
69
+ };
70
+ X(!0);
71
+ try {
72
+ let e = await Ce(n);
73
+ J(F ? "Your offer was updated." : "Your offer was submitted."), I(e), await Z(!1);
74
+ } catch (e) {
75
+ K(h(e, "Your offer could not be saved. The request may have closed while you were editing."));
76
+ } finally {
77
+ X(!1);
78
+ }
79
+ }, $ = (e) => {
80
+ let t = B[e];
81
+ return t ? /* @__PURE__ */ y("p", {
82
+ id: `${e}-error`,
83
+ className: "mt-1 text-xs text-text-danger",
84
+ children: t
85
+ }) : null;
86
+ }, Ae = L && (!F || F.status === r.Active);
87
+ return /* @__PURE__ */ b("div", {
88
+ className: "min-h-full bg-surface-default",
89
+ children: [/* @__PURE__ */ y(ee, {
90
+ title: P?.productName ?? "Sourcing opportunity",
91
+ description: "Review the sanitized buyer request and create or update your publisher’s offer.",
92
+ icon: /* @__PURE__ */ y(_, {
93
+ className: "size-5",
94
+ "aria-hidden": "true"
95
+ }),
96
+ onBack: () => S(De),
97
+ actions: /* @__PURE__ */ y("button", {
98
+ type: "button",
99
+ onClick: () => S(f(w, "publisher/sourcing/offers")),
100
+ className: ie,
101
+ children: "My offers"
102
+ })
103
+ }), /* @__PURE__ */ b("main", {
104
+ className: "mx-auto max-w-6xl px-4 py-6 sm:px-6",
105
+ children: [/* @__PURE__ */ y(ye, {
106
+ className: "mb-6",
107
+ children: "Quantity and unit are fixed by the buyer request. Store validates publisher identity, USD settlement price, delivery window, and optional linked product on every save. You can update one active offer until the request closes."
108
+ }), k ? /* @__PURE__ */ y(o, { label: "Checking Store Publisher access…" }) : A ? /* @__PURE__ */ y(a, {
109
+ title: "Publisher access could not be checked",
110
+ message: A,
111
+ onRetry: () => void M()
112
+ }) : T ? j ? Ee && !P ? /* @__PURE__ */ y(o, { label: "Loading opportunity and your offer…" }) : U && !P ? /* @__PURE__ */ y(a, {
113
+ title: "Opportunity unavailable",
114
+ message: U,
115
+ onRetry: C ? () => void Z(!0) : void 0
116
+ }) : P ? /* @__PURE__ */ b(v, { children: [
117
+ G ? /* @__PURE__ */ y("div", {
118
+ role: "alert",
119
+ className: "mb-5 rounded-lg border border-border-danger bg-surface-danger-muted px-4 py-3 text-sm text-text-danger",
120
+ children: G
121
+ }) : null,
122
+ q ? /* @__PURE__ */ b("div", {
123
+ role: "status",
124
+ "aria-live": "polite",
125
+ className: "mb-5 flex items-center gap-2 rounded-lg border border-status-success-border bg-status-success-bg-subtle px-4 py-3 text-sm text-status-success-text",
126
+ children: [/* @__PURE__ */ y(fe, {
127
+ className: "size-4",
128
+ "aria-hidden": "true"
129
+ }), q]
130
+ }) : null,
131
+ F?.order ? /* @__PURE__ */ y(ve, {
132
+ className: "mb-6",
133
+ children: /* @__PURE__ */ b("div", {
134
+ className: "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",
135
+ children: [/* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
136
+ className: "text-sm font-semibold text-status-success-text",
137
+ children: "This offer was accepted"
138
+ }), /* @__PURE__ */ b("p", {
139
+ className: "mt-1 text-sm text-text-secondary",
140
+ children: [
141
+ "Store order ",
142
+ F.order.id,
143
+ " ·",
144
+ " ",
145
+ c(F.order.total, F.order.currency),
146
+ " · ",
147
+ F.order.status
148
+ ]
149
+ })] }), F.order.fulfillment ? /* @__PURE__ */ b("span", {
150
+ className: "rounded-full border border-border-default bg-surface-muted px-3 py-1.5 text-xs font-medium text-text-secondary",
151
+ children: ["Fulfillment ", F.order.fulfillment.status.replaceAll("_", " ")]
152
+ }) : null]
153
+ })
154
+ }) : null,
155
+ /* @__PURE__ */ b("div", {
156
+ className: "grid gap-6 lg:grid-cols-[minmax(0,1.2fr)_minmax(340px,0.8fr)]",
157
+ children: [/* @__PURE__ */ b(x, {
158
+ className: "p-5 sm:p-6",
159
+ children: [
160
+ /* @__PURE__ */ b("div", {
161
+ className: "flex flex-wrap items-start justify-between gap-3",
162
+ children: [/* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
163
+ className: "text-sm font-medium text-text-accent",
164
+ children: P.category
165
+ }), /* @__PURE__ */ y("h2", {
166
+ className: "mt-1 text-xl font-semibold text-text-primary",
167
+ children: P.productName
168
+ })] }), /* @__PURE__ */ y("span", {
169
+ className: `rounded-full border px-2.5 py-1 text-xs font-semibold ${L ? "border-status-success-border bg-status-success-bg-subtle text-status-success-text" : "border-border-default bg-surface-muted text-text-secondary"}`,
170
+ children: L ? "OPEN" : "CLOSED"
171
+ })]
172
+ }),
173
+ P.summary ? /* @__PURE__ */ y("p", {
174
+ className: "mt-4 whitespace-pre-wrap text-sm leading-6 text-text-secondary",
175
+ children: P.summary
176
+ }) : null,
177
+ /* @__PURE__ */ b("dl", {
178
+ className: "mt-6 grid gap-5 border-t border-border-seam pt-5 sm:grid-cols-2",
179
+ children: [
180
+ /* @__PURE__ */ b("div", {
181
+ className: "flex gap-3",
182
+ children: [/* @__PURE__ */ y(ge, {
183
+ className: "mt-0.5 size-5 shrink-0 text-text-tertiary",
184
+ "aria-hidden": "true"
185
+ }), /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("dt", {
186
+ className: "text-xs text-text-tertiary",
187
+ children: "Required quantity"
188
+ }), /* @__PURE__ */ b("dd", {
189
+ className: "mt-0.5 font-medium text-text-primary",
190
+ children: [
191
+ P.quantity.toLocaleString(),
192
+ " ",
193
+ l(P.unit)
194
+ ]
195
+ })] })]
196
+ }),
197
+ /* @__PURE__ */ b("div", {
198
+ className: "flex gap-3",
199
+ children: [/* @__PURE__ */ y(pe, {
200
+ className: "mt-0.5 size-5 shrink-0 text-text-tertiary",
201
+ "aria-hidden": "true"
202
+ }), /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("dt", {
203
+ className: "text-xs text-text-tertiary",
204
+ children: "Buyer target"
205
+ }), /* @__PURE__ */ y("dd", {
206
+ className: "mt-0.5 font-medium text-text-primary",
207
+ children: c(P.targetUnitPrice, P.targetCurrency)
208
+ })] })]
209
+ }),
210
+ /* @__PURE__ */ b("div", {
211
+ className: "flex gap-3",
212
+ children: [/* @__PURE__ */ y(de, {
213
+ className: "mt-0.5 size-5 shrink-0 text-text-tertiary",
214
+ "aria-hidden": "true"
215
+ }), /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("dt", {
216
+ className: "text-xs text-text-tertiary",
217
+ children: "Delivery window"
218
+ }), /* @__PURE__ */ b("dd", {
219
+ className: "mt-0.5 font-medium text-text-primary",
220
+ children: [
221
+ s(P.deliveryWindowStart),
222
+ " –",
223
+ " ",
224
+ s(P.deliveryWindowEnd)
225
+ ]
226
+ })] })]
227
+ }),
228
+ /* @__PURE__ */ b("div", {
229
+ className: "flex gap-3",
230
+ children: [/* @__PURE__ */ y(he, {
231
+ className: "mt-0.5 size-5 shrink-0 text-text-tertiary",
232
+ "aria-hidden": "true"
233
+ }), /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("dt", {
234
+ className: "text-xs text-text-tertiary",
235
+ children: "Destination"
236
+ }), /* @__PURE__ */ y("dd", {
237
+ className: "mt-0.5 font-medium text-text-primary",
238
+ children: ne({
239
+ country: P.deliveryCountry,
240
+ region: P.deliveryRegion,
241
+ city: P.deliveryCity
242
+ })
243
+ })] })]
244
+ })
245
+ ]
246
+ })
247
+ ]
248
+ }), Ae ? /* @__PURE__ */ y("form", {
249
+ onSubmit: (e) => void ke(e),
250
+ noValidate: !0,
251
+ children: /* @__PURE__ */ b(x, {
252
+ className: "p-5 sm:p-6",
253
+ children: [
254
+ /* @__PURE__ */ b("div", {
255
+ className: "flex items-center justify-between gap-3",
256
+ children: [/* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("h2", {
257
+ className: "text-lg font-semibold text-text-primary",
258
+ children: F ? "Update your offer" : "Create an offer"
259
+ }), /* @__PURE__ */ b("p", {
260
+ className: "mt-1 text-xs text-text-tertiary",
261
+ children: ["Offering as ", T.name]
262
+ })] }), /* @__PURE__ */ y(ue, {
263
+ className: "size-5 text-text-accent",
264
+ "aria-label": "Verified publisher"
265
+ })]
266
+ }),
267
+ /* @__PURE__ */ b("div", {
268
+ className: "mt-5 space-y-5",
269
+ children: [
270
+ /* @__PURE__ */ b("label", {
271
+ className: p,
272
+ children: [
273
+ "Unit price",
274
+ /* @__PURE__ */ b("div", {
275
+ className: "mt-1.5 grid grid-cols-[1fr_96px] gap-2",
276
+ children: [/* @__PURE__ */ y("input", {
277
+ type: "text",
278
+ value: R.unitPrice,
279
+ onChange: Q("unitPrice"),
280
+ inputMode: "decimal",
281
+ required: !0,
282
+ maxLength: 19,
283
+ "aria-invalid": !!B.unitPrice,
284
+ "aria-describedby": B.unitPrice ? "unitPrice-error" : "unitPrice-help",
285
+ placeholder: "125.50",
286
+ className: `${d} mt-0`
287
+ }), /* @__PURE__ */ y("span", {
288
+ "aria-label": "Offer currency",
289
+ className: "mt-0 flex items-center justify-center rounded-md border border-border-default bg-surface-muted px-3 text-sm font-semibold text-text-secondary",
290
+ children: "USD"
291
+ })]
292
+ }),
293
+ $("unitPrice"),
294
+ B.unitPrice ? null : /* @__PURE__ */ b("p", {
295
+ id: "unitPrice-help",
296
+ className: u,
297
+ children: [
298
+ "Price per ",
299
+ l(P.unit).toLowerCase(),
300
+ ". Store sourcing currently settles in USD."
301
+ ]
302
+ })
303
+ ]
304
+ }),
305
+ /* @__PURE__ */ b("label", {
306
+ className: p,
307
+ children: [
308
+ "Promised delivery date",
309
+ /* @__PURE__ */ y("input", {
310
+ type: "datetime-local",
311
+ value: R.deliveryDate,
312
+ onChange: Q("deliveryDate"),
313
+ required: !0,
314
+ min: m(P.deliveryWindowStart),
315
+ max: m(P.deliveryWindowEnd),
316
+ "aria-invalid": !!B.deliveryDate,
317
+ "aria-describedby": B.deliveryDate ? "deliveryDate-error" : "deliveryDate-help",
318
+ className: d
319
+ }),
320
+ $("deliveryDate"),
321
+ B.deliveryDate ? null : /* @__PURE__ */ y("p", {
322
+ id: "deliveryDate-help",
323
+ className: u,
324
+ children: "Must fall inside the buyer’s delivery window."
325
+ })
326
+ ]
327
+ }),
328
+ /* @__PURE__ */ b("label", {
329
+ className: p,
330
+ children: [
331
+ "Link a published product",
332
+ " ",
333
+ /* @__PURE__ */ y("span", {
334
+ className: "font-normal text-text-tertiary",
335
+ children: "(optional)"
336
+ }),
337
+ /* @__PURE__ */ b("select", {
338
+ value: R.storeProductId,
339
+ onChange: Q("storeProductId"),
340
+ disabled: D,
341
+ "aria-describedby": O ? "store-product-error" : "store-product-help",
342
+ className: d,
343
+ children: [/* @__PURE__ */ y("option", {
344
+ value: "",
345
+ children: D ? "Loading published products…" : "No linked Store product"
346
+ }), Oe.map((e) => /* @__PURE__ */ y("option", {
347
+ value: e.id,
348
+ children: e.name
349
+ }, e.id))]
350
+ }),
351
+ O ? /* @__PURE__ */ b("div", {
352
+ id: "store-product-error",
353
+ role: "alert",
354
+ className: "mt-2 flex flex-wrap items-center gap-2 text-xs text-text-danger",
355
+ children: [/* @__PURE__ */ y("span", { children: O }), /* @__PURE__ */ y("button", {
356
+ type: "button",
357
+ onClick: () => void Se(),
358
+ className: "font-semibold underline underline-offset-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-action-primary-bg",
359
+ children: "Try again"
360
+ })]
361
+ }) : /* @__PURE__ */ y("p", {
362
+ id: "store-product-help",
363
+ className: u,
364
+ children: "Only products owned by this publisher and currently published are accepted. The link is reference metadata and does not reserve catalog inventory or create digital entitlements."
365
+ })
366
+ ]
367
+ }),
368
+ /* @__PURE__ */ b("label", {
369
+ className: p,
370
+ children: [
371
+ "Message ",
372
+ /* @__PURE__ */ y("span", {
373
+ className: "font-normal text-text-tertiary",
374
+ children: "(optional)"
375
+ }),
376
+ /* @__PURE__ */ y("textarea", {
377
+ value: R.message,
378
+ onChange: Q("message"),
379
+ maxLength: 1e3,
380
+ rows: 4,
381
+ "aria-invalid": !!B.message,
382
+ "aria-describedby": B.message ? "message-error" : "message-help",
383
+ placeholder: "Add packaging, quality, or delivery notes relevant to this offer.",
384
+ className: `${d} resize-y`
385
+ }),
386
+ $("message"),
387
+ B.message ? null : /* @__PURE__ */ b("p", {
388
+ id: "message-help",
389
+ className: u,
390
+ children: [R.message.length, "/1,000 characters"]
391
+ })
392
+ ]
393
+ })
394
+ ]
395
+ }),
396
+ /* @__PURE__ */ b("button", {
397
+ type: "submit",
398
+ disabled: Y,
399
+ className: `${re} mt-6 w-full`,
400
+ children: [Y ? /* @__PURE__ */ y(me, {
401
+ className: "size-4 animate-spin",
402
+ "aria-hidden": "true"
403
+ }) : y(F ? _e : _, {
404
+ className: "size-4",
405
+ "aria-hidden": "true"
406
+ }), Y ? "Saving offer…" : F ? "Update offer" : "Submit offer"]
407
+ })
408
+ ]
409
+ })
410
+ }) : F ? /* @__PURE__ */ b(x, {
411
+ className: "p-5 sm:p-6",
412
+ children: [/* @__PURE__ */ b("div", {
413
+ className: "flex items-start justify-between gap-3",
414
+ children: [/* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("h2", {
415
+ className: "text-lg font-semibold text-text-primary",
416
+ children: "Your offer"
417
+ }), /* @__PURE__ */ b("p", {
418
+ className: "mt-1 text-xs text-text-tertiary",
419
+ children: ["Updated ", s(F.updatedAt)]
420
+ })] }), /* @__PURE__ */ y(te, { status: F.status })]
421
+ }), /* @__PURE__ */ b("dl", {
422
+ className: "mt-5 space-y-4 text-sm",
423
+ children: [
424
+ /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("dt", {
425
+ className: "text-xs text-text-tertiary",
426
+ children: "Unit price"
427
+ }), /* @__PURE__ */ y("dd", {
428
+ className: "mt-0.5 text-lg font-semibold text-text-primary",
429
+ children: c(F.unitPrice, F.currency)
430
+ })] }),
431
+ /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("dt", {
432
+ className: "text-xs text-text-tertiary",
433
+ children: "Promised delivery"
434
+ }), /* @__PURE__ */ y("dd", {
435
+ className: "mt-0.5 font-medium text-text-primary",
436
+ children: s(F.deliveryDate)
437
+ })] }),
438
+ F.message ? /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("dt", {
439
+ className: "text-xs text-text-tertiary",
440
+ children: "Message"
441
+ }), /* @__PURE__ */ y("dd", {
442
+ className: "mt-1 whitespace-pre-wrap text-text-secondary",
443
+ children: F.message
444
+ })] }) : null
445
+ ]
446
+ })]
447
+ }) : /* @__PURE__ */ y(i, {
448
+ title: "This request is closed",
449
+ description: "The buyer matched or canceled this request before your publisher submitted an offer."
450
+ })]
451
+ })
452
+ ] }) : null : /* @__PURE__ */ y(i, {
453
+ title: "Verified publisher status required",
454
+ description: `The publisher profile “${T.name}” is currently ${T.verificationStatus.toLowerCase().replaceAll("_", " ")}.`
455
+ }) : /* @__PURE__ */ y(i, {
456
+ title: "Store Publisher profile required",
457
+ description: "Only users who own a verified Store Publisher profile can view this opportunity or submit an offer."
458
+ })]
459
+ })]
460
+ });
461
+ };
462
+ //#endregion
463
+ export { C as SellerSourcingOpportunityDetailPage };
464
+
465
+ //# sourceMappingURL=SellerSourcingOpportunityDetailPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SellerSourcingOpportunityDetailPage.js","names":[],"sources":["../../src/pages/SellerSourcingOpportunityDetailPage.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useState } from 'react';\nimport type { ChangeEvent, FC, FormEvent } from 'react';\nimport { useNavigate, useParams } from 'react-router';\nimport {\n BadgeCheck,\n CalendarDays,\n Check,\n CircleDollarSign,\n Loader2,\n MapPin,\n PackageSearch,\n Save,\n TicketCheck,\n} from 'lucide-react';\nimport { EmphasisPanel, GlassCard, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { SourcingOfferStatus } from '../generated/global-types';\nimport type { UpsertSourcingOfferInput } from '../generated/global-types';\nimport { useStore } from '../providers/StoreProvider';\nimport {\n type SellerSourcingOfferDetail,\n type SellerSourcingOpportunityDetail,\n useSourcingApi,\n} from '../hooks/useSourcing';\nimport { usePublisherSourcingAccess } from '../providers/SourcingAccessProvider';\nimport {\n ContextRequiredPanel,\n formatDateTime,\n formatLocation,\n formatMoney,\n formatSourcingUnit,\n helpClassName,\n inputClassName,\n joinStorePath,\n labelClassName,\n primaryButtonClassName,\n secondaryButtonClassName,\n SourcingErrorState,\n SourcingLoadingState,\n SourcingPageHeader,\n SourcingStatusBadge,\n toDateTimeLocal,\n toErrorMessage,\n} from '../components/sourcing/SourcingUi';\n\ninterface OfferFormState {\n unitPrice: string;\n deliveryDate: string;\n storeProductId: string;\n message: string;\n}\n\ntype OfferField = keyof OfferFormState;\ntype OfferErrors = Partial<Record<OfferField, string>>;\n\nconst EMPTY_FORM: OfferFormState = {\n unitPrice: '',\n deliveryDate: '',\n storeProductId: '',\n message: '',\n};\nconst MONEY_PATTERN = /^(?:0|[1-9]\\d{0,15})(?:\\.\\d{1,2})?$/;\n\nfunction validateOffer(\n form: OfferFormState,\n opportunity: SellerSourcingOpportunityDetail\n): OfferErrors {\n const errors: OfferErrors = {};\n const amount = form.unitPrice.trim();\n const delivery = new Date(form.deliveryDate);\n const start = new Date(opportunity.deliveryWindowStart);\n const end = new Date(opportunity.deliveryWindowEnd);\n\n if (!MONEY_PATTERN.test(amount) || Number(amount) <= 0) {\n errors.unitPrice = 'Enter a positive unit price with no more than two decimal places.';\n }\n if (\n !form.deliveryDate ||\n Number.isNaN(delivery.getTime()) ||\n delivery < start ||\n delivery > end\n ) {\n errors.deliveryDate = 'Choose a delivery date within the buyer’s requested window.';\n }\n if (form.message.trim().length > 1000) {\n errors.message = 'Offer message cannot exceed 1,000 characters.';\n }\n return errors;\n}\n\nexport const SellerSourcingOpportunityDetailPage: FC = () => {\n const navigate = useNavigate();\n const { requestId } = useParams<{ requestId: string }>();\n const { basePath } = useStore();\n const {\n profile,\n products,\n productsLoading,\n productsError,\n loading: accessLoading,\n error: accessError,\n isEligible,\n refresh: refreshAccess,\n refreshProducts,\n } = usePublisherSourcingAccess();\n const { getOpportunity, upsertOffer } = useSourcingApi();\n const [opportunity, setOpportunity] = useState<SellerSourcingOpportunityDetail | null>(null);\n const [offer, setOffer] = useState<SellerSourcingOfferDetail | null>(null);\n const [isOpen, setIsOpen] = useState(false);\n const [form, setForm] = useState<OfferFormState>(EMPTY_FORM);\n const [errors, setErrors] = useState<OfferErrors>({});\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [submitError, setSubmitError] = useState<string | null>(null);\n const [success, setSuccess] = useState<string | null>(null);\n const [submitting, setSubmitting] = useState(false);\n\n const opportunitiesPath = joinStorePath(basePath, 'publisher/sourcing/opportunities');\n\n const load = useCallback(\n async (initializeForm = false) => {\n if (!isEligible || !requestId) return;\n setLoading(true);\n setError(null);\n try {\n const result = await getOpportunity(requestId);\n setOpportunity(result.opportunity);\n setOffer(result.offer);\n setIsOpen(result.isOpen);\n if (!result.opportunity) {\n setError('This sourcing opportunity is no longer available.');\n } else if (initializeForm) {\n setForm({\n unitPrice: result.offer?.unitPrice ?? '',\n deliveryDate: result.offer\n ? toDateTimeLocal(result.offer.deliveryDate)\n : toDateTimeLocal(result.opportunity.deliveryWindowStart),\n storeProductId: result.offer?.storeProductId ?? '',\n message: result.offer?.message ?? '',\n });\n }\n } catch (loadError) {\n setError(toErrorMessage(loadError, 'The sourcing opportunity could not be loaded.'));\n } finally {\n setLoading(false);\n }\n },\n [getOpportunity, isEligible, requestId]\n );\n\n useEffect(() => {\n void load(true);\n }, [load]);\n\n const publishedProducts = useMemo(\n () =>\n [...products]\n .filter((product) => product.status === 'PUBLISHED')\n .sort((left, right) => left.name.localeCompare(right.name)),\n [products]\n );\n\n const updateField =\n (field: OfferField) =>\n (event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => {\n setForm((current) => ({ ...current, [field]: event.target.value }));\n setErrors((current) => ({ ...current, [field]: undefined }));\n setSuccess(null);\n };\n\n const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n if (!opportunity || !requestId || !isOpen || submitting) return;\n\n const validationErrors = validateOffer(form, opportunity);\n setErrors(validationErrors);\n setSubmitError(null);\n setSuccess(null);\n if (Object.keys(validationErrors).length > 0) return;\n\n const input: UpsertSourcingOfferInput = {\n requestId,\n quantity: opportunity.quantity,\n unit: opportunity.unit,\n unitPrice: form.unitPrice.trim(),\n currency: 'USD',\n deliveryDate: new Date(form.deliveryDate).toISOString(),\n storeProductId: form.storeProductId || undefined,\n message: form.message.trim() || undefined,\n };\n\n setSubmitting(true);\n try {\n const saved = await upsertOffer(input);\n setSuccess(offer ? 'Your offer was updated.' : 'Your offer was submitted.');\n setOffer(saved);\n await load(false);\n } catch (saveError) {\n setSubmitError(\n toErrorMessage(\n saveError,\n 'Your offer could not be saved. The request may have closed while you were editing.'\n )\n );\n } finally {\n setSubmitting(false);\n }\n };\n\n const fieldError = (field: OfferField) => {\n const message = errors[field];\n return message ? (\n <p id={`${field}-error`} className=\"mt-1 text-xs text-text-danger\">\n {message}\n </p>\n ) : null;\n };\n\n const canEdit = isOpen && (!offer || offer.status === SourcingOfferStatus.Active);\n\n return (\n <div className=\"min-h-full bg-surface-default\">\n <SourcingPageHeader\n title={opportunity?.productName ?? 'Sourcing opportunity'}\n description=\"Review the sanitized buyer request and create or update your publisher’s offer.\"\n icon={<TicketCheck className=\"size-5\" aria-hidden=\"true\" />}\n onBack={() => navigate(opportunitiesPath)}\n actions={\n <button\n type=\"button\"\n onClick={() => navigate(joinStorePath(basePath, 'publisher/sourcing/offers'))}\n className={secondaryButtonClassName}\n >\n My offers\n </button>\n }\n />\n\n <main className=\"mx-auto max-w-6xl px-4 py-6 sm:px-6\">\n <PagePurpose className=\"mb-6\">\n Quantity and unit are fixed by the buyer request. Store validates publisher identity, USD\n settlement price, delivery window, and optional linked product on every save. You can\n update one active offer until the request closes.\n </PagePurpose>\n\n {accessLoading ? (\n <SourcingLoadingState label=\"Checking Store Publisher access…\" />\n ) : accessError ? (\n <SourcingErrorState\n title=\"Publisher access could not be checked\"\n message={accessError}\n onRetry={() => void refreshAccess()}\n />\n ) : !profile ? (\n <ContextRequiredPanel\n title=\"Store Publisher profile required\"\n description=\"Only users who own a verified Store Publisher profile can view this opportunity or submit an offer.\"\n />\n ) : !isEligible ? (\n <ContextRequiredPanel\n title=\"Verified publisher status required\"\n description={`The publisher profile “${profile.name}” is currently ${profile.verificationStatus.toLowerCase().replaceAll('_', ' ')}.`}\n />\n ) : loading && !opportunity ? (\n <SourcingLoadingState label=\"Loading opportunity and your offer…\" />\n ) : error && !opportunity ? (\n <SourcingErrorState\n title=\"Opportunity unavailable\"\n message={error}\n onRetry={requestId ? () => void load(true) : undefined}\n />\n ) : opportunity ? (\n <>\n {submitError ? (\n <div\n role=\"alert\"\n className=\"mb-5 rounded-lg border border-border-danger bg-surface-danger-muted px-4 py-3 text-sm text-text-danger\"\n >\n {submitError}\n </div>\n ) : null}\n {success ? (\n <div\n role=\"status\"\n aria-live=\"polite\"\n className=\"mb-5 flex items-center gap-2 rounded-lg border border-status-success-border bg-status-success-bg-subtle px-4 py-3 text-sm text-status-success-text\"\n >\n <Check className=\"size-4\" aria-hidden=\"true\" />\n {success}\n </div>\n ) : null}\n\n {offer?.order ? (\n <EmphasisPanel className=\"mb-6\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <p className=\"text-sm font-semibold text-status-success-text\">\n This offer was accepted\n </p>\n <p className=\"mt-1 text-sm text-text-secondary\">\n Store order {offer.order.id} ·{' '}\n {formatMoney(offer.order.total, offer.order.currency)} · {offer.order.status}\n </p>\n </div>\n {offer.order.fulfillment ? (\n <span className=\"rounded-full border border-border-default bg-surface-muted px-3 py-1.5 text-xs font-medium text-text-secondary\">\n Fulfillment {offer.order.fulfillment.status.replaceAll('_', ' ')}\n </span>\n ) : null}\n </div>\n </EmphasisPanel>\n ) : null}\n\n <div className=\"grid gap-6 lg:grid-cols-[minmax(0,1.2fr)_minmax(340px,0.8fr)]\">\n <GlassCard className=\"p-5 sm:p-6\">\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div>\n <p className=\"text-sm font-medium text-text-accent\">{opportunity.category}</p>\n <h2 className=\"mt-1 text-xl font-semibold text-text-primary\">\n {opportunity.productName}\n </h2>\n </div>\n <span\n className={`rounded-full border px-2.5 py-1 text-xs font-semibold ${\n isOpen\n ? 'border-status-success-border bg-status-success-bg-subtle text-status-success-text'\n : 'border-border-default bg-surface-muted text-text-secondary'\n }`}\n >\n {isOpen ? 'OPEN' : 'CLOSED'}\n </span>\n </div>\n\n {opportunity.summary ? (\n <p className=\"mt-4 whitespace-pre-wrap text-sm leading-6 text-text-secondary\">\n {opportunity.summary}\n </p>\n ) : null}\n\n <dl className=\"mt-6 grid gap-5 border-t border-border-seam pt-5 sm:grid-cols-2\">\n <div className=\"flex gap-3\">\n <PackageSearch\n className=\"mt-0.5 size-5 shrink-0 text-text-tertiary\"\n aria-hidden=\"true\"\n />\n <div>\n <dt className=\"text-xs text-text-tertiary\">Required quantity</dt>\n <dd className=\"mt-0.5 font-medium text-text-primary\">\n {opportunity.quantity.toLocaleString()}{' '}\n {formatSourcingUnit(opportunity.unit)}\n </dd>\n </div>\n </div>\n <div className=\"flex gap-3\">\n <CircleDollarSign\n className=\"mt-0.5 size-5 shrink-0 text-text-tertiary\"\n aria-hidden=\"true\"\n />\n <div>\n <dt className=\"text-xs text-text-tertiary\">Buyer target</dt>\n <dd className=\"mt-0.5 font-medium text-text-primary\">\n {formatMoney(opportunity.targetUnitPrice, opportunity.targetCurrency)}\n </dd>\n </div>\n </div>\n <div className=\"flex gap-3\">\n <CalendarDays\n className=\"mt-0.5 size-5 shrink-0 text-text-tertiary\"\n aria-hidden=\"true\"\n />\n <div>\n <dt className=\"text-xs text-text-tertiary\">Delivery window</dt>\n <dd className=\"mt-0.5 font-medium text-text-primary\">\n {formatDateTime(opportunity.deliveryWindowStart)} –{' '}\n {formatDateTime(opportunity.deliveryWindowEnd)}\n </dd>\n </div>\n </div>\n <div className=\"flex gap-3\">\n <MapPin\n className=\"mt-0.5 size-5 shrink-0 text-text-tertiary\"\n aria-hidden=\"true\"\n />\n <div>\n <dt className=\"text-xs text-text-tertiary\">Destination</dt>\n <dd className=\"mt-0.5 font-medium text-text-primary\">\n {formatLocation({\n country: opportunity.deliveryCountry,\n region: opportunity.deliveryRegion,\n city: opportunity.deliveryCity,\n })}\n </dd>\n </div>\n </div>\n </dl>\n </GlassCard>\n\n {canEdit ? (\n <form onSubmit={(event) => void handleSubmit(event)} noValidate>\n <GlassCard className=\"p-5 sm:p-6\">\n <div className=\"flex items-center justify-between gap-3\">\n <div>\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {offer ? 'Update your offer' : 'Create an offer'}\n </h2>\n <p className=\"mt-1 text-xs text-text-tertiary\">\n Offering as {profile.name}\n </p>\n </div>\n <BadgeCheck\n className=\"size-5 text-text-accent\"\n aria-label=\"Verified publisher\"\n />\n </div>\n\n <div className=\"mt-5 space-y-5\">\n <label className={labelClassName}>\n Unit price\n <div className=\"mt-1.5 grid grid-cols-[1fr_96px] gap-2\">\n <input\n type=\"text\"\n value={form.unitPrice}\n onChange={updateField('unitPrice')}\n inputMode=\"decimal\"\n required\n maxLength={19}\n aria-invalid={Boolean(errors.unitPrice)}\n aria-describedby={\n errors.unitPrice ? 'unitPrice-error' : 'unitPrice-help'\n }\n placeholder=\"125.50\"\n className={`${inputClassName} mt-0`}\n />\n <span\n aria-label=\"Offer currency\"\n className=\"mt-0 flex items-center justify-center rounded-md border border-border-default bg-surface-muted px-3 text-sm font-semibold text-text-secondary\"\n >\n USD\n </span>\n </div>\n {fieldError('unitPrice')}\n {!errors.unitPrice ? (\n <p id=\"unitPrice-help\" className={helpClassName}>\n Price per {formatSourcingUnit(opportunity.unit).toLowerCase()}. Store\n sourcing currently settles in USD.\n </p>\n ) : null}\n </label>\n\n <label className={labelClassName}>\n Promised delivery date\n <input\n type=\"datetime-local\"\n value={form.deliveryDate}\n onChange={updateField('deliveryDate')}\n required\n min={toDateTimeLocal(opportunity.deliveryWindowStart)}\n max={toDateTimeLocal(opportunity.deliveryWindowEnd)}\n aria-invalid={Boolean(errors.deliveryDate)}\n aria-describedby={\n errors.deliveryDate ? 'deliveryDate-error' : 'deliveryDate-help'\n }\n className={inputClassName}\n />\n {fieldError('deliveryDate')}\n {!errors.deliveryDate ? (\n <p id=\"deliveryDate-help\" className={helpClassName}>\n Must fall inside the buyer’s delivery window.\n </p>\n ) : null}\n </label>\n\n <label className={labelClassName}>\n Link a published product{' '}\n <span className=\"font-normal text-text-tertiary\">(optional)</span>\n <select\n value={form.storeProductId}\n onChange={updateField('storeProductId')}\n disabled={productsLoading}\n aria-describedby={\n productsError ? 'store-product-error' : 'store-product-help'\n }\n className={inputClassName}\n >\n <option value=\"\">\n {productsLoading\n ? 'Loading published products…'\n : 'No linked Store product'}\n </option>\n {publishedProducts.map((product) => (\n <option key={product.id} value={product.id}>\n {product.name}\n </option>\n ))}\n </select>\n {productsError ? (\n <div\n id=\"store-product-error\"\n role=\"alert\"\n className=\"mt-2 flex flex-wrap items-center gap-2 text-xs text-text-danger\"\n >\n <span>{productsError}</span>\n <button\n type=\"button\"\n onClick={() => void refreshProducts()}\n className=\"font-semibold underline underline-offset-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-action-primary-bg\"\n >\n Try again\n </button>\n </div>\n ) : (\n <p id=\"store-product-help\" className={helpClassName}>\n Only products owned by this publisher and currently published are\n accepted. The link is reference metadata and does not reserve catalog\n inventory or create digital entitlements.\n </p>\n )}\n </label>\n\n <label className={labelClassName}>\n Message <span className=\"font-normal text-text-tertiary\">(optional)</span>\n <textarea\n value={form.message}\n onChange={updateField('message')}\n maxLength={1000}\n rows={4}\n aria-invalid={Boolean(errors.message)}\n aria-describedby={errors.message ? 'message-error' : 'message-help'}\n placeholder=\"Add packaging, quality, or delivery notes relevant to this offer.\"\n className={`${inputClassName} resize-y`}\n />\n {fieldError('message')}\n {!errors.message ? (\n <p id=\"message-help\" className={helpClassName}>\n {form.message.length}/1,000 characters\n </p>\n ) : null}\n </label>\n </div>\n\n <button\n type=\"submit\"\n disabled={submitting}\n className={`${primaryButtonClassName} mt-6 w-full`}\n >\n {submitting ? (\n <Loader2 className=\"size-4 animate-spin\" aria-hidden=\"true\" />\n ) : offer ? (\n <Save className=\"size-4\" aria-hidden=\"true\" />\n ) : (\n <TicketCheck className=\"size-4\" aria-hidden=\"true\" />\n )}\n {submitting ? 'Saving offer…' : offer ? 'Update offer' : 'Submit offer'}\n </button>\n </GlassCard>\n </form>\n ) : offer ? (\n <GlassCard className=\"p-5 sm:p-6\">\n <div className=\"flex items-start justify-between gap-3\">\n <div>\n <h2 className=\"text-lg font-semibold text-text-primary\">Your offer</h2>\n <p className=\"mt-1 text-xs text-text-tertiary\">\n Updated {formatDateTime(offer.updatedAt)}\n </p>\n </div>\n <SourcingStatusBadge status={offer.status} />\n </div>\n <dl className=\"mt-5 space-y-4 text-sm\">\n <div>\n <dt className=\"text-xs text-text-tertiary\">Unit price</dt>\n <dd className=\"mt-0.5 text-lg font-semibold text-text-primary\">\n {formatMoney(offer.unitPrice, offer.currency)}\n </dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-tertiary\">Promised delivery</dt>\n <dd className=\"mt-0.5 font-medium text-text-primary\">\n {formatDateTime(offer.deliveryDate)}\n </dd>\n </div>\n {offer.message ? (\n <div>\n <dt className=\"text-xs text-text-tertiary\">Message</dt>\n <dd className=\"mt-1 whitespace-pre-wrap text-text-secondary\">\n {offer.message}\n </dd>\n </div>\n ) : null}\n </dl>\n </GlassCard>\n ) : (\n <ContextRequiredPanel\n title=\"This request is closed\"\n description=\"The buyer matched or canceled this request before your publisher submitted an offer.\"\n />\n )}\n </div>\n </>\n ) : null}\n </main>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { FC } from 'react';
2
+
3
+ export declare const SourcingRequestDetailPage: FC;