@medialane/ui 0.146.0 → 0.147.0

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.
@@ -78,43 +78,46 @@ function AssetMarketplacePanel({
78
78
  onOpenRemix,
79
79
  onProposeDeal
80
80
  }) {
81
- const myBid = !isOwner && walletAddress ? activeBids.find((bid) => bid.offerer.toLowerCase() === walletAddress.toLowerCase()) ?? null : null;
82
- const canBuyMore = isERC1155 && isOwner && !!cheapest && !!walletAddress && cheapest.offerer.toLowerCase() !== walletAddress.toLowerCase();
83
- if (isMarketLoading && !cheapest) {
81
+ const liveBids = activeBids.filter((bid) => !(0, import_time.isExpired)(bid.endTime));
82
+ const liveCheapest = cheapest && !(0, import_time.isExpired)(cheapest.endTime) ? cheapest : void 0;
83
+ const liveMyListing = myListing && !(0, import_time.isExpired)(myListing.endTime) ? myListing : null;
84
+ const myBid = !isOwner && walletAddress ? liveBids.find((bid) => bid.offerer.toLowerCase() === walletAddress.toLowerCase()) ?? null : null;
85
+ const canBuyMore = isERC1155 && isOwner && !!liveCheapest && !!walletAddress && liveCheapest.offerer.toLowerCase() !== walletAddress.toLowerCase();
86
+ if (isMarketLoading && !liveCheapest) {
84
87
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-4", children: [
85
88
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-9 w-32 rounded-md bg-muted animate-pulse" }),
86
89
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-12 w-full rounded-2xl bg-muted animate-pulse" })
87
90
  ] });
88
91
  }
89
92
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "relative", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative space-y-4", children: [
90
- cheapest ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-4", children: [
93
+ liveCheapest ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-4", children: [
91
94
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
92
95
  import_dual_price.DualPrice,
93
96
  {
94
- amountFormatted: cheapest.price.formatted,
95
- currency: cheapest.price.currency,
97
+ amountFormatted: liveCheapest.price.formatted,
98
+ currency: liveCheapest.price.currency,
96
99
  usdValue,
97
100
  scale: "hero",
98
101
  trailing: renderHelp(
99
- `${isOwner && !canBuyMore ? "Your listing" : "Current price"} \xB7 Expires ${(0, import_time.timeUntil)(cheapest.endTime)}`
102
+ `${isOwner && !canBuyMore ? "Your listing" : "Current price"} \xB7 Expires ${(0, import_time.timeUntil)(liveCheapest.endTime)}`
100
103
  )
101
104
  }
102
105
  ),
103
106
  isOwner ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-2", children: [
104
107
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
105
- myListing ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
108
+ liveMyListing ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
106
109
  import_action_button.ActionButton,
107
110
  {
108
111
  big: true,
109
112
  icon: isProcessing ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.X, { className: "h-4 w-4" }),
110
- onClick: () => onCancelClick(myListing),
113
+ onClick: () => onCancelClick(liveMyListing),
111
114
  disabled: isProcessing,
112
115
  tone: "red",
113
116
  renderHelp,
114
- children: "Cancel Listing"
117
+ children: isERC1155 ? "Cancel My Listing" : "Cancel Listing"
115
118
  }
116
119
  ) : null,
117
- !myListing || isERC1155 ? listingRequiresEmailVerification ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_email_verification_gate.EmailVerificationGate, { reason: "list assets for sale", settingsHref }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_action_button.ActionButton, { big: true, tone: "blue", icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Tag, { className: "h-4 w-4" }), onClick: onOpenListing, renderHelp, children: "List on Marketplace" }) : null,
120
+ !liveMyListing || isERC1155 ? listingRequiresEmailVerification ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_email_verification_gate.EmailVerificationGate, { reason: "list assets for sale", settingsHref }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_action_button.ActionButton, { big: true, tone: "blue", icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Tag, { className: "h-4 w-4" }), onClick: onOpenListing, renderHelp, children: liveMyListing ? "List More Editions" : "List on Marketplace" }) : null,
118
121
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_action_button.ActionButton, { big: true, tone: "orange", icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ArrowRightLeft, { className: "h-4 w-4" }), onClick: onOpenTransfer, renderHelp, children: "Transfer" }),
119
122
  remixEnabled && onOpenRemix ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
120
123
  import_action_button.ActionButton,
@@ -144,13 +147,13 @@ function AssetMarketplacePanel({
144
147
  canBuyMore && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
145
148
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "border-t border-border/40 pt-2 mt-1" }),
146
149
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
147
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_action_button.ActionButton, { big: true, action: "buy", icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ShoppingCart, { className: "h-4 w-4" }), onClick: () => onOpenPurchase(cheapest), renderHelp, children: "Buy" }),
150
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_action_button.ActionButton, { big: true, action: "buy", icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ShoppingCart, { className: "h-4 w-4" }), onClick: () => onOpenPurchase(liveCheapest), renderHelp, children: "Buy" }),
148
151
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_action_button.ActionButton, { big: true, action: "offer", icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.HandCoins, { className: "h-4 w-4" }), onClick: onOpenOffer, renderHelp, children: "Make offer" })
149
152
  ] })
150
153
  ] })
151
154
  ] }) : isSignedIn ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
152
155
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
153
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_action_button.ActionButton, { big: true, action: "buy", icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ShoppingCart, { className: "h-4 w-4" }), onClick: () => onOpenPurchase(cheapest), renderHelp, children: "Buy" }),
156
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_action_button.ActionButton, { big: true, action: "buy", icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ShoppingCart, { className: "h-4 w-4" }), onClick: () => onOpenPurchase(liveCheapest), renderHelp, children: "Buy" }),
154
157
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_action_button.ActionButton, { big: true, action: "offer", icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.HandCoins, { className: "h-4 w-4" }), onClick: onOpenOffer, renderHelp, children: "Make offer" }),
155
158
  remixEnabled && onOpenRemix ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
156
159
  import_action_button.ActionButton,
@@ -276,13 +279,13 @@ function AssetMarketplacePanel({
276
279
  }
277
280
  )
278
281
  ] }) : null,
279
- isOwner && activeBids.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "rounded-xl bg-card/40 p-5 space-y-3", children: [
282
+ isOwner && liveBids.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "rounded-xl bg-card/40 p-5 space-y-3", children: [
280
283
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-xs font-semibold text-muted-foreground", children: [
281
284
  "Incoming offers (",
282
- activeBids.length,
285
+ liveBids.length,
283
286
  ")"
284
287
  ] }),
