@medialane/ui 0.114.0 → 0.116.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.
- package/dist/components/asset-card.cjs +10 -17
- package/dist/components/asset-card.cjs.map +1 -1
- package/dist/components/asset-card.js +11 -18
- package/dist/components/asset-card.js.map +1 -1
- package/dist/components/asset-marketplace-panel.cjs +3 -35
- package/dist/components/asset-marketplace-panel.cjs.map +1 -1
- package/dist/components/asset-marketplace-panel.js +4 -36
- package/dist/components/asset-marketplace-panel.js.map +1 -1
- package/dist/components/dual-price.cjs +118 -0
- package/dist/components/dual-price.cjs.map +1 -0
- package/dist/components/dual-price.d.cts +77 -0
- package/dist/components/dual-price.d.ts +77 -0
- package/dist/components/dual-price.js +92 -0
- package/dist/components/dual-price.js.map +1 -0
- package/dist/components/listing-card.cjs +2 -35
- package/dist/components/listing-card.cjs.map +1 -1
- package/dist/components/listing-card.js +2 -35
- package/dist/components/listing-card.js.map +1 -1
- package/dist/components/token-card.cjs +12 -6
- package/dist/components/token-card.cjs.map +1 -1
- package/dist/components/token-card.d.cts +8 -1
- package/dist/components/token-card.d.ts +8 -1
- package/dist/components/token-card.js +12 -6
- package/dist/components/token-card.js.map +1 -1
- package/package.json +1 -1
|
@@ -38,8 +38,7 @@ var import_link = __toESM(require("next/link"), 1);
|
|
|
38
38
|
var import_lucide_react = require("lucide-react");
|
|
39
39
|
var import_cn = require("../utils/cn.js");
|
|
40
40
|
var import_ipfs = require("../utils/ipfs.js");
|
|
41
|
-
var
|
|
42
|
-
var import_currency_icon = require("./currency-icon.js");
|
|
41
|
+
var import_dual_price = require("./dual-price.js");
|
|
43
42
|
var import_ip_type_badge = require("./ip-type-badge.js");
|
|
44
43
|
var import_animated_token_media = require("./animated-token-media.js");
|
|
45
44
|
function AssetCard({
|
|
@@ -83,21 +82,15 @@ function AssetCard({
|
|
|
83
82
|
] }) })
|
|
84
83
|
}
|
|
85
84
|
),
|
|
86
|
-
hasPrice && !indexing && ((
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
price.
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
] })
|
|
96
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
97
|
-
price.currency && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_currency_icon.CurrencyIcon, { symbol: price.currency, size: 13 }),
|
|
98
|
-
cryptoDisplay
|
|
99
|
-
] }) });
|
|
100
|
-
})(),
|
|
85
|
+
hasPrice && !indexing && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "absolute bottom-2 right-2 inline-flex items-center gap-1.5 text-sm font-bold text-white/95 backdrop-blur-md bg-black/40 rounded-full pl-3 pr-3 py-1.5 tabular-nums", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
86
|
+
import_dual_price.PriceChipContent,
|
|
87
|
+
{
|
|
88
|
+
amountFormatted: price.formatted,
|
|
89
|
+
currency: price.currency,
|
|
90
|
+
usdValue: price.usdValue,
|
|
91
|
+
tone: "overlay-dark"
|
|
92
|
+
}
|
|
93
|
+
) }),
|
|
101
94
|
indexing && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "absolute bottom-0 inset-x-0 flex items-center justify-center gap-1.5 bg-black/50 backdrop-blur-sm py-1.5", children: [
|
|
102
95
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Loader2, { className: "h-3 w-3 animate-spin text-white/70" }),
|
|
103
96
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-2xs text-white/70", children: "Indexing\u2026" })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/asset-card.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"next/link\";\nimport { Loader2 } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/components/asset-card.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"next/link\";\nimport { Loader2 } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { PriceChipContent } from \"./dual-price.js\";\nimport { IpTypeBadge } from \"./ip-type-badge.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\n\nexport interface AssetCardPrice {\n formatted?: string | null;\n currency?: string | null;\n /**\n * Pre-formatted USD equivalent (e.g. \"$13.15\"), computed by the host from\n * its own live rate feed — this package has no price-feed access by\n * design. Omit/null renders the crypto amount alone (today's behavior).\n */\n usdValue?: string | null;\n}\n\nexport interface AssetCardProps {\n /** Asset detail link. */\n href: string;\n /** Asset title. */\n name: string;\n /** Raw image (ipfs:// or http) — resolved internally. */\n image?: string | null;\n /** Resolved animation_url — the live on-chain renderer, if any. */\n animationUrl?: string | null;\n /** Caller-computed eligibility for the living-render treatment. */\n live?: boolean;\n /** Secondary line under the title (collection or description). */\n subtitle?: string | null;\n /** IP type (apiValue or label) — renders the icon badge on the footer left. */\n ipType?: string | null;\n /** Listing price; omit/null shows no price. */\n price?: AssetCardPrice | null;\n /** Shown when the image is missing/errors (e.g. token id). */\n fallbackId?: string | null;\n /** Show the \"Indexing…\" overlay. */\n indexing?: boolean;\n /** Base URL for the ipType badge link. Default \"\" (relative). */\n ipTypeBaseUrl?: string;\n className?: string;\n}\n\n/**\n * The platform's shared asset card — lean and presentational.\n *\n * Intentionally has no action buttons, dropdowns or dialogs: the image and\n * text are the only interactive surface (a single asset link), which keeps\n * browse grids and carousels fast even when many cards render. Surfaces that\n * need owner/marketplace actions use the richer `TokenCard` / `ListingCard`.\n *\n * Layout: inset 4:5 artwork (gallery ratio, echoing the Medialane Collection\n * Card) with the price as a glass pill on the artwork (the collection cards'\n * Floor-pill vocabulary) → one body row: display-face title + optional\n * subtitle, with the optional ipType badge inline on the right.\n */\nexport function AssetCard({\n href,\n name,\n image,\n animationUrl,\n live = false,\n subtitle,\n ipType,\n price,\n fallbackId,\n indexing = false,\n ipTypeBaseUrl = \"\",\n className,\n}: AssetCardProps) {\n const resolved = image ? ipfsToHttp(image) : null;\n const hasPrice = !!price?.formatted;\n\n return (\n <div\n className={cn(\n \"card-base group relative flex flex-col w-full transition-colors hover:border-foreground/20\",\n className\n )}\n >\n {/* Artwork — inset with a gallery 4:5 ratio, like the Collection Card */}\n <Link href={href} className=\"block p-1.5 pb-0\">\n <div className=\"relative aspect-[4/5] rounded-[12px] bg-muted overflow-hidden ring-1 ring-border/50\">\n <AnimatedTokenMedia\n image={resolved}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 22vw\"\n className=\"object-cover transition-transform duration-500 group-hover:scale-105\"\n fallback={\n <div className=\"absolute inset-0 flex items-center justify-center bg-gradient-to-br from-brand-blue/25 via-brand-purple/25 to-brand-rose/25\">\n <span className=\"text-sm font-semibold text-muted-foreground tabular-nums\">\n #{fallbackId ?? \"?\"}\n </span>\n </div>\n }\n />\n\n {/* Price pill — anchored on the artwork, same glass chip as the\n collection cards' Floor pill. Fiat leads when a live rate is\n available; the on-chain amount trails, dimmer, as a secondary\n fact — never a second full-weight number competing for\n attention. Stablecoins collapse to fiat + symbol alone, since\n the crypto amount would just repeat the same figure. */}\n {hasPrice && !indexing && (\n <span className=\"absolute bottom-2 right-2 inline-flex items-center gap-1.5 text-sm font-bold text-white/95 backdrop-blur-md bg-black/40 rounded-full pl-3 pr-3 py-1.5 tabular-nums\">\n <PriceChipContent\n amountFormatted={price!.formatted}\n currency={price!.currency}\n usdValue={price!.usdValue}\n tone=\"overlay-dark\"\n />\n </span>\n )}\n\n {indexing && (\n <div className=\"absolute bottom-0 inset-x-0 flex items-center justify-center gap-1.5 bg-black/50 backdrop-blur-sm py-1.5\">\n <Loader2 className=\"h-3 w-3 animate-spin text-white/70\" />\n <span className=\"text-2xs text-white/70\">Indexing…</span>\n </div>\n )}\n </div>\n </Link>\n\n {/* Body — one tight block: title (+ optional ipType badge inline) and subtitle */}\n <div className=\"flex items-start justify-between gap-2 px-3 py-3\">\n <Link href={href} className=\"block min-w-0 flex-1\">\n <p className=\"text-base font-bold line-clamp-1 leading-snug\">\n {name}\n </p>\n {subtitle && (\n <p className=\"text-xs text-muted-foreground line-clamp-1 leading-snug\">\n {subtitle}\n </p>\n )}\n </Link>\n\n {ipType && (\n <div className=\"shrink-0 mt-0.5\">\n <IpTypeBadge ipType={ipType} size=\"sm\" baseUrl={ipTypeBaseUrl} />\n </div>\n )}\n </div>\n </div>\n );\n}\n\nexport function AssetCardSkeleton() {\n return (\n <div className=\"card-base flex flex-col w-full\">\n <div className=\"p-1.5 pb-0\">\n <div className=\"aspect-[4/5] w-full animate-pulse bg-muted rounded-[12px]\" />\n </div>\n <div className=\"px-3 py-3 space-y-1.5\">\n <div className=\"h-4 w-3/4 rounded-md animate-pulse bg-muted\" />\n <div className=\"h-3.5 w-2/5 rounded-md animate-pulse bg-muted\" />\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgGc;AA9Fd,kBAAiB;AACjB,0BAAwB;AACxB,gBAAmB;AACnB,kBAA2B;AAC3B,wBAAiC;AACjC,2BAA4B;AAC5B,kCAAmC;AAoD5B,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,gBAAgB;AAAA,EAChB;AACF,GAAmB;AACjB,QAAM,WAAW,YAAQ,wBAAW,KAAK,IAAI;AAC7C,QAAM,WAAW,CAAC,CAAC,OAAO;AAE1B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MAGA;AAAA,oDAAC,YAAAA,SAAA,EAAK,MAAY,WAAU,oBAC1B,uDAAC,SAAI,WAAU,uFACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,cACP;AAAA,cACA;AAAA,cACA,KAAK;AAAA,cACL,MAAK;AAAA,cACL,OAAM;AAAA,cACN,WAAU;AAAA,cACV,UACE,4CAAC,SAAI,WAAU,+HACb,uDAAC,UAAK,WAAU,4DAA2D;AAAA;AAAA,gBACvE,cAAc;AAAA,iBAClB,GACF;AAAA;AAAA,UAEJ;AAAA,UAQC,YAAY,CAAC,YACZ,4CAAC,UAAK,WAAU,sKACd;AAAA,YAAC;AAAA;AAAA,cACC,iBAAiB,MAAO;AAAA,cACxB,UAAU,MAAO;AAAA,cACjB,UAAU,MAAO;AAAA,cACjB,MAAK;AAAA;AAAA,UACP,GACF;AAAA,UAGD,YACC,6CAAC,SAAI,WAAU,4GACb;AAAA,wDAAC,+BAAQ,WAAU,sCAAqC;AAAA,YACxD,4CAAC,UAAK,WAAU,0BAAyB,4BAAS;AAAA,aACpD;AAAA,WAEJ,GACF;AAAA,QAGA,6CAAC,SAAI,WAAU,oDACb;AAAA,uDAAC,YAAAA,SAAA,EAAK,MAAY,WAAU,wBAC1B;AAAA,wDAAC,OAAE,WAAU,iDACV,gBACH;AAAA,YACC,YACC,4CAAC,OAAE,WAAU,2DACV,oBACH;AAAA,aAEJ;AAAA,UAEC,UACC,4CAAC,SAAI,WAAU,mBACb,sDAAC,oCAAY,QAAgB,MAAK,MAAK,SAAS,eAAe,GACjE;AAAA,WAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,oBAAoB;AAClC,SACE,6CAAC,SAAI,WAAU,kCACb;AAAA,gDAAC,SAAI,WAAU,cACb,sDAAC,SAAI,WAAU,6DAA4D,GAC7E;AAAA,IACA,6CAAC,SAAI,WAAU,yBACb;AAAA,kDAAC,SAAI,WAAU,+CAA8C;AAAA,MAC7D,4CAAC,SAAI,WAAU,iDAAgD;AAAA,OACjE;AAAA,KACF;AAEJ;","names":["Link"]}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import Link from "next/link";
|
|
4
4
|
import { Loader2 } from "lucide-react";
|
|
5
5
|
import { cn } from "../utils/cn.js";
|
|
6
6
|
import { ipfsToHttp } from "../utils/ipfs.js";
|
|
7
|
-
import {
|
|
8
|
-
import { CurrencyIcon } from "./currency-icon.js";
|
|
7
|
+
import { PriceChipContent } from "./dual-price.js";
|
|
9
8
|
import { IpTypeBadge } from "./ip-type-badge.js";
|
|
10
9
|
import { AnimatedTokenMedia } from "./animated-token-media.js";
|
|
11
10
|
function AssetCard({
|
|
@@ -49,21 +48,15 @@ function AssetCard({
|
|
|
49
48
|
] }) })
|
|
50
49
|
}
|
|
51
50
|
),
|
|
52
|
-
hasPrice && !indexing && (
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
price.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
] })
|
|
62
|
-
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
63
|
-
price.currency && /* @__PURE__ */ jsx(CurrencyIcon, { symbol: price.currency, size: 13 }),
|
|
64
|
-
cryptoDisplay
|
|
65
|
-
] }) });
|
|
66
|
-
})(),
|
|
51
|
+
hasPrice && !indexing && /* @__PURE__ */ jsx("span", { className: "absolute bottom-2 right-2 inline-flex items-center gap-1.5 text-sm font-bold text-white/95 backdrop-blur-md bg-black/40 rounded-full pl-3 pr-3 py-1.5 tabular-nums", children: /* @__PURE__ */ jsx(
|
|
52
|
+
PriceChipContent,
|
|
53
|
+
{
|
|
54
|
+
amountFormatted: price.formatted,
|
|
55
|
+
currency: price.currency,
|
|
56
|
+
usdValue: price.usdValue,
|
|
57
|
+
tone: "overlay-dark"
|
|
58
|
+
}
|
|
59
|
+
) }),
|
|
67
60
|
indexing && /* @__PURE__ */ jsxs("div", { className: "absolute bottom-0 inset-x-0 flex items-center justify-center gap-1.5 bg-black/50 backdrop-blur-sm py-1.5", children: [
|
|
68
61
|
/* @__PURE__ */ jsx(Loader2, { className: "h-3 w-3 animate-spin text-white/70" }),
|
|
69
62
|
/* @__PURE__ */ jsx("span", { className: "text-2xs text-white/70", children: "Indexing\u2026" })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/asset-card.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"next/link\";\nimport { Loader2 } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/components/asset-card.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"next/link\";\nimport { Loader2 } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { PriceChipContent } from \"./dual-price.js\";\nimport { IpTypeBadge } from \"./ip-type-badge.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\n\nexport interface AssetCardPrice {\n formatted?: string | null;\n currency?: string | null;\n /**\n * Pre-formatted USD equivalent (e.g. \"$13.15\"), computed by the host from\n * its own live rate feed — this package has no price-feed access by\n * design. Omit/null renders the crypto amount alone (today's behavior).\n */\n usdValue?: string | null;\n}\n\nexport interface AssetCardProps {\n /** Asset detail link. */\n href: string;\n /** Asset title. */\n name: string;\n /** Raw image (ipfs:// or http) — resolved internally. */\n image?: string | null;\n /** Resolved animation_url — the live on-chain renderer, if any. */\n animationUrl?: string | null;\n /** Caller-computed eligibility for the living-render treatment. */\n live?: boolean;\n /** Secondary line under the title (collection or description). */\n subtitle?: string | null;\n /** IP type (apiValue or label) — renders the icon badge on the footer left. */\n ipType?: string | null;\n /** Listing price; omit/null shows no price. */\n price?: AssetCardPrice | null;\n /** Shown when the image is missing/errors (e.g. token id). */\n fallbackId?: string | null;\n /** Show the \"Indexing…\" overlay. */\n indexing?: boolean;\n /** Base URL for the ipType badge link. Default \"\" (relative). */\n ipTypeBaseUrl?: string;\n className?: string;\n}\n\n/**\n * The platform's shared asset card — lean and presentational.\n *\n * Intentionally has no action buttons, dropdowns or dialogs: the image and\n * text are the only interactive surface (a single asset link), which keeps\n * browse grids and carousels fast even when many cards render. Surfaces that\n * need owner/marketplace actions use the richer `TokenCard` / `ListingCard`.\n *\n * Layout: inset 4:5 artwork (gallery ratio, echoing the Medialane Collection\n * Card) with the price as a glass pill on the artwork (the collection cards'\n * Floor-pill vocabulary) → one body row: display-face title + optional\n * subtitle, with the optional ipType badge inline on the right.\n */\nexport function AssetCard({\n href,\n name,\n image,\n animationUrl,\n live = false,\n subtitle,\n ipType,\n price,\n fallbackId,\n indexing = false,\n ipTypeBaseUrl = \"\",\n className,\n}: AssetCardProps) {\n const resolved = image ? ipfsToHttp(image) : null;\n const hasPrice = !!price?.formatted;\n\n return (\n <div\n className={cn(\n \"card-base group relative flex flex-col w-full transition-colors hover:border-foreground/20\",\n className\n )}\n >\n {/* Artwork — inset with a gallery 4:5 ratio, like the Collection Card */}\n <Link href={href} className=\"block p-1.5 pb-0\">\n <div className=\"relative aspect-[4/5] rounded-[12px] bg-muted overflow-hidden ring-1 ring-border/50\">\n <AnimatedTokenMedia\n image={resolved}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 22vw\"\n className=\"object-cover transition-transform duration-500 group-hover:scale-105\"\n fallback={\n <div className=\"absolute inset-0 flex items-center justify-center bg-gradient-to-br from-brand-blue/25 via-brand-purple/25 to-brand-rose/25\">\n <span className=\"text-sm font-semibold text-muted-foreground tabular-nums\">\n #{fallbackId ?? \"?\"}\n </span>\n </div>\n }\n />\n\n {/* Price pill — anchored on the artwork, same glass chip as the\n collection cards' Floor pill. Fiat leads when a live rate is\n available; the on-chain amount trails, dimmer, as a secondary\n fact — never a second full-weight number competing for\n attention. Stablecoins collapse to fiat + symbol alone, since\n the crypto amount would just repeat the same figure. */}\n {hasPrice && !indexing && (\n <span className=\"absolute bottom-2 right-2 inline-flex items-center gap-1.5 text-sm font-bold text-white/95 backdrop-blur-md bg-black/40 rounded-full pl-3 pr-3 py-1.5 tabular-nums\">\n <PriceChipContent\n amountFormatted={price!.formatted}\n currency={price!.currency}\n usdValue={price!.usdValue}\n tone=\"overlay-dark\"\n />\n </span>\n )}\n\n {indexing && (\n <div className=\"absolute bottom-0 inset-x-0 flex items-center justify-center gap-1.5 bg-black/50 backdrop-blur-sm py-1.5\">\n <Loader2 className=\"h-3 w-3 animate-spin text-white/70\" />\n <span className=\"text-2xs text-white/70\">Indexing…</span>\n </div>\n )}\n </div>\n </Link>\n\n {/* Body — one tight block: title (+ optional ipType badge inline) and subtitle */}\n <div className=\"flex items-start justify-between gap-2 px-3 py-3\">\n <Link href={href} className=\"block min-w-0 flex-1\">\n <p className=\"text-base font-bold line-clamp-1 leading-snug\">\n {name}\n </p>\n {subtitle && (\n <p className=\"text-xs text-muted-foreground line-clamp-1 leading-snug\">\n {subtitle}\n </p>\n )}\n </Link>\n\n {ipType && (\n <div className=\"shrink-0 mt-0.5\">\n <IpTypeBadge ipType={ipType} size=\"sm\" baseUrl={ipTypeBaseUrl} />\n </div>\n )}\n </div>\n </div>\n );\n}\n\nexport function AssetCardSkeleton() {\n return (\n <div className=\"card-base flex flex-col w-full\">\n <div className=\"p-1.5 pb-0\">\n <div className=\"aspect-[4/5] w-full animate-pulse bg-muted rounded-[12px]\" />\n </div>\n <div className=\"px-3 py-3 space-y-1.5\">\n <div className=\"h-4 w-3/4 rounded-md animate-pulse bg-muted\" />\n <div className=\"h-3.5 w-2/5 rounded-md animate-pulse bg-muted\" />\n </div>\n </div>\n );\n}\n"],"mappings":";AAgGc,cACE,YADF;AA9Fd,OAAO,UAAU;AACjB,SAAS,eAAe;AACxB,SAAS,UAAU;AACnB,SAAS,kBAAkB;AAC3B,SAAS,wBAAwB;AACjC,SAAS,mBAAmB;AAC5B,SAAS,0BAA0B;AAoD5B,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,gBAAgB;AAAA,EAChB;AACF,GAAmB;AACjB,QAAM,WAAW,QAAQ,WAAW,KAAK,IAAI;AAC7C,QAAM,WAAW,CAAC,CAAC,OAAO;AAE1B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MAGA;AAAA,4BAAC,QAAK,MAAY,WAAU,oBAC1B,+BAAC,SAAI,WAAU,uFACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,cACP;AAAA,cACA;AAAA,cACA,KAAK;AAAA,cACL,MAAK;AAAA,cACL,OAAM;AAAA,cACN,WAAU;AAAA,cACV,UACE,oBAAC,SAAI,WAAU,+HACb,+BAAC,UAAK,WAAU,4DAA2D;AAAA;AAAA,gBACvE,cAAc;AAAA,iBAClB,GACF;AAAA;AAAA,UAEJ;AAAA,UAQC,YAAY,CAAC,YACZ,oBAAC,UAAK,WAAU,sKACd;AAAA,YAAC;AAAA;AAAA,cACC,iBAAiB,MAAO;AAAA,cACxB,UAAU,MAAO;AAAA,cACjB,UAAU,MAAO;AAAA,cACjB,MAAK;AAAA;AAAA,UACP,GACF;AAAA,UAGD,YACC,qBAAC,SAAI,WAAU,4GACb;AAAA,gCAAC,WAAQ,WAAU,sCAAqC;AAAA,YACxD,oBAAC,UAAK,WAAU,0BAAyB,4BAAS;AAAA,aACpD;AAAA,WAEJ,GACF;AAAA,QAGA,qBAAC,SAAI,WAAU,oDACb;AAAA,+BAAC,QAAK,MAAY,WAAU,wBAC1B;AAAA,gCAAC,OAAE,WAAU,iDACV,gBACH;AAAA,YACC,YACC,oBAAC,OAAE,WAAU,2DACV,oBACH;AAAA,aAEJ;AAAA,UAEC,UACC,oBAAC,SAAI,WAAU,mBACb,8BAAC,eAAY,QAAgB,MAAK,MAAK,SAAS,eAAe,GACjE;AAAA,WAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,oBAAoB;AAClC,SACE,qBAAC,SAAI,WAAU,kCACb;AAAA,wBAAC,SAAI,WAAU,cACb,8BAAC,SAAI,WAAU,6DAA4D,GAC7E;AAAA,IACA,qBAAC,SAAI,WAAU,yBACb;AAAA,0BAAC,SAAI,WAAU,+CAA8C;AAAA,MAC7D,oBAAC,SAAI,WAAU,iDAAgD;AAAA,OACjE;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -27,6 +27,7 @@ var import_lucide_react = require("lucide-react");
|
|
|
27
27
|
var import_currency_icon = require("./currency-icon.js");
|
|
28
28
|
var import_address_display = require("./address-display.js");
|
|
29
29
|
var import_action_button = require("./action-button.js");
|
|
30
|
+
var import_dual_price = require("./dual-price.js");
|
|
30
31
|
var import_format = require("../utils/format.js");
|
|
31
32
|
var import_time = require("../utils/time.js");
|
|
32
33
|
function StatRow({ floorPriceRaw, lastSaleRaw }) {
|
|
@@ -44,40 +45,6 @@ function StatRow({ floorPriceRaw, lastSaleRaw }) {
|
|
|
44
45
|
] })
|
|
45
46
|
] });
|
|
46
47
|
}
|
|
47
|
-
function CoinChip({ symbol, size }) {
|
|
48
|
-
const wrap = size === "md" ? "h-7 w-7" : "h-6 w-6";
|
|
49
|
-
const icon = size === "md" ? 16 : 13;
|
|
50
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: `grid ${wrap} shrink-0 place-items-center rounded-full bg-foreground/[0.06]`, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_currency_icon.CurrencyIcon, { symbol: symbol ?? "", size: icon }) });
|
|
51
|
-
}
|
|
52
|
-
function PrimaryPrice({
|
|
53
|
-
amountFormatted,
|
|
54
|
-
currency,
|
|
55
|
-
usdValue,
|
|
56
|
-
trailing
|
|
57
|
-
}) {
|
|
58
|
-
const cryptoDisplay = (0, import_format.formatDisplayPrice)(amountFormatted);
|
|
59
|
-
const displayFace = "font-[family-name:var(--font-display)] font-extrabold tracking-tight tabular-nums";
|
|
60
|
-
if (!usdValue) {
|
|
61
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2.5", children: [
|
|
62
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CoinChip, { symbol: currency, size: "md" }),
|
|
63
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: `${displayFace} text-4xl`, children: cryptoDisplay }),
|
|
64
|
-
trailing && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "ml-0.5", children: trailing })
|
|
65
|
-
] });
|
|
66
|
-
}
|
|
67
|
-
const stable = (0, import_format.isStableCurrency)(currency);
|
|
68
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-4", children: [
|
|
69
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: `${displayFace} text-4xl`, children: usdValue }),
|
|
70
|
-
!stable && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "h-7 w-px bg-border/60 shrink-0" }),
|
|
71
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "inline-flex items-center gap-2", children: [
|
|
72
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CoinChip, { symbol: currency, size: stable ? "sm" : "md" }),
|
|
73
|
-
stable ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-sm font-semibold text-muted-foreground", children: currency }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "flex items-baseline gap-1.5", children: [
|
|
74
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: `${displayFace} text-2xl text-foreground/90`, children: cryptoDisplay }),
|
|
75
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-sm font-semibold text-muted-foreground/70", children: currency })
|
|
76
|
-
] })
|
|
77
|
-
] }),
|
|
78
|
-
trailing && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "ml-0.5", children: trailing })
|
|
79
|
-
] });
|
|
80
|
-
}
|
|
81
48
|
function AssetMarketplacePanel({
|
|
82
49
|
cheapest,
|
|
83
50
|
isOwner,
|
|
@@ -119,11 +86,12 @@ function AssetMarketplacePanel({
|
|
|
119
86
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "relative", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative space-y-4", children: [
|
|
120
87
|
cheapest ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-4", children: [
|
|
121
88
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
122
|
-
|
|
89
|
+
import_dual_price.DualPrice,
|
|
123
90
|
{
|
|
124
91
|
amountFormatted: cheapest.price.formatted,
|
|
125
92
|
currency: cheapest.price.currency,
|
|
126
93
|
usdValue,
|
|
94
|
+
scale: "hero",
|
|
127
95
|
trailing: renderHelp(
|
|
128
96
|
`${isOwner && !canBuyMore ? "Your listing" : "Current price"} \xB7 Expires ${(0, import_time.timeUntil)(cheapest.endTime)}`
|
|
129
97
|
)
|
|
@@ -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 { formatDisplayPrice, parsePriceDisplay, isStableCurrency } from \"../utils/format.js\";\nimport { timeUntil } from \"../utils/time.js\";\n\n/** Structural subset of `ApiOrder` (both apps' `@medialane/sdk` types satisfy this). */\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 * Pre-formatted USD equivalent of `cheapest.price` (e.g. \"$12.34\"), computed\n * by the host from its own live rate feed — this package has no price-feed\n * access by design. Omit (or pass null) to render no USD line.\n */\n usdValue?: string | null;\n /** Renders the sign-in/connect-wallet CTA for the given label (e.g. \"Sign in to trade\"). */\n renderAuthAction: (label: string) => ReactNode;\n /** Renders an inline help/info affordance for the given tooltip text. */\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 /** Non-owner: propose a sponsorship deal on this asset. */\n showSponsorOption?: boolean;\n onOpenSponsorProposal?: () => void;\n /** Owner: open this asset for sponsorship bidding. */\n showSponsorSolicitOption?: boolean;\n onOpenSponsorSolicit?: () => void;\n /** Raw \"0.07 STRK\"-style strings — already resolved by the caller. Shown\n * only in the \"not currently listed\" fallback state (see StatRow) — the\n * active-listing price row dropped them to stay uncluttered. */\n floorPriceRaw?: string | null;\n lastSaleRaw?: string | null;\n}\n\n/** Floor + last-sale stats — each hides itself when its data is absent\n * (no dangling \"—\" placeholders), and the whole row disappears when\n * neither is available. Only used in the \"not currently listed\" state. */\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\n/** A currency icon in the soft circular chip used throughout the wallet UI —\n * reads as a coin, not a stray glyph floating next to text. */\nfunction CoinChip({ symbol, size }: { symbol: string | null; size: \"md\" | \"sm\" }) {\n const wrap = size === \"md\" ? \"h-7 w-7\" : \"h-6 w-6\";\n const icon = size === \"md\" ? 16 : 13;\n return (\n <span className={`grid ${wrap} shrink-0 place-items-center rounded-full bg-foreground/[0.06]`}>\n <CurrencyIcon symbol={symbol ?? \"\"} size={icon} />\n </span>\n );\n}\n\n/**\n * Dual price: fiat and the on-chain currency shown as equal-weight peers,\n * not primary/afterthought — io's audience spans non-crypto newcomers who\n * read fiat and crypto-native buyers who read the token amount. Both use\n * the brand display face at a real step-down in scale (4xl → 2xl) so the\n * pairing reads as \"two related numbers,\" not one dominant + one caption.\n * Falls back to crypto-only when no USD rate is available. When the\n * order's currency is itself a USD-pegged stablecoin, the crypto amount\n * collapses to a small currency badge — showing \"$12.00\" beside \"12.00\n * USDC\" would just be the same number twice.\n */\nfunction PrimaryPrice({\n amountFormatted,\n currency,\n usdValue,\n trailing,\n}: {\n amountFormatted: string | null;\n currency: string | null;\n usdValue?: string | null;\n trailing?: ReactNode;\n}) {\n const cryptoDisplay = formatDisplayPrice(amountFormatted);\n const displayFace = \"font-[family-name:var(--font-display)] font-extrabold tracking-tight tabular-nums\";\n\n if (!usdValue) {\n return (\n <div className=\"flex items-center gap-2.5\">\n <CoinChip symbol={currency} size=\"md\" />\n <span className={`${displayFace} text-4xl`}>{cryptoDisplay}</span>\n {trailing && <span className=\"ml-0.5\">{trailing}</span>}\n </div>\n );\n }\n\n const stable = isStableCurrency(currency);\n return (\n <div className=\"flex items-center gap-4\">\n <span className={`${displayFace} text-4xl`}>{usdValue}</span>\n {!stable && <span className=\"h-7 w-px bg-border/60 shrink-0\" />}\n <span className=\"inline-flex items-center gap-2\">\n <CoinChip symbol={currency} size={stable ? \"sm\" : \"md\"} />\n {stable ? (\n <span className=\"text-sm font-semibold text-muted-foreground\">{currency}</span>\n ) : (\n <span className=\"flex items-baseline gap-1.5\">\n <span className={`${displayFace} text-2xl text-foreground/90`}>{cryptoDisplay}</span>\n <span className=\"text-sm font-semibold text-muted-foreground/70\">{currency}</span>\n </span>\n )}\n </span>\n {trailing && <span className=\"ml-0.5\">{trailing}</span>}\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 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 <PrimaryPrice\n amountFormatted={cheapest.price.formatted}\n currency={cheapest.price.currency}\n usdValue={usdValue}\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 {/* ERC-721 has exactly one possible listing — once myListing exists,\n \"List on Marketplace\" is redundant next to \"Cancel Listing\" and\n reads as a broken/confusing pair. An ERC-1155 owner can still hold\n un-listed editions while one listing is active, so it stays for them. */}\n {(!myListing || isERC1155) ? (\n <ActionButton big tone=\"blue\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing} renderHelp={renderHelp}>List on Marketplace</ActionButton>\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 <ActionButton big tone=\"blue\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing} renderHelp={renderHelp}>List on Marketplace</ActionButton>\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 { formatDisplayPrice, parsePriceDisplay } from \"../utils/format.js\";\nimport { timeUntil } from \"../utils/time.js\";\n\n/** Structural subset of `ApiOrder` (both apps' `@medialane/sdk` types satisfy this). */\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 * Pre-formatted USD equivalent of `cheapest.price` (e.g. \"$12.34\"), computed\n * by the host from its own live rate feed — this package has no price-feed\n * access by design. Omit (or pass null) to render no USD line.\n */\n usdValue?: string | null;\n /** Renders the sign-in/connect-wallet CTA for the given label (e.g. \"Sign in to trade\"). */\n renderAuthAction: (label: string) => ReactNode;\n /** Renders an inline help/info affordance for the given tooltip text. */\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 /** Non-owner: propose a sponsorship deal on this asset. */\n showSponsorOption?: boolean;\n onOpenSponsorProposal?: () => void;\n /** Owner: open this asset for sponsorship bidding. */\n showSponsorSolicitOption?: boolean;\n onOpenSponsorSolicit?: () => void;\n /** Raw \"0.07 STRK\"-style strings — already resolved by the caller. Shown\n * only in the \"not currently listed\" fallback state (see StatRow) — the\n * active-listing price row dropped them to stay uncluttered. */\n floorPriceRaw?: string | null;\n lastSaleRaw?: string | null;\n}\n\n/** Floor + last-sale stats — each hides itself when its data is absent\n * (no dangling \"—\" placeholders), and the whole row disappears when\n * neither is available. Only used in the \"not currently listed\" state. */\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 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 {/* ERC-721 has exactly one possible listing — once myListing exists,\n \"List on Marketplace\" is redundant next to \"Cancel Listing\" and\n reads as a broken/confusing pair. An ERC-1155 owner can still hold\n un-listed editions while one listing is active, so it stays for them. */}\n {(!myListing || isERC1155) ? (\n <ActionButton big tone=\"blue\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing} renderHelp={renderHelp}>List on Marketplace</ActionButton>\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 <ActionButton big tone=\"blue\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing} renderHelp={renderHelp}>List on Marketplace</ActionButton>\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":[]}
|
|
@@ -15,7 +15,8 @@ import {
|
|
|
15
15
|
import { CurrencyIcon, CurrencyAmount } from "./currency-icon.js";
|
|
16
16
|
import { AddressDisplay } from "./address-display.js";
|
|
17
17
|
import { ActionButton } from "./action-button.js";
|
|
18
|
-
import {
|
|
18
|
+
import { DualPrice } from "./dual-price.js";
|
|
19
|
+
import { formatDisplayPrice, parsePriceDisplay } from "../utils/format.js";
|
|
19
20
|
import { timeUntil } from "../utils/time.js";
|
|
20
21
|
function StatRow({ floorPriceRaw, lastSaleRaw }) {
|
|
21
22
|
const floor = floorPriceRaw ? parsePriceDisplay(floorPriceRaw) : null;
|
|
@@ -32,40 +33,6 @@ function StatRow({ floorPriceRaw, lastSaleRaw }) {
|
|
|
32
33
|
] })
|
|
33
34
|
] });
|
|
34
35
|
}
|
|
35
|
-
function CoinChip({ symbol, size }) {
|
|
36
|
-
const wrap = size === "md" ? "h-7 w-7" : "h-6 w-6";
|
|
37
|
-
const icon = size === "md" ? 16 : 13;
|
|
38
|
-
return /* @__PURE__ */ jsx("span", { className: `grid ${wrap} shrink-0 place-items-center rounded-full bg-foreground/[0.06]`, children: /* @__PURE__ */ jsx(CurrencyIcon, { symbol: symbol ?? "", size: icon }) });
|
|
39
|
-
}
|
|
40
|
-
function PrimaryPrice({
|
|
41
|
-
amountFormatted,
|
|
42
|
-
currency,
|
|
43
|
-
usdValue,
|
|
44
|
-
trailing
|
|
45
|
-
}) {
|
|
46
|
-
const cryptoDisplay = formatDisplayPrice(amountFormatted);
|
|
47
|
-
const displayFace = "font-[family-name:var(--font-display)] font-extrabold tracking-tight tabular-nums";
|
|
48
|
-
if (!usdValue) {
|
|
49
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5", children: [
|
|
50
|
-
/* @__PURE__ */ jsx(CoinChip, { symbol: currency, size: "md" }),
|
|
51
|
-
/* @__PURE__ */ jsx("span", { className: `${displayFace} text-4xl`, children: cryptoDisplay }),
|
|
52
|
-
trailing && /* @__PURE__ */ jsx("span", { className: "ml-0.5", children: trailing })
|
|
53
|
-
] });
|
|
54
|
-
}
|
|
55
|
-
const stable = isStableCurrency(currency);
|
|
56
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
|
|
57
|
-
/* @__PURE__ */ jsx("span", { className: `${displayFace} text-4xl`, children: usdValue }),
|
|
58
|
-
!stable && /* @__PURE__ */ jsx("span", { className: "h-7 w-px bg-border/60 shrink-0" }),
|
|
59
|
-
/* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-2", children: [
|
|
60
|
-
/* @__PURE__ */ jsx(CoinChip, { symbol: currency, size: stable ? "sm" : "md" }),
|
|
61
|
-
stable ? /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-muted-foreground", children: currency }) : /* @__PURE__ */ jsxs("span", { className: "flex items-baseline gap-1.5", children: [
|
|
62
|
-
/* @__PURE__ */ jsx("span", { className: `${displayFace} text-2xl text-foreground/90`, children: cryptoDisplay }),
|
|
63
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-muted-foreground/70", children: currency })
|
|
64
|
-
] })
|
|
65
|
-
] }),
|
|
66
|
-
trailing && /* @__PURE__ */ jsx("span", { className: "ml-0.5", children: trailing })
|
|
67
|
-
] });
|
|
68
|
-
}
|
|
69
36
|
function AssetMarketplacePanel({
|
|
70
37
|
cheapest,
|
|
71
38
|
isOwner,
|
|
@@ -107,11 +74,12 @@ function AssetMarketplacePanel({
|
|
|
107
74
|
return /* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsxs("div", { className: "relative space-y-4", children: [
|
|
108
75
|
cheapest ? /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
109
76
|
/* @__PURE__ */ jsx(
|
|
110
|
-
|
|
77
|
+
DualPrice,
|
|
111
78
|
{
|
|
112
79
|
amountFormatted: cheapest.price.formatted,
|
|
113
80
|
currency: cheapest.price.currency,
|
|
114
81
|
usdValue,
|
|
82
|
+
scale: "hero",
|
|
115
83
|
trailing: renderHelp(
|
|
116
84
|
`${isOwner && !canBuyMore ? "Your listing" : "Current price"} \xB7 Expires ${timeUntil(cheapest.endTime)}`
|
|
117
85
|
)
|
|
@@ -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 { formatDisplayPrice, parsePriceDisplay, isStableCurrency } from \"../utils/format.js\";\nimport { timeUntil } from \"../utils/time.js\";\n\n/** Structural subset of `ApiOrder` (both apps' `@medialane/sdk` types satisfy this). */\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 * Pre-formatted USD equivalent of `cheapest.price` (e.g. \"$12.34\"), computed\n * by the host from its own live rate feed — this package has no price-feed\n * access by design. Omit (or pass null) to render no USD line.\n */\n usdValue?: string | null;\n /** Renders the sign-in/connect-wallet CTA for the given label (e.g. \"Sign in to trade\"). */\n renderAuthAction: (label: string) => ReactNode;\n /** Renders an inline help/info affordance for the given tooltip text. */\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 /** Non-owner: propose a sponsorship deal on this asset. */\n showSponsorOption?: boolean;\n onOpenSponsorProposal?: () => void;\n /** Owner: open this asset for sponsorship bidding. */\n showSponsorSolicitOption?: boolean;\n onOpenSponsorSolicit?: () => void;\n /** Raw \"0.07 STRK\"-style strings — already resolved by the caller. Shown\n * only in the \"not currently listed\" fallback state (see StatRow) — the\n * active-listing price row dropped them to stay uncluttered. */\n floorPriceRaw?: string | null;\n lastSaleRaw?: string | null;\n}\n\n/** Floor + last-sale stats — each hides itself when its data is absent\n * (no dangling \"—\" placeholders), and the whole row disappears when\n * neither is available. Only used in the \"not currently listed\" state. */\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\n/** A currency icon in the soft circular chip used throughout the wallet UI —\n * reads as a coin, not a stray glyph floating next to text. */\nfunction CoinChip({ symbol, size }: { symbol: string | null; size: \"md\" | \"sm\" }) {\n const wrap = size === \"md\" ? \"h-7 w-7\" : \"h-6 w-6\";\n const icon = size === \"md\" ? 16 : 13;\n return (\n <span className={`grid ${wrap} shrink-0 place-items-center rounded-full bg-foreground/[0.06]`}>\n <CurrencyIcon symbol={symbol ?? \"\"} size={icon} />\n </span>\n );\n}\n\n/**\n * Dual price: fiat and the on-chain currency shown as equal-weight peers,\n * not primary/afterthought — io's audience spans non-crypto newcomers who\n * read fiat and crypto-native buyers who read the token amount. Both use\n * the brand display face at a real step-down in scale (4xl → 2xl) so the\n * pairing reads as \"two related numbers,\" not one dominant + one caption.\n * Falls back to crypto-only when no USD rate is available. When the\n * order's currency is itself a USD-pegged stablecoin, the crypto amount\n * collapses to a small currency badge — showing \"$12.00\" beside \"12.00\n * USDC\" would just be the same number twice.\n */\nfunction PrimaryPrice({\n amountFormatted,\n currency,\n usdValue,\n trailing,\n}: {\n amountFormatted: string | null;\n currency: string | null;\n usdValue?: string | null;\n trailing?: ReactNode;\n}) {\n const cryptoDisplay = formatDisplayPrice(amountFormatted);\n const displayFace = \"font-[family-name:var(--font-display)] font-extrabold tracking-tight tabular-nums\";\n\n if (!usdValue) {\n return (\n <div className=\"flex items-center gap-2.5\">\n <CoinChip symbol={currency} size=\"md\" />\n <span className={`${displayFace} text-4xl`}>{cryptoDisplay}</span>\n {trailing && <span className=\"ml-0.5\">{trailing}</span>}\n </div>\n );\n }\n\n const stable = isStableCurrency(currency);\n return (\n <div className=\"flex items-center gap-4\">\n <span className={`${displayFace} text-4xl`}>{usdValue}</span>\n {!stable && <span className=\"h-7 w-px bg-border/60 shrink-0\" />}\n <span className=\"inline-flex items-center gap-2\">\n <CoinChip symbol={currency} size={stable ? \"sm\" : \"md\"} />\n {stable ? (\n <span className=\"text-sm font-semibold text-muted-foreground\">{currency}</span>\n ) : (\n <span className=\"flex items-baseline gap-1.5\">\n <span className={`${displayFace} text-2xl text-foreground/90`}>{cryptoDisplay}</span>\n <span className=\"text-sm font-semibold text-muted-foreground/70\">{currency}</span>\n </span>\n )}\n </span>\n {trailing && <span className=\"ml-0.5\">{trailing}</span>}\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 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 <PrimaryPrice\n amountFormatted={cheapest.price.formatted}\n currency={cheapest.price.currency}\n usdValue={usdValue}\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 {/* ERC-721 has exactly one possible listing — once myListing exists,\n \"List on Marketplace\" is redundant next to \"Cancel Listing\" and\n reads as a broken/confusing pair. An ERC-1155 owner can still hold\n un-listed editions while one listing is active, so it stays for them. */}\n {(!myListing || isERC1155) ? (\n <ActionButton big tone=\"blue\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing} renderHelp={renderHelp}>List on Marketplace</ActionButton>\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 <ActionButton big tone=\"blue\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing} renderHelp={renderHelp}>List on Marketplace</ActionButton>\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 { formatDisplayPrice, parsePriceDisplay } from \"../utils/format.js\";\nimport { timeUntil } from \"../utils/time.js\";\n\n/** Structural subset of `ApiOrder` (both apps' `@medialane/sdk` types satisfy this). */\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 * Pre-formatted USD equivalent of `cheapest.price` (e.g. \"$12.34\"), computed\n * by the host from its own live rate feed — this package has no price-feed\n * access by design. Omit (or pass null) to render no USD line.\n */\n usdValue?: string | null;\n /** Renders the sign-in/connect-wallet CTA for the given label (e.g. \"Sign in to trade\"). */\n renderAuthAction: (label: string) => ReactNode;\n /** Renders an inline help/info affordance for the given tooltip text. */\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 /** Non-owner: propose a sponsorship deal on this asset. */\n showSponsorOption?: boolean;\n onOpenSponsorProposal?: () => void;\n /** Owner: open this asset for sponsorship bidding. */\n showSponsorSolicitOption?: boolean;\n onOpenSponsorSolicit?: () => void;\n /** Raw \"0.07 STRK\"-style strings — already resolved by the caller. Shown\n * only in the \"not currently listed\" fallback state (see StatRow) — the\n * active-listing price row dropped them to stay uncluttered. */\n floorPriceRaw?: string | null;\n lastSaleRaw?: string | null;\n}\n\n/** Floor + last-sale stats — each hides itself when its data is absent\n * (no dangling \"—\" placeholders), and the whole row disappears when\n * neither is available. Only used in the \"not currently listed\" state. */\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 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 {/* ERC-721 has exactly one possible listing — once myListing exists,\n \"List on Marketplace\" is redundant next to \"Cancel Listing\" and\n reads as a broken/confusing pair. An ERC-1155 owner can still hold\n un-listed editions while one listing is active, so it stays for them. */}\n {(!myListing || isERC1155) ? (\n <ActionButton big tone=\"blue\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing} renderHelp={renderHelp}>List on Marketplace</ActionButton>\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 <ActionButton big tone=\"blue\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing} renderHelp={renderHelp}>List on Marketplace</ActionButton>\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":[]}
|