@medialane/ui 0.74.2 → 0.76.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.
@@ -38,238 +38,257 @@ var import_react = require("react");
38
38
  var import_link = __toESM(require("next/link"), 1);
39
39
  var import_image = __toESM(require("next/image"), 1);
40
40
  var import_lucide_react = require("lucide-react");
41
+ var import_dropdown_menu = require("./dropdown-menu.js");
41
42
  var import_cn = require("../utils/cn.js");
42
43
  var import_ipfs = require("../utils/ipfs.js");
43
44
  var import_format = require("../utils/format.js");
44
45
  var import_currency_icon = require("./currency-icon.js");
45
46
  var import_ip_type_badge = require("./ip-type-badge.js");
46
- var import_motion_primitives = require("./motion-primitives.js");
47
- const RARITY_STYLE = {
48
- legendary: { label: "Legendary", className: "bg-yellow-400/90 text-yellow-900" },
49
- epic: { label: "Epic", className: "bg-purple-500/85 text-white" },
50
- rare: { label: "Rare", className: "bg-blue-500/85 text-white" },
51
- uncommon: { label: "Uncommon", className: "bg-emerald-500/85 text-white" },
52
- common: null
53
- };
54
- const BTN_BASE = "h-8 rounded-[11px] flex items-center justify-center gap-1.5 text-xs font-semibold transition-all active:scale-[0.98] shadow-none border-0";
55
- const BTN_SOLID = (0, import_cn.cn)(BTN_BASE, "text-white hover:brightness-110");
47
+ var import_sdk = require("@medialane/sdk");
48
+ const BTN_BASE = "h-8 rounded-[9px] flex items-center justify-center gap-1.5 text-xs font-semibold transition-all active:scale-[0.98] shadow-none border-0";
56
49
  const BTN_OUTLINE = (0, import_cn.cn)(BTN_BASE, "border border-border/60 text-foreground hover:bg-muted/60");