285
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "space-y-2", children: activeBids.map((bid) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center justify-between gap-3 rounded-lg bg-muted/30 px-3 py-2", children: [
288
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "space-y-2", children: liveBids.map((bid) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center justify-between gap-3 rounded-lg bg-muted/30 px-3 py-2", children: [
286
289
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "min-w-0", children: [
287
290
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm font-bold", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "inline-flex items-center gap-1.5", children: [
288
291
  (0, import_format.formatDisplayPrice)(bid.price.formatted),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/asset-marketplace-panel.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport {\n ArrowRightLeft, CheckCircle, Clock, GitBranch, HandCoins, Handshake, Loader2,\n ShoppingCart, Tag, X,\n} from \"lucide-react\";\nimport { CurrencyIcon, CurrencyAmount } from \"./currency-icon.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { ActionButton } from \"./action-button.js\";\nimport { DualPrice } from \"./dual-price.js\";\nimport { EmailVerificationGate } from \"./email-verification-gate.js\";\nimport { formatDisplayPrice, parsePriceDisplay } from \"../utils/format.js\";\nimport { timeUntil } from \"../utils/time.js\";\n\nexport interface ApiOrderLike {\n orderHash: string;\n offerer: string;\n endTime: string;\n price: { formatted: string | null; currency: string | null };\n}\n\nexport interface AssetMarketplacePanelProps<T extends ApiOrderLike = ApiOrderLike> {\n cheapest?: T;\n isOwner: boolean;\n isSignedIn: boolean;\n isProcessing: boolean;\n isERC1155: boolean;\n isMarketLoading?: boolean;\n myListing: T | null;\n activeBids: T[];\n walletAddress?: string | null;\n remixEnabled?: boolean;\n showDealOption?: boolean;\n\n usdValue?: string | null;\n\n renderAuthAction: (label: string) => ReactNode;\n\n renderHelp: (content: string) => ReactNode;\n onCancelClick: (order: T) => void;\n onAcceptBid: (order: T) => void;\n onOpenListing: () => void;\n onOpenTransfer: () => void;\n onOpenPurchase: (order: T) => void;\n onOpenOffer: () => void;\n onOpenRemix?: () => void;\n onProposeDeal?: () => void;\n\n showSponsorOption?: boolean;\n onOpenSponsorProposal?: () => void;\n\n showSponsorSolicitOption?: boolean;\n onOpenSponsorSolicit?: () => void;\n\n floorPriceRaw?: string | null;\n lastSaleRaw?: string | null;\n\n listingRequiresEmailVerification?: boolean;\n settingsHref?: string;\n}\n\nfunction StatRow({ floorPriceRaw, lastSaleRaw }: { floorPriceRaw?: string | null; lastSaleRaw?: string | null }) {\n const floor = floorPriceRaw ? parsePriceDisplay(floorPriceRaw) : null;\n const lastSale = lastSaleRaw ? parsePriceDisplay(lastSaleRaw) : null;\n if (!floor?.symbol && !lastSale?.symbol) return null;\n return (\n <div className=\"flex items-center gap-4 text-sm text-muted-foreground\">\n {floor?.symbol && (\n <span className=\"flex items-center gap-1.5\">\n <span>Floor</span>\n <CurrencyAmount amount={floor.numStr} symbol={floor.symbol} iconSize={12} amountClassName=\"text-foreground font-semibold\" />\n </span>\n )}\n {lastSale?.symbol && (\n <span className=\"flex items-center gap-1.5\">\n <span>Last sale</span>\n <CurrencyAmount amount={lastSale.numStr} symbol={lastSale.symbol} iconSize={12} amountClassName=\"text-foreground font-semibold\" />\n </span>\n )}\n </div>\n );\n}\n\nexport function AssetMarketplacePanel<T extends ApiOrderLike = ApiOrderLike>({\n cheapest,\n isOwner,\n isSignedIn,\n isProcessing,\n isERC1155,\n isMarketLoading = false,\n myListing,\n activeBids,\n walletAddress,\n remixEnabled = false,\n showDealOption = false,\n showSponsorOption = false,\n onOpenSponsorProposal,\n showSponsorSolicitOption = false,\n onOpenSponsorSolicit,\n floorPriceRaw,\n lastSaleRaw,\n usdValue,\n listingRequiresEmailVerification = false,\n settingsHref = \"/settings\",\n renderAuthAction,\n renderHelp,\n onCancelClick,\n onAcceptBid,\n onOpenListing,\n onOpenTransfer,\n onOpenPurchase,\n onOpenOffer,\n onOpenRemix,\n onProposeDeal,\n}: AssetMarketplacePanelProps<T>) {\n const myBid = !isOwner && walletAddress\n ? activeBids.find((bid) => bid.offerer.toLowerCase() === walletAddress.toLowerCase()) ?? null\n : null;\n\n const canBuyMore =\n isERC1155 && isOwner && !!cheapest && !!walletAddress &&\n cheapest.offerer.toLowerCase() !== walletAddress.toLowerCase();\n\n if (isMarketLoading && !cheapest) {\n return (\n <div className=\"space-y-4\">\n <div className=\"h-9 w-32 rounded-md bg-muted animate-pulse\" />\n <div className=\"h-12 w-full rounded-2xl bg-muted animate-pulse\" />\n </div>\n );\n }\n\n return (\n <div className=\"relative\">\n\n <div className=\"relative space-y-4\">\n {cheapest ? (\n <div className=\"space-y-4\">\n <DualPrice\n amountFormatted={cheapest.price.formatted}\n currency={cheapest.price.currency}\n usdValue={usdValue}\n scale=\"hero\"\n trailing={renderHelp(\n `${isOwner && !canBuyMore ? \"Your listing\" : \"Current price\"} · Expires ${timeUntil(cheapest.endTime)}`\n )}\n />\n\n {isOwner ? (\n <div className=\"space-y-2\">\n <div className=\"grid grid-cols-2 gap-2\">\n {myListing ? (\n <ActionButton big\n icon={isProcessing ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <X className=\"h-4 w-4\" />}\n onClick={() => onCancelClick(myListing)}\n disabled={isProcessing}\n tone=\"red\"\n renderHelp={renderHelp}\n >\n Cancel Listing\n </ActionButton>\n ) : null}\n\n {(!myListing || isERC1155) ? (\n listingRequiresEmailVerification ? (\n <EmailVerificationGate reason=\"list assets for sale\" settingsHref={settingsHref} />\n ) : (\n <ActionButton big tone=\"blue\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing} renderHelp={renderHelp}>List on Marketplace</ActionButton>\n )\n ) : null}\n <ActionButton big tone=\"orange\" icon={<ArrowRightLeft className=\"h-4 w-4\" />} onClick={onOpenTransfer} renderHelp={renderHelp}>Transfer</ActionButton>\n {remixEnabled && onOpenRemix ? (\n <ActionButton big\n action=\"remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Build a licensed derivative of this digital asset — your remix is minted as a new onchain NFT linked to the original\"\n renderHelp={renderHelp}\n >\n Remix\n </ActionButton>\n ) : null}\n {showSponsorSolicitOption && onOpenSponsorSolicit ? (\n <ActionButton big\n tone=\"blue\"\n icon={<Handshake className=\"h-4 w-4\" />}\n onClick={onOpenSponsorSolicit}\n helpContent=\"Let sponsors bid on a license for this asset.\"\n renderHelp={renderHelp}\n >\n Open for Sponsorship\n </ActionButton>\n ) : null}\n </div>\n\n {canBuyMore && (\n <>\n <div className=\"border-t border-border/40 pt-2 mt-1\" />\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton big action=\"buy\" icon={<ShoppingCart className=\"h-4 w-4\" />} onClick={() => onOpenPurchase(cheapest!)} renderHelp={renderHelp}>Buy</ActionButton>\n <ActionButton big action=\"offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer} renderHelp={renderHelp}>Make offer</ActionButton>\n </div>\n </>\n )}\n </div>\n ) : isSignedIn ? (\n <>\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton big action=\"buy\" icon={<ShoppingCart className=\"h-4 w-4\" />} onClick={() => onOpenPurchase(cheapest)} renderHelp={renderHelp}>Buy</ActionButton>\n <ActionButton big action=\"offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer} renderHelp={renderHelp}>Make offer</ActionButton>\n {remixEnabled && onOpenRemix ? (\n <ActionButton big\n action=\"remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Create your own attributed derivative of this work.\"\n renderHelp={renderHelp}\n >\n Remix\n </ActionButton>\n ) : null}\n {showDealOption && onProposeDeal ? (\n <ActionButton big\n action=\"license\"\n icon={<HandCoins className=\"h-4 w-4\" />}\n onClick={onProposeDeal}\n helpContent=\"Propose a license deal to the creator to use this work.\"\n renderHelp={renderHelp}\n >\n License\n </ActionButton>\n ) : null}\n {showSponsorOption && onOpenSponsorProposal ? (\n <ActionButton big\n tone=\"blue\"\n icon={<Handshake className=\"h-4 w-4\" />}\n onClick={onOpenSponsorProposal}\n helpContent=\"Propose to sponsor this creator's work — pay them directly for a license, no escrow.\"\n renderHelp={renderHelp}\n >\n Sponsor this IP\n </ActionButton>\n ) : null}\n </div>\n {!remixEnabled && !showDealOption ? (\n <p className=\"text-xs text-muted-foreground mt-2 leading-relaxed\">\n The creator marked this asset as no-derivatives.\n </p>\n ) : null}\n </>\n ) : (\n renderAuthAction(\"Sign in to trade\")\n )}\n </div>\n ) : (\n <div className=\"space-y-3\">\n <StatRow floorPriceRaw={floorPriceRaw} lastSaleRaw={lastSaleRaw} />\n {isOwner ? (\n <div className=\"grid grid-cols-2 gap-2\">\n {listingRequiresEmailVerification ? (\n <EmailVerificationGate reason=\"list assets for sale\" settingsHref={settingsHref} />\n ) : (\n <ActionButton big tone=\"blue\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing} renderHelp={renderHelp}>List on Marketplace</ActionButton>\n )}\n <ActionButton big tone=\"orange\" icon={<ArrowRightLeft className=\"h-4 w-4\" />} onClick={onOpenTransfer} renderHelp={renderHelp}>Transfer</ActionButton>\n {remixEnabled && onOpenRemix ? (\n <ActionButton big\n action=\"remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Build a licensed derivative of this digital asset — your remix is minted as a new onchain NFT linked to the original\"\n renderHelp={renderHelp}\n >\n Remix\n </ActionButton>\n ) : null}\n {showSponsorSolicitOption && onOpenSponsorSolicit ? (\n <ActionButton big\n tone=\"blue\"\n icon={<Handshake className=\"h-4 w-4\" />}\n onClick={onOpenSponsorSolicit}\n helpContent=\"Let sponsors bid on a license for this asset.\"\n renderHelp={renderHelp}\n >\n Open for Sponsorship\n </ActionButton>\n ) : null}\n </div>\n ) : isSignedIn ? (\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton big action=\"offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer} renderHelp={renderHelp}>Make offer</ActionButton>\n {remixEnabled && onOpenRemix ? (\n <ActionButton big\n action=\"remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Build a licensed derivative of this digital asset — your remix is minted as a new onchain NFT linked to the original\"\n renderHelp={renderHelp}\n >\n Remix\n </ActionButton>\n ) : null}\n {showSponsorOption && onOpenSponsorProposal ? (\n <ActionButton big\n tone=\"blue\"\n icon={<Handshake className=\"h-4 w-4\" />}\n onClick={onOpenSponsorProposal}\n helpContent=\"Propose to sponsor this creator's work — pay them directly for a license, no escrow.\"\n renderHelp={renderHelp}\n >\n Sponsor this IP\n </ActionButton>\n ) : null}\n </div>\n ) : (\n renderAuthAction(\"Sign in to make an offer\")\n )}\n </div>\n )}\n\n {myBid ? (\n <div className=\"rounded-xl bg-amber-500/8 px-4 py-3 flex items-center justify-between gap-3\">\n <div className=\"min-w-0 flex items-center gap-2.5\">\n <HandCoins className=\"h-4 w-4 text-amber-500 shrink-0\" />\n <div className=\"min-w-0\">\n <p className=\"text-xs font-semibold text-amber-500\">Your active offer</p>\n <p className=\"text-xs text-muted-foreground flex items-center gap-1.5 mt-0.5\">\n <span className=\"font-bold text-foreground inline-flex items-center gap-1\">\n {formatDisplayPrice(myBid.price.formatted)}\n <CurrencyIcon symbol={myBid.price.currency ?? \"\"} size={12} />\n </span>\n <span>·</span>\n <Clock className=\"h-3 w-3\" />\n {timeUntil(myBid.endTime)}\n </p>\n </div>\n </div>\n <button\n className=\"shrink-0 text-xs font-semibold text-red-400 hover:text-red-300 transition-colors flex items-center gap-1\"\n onClick={() => onCancelClick(myBid)}\n >\n <X className=\"h-3.5 w-3.5\" />\n Cancel\n </button>\n </div>\n ) : null}\n\n {isOwner && activeBids.length > 0 ? (\n <div className=\"rounded-xl bg-card/40 p-5 space-y-3\">\n <p className=\"text-xs font-semibold text-muted-foreground\">\n Incoming offers ({activeBids.length})\n </p>\n <div className=\"space-y-2\">\n {activeBids.map((bid) => (\n <div key={bid.orderHash} className=\"flex items-center justify-between gap-3 rounded-lg bg-muted/30 px-3 py-2\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-bold\">\n <span className=\"inline-flex items-center gap-1.5\">\n {formatDisplayPrice(bid.price.formatted)}\n <CurrencyIcon symbol={bid.price.currency ?? \"\"} size={14} />\n </span>\n </p>\n <div className=\"flex items-center gap-2 mt-0.5\">\n <AddressDisplay address={bid.offerer} chars={4} showCopy={false} className=\"text-xs text-muted-foreground\" />\n <span className=\"text-xs text-muted-foreground\">·</span>\n <div className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n <Clock className=\"h-3 w-3\" />\n {timeUntil(bid.endTime)}\n </div>\n </div>\n </div>\n <button\n disabled={isProcessing}\n onClick={() => onAcceptBid(bid)}\n className=\"inline-flex items-center gap-1.5 rounded-lg bg-primary px-3 py-1.5 text-xs font-semibold text-primary-foreground disabled:opacity-50\"\n >\n <CheckCircle className=\"h-3.5 w-3.5\" />\n Accept\n </button>\n </div>\n ))}\n </div>\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/asset-marketplace-panel.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport {\n ArrowRightLeft, CheckCircle, Clock, GitBranch, HandCoins, Handshake, Loader2,\n ShoppingCart, Tag, X,\n} from \"lucide-react\";\nimport { CurrencyIcon, CurrencyAmount } from \"./currency-icon.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { ActionButton } from \"./action-button.js\";\nimport { DualPrice } from \"./dual-price.js\";\nimport { EmailVerificationGate } from \"./email-verification-gate.js\";\nimport { formatDisplayPrice, parsePriceDisplay } from \"../utils/format.js\";\nimport { isExpired, timeUntil } from \"../utils/time.js\";\n\nexport interface ApiOrderLike {\n orderHash: string;\n offerer: string;\n endTime: string;\n price: { formatted: string | null; currency: string | null };\n}\n\nexport interface AssetMarketplacePanelProps<T extends ApiOrderLike = ApiOrderLike> {\n cheapest?: T;\n isOwner: boolean;\n isSignedIn: boolean;\n isProcessing: boolean;\n isERC1155: boolean;\n isMarketLoading?: boolean;\n myListing: T | null;\n activeBids: T[];\n walletAddress?: string | null;\n remixEnabled?: boolean;\n showDealOption?: boolean;\n\n usdValue?: string | null;\n\n renderAuthAction: (label: string) => ReactNode;\n\n renderHelp: (content: string) => ReactNode;\n onCancelClick: (order: T) => void;\n onAcceptBid: (order: T) => void;\n onOpenListing: () => void;\n onOpenTransfer: () => void;\n onOpenPurchase: (order: T) => void;\n onOpenOffer: () => void;\n onOpenRemix?: () => void;\n onProposeDeal?: () => void;\n\n showSponsorOption?: boolean;\n onOpenSponsorProposal?: () => void;\n\n showSponsorSolicitOption?: boolean;\n onOpenSponsorSolicit?: () => void;\n\n floorPriceRaw?: string | null;\n lastSaleRaw?: string | null;\n\n listingRequiresEmailVerification?: boolean;\n settingsHref?: string;\n}\n\nfunction StatRow({ floorPriceRaw, lastSaleRaw }: { floorPriceRaw?: string | null; lastSaleRaw?: string | null }) {\n const floor = floorPriceRaw ? parsePriceDisplay(floorPriceRaw) : null;\n const lastSale = lastSaleRaw ? parsePriceDisplay(lastSaleRaw) : null;\n if (!floor?.symbol && !lastSale?.symbol) return null;\n return (\n <div className=\"flex items-center gap-4 text-sm text-muted-foreground\">\n {floor?.symbol && (\n <span className=\"flex items-center gap-1.5\">\n <span>Floor</span>\n <CurrencyAmount amount={floor.numStr} symbol={floor.symbol} iconSize={12} amountClassName=\"text-foreground font-semibold\" />\n </span>\n )}\n {lastSale?.symbol && (\n <span className=\"flex items-center gap-1.5\">\n <span>Last sale</span>\n <CurrencyAmount amount={lastSale.numStr} symbol={lastSale.symbol} iconSize={12} amountClassName=\"text-foreground font-semibold\" />\n </span>\n )}\n </div>\n );\n}\n\nexport function AssetMarketplacePanel<T extends ApiOrderLike = ApiOrderLike>({\n cheapest,\n isOwner,\n isSignedIn,\n isProcessing,\n isERC1155,\n isMarketLoading = false,\n myListing,\n activeBids,\n walletAddress,\n remixEnabled = false,\n showDealOption = false,\n showSponsorOption = false,\n onOpenSponsorProposal,\n showSponsorSolicitOption = false,\n onOpenSponsorSolicit,\n floorPriceRaw,\n lastSaleRaw,\n usdValue,\n listingRequiresEmailVerification = false,\n settingsHref = \"/settings\",\n renderAuthAction,\n renderHelp,\n onCancelClick,\n onAcceptBid,\n onOpenListing,\n onOpenTransfer,\n onOpenPurchase,\n onOpenOffer,\n onOpenRemix,\n onProposeDeal,\n}: AssetMarketplacePanelProps<T>) {\n // The indexer marks orders EXPIRED on a slow sweep, so a client can hold one\n // that lapsed minutes ago. Every action below is derived from the live set\n // rather than from status, because filling a lapsed order reverts on chain\n // and the gas for that revert is sponsored.\n const liveBids = activeBids.filter((bid) => !isExpired(bid.endTime));\n const liveCheapest = cheapest && !isExpired(cheapest.endTime) ? cheapest : undefined;\n const liveMyListing = myListing && !isExpired(myListing.endTime) ? myListing : null;\n\n const myBid = !isOwner && walletAddress\n ? liveBids.find((bid) => bid.offerer.toLowerCase() === walletAddress.toLowerCase()) ?? null\n : null;\n\n const canBuyMore =\n isERC1155 && isOwner && !!liveCheapest && !!walletAddress &&\n liveCheapest.offerer.toLowerCase() !== walletAddress.toLowerCase();\n\n if (isMarketLoading && !liveCheapest) {\n return (\n <div className=\"space-y-4\">\n <div className=\"h-9 w-32 rounded-md bg-muted animate-pulse\" />\n <div className=\"h-12 w-full rounded-2xl bg-muted animate-pulse\" />\n </div>\n );\n }\n\n return (\n <div className=\"relative\">\n\n <div className=\"relative space-y-4\">\n {liveCheapest ? (\n <div className=\"space-y-4\">\n <DualPrice\n amountFormatted={liveCheapest.price.formatted}\n currency={liveCheapest.price.currency}\n usdValue={usdValue}\n scale=\"hero\"\n trailing={renderHelp(\n `${isOwner && !canBuyMore ? \"Your listing\" : \"Current price\"} · Expires ${timeUntil(liveCheapest.endTime)}`\n )}\n />\n\n {isOwner ? (\n <div className=\"space-y-2\">\n <div className=\"grid grid-cols-2 gap-2\">\n {liveMyListing ? (\n <ActionButton big\n icon={isProcessing ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <X className=\"h-4 w-4\" />}\n onClick={() => onCancelClick(liveMyListing)}\n disabled={isProcessing}\n tone=\"red\"\n renderHelp={renderHelp}\n >\n {isERC1155 ? \"Cancel My Listing\" : \"Cancel Listing\"}\n </ActionButton>\n ) : null}\n\n {(!liveMyListing || isERC1155) ? (\n listingRequiresEmailVerification ? (\n <EmailVerificationGate reason=\"list assets for sale\" settingsHref={settingsHref} />\n ) : (\n <ActionButton big tone=\"blue\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing} renderHelp={renderHelp}>\n {liveMyListing ? \"List More Editions\" : \"List on Marketplace\"}\n </ActionButton>\n )\n ) : null}\n <ActionButton big tone=\"orange\" icon={<ArrowRightLeft className=\"h-4 w-4\" />} onClick={onOpenTransfer} renderHelp={renderHelp}>Transfer</ActionButton>\n {remixEnabled && onOpenRemix ? (\n <ActionButton big\n action=\"remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Build a licensed derivative of this digital asset — your remix is minted as a new onchain NFT linked to the original\"\n renderHelp={renderHelp}\n >\n Remix\n </ActionButton>\n ) : null}\n {showSponsorSolicitOption && onOpenSponsorSolicit ? (\n <ActionButton big\n tone=\"blue\"\n icon={<Handshake className=\"h-4 w-4\" />}\n onClick={onOpenSponsorSolicit}\n helpContent=\"Let sponsors bid on a license for this asset.\"\n renderHelp={renderHelp}\n >\n Open for Sponsorship\n </ActionButton>\n ) : null}\n </div>\n\n {canBuyMore && (\n <>\n <div className=\"border-t border-border/40 pt-2 mt-1\" />\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton big action=\"buy\" icon={<ShoppingCart className=\"h-4 w-4\" />} onClick={() => onOpenPurchase(liveCheapest!)} renderHelp={renderHelp}>Buy</ActionButton>\n <ActionButton big action=\"offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer} renderHelp={renderHelp}>Make offer</ActionButton>\n </div>\n </>\n )}\n </div>\n ) : isSignedIn ? (\n <>\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton big action=\"buy\" icon={<ShoppingCart className=\"h-4 w-4\" />} onClick={() => onOpenPurchase(liveCheapest)} renderHelp={renderHelp}>Buy</ActionButton>\n <ActionButton big action=\"offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer} renderHelp={renderHelp}>Make offer</ActionButton>\n {remixEnabled && onOpenRemix ? (\n <ActionButton big\n action=\"remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Create your own attributed derivative of this work.\"\n renderHelp={renderHelp}\n >\n Remix\n </ActionButton>\n ) : null}\n {showDealOption && onProposeDeal ? (\n <ActionButton big\n action=\"license\"\n icon={<HandCoins className=\"h-4 w-4\" />}\n onClick={onProposeDeal}\n helpContent=\"Propose a license deal to the creator to use this work.\"\n renderHelp={renderHelp}\n >\n License\n </ActionButton>\n ) : null}\n {showSponsorOption && onOpenSponsorProposal ? (\n <ActionButton big\n tone=\"blue\"\n icon={<Handshake className=\"h-4 w-4\" />}\n onClick={onOpenSponsorProposal}\n helpContent=\"Propose to sponsor this creator's work — pay them directly for a license, no escrow.\"\n renderHelp={renderHelp}\n >\n Sponsor this IP\n </ActionButton>\n ) : null}\n </div>\n {!remixEnabled && !showDealOption ? (\n <p className=\"text-xs text-muted-foreground mt-2 leading-relaxed\">\n The creator marked this asset as no-derivatives.\n </p>\n ) : null}\n </>\n ) : (\n renderAuthAction(\"Sign in to trade\")\n )}\n </div>\n ) : (\n <div className=\"space-y-3\">\n <StatRow floorPriceRaw={floorPriceRaw} lastSaleRaw={lastSaleRaw} />\n {isOwner ? (\n <div className=\"grid grid-cols-2 gap-2\">\n {listingRequiresEmailVerification ? (\n <EmailVerificationGate reason=\"list assets for sale\" settingsHref={settingsHref} />\n ) : (\n <ActionButton big tone=\"blue\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing} renderHelp={renderHelp}>List on Marketplace</ActionButton>\n )}\n <ActionButton big tone=\"orange\" icon={<ArrowRightLeft className=\"h-4 w-4\" />} onClick={onOpenTransfer} renderHelp={renderHelp}>Transfer</ActionButton>\n {remixEnabled && onOpenRemix ? (\n <ActionButton big\n action=\"remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Build a licensed derivative of this digital asset — your remix is minted as a new onchain NFT linked to the original\"\n renderHelp={renderHelp}\n >\n Remix\n </ActionButton>\n ) : null}\n {showSponsorSolicitOption && onOpenSponsorSolicit ? (\n <ActionButton big\n tone=\"blue\"\n icon={<Handshake className=\"h-4 w-4\" />}\n onClick={onOpenSponsorSolicit}\n helpContent=\"Let sponsors bid on a license for this asset.\"\n renderHelp={renderHelp}\n >\n Open for Sponsorship\n </ActionButton>\n ) : null}\n </div>\n ) : isSignedIn ? (\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton big action=\"offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer} renderHelp={renderHelp}>Make offer</ActionButton>\n {remixEnabled && onOpenRemix ? (\n <ActionButton big\n action=\"remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Build a licensed derivative of this digital asset — your remix is minted as a new onchain NFT linked to the original\"\n renderHelp={renderHelp}\n >\n Remix\n </ActionButton>\n ) : null}\n {showSponsorOption && onOpenSponsorProposal ? (\n <ActionButton big\n tone=\"blue\"\n icon={<Handshake className=\"h-4 w-4\" />}\n onClick={onOpenSponsorProposal}\n helpContent=\"Propose to sponsor this creator's work — pay them directly for a license, no escrow.\"\n renderHelp={renderHelp}\n >\n Sponsor this IP\n </ActionButton>\n ) : null}\n </div>\n ) : (\n renderAuthAction(\"Sign in to make an offer\")\n )}\n </div>\n )}\n\n {myBid ? (\n <div className=\"rounded-xl bg-amber-500/8 px-4 py-3 flex items-center justify-between gap-3\">\n <div className=\"min-w-0 flex items-center gap-2.5\">\n <HandCoins className=\"h-4 w-4 text-amber-500 shrink-0\" />\n <div className=\"min-w-0\">\n <p className=\"text-xs font-semibold text-amber-500\">Your active offer</p>\n <p className=\"text-xs text-muted-foreground flex items-center gap-1.5 mt-0.5\">\n <span className=\"font-bold text-foreground inline-flex items-center gap-1\">\n {formatDisplayPrice(myBid.price.formatted)}\n <CurrencyIcon symbol={myBid.price.currency ?? \"\"} size={12} />\n </span>\n <span>·</span>\n <Clock className=\"h-3 w-3\" />\n {timeUntil(myBid.endTime)}\n </p>\n </div>\n </div>\n <button\n className=\"shrink-0 text-xs font-semibold text-red-400 hover:text-red-300 transition-colors flex items-center gap-1\"\n onClick={() => onCancelClick(myBid)}\n >\n <X className=\"h-3.5 w-3.5\" />\n Cancel\n </button>\n </div>\n ) : null}\n\n {isOwner && liveBids.length > 0 ? (\n <div className=\"rounded-xl bg-card/40 p-5 space-y-3\">\n <p className=\"text-xs font-semibold text-muted-foreground\">\n Incoming offers ({liveBids.length})\n </p>\n <div className=\"space-y-2\">\n {liveBids.map((bid) => (\n <div key={bid.orderHash} className=\"flex items-center justify-between gap-3 rounded-lg bg-muted/30 px-3 py-2\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-bold\">\n <span className=\"inline-flex items-center gap-1.5\">\n {formatDisplayPrice(bid.price.formatted)}\n <CurrencyIcon symbol={bid.price.currency ?? \"\"} size={14} />\n </span>\n </p>\n <div className=\"flex items-center gap-2 mt-0.5\">\n <AddressDisplay address={bid.offerer} chars={4} showCopy={false} className=\"text-xs text-muted-foreground\" />\n <span className=\"text-xs text-muted-foreground\">·</span>\n <div className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n <Clock className=\"h-3 w-3\" />\n {timeUntil(bid.endTime)}\n </div>\n </div>\n </div>\n <button\n disabled={isProcessing}\n onClick={() => onAcceptBid(bid)}\n className=\"inline-flex items-center gap-1.5 rounded-lg bg-primary px-3 py-1.5 text-xs font-semibold text-primary-foreground disabled:opacity-50\"\n >\n <CheckCircle className=\"h-3.5 w-3.5\" />\n Accept\n </button>\n </div>\n ))}\n </div>\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
@@ -18,7 +18,7 @@ import { ActionButton } from "./action-button.js";
18
18
  import { DualPrice } from "./dual-price.js";
19
19
  import { EmailVerificationGate } from "./email-verification-gate.js";
20
20
  import { formatDisplayPrice, parsePriceDisplay } from "../utils/format.js";
21
- import { timeUntil } from "../utils/time.js";
21
+ import { isExpired, timeUntil } from "../utils/time.js";
22
22
  function StatRow({ floorPriceRaw, lastSaleRaw }) {
23
23
  const floor = floorPriceRaw ? parsePriceDisplay(floorPriceRaw) : null;
24
24
  const lastSale = lastSaleRaw ? parsePriceDisplay(lastSaleRaw) : null;
@@ -66,43 +66,46 @@ function AssetMarketplacePanel({
66
66
  onOpenRemix,
67
67
  onProposeDeal
68
68
  }) {
69
- const myBid = !isOwner && walletAddress ? activeBids.find((bid) => bid.offerer.toLowerCase() === walletAddress.toLowerCase()) ?? null : null;
70
- const canBuyMore = isERC1155 && isOwner && !!cheapest && !!walletAddress && cheapest.offerer.toLowerCase() !== walletAddress.toLowerCase();
71
- if (isMarketLoading && !cheapest) {
69
+ const liveBids = activeBids.filter((bid) => !isExpired(bid.endTime));
70
+ const liveCheapest = cheapest && !isExpired(cheapest.endTime) ? cheapest : void 0;
71
+ const liveMyListing = myListing && !isExpired(myListing.endTime) ? myListing : null;
72
+ const myBid = !isOwner && walletAddress ? liveBids.find((bid) => bid.offerer.toLowerCase() === walletAddress.toLowerCase()) ?? null : null;
73
+ const canBuyMore = isERC1155 && isOwner && !!liveCheapest && !!walletAddress && liveCheapest.offerer.toLowerCase() !== walletAddress.toLowerCase();
74
+ if (isMarketLoading && !liveCheapest) {
72
75
  return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
73
76
  /* @__PURE__ */ jsx("div", { className: "h-9 w-32 rounded-md bg-muted animate-pulse" }),
74
77
  /* @__PURE__ */ jsx("div", { className: "h-12 w-full rounded-2xl bg-muted animate-pulse" })
75
78
  ] });
76
79
  }
77
80
  return /* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsxs("div", { className: "relative space-y-4", children: [
78
- cheapest ? /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
81
+ liveCheapest ? /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
79
82
  /* @__PURE__ */ jsx(
80
83
  DualPrice,
81
84
  {
82
- amountFormatted: cheapest.price.formatted,
83
- currency: cheapest.price.currency,
85
+ amountFormatted: liveCheapest.price.formatted,
86
+ currency: liveCheapest.price.currency,
84
87
  usdValue,
85
88
  scale: "hero",
86
89
  trailing: renderHelp(
87
- `${isOwner && !canBuyMore ? "Your listing" : "Current price"} \xB7 Expires ${timeUntil(cheapest.endTime)}`
90
+ `${isOwner && !canBuyMore ? "Your listing" : "Current price"} \xB7 Expires ${timeUntil(liveCheapest.endTime)}`
88
91
  )
89
92
  }
90
93
  ),
91
94
  isOwner ? /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
92
95
  /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
93
- myListing ? /* @__PURE__ */ jsx(
96
+ liveMyListing ? /* @__PURE__ */ jsx(
94
97
  ActionButton,
95
98
  {
96
99
  big: true,
97
100
  icon: isProcessing ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(X, { className: "h-4 w-4" }),
98
- onClick: () => onCancelClick(myListing),
101
+ onClick: () => onCancelClick(liveMyListing),
99
102
  disabled: isProcessing,
100
103
  tone: "red",
101
104
  renderHelp,
102
- children: "Cancel Listing"
105
+ children: isERC1155 ? "Cancel My Listing" : "Cancel Listing"
103
106
  }
104
107
  ) : null,
105
- !myListing || isERC1155 ? listingRequiresEmailVerification ? /* @__PURE__ */ jsx(EmailVerificationGate, { reason: "list assets for sale", settingsHref }) : /* @__PURE__ */ jsx(ActionButton, { big: true, tone: "blue", icon: /* @__PURE__ */ jsx(Tag, { className: "h-4 w-4" }), onClick: onOpenListing, renderHelp, children: "List on Marketplace" }) : null,
108
+ !liveMyListing || isERC1155 ? listingRequiresEmailVerification ? /* @__PURE__ */ jsx(EmailVerificationGate, { reason: "list assets for sale", settingsHref }) : /* @__PURE__ */ jsx(ActionButton, { big: true, tone: "blue", icon: /* @__PURE__ */ jsx(Tag, { className: "h-4 w-4" }), onClick: onOpenListing, renderHelp, children: liveMyListing ? "List More Editions" : "List on Marketplace" }) : null,
106
109
  /* @__PURE__ */ jsx(ActionButton, { big: true, tone: "orange", icon: /* @__PURE__ */ jsx(ArrowRightLeft, { className: "h-4 w-4" }), onClick: onOpenTransfer, renderHelp, children: "Transfer" }),
107
110
  remixEnabled && onOpenRemix ? /* @__PURE__ */ jsx(
108
111
  ActionButton,
@@ -132,13 +135,13 @@ function AssetMarketplacePanel({
132
135
  canBuyMore && /* @__PURE__ */ jsxs(Fragment, { children: [
133
136
  /* @__PURE__ */ jsx("div", { className: "border-t border-border/40 pt-2 mt-1" }),
134
137
  /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
135
- /* @__PURE__ */ jsx(ActionButton, { big: true, action: "buy", icon: /* @__PURE__ */ jsx(ShoppingCart, { className: "h-4 w-4" }), onClick: () => onOpenPurchase(cheapest), renderHelp, children: "Buy" }),
138
+ /* @__PURE__ */ jsx(ActionButton, { big: true, action: "buy", icon: /* @__PURE__ */ jsx(ShoppingCart, { className: "h-4 w-4" }), onClick: () => onOpenPurchase(liveCheapest), renderHelp, children: "Buy" }),
136
139
  /* @__PURE__ */ jsx(ActionButton, { big: true, action: "offer", icon: /* @__PURE__ */ jsx(HandCoins, { className: "h-4 w-4" }), onClick: onOpenOffer, renderHelp, children: "Make offer" })
137
140
  ] })
138
141
  ] })
139
142
  ] }) : isSignedIn ? /* @__PURE__ */ jsxs(Fragment, { children: [
140
143
  /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
141
- /* @__PURE__ */ jsx(ActionButton, { big: true, action: "buy", icon: /* @__PURE__ */ jsx(ShoppingCart, { className: "h-4 w-4" }), onClick: () => onOpenPurchase(cheapest), renderHelp, children: "Buy" }),
144
+ /* @__PURE__ */ jsx(ActionButton, { big: true, action: "buy", icon: /* @__PURE__ */ jsx(ShoppingCart, { className: "h-4 w-4" }), onClick: () => onOpenPurchase(liveCheapest), renderHelp, children: "Buy" }),
142
145
  /* @__PURE__ */ jsx(ActionButton, { big: true, action: "offer", icon: /* @__PURE__ */ jsx(HandCoins, { className: "h-4 w-4" }), onClick: onOpenOffer, renderHelp, children: "Make offer" }),
143
146
  remixEnabled && onOpenRemix ? /* @__PURE__ */ jsx(
144
147
  ActionButton,
@@ -264,13 +267,13 @@ function AssetMarketplacePanel({
264
267
  }
265
268
  )
266
269
  ] }) : null,
267
- isOwner && activeBids.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-xl bg-card/40 p-5 space-y-3", children: [
270
+ isOwner && liveBids.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-xl bg-card/40 p-5 space-y-3", children: [
268
271
  /* @__PURE__ */ jsxs("p", { className: "text-xs font-semibold text-muted-foreground", children: [
269
272
  "Incoming offers (",
270
- activeBids.length,
273
+ liveBids.length,
271
274
  ")"
272
275
  ] }),
273
- /* @__PURE__ */ jsx("div", { className: "space-y-2", children: activeBids.map((bid) => /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 rounded-lg bg-muted/30 px-3 py-2", children: [
276
+ /* @__PURE__ */ jsx("div", { className: "space-y-2", children: liveBids.map((bid) => /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 rounded-lg bg-muted/30 px-3 py-2", children: [
274
277
  /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
275
278
  /* @__PURE__ */ jsx("p", { className: "text-sm font-bold", children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5", children: [
276
279
  formatDisplayPrice(bid.price.formatted),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/asset-marketplace-panel.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport {\n ArrowRightLeft, CheckCircle, Clock, GitBranch, HandCoins, Handshake, Loader2,\n ShoppingCart, Tag, X,\n} from \"lucide-react\";\nimport { CurrencyIcon, CurrencyAmount } from \"./currency-icon.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { ActionButton } from \"./action-button.js\";\nimport { DualPrice } from \"./dual-price.js\";\nimport { EmailVerificationGate } from \"./email-verification-gate.js\";\nimport { formatDisplayPrice, parsePriceDisplay } from \"../utils/format.js\";\nimport { timeUntil } from \"../utils/time.js\";\n\nexport interface ApiOrderLike {\n orderHash: string;\n offerer: string;\n endTime: string;\n price: { formatted: string | null; currency: string | null };\n}\n\nexport interface AssetMarketplacePanelProps<T extends ApiOrderLike = ApiOrderLike> {\n cheapest?: T;\n isOwner: boolean;\n isSignedIn: boolean;\n isProcessing: boolean;\n isERC1155: boolean;\n isMarketLoading?: boolean;\n myListing: T | null;\n activeBids: T[];\n walletAddress?: string | null;\n remixEnabled?: boolean;\n showDealOption?: boolean;\n\n usdValue?: string | null;\n\n renderAuthAction: (label: string) => ReactNode;\n\n renderHelp: (content: string) => ReactNode;\n onCancelClick: (order: T) => void;\n onAcceptBid: (order: T) => void;\n onOpenListing: () => void;\n onOpenTransfer: () => void;\n onOpenPurchase: (order: T) => void;\n onOpenOffer: () => void;\n onOpenRemix?: () => void;\n onProposeDeal?: () => void;\n\n showSponsorOption?: boolean;\n onOpenSponsorProposal?: () => void;\n\n showSponsorSolicitOption?: boolean;\n onOpenSponsorSolicit?: () => void;\n\n floorPriceRaw?: string | null;\n lastSaleRaw?: string | null;\n\n listingRequiresEmailVerification?: boolean;\n settingsHref?: string;\n}\n\nfunction StatRow({ floorPriceRaw, lastSaleRaw }: { floorPriceRaw?: string | null; lastSaleRaw?: string | null }) {\n const floor = floorPriceRaw ? parsePriceDisplay(floorPriceRaw) : null;\n const lastSale = lastSaleRaw ? parsePriceDisplay(lastSaleRaw) : null;\n if (!floor?.symbol && !lastSale?.symbol) return null;\n return (\n <div className=\"flex items-center gap-4 text-sm text-muted-foreground\">\n {floor?.symbol && (\n <span className=\"flex items-center gap-1.5\">\n <span>Floor</span>\n <CurrencyAmount amount={floor.numStr} symbol={floor.symbol} iconSize={12} amountClassName=\"text-foreground font-semibold\" />\n </span>\n )}\n {lastSale?.symbol && (\n <span className=\"flex items-center gap-1.5\">\n <span>Last sale</span>\n <CurrencyAmount amount={lastSale.numStr} symbol={lastSale.symbol} iconSize={12} amountClassName=\"text-foreground font-semibold\" />\n </span>\n )}\n </div>\n );\n}\n\nexport function AssetMarketplacePanel<T extends ApiOrderLike = ApiOrderLike>({\n cheapest,\n isOwner,\n isSignedIn,\n isProcessing,\n isERC1155,\n isMarketLoading = false,\n myListing,\n activeBids,\n walletAddress,\n remixEnabled = false,\n showDealOption = false,\n showSponsorOption = false,\n onOpenSponsorProposal,\n showSponsorSolicitOption = false,\n onOpenSponsorSolicit,\n floorPriceRaw,\n lastSaleRaw,\n usdValue,\n listingRequiresEmailVerification = false,\n settingsHref = \"/settings\",\n renderAuthAction,\n renderHelp,\n onCancelClick,\n onAcceptBid,\n onOpenListing,\n onOpenTransfer,\n onOpenPurchase,\n onOpenOffer,\n onOpenRemix,\n onProposeDeal,\n}: AssetMarketplacePanelProps<T>) {\n const myBid = !isOwner && walletAddress\n ? activeBids.find((bid) => bid.offerer.toLowerCase() === walletAddress.toLowerCase()) ?? null\n : null;\n\n const canBuyMore =\n isERC1155 && isOwner && !!cheapest && !!walletAddress &&\n cheapest.offerer.toLowerCase() !== walletAddress.toLowerCase();\n\n if (isMarketLoading && !cheapest) {\n return (\n <div className=\"space-y-4\">\n <div className=\"h-9 w-32 rounded-md bg-muted animate-pulse\" />\n <div className=\"h-12 w-full rounded-2xl bg-muted animate-pulse\" />\n </div>\n );\n }\n\n return (\n <div className=\"relative\">\n\n <div className=\"relative space-y-4\">\n {cheapest ? (\n <div className=\"space-y-4\">\n <DualPrice\n amountFormatted={cheapest.price.formatted}\n currency={cheapest.price.currency}\n usdValue={usdValue}\n scale=\"hero\"\n trailing={renderHelp(\n `${isOwner && !canBuyMore ? \"Your listing\" : \"Current price\"} · Expires ${timeUntil(cheapest.endTime)}`\n )}\n />\n\n {isOwner ? (\n <div className=\"space-y-2\">\n <div className=\"grid grid-cols-2 gap-2\">\n {myListing ? (\n <ActionButton big\n icon={isProcessing ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <X className=\"h-4 w-4\" />}\n onClick={() => onCancelClick(myListing)}\n disabled={isProcessing}\n tone=\"red\"\n renderHelp={renderHelp}\n >\n Cancel Listing\n </ActionButton>\n ) : null}\n\n {(!myListing || isERC1155) ? (\n listingRequiresEmailVerification ? (\n <EmailVerificationGate reason=\"list assets for sale\" settingsHref={settingsHref} />\n ) : (\n <ActionButton big tone=\"blue\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing} renderHelp={renderHelp}>List on Marketplace</ActionButton>\n )\n ) : null}\n <ActionButton big tone=\"orange\" icon={<ArrowRightLeft className=\"h-4 w-4\" />} onClick={onOpenTransfer} renderHelp={renderHelp}>Transfer</ActionButton>\n {remixEnabled && onOpenRemix ? (\n <ActionButton big\n action=\"remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Build a licensed derivative of this digital asset — your remix is minted as a new onchain NFT linked to the original\"\n renderHelp={renderHelp}\n >\n Remix\n </ActionButton>\n ) : null}\n {showSponsorSolicitOption && onOpenSponsorSolicit ? (\n <ActionButton big\n tone=\"blue\"\n icon={<Handshake className=\"h-4 w-4\" />}\n onClick={onOpenSponsorSolicit}\n helpContent=\"Let sponsors bid on a license for this asset.\"\n renderHelp={renderHelp}\n >\n Open for Sponsorship\n </ActionButton>\n ) : null}\n </div>\n\n {canBuyMore && (\n <>\n <div className=\"border-t border-border/40 pt-2 mt-1\" />\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton big action=\"buy\" icon={<ShoppingCart className=\"h-4 w-4\" />} onClick={() => onOpenPurchase(cheapest!)} renderHelp={renderHelp}>Buy</ActionButton>\n <ActionButton big action=\"offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer} renderHelp={renderHelp}>Make offer</ActionButton>\n </div>\n </>\n )}\n </div>\n ) : isSignedIn ? (\n <>\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton big action=\"buy\" icon={<ShoppingCart className=\"h-4 w-4\" />} onClick={() => onOpenPurchase(cheapest)} renderHelp={renderHelp}>Buy</ActionButton>\n <ActionButton big action=\"offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer} renderHelp={renderHelp}>Make offer</ActionButton>\n {remixEnabled && onOpenRemix ? (\n <ActionButton big\n action=\"remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Create your own attributed derivative of this work.\"\n renderHelp={renderHelp}\n >\n Remix\n </ActionButton>\n ) : null}\n {showDealOption && onProposeDeal ? (\n <ActionButton big\n action=\"license\"\n icon={<HandCoins className=\"h-4 w-4\" />}\n onClick={onProposeDeal}\n helpContent=\"Propose a license deal to the creator to use this work.\"\n renderHelp={renderHelp}\n >\n License\n </ActionButton>\n ) : null}\n {showSponsorOption && onOpenSponsorProposal ? (\n <ActionButton big\n tone=\"blue\"\n icon={<Handshake className=\"h-4 w-4\" />}\n onClick={onOpenSponsorProposal}\n helpContent=\"Propose to sponsor this creator's work — pay them directly for a license, no escrow.\"\n renderHelp={renderHelp}\n >\n Sponsor this IP\n </ActionButton>\n ) : null}\n </div>\n {!remixEnabled && !showDealOption ? (\n <p className=\"text-xs text-muted-foreground mt-2 leading-relaxed\">\n The creator marked this asset as no-derivatives.\n </p>\n ) : null}\n </>\n ) : (\n renderAuthAction(\"Sign in to trade\")\n )}\n </div>\n ) : (\n <div className=\"space-y-3\">\n <StatRow floorPriceRaw={floorPriceRaw} lastSaleRaw={lastSaleRaw} />\n {isOwner ? (\n <div className=\"grid grid-cols-2 gap-2\">\n {listingRequiresEmailVerification ? (\n <EmailVerificationGate reason=\"list assets for sale\" settingsHref={settingsHref} />\n ) : (\n <ActionButton big tone=\"blue\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing} renderHelp={renderHelp}>List on Marketplace</ActionButton>\n )}\n <ActionButton big tone=\"orange\" icon={<ArrowRightLeft className=\"h-4 w-4\" />} onClick={onOpenTransfer} renderHelp={renderHelp}>Transfer</ActionButton>\n {remixEnabled && onOpenRemix ? (\n <ActionButton big\n action=\"remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Build a licensed derivative of this digital asset — your remix is minted as a new onchain NFT linked to the original\"\n renderHelp={renderHelp}\n >\n Remix\n </ActionButton>\n ) : null}\n {showSponsorSolicitOption && onOpenSponsorSolicit ? (\n <ActionButton big\n tone=\"blue\"\n icon={<Handshake className=\"h-4 w-4\" />}\n onClick={onOpenSponsorSolicit}\n helpContent=\"Let sponsors bid on a license for this asset.\"\n renderHelp={renderHelp}\n >\n Open for Sponsorship\n </ActionButton>\n ) : null}\n </div>\n ) : isSignedIn ? (\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton big action=\"offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer} renderHelp={renderHelp}>Make offer</ActionButton>\n {remixEnabled && onOpenRemix ? (\n <ActionButton big\n action=\"remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Build a licensed derivative of this digital asset — your remix is minted as a new onchain NFT linked to the original\"\n renderHelp={renderHelp}\n >\n Remix\n </ActionButton>\n ) : null}\n {showSponsorOption && onOpenSponsorProposal ? (\n <ActionButton big\n tone=\"blue\"\n icon={<Handshake className=\"h-4 w-4\" />}\n onClick={onOpenSponsorProposal}\n helpContent=\"Propose to sponsor this creator's work — pay them directly for a license, no escrow.\"\n renderHelp={renderHelp}\n >\n Sponsor this IP\n </ActionButton>\n ) : null}\n </div>\n ) : (\n renderAuthAction(\"Sign in to make an offer\")\n )}\n </div>\n )}\n\n {myBid ? (\n <div className=\"rounded-xl bg-amber-500/8 px-4 py-3 flex items-center justify-between gap-3\">\n <div className=\"min-w-0 flex items-center gap-2.5\">\n <HandCoins className=\"h-4 w-4 text-amber-500 shrink-0\" />\n <div className=\"min-w-0\">\n <p className=\"text-xs font-semibold text-amber-500\">Your active offer</p>\n <p className=\"text-xs text-muted-foreground flex items-center gap-1.5 mt-0.5\">\n <span className=\"font-bold text-foreground inline-flex items-center gap-1\">\n {formatDisplayPrice(myBid.price.formatted)}\n <CurrencyIcon symbol={myBid.price.currency ?? \"\"} size={12} />\n </span>\n <span>·</span>\n <Clock className=\"h-3 w-3\" />\n {timeUntil(myBid.endTime)}\n </p>\n </div>\n </div>\n <button\n className=\"shrink-0 text-xs font-semibold text-red-400 hover:text-red-300 transition-colors flex items-center gap-1\"\n onClick={() => onCancelClick(myBid)}\n >\n <X className=\"h-3.5 w-3.5\" />\n Cancel\n </button>\n </div>\n ) : null}\n\n {isOwner && activeBids.length > 0 ? (\n <div className=\"rounded-xl bg-card/40 p-5 space-y-3\">\n <p className=\"text-xs font-semibold text-muted-foreground\">\n Incoming offers ({activeBids.length})\n </p>\n <div className=\"space-y-2\">\n {activeBids.map((bid) => (\n <div key={bid.orderHash} className=\"flex items-center justify-between gap-3 rounded-lg bg-muted/30 px-3 py-2\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-bold\">\n <span className=\"inline-flex items-center gap-1.5\">\n {formatDisplayPrice(bid.price.formatted)}\n <CurrencyIcon symbol={bid.price.currency ?? \"\"} size={14} />\n </span>\n </p>\n <div className=\"flex items-center gap-2 mt-0.5\">\n <AddressDisplay address={bid.offerer} chars={4} showCopy={false} className=\"text-xs text-muted-foreground\" />\n <span className=\"text-xs text-muted-foreground\">·</span>\n <div className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n <Clock className=\"h-3 w-3\" />\n {timeUntil(bid.endTime)}\n </div>\n </div>\n </div>\n <button\n disabled={isProcessing}\n onClick={() => onAcceptBid(bid)}\n className=\"inline-flex items-center gap-1.5 rounded-lg bg-primary px-3 py-1.5 text-xs font-semibold text-primary-foreground disabled:opacity-50\"\n >\n <CheckCircle className=\"h-3.5 w-3.5\" />\n Accept\n </button>\n </div>\n ))}\n </div>\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/asset-marketplace-panel.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport {\n ArrowRightLeft, CheckCircle, Clock, GitBranch, HandCoins, Handshake, Loader2,\n ShoppingCart, Tag, X,\n} from \"lucide-react\";\nimport { CurrencyIcon, CurrencyAmount } from \"./currency-icon.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { ActionButton } from \"./action-button.js\";\nimport { DualPrice } from \"./dual-price.js\";\nimport { EmailVerificationGate } from \"./email-verification-gate.js\";\nimport { formatDisplayPrice, parsePriceDisplay } from \"../utils/format.js\";\nimport { isExpired, timeUntil } from \"../utils/time.js\";\n\nexport interface ApiOrderLike {\n orderHash: string;\n offerer: string;\n endTime: string;\n price: { formatted: string | null; currency: string | null };\n}\n\nexport interface AssetMarketplacePanelProps<T extends ApiOrderLike = ApiOrderLike> {\n cheapest?: T;\n isOwner: boolean;\n isSignedIn: boolean;\n isProcessing: boolean;\n isERC1155: boolean;\n isMarketLoading?: boolean;\n myListing: T | null;\n activeBids: T[];\n walletAddress?: string | null;\n remixEnabled?: boolean;\n showDealOption?: boolean;\n\n usdValue?: string | null;\n\n renderAuthAction: (label: string) => ReactNode;\n\n renderHelp: (content: string) => ReactNode;\n onCancelClick: (order: T) => void;\n onAcceptBid: (order: T) => void;\n onOpenListing: () => void;\n onOpenTransfer: () => void;\n onOpenPurchase: (order: T) => void;\n onOpenOffer: () => void;\n onOpenRemix?: () => void;\n onProposeDeal?: () => void;\n\n showSponsorOption?: boolean;\n onOpenSponsorProposal?: () => void;\n\n showSponsorSolicitOption?: boolean;\n onOpenSponsorSolicit?: () => void;\n\n floorPriceRaw?: string | null;\n lastSaleRaw?: string | null;\n\n listingRequiresEmailVerification?: boolean;\n settingsHref?: string;\n}\n\nfunction StatRow({ floorPriceRaw, lastSaleRaw }: { floorPriceRaw?: string | null; lastSaleRaw?: string | null }) {\n const floor = floorPriceRaw ? parsePriceDisplay(floorPriceRaw) : null;\n const lastSale = lastSaleRaw ? parsePriceDisplay(lastSaleRaw) : null;\n if (!floor?.symbol && !lastSale?.symbol) return null;\n return (\n <div className=\"flex items-center gap-4 text-sm text-muted-foreground\">\n {floor?.symbol && (\n <span className=\"flex items-center gap-1.5\">\n <span>Floor</span>\n <CurrencyAmount amount={floor.numStr} symbol={floor.symbol} iconSize={12} amountClassName=\"text-foreground font-semibold\" />\n </span>\n )}\n {lastSale?.symbol && (\n <span className=\"flex items-center gap-1.5\">\n <span>Last sale</span>\n <CurrencyAmount amount={lastSale.numStr} symbol={lastSale.symbol} iconSize={12} amountClassName=\"text-foreground font-semibold\" />\n </span>\n )}\n </div>\n );\n}\n\nexport function AssetMarketplacePanel<T extends ApiOrderLike = ApiOrderLike>({\n cheapest,\n isOwner,\n isSignedIn,\n isProcessing,\n isERC1155,\n isMarketLoading = false,\n myListing,\n activeBids,\n walletAddress,\n remixEnabled = false,\n showDealOption = false,\n showSponsorOption = false,\n onOpenSponsorProposal,\n showSponsorSolicitOption = false,\n onOpenSponsorSolicit,\n floorPriceRaw,\n lastSaleRaw,\n usdValue,\n listingRequiresEmailVerification = false,\n settingsHref = \"/settings\",\n renderAuthAction,\n renderHelp,\n onCancelClick,\n onAcceptBid,\n onOpenListing,\n onOpenTransfer,\n onOpenPurchase,\n onOpenOffer,\n onOpenRemix,\n onProposeDeal,\n}: AssetMarketplacePanelProps<T>) {\n // The indexer marks orders EXPIRED on a slow sweep, so a client can hold one\n // that lapsed minutes ago. Every action below is derived from the live set\n // rather than from status, because filling a lapsed order reverts on chain\n // and the gas for that revert is sponsored.\n const liveBids = activeBids.filter((bid) => !isExpired(bid.endTime));\n const liveCheapest = cheapest && !isExpired(cheapest.endTime) ? cheapest : undefined;\n const liveMyListing = myListing && !isExpired(myListing.endTime) ? myListing : null;\n\n const myBid = !isOwner && walletAddress\n ? liveBids.find((bid) => bid.offerer.toLowerCase() === walletAddress.toLowerCase()) ?? null\n : null;\n\n const canBuyMore =\n isERC1155 && isOwner && !!liveCheapest && !!walletAddress &&\n liveCheapest.offerer.toLowerCase() !== walletAddress.toLowerCase();\n\n if (isMarketLoading && !liveCheapest) {\n return (\n <div className=\"space-y-4\">\n <div className=\"h-9 w-32 rounded-md bg-muted animate-pulse\" />\n <div className=\"h-12 w-full rounded-2xl bg-muted animate-pulse\" />\n </div>\n );\n }\n\n return (\n <div className=\"relative\">\n\n <div className=\"relative space-y-4\">\n {liveCheapest ? (\n <div className=\"space-y-4\">\n <DualPrice\n amountFormatted={liveCheapest.price.formatted}\n currency={liveCheapest.price.currency}\n usdValue={usdValue}\n scale=\"hero\"\n trailing={renderHelp(\n `${isOwner && !canBuyMore ? \"Your listing\" : \"Current price\"} · Expires ${timeUntil(liveCheapest.endTime)}`\n )}\n />\n\n {isOwner ? (\n <div className=\"space-y-2\">\n <div className=\"grid grid-cols-2 gap-2\">\n {liveMyListing ? (\n <ActionButton big\n icon={isProcessing ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <X className=\"h-4 w-4\" />}\n onClick={() => onCancelClick(liveMyListing)}\n disabled={isProcessing}\n tone=\"red\"\n renderHelp={renderHelp}\n >\n {isERC1155 ? \"Cancel My Listing\" : \"Cancel Listing\"}\n </ActionButton>\n ) : null}\n\n {(!liveMyListing || isERC1155) ? (\n listingRequiresEmailVerification ? (\n <EmailVerificationGate reason=\"list assets for sale\" settingsHref={settingsHref} />\n ) : (\n <ActionButton big tone=\"blue\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing} renderHelp={renderHelp}>\n {liveMyListing ? \"List More Editions\" : \"List on Marketplace\"}\n </ActionButton>\n )\n ) : null}\n <ActionButton big tone=\"orange\" icon={<ArrowRightLeft className=\"h-4 w-4\" />} onClick={onOpenTransfer} renderHelp={renderHelp}>Transfer</ActionButton>\n {remixEnabled && onOpenRemix ? (\n <ActionButton big\n action=\"remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Build a licensed derivative of this digital asset — your remix is minted as a new onchain NFT linked to the original\"\n renderHelp={renderHelp}\n >\n Remix\n </ActionButton>\n ) : null}\n {showSponsorSolicitOption && onOpenSponsorSolicit ? (\n <ActionButton big\n tone=\"blue\"\n icon={<Handshake className=\"h-4 w-4\" />}\n onClick={onOpenSponsorSolicit}\n helpContent=\"Let sponsors bid on a license for this asset.\"\n renderHelp={renderHelp}\n >\n Open for Sponsorship\n </ActionButton>\n ) : null}\n </div>\n\n {canBuyMore && (\n <>\n <div className=\"border-t border-border/40 pt-2 mt-1\" />\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton big action=\"buy\" icon={<ShoppingCart className=\"h-4 w-4\" />} onClick={() => onOpenPurchase(liveCheapest!)} renderHelp={renderHelp}>Buy</ActionButton>\n <ActionButton big action=\"offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer} renderHelp={renderHelp}>Make offer</ActionButton>\n </div>\n </>\n )}\n </div>\n ) : isSignedIn ? (\n <>\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton big action=\"buy\" icon={<ShoppingCart className=\"h-4 w-4\" />} onClick={() => onOpenPurchase(liveCheapest)} renderHelp={renderHelp}>Buy</ActionButton>\n <ActionButton big action=\"offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer} renderHelp={renderHelp}>Make offer</ActionButton>\n {remixEnabled && onOpenRemix ? (\n <ActionButton big\n action=\"remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Create your own attributed derivative of this work.\"\n renderHelp={renderHelp}\n >\n Remix\n </ActionButton>\n ) : null}\n {showDealOption && onProposeDeal ? (\n <ActionButton big\n action=\"license\"\n icon={<HandCoins className=\"h-4 w-4\" />}\n onClick={onProposeDeal}\n helpContent=\"Propose a license deal to the creator to use this work.\"\n renderHelp={renderHelp}\n >\n License\n </ActionButton>\n ) : null}\n {showSponsorOption && onOpenSponsorProposal ? (\n <ActionButton big\n tone=\"blue\"\n icon={<Handshake className=\"h-4 w-4\" />}\n onClick={onOpenSponsorProposal}\n helpContent=\"Propose to sponsor this creator's work — pay them directly for a license, no escrow.\"\n renderHelp={renderHelp}\n >\n Sponsor this IP\n </ActionButton>\n ) : null}\n </div>\n {!remixEnabled && !showDealOption ? (\n <p className=\"text-xs text-muted-foreground mt-2 leading-relaxed\">\n The creator marked this asset as no-derivatives.\n </p>\n ) : null}\n </>\n ) : (\n renderAuthAction(\"Sign in to trade\")\n )}\n </div>\n ) : (\n <div className=\"space-y-3\">\n <StatRow floorPriceRaw={floorPriceRaw} lastSaleRaw={lastSaleRaw} />\n {isOwner ? (\n <div className=\"grid grid-cols-2 gap-2\">\n {listingRequiresEmailVerification ? (\n <EmailVerificationGate reason=\"list assets for sale\" settingsHref={settingsHref} />\n ) : (\n <ActionButton big tone=\"blue\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing} renderHelp={renderHelp}>List on Marketplace</ActionButton>\n )}\n <ActionButton big tone=\"orange\" icon={<ArrowRightLeft className=\"h-4 w-4\" />} onClick={onOpenTransfer} renderHelp={renderHelp}>Transfer</ActionButton>\n {remixEnabled && onOpenRemix ? (\n <ActionButton big\n action=\"remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Build a licensed derivative of this digital asset — your remix is minted as a new onchain NFT linked to the original\"\n renderHelp={renderHelp}\n >\n Remix\n </ActionButton>\n ) : null}\n {showSponsorSolicitOption && onOpenSponsorSolicit ? (\n <ActionButton big\n tone=\"blue\"\n icon={<Handshake className=\"h-4 w-4\" />}\n onClick={onOpenSponsorSolicit}\n helpContent=\"Let sponsors bid on a license for this asset.\"\n renderHelp={renderHelp}\n >\n Open for Sponsorship\n </ActionButton>\n ) : null}\n </div>\n ) : isSignedIn ? (\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton big action=\"offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer} renderHelp={renderHelp}>Make offer</ActionButton>\n {remixEnabled && onOpenRemix ? (\n <ActionButton big\n action=\"remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Build a licensed derivative of this digital asset — your remix is minted as a new onchain NFT linked to the original\"\n renderHelp={renderHelp}\n >\n Remix\n </ActionButton>\n ) : null}\n {showSponsorOption && onOpenSponsorProposal ? (\n <ActionButton big\n tone=\"blue\"\n icon={<Handshake className=\"h-4 w-4\" />}\n onClick={onOpenSponsorProposal}\n helpContent=\"Propose to sponsor this creator's work — pay them directly for a license, no escrow.\"\n renderHelp={renderHelp}\n >\n Sponsor this IP\n </ActionButton>\n ) : null}\n </div>\n ) : (\n renderAuthAction(\"Sign in to make an offer\")\n )}\n </div>\n )}\n\n {myBid ? (\n <div className=\"rounded-xl bg-amber-500/8 px-4 py-3 flex items-center justify-between gap-3\">\n <div className=\"min-w-0 flex items-center gap-2.5\">\n <HandCoins className=\"h-4 w-4 text-amber-500 shrink-0\" />\n <div className=\"min-w-0\">\n <p className=\"text-xs font-semibold text-amber-500\">Your active offer</p>\n <p className=\"text-xs text-muted-foreground flex items-center gap-1.5 mt-0.5\">\n <span className=\"font-bold text-foreground inline-flex items-center gap-1\">\n {formatDisplayPrice(myBid.price.formatted)}\n <CurrencyIcon symbol={myBid.price.currency ?? \"\"} size={12} />\n </span>\n <span>·</span>\n <Clock className=\"h-3 w-3\" />\n {timeUntil(myBid.endTime)}\n </p>\n </div>\n </div>\n <button\n className=\"shrink-0 text-xs font-semibold text-red-400 hover:text-red-300 transition-colors flex items-center gap-1\"\n onClick={() => onCancelClick(myBid)}\n >\n <X className=\"h-3.5 w-3.5\" />\n Cancel\n </button>\n </div>\n ) : null}\n\n {isOwner && liveBids.length > 0 ? (\n <div className=\"rounded-xl bg-card/40 p-5 space-y-3\">\n <p className=\"text-xs font-semibold text-muted-foreground\">\n Incoming offers ({liveBids.length})\n </p>\n <div className=\"space-y-2\">\n {liveBids.map((bid) => (\n <div key={bid.orderHash} className=\"flex items-center justify-between gap-3 rounded-lg bg-muted/30 px-3 py-2\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-bold\">\n <span className=\"inline-flex items-center gap-1.5\">\n {formatDisplayPrice(bid.price.formatted)}\n <CurrencyIcon symbol={bid.price.currency ?? \"\"} size={14} />\n </span>\n </p>\n <div className=\"flex items-center gap-2 mt-0.5\">\n <AddressDisplay address={bid.offerer} chars={4} showCopy={false} className=\"text-xs text-muted-foreground\" />\n <span className=\"text-xs text-muted-foreground\">·</span>\n <div className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n <Clock className=\"h-3 w-3\" />\n {timeUntil(bid.endTime)}\n </div>\n </div>\n </div>\n <button\n disabled={isProcessing}\n onClick={() => onAcceptBid(bid)}\n className=\"inline-flex items-center gap-1.5 rounded-lg bg-primary px-3 py-1.5 text-xs font-semibold text-primary-foreground disabled:opacity-50\"\n >\n <CheckCircle className=\"h-3.5 w-3.5\" />\n Accept\n </button>\n </div>\n ))}\n </div>\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
@@ -26,8 +26,13 @@ var import_jsx_runtime = require("react/jsx-runtime");
26
26
  var import_lucide_react = require("lucide-react");
27
27
  var import_medialane_collection_card = require("./medialane-collection-card.js");
28
28
  var import_drop_status_display = require("./drop-status-display.js");
29
- var import_drop_countdown = require("./drop-countdown.js");
30
29
  var import_drop_status = require("../utils/drop-status.js");
30
+ function formatTs(ts) {
31
+ return new Date(ts * 1e3).toLocaleString(void 0, {
32
+ dateStyle: "medium",
33
+ timeStyle: "short"
34
+ });
35
+ }
31
36
  function DropPreviewCard({
32
37
  coverImage,
33
38
  name,
@@ -40,17 +45,21 @@ function DropPreviewCard({
40
45
  gatedContentEnabled
41
46
  }) {
42
47
  const status = (0, import_drop_status.getDropStatus)(conditions, 0);
48
+ const maxPerWallet = conditions ? parseInt(conditions.maxPerWallet, 10) : 0;
43
49
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-3", children: [
44
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
45
- import_medialane_collection_card.MedialaneCollectionCard,
46
- {
47
- image: coverImage,
48
- name,
49
- collection: symbol || "Drop",
50
- creator: creatorAddress,
51
- creatorHref
52
- }
53
- ),
50
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative", children: [
51
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
52
+ import_medialane_collection_card.MedialaneCollectionCard,
53
+ {
54
+ image: coverImage,
55
+ name,
56
+ collection: symbol || "Drop",
57
+ creator: creatorAddress,
58
+ creatorHref
59
+ }
60
+ ),
61
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "absolute top-4 right-4 text-[9px] font-bold uppercase tracking-widest text-white bg-black/50 backdrop-blur-sm rounded-full px-2 py-0.5", children: "Drop" })
62
+ ] }),
54
63
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bento-cell p-4 space-y-3", children: [
55
64
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2 flex-wrap", children: [
56
65
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_drop_status_display.DropStatusBadge, { status }),
@@ -64,11 +73,29 @@ function DropPreviewCard({
64
73
  ] })
65
74
  ] }),
66
75
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_drop_status_display.DropSupplyProgress, { minted: 0, max: itemCount }),
67
- conditions && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2 text-sm", children: [
68
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ShieldCheck, { className: "h-3.5 w-3.5 text-muted-foreground" }),
69
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_drop_status_display.DropPriceDisplay, { conditions })
76
+ conditions && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center justify-between text-sm", children: [
77
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2", children: [
78
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ShieldCheck, { className: "h-3.5 w-3.5 text-muted-foreground" }),
79
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_drop_status_display.DropPriceDisplay, { conditions })
80
+ ] }),
81
+ maxPerWallet > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "text-xs text-muted-foreground", children: [
82
+ "Max ",
83
+ maxPerWallet,
84
+ "/wallet"
85
+ ] })
70
86
  ] }),
71
- conditions && status === "upcoming" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_drop_countdown.DropCountdown, { targetTs: conditions.startTime, label: whitelistEnabled ? "Whitelist opens in" : "Mint opens in" })
87
+ conditions && conditions.startTime > 0 && conditions.endTime > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-1 text-xs text-muted-foreground border-t border-border/60 pt-3", children: [
88
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-1.5", children: [
89
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Calendar, { className: "h-3 w-3 shrink-0" }),
90
+ "Opens: ",
91
+ formatTs(conditions.startTime)
92
+ ] }),
93
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-1.5", children: [
94
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Calendar, { className: "h-3 w-3 shrink-0" }),
95
+ "Closes: ",
96
+ formatTs(conditions.endTime)
97
+ ] })
98
+ ] })
72
99
  ] })
73
100
  ] });
74
101
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/drop-preview-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { Lock, ShieldCheck, Users } from \"lucide-react\";\nimport { MedialaneCollectionCard } from \"./medialane-collection-card.js\";\nimport { DropStatusBadge, DropSupplyProgress, DropPriceDisplay } from \"./drop-status-display.js\";\nimport { DropCountdown } from \"./drop-countdown.js\";\nimport { getDropStatus, type DropConditions } from \"../utils/drop-status.js\";\n\nexport interface DropPreviewCardProps {\n coverImage: string | null;\n name: string;\n symbol: string;\n creatorAddress?: string;\n creatorHref?: string;\n itemCount: number;\n conditions: DropConditions | null;\n whitelistEnabled: boolean;\n gatedContentEnabled: boolean;\n}\n\nexport function DropPreviewCard({\n coverImage, name, symbol, creatorAddress, creatorHref,\n itemCount, conditions, whitelistEnabled, gatedContentEnabled,\n}: DropPreviewCardProps) {\n const status = getDropStatus(conditions, 0);\n\n return (\n <div className=\"space-y-3\">\n <MedialaneCollectionCard\n image={coverImage}\n name={name}\n collection={symbol || \"Drop\"}\n creator={creatorAddress}\n creatorHref={creatorHref}\n />\n\n <div className=\"bento-cell p-4 space-y-3\">\n <div className=\"flex items-center gap-2 flex-wrap\">\n <DropStatusBadge status={status} />\n {whitelistEnabled && (\n <span className=\"inline-flex items-center gap-1 text-[10px] font-bold uppercase tracking-widest text-brand-orange bg-brand-orange/10 rounded-full px-2 py-0.5\">\n <Users className=\"h-3 w-3\" />\n Whitelist\n </span>\n )}\n {gatedContentEnabled && (\n <span className=\"inline-flex items-center gap-1 text-[10px] font-bold uppercase tracking-widest text-primary bg-primary/10 rounded-full px-2 py-0.5\">\n <Lock className=\"h-3 w-3\" />\n Exclusive content\n </span>\n )}\n </div>\n\n <DropSupplyProgress minted={0} max={itemCount} />\n\n {conditions && (\n <div className=\"flex items-center gap-2 text-sm\">\n <ShieldCheck className=\"h-3.5 w-3.5 text-muted-foreground\" />\n <DropPriceDisplay conditions={conditions} />\n </div>\n )}\n\n {conditions && status === \"upcoming\" && (\n <DropCountdown targetTs={conditions.startTime} label={whitelistEnabled ? \"Whitelist opens in\" : \"Mint opens in\"} />\n )}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA4BM;AA1BN,0BAAyC;AACzC,uCAAwC;AACxC,iCAAsE;AACtE,4BAA8B;AAC9B,yBAAmD;AAc5C,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EAAY;AAAA,EAAM;AAAA,EAAQ;AAAA,EAAgB;AAAA,EAC1C;AAAA,EAAW;AAAA,EAAY;AAAA,EAAkB;AAC3C,GAAyB;AACvB,QAAM,aAAS,kCAAc,YAAY,CAAC;AAE1C,SACE,6CAAC,SAAI,WAAU,aACb;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,QACP;AAAA,QACA,YAAY,UAAU;AAAA,QACtB,SAAS;AAAA,QACT;AAAA;AAAA,IACF;AAAA,IAEA,6CAAC,SAAI,WAAU,4BACb;AAAA,mDAAC,SAAI,WAAU,qCACb;AAAA,oDAAC,8CAAgB,QAAgB;AAAA,QAChC,oBACC,6CAAC,UAAK,WAAU,gJACd;AAAA,sDAAC,6BAAM,WAAU,WAAU;AAAA,UAAE;AAAA,WAE/B;AAAA,QAED,uBACC,6CAAC,UAAK,WAAU,sIACd;AAAA,sDAAC,4BAAK,WAAU,WAAU;AAAA,UAAE;AAAA,WAE9B;AAAA,SAEJ;AAAA,MAEA,4CAAC,iDAAmB,QAAQ,GAAG,KAAK,WAAW;AAAA,MAE9C,cACC,6CAAC,SAAI,WAAU,mCACb;AAAA,oDAAC,mCAAY,WAAU,qCAAoC;AAAA,QAC3D,4CAAC,+CAAiB,YAAwB;AAAA,SAC5C;AAAA,MAGD,cAAc,WAAW,cACxB,4CAAC,uCAAc,UAAU,WAAW,WAAW,OAAO,mBAAmB,uBAAuB,iBAAiB;AAAA,OAErH;AAAA,KACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/drop-preview-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { Calendar, Lock, ShieldCheck, Users } from \"lucide-react\";\nimport { MedialaneCollectionCard } from \"./medialane-collection-card.js\";\nimport { DropStatusBadge, DropSupplyProgress, DropPriceDisplay } from \"./drop-status-display.js\";\nimport { getDropStatus, type DropConditions } from \"../utils/drop-status.js\";\n\nexport interface DropPreviewCardProps {\n coverImage: string | null;\n name: string;\n symbol: string;\n creatorAddress?: string;\n creatorHref?: string;\n itemCount: number;\n conditions: DropConditions | null;\n whitelistEnabled: boolean;\n gatedContentEnabled: boolean;\n}\n\nfunction formatTs(ts: number): string {\n return new Date(ts * 1000).toLocaleString(undefined, {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n });\n}\n\nexport function DropPreviewCard({\n coverImage, name, symbol, creatorAddress, creatorHref,\n itemCount, conditions, whitelistEnabled, gatedContentEnabled,\n}: DropPreviewCardProps) {\n const status = getDropStatus(conditions, 0);\n const maxPerWallet = conditions ? parseInt(conditions.maxPerWallet, 10) : 0;\n\n return (\n <div className=\"space-y-3\">\n <div className=\"relative\">\n <MedialaneCollectionCard\n image={coverImage}\n name={name}\n collection={symbol || \"Drop\"}\n creator={creatorAddress}\n creatorHref={creatorHref}\n />\n <span className=\"absolute top-4 right-4 text-[9px] font-bold uppercase tracking-widest text-white bg-black/50 backdrop-blur-sm rounded-full px-2 py-0.5\">\n Drop\n </span>\n </div>\n\n <div className=\"bento-cell p-4 space-y-3\">\n <div className=\"flex items-center gap-2 flex-wrap\">\n <DropStatusBadge status={status} />\n {whitelistEnabled && (\n <span className=\"inline-flex items-center gap-1 text-[10px] font-bold uppercase tracking-widest text-brand-orange bg-brand-orange/10 rounded-full px-2 py-0.5\">\n <Users className=\"h-3 w-3\" />\n Whitelist\n </span>\n )}\n {gatedContentEnabled && (\n <span className=\"inline-flex items-center gap-1 text-[10px] font-bold uppercase tracking-widest text-primary bg-primary/10 rounded-full px-2 py-0.5\">\n <Lock className=\"h-3 w-3\" />\n Exclusive content\n </span>\n )}\n </div>\n\n <DropSupplyProgress minted={0} max={itemCount} />\n\n {conditions && (\n <div className=\"flex items-center justify-between text-sm\">\n <div className=\"flex items-center gap-2\">\n <ShieldCheck className=\"h-3.5 w-3.5 text-muted-foreground\" />\n <DropPriceDisplay conditions={conditions} />\n </div>\n {maxPerWallet > 0 && (\n <span className=\"text-xs text-muted-foreground\">Max {maxPerWallet}/wallet</span>\n )}\n </div>\n )}\n\n {conditions && conditions.startTime > 0 && conditions.endTime > 0 && (\n <div className=\"space-y-1 text-xs text-muted-foreground border-t border-border/60 pt-3\">\n <div className=\"flex items-center gap-1.5\">\n <Calendar className=\"h-3 w-3 shrink-0\" />\n Opens: {formatTs(conditions.startTime)}\n </div>\n <div className=\"flex items-center gap-1.5\">\n <Calendar className=\"h-3 w-3 shrink-0\" />\n Closes: {formatTs(conditions.endTime)}\n </div>\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAmCM;AAjCN,0BAAmD;AACnD,uCAAwC;AACxC,iCAAsE;AACtE,yBAAmD;AAcnD,SAAS,SAAS,IAAoB;AACpC,SAAO,IAAI,KAAK,KAAK,GAAI,EAAE,eAAe,QAAW;AAAA,IACnD,WAAW;AAAA,IACX,WAAW;AAAA,EACb,CAAC;AACH;AAEO,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EAAY;AAAA,EAAM;AAAA,EAAQ;AAAA,EAAgB;AAAA,EAC1C;AAAA,EAAW;AAAA,EAAY;AAAA,EAAkB;AAC3C,GAAyB;AACvB,QAAM,aAAS,kCAAc,YAAY,CAAC;AAC1C,QAAM,eAAe,aAAa,SAAS,WAAW,cAAc,EAAE,IAAI;AAE1E,SACE,6CAAC,SAAI,WAAU,aACb;AAAA,iDAAC,SAAI,WAAU,YACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO;AAAA,UACP;AAAA,UACA,YAAY,UAAU;AAAA,UACtB,SAAS;AAAA,UACT;AAAA;AAAA,MACF;AAAA,MACA,4CAAC,UAAK,WAAU,0IAAyI,kBAEzJ;AAAA,OACF;AAAA,IAEA,6CAAC,SAAI,WAAU,4BACb;AAAA,mDAAC,SAAI,WAAU,qCACb;AAAA,oDAAC,8CAAgB,QAAgB;AAAA,QAChC,oBACC,6CAAC,UAAK,WAAU,gJACd;AAAA,sDAAC,6BAAM,WAAU,WAAU;AAAA,UAAE;AAAA,WAE/B;AAAA,QAED,uBACC,6CAAC,UAAK,WAAU,sIACd;AAAA,sDAAC,4BAAK,WAAU,WAAU;AAAA,UAAE;AAAA,WAE9B;AAAA,SAEJ;AAAA,MAEA,4CAAC,iDAAmB,QAAQ,GAAG,KAAK,WAAW;AAAA,MAE9C,cACC,6CAAC,SAAI,WAAU,6CACb;AAAA,qDAAC,SAAI,WAAU,2BACb;AAAA,sDAAC,mCAAY,WAAU,qCAAoC;AAAA,UAC3D,4CAAC,+CAAiB,YAAwB;AAAA,WAC5C;AAAA,QACC,eAAe,KACd,6CAAC,UAAK,WAAU,iCAAgC;AAAA;AAAA,UAAK;AAAA,UAAa;AAAA,WAAO;AAAA,SAE7E;AAAA,MAGD,cAAc,WAAW,YAAY,KAAK,WAAW,UAAU,KAC9D,6CAAC,SAAI,WAAU,0EACb;AAAA,qDAAC,SAAI,WAAU,6BACb;AAAA,sDAAC,gCAAS,WAAU,oBAAmB;AAAA,UAAE;AAAA,UACjC,SAAS,WAAW,SAAS;AAAA,WACvC;AAAA,QACA,6CAAC,SAAI,WAAU,6BACb;AAAA,sDAAC,gCAAS,WAAU,oBAAmB;AAAA,UAAE;AAAA,UAChC,SAAS,WAAW,OAAO;AAAA,WACtC;AAAA,SACF;AAAA,OAEJ;AAAA,KACF;AAEJ;","names":[]}