@burdenoff/microfe-store 2026.819.2 → 2026.819.11

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.
@@ -1 +1 @@
1
- {"version":3,"file":"SellerSourcingOffersPage.js","names":[],"sources":["../../src/pages/SellerSourcingOffersPage.tsx"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react';\nimport type { FC } from 'react';\nimport { useNavigate } from 'react-router';\nimport {\n ArrowRight,\n CalendarDays,\n CircleDollarSign,\n MapPin,\n PackageSearch,\n RefreshCw,\n TicketCheck,\n} from 'lucide-react';\nimport { GlassCard, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { SourcingOfferStatus } from '../generated/global-types';\nimport { useStore } from '../providers/StoreProvider';\nimport { type SellerSourcingOffer, useSourcingApi } from '../hooks/useSourcing';\nimport { usePublisherSourcingAccess } from '../providers/SourcingAccessProvider';\nimport {\n ContextRequiredPanel,\n formatDate,\n formatDateTime,\n formatLocation,\n formatMoney,\n formatSourcingUnit,\n joinStorePath,\n primaryButtonClassName,\n secondaryButtonClassName,\n SourcingEmptyState,\n SourcingErrorState,\n SourcingLoadingState,\n SourcingPageHeader,\n SourcingStatusBadge,\n toErrorMessage,\n} from '../components/sourcing/SourcingUi';\n\nconst PAGE_SIZE = 30;\ntype OfferFilter = SourcingOfferStatus | '';\n\nfunction parseOfferFilter(value: string): OfferFilter {\n switch (value) {\n case SourcingOfferStatus.Active:\n return SourcingOfferStatus.Active;\n case SourcingOfferStatus.Accepted:\n return SourcingOfferStatus.Accepted;\n case SourcingOfferStatus.Rejected:\n return SourcingOfferStatus.Rejected;\n default:\n return '';\n }\n}\n\nexport const SellerSourcingOffersPage: FC = () => {\n const navigate = useNavigate();\n const { basePath } = useStore();\n const {\n profile,\n loading: accessLoading,\n error: accessError,\n isEligible,\n refresh: refreshAccess,\n } = usePublisherSourcingAccess();\n const { listSellerOffers } = useSourcingApi();\n const [offers, setOffers] = useState<SellerSourcingOffer[]>([]);\n const [status, setStatus] = useState<OfferFilter>('');\n const [offset, setOffset] = useState(0);\n const [hasMore, setHasMore] = useState(false);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const load = useCallback(\n async (nextOffset = 0, append = false) => {\n if (!isEligible) return;\n setLoading(true);\n setError(null);\n try {\n const result = await listSellerOffers({\n status: status || undefined,\n limit: PAGE_SIZE,\n offset: nextOffset,\n });\n setOffers((current) => (append ? [...current, ...result] : result));\n setOffset(nextOffset);\n setHasMore(result.length === PAGE_SIZE);\n } catch (loadError) {\n setError(toErrorMessage(loadError, 'Your sourcing offers could not be loaded.'));\n } finally {\n setLoading(false);\n }\n },\n [isEligible, listSellerOffers, status]\n );\n\n useEffect(() => {\n void load();\n }, [load]);\n\n return (\n <div className=\"min-h-full bg-surface-default\">\n <SourcingPageHeader\n title=\"My sourcing offers\"\n description=\"Track and update the offers submitted by your verified Store Publisher.\"\n icon={<TicketCheck className=\"size-5\" aria-hidden=\"true\" />}\n actions={\n <button\n type=\"button\"\n onClick={() => navigate(joinStorePath(basePath, 'publisher/sourcing/opportunities'))}\n className={primaryButtonClassName}\n >\n <PackageSearch className=\"size-4\" aria-hidden=\"true\" />\n Find opportunities\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 Active offers can be updated while their request remains open. Accepted and rejected\n offers are final. When a buyer accepts your offer, the resulting Store order and\n fulfillment status appear here without exposing another publisher's private offer.\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=\"A Store Publisher profile is required to submit or review sourcing offers.\"\n />\n ) : !isEligible ? (\n <ContextRequiredPanel\n title=\"Verified publisher status required\"\n description={`The publisher profile “${profile.name}” is currently ${profile.verificationStatus.toLowerCase().replaceAll('_', ' ')}. Offers are available only to active verified publishers.`}\n />\n ) : (\n <>\n <div className=\"mb-5 flex flex-col gap-3 rounded-xl border border-border-seam bg-surface-raised p-4 sm:flex-row sm:items-end sm:justify-between\">\n <label className=\"block sm:w-64\">\n <span className=\"text-sm font-medium text-text-primary\">Offer status</span>\n <select\n value={status}\n onChange={(event) => setStatus(parseOfferFilter(event.target.value))}\n className=\"mt-1.5 w-full rounded-lg border border-border-default bg-surface-default px-3 py-2 text-sm text-text-primary outline-none focus:border-action-primary-bg focus:ring-2 focus:ring-action-primary-bg/20\"\n >\n <option value=\"\">All statuses</option>\n <option value={SourcingOfferStatus.Active}>Active</option>\n <option value={SourcingOfferStatus.Accepted}>Accepted</option>\n <option value={SourcingOfferStatus.Rejected}>Rejected</option>\n </select>\n </label>\n <button\n type=\"button\"\n onClick={() => void load()}\n disabled={loading}\n className={secondaryButtonClassName}\n >\n <RefreshCw\n className={`size-4 ${loading ? 'animate-spin' : ''}`}\n aria-hidden=\"true\"\n />\n Refresh\n </button>\n </div>\n\n {loading && offers.length === 0 ? (\n <SourcingLoadingState label=\"Loading your sourcing offers…\" />\n ) : error && offers.length === 0 ? (\n <SourcingErrorState\n title=\"Offers could not be loaded\"\n message={error}\n onRetry={() => void load()}\n />\n ) : offers.length === 0 ? (\n <SourcingEmptyState\n title={status ? 'No offers match this status' : 'No sourcing offers yet'}\n description={\n status\n ? 'Choose another status to review the rest of your offers.'\n : 'Browse open buyer opportunities to create your first sourcing offer.'\n }\n action={\n <button\n type=\"button\"\n onClick={() =>\n navigate(joinStorePath(basePath, 'publisher/sourcing/opportunities'))\n }\n className={primaryButtonClassName}\n >\n <PackageSearch className=\"size-4\" aria-hidden=\"true\" />\n Browse opportunities\n </button>\n }\n />\n ) : (\n <>\n {error ? (\n <div\n role=\"alert\"\n className=\"mb-4 rounded-lg border border-border-danger bg-surface-danger-muted px-4 py-3 text-sm text-text-danger\"\n >\n {error}\n </div>\n ) : null}\n <ul className=\"grid gap-4 md:grid-cols-2\">\n {offers.map((offer) => (\n <li key={offer.id}>\n <GlassCard className=\"flex h-full flex-col p-5\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"truncate text-xs font-semibold uppercase tracking-wide text-text-accent\">\n {offer.request?.category ?? 'Sourcing request'}\n </p>\n <h2 className=\"mt-1 line-clamp-2 text-lg font-semibold text-text-primary\">\n {offer.request?.productName ?? `Request ${offer.requestId}`}\n </h2>\n </div>\n <SourcingStatusBadge status={offer.status} />\n </div>\n\n <dl className=\"mt-5 grid gap-4 text-sm sm:grid-cols-2\">\n <div className=\"flex gap-2\">\n <CircleDollarSign\n className=\"mt-0.5 size-4 shrink-0 text-text-tertiary\"\n aria-hidden=\"true\"\n />\n <div>\n <dt className=\"text-xs text-text-tertiary\">Your unit price</dt>\n <dd className=\"font-semibold text-text-primary\">\n {formatMoney(offer.unitPrice, offer.currency)}\n </dd>\n </div>\n </div>\n <div className=\"flex gap-2\">\n <PackageSearch\n className=\"mt-0.5 size-4 shrink-0 text-text-tertiary\"\n aria-hidden=\"true\"\n />\n <div>\n <dt className=\"text-xs text-text-tertiary\">Quantity</dt>\n <dd className=\"font-medium text-text-primary\">\n {offer.quantity.toLocaleString()} {formatSourcingUnit(offer.unit)}\n </dd>\n </div>\n </div>\n <div className=\"flex gap-2\">\n <CalendarDays\n className=\"mt-0.5 size-4 shrink-0 text-text-tertiary\"\n aria-hidden=\"true\"\n />\n <div>\n <dt className=\"text-xs text-text-tertiary\">Promised delivery</dt>\n <dd className=\"font-medium text-text-primary\">\n {formatDateTime(offer.deliveryDate)}\n </dd>\n </div>\n </div>\n {offer.request ? (\n <div className=\"flex gap-2\">\n <MapPin\n className=\"mt-0.5 size-4 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=\"font-medium text-text-primary\">\n {formatLocation({\n country: offer.request.deliveryCountry,\n region: offer.request.deliveryRegion,\n city: offer.request.deliveryCity,\n })}\n </dd>\n </div>\n </div>\n ) : null}\n </dl>\n\n {offer.message ? (\n <p className=\"mt-4 line-clamp-3 rounded-lg bg-surface-muted p-3 text-sm leading-6 text-text-secondary\">\n {offer.message}\n </p>\n ) : null}\n\n {offer.order ? (\n <div className=\"mt-4 rounded-lg border border-status-success-border bg-status-success-bg-subtle p-3\">\n <p className=\"text-xs font-medium text-status-success-text\">\n Store order {offer.order.id}\n </p>\n <p className=\"mt-1 text-sm font-semibold text-text-primary\">\n {formatMoney(offer.order.total, offer.order.currency)} ·{' '}\n {offer.order.status}\n </p>\n {offer.order.fulfillment ? (\n <p className=\"mt-1 text-xs text-text-secondary\">\n Fulfillment: {offer.order.fulfillment.status.replaceAll('_', ' ')}\n </p>\n ) : null}\n </div>\n ) : null}\n\n <div className=\"mt-auto flex items-center justify-between gap-3 border-t border-border-seam pt-4\">\n <p className=\"text-xs text-text-tertiary\">\n Updated {formatDate(offer.updatedAt)}\n </p>\n <button\n type=\"button\"\n onClick={() =>\n navigate(\n joinStorePath(\n basePath,\n `publisher/sourcing/opportunities/${offer.requestId}`\n )\n )\n }\n className={secondaryButtonClassName}\n >\n {offer.status === SourcingOfferStatus.Active\n ? 'Review or update'\n : 'View details'}\n <ArrowRight className=\"size-4\" aria-hidden=\"true\" />\n </button>\n </div>\n </GlassCard>\n </li>\n ))}\n </ul>\n\n {hasMore ? (\n <div className=\"mt-6 flex justify-center\">\n <button\n type=\"button\"\n onClick={() => void load(offset + PAGE_SIZE, true)}\n disabled={loading}\n className={secondaryButtonClassName}\n >\n {loading ? 'Loading…' : 'Load more'}\n </button>\n </div>\n ) : null}\n </>\n )}\n </>\n )}\n </main>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"SellerSourcingOffersPage.js","names":[],"sources":["../../src/pages/SellerSourcingOffersPage.tsx"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react';\nimport type { FC } from 'react';\nimport { useNavigate } from 'react-router';\nimport {\n ArrowRight,\n CalendarDays,\n CircleDollarSign,\n MapPin,\n PackageSearch,\n RefreshCw,\n TicketCheck,\n} from 'lucide-react';\nimport { GlassCard, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { SourcingOfferStatus } from '../generated/global-types';\nimport { useStore } from '../providers/StoreProvider';\nimport { type SellerSourcingOffer, useSourcingApi } from '../hooks/useSourcing';\nimport { usePublisherSourcingAccess } from '../providers/SourcingAccessProvider';\nimport {\n ContextRequiredPanel,\n formatDate,\n formatDateTime,\n formatLocation,\n formatMoney,\n formatSourcingUnit,\n joinStorePath,\n primaryButtonClassName,\n secondaryButtonClassName,\n SourcingEmptyState,\n SourcingErrorState,\n SourcingLoadingState,\n SourcingPageHeader,\n SourcingStatusBadge,\n toErrorMessage,\n} from '../components/sourcing/SourcingUi';\n\nconst PAGE_SIZE = 30;\ntype OfferFilter = SourcingOfferStatus | '';\n\nfunction parseOfferFilter(value: string): OfferFilter {\n switch (value) {\n case SourcingOfferStatus.Active:\n return SourcingOfferStatus.Active;\n case SourcingOfferStatus.Accepted:\n return SourcingOfferStatus.Accepted;\n case SourcingOfferStatus.Rejected:\n return SourcingOfferStatus.Rejected;\n default:\n return '';\n }\n}\n\nexport const SellerSourcingOffersPage: FC = () => {\n const navigate = useNavigate();\n const { basePath } = useStore();\n const {\n profile,\n loading: accessLoading,\n error: accessError,\n isEligible,\n refresh: refreshAccess,\n } = usePublisherSourcingAccess();\n const { listSellerOffers } = useSourcingApi();\n const [offers, setOffers] = useState<SellerSourcingOffer[]>([]);\n const [status, setStatus] = useState<OfferFilter>('');\n const [offset, setOffset] = useState(0);\n const [hasMore, setHasMore] = useState(false);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const load = useCallback(\n async (nextOffset = 0, append = false) => {\n if (!isEligible) return;\n setLoading(true);\n setError(null);\n try {\n const result = await listSellerOffers({\n status: status || undefined,\n limit: PAGE_SIZE,\n offset: nextOffset,\n });\n setOffers((current) => (append ? [...current, ...result] : result));\n setOffset(nextOffset);\n setHasMore(result.length === PAGE_SIZE);\n } catch (loadError) {\n setError(toErrorMessage(loadError, 'Your sourcing offers could not be loaded.'));\n } finally {\n setLoading(false);\n }\n },\n [isEligible, listSellerOffers, status]\n );\n\n useEffect(() => {\n void load();\n }, [load]);\n\n return (\n <div className=\"min-h-full bg-surface\">\n <SourcingPageHeader\n title=\"My sourcing offers\"\n description=\"Track and update the offers submitted by your verified Store Publisher.\"\n icon={<TicketCheck className=\"size-5\" aria-hidden=\"true\" />}\n actions={\n <button\n type=\"button\"\n onClick={() => navigate(joinStorePath(basePath, 'publisher/sourcing/opportunities'))}\n className={primaryButtonClassName}\n >\n <PackageSearch className=\"size-4\" aria-hidden=\"true\" />\n Find opportunities\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 Active offers can be updated while their request remains open. Accepted and rejected\n offers are final. When a buyer accepts your offer, the resulting Store order and\n fulfillment status appear here without exposing another publisher's private offer.\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=\"A Store Publisher profile is required to submit or review sourcing offers.\"\n />\n ) : !isEligible ? (\n <ContextRequiredPanel\n title=\"Verified publisher status required\"\n description={`The publisher profile “${profile.name}” is currently ${profile.verificationStatus.toLowerCase().replaceAll('_', ' ')}. Offers are available only to active verified publishers.`}\n />\n ) : (\n <>\n <div className=\"mb-5 flex flex-col gap-3 rounded-xl border border-border-subtle bg-surface-elevated p-4 sm:flex-row sm:items-end sm:justify-between\">\n <label className=\"block sm:w-64\">\n <span className=\"text-sm font-medium text-text-primary\">Offer status</span>\n <select\n value={status}\n onChange={(event) => setStatus(parseOfferFilter(event.target.value))}\n className=\"mt-1.5 w-full rounded-lg border border-border-default bg-surface px-3 py-2 text-sm text-text-primary outline-none focus:border-action-primary-bg focus:ring-2 focus:ring-action-primary-bg/20\"\n >\n <option value=\"\">All statuses</option>\n <option value={SourcingOfferStatus.Active}>Active</option>\n <option value={SourcingOfferStatus.Accepted}>Accepted</option>\n <option value={SourcingOfferStatus.Rejected}>Rejected</option>\n </select>\n </label>\n <button\n type=\"button\"\n onClick={() => void load()}\n disabled={loading}\n className={secondaryButtonClassName}\n >\n <RefreshCw\n className={`size-4 ${loading ? 'animate-spin' : ''}`}\n aria-hidden=\"true\"\n />\n Refresh\n </button>\n </div>\n\n {loading && offers.length === 0 ? (\n <SourcingLoadingState label=\"Loading your sourcing offers…\" />\n ) : error && offers.length === 0 ? (\n <SourcingErrorState\n title=\"Offers could not be loaded\"\n message={error}\n onRetry={() => void load()}\n />\n ) : offers.length === 0 ? (\n <SourcingEmptyState\n title={status ? 'No offers match this status' : 'No sourcing offers yet'}\n description={\n status\n ? 'Choose another status to review the rest of your offers.'\n : 'Browse open buyer opportunities to create your first sourcing offer.'\n }\n action={\n <button\n type=\"button\"\n onClick={() =>\n navigate(joinStorePath(basePath, 'publisher/sourcing/opportunities'))\n }\n className={primaryButtonClassName}\n >\n <PackageSearch className=\"size-4\" aria-hidden=\"true\" />\n Browse opportunities\n </button>\n }\n />\n ) : (\n <>\n {error ? (\n <div\n role=\"alert\"\n className=\"mb-4 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-4 py-3 text-sm text-status-error-text\"\n >\n {error}\n </div>\n ) : null}\n <ul className=\"grid gap-4 md:grid-cols-2\">\n {offers.map((offer) => (\n <li key={offer.id}>\n <GlassCard className=\"flex h-full flex-col p-5\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"truncate text-xs font-semibold uppercase tracking-wide text-accent-primary\">\n {offer.request?.category ?? 'Sourcing request'}\n </p>\n <h2 className=\"mt-1 line-clamp-2 text-lg font-semibold text-text-primary\">\n {offer.request?.productName ?? `Request ${offer.requestId}`}\n </h2>\n </div>\n <SourcingStatusBadge status={offer.status} />\n </div>\n\n <dl className=\"mt-5 grid gap-4 text-sm sm:grid-cols-2\">\n <div className=\"flex gap-2\">\n <CircleDollarSign\n className=\"mt-0.5 size-4 shrink-0 text-text-muted\"\n aria-hidden=\"true\"\n />\n <div>\n <dt className=\"text-xs text-text-muted\">Your unit price</dt>\n <dd className=\"font-semibold text-text-primary\">\n {formatMoney(offer.unitPrice, offer.currency)}\n </dd>\n </div>\n </div>\n <div className=\"flex gap-2\">\n <PackageSearch\n className=\"mt-0.5 size-4 shrink-0 text-text-muted\"\n aria-hidden=\"true\"\n />\n <div>\n <dt className=\"text-xs text-text-muted\">Quantity</dt>\n <dd className=\"font-medium text-text-primary\">\n {offer.quantity.toLocaleString()} {formatSourcingUnit(offer.unit)}\n </dd>\n </div>\n </div>\n <div className=\"flex gap-2\">\n <CalendarDays\n className=\"mt-0.5 size-4 shrink-0 text-text-muted\"\n aria-hidden=\"true\"\n />\n <div>\n <dt className=\"text-xs text-text-muted\">Promised delivery</dt>\n <dd className=\"font-medium text-text-primary\">\n {formatDateTime(offer.deliveryDate)}\n </dd>\n </div>\n </div>\n {offer.request ? (\n <div className=\"flex gap-2\">\n <MapPin\n className=\"mt-0.5 size-4 shrink-0 text-text-muted\"\n aria-hidden=\"true\"\n />\n <div>\n <dt className=\"text-xs text-text-muted\">Destination</dt>\n <dd className=\"font-medium text-text-primary\">\n {formatLocation({\n country: offer.request.deliveryCountry,\n region: offer.request.deliveryRegion,\n city: offer.request.deliveryCity,\n })}\n </dd>\n </div>\n </div>\n ) : null}\n </dl>\n\n {offer.message ? (\n <p className=\"mt-4 line-clamp-3 rounded-lg bg-surface-sunken p-3 text-sm leading-6 text-text-secondary\">\n {offer.message}\n </p>\n ) : null}\n\n {offer.order ? (\n <div className=\"mt-4 rounded-lg border border-status-success-border bg-status-success-bg-subtle p-3\">\n <p className=\"text-xs font-medium text-status-success-text\">\n Store order {offer.order.id}\n </p>\n <p className=\"mt-1 text-sm font-semibold text-text-primary\">\n {formatMoney(offer.order.total, offer.order.currency)} ·{' '}\n {offer.order.status}\n </p>\n {offer.order.fulfillment ? (\n <p className=\"mt-1 text-xs text-text-secondary\">\n Fulfillment: {offer.order.fulfillment.status.replaceAll('_', ' ')}\n </p>\n ) : null}\n </div>\n ) : null}\n\n <div className=\"mt-auto flex items-center justify-between gap-3 border-t border-border-subtle pt-4\">\n <p className=\"text-xs text-text-muted\">\n Updated {formatDate(offer.updatedAt)}\n </p>\n <button\n type=\"button\"\n onClick={() =>\n navigate(\n joinStorePath(\n basePath,\n `publisher/sourcing/opportunities/${offer.requestId}`\n )\n )\n }\n className={secondaryButtonClassName}\n >\n {offer.status === SourcingOfferStatus.Active\n ? 'Review or update'\n : 'View details'}\n <ArrowRight className=\"size-4\" aria-hidden=\"true\" />\n </button>\n </div>\n </GlassCard>\n </li>\n ))}\n </ul>\n\n {hasMore ? (\n <div className=\"mt-6 flex justify-center\">\n <button\n type=\"button\"\n onClick={() => void load(offset + PAGE_SIZE, true)}\n disabled={loading}\n className={secondaryButtonClassName}\n >\n {loading ? 'Loading…' : 'Load more'}\n </button>\n </div>\n ) : null}\n </>\n )}\n </>\n )}\n </main>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -37,7 +37,7 @@ var j = () => {
37
37
  return h(() => {
38
38
  $();
39
39
  }, [$]), /* @__PURE__ */ E("div", {
40
- className: "min-h-full bg-surface-default",
40
+ className: "min-h-full bg-surface",
41
41
  children: [/* @__PURE__ */ T(o, {
42
42
  title: "Sourcing opportunities",
43
43
  description: "Respond to open buyer requests as your verified Store Publisher.",
@@ -64,7 +64,7 @@ var j = () => {
64
64
  message: F,
65
65
  onRetry: () => void L()
66
66
  }) : N ? I ? /* @__PURE__ */ E(w, { children: [/* @__PURE__ */ T("div", {
67
- className: "mb-5 rounded-xl border border-border-seam bg-surface-raised p-4",
67
+ className: "mb-5 rounded-xl border border-border-subtle bg-surface-elevated p-4",
68
68
  children: /* @__PURE__ */ E("div", {
69
69
  className: "flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between",
70
70
  children: [/* @__PURE__ */ E("form", {
@@ -80,7 +80,7 @@ var j = () => {
80
80
  }), /* @__PURE__ */ E("div", {
81
81
  className: "relative",
82
82
  children: [/* @__PURE__ */ T(S, {
83
- className: "pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-text-tertiary",
83
+ className: "pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-text-muted",
84
84
  "aria-hidden": "true"
85
85
  }), /* @__PURE__ */ T("input", {
86
86
  type: "text",
@@ -112,7 +112,7 @@ var j = () => {
112
112
  className: "inline-flex items-center gap-1.5 text-sm text-text-secondary",
113
113
  children: [
114
114
  /* @__PURE__ */ T(_, {
115
- className: "size-4 text-text-accent",
115
+ className: "size-4 text-accent-primary",
116
116
  "aria-hidden": "true"
117
117
  }),
118
118
  "Offering as ",
@@ -140,7 +140,7 @@ var j = () => {
140
140
  }) : /* @__PURE__ */ E(w, { children: [
141
141
  Z ? /* @__PURE__ */ T("div", {
142
142
  role: "alert",
143
- className: "mb-4 rounded-lg border border-border-danger bg-surface-danger-muted px-4 py-3 text-sm text-text-danger",
143
+ className: "mb-4 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-4 py-3 text-sm text-status-error-text",
144
144
  children: Z
145
145
  }) : null,
146
146
  /* @__PURE__ */ T("ul", {
@@ -153,7 +153,7 @@ var j = () => {
153
153
  children: [/* @__PURE__ */ E("div", {
154
154
  className: "min-w-0",
155
155
  children: [/* @__PURE__ */ T("p", {
156
- className: "truncate text-xs font-semibold uppercase tracking-wide text-text-accent",
156
+ className: "truncate text-xs font-semibold uppercase tracking-wide text-accent-primary",
157
157
  children: e.category
158
158
  }), /* @__PURE__ */ T("h2", {
159
159
  className: "mt-1 line-clamp-2 text-lg font-semibold text-text-primary",
@@ -174,10 +174,10 @@ var j = () => {
174
174
  /* @__PURE__ */ E("div", {
175
175
  className: "flex items-start gap-2",
176
176
  children: [/* @__PURE__ */ T(b, {
177
- className: "mt-0.5 size-4 shrink-0 text-text-tertiary",
177
+ className: "mt-0.5 size-4 shrink-0 text-text-muted",
178
178
  "aria-hidden": "true"
179
179
  }), /* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("dt", {
180
- className: "text-xs text-text-tertiary",
180
+ className: "text-xs text-text-muted",
181
181
  children: "Quantity"
182
182
  }), /* @__PURE__ */ E("dd", {
183
183
  className: "font-medium text-text-primary",
@@ -191,10 +191,10 @@ var j = () => {
191
191
  /* @__PURE__ */ E("div", {
192
192
  className: "flex items-start gap-2",
193
193
  children: [/* @__PURE__ */ T(v, {
194
- className: "mt-0.5 size-4 shrink-0 text-text-tertiary",
194
+ className: "mt-0.5 size-4 shrink-0 text-text-muted",
195
195
  "aria-hidden": "true"
196
196
  }), /* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("dt", {
197
- className: "text-xs text-text-tertiary",
197
+ className: "text-xs text-text-muted",
198
198
  children: "Deliver by"
199
199
  }), /* @__PURE__ */ E("dd", {
200
200
  className: "font-medium text-text-primary",
@@ -209,10 +209,10 @@ var j = () => {
209
209
  /* @__PURE__ */ E("div", {
210
210
  className: "flex items-start gap-2",
211
211
  children: [/* @__PURE__ */ T(y, {
212
- className: "mt-0.5 size-4 shrink-0 text-text-tertiary",
212
+ className: "mt-0.5 size-4 shrink-0 text-text-muted",
213
213
  "aria-hidden": "true"
214
214
  }), /* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("dt", {
215
- className: "text-xs text-text-tertiary",
215
+ className: "text-xs text-text-muted",
216
216
  children: "Destination"
217
217
  }), /* @__PURE__ */ T("dd", {
218
218
  className: "font-medium text-text-primary",
@@ -226,9 +226,9 @@ var j = () => {
226
226
  ]
227
227
  }),
228
228
  /* @__PURE__ */ E("div", {
229
- className: "mt-auto flex items-end justify-between gap-3 border-t border-border-seam pt-4",
229
+ className: "mt-auto flex items-end justify-between gap-3 border-t border-border-subtle pt-4",
230
230
  children: [/* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("p", {
231
- className: "text-xs text-text-tertiary",
231
+ className: "text-xs text-text-muted",
232
232
  children: "Buyer target"
233
233
  }), /* @__PURE__ */ T("p", {
234
234
  className: "text-sm font-semibold text-text-primary",
@@ -1 +1 @@
1
- {"version":3,"file":"SellerSourcingOpportunitiesPage.js","names":[],"sources":["../../src/pages/SellerSourcingOpportunitiesPage.tsx"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react';\nimport type { FC, FormEvent } from 'react';\nimport { useNavigate } from 'react-router';\nimport {\n ArrowRight,\n BadgeCheck,\n CalendarDays,\n MapPin,\n PackageSearch,\n RefreshCw,\n Tags,\n TicketCheck,\n} from 'lucide-react';\nimport { GlassCard, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { useStore } from '../providers/StoreProvider';\nimport { type SellerSourcingOpportunity, useSourcingApi } from '../hooks/useSourcing';\nimport { usePublisherSourcingAccess } from '../providers/SourcingAccessProvider';\nimport {\n ContextRequiredPanel,\n formatDate,\n formatLocation,\n formatMoney,\n formatSourcingUnit,\n inputClassName,\n joinStorePath,\n primaryButtonClassName,\n secondaryButtonClassName,\n SourcingEmptyState,\n SourcingErrorState,\n SourcingLoadingState,\n SourcingPageHeader,\n toErrorMessage,\n} from '../components/sourcing/SourcingUi';\n\nconst PAGE_SIZE = 30;\n\nfunction normalizeCategory(value: string): string {\n return value\n .trim()\n .toLowerCase()\n .replaceAll(/[_\\s]+/g, '-')\n .replaceAll(/-+/g, '-');\n}\n\nexport const SellerSourcingOpportunitiesPage: FC = () => {\n const navigate = useNavigate();\n const { basePath } = useStore();\n const {\n profile,\n loading: accessLoading,\n error: accessError,\n isEligible,\n refresh: refreshAccess,\n } = usePublisherSourcingAccess();\n const { listOpportunities } = useSourcingApi();\n const [opportunities, setOpportunities] = useState<SellerSourcingOpportunity[]>([]);\n const [categoryInput, setCategoryInput] = useState('');\n const [category, setCategory] = useState('');\n const [offset, setOffset] = useState(0);\n const [hasMore, setHasMore] = useState(false);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const load = useCallback(\n async (nextOffset = 0, append = false) => {\n if (!isEligible) return;\n setLoading(true);\n setError(null);\n try {\n const result = await listOpportunities({\n category: category || undefined,\n limit: PAGE_SIZE,\n offset: nextOffset,\n });\n setOpportunities((current) => (append ? [...current, ...result] : result));\n setOffset(nextOffset);\n setHasMore(result.length === PAGE_SIZE);\n } catch (loadError) {\n setError(toErrorMessage(loadError, 'Sourcing opportunities could not be loaded.'));\n } finally {\n setLoading(false);\n }\n },\n [category, isEligible, listOpportunities]\n );\n\n useEffect(() => {\n void load();\n }, [load]);\n\n const applyCategory = (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setCategory(normalizeCategory(categoryInput));\n };\n\n const clearCategory = () => {\n setCategoryInput('');\n setCategory('');\n };\n\n return (\n <div className=\"min-h-full bg-surface-default\">\n <SourcingPageHeader\n title=\"Sourcing opportunities\"\n description=\"Respond to open buyer requests as your verified Store Publisher.\"\n icon={<PackageSearch className=\"size-5\" aria-hidden=\"true\" />}\n actions={\n <button\n type=\"button\"\n onClick={() => navigate(joinStorePath(basePath, 'publisher/sourcing/offers'))}\n className={secondaryButtonClassName}\n >\n <TicketCheck className=\"size-4\" aria-hidden=\"true\" />\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 Opportunities contain only the buyer's sanitized request details. Your offer must match\n the requested quantity and unit, use the Store's USD settlement currency, and promise\n delivery within the requested window. One active offer per publisher can be updated until\n 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 discover sourcing opportunities or submit offers.\"\n />\n ) : !isEligible ? (\n <ContextRequiredPanel\n title=\"Verified publisher status required\"\n description={`The publisher profile “${profile.name}” is currently ${profile.verificationStatus.toLowerCase().replaceAll('_', ' ')}. Opportunities become available after Store verification is active.`}\n />\n ) : (\n <>\n <div className=\"mb-5 rounded-xl border border-border-seam bg-surface-raised p-4\">\n <div className=\"flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between\">\n <form\n onSubmit={applyCategory}\n className=\"flex flex-col gap-2 sm:flex-row sm:items-end\"\n >\n <label className=\"block min-w-0 sm:w-72\">\n <span className=\"text-sm font-medium text-text-primary\">\n Filter by category\n </span>\n <div className=\"relative\">\n <Tags\n className=\"pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-text-tertiary\"\n aria-hidden=\"true\"\n />\n <input\n type=\"text\"\n value={categoryInput}\n onChange={(event) => setCategoryInput(event.target.value)}\n maxLength={64}\n placeholder=\"food-grains\"\n className={`${inputClassName} pl-9`}\n />\n </div>\n </label>\n <div className=\"flex gap-2\">\n <button type=\"submit\" className={primaryButtonClassName}>\n Apply\n </button>\n {category ? (\n <button\n type=\"button\"\n onClick={clearCategory}\n className={secondaryButtonClassName}\n >\n Clear\n </button>\n ) : null}\n </div>\n </form>\n\n <div className=\"flex flex-wrap items-center gap-3\">\n <span className=\"inline-flex items-center gap-1.5 text-sm text-text-secondary\">\n <BadgeCheck className=\"size-4 text-text-accent\" aria-hidden=\"true\" />\n Offering as {profile.name}\n </span>\n <button\n type=\"button\"\n onClick={() => void load()}\n disabled={loading}\n className={secondaryButtonClassName}\n >\n <RefreshCw\n className={`size-4 ${loading ? 'animate-spin' : ''}`}\n aria-hidden=\"true\"\n />\n Refresh\n </button>\n </div>\n </div>\n </div>\n\n {loading && opportunities.length === 0 ? (\n <SourcingLoadingState label=\"Loading open opportunities…\" />\n ) : error && opportunities.length === 0 ? (\n <SourcingErrorState\n title=\"Opportunities could not be loaded\"\n message={error}\n onRetry={() => void load()}\n />\n ) : opportunities.length === 0 ? (\n <SourcingEmptyState\n title={\n category ? 'No open opportunities in this category' : 'No open opportunities'\n }\n description={\n category\n ? 'Clear the category filter or check again later for new buyer requests.'\n : 'New sanitized requests from buyers will appear here while they are open.'\n }\n />\n ) : (\n <>\n {error ? (\n <div\n role=\"alert\"\n className=\"mb-4 rounded-lg border border-border-danger bg-surface-danger-muted px-4 py-3 text-sm text-text-danger\"\n >\n {error}\n </div>\n ) : null}\n <ul className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-3\">\n {opportunities.map((opportunity) => (\n <li key={opportunity.id}>\n <GlassCard className=\"flex h-full flex-col p-5\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"truncate text-xs font-semibold uppercase tracking-wide text-text-accent\">\n {opportunity.category}\n </p>\n <h2 className=\"mt-1 line-clamp-2 text-lg font-semibold text-text-primary\">\n {opportunity.productName}\n </h2>\n </div>\n <span className=\"rounded-full border border-status-success-border bg-status-success-bg-subtle px-2.5 py-1 text-xs font-semibold text-status-success-text\">\n OPEN\n </span>\n </div>\n\n {opportunity.summary ? (\n <p className=\"mt-3 line-clamp-3 text-sm leading-6 text-text-secondary\">\n {opportunity.summary}\n </p>\n ) : null}\n\n <dl className=\"mt-5 space-y-3 text-sm\">\n <div className=\"flex items-start gap-2\">\n <PackageSearch\n className=\"mt-0.5 size-4 shrink-0 text-text-tertiary\"\n aria-hidden=\"true\"\n />\n <div>\n <dt className=\"text-xs text-text-tertiary\">Quantity</dt>\n <dd className=\"font-medium text-text-primary\">\n {opportunity.quantity.toLocaleString()}{' '}\n {formatSourcingUnit(opportunity.unit)}\n </dd>\n </div>\n </div>\n <div className=\"flex items-start gap-2\">\n <CalendarDays\n className=\"mt-0.5 size-4 shrink-0 text-text-tertiary\"\n aria-hidden=\"true\"\n />\n <div>\n <dt className=\"text-xs text-text-tertiary\">Deliver by</dt>\n <dd className=\"font-medium text-text-primary\">\n {formatDate(opportunity.deliveryWindowStart)} –{' '}\n {formatDate(opportunity.deliveryWindowEnd)}\n </dd>\n </div>\n </div>\n <div className=\"flex items-start gap-2\">\n <MapPin\n className=\"mt-0.5 size-4 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=\"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\n <div className=\"mt-auto flex items-end justify-between gap-3 border-t border-border-seam pt-4\">\n <div>\n <p className=\"text-xs text-text-tertiary\">Buyer target</p>\n <p className=\"text-sm font-semibold text-text-primary\">\n {formatMoney(opportunity.targetUnitPrice, opportunity.targetCurrency)}\n </p>\n </div>\n <button\n type=\"button\"\n onClick={() =>\n navigate(\n joinStorePath(\n basePath,\n `publisher/sourcing/opportunities/${opportunity.id}`\n )\n )\n }\n className={secondaryButtonClassName}\n >\n View and offer\n <ArrowRight className=\"size-4\" aria-hidden=\"true\" />\n </button>\n </div>\n </GlassCard>\n </li>\n ))}\n </ul>\n\n {hasMore ? (\n <div className=\"mt-6 flex justify-center\">\n <button\n type=\"button\"\n onClick={() => void load(offset + PAGE_SIZE, true)}\n disabled={loading}\n className={secondaryButtonClassName}\n >\n {loading ? 'Loading…' : 'Load more'}\n </button>\n </div>\n ) : null}\n </>\n )}\n </>\n )}\n </main>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"SellerSourcingOpportunitiesPage.js","names":[],"sources":["../../src/pages/SellerSourcingOpportunitiesPage.tsx"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react';\nimport type { FC, FormEvent } from 'react';\nimport { useNavigate } from 'react-router';\nimport {\n ArrowRight,\n BadgeCheck,\n CalendarDays,\n MapPin,\n PackageSearch,\n RefreshCw,\n Tags,\n TicketCheck,\n} from 'lucide-react';\nimport { GlassCard, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { useStore } from '../providers/StoreProvider';\nimport { type SellerSourcingOpportunity, useSourcingApi } from '../hooks/useSourcing';\nimport { usePublisherSourcingAccess } from '../providers/SourcingAccessProvider';\nimport {\n ContextRequiredPanel,\n formatDate,\n formatLocation,\n formatMoney,\n formatSourcingUnit,\n inputClassName,\n joinStorePath,\n primaryButtonClassName,\n secondaryButtonClassName,\n SourcingEmptyState,\n SourcingErrorState,\n SourcingLoadingState,\n SourcingPageHeader,\n toErrorMessage,\n} from '../components/sourcing/SourcingUi';\n\nconst PAGE_SIZE = 30;\n\nfunction normalizeCategory(value: string): string {\n return value\n .trim()\n .toLowerCase()\n .replaceAll(/[_\\s]+/g, '-')\n .replaceAll(/-+/g, '-');\n}\n\nexport const SellerSourcingOpportunitiesPage: FC = () => {\n const navigate = useNavigate();\n const { basePath } = useStore();\n const {\n profile,\n loading: accessLoading,\n error: accessError,\n isEligible,\n refresh: refreshAccess,\n } = usePublisherSourcingAccess();\n const { listOpportunities } = useSourcingApi();\n const [opportunities, setOpportunities] = useState<SellerSourcingOpportunity[]>([]);\n const [categoryInput, setCategoryInput] = useState('');\n const [category, setCategory] = useState('');\n const [offset, setOffset] = useState(0);\n const [hasMore, setHasMore] = useState(false);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const load = useCallback(\n async (nextOffset = 0, append = false) => {\n if (!isEligible) return;\n setLoading(true);\n setError(null);\n try {\n const result = await listOpportunities({\n category: category || undefined,\n limit: PAGE_SIZE,\n offset: nextOffset,\n });\n setOpportunities((current) => (append ? [...current, ...result] : result));\n setOffset(nextOffset);\n setHasMore(result.length === PAGE_SIZE);\n } catch (loadError) {\n setError(toErrorMessage(loadError, 'Sourcing opportunities could not be loaded.'));\n } finally {\n setLoading(false);\n }\n },\n [category, isEligible, listOpportunities]\n );\n\n useEffect(() => {\n void load();\n }, [load]);\n\n const applyCategory = (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setCategory(normalizeCategory(categoryInput));\n };\n\n const clearCategory = () => {\n setCategoryInput('');\n setCategory('');\n };\n\n return (\n <div className=\"min-h-full bg-surface\">\n <SourcingPageHeader\n title=\"Sourcing opportunities\"\n description=\"Respond to open buyer requests as your verified Store Publisher.\"\n icon={<PackageSearch className=\"size-5\" aria-hidden=\"true\" />}\n actions={\n <button\n type=\"button\"\n onClick={() => navigate(joinStorePath(basePath, 'publisher/sourcing/offers'))}\n className={secondaryButtonClassName}\n >\n <TicketCheck className=\"size-4\" aria-hidden=\"true\" />\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 Opportunities contain only the buyer's sanitized request details. Your offer must match\n the requested quantity and unit, use the Store's USD settlement currency, and promise\n delivery within the requested window. One active offer per publisher can be updated until\n 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 discover sourcing opportunities or submit offers.\"\n />\n ) : !isEligible ? (\n <ContextRequiredPanel\n title=\"Verified publisher status required\"\n description={`The publisher profile “${profile.name}” is currently ${profile.verificationStatus.toLowerCase().replaceAll('_', ' ')}. Opportunities become available after Store verification is active.`}\n />\n ) : (\n <>\n <div className=\"mb-5 rounded-xl border border-border-subtle bg-surface-elevated p-4\">\n <div className=\"flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between\">\n <form\n onSubmit={applyCategory}\n className=\"flex flex-col gap-2 sm:flex-row sm:items-end\"\n >\n <label className=\"block min-w-0 sm:w-72\">\n <span className=\"text-sm font-medium text-text-primary\">\n Filter by category\n </span>\n <div className=\"relative\">\n <Tags\n className=\"pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-text-muted\"\n aria-hidden=\"true\"\n />\n <input\n type=\"text\"\n value={categoryInput}\n onChange={(event) => setCategoryInput(event.target.value)}\n maxLength={64}\n placeholder=\"food-grains\"\n className={`${inputClassName} pl-9`}\n />\n </div>\n </label>\n <div className=\"flex gap-2\">\n <button type=\"submit\" className={primaryButtonClassName}>\n Apply\n </button>\n {category ? (\n <button\n type=\"button\"\n onClick={clearCategory}\n className={secondaryButtonClassName}\n >\n Clear\n </button>\n ) : null}\n </div>\n </form>\n\n <div className=\"flex flex-wrap items-center gap-3\">\n <span className=\"inline-flex items-center gap-1.5 text-sm text-text-secondary\">\n <BadgeCheck className=\"size-4 text-accent-primary\" aria-hidden=\"true\" />\n Offering as {profile.name}\n </span>\n <button\n type=\"button\"\n onClick={() => void load()}\n disabled={loading}\n className={secondaryButtonClassName}\n >\n <RefreshCw\n className={`size-4 ${loading ? 'animate-spin' : ''}`}\n aria-hidden=\"true\"\n />\n Refresh\n </button>\n </div>\n </div>\n </div>\n\n {loading && opportunities.length === 0 ? (\n <SourcingLoadingState label=\"Loading open opportunities…\" />\n ) : error && opportunities.length === 0 ? (\n <SourcingErrorState\n title=\"Opportunities could not be loaded\"\n message={error}\n onRetry={() => void load()}\n />\n ) : opportunities.length === 0 ? (\n <SourcingEmptyState\n title={\n category ? 'No open opportunities in this category' : 'No open opportunities'\n }\n description={\n category\n ? 'Clear the category filter or check again later for new buyer requests.'\n : 'New sanitized requests from buyers will appear here while they are open.'\n }\n />\n ) : (\n <>\n {error ? (\n <div\n role=\"alert\"\n className=\"mb-4 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-4 py-3 text-sm text-status-error-text\"\n >\n {error}\n </div>\n ) : null}\n <ul className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-3\">\n {opportunities.map((opportunity) => (\n <li key={opportunity.id}>\n <GlassCard className=\"flex h-full flex-col p-5\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"truncate text-xs font-semibold uppercase tracking-wide text-accent-primary\">\n {opportunity.category}\n </p>\n <h2 className=\"mt-1 line-clamp-2 text-lg font-semibold text-text-primary\">\n {opportunity.productName}\n </h2>\n </div>\n <span className=\"rounded-full border border-status-success-border bg-status-success-bg-subtle px-2.5 py-1 text-xs font-semibold text-status-success-text\">\n OPEN\n </span>\n </div>\n\n {opportunity.summary ? (\n <p className=\"mt-3 line-clamp-3 text-sm leading-6 text-text-secondary\">\n {opportunity.summary}\n </p>\n ) : null}\n\n <dl className=\"mt-5 space-y-3 text-sm\">\n <div className=\"flex items-start gap-2\">\n <PackageSearch\n className=\"mt-0.5 size-4 shrink-0 text-text-muted\"\n aria-hidden=\"true\"\n />\n <div>\n <dt className=\"text-xs text-text-muted\">Quantity</dt>\n <dd className=\"font-medium text-text-primary\">\n {opportunity.quantity.toLocaleString()}{' '}\n {formatSourcingUnit(opportunity.unit)}\n </dd>\n </div>\n </div>\n <div className=\"flex items-start gap-2\">\n <CalendarDays\n className=\"mt-0.5 size-4 shrink-0 text-text-muted\"\n aria-hidden=\"true\"\n />\n <div>\n <dt className=\"text-xs text-text-muted\">Deliver by</dt>\n <dd className=\"font-medium text-text-primary\">\n {formatDate(opportunity.deliveryWindowStart)} –{' '}\n {formatDate(opportunity.deliveryWindowEnd)}\n </dd>\n </div>\n </div>\n <div className=\"flex items-start gap-2\">\n <MapPin\n className=\"mt-0.5 size-4 shrink-0 text-text-muted\"\n aria-hidden=\"true\"\n />\n <div>\n <dt className=\"text-xs text-text-muted\">Destination</dt>\n <dd className=\"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\n <div className=\"mt-auto flex items-end justify-between gap-3 border-t border-border-subtle pt-4\">\n <div>\n <p className=\"text-xs text-text-muted\">Buyer target</p>\n <p className=\"text-sm font-semibold text-text-primary\">\n {formatMoney(opportunity.targetUnitPrice, opportunity.targetCurrency)}\n </p>\n </div>\n <button\n type=\"button\"\n onClick={() =>\n navigate(\n joinStorePath(\n basePath,\n `publisher/sourcing/opportunities/${opportunity.id}`\n )\n )\n }\n className={secondaryButtonClassName}\n >\n View and offer\n <ArrowRight className=\"size-4\" aria-hidden=\"true\" />\n </button>\n </div>\n </GlassCard>\n </li>\n ))}\n </ul>\n\n {hasMore ? (\n <div className=\"mt-6 flex justify-center\">\n <button\n type=\"button\"\n onClick={() => void load(offset + PAGE_SIZE, true)}\n disabled={loading}\n className={secondaryButtonClassName}\n >\n {loading ? 'Loading…' : 'Load more'}\n </button>\n </div>\n ) : null}\n </>\n )}\n </>\n )}\n </main>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -80,12 +80,12 @@ var C = () => {
80
80
  let t = B[e];
81
81
  return t ? /* @__PURE__ */ y("p", {
82
82
  id: `${e}-error`,
83
- className: "mt-1 text-xs text-text-danger",
83
+ className: "mt-1 text-xs text-status-error-text",
84
84
  children: t
85
85
  }) : null;
86
86
  }, Ae = L && (!F || F.status === r.Active);
87
87
  return /* @__PURE__ */ b("div", {
88
- className: "min-h-full bg-surface-default",
88
+ className: "min-h-full bg-surface",
89
89
  children: [/* @__PURE__ */ y(ee, {
90
90
  title: P?.productName ?? "Sourcing opportunity",
91
91
  description: "Review the sanitized buyer request and create or update your publisher’s offer.",
@@ -116,7 +116,7 @@ var C = () => {
116
116
  }) : P ? /* @__PURE__ */ b(v, { children: [
117
117
  G ? /* @__PURE__ */ y("div", {
118
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",
119
+ className: "mb-5 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-4 py-3 text-sm text-status-error-text",
120
120
  children: G
121
121
  }) : null,
122
122
  q ? /* @__PURE__ */ b("div", {
@@ -147,7 +147,7 @@ var C = () => {
147
147
  F.order.status
148
148
  ]
149
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",
150
+ className: "rounded-full border border-border-default bg-surface-sunken px-3 py-1.5 text-xs font-medium text-text-secondary",
151
151
  children: ["Fulfillment ", F.order.fulfillment.status.replaceAll("_", " ")]
152
152
  }) : null]
153
153
  })
@@ -160,13 +160,13 @@ var C = () => {
160
160
  /* @__PURE__ */ b("div", {
161
161
  className: "flex flex-wrap items-start justify-between gap-3",
162
162
  children: [/* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
163
- className: "text-sm font-medium text-text-accent",
163
+ className: "text-sm font-medium text-accent-primary",
164
164
  children: P.category
165
165
  }), /* @__PURE__ */ y("h2", {
166
166
  className: "mt-1 text-xl font-semibold text-text-primary",
167
167
  children: P.productName
168
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"}`,
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-sunken text-text-secondary"}`,
170
170
  children: L ? "OPEN" : "CLOSED"
171
171
  })]
172
172
  }),
@@ -175,15 +175,15 @@ var C = () => {
175
175
  children: P.summary
176
176
  }) : null,
177
177
  /* @__PURE__ */ b("dl", {
178
- className: "mt-6 grid gap-5 border-t border-border-seam pt-5 sm:grid-cols-2",
178
+ className: "mt-6 grid gap-5 border-t border-border-subtle pt-5 sm:grid-cols-2",
179
179
  children: [
180
180
  /* @__PURE__ */ b("div", {
181
181
  className: "flex gap-3",
182
182
  children: [/* @__PURE__ */ y(ge, {
183
- className: "mt-0.5 size-5 shrink-0 text-text-tertiary",
183
+ className: "mt-0.5 size-5 shrink-0 text-text-muted",
184
184
  "aria-hidden": "true"
185
185
  }), /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("dt", {
186
- className: "text-xs text-text-tertiary",
186
+ className: "text-xs text-text-muted",
187
187
  children: "Required quantity"
188
188
  }), /* @__PURE__ */ b("dd", {
189
189
  className: "mt-0.5 font-medium text-text-primary",
@@ -197,10 +197,10 @@ var C = () => {
197
197
  /* @__PURE__ */ b("div", {
198
198
  className: "flex gap-3",
199
199
  children: [/* @__PURE__ */ y(pe, {
200
- className: "mt-0.5 size-5 shrink-0 text-text-tertiary",
200
+ className: "mt-0.5 size-5 shrink-0 text-text-muted",
201
201
  "aria-hidden": "true"
202
202
  }), /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("dt", {
203
- className: "text-xs text-text-tertiary",
203
+ className: "text-xs text-text-muted",
204
204
  children: "Buyer target"
205
205
  }), /* @__PURE__ */ y("dd", {
206
206
  className: "mt-0.5 font-medium text-text-primary",
@@ -210,10 +210,10 @@ var C = () => {
210
210
  /* @__PURE__ */ b("div", {
211
211
  className: "flex gap-3",
212
212
  children: [/* @__PURE__ */ y(de, {
213
- className: "mt-0.5 size-5 shrink-0 text-text-tertiary",
213
+ className: "mt-0.5 size-5 shrink-0 text-text-muted",
214
214
  "aria-hidden": "true"
215
215
  }), /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("dt", {
216
- className: "text-xs text-text-tertiary",
216
+ className: "text-xs text-text-muted",
217
217
  children: "Delivery window"
218
218
  }), /* @__PURE__ */ b("dd", {
219
219
  className: "mt-0.5 font-medium text-text-primary",
@@ -228,10 +228,10 @@ var C = () => {
228
228
  /* @__PURE__ */ b("div", {
229
229
  className: "flex gap-3",
230
230
  children: [/* @__PURE__ */ y(he, {
231
- className: "mt-0.5 size-5 shrink-0 text-text-tertiary",
231
+ className: "mt-0.5 size-5 shrink-0 text-text-muted",
232
232
  "aria-hidden": "true"
233
233
  }), /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("dt", {
234
- className: "text-xs text-text-tertiary",
234
+ className: "text-xs text-text-muted",
235
235
  children: "Destination"
236
236
  }), /* @__PURE__ */ y("dd", {
237
237
  className: "mt-0.5 font-medium text-text-primary",
@@ -257,10 +257,10 @@ var C = () => {
257
257
  className: "text-lg font-semibold text-text-primary",
258
258
  children: F ? "Update your offer" : "Create an offer"
259
259
  }), /* @__PURE__ */ b("p", {
260
- className: "mt-1 text-xs text-text-tertiary",
260
+ className: "mt-1 text-xs text-text-muted",
261
261
  children: ["Offering as ", T.name]
262
262
  })] }), /* @__PURE__ */ y(ue, {
263
- className: "size-5 text-text-accent",
263
+ className: "size-5 text-accent-primary",
264
264
  "aria-label": "Verified publisher"
265
265
  })]
266
266
  }),
@@ -286,7 +286,7 @@ var C = () => {
286
286
  className: `${d} mt-0`
287
287
  }), /* @__PURE__ */ y("span", {
288
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",
289
+ className: "mt-0 flex items-center justify-center rounded-md border border-border-default bg-surface-sunken px-3 text-sm font-semibold text-text-secondary",
290
290
  children: "USD"
291
291
  })]
292
292
  }),
@@ -331,7 +331,7 @@ var C = () => {
331
331
  "Link a published product",
332
332
  " ",
333
333
  /* @__PURE__ */ y("span", {
334
- className: "font-normal text-text-tertiary",
334
+ className: "font-normal text-text-muted",
335
335
  children: "(optional)"
336
336
  }),
337
337
  /* @__PURE__ */ b("select", {
@@ -351,7 +351,7 @@ var C = () => {
351
351
  O ? /* @__PURE__ */ b("div", {
352
352
  id: "store-product-error",
353
353
  role: "alert",
354
- className: "mt-2 flex flex-wrap items-center gap-2 text-xs text-text-danger",
354
+ className: "mt-2 flex flex-wrap items-center gap-2 text-xs text-status-error-text",
355
355
  children: [/* @__PURE__ */ y("span", { children: O }), /* @__PURE__ */ y("button", {
356
356
  type: "button",
357
357
  onClick: () => void Se(),
@@ -370,7 +370,7 @@ var C = () => {
370
370
  children: [
371
371
  "Message ",
372
372
  /* @__PURE__ */ y("span", {
373
- className: "font-normal text-text-tertiary",
373
+ className: "font-normal text-text-muted",
374
374
  children: "(optional)"
375
375
  }),
376
376
  /* @__PURE__ */ y("textarea", {
@@ -415,28 +415,28 @@ var C = () => {
415
415
  className: "text-lg font-semibold text-text-primary",
416
416
  children: "Your offer"
417
417
  }), /* @__PURE__ */ b("p", {
418
- className: "mt-1 text-xs text-text-tertiary",
418
+ className: "mt-1 text-xs text-text-muted",
419
419
  children: ["Updated ", s(F.updatedAt)]
420
420
  })] }), /* @__PURE__ */ y(te, { status: F.status })]
421
421
  }), /* @__PURE__ */ b("dl", {
422
422
  className: "mt-5 space-y-4 text-sm",
423
423
  children: [
424
424
  /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("dt", {
425
- className: "text-xs text-text-tertiary",
425
+ className: "text-xs text-text-muted",
426
426
  children: "Unit price"
427
427
  }), /* @__PURE__ */ y("dd", {
428
428
  className: "mt-0.5 text-lg font-semibold text-text-primary",
429
429
  children: c(F.unitPrice, F.currency)
430
430
  })] }),
431
431
  /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("dt", {
432
- className: "text-xs text-text-tertiary",
432
+ className: "text-xs text-text-muted",
433
433
  children: "Promised delivery"
434
434
  }), /* @__PURE__ */ y("dd", {
435
435
  className: "mt-0.5 font-medium text-text-primary",
436
436
  children: s(F.deliveryDate)
437
437
  })] }),
438
438
  F.message ? /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("dt", {
439
- className: "text-xs text-text-tertiary",
439
+ className: "text-xs text-text-muted",
440
440
  children: "Message"
441
441
  }), /* @__PURE__ */ y("dd", {
442
442
  className: "mt-1 whitespace-pre-wrap text-text-secondary",