57
50
  function TokenCard({
58
51
  token,
59
52
  isOwner = false,
60
- inCart = false,
61
- showBuyButton = true,
62
- rarityTier,
63
- className,
64
- onBuy,
65
- onCart,
66
- onOffer,
67
53
  onList,
68
- onCancel,
69
54
  onTransfer,
70
- overflowMenu
55
+ onCancel,
56
+ onBuy,
57
+ onOffer,
58
+ onReport
71
59
  }) {
72
60
  const [imgError, setImgError] = (0, import_react.useState)(false);
73
61
  const name = token.metadata?.name || `Token #${token.tokenId}`;
74
62
  const image = (0, import_ipfs.ipfsToHttp)(token.metadata?.image);
75
- const activeOrder = token.activeOrders?.[0];
76
- const assetHref = `/asset/${token.contractAddress}/${token.tokenId}`;
77
- const renderActions = () => {
78
- if (!isOwner && activeOrder && showBuyButton) {
79
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
80
- onBuy && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
81
- "button",
82
- {
83
- className: (0, import_cn.cn)(BTN_SOLID, "flex-1 bg-brand-purple"),
84
- onClick: (e) => {
85
- e.preventDefault();
86
- e.stopPropagation();
87
- onBuy(token);
88
- },
89
- children: [
90
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Zap, { className: "h-3.5 w-3.5 shrink-0" }),
91
- "Buy"
92
- ]
93
- }
94
- ),
95
- onCart && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
96
- "button",
97
- {
98
- className: (0, import_cn.cn)(
99
- BTN_OUTLINE,
100
- "w-8 shrink-0",
101
- inCart && "border-brand-orange/50 bg-brand-orange/10 text-brand-orange"
102
- ),
103
- onClick: (e) => {
104
- e.preventDefault();
105
- e.stopPropagation();
106
- onCart(token);
107
- },
108
- disabled: inCart,
109
- "aria-label": inCart ? "In cart" : "Add to cart",
110
- children: inCart ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Check, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ShoppingCart, { className: "h-3.5 w-3.5" })
111
- }
112
- ),
113
- onOffer && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
114
- "button",
115
- {
116
- className: (0, import_cn.cn)(BTN_OUTLINE, "w-8 shrink-0 text-brand-orange border-brand-orange/40 hover:bg-brand-orange/10"),
117
- onClick: (e) => {
118
- e.preventDefault();
119
- e.stopPropagation();
120
- onOffer(token);
121
- },
122
- "aria-label": "Make an offer",
123
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.HandCoins, { className: "h-3.5 w-3.5" })
124
- }
125
- )
126
- ] });
127
- }
128
- if (!isOwner) {
129
- if (!onOffer) return null;
130
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
131
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_link.default, { href: assetHref, className: (0, import_cn.cn)(BTN_OUTLINE, "flex-1"), children: [
132
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ArrowUpRight, { className: "h-3.5 w-3.5 shrink-0" }),
133
- "View"
134
- ] }),
135
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
136
- "button",
137
- {
138
- className: (0, import_cn.cn)(BTN_OUTLINE, "w-8 shrink-0 text-brand-orange border-brand-orange/40 hover:bg-brand-orange/10"),
139
- onClick: (e) => {
140
- e.preventDefault();
141
- e.stopPropagation();
142
- onOffer(token);
143
- },
144
- "aria-label": "Make an offer",
145
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.HandCoins, { className: "h-3.5 w-3.5" })
146
- }
147
- )
148
- ] });
149
- }
150
- if (isOwner && activeOrder) {
151
- if (!onCancel) return null;
152
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
153
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
154
- "button",
155
- {
156
- className: (0, import_cn.cn)(BTN_SOLID, "flex-1 bg-brand-rose"),
157
- onClick: (e) => {
158
- e.preventDefault();
159
- e.stopPropagation();
160
- onCancel(token);
161
- },
162
- children: [
163
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.X, { className: "h-3.5 w-3.5 shrink-0" }),
164
- "Cancel listing"
165
- ]
166
- }
167
- ),
168
- onTransfer && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
169
- "button",
170
- {
171
- className: (0, import_cn.cn)(BTN_OUTLINE, "w-8 shrink-0"),
172
- onClick: (e) => {
173
- e.preventDefault();
174
- e.stopPropagation();
175
- onTransfer(token);
176
- },
177
- "aria-label": "Transfer",
178
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ArrowRightLeft, { className: "h-3.5 w-3.5" })
179
- }
180
- )
181
- ] });
182
- }
183
- if (isOwner && !activeOrder) {
184
- if (!onList) return null;
185
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
186
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
187
- "button",
63
+ const ipType = token.metadata?.ipType;
64
+ const listingOrder = token.activeOrders?.find(
65
+ (o) => o.offer.itemType === "ERC721" || o.offer.itemType === "ERC1155"
66
+ );
67
+ const creatorAttr = token.metadata?.attributes?.find((a) => a.trait_type === "Creator");
68
+ const creator = typeof creatorAttr?.value === "string" ? creatorAttr.value : null;
69
+ const owner = token.balances?.[0]?.owner ?? token.owner ?? null;
70
+ const chain = token.chain.toUpperCase();
71
+ const assetHref = (0, import_sdk.assetHref)(chain, token.contractAddress, token.tokenId);
72
+ const collectionHref = (0, import_sdk.collectionHref)(chain, token.contractAddress);
73
+ const remixHref = `/create/remix/${token.contractAddress}/${token.tokenId}`;
74
+ const handleBuy = (e) => {
75
+ e.preventDefault();
76
+ e.stopPropagation();
77
+ onBuy?.(token);
78
+ };
79
+ const handleOffer = (e) => {
80
+ e.preventDefault();
81
+ e.stopPropagation();
82
+ onOffer?.(token);
83
+ };
84
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "card-base relative overflow-hidden flex flex-col w-full", children: [
85
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_link.default, { href: assetHref, className: "flex flex-col flex-1", children: [
86
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative aspect-square bg-muted overflow-hidden shrink-0", children: [
87
+ !imgError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
88
+ import_image.default,
188
89
  {
189
- className: (0, import_cn.cn)(BTN_SOLID, "flex-1 bg-brand-blue"),
190
- onClick: (e) => {
191
- e.preventDefault();
192
- e.stopPropagation();
193
- onList(token);
194
- },
195
- children: [
196
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Tag, { className: "h-3.5 w-3.5 shrink-0" }),
197
- "List for sale"
198
- ]
90
+ src: image,
91
+ alt: name,
92
+ fill: true,
93
+ unoptimized: true,
94
+ sizes: "(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 22vw",
95
+ className: "object-cover",
96
+ onError: () => setImgError(true)
199
97
  }
200
- ),
201
- onTransfer && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
98
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute inset-0 flex items-center justify-center bg-gradient-to-br from-brand-purple/15 to-brand-blue/15", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "text-2xl tabular-nums text-muted-foreground", children: [
99
+ "#",
100
+ token.tokenId
101
+ ] }) }),
102
+ listingOrder && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute bottom-2 right-2 z-10", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "inline-flex items-center gap-1 px-2 py-1 rounded-full text-[11px] font-bold bg-background/90 backdrop-blur-sm border border-border/40 shadow-sm", children: [
103
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_currency_icon.CurrencyIcon, { symbol: listingOrder.price.currency ?? "", size: 10 }),
104
+ (0, import_format.formatDisplayPrice)(listingOrder.price.formatted),
105
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-muted-foreground font-normal", children: listingOrder.price.currency })
106
+ ] }) }),
107
+ (token.metadataStatus === "PENDING" || token.metadataStatus === "FETCHING") && /* @__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: [
108
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Loader2, { className: "h-3 w-3 animate-spin text-white/70" }),
109
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-[10px] text-white/70", children: "Indexing\u2026" })
110
+ ] })
111
+ ] }),
112
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-3 pt-2.5 pb-4 flex-1", children: [
113
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-base font-bold line-clamp-2 leading-snug", children: name }),
114
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-1.5 mt-1.5 flex-wrap", children: [
115
+ ipType && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ip_type_badge.IpTypeBadge, { ipType, size: "sm" }),
116
+ creator ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-[10px] tabular-nums text-muted-foreground/60 truncate", children: [
117
+ creator.slice(0, 8),
118
+ "\u2026",
119
+ creator.slice(-6)
120
+ ] }) : token.metadata?.description ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-[10px] text-muted-foreground truncate leading-snug", children: token.metadata.description }) : null
121
+ ] })
122
+ ] })
123
+ ] }),
124
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-3 pb-3 flex items-center gap-1.5", children: [
125
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
126
+ import_link.default,
127
+ {
128
+ href: assetHref,
129
+ className: (0, import_cn.cn)(BTN_OUTLINE, "w-8 shrink-0 px-0"),
130
+ title: "View asset",
131
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ArrowUpRight, { className: "h-3.5 w-3.5" })
132
+ }
133
+ ),
134
+ isOwner ? listingOrder ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_link.default, { href: assetHref, className: (0, import_cn.cn)(BTN_OUTLINE, "flex-1"), children: [
135
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ArrowUpRight, { className: "h-3.5 w-3.5 mr-1.5" }),
136
+ "View"
137
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
138
+ "button",
139
+ {
140
+ className: (0, import_cn.cn)(BTN_OUTLINE, "flex-1 text-brand-purple border-brand-purple/30 hover:bg-brand-purple/10 hover:text-brand-purple"),
141
+ onClick: (e) => {
142
+ e.preventDefault();
143
+ e.stopPropagation();
144
+ onList?.(token);
145
+ },
146
+ children: [
147
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Tag, { className: "h-3.5 w-3.5 mr-1.5" }),
148
+ "List"
149
+ ]
150
+ }
151
+ ) : listingOrder ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "btn-border-animated p-[1.5px] rounded-[10px] flex-1 h-8", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
152
+ "button",
153
+ {
154
+ className: "w-full h-full rounded-[9px] bg-background flex items-center justify-center gap-1.5 text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]",
155
+ onClick: handleBuy,
156
+ children: [
157
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Zap, { className: "h-3.5 w-3.5 shrink-0" }),
158
+ "Buy"
159
+ ]
160
+ }
161
+ ) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
162
+ "button",
163
+ {
164
+ className: (0, import_cn.cn)(BTN_OUTLINE, "flex-1 text-brand-orange border-brand-orange/30 hover:bg-brand-orange/10 hover:text-brand-orange"),
165
+ onClick: handleOffer,
166
+ children: [
167
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.HandCoins, { className: "h-3.5 w-3.5 mr-1.5" }),
168
+ "Offer"
169
+ ]
170
+ }
171
+ ),
172
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_dropdown_menu.DropdownMenu, { children: [
173
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dropdown_menu.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
202
174
  "button",
203
175
  {
204
- className: (0, import_cn.cn)(BTN_OUTLINE, "w-8 shrink-0"),
205
- onClick: (e) => {
206
- e.preventDefault();
207
- e.stopPropagation();
208
- onTransfer(token);
209
- },
210
- "aria-label": "Transfer",
211
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ArrowRightLeft, { className: "h-3.5 w-3.5" })
176
+ className: (0, import_cn.cn)(BTN_OUTLINE, "w-8 p-0 shrink-0"),
177
+ "aria-label": "More actions",
178
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.MoreHorizontal, { className: "h-3.5 w-3.5" })
212
179
  }
213
- )
214
- ] });
215
- }
216
- return null;
217
- };
218
- const actionContent = renderActions();
219
- const showActionBar = actionContent != null || !!overflowMenu;
220
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_motion_primitives.MotionCard, { className: (0, import_cn.cn)("card-base group relative overflow-hidden flex flex-col", className), children: [
221
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_link.default, { href: assetHref, className: "block relative shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative aspect-square bg-muted overflow-hidden", children: [
222
- !imgError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
223
- import_image.default,
224
- {
225
- src: image,
226
- alt: name,
227
- fill: true,
228
- unoptimized: true,
229
- sizes: "(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 22vw",
230
- className: "object-cover transition-transform duration-500 group-hover:scale-105",
231
- onError: () => setImgError(true)
232
- }
233
- ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute inset-0 flex items-center justify-center bg-gradient-to-br from-brand-purple/15 to-brand-blue/15", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "text-2xl font-mono text-muted-foreground", children: [
234
- "#",
235
- token.tokenId
236
- ] }) }),
237
- token.metadata?.ipType && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute top-2 left-2", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ip_type_badge.IpTypeBadge, { ipType: token.metadata.ipType, size: "sm" }) }),
238
- rarityTier && RARITY_STYLE[rarityTier] && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute top-2 right-2 z-10", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: (0, import_cn.cn)(
239
- "inline-flex items-center px-1.5 py-0.5 rounded-md backdrop-blur-sm text-[10px] font-bold leading-none",
240
- RARITY_STYLE[rarityTier].className
241
- ), children: RARITY_STYLE[rarityTier].label }) }),
242
- (token.metadataStatus === "PENDING" || token.metadataStatus === "FETCHING") && /* @__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: [
243
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Loader2, { className: "h-3 w-3 animate-spin text-white/70" }),
244
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-[10px] text-white/70", children: "Indexing\u2026" })
180
+ ) }),
181
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_dropdown_menu.DropdownMenuContent, { align: "end", className: "w-52", children: [
182
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dropdown_menu.DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_link.default, { href: assetHref, className: "flex items-center gap-2", children: [
183
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ArrowUpRight, { className: "h-3.5 w-3.5 text-muted-foreground" }),
184
+ "View asset"
185
+ ] }) }),
186
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dropdown_menu.DropdownMenuSeparator, {}),
187
+ isOwner ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
188
+ !listingOrder && onList && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
189
+ import_dropdown_menu.DropdownMenuItem,
190
+ {
191
+ className: "flex items-center gap-2 text-brand-purple focus:text-brand-purple",
192
+ onClick: () => onList(token),
193
+ children: [
194
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Tag, { className: "h-3.5 w-3.5" }),
195
+ "List"
196
+ ]
197
+ }
198
+ ),
199
+ onTransfer && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
200
+ import_dropdown_menu.DropdownMenuItem,
201
+ {
202
+ className: "flex items-center gap-2",
203
+ onClick: () => onTransfer(token),
204
+ children: [
205
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ArrowRightLeft, { className: "h-3.5 w-3.5 text-muted-foreground" }),
206
+ "Transfer"
207
+ ]
208
+ }
209
+ ),
210
+ listingOrder && onCancel && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
211
+ import_dropdown_menu.DropdownMenuItem,
212
+ {
213
+ className: "flex items-center gap-2 text-brand-orange focus:text-brand-orange",
214
+ onClick: () => onCancel(token),
215
+ children: [
216
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.XCircle, { className: "h-3.5 w-3.5" }),
217
+ "Cancel listing"
218
+ ]
219
+ }
220
+ )
221
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
222
+ listingOrder && onBuy && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
223
+ import_dropdown_menu.DropdownMenuItem,
224
+ {
225
+ className: "flex items-center gap-2 text-brand-blue focus:text-brand-blue",
226
+ onClick: handleBuy,
227
+ children: [
228
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Zap, { className: "h-3.5 w-3.5" }),
229
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "flex items-center gap-1", children: [
230
+ "Buy \u2014",
231
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_currency_icon.CurrencyIcon, { symbol: listingOrder.price.currency, size: 12 }),
232
+ (0, import_format.formatDisplayPrice)(listingOrder.price.formatted)
233
+ ] })
234
+ ]
235
+ }
236
+ ),
237
+ onOffer && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
238
+ import_dropdown_menu.DropdownMenuItem,
239
+ {
240
+ className: "flex items-center gap-2 text-brand-orange focus:text-brand-orange",
241
+ onClick: handleOffer,
242
+ children: [
243
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.HandCoins, { className: "h-3.5 w-3.5" }),
244
+ "Make offer"
245
+ ]
246
+ }
247
+ )
248
+ ] }),
249
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dropdown_menu.DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_link.default, { href: remixHref, className: "flex items-center gap-2 text-brand-purple focus:text-brand-purple", children: [
250
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.GitBranch, { className: "h-3.5 w-3.5" }),
251
+ "Remix"
252
+ ] }) }),
253
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dropdown_menu.DropdownMenuSeparator, {}),
254
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dropdown_menu.DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_link.default, { href: collectionHref, className: "flex items-center gap-2", children: [
255
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Layers, { className: "h-3.5 w-3.5 text-muted-foreground" }),
256
+ "View collection"
257
+ ] }) }),
258
+ (owner ?? creator) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dropdown_menu.DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_link.default, { href: `/account/${owner ?? creator}`, className: "flex items-center gap-2", children: [
259
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.UserCircle2, { className: "h-3.5 w-3.5 text-muted-foreground" }),
260
+ "View owner"
261
+ ] }) }),
262
+ onReport && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
263
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dropdown_menu.DropdownMenuSeparator, {}),
264
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
265
+ import_dropdown_menu.DropdownMenuItem,
266
+ {
267
+ className: "flex items-center gap-2 text-muted-foreground focus:text-muted-foreground",
268
+ onClick: () => onReport(token),
269
+ children: [
270
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Flag, { className: "h-3.5 w-3.5" }),
271
+ "Report"
272
+ ]
273
+ }
274
+ )
275
+ ] })
276
+ ] })
245
277
  ] })
246
- ] }) }),
247
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "px-3 pt-2.5 pb-1 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_link.default, { href: assetHref, className: "block space-y-0.5 mb-2", children: [
248
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xl font-bold line-clamp-2 leading-tight", children: name }),
249
- activeOrder && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "flex items-center gap-1 text-[11px] font-semibold text-foreground/80", children: [
250
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_currency_icon.CurrencyIcon, { symbol: activeOrder.price.currency, size: 11 }),
251
- (0, import_format.formatDisplayPrice)(activeOrder.price.formatted),
252
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "font-normal text-muted-foreground", children: activeOrder.price.currency })
253
- ] }),
254
- token.metadata?.description ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-[10px] text-muted-foreground truncate leading-snug", children: token.metadata.description }) : token.metadata?.ipType ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-[10px] text-muted-foreground opacity-70", children: token.metadata.ipType }) : null
255
- ] }) }),
256
- showActionBar && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-1.5 px-2 pb-2", children: [
257
- actionContent,
258
- overflowMenu
259
278
  ] })
260
279
  ] });
261
280
  }
262
281
  function TokenCardSkeleton() {
263
282
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "card-base overflow-hidden", children: [
264
283
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "aspect-square w-full animate-pulse bg-muted" }),
265
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-3 pt-2.5 pb-2 space-y-1.5", children: [
266
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-5 w-3/4 rounded-md animate-pulse bg-muted" }),
284
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-3 pt-2.5 pb-3 space-y-1.5", children: [
285
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-4 w-3/4 rounded-md animate-pulse bg-muted" }),
267
286
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-2.5 w-2/5 rounded-md animate-pulse bg-muted" })
268
287
  ] }),
269
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-2 pb-2 flex gap-1.5", children: [
270
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-8 flex-1 rounded-[11px] animate-pulse bg-muted" }),
271
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-8 w-8 rounded-[11px] animate-pulse bg-muted shrink-0" }),
272
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-8 w-8 rounded-[11px] animate-pulse bg-muted shrink-0" })
288
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-3 pb-3 flex gap-1.5", children: [
289
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-8 w-8 rounded-[9px] animate-pulse bg-muted shrink-0" }),
290
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-8 flex-1 rounded-[9px] animate-pulse bg-muted" }),
291
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-8 w-8 rounded-[9px] animate-pulse bg-muted shrink-0" })
273
292
  ] })
274
293
  ] });
275
294
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/token-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"next/link\";\nimport Image from \"next/image\";\nimport {\n ShoppingCart, Tag, ArrowRightLeft, X, Loader2, HandCoins,\n Check, ArrowUpRight, Zap,\n} from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { IpTypeBadge } from \"./ip-type-badge.js\";\nimport { MotionCard } from \"./motion-primitives.js\";\nimport type { ApiToken } from \"@medialane/sdk\";\n\nexport type RarityTier = \"legendary\" | \"epic\" | \"rare\" | \"uncommon\" | \"common\";\n\nconst RARITY_STYLE: Record<RarityTier, { label: string; className: string } | null> = {\n legendary: { label: \"Legendary\", className: \"bg-yellow-400/90 text-yellow-900\" },\n epic: { label: \"Epic\", className: \"bg-purple-500/85 text-white\" },\n rare: { label: \"Rare\", className: \"bg-blue-500/85 text-white\" },\n uncommon: { label: \"Uncommon\", className: \"bg-emerald-500/85 text-white\" },\n common: null,\n};\n\nconst BTN_BASE = \"h-8 rounded-[11px] flex items-center justify-center gap-1.5 text-xs font-semibold transition-all active:scale-[0.98] shadow-none border-0\";\nconst BTN_SOLID = cn(BTN_BASE, \"text-white hover:brightness-110\");\nconst BTN_OUTLINE = cn(BTN_BASE, \"border border-border/60 text-foreground hover:bg-muted/60\");\n\nexport interface TokenCardProps {\n token: ApiToken;\n /** Whether the current user owns this token. Default: false */\n isOwner?: boolean;\n /** Whether this token's listing is already in the cart. Default: false */\n inCart?: boolean;\n /** Show the Buy button for listed tokens. Default: true */\n showBuyButton?: boolean;\n /** Optional rarity label shown as an overlay badge */\n rarityTier?: RarityTier;\n className?: string;\n /** Callbacks — omit any to hide that button */\n onBuy?: (token: ApiToken) => void;\n onCart?: (token: ApiToken) => void;\n onOffer?: (token: ApiToken) => void;\n onList?: (token: ApiToken) => void;\n onCancel?: (token: ApiToken) => void;\n onTransfer?: (token: ApiToken) => void;\n onRemix?: (token: ApiToken) => void;\n onReport?: (token: ApiToken) => void;\n /** Slot for a DropdownMenu trigger — rendered after primary buttons */\n overflowMenu?: React.ReactNode;\n}\n\nexport function TokenCard({\n token,\n isOwner = false,\n inCart = false,\n showBuyButton = true,\n rarityTier,\n className,\n onBuy,\n onCart,\n onOffer,\n onList,\n onCancel,\n onTransfer,\n overflowMenu,\n}: TokenCardProps) {\n const [imgError, setImgError] = useState(false);\n\n const name = token.metadata?.name || `Token #${token.tokenId}`;\n const image = ipfsToHttp(token.metadata?.image);\n const activeOrder = token.activeOrders?.[0];\n const assetHref = `/asset/${token.contractAddress}/${token.tokenId}`;\n\n const renderActions = () => {\n // Non-owner + listed + showBuyButton\n if (!isOwner && activeOrder && showBuyButton) {\n return (\n <>\n {onBuy && (\n <button\n className={cn(BTN_SOLID, \"flex-1 bg-brand-purple\")}\n onClick={(e) => { e.preventDefault(); e.stopPropagation(); onBuy(token); }}\n >\n <Zap className=\"h-3.5 w-3.5 shrink-0\" />\n Buy\n </button>\n )}\n {onCart && (\n <button\n className={cn(\n BTN_OUTLINE, \"w-8 shrink-0\",\n inCart && \"border-brand-orange/50 bg-brand-orange/10 text-brand-orange\"\n )}\n onClick={(e) => { e.preventDefault(); e.stopPropagation(); onCart(token); }}\n disabled={inCart}\n aria-label={inCart ? \"In cart\" : \"Add to cart\"}\n >\n {inCart ? <Check className=\"h-3.5 w-3.5\" /> : <ShoppingCart className=\"h-3.5 w-3.5\" />}\n </button>\n )}\n {onOffer && (\n <button\n className={cn(BTN_OUTLINE, \"w-8 shrink-0 text-brand-orange border-brand-orange/40 hover:bg-brand-orange/10\")}\n onClick={(e) => { e.preventDefault(); e.stopPropagation(); onOffer(token); }}\n aria-label=\"Make an offer\"\n >\n <HandCoins className=\"h-3.5 w-3.5\" />\n </button>\n )}\n </>\n );\n }\n\n // Non-owner + no listing (or showBuyButton=false)\n if (!isOwner) {\n if (!onOffer) return null;\n return (\n <>\n <Link href={assetHref} className={cn(BTN_OUTLINE, \"flex-1\")}>\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0\" />\n View\n </Link>\n <button\n className={cn(BTN_OUTLINE, \"w-8 shrink-0 text-brand-orange border-brand-orange/40 hover:bg-brand-orange/10\")}\n onClick={(e) => { e.preventDefault(); e.stopPropagation(); onOffer(token); }}\n aria-label=\"Make an offer\"\n >\n <HandCoins className=\"h-3.5 w-3.5\" />\n </button>\n </>\n );\n }\n\n // Owner + listed\n if (isOwner && activeOrder) {\n if (!onCancel) return null;\n return (\n <>\n <button\n className={cn(BTN_SOLID, \"flex-1 bg-brand-rose\")}\n onClick={(e) => { e.preventDefault(); e.stopPropagation(); onCancel(token); }}\n >\n <X className=\"h-3.5 w-3.5 shrink-0\" />\n Cancel listing\n </button>\n {onTransfer && (\n <button\n className={cn(BTN_OUTLINE, \"w-8 shrink-0\")}\n onClick={(e) => { e.preventDefault(); e.stopPropagation(); onTransfer(token); }}\n aria-label=\"Transfer\"\n >\n <ArrowRightLeft className=\"h-3.5 w-3.5\" />\n </button>\n )}\n </>\n );\n }\n\n // Owner + unlisted\n if (isOwner && !activeOrder) {\n if (!onList) return null;\n return (\n <>\n <button\n className={cn(BTN_SOLID, \"flex-1 bg-brand-blue\")}\n onClick={(e) => { e.preventDefault(); e.stopPropagation(); onList(token); }}\n >\n <Tag className=\"h-3.5 w-3.5 shrink-0\" />\n List for sale\n </button>\n {onTransfer && (\n <button\n className={cn(BTN_OUTLINE, \"w-8 shrink-0\")}\n onClick={(e) => { e.preventDefault(); e.stopPropagation(); onTransfer(token); }}\n aria-label=\"Transfer\"\n >\n <ArrowRightLeft className=\"h-3.5 w-3.5\" />\n </button>\n )}\n </>\n );\n }\n\n return null;\n };\n\n const actionContent = renderActions();\n const showActionBar = actionContent != null || !!overflowMenu;\n\n return (\n <MotionCard className={cn(\"card-base group relative overflow-hidden flex flex-col\", className)}>\n <Link href={assetHref} className=\"block relative shrink-0\">\n <div className=\"relative aspect-square bg-muted overflow-hidden\">\n {!imgError ? (\n <Image\n src={image}\n alt={name}\n fill\n unoptimized\n sizes=\"(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 22vw\"\n className=\"object-cover transition-transform duration-500 group-hover:scale-105\"\n onError={() => setImgError(true)}\n />\n ) : (\n <div className=\"absolute inset-0 flex items-center justify-center bg-gradient-to-br from-brand-purple/15 to-brand-blue/15\">\n <span className=\"text-2xl font-mono text-muted-foreground\">#{token.tokenId}</span>\n </div>\n )}\n\n {token.metadata?.ipType && (\n <div className=\"absolute top-2 left-2\">\n <IpTypeBadge ipType={token.metadata.ipType as any} size=\"sm\" />\n </div>\n )}\n\n {rarityTier && RARITY_STYLE[rarityTier] && (\n <div className=\"absolute top-2 right-2 z-10\">\n <span className={cn(\n \"inline-flex items-center px-1.5 py-0.5 rounded-md backdrop-blur-sm text-[10px] font-bold leading-none\",\n RARITY_STYLE[rarityTier]!.className\n )}>\n {RARITY_STYLE[rarityTier]!.label}\n </span>\n </div>\n )}\n\n {(token.metadataStatus === \"PENDING\" || token.metadataStatus === \"FETCHING\") && (\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-[10px] text-white/70\">Indexing…</span>\n </div>\n )}\n </div>\n </Link>\n\n <div className=\"px-3 pt-2.5 pb-1 flex-1\">\n <Link href={assetHref} className=\"block space-y-0.5 mb-2\">\n <p className=\"text-xl font-bold line-clamp-2 leading-tight\">{name}</p>\n {activeOrder && (\n <p className=\"flex items-center gap-1 text-[11px] font-semibold text-foreground/80\">\n <CurrencyIcon symbol={activeOrder.price.currency} size={11} />\n {formatDisplayPrice(activeOrder.price.formatted)}\n <span className=\"font-normal text-muted-foreground\">{activeOrder.price.currency}</span>\n </p>\n )}\n {token.metadata?.description ? (\n <p className=\"text-[10px] text-muted-foreground truncate leading-snug\">\n {token.metadata.description}\n </p>\n ) : token.metadata?.ipType ? (\n <p className=\"text-[10px] text-muted-foreground opacity-70\">{token.metadata.ipType}</p>\n ) : null}\n </Link>\n </div>\n\n {showActionBar && (\n <div className=\"flex items-center gap-1.5 px-2 pb-2\">\n {actionContent}\n {overflowMenu}\n </div>\n )}\n </MotionCard>\n );\n}\n\nexport function TokenCardSkeleton() {\n return (\n <div className=\"card-base overflow-hidden\">\n <div className=\"aspect-square w-full animate-pulse bg-muted\" />\n <div className=\"px-3 pt-2.5 pb-2 space-y-1.5\">\n <div className=\"h-5 w-3/4 rounded-md animate-pulse bg-muted\" />\n <div className=\"h-2.5 w-2/5 rounded-md animate-pulse bg-muted\" />\n </div>\n <div className=\"px-2 pb-2 flex gap-1.5\">\n <div className=\"h-8 flex-1 rounded-[11px] animate-pulse bg-muted\" />\n <div className=\"h-8 w-8 rounded-[11px] animate-pulse bg-muted shrink-0\" />\n <div className=\"h-8 w-8 rounded-[11px] animate-pulse bg-muted shrink-0\" />\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["Link","Image"]}
1
+ {"version":3,"sources":["../../src/components/token-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"next/link\";\nimport Image from \"next/image\";\nimport {\n Loader2, ArrowUpRight, MoreHorizontal, Zap, HandCoins, Tag,\n Layers, GitBranch, Flag, UserCircle2, ArrowRightLeft, XCircle,\n} from \"lucide-react\";\nimport {\n DropdownMenu, DropdownMenuContent, DropdownMenuItem,\n DropdownMenuSeparator, DropdownMenuTrigger,\n} from \"./dropdown-menu.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { IpTypeBadge } from \"./ip-type-badge.js\";\nimport { assetHref as buildAssetHref, collectionHref as buildCollectionHref } from \"@medialane/sdk\";\nimport type { ApiToken, Chain } from \"@medialane/sdk\";\n\nconst BTN_BASE = \"h-8 rounded-[9px] flex items-center justify-center gap-1.5 text-xs font-semibold transition-all active:scale-[0.98] shadow-none border-0\";\nconst BTN_OUTLINE = cn(BTN_BASE, \"border border-border/60 text-foreground hover:bg-muted/60\");\n\nexport interface TokenCardProps {\n token: ApiToken;\n isOwner?: boolean;\n onList?: (token: ApiToken) => void;\n onTransfer?: (token: ApiToken) => void;\n onCancel?: (token: ApiToken) => void;\n onBuy?: (token: ApiToken) => void;\n onOffer?: (token: ApiToken) => void;\n onReport?: (token: ApiToken) => void;\n}\n\nexport function TokenCard({\n token,\n isOwner = false,\n onList,\n onTransfer,\n onCancel,\n onBuy,\n onOffer,\n onReport,\n}: TokenCardProps) {\n const [imgError, setImgError] = useState(false);\n\n const name = token.metadata?.name || `Token #${token.tokenId}`;\n const image = ipfsToHttp(token.metadata?.image);\n const ipType = token.metadata?.ipType;\n\n // First listing-type active order (offer.itemType = ERC721 or ERC1155)\n const listingOrder = token.activeOrders?.find(\n (o) => o.offer.itemType === \"ERC721\" || o.offer.itemType === \"ERC1155\"\n );\n\n const creatorAttr = token.metadata?.attributes?.find((a) => a.trait_type === \"Creator\");\n const creator = typeof creatorAttr?.value === \"string\" ? creatorAttr.value : null;\n const owner = token.balances?.[0]?.owner ?? token.owner ?? null;\n\n const chain = token.chain.toUpperCase() as Chain;\n const assetHref = buildAssetHref(chain, token.contractAddress, token.tokenId);\n const collectionHref = buildCollectionHref(chain, token.contractAddress);\n const remixHref = `/create/remix/${token.contractAddress}/${token.tokenId}`;\n\n const handleBuy = (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n onBuy?.(token);\n };\n\n const handleOffer = (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n onOffer?.(token);\n };\n\n return (\n <div className=\"card-base relative overflow-hidden flex flex-col w-full\">\n\n {/* ── Clickable image + info ─────────────────────────────── */}\n <Link href={assetHref} className=\"flex flex-col flex-1\">\n\n {/* Image */}\n <div className=\"relative aspect-square bg-muted overflow-hidden shrink-0\">\n {!imgError ? (\n <Image\n src={image}\n alt={name}\n fill\n unoptimized\n sizes=\"(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 22vw\"\n className=\"object-cover\"\n onError={() => setImgError(true)}\n />\n ) : (\n <div className=\"absolute inset-0 flex items-center justify-center bg-gradient-to-br from-brand-purple/15 to-brand-blue/15\">\n <span className=\"text-2xl tabular-nums text-muted-foreground\">#{token.tokenId}</span>\n </div>\n )}\n\n {/* Price chip — bottom right overlay */}\n {listingOrder && (\n <div className=\"absolute bottom-2 right-2 z-10\">\n <span className=\"inline-flex items-center gap-1 px-2 py-1 rounded-full text-[11px] font-bold bg-background/90 backdrop-blur-sm border border-border/40 shadow-sm\">\n <CurrencyIcon symbol={listingOrder.price.currency ?? \"\"} size={10} />\n {formatDisplayPrice(listingOrder.price.formatted)}\n <span className=\"text-muted-foreground font-normal\">{listingOrder.price.currency}</span>\n </span>\n </div>\n )}\n\n {/* Indexing indicator */}\n {(token.metadataStatus === \"PENDING\" || token.metadataStatus === \"FETCHING\") && (\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-[10px] text-white/70\">Indexing…</span>\n </div>\n )}\n </div>\n\n {/* Info */}\n <div className=\"px-3 pt-2.5 pb-4 flex-1\">\n <p className=\"text-base font-bold line-clamp-2 leading-snug\">{name}</p>\n <div className=\"flex items-center gap-1.5 mt-1.5 flex-wrap\">\n {ipType && <IpTypeBadge ipType={ipType as any} size=\"sm\" />}\n {creator ? (\n <p className=\"text-[10px] tabular-nums text-muted-foreground/60 truncate\">\n {creator.slice(0, 8)}…{creator.slice(-6)}\n </p>\n ) : token.metadata?.description ? (\n <p className=\"text-[10px] text-muted-foreground truncate leading-snug\">\n {token.metadata.description}\n </p>\n ) : null}\n </div>\n </div>\n </Link>\n\n {/* ── Action row ────────────────────────────────────────── */}\n <div className=\"px-3 pb-3 flex items-center gap-1.5\">\n\n {/* Expand */}\n <Link\n href={assetHref}\n className={cn(BTN_OUTLINE, \"w-8 shrink-0 px-0\")}\n title=\"View asset\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5\" />\n </Link>\n\n {/* Owner: List (or Listed label) — Buyer: Buy / Make offer */}\n {isOwner ? (\n listingOrder ? (\n <Link href={assetHref} className={cn(BTN_OUTLINE, \"flex-1\")}>\n <ArrowUpRight className=\"h-3.5 w-3.5 mr-1.5\" />\n View\n </Link>\n ) : (\n <button\n className={cn(BTN_OUTLINE, \"flex-1 text-brand-purple border-brand-purple/30 hover:bg-brand-purple/10 hover:text-brand-purple\")}\n onClick={(e) => { e.preventDefault(); e.stopPropagation(); onList?.(token); }}\n >\n <Tag className=\"h-3.5 w-3.5 mr-1.5\" />\n List\n </button>\n )\n ) : listingOrder ? (\n <div className=\"btn-border-animated p-[1.5px] rounded-[10px] flex-1 h-8\">\n <button\n className=\"w-full h-full rounded-[9px] bg-background flex items-center justify-center gap-1.5 text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n onClick={handleBuy}\n >\n <Zap className=\"h-3.5 w-3.5 shrink-0\" />\n Buy\n </button>\n </div>\n ) : (\n <button\n className={cn(BTN_OUTLINE, \"flex-1 text-brand-orange border-brand-orange/30 hover:bg-brand-orange/10 hover:text-brand-orange\")}\n onClick={handleOffer}\n >\n <HandCoins className=\"h-3.5 w-3.5 mr-1.5\" />\n Offer\n </button>\n )}\n\n {/* 3-dot menu */}\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n className={cn(BTN_OUTLINE, \"w-8 p-0 shrink-0\")}\n aria-label=\"More actions\"\n >\n <MoreHorizontal className=\"h-3.5 w-3.5\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-52\">\n\n <DropdownMenuItem asChild>\n <Link href={assetHref} className=\"flex items-center gap-2\">\n <ArrowUpRight className=\"h-3.5 w-3.5 text-muted-foreground\" />\n View asset\n </Link>\n </DropdownMenuItem>\n\n <DropdownMenuSeparator />\n\n {isOwner ? (\n <>\n {!listingOrder && onList && (\n <DropdownMenuItem\n className=\"flex items-center gap-2 text-brand-purple focus:text-brand-purple\"\n onClick={() => onList(token)}\n >\n <Tag className=\"h-3.5 w-3.5\" />\n List\n </DropdownMenuItem>\n )}\n {onTransfer && (\n <DropdownMenuItem\n className=\"flex items-center gap-2\"\n onClick={() => onTransfer(token)}\n >\n <ArrowRightLeft className=\"h-3.5 w-3.5 text-muted-foreground\" />\n Transfer\n </DropdownMenuItem>\n )}\n {listingOrder && onCancel && (\n <DropdownMenuItem\n className=\"flex items-center gap-2 text-brand-orange focus:text-brand-orange\"\n onClick={() => onCancel(token)}\n >\n <XCircle className=\"h-3.5 w-3.5\" />\n Cancel listing\n </DropdownMenuItem>\n )}\n </>\n ) : (\n <>\n {listingOrder && onBuy && (\n <DropdownMenuItem\n className=\"flex items-center gap-2 text-brand-blue focus:text-brand-blue\"\n onClick={handleBuy}\n >\n <Zap className=\"h-3.5 w-3.5\" />\n <span className=\"flex items-center gap-1\">\n Buy —\n <CurrencyIcon symbol={listingOrder.price.currency} size={12} />\n {formatDisplayPrice(listingOrder.price.formatted)}\n </span>\n </DropdownMenuItem>\n )}\n {onOffer && (\n <DropdownMenuItem\n className=\"flex items-center gap-2 text-brand-orange focus:text-brand-orange\"\n onClick={handleOffer}\n >\n <HandCoins className=\"h-3.5 w-3.5\" />\n Make offer\n </DropdownMenuItem>\n )}\n </>\n )}\n\n <DropdownMenuItem asChild>\n <Link href={remixHref} className=\"flex items-center gap-2 text-brand-purple focus:text-brand-purple\">\n <GitBranch className=\"h-3.5 w-3.5\" />\n Remix\n </Link>\n </DropdownMenuItem>\n\n <DropdownMenuSeparator />\n\n <DropdownMenuItem asChild>\n <Link href={collectionHref} className=\"flex items-center gap-2\">\n <Layers className=\"h-3.5 w-3.5 text-muted-foreground\" />\n View collection\n </Link>\n </DropdownMenuItem>\n\n {(owner ?? creator) && (\n <DropdownMenuItem asChild>\n <Link href={`/account/${owner ?? creator}`} className=\"flex items-center gap-2\">\n <UserCircle2 className=\"h-3.5 w-3.5 text-muted-foreground\" />\n View owner\n </Link>\n </DropdownMenuItem>\n )}\n\n {onReport && (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n className=\"flex items-center gap-2 text-muted-foreground focus:text-muted-foreground\"\n onClick={() => onReport(token)}\n >\n <Flag className=\"h-3.5 w-3.5\" />\n Report\n </DropdownMenuItem>\n </>\n )}\n\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </div>\n );\n}\n\nexport function TokenCardSkeleton() {\n return (\n <div className=\"card-base overflow-hidden\">\n <div className=\"aspect-square w-full animate-pulse bg-muted\" />\n <div className=\"px-3 pt-2.5 pb-3 space-y-1.5\">\n <div className=\"h-4 w-3/4 rounded-md animate-pulse bg-muted\" />\n <div className=\"h-2.5 w-2/5 rounded-md animate-pulse bg-muted\" />\n </div>\n <div className=\"px-3 pb-3 flex gap-1.5\">\n <div className=\"h-8 w-8 rounded-[9px] animate-pulse bg-muted shrink-0\" />\n <div className=\"h-8 flex-1 rounded-[9px] animate-pulse bg-muted\" />\n <div className=\"h-8 w-8 rounded-[9px] animate-pulse bg-muted shrink-0\" />\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["buildAssetHref","buildCollectionHref","Link","Image"]}
@@ -1,31 +1,17 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ApiToken } from '@medialane/sdk';
3
3
 
4
- type RarityTier = "legendary" | "epic" | "rare" | "uncommon" | "common";
5
4
  interface TokenCardProps {
6
5
  token: ApiToken;
7
- /** Whether the current user owns this token. Default: false */
8
6
  isOwner?: boolean;
9
- /** Whether this token's listing is already in the cart. Default: false */
10
- inCart?: boolean;
11
- /** Show the Buy button for listed tokens. Default: true */
12
- showBuyButton?: boolean;
13
- /** Optional rarity label shown as an overlay badge */
14
- rarityTier?: RarityTier;
15
- className?: string;
16
- /** Callbacks — omit any to hide that button */
17
- onBuy?: (token: ApiToken) => void;
18
- onCart?: (token: ApiToken) => void;
19
- onOffer?: (token: ApiToken) => void;
20
7
  onList?: (token: ApiToken) => void;
21
- onCancel?: (token: ApiToken) => void;
22
8
  onTransfer?: (token: ApiToken) => void;
23
- onRemix?: (token: ApiToken) => void;
9
+ onCancel?: (token: ApiToken) => void;
10
+ onBuy?: (token: ApiToken) => void;
11
+ onOffer?: (token: ApiToken) => void;
24
12
  onReport?: (token: ApiToken) => void;
25
- /** Slot for a DropdownMenu trigger — rendered after primary buttons */
26
- overflowMenu?: React.ReactNode;
27
13
  }
28
- declare function TokenCard({ token, isOwner, inCart, showBuyButton, rarityTier, className, onBuy, onCart, onOffer, onList, onCancel, onTransfer, overflowMenu, }: TokenCardProps): react_jsx_runtime.JSX.Element;
14
+ declare function TokenCard({ token, isOwner, onList, onTransfer, onCancel, onBuy, onOffer, onReport, }: TokenCardProps): react_jsx_runtime.JSX.Element;
29
15
  declare function TokenCardSkeleton(): react_jsx_runtime.JSX.Element;
30
16
 
31
- export { type RarityTier, TokenCard, type TokenCardProps, TokenCardSkeleton };
17
+ export { TokenCard, type TokenCardProps, TokenCardSkeleton };