@medialane/ui 0.300.0 → 0.302.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/account/input-otp.d.cts +2 -2
- package/dist/components/account/input-otp.d.ts +2 -2
- package/dist/components/button.d.cts +2 -2
- package/dist/components/button.d.ts +2 -2
- package/dist/components/collection-page.cjs +2 -11
- package/dist/components/collection-page.cjs.map +1 -1
- package/dist/components/collection-page.js +2 -11
- package/dist/components/collection-page.js.map +1 -1
- package/dist/components/collection-provenance-tab.cjs +207 -0
- package/dist/components/collection-provenance-tab.cjs.map +1 -0
- package/dist/components/collection-provenance-tab.d.cts +8 -0
- package/dist/components/collection-provenance-tab.d.ts +8 -0
- package/dist/components/collection-provenance-tab.js +173 -0
- package/dist/components/collection-provenance-tab.js.map +1 -0
- package/dist/components/fast-mint/fast-mint.d.cts +2 -2
- package/dist/components/fast-mint/fast-mint.d.ts +2 -2
- package/dist/components/launchpad/edition-mint-schema.d.cts +2 -2
- package/dist/components/launchpad/edition-mint-schema.d.ts +2 -2
- package/dist/components/sheet.d.cts +1 -1
- package/dist/components/sheet.d.ts +1 -1
- package/dist/data/activity.cjs +6 -6
- package/dist/data/activity.cjs.map +1 -1
- package/dist/data/activity.js +6 -6
- package/dist/data/activity.js.map +1 -1
- package/dist/index.cjs +3 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -2
- package/dist/index.d.ts +1 -2
- package/dist/index.js +2 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/components/collection-activity-tab.cjs +0 -60
- package/dist/components/collection-activity-tab.cjs.map +0 -1
- package/dist/components/collection-activity-tab.d.cts +0 -8
- package/dist/components/collection-activity-tab.d.ts +0 -8
- package/dist/components/collection-activity-tab.js +0 -36
- package/dist/components/collection-activity-tab.js.map +0 -1
- package/dist/components/collection-traits-tab.cjs +0 -79
- package/dist/components/collection-traits-tab.cjs.map +0 -1
- package/dist/components/collection-traits-tab.d.cts +0 -8
- package/dist/components/collection-traits-tab.d.ts +0 -8
- package/dist/components/collection-traits-tab.js +0 -55
- package/dist/components/collection-traits-tab.js.map +0 -1
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
var collection_provenance_tab_exports = {};
|
|
31
|
+
__export(collection_provenance_tab_exports, {
|
|
32
|
+
CollectionProvenanceTab: () => CollectionProvenanceTab
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(collection_provenance_tab_exports);
|
|
35
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
36
|
+
var import_react = require("react");
|
|
37
|
+
var import_sdk = require("@medialane/sdk");
|
|
38
|
+
var import_lucide_react = require("lucide-react");
|
|
39
|
+
var import_image = __toESM(require("./image.js"), 1);
|
|
40
|
+
var import_link = __toESM(require("./link.js"), 1);
|
|
41
|
+
var import_address_display = require("./address-display.js");
|
|
42
|
+
var import_currency_icon = require("./currency-icon.js");
|
|
43
|
+
var import_load_more_sentinel = require("./load-more-sentinel.js");
|
|
44
|
+
var import_use_activities = require("../utils/use-activities.js");
|
|
45
|
+
var import_use_image_url = require("../utils/use-image-url.js");
|
|
46
|
+
var import_activity = require("../data/activity.js");
|
|
47
|
+
var import_explorer_url = require("../utils/explorer-url.js");
|
|
48
|
+
var import_format = require("../utils/format.js");
|
|
49
|
+
var import_time = require("../utils/time.js");
|
|
50
|
+
var import_cn = require("../utils/cn.js");
|
|
51
|
+
const PAGE_SIZE = 30;
|
|
52
|
+
const EVENT_TITLE = {
|
|
53
|
+
mint: "Minted",
|
|
54
|
+
listing: "Listed for sale",
|
|
55
|
+
sale: "Purchased",
|
|
56
|
+
offer: "Offer made",
|
|
57
|
+
transfer: "Transferred",
|
|
58
|
+
cancelled: "Listing cancelled"
|
|
59
|
+
};
|
|
60
|
+
function dayLabel(iso) {
|
|
61
|
+
const date = new Date(iso);
|
|
62
|
+
const today = /* @__PURE__ */ new Date();
|
|
63
|
+
const yesterday = /* @__PURE__ */ new Date();
|
|
64
|
+
yesterday.setDate(today.getDate() - 1);
|
|
65
|
+
if (date.toDateString() === today.toDateString()) return "Today";
|
|
66
|
+
if (date.toDateString() === yesterday.toDateString()) return "Yesterday";
|
|
67
|
+
return date.toLocaleDateString(void 0, { day: "numeric", month: "long", year: "numeric" });
|
|
68
|
+
}
|
|
69
|
+
function groupByDay(events) {
|
|
70
|
+
const groups = [];
|
|
71
|
+
for (const event of events) {
|
|
72
|
+
const label = dayLabel(event.timestamp);
|
|
73
|
+
const last = groups[groups.length - 1];
|
|
74
|
+
if (last && last.label === label) last.events.push(event);
|
|
75
|
+
else groups.push({ label, events: [event] });
|
|
76
|
+
}
|
|
77
|
+
return groups;
|
|
78
|
+
}
|
|
79
|
+
function ProvenanceEvent({ event, showAsset }) {
|
|
80
|
+
const resolveImage = (0, import_use_image_url.useImageUrl)();
|
|
81
|
+
const config = import_activity.ACTIVITY_TYPE_CONFIG[event.type];
|
|
82
|
+
const Icon = config?.icon ?? import_lucide_react.ExternalLink;
|
|
83
|
+
const contract = event.nftContract ?? event.contractAddress ?? null;
|
|
84
|
+
const tokenId = event.nftTokenId ?? event.tokenId ?? null;
|
|
85
|
+
const actor = event.offerer ?? event.fulfiller ?? (event.type === "mint" ? event.to : event.from) ?? null;
|
|
86
|
+
const amount = event.amount && Number(event.amount) > 1 ? event.amount : null;
|
|
87
|
+
const name = event.token?.name ?? (tokenId ? `#${tokenId}` : null);
|
|
88
|
+
const image = resolveImage(event.token?.image ?? null);
|
|
89
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", { className: "flex items-center gap-4 rounded-2xl border border-border/50 bg-card/60 p-4 backdrop-blur-sm transition-colors hover:bg-card/90", children: [
|
|
90
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
91
|
+
"span",
|
|
92
|
+
{
|
|
93
|
+
className: (0, import_cn.cn)(
|
|
94
|
+
"flex h-11 w-11 shrink-0 items-center justify-center rounded-xl",
|
|
95
|
+
config?.bgClass ?? "bg-muted"
|
|
96
|
+
),
|
|
97
|
+
"aria-hidden": true,
|
|
98
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { className: (0, import_cn.cn)("h-5 w-5", config?.colorClass ?? "text-muted-foreground") })
|
|
99
|
+
}
|
|
100
|
+
),
|
|
101
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
102
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "flex flex-wrap items-baseline gap-x-1.5 text-base font-semibold leading-tight", children: [
|
|
103
|
+
EVENT_TITLE[event.type] ?? event.type,
|
|
104
|
+
amount ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "text-sm font-medium text-muted-foreground", children: [
|
|
105
|
+
"\xD7",
|
|
106
|
+
amount
|
|
107
|
+
] }) : null,
|
|
108
|
+
actor ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "text-sm font-normal text-muted-foreground", children: [
|
|
109
|
+
"by",
|
|
110
|
+
" ",
|
|
111
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
112
|
+
import_link.default,
|
|
113
|
+
{
|
|
114
|
+
href: (0, import_sdk.profileHref)({ address: actor }),
|
|
115
|
+
className: "font-medium text-foreground/80 hover:text-primary transition-colors",
|
|
116
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_address_display.AddressDisplay, { address: actor, chars: 6, showCopy: false, className: "text-sm" })
|
|
117
|
+
}
|
|
118
|
+
)
|
|
119
|
+
] }) : null
|
|
120
|
+
] }),
|
|
121
|
+
showAsset && name ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
122
|
+
import_link.default,
|
|
123
|
+
{
|
|
124
|
+
href: contract && tokenId ? (0, import_sdk.assetHref)(event.chain ?? "STARKNET", contract, tokenId) : "#",
|
|
125
|
+
className: "mt-2 inline-flex max-w-full items-center gap-2 rounded-full bg-muted/70 py-1 pl-1 pr-3 hover:bg-muted transition-colors",
|
|
126
|
+
children: [
|
|
127
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "relative h-6 w-6 shrink-0 overflow-hidden rounded-full bg-muted", children: image ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_image.default, { src: image, alt: "", width: 24, height: 24, className: "h-full w-full object-cover", unoptimized: true }) : null }),
|
|
128
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "truncate text-xs font-medium", children: name })
|
|
129
|
+
]
|
|
130
|
+
}
|
|
131
|
+
) : null
|
|
132
|
+
] }),
|
|
133
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex shrink-0 flex-col items-end gap-1", children: [
|
|
134
|
+
event.price?.formatted ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "flex items-center gap-1.5 text-base font-bold tabular-nums", children: [
|
|
135
|
+
event.price.currency ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_currency_icon.CurrencyIcon, { symbol: event.price.currency, size: 15, "aria-hidden": true }) : null,
|
|
136
|
+
(0, import_format.formatDisplayPrice)(event.price.formatted),
|
|
137
|
+
event.price.currency ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-xs font-medium text-muted-foreground", children: event.price.currency }) : null
|
|
138
|
+
] }) : null,
|
|
139
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "flex items-center gap-1 text-xs text-muted-foreground", children: [
|
|
140
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("time", { dateTime: event.timestamp, title: new Date(event.timestamp).toLocaleString(), children: (0, import_time.timeAgo)(event.timestamp) }),
|
|
141
|
+
event.txHash ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
142
|
+
"a",
|
|
143
|
+
{
|
|
144
|
+
href: `${import_explorer_url.EXPLORER_URL}/tx/${event.txHash}`,
|
|
145
|
+
target: "_blank",
|
|
146
|
+
rel: "noopener noreferrer",
|
|
147
|
+
className: "rounded-md p-1 hover:bg-muted hover:text-foreground transition-colors",
|
|
148
|
+
"aria-label": "View transaction",
|
|
149
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ExternalLink, { className: "h-3.5 w-3.5", "aria-hidden": true })
|
|
150
|
+
}
|
|
151
|
+
) : null
|
|
152
|
+
] })
|
|
153
|
+
] })
|
|
154
|
+
] });
|
|
155
|
+
}
|
|
156
|
+
function ProvenanceSkeleton() {
|
|
157
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "space-y-2.5", "aria-hidden": true, children: Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-4 rounded-2xl border border-border/50 bg-card/60 p-4", children: [
|
|
158
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-11 w-11 shrink-0 rounded-xl bg-muted animate-pulse" }),
|
|
159
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex-1 space-y-2", children: [
|
|
160
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-4 w-44 rounded bg-muted animate-pulse" }),
|
|
161
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-3 w-24 rounded bg-muted animate-pulse" })
|
|
162
|
+
] }),
|
|
163
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-4 w-16 rounded bg-muted animate-pulse" })
|
|
164
|
+
] }, i)) });
|
|
165
|
+
}
|
|
166
|
+
function CollectionProvenanceTab({ contract }) {
|
|
167
|
+
const [page, setPage] = (0, import_react.useState)(1);
|
|
168
|
+
const [all, setAll] = (0, import_react.useState)([]);
|
|
169
|
+
const { activities, meta, isLoading } = (0, import_use_activities.useActivities)({ contract, page, limit: PAGE_SIZE });
|
|
170
|
+
(0, import_react.useEffect)(() => {
|
|
171
|
+
if (activities.length === 0) return;
|
|
172
|
+
setAll((prev) => page === 1 ? activities : [...prev, ...activities]);
|
|
173
|
+
}, [activities, page]);
|
|
174
|
+
const groups = (0, import_react.useMemo)(() => groupByDay(all), [all]);
|
|
175
|
+
const showAsset = (0, import_react.useMemo)(
|
|
176
|
+
() => new Set(all.map((e) => e.nftTokenId ?? e.tokenId ?? "")).size > 1,
|
|
177
|
+
[all]
|
|
178
|
+
);
|
|
179
|
+
const hasMore = meta ? all.length < (meta.total ?? 0) : false;
|
|
180
|
+
if (isLoading && all.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ProvenanceSkeleton, {});
|
|
181
|
+
if (all.length === 0) {
|
|
182
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "py-20 flex flex-col items-center gap-3 text-center", children: [
|
|
183
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Inbox, { className: "h-10 w-10 text-muted-foreground/40" }),
|
|
184
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm font-medium text-muted-foreground", children: "No history yet" }),
|
|
185
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs text-muted-foreground/70 max-w-xs", children: "Mints, transfers, listings and sales will appear here as they happen." })
|
|
186
|
+
] });
|
|
187
|
+
}
|
|
188
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-8", children: [
|
|
189
|
+
groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { children: [
|
|
190
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "mb-3 font-display text-lg font-bold", children: group.label }),
|
|
191
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { className: "space-y-2.5", children: group.events.map((event, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
192
|
+
ProvenanceEvent,
|
|
193
|
+
{
|
|
194
|
+
event,
|
|
195
|
+
showAsset
|
|
196
|
+
},
|
|
197
|
+
`${event.txHash ?? event.orderHash}-${event.type}-${i}`
|
|
198
|
+
)) })
|
|
199
|
+
] }, group.label)),
|
|
200
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_load_more_sentinel.LoadMoreSentinel, { hasMore, isLoading, onLoadMore: () => setPage((p) => p + 1) })
|
|
201
|
+
] });
|
|
202
|
+
}
|
|
203
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
204
|
+
0 && (module.exports = {
|
|
205
|
+
CollectionProvenanceTab
|
|
206
|
+
});
|
|
207
|
+
//# sourceMappingURL=collection-provenance-tab.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/collection-provenance-tab.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState, useEffect, useMemo } from \"react\";\nimport type { ApiActivity } from \"@medialane/sdk\";\nimport { assetHref, profileHref } from \"@medialane/sdk\";\nimport { ExternalLink, Inbox } from \"lucide-react\";\nimport Image from \"./image.js\";\nimport Link from \"./link.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { LoadMoreSentinel } from \"./load-more-sentinel.js\";\nimport { useActivities } from \"../utils/use-activities.js\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\nimport { ACTIVITY_TYPE_CONFIG } from \"../data/activity.js\";\nimport { EXPLORER_URL } from \"../utils/explorer-url.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { cn } from \"../utils/cn.js\";\n\nconst PAGE_SIZE = 30;\n\nconst EVENT_TITLE: Record<string, string> = {\n mint: \"Minted\",\n listing: \"Listed for sale\",\n sale: \"Purchased\",\n offer: \"Offer made\",\n transfer: \"Transferred\",\n cancelled: \"Listing cancelled\",\n};\n\nfunction dayLabel(iso: string): string {\n const date = new Date(iso);\n const today = new Date();\n const yesterday = new Date();\n yesterday.setDate(today.getDate() - 1);\n if (date.toDateString() === today.toDateString()) return \"Today\";\n if (date.toDateString() === yesterday.toDateString()) return \"Yesterday\";\n return date.toLocaleDateString(undefined, { day: \"numeric\", month: \"long\", year: \"numeric\" });\n}\n\nfunction groupByDay(events: ApiActivity[]) {\n const groups: { label: string; events: ApiActivity[] }[] = [];\n for (const event of events) {\n const label = dayLabel(event.timestamp);\n const last = groups[groups.length - 1];\n if (last && last.label === label) last.events.push(event);\n else groups.push({ label, events: [event] });\n }\n return groups;\n}\n\nfunction ProvenanceEvent({ event, showAsset }: { event: ApiActivity; showAsset: boolean }) {\n const resolveImage = useImageUrl();\n const config = ACTIVITY_TYPE_CONFIG[event.type];\n const Icon = config?.icon ?? ExternalLink;\n const contract = event.nftContract ?? event.contractAddress ?? null;\n const tokenId = event.nftTokenId ?? event.tokenId ?? null;\n const actor =\n event.offerer ?? event.fulfiller ?? (event.type === \"mint\" ? event.to : event.from) ?? null;\n const amount = event.amount && Number(event.amount) > 1 ? event.amount : null;\n const name = event.token?.name ?? (tokenId ? `#${tokenId}` : null);\n const image = resolveImage(event.token?.image ?? null);\n\n return (\n <li className=\"flex items-center gap-4 rounded-2xl border border-border/50 bg-card/60 p-4 backdrop-blur-sm transition-colors hover:bg-card/90\">\n <span\n className={cn(\n \"flex h-11 w-11 shrink-0 items-center justify-center rounded-xl\",\n config?.bgClass ?? \"bg-muted\"\n )}\n aria-hidden\n >\n <Icon className={cn(\"h-5 w-5\", config?.colorClass ?? \"text-muted-foreground\")} />\n </span>\n\n <div className=\"min-w-0 flex-1\">\n <p className=\"flex flex-wrap items-baseline gap-x-1.5 text-base font-semibold leading-tight\">\n {EVENT_TITLE[event.type] ?? event.type}\n {amount ? <span className=\"text-sm font-medium text-muted-foreground\">×{amount}</span> : null}\n {actor ? (\n <span className=\"text-sm font-normal text-muted-foreground\">\n by{\" \"}\n <Link\n href={profileHref({ address: actor })}\n className=\"font-medium text-foreground/80 hover:text-primary transition-colors\"\n >\n <AddressDisplay address={actor} chars={6} showCopy={false} className=\"text-sm\" />\n </Link>\n </span>\n ) : null}\n </p>\n\n {showAsset && name ? (\n <Link\n href={contract && tokenId ? assetHref(event.chain ?? \"STARKNET\", contract, tokenId) : \"#\"}\n className=\"mt-2 inline-flex max-w-full items-center gap-2 rounded-full bg-muted/70 py-1 pl-1 pr-3 hover:bg-muted transition-colors\"\n >\n <span className=\"relative h-6 w-6 shrink-0 overflow-hidden rounded-full bg-muted\">\n {image ? (\n <Image src={image} alt=\"\" width={24} height={24} className=\"h-full w-full object-cover\" unoptimized />\n ) : null}\n </span>\n <span className=\"truncate text-xs font-medium\">{name}</span>\n </Link>\n ) : null}\n </div>\n\n <div className=\"flex shrink-0 flex-col items-end gap-1\">\n {event.price?.formatted ? (\n <span className=\"flex items-center gap-1.5 text-base font-bold tabular-nums\">\n {event.price.currency ? <CurrencyIcon symbol={event.price.currency} size={15} aria-hidden /> : null}\n {formatDisplayPrice(event.price.formatted)}\n {event.price.currency ? (\n <span className=\"text-xs font-medium text-muted-foreground\">{event.price.currency}</span>\n ) : null}\n </span>\n ) : null}\n <span className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n <time dateTime={event.timestamp} title={new Date(event.timestamp).toLocaleString()}>\n {timeAgo(event.timestamp)}\n </time>\n {event.txHash ? (\n <a\n href={`${EXPLORER_URL}/tx/${event.txHash}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"rounded-md p-1 hover:bg-muted hover:text-foreground transition-colors\"\n aria-label=\"View transaction\"\n >\n <ExternalLink className=\"h-3.5 w-3.5\" aria-hidden />\n </a>\n ) : null}\n </span>\n </div>\n </li>\n );\n}\n\nfunction ProvenanceSkeleton() {\n return (\n <div className=\"space-y-2.5\" aria-hidden>\n {Array.from({ length: 5 }).map((_, i) => (\n <div key={i} className=\"flex items-center gap-4 rounded-2xl border border-border/50 bg-card/60 p-4\">\n <div className=\"h-11 w-11 shrink-0 rounded-xl bg-muted animate-pulse\" />\n <div className=\"flex-1 space-y-2\">\n <div className=\"h-4 w-44 rounded bg-muted animate-pulse\" />\n <div className=\"h-3 w-24 rounded bg-muted animate-pulse\" />\n </div>\n <div className=\"h-4 w-16 rounded bg-muted animate-pulse\" />\n </div>\n ))}\n </div>\n );\n}\n\nexport interface CollectionProvenanceTabProps {\n contract: string;\n}\n\nexport function CollectionProvenanceTab({ contract }: CollectionProvenanceTabProps) {\n const [page, setPage] = useState(1);\n const [all, setAll] = useState<ApiActivity[]>([]);\n const { activities, meta, isLoading } = useActivities({ contract, page, limit: PAGE_SIZE });\n\n useEffect(() => {\n if (activities.length === 0) return;\n setAll((prev) => (page === 1 ? activities : [...prev, ...activities]));\n }, [activities, page]);\n\n const groups = useMemo(() => groupByDay(all), [all]);\n const showAsset = useMemo(\n () => new Set(all.map((e) => e.nftTokenId ?? e.tokenId ?? \"\")).size > 1,\n [all]\n );\n const hasMore = meta ? all.length < (meta.total ?? 0) : false;\n\n if (isLoading && all.length === 0) return <ProvenanceSkeleton />;\n\n if (all.length === 0) {\n return (\n <div className=\"py-20 flex flex-col items-center gap-3 text-center\">\n <Inbox className=\"h-10 w-10 text-muted-foreground/40\" />\n <p className=\"text-sm font-medium text-muted-foreground\">No history yet</p>\n <p className=\"text-xs text-muted-foreground/70 max-w-xs\">\n Mints, transfers, listings and sales will appear here as they happen.\n </p>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-8\">\n {groups.map((group) => (\n <section key={group.label}>\n <h3 className=\"mb-3 font-display text-lg font-bold\">{group.label}</h3>\n <ol className=\"space-y-2.5\">\n {group.events.map((event, i) => (\n <ProvenanceEvent\n key={`${event.txHash ?? event.orderHash}-${event.type}-${i}`}\n event={event}\n showAsset={showAsset}\n />\n ))}\n </ol>\n </section>\n ))}\n <LoadMoreSentinel hasMore={hasMore} isLoading={isLoading} onLoadMore={() => setPage((p) => p + 1)} />\n </div>\n );\n}\n"],"mappings":"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","names":["Link","Image"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
interface CollectionProvenanceTabProps {
|
|
4
|
+
contract: string;
|
|
5
|
+
}
|
|
6
|
+
declare function CollectionProvenanceTab({ contract }: CollectionProvenanceTabProps): react_jsx_runtime.JSX.Element;
|
|
7
|
+
|
|
8
|
+
export { CollectionProvenanceTab, type CollectionProvenanceTabProps };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
interface CollectionProvenanceTabProps {
|
|
4
|
+
contract: string;
|
|
5
|
+
}
|
|
6
|
+
declare function CollectionProvenanceTab({ contract }: CollectionProvenanceTabProps): react_jsx_runtime.JSX.Element;
|
|
7
|
+
|
|
8
|
+
export { CollectionProvenanceTab, type CollectionProvenanceTabProps };
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useEffect, useMemo } from "react";
|
|
4
|
+
import { assetHref, profileHref } from "@medialane/sdk";
|
|
5
|
+
import { ExternalLink, Inbox } from "lucide-react";
|
|
6
|
+
import Image from "./image.js";
|
|
7
|
+
import Link from "./link.js";
|
|
8
|
+
import { AddressDisplay } from "./address-display.js";
|
|
9
|
+
import { CurrencyIcon } from "./currency-icon.js";
|
|
10
|
+
import { LoadMoreSentinel } from "./load-more-sentinel.js";
|
|
11
|
+
import { useActivities } from "../utils/use-activities.js";
|
|
12
|
+
import { useImageUrl } from "../utils/use-image-url.js";
|
|
13
|
+
import { ACTIVITY_TYPE_CONFIG } from "../data/activity.js";
|
|
14
|
+
import { EXPLORER_URL } from "../utils/explorer-url.js";
|
|
15
|
+
import { formatDisplayPrice } from "../utils/format.js";
|
|
16
|
+
import { timeAgo } from "../utils/time.js";
|
|
17
|
+
import { cn } from "../utils/cn.js";
|
|
18
|
+
const PAGE_SIZE = 30;
|
|
19
|
+
const EVENT_TITLE = {
|
|
20
|
+
mint: "Minted",
|
|
21
|
+
listing: "Listed for sale",
|
|
22
|
+
sale: "Purchased",
|
|
23
|
+
offer: "Offer made",
|
|
24
|
+
transfer: "Transferred",
|
|
25
|
+
cancelled: "Listing cancelled"
|
|
26
|
+
};
|
|
27
|
+
function dayLabel(iso) {
|
|
28
|
+
const date = new Date(iso);
|
|
29
|
+
const today = /* @__PURE__ */ new Date();
|
|
30
|
+
const yesterday = /* @__PURE__ */ new Date();
|
|
31
|
+
yesterday.setDate(today.getDate() - 1);
|
|
32
|
+
if (date.toDateString() === today.toDateString()) return "Today";
|
|
33
|
+
if (date.toDateString() === yesterday.toDateString()) return "Yesterday";
|
|
34
|
+
return date.toLocaleDateString(void 0, { day: "numeric", month: "long", year: "numeric" });
|
|
35
|
+
}
|
|
36
|
+
function groupByDay(events) {
|
|
37
|
+
const groups = [];
|
|
38
|
+
for (const event of events) {
|
|
39
|
+
const label = dayLabel(event.timestamp);
|
|
40
|
+
const last = groups[groups.length - 1];
|
|
41
|
+
if (last && last.label === label) last.events.push(event);
|
|
42
|
+
else groups.push({ label, events: [event] });
|
|
43
|
+
}
|
|
44
|
+
return groups;
|
|
45
|
+
}
|
|
46
|
+
function ProvenanceEvent({ event, showAsset }) {
|
|
47
|
+
const resolveImage = useImageUrl();
|
|
48
|
+
const config = ACTIVITY_TYPE_CONFIG[event.type];
|
|
49
|
+
const Icon = config?.icon ?? ExternalLink;
|
|
50
|
+
const contract = event.nftContract ?? event.contractAddress ?? null;
|
|
51
|
+
const tokenId = event.nftTokenId ?? event.tokenId ?? null;
|
|
52
|
+
const actor = event.offerer ?? event.fulfiller ?? (event.type === "mint" ? event.to : event.from) ?? null;
|
|
53
|
+
const amount = event.amount && Number(event.amount) > 1 ? event.amount : null;
|
|
54
|
+
const name = event.token?.name ?? (tokenId ? `#${tokenId}` : null);
|
|
55
|
+
const image = resolveImage(event.token?.image ?? null);
|
|
56
|
+
return /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-4 rounded-2xl border border-border/50 bg-card/60 p-4 backdrop-blur-sm transition-colors hover:bg-card/90", children: [
|
|
57
|
+
/* @__PURE__ */ jsx(
|
|
58
|
+
"span",
|
|
59
|
+
{
|
|
60
|
+
className: cn(
|
|
61
|
+
"flex h-11 w-11 shrink-0 items-center justify-center rounded-xl",
|
|
62
|
+
config?.bgClass ?? "bg-muted"
|
|
63
|
+
),
|
|
64
|
+
"aria-hidden": true,
|
|
65
|
+
children: /* @__PURE__ */ jsx(Icon, { className: cn("h-5 w-5", config?.colorClass ?? "text-muted-foreground") })
|
|
66
|
+
}
|
|
67
|
+
),
|
|
68
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
69
|
+
/* @__PURE__ */ jsxs("p", { className: "flex flex-wrap items-baseline gap-x-1.5 text-base font-semibold leading-tight", children: [
|
|
70
|
+
EVENT_TITLE[event.type] ?? event.type,
|
|
71
|
+
amount ? /* @__PURE__ */ jsxs("span", { className: "text-sm font-medium text-muted-foreground", children: [
|
|
72
|
+
"\xD7",
|
|
73
|
+
amount
|
|
74
|
+
] }) : null,
|
|
75
|
+
actor ? /* @__PURE__ */ jsxs("span", { className: "text-sm font-normal text-muted-foreground", children: [
|
|
76
|
+
"by",
|
|
77
|
+
" ",
|
|
78
|
+
/* @__PURE__ */ jsx(
|
|
79
|
+
Link,
|
|
80
|
+
{
|
|
81
|
+
href: profileHref({ address: actor }),
|
|
82
|
+
className: "font-medium text-foreground/80 hover:text-primary transition-colors",
|
|
83
|
+
children: /* @__PURE__ */ jsx(AddressDisplay, { address: actor, chars: 6, showCopy: false, className: "text-sm" })
|
|
84
|
+
}
|
|
85
|
+
)
|
|
86
|
+
] }) : null
|
|
87
|
+
] }),
|
|
88
|
+
showAsset && name ? /* @__PURE__ */ jsxs(
|
|
89
|
+
Link,
|
|
90
|
+
{
|
|
91
|
+
href: contract && tokenId ? assetHref(event.chain ?? "STARKNET", contract, tokenId) : "#",
|
|
92
|
+
className: "mt-2 inline-flex max-w-full items-center gap-2 rounded-full bg-muted/70 py-1 pl-1 pr-3 hover:bg-muted transition-colors",
|
|
93
|
+
children: [
|
|
94
|
+
/* @__PURE__ */ jsx("span", { className: "relative h-6 w-6 shrink-0 overflow-hidden rounded-full bg-muted", children: image ? /* @__PURE__ */ jsx(Image, { src: image, alt: "", width: 24, height: 24, className: "h-full w-full object-cover", unoptimized: true }) : null }),
|
|
95
|
+
/* @__PURE__ */ jsx("span", { className: "truncate text-xs font-medium", children: name })
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
) : null
|
|
99
|
+
] }),
|
|
100
|
+
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 flex-col items-end gap-1", children: [
|
|
101
|
+
event.price?.formatted ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5 text-base font-bold tabular-nums", children: [
|
|
102
|
+
event.price.currency ? /* @__PURE__ */ jsx(CurrencyIcon, { symbol: event.price.currency, size: 15, "aria-hidden": true }) : null,
|
|
103
|
+
formatDisplayPrice(event.price.formatted),
|
|
104
|
+
event.price.currency ? /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground", children: event.price.currency }) : null
|
|
105
|
+
] }) : null,
|
|
106
|
+
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-xs text-muted-foreground", children: [
|
|
107
|
+
/* @__PURE__ */ jsx("time", { dateTime: event.timestamp, title: new Date(event.timestamp).toLocaleString(), children: timeAgo(event.timestamp) }),
|
|
108
|
+
event.txHash ? /* @__PURE__ */ jsx(
|
|
109
|
+
"a",
|
|
110
|
+
{
|
|
111
|
+
href: `${EXPLORER_URL}/tx/${event.txHash}`,
|
|
112
|
+
target: "_blank",
|
|
113
|
+
rel: "noopener noreferrer",
|
|
114
|
+
className: "rounded-md p-1 hover:bg-muted hover:text-foreground transition-colors",
|
|
115
|
+
"aria-label": "View transaction",
|
|
116
|
+
children: /* @__PURE__ */ jsx(ExternalLink, { className: "h-3.5 w-3.5", "aria-hidden": true })
|
|
117
|
+
}
|
|
118
|
+
) : null
|
|
119
|
+
] })
|
|
120
|
+
] })
|
|
121
|
+
] });
|
|
122
|
+
}
|
|
123
|
+
function ProvenanceSkeleton() {
|
|
124
|
+
return /* @__PURE__ */ jsx("div", { className: "space-y-2.5", "aria-hidden": true, children: Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 rounded-2xl border border-border/50 bg-card/60 p-4", children: [
|
|
125
|
+
/* @__PURE__ */ jsx("div", { className: "h-11 w-11 shrink-0 rounded-xl bg-muted animate-pulse" }),
|
|
126
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-2", children: [
|
|
127
|
+
/* @__PURE__ */ jsx("div", { className: "h-4 w-44 rounded bg-muted animate-pulse" }),
|
|
128
|
+
/* @__PURE__ */ jsx("div", { className: "h-3 w-24 rounded bg-muted animate-pulse" })
|
|
129
|
+
] }),
|
|
130
|
+
/* @__PURE__ */ jsx("div", { className: "h-4 w-16 rounded bg-muted animate-pulse" })
|
|
131
|
+
] }, i)) });
|
|
132
|
+
}
|
|
133
|
+
function CollectionProvenanceTab({ contract }) {
|
|
134
|
+
const [page, setPage] = useState(1);
|
|
135
|
+
const [all, setAll] = useState([]);
|
|
136
|
+
const { activities, meta, isLoading } = useActivities({ contract, page, limit: PAGE_SIZE });
|
|
137
|
+
useEffect(() => {
|
|
138
|
+
if (activities.length === 0) return;
|
|
139
|
+
setAll((prev) => page === 1 ? activities : [...prev, ...activities]);
|
|
140
|
+
}, [activities, page]);
|
|
141
|
+
const groups = useMemo(() => groupByDay(all), [all]);
|
|
142
|
+
const showAsset = useMemo(
|
|
143
|
+
() => new Set(all.map((e) => e.nftTokenId ?? e.tokenId ?? "")).size > 1,
|
|
144
|
+
[all]
|
|
145
|
+
);
|
|
146
|
+
const hasMore = meta ? all.length < (meta.total ?? 0) : false;
|
|
147
|
+
if (isLoading && all.length === 0) return /* @__PURE__ */ jsx(ProvenanceSkeleton, {});
|
|
148
|
+
if (all.length === 0) {
|
|
149
|
+
return /* @__PURE__ */ jsxs("div", { className: "py-20 flex flex-col items-center gap-3 text-center", children: [
|
|
150
|
+
/* @__PURE__ */ jsx(Inbox, { className: "h-10 w-10 text-muted-foreground/40" }),
|
|
151
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-muted-foreground", children: "No history yet" }),
|
|
152
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground/70 max-w-xs", children: "Mints, transfers, listings and sales will appear here as they happen." })
|
|
153
|
+
] });
|
|
154
|
+
}
|
|
155
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-8", children: [
|
|
156
|
+
groups.map((group) => /* @__PURE__ */ jsxs("section", { children: [
|
|
157
|
+
/* @__PURE__ */ jsx("h3", { className: "mb-3 font-display text-lg font-bold", children: group.label }),
|
|
158
|
+
/* @__PURE__ */ jsx("ol", { className: "space-y-2.5", children: group.events.map((event, i) => /* @__PURE__ */ jsx(
|
|
159
|
+
ProvenanceEvent,
|
|
160
|
+
{
|
|
161
|
+
event,
|
|
162
|
+
showAsset
|
|
163
|
+
},
|
|
164
|
+
`${event.txHash ?? event.orderHash}-${event.type}-${i}`
|
|
165
|
+
)) })
|
|
166
|
+
] }, group.label)),
|
|
167
|
+
/* @__PURE__ */ jsx(LoadMoreSentinel, { hasMore, isLoading, onLoadMore: () => setPage((p) => p + 1) })
|
|
168
|
+
] });
|
|
169
|
+
}
|
|
170
|
+
export {
|
|
171
|
+
CollectionProvenanceTab
|
|
172
|
+
};
|
|
173
|
+
//# sourceMappingURL=collection-provenance-tab.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/collection-provenance-tab.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState, useEffect, useMemo } from \"react\";\nimport type { ApiActivity } from \"@medialane/sdk\";\nimport { assetHref, profileHref } from \"@medialane/sdk\";\nimport { ExternalLink, Inbox } from \"lucide-react\";\nimport Image from \"./image.js\";\nimport Link from \"./link.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { LoadMoreSentinel } from \"./load-more-sentinel.js\";\nimport { useActivities } from \"../utils/use-activities.js\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\nimport { ACTIVITY_TYPE_CONFIG } from \"../data/activity.js\";\nimport { EXPLORER_URL } from \"../utils/explorer-url.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { cn } from \"../utils/cn.js\";\n\nconst PAGE_SIZE = 30;\n\nconst EVENT_TITLE: Record<string, string> = {\n mint: \"Minted\",\n listing: \"Listed for sale\",\n sale: \"Purchased\",\n offer: \"Offer made\",\n transfer: \"Transferred\",\n cancelled: \"Listing cancelled\",\n};\n\nfunction dayLabel(iso: string): string {\n const date = new Date(iso);\n const today = new Date();\n const yesterday = new Date();\n yesterday.setDate(today.getDate() - 1);\n if (date.toDateString() === today.toDateString()) return \"Today\";\n if (date.toDateString() === yesterday.toDateString()) return \"Yesterday\";\n return date.toLocaleDateString(undefined, { day: \"numeric\", month: \"long\", year: \"numeric\" });\n}\n\nfunction groupByDay(events: ApiActivity[]) {\n const groups: { label: string; events: ApiActivity[] }[] = [];\n for (const event of events) {\n const label = dayLabel(event.timestamp);\n const last = groups[groups.length - 1];\n if (last && last.label === label) last.events.push(event);\n else groups.push({ label, events: [event] });\n }\n return groups;\n}\n\nfunction ProvenanceEvent({ event, showAsset }: { event: ApiActivity; showAsset: boolean }) {\n const resolveImage = useImageUrl();\n const config = ACTIVITY_TYPE_CONFIG[event.type];\n const Icon = config?.icon ?? ExternalLink;\n const contract = event.nftContract ?? event.contractAddress ?? null;\n const tokenId = event.nftTokenId ?? event.tokenId ?? null;\n const actor =\n event.offerer ?? event.fulfiller ?? (event.type === \"mint\" ? event.to : event.from) ?? null;\n const amount = event.amount && Number(event.amount) > 1 ? event.amount : null;\n const name = event.token?.name ?? (tokenId ? `#${tokenId}` : null);\n const image = resolveImage(event.token?.image ?? null);\n\n return (\n <li className=\"flex items-center gap-4 rounded-2xl border border-border/50 bg-card/60 p-4 backdrop-blur-sm transition-colors hover:bg-card/90\">\n <span\n className={cn(\n \"flex h-11 w-11 shrink-0 items-center justify-center rounded-xl\",\n config?.bgClass ?? \"bg-muted\"\n )}\n aria-hidden\n >\n <Icon className={cn(\"h-5 w-5\", config?.colorClass ?? \"text-muted-foreground\")} />\n </span>\n\n <div className=\"min-w-0 flex-1\">\n <p className=\"flex flex-wrap items-baseline gap-x-1.5 text-base font-semibold leading-tight\">\n {EVENT_TITLE[event.type] ?? event.type}\n {amount ? <span className=\"text-sm font-medium text-muted-foreground\">×{amount}</span> : null}\n {actor ? (\n <span className=\"text-sm font-normal text-muted-foreground\">\n by{\" \"}\n <Link\n href={profileHref({ address: actor })}\n className=\"font-medium text-foreground/80 hover:text-primary transition-colors\"\n >\n <AddressDisplay address={actor} chars={6} showCopy={false} className=\"text-sm\" />\n </Link>\n </span>\n ) : null}\n </p>\n\n {showAsset && name ? (\n <Link\n href={contract && tokenId ? assetHref(event.chain ?? \"STARKNET\", contract, tokenId) : \"#\"}\n className=\"mt-2 inline-flex max-w-full items-center gap-2 rounded-full bg-muted/70 py-1 pl-1 pr-3 hover:bg-muted transition-colors\"\n >\n <span className=\"relative h-6 w-6 shrink-0 overflow-hidden rounded-full bg-muted\">\n {image ? (\n <Image src={image} alt=\"\" width={24} height={24} className=\"h-full w-full object-cover\" unoptimized />\n ) : null}\n </span>\n <span className=\"truncate text-xs font-medium\">{name}</span>\n </Link>\n ) : null}\n </div>\n\n <div className=\"flex shrink-0 flex-col items-end gap-1\">\n {event.price?.formatted ? (\n <span className=\"flex items-center gap-1.5 text-base font-bold tabular-nums\">\n {event.price.currency ? <CurrencyIcon symbol={event.price.currency} size={15} aria-hidden /> : null}\n {formatDisplayPrice(event.price.formatted)}\n {event.price.currency ? (\n <span className=\"text-xs font-medium text-muted-foreground\">{event.price.currency}</span>\n ) : null}\n </span>\n ) : null}\n <span className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n <time dateTime={event.timestamp} title={new Date(event.timestamp).toLocaleString()}>\n {timeAgo(event.timestamp)}\n </time>\n {event.txHash ? (\n <a\n href={`${EXPLORER_URL}/tx/${event.txHash}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"rounded-md p-1 hover:bg-muted hover:text-foreground transition-colors\"\n aria-label=\"View transaction\"\n >\n <ExternalLink className=\"h-3.5 w-3.5\" aria-hidden />\n </a>\n ) : null}\n </span>\n </div>\n </li>\n );\n}\n\nfunction ProvenanceSkeleton() {\n return (\n <div className=\"space-y-2.5\" aria-hidden>\n {Array.from({ length: 5 }).map((_, i) => (\n <div key={i} className=\"flex items-center gap-4 rounded-2xl border border-border/50 bg-card/60 p-4\">\n <div className=\"h-11 w-11 shrink-0 rounded-xl bg-muted animate-pulse\" />\n <div className=\"flex-1 space-y-2\">\n <div className=\"h-4 w-44 rounded bg-muted animate-pulse\" />\n <div className=\"h-3 w-24 rounded bg-muted animate-pulse\" />\n </div>\n <div className=\"h-4 w-16 rounded bg-muted animate-pulse\" />\n </div>\n ))}\n </div>\n );\n}\n\nexport interface CollectionProvenanceTabProps {\n contract: string;\n}\n\nexport function CollectionProvenanceTab({ contract }: CollectionProvenanceTabProps) {\n const [page, setPage] = useState(1);\n const [all, setAll] = useState<ApiActivity[]>([]);\n const { activities, meta, isLoading } = useActivities({ contract, page, limit: PAGE_SIZE });\n\n useEffect(() => {\n if (activities.length === 0) return;\n setAll((prev) => (page === 1 ? activities : [...prev, ...activities]));\n }, [activities, page]);\n\n const groups = useMemo(() => groupByDay(all), [all]);\n const showAsset = useMemo(\n () => new Set(all.map((e) => e.nftTokenId ?? e.tokenId ?? \"\")).size > 1,\n [all]\n );\n const hasMore = meta ? all.length < (meta.total ?? 0) : false;\n\n if (isLoading && all.length === 0) return <ProvenanceSkeleton />;\n\n if (all.length === 0) {\n return (\n <div className=\"py-20 flex flex-col items-center gap-3 text-center\">\n <Inbox className=\"h-10 w-10 text-muted-foreground/40\" />\n <p className=\"text-sm font-medium text-muted-foreground\">No history yet</p>\n <p className=\"text-xs text-muted-foreground/70 max-w-xs\">\n Mints, transfers, listings and sales will appear here as they happen.\n </p>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-8\">\n {groups.map((group) => (\n <section key={group.label}>\n <h3 className=\"mb-3 font-display text-lg font-bold\">{group.label}</h3>\n <ol className=\"space-y-2.5\">\n {group.events.map((event, i) => (\n <ProvenanceEvent\n key={`${event.txHash ?? event.orderHash}-${event.type}-${i}`}\n event={event}\n showAsset={showAsset}\n />\n ))}\n </ol>\n </section>\n ))}\n <LoadMoreSentinel hasMore={hasMore} isLoading={isLoading} onLoadMore={() => setPage((p) => p + 1)} />\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
1
|
import * as React from 'react';
|
|
2
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
3
|
import { FastMintProps } from './types.cjs';
|
|
4
4
|
import 'starknet';
|
|
5
5
|
import '@medialane/sdk';
|
|
6
6
|
import '@medialane/sdk/starknet';
|
|
7
7
|
|
|
8
|
-
declare function FastMint(props: FastMintProps): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> |
|
|
8
|
+
declare function FastMint(props: FastMintProps): string | number | bigint | boolean | react_jsx_runtime.JSX.Element | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null | undefined;
|
|
9
9
|
|
|
10
10
|
export { FastMint };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
1
|
import * as React from 'react';
|
|
2
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
3
|
import { FastMintProps } from './types.js';
|
|
4
4
|
import 'starknet';
|
|
5
5
|
import '@medialane/sdk';
|
|
6
6
|
import '@medialane/sdk/starknet';
|
|
7
7
|
|
|
8
|
-
declare function FastMint(props: FastMintProps): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> |
|
|
8
|
+
declare function FastMint(props: FastMintProps): string | number | bigint | boolean | react_jsx_runtime.JSX.Element | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null | undefined;
|
|
9
9
|
|
|
10
10
|
export { FastMint };
|
|
@@ -16,7 +16,6 @@ declare const editionMintSchema: zod.ZodObject<{
|
|
|
16
16
|
royalty: zod.ZodNumber;
|
|
17
17
|
}, "strip", zod.ZodTypeAny, {
|
|
18
18
|
name: string;
|
|
19
|
-
value: string;
|
|
20
19
|
ipType: "Audio" | "Video" | "Art" | "Photography" | "NFT" | "Software" | "RWA" | "Patents" | "Posts" | "Publications" | "Documents" | "Custom";
|
|
21
20
|
licenseType: string;
|
|
22
21
|
commercialUse: "Yes" | "No";
|
|
@@ -25,12 +24,12 @@ declare const editionMintSchema: zod.ZodObject<{
|
|
|
25
24
|
geographicScope: string;
|
|
26
25
|
aiPolicy: "Allowed" | "Not Allowed" | "Training Only";
|
|
27
26
|
royalty: number;
|
|
27
|
+
value: string;
|
|
28
28
|
recipient: string;
|
|
29
29
|
description?: string | undefined;
|
|
30
30
|
external_url?: string | undefined;
|
|
31
31
|
}, {
|
|
32
32
|
name: string;
|
|
33
|
-
value: string;
|
|
34
33
|
ipType: "Audio" | "Video" | "Art" | "Photography" | "NFT" | "Software" | "RWA" | "Patents" | "Posts" | "Publications" | "Documents" | "Custom";
|
|
35
34
|
licenseType: string;
|
|
36
35
|
commercialUse: "Yes" | "No";
|
|
@@ -39,6 +38,7 @@ declare const editionMintSchema: zod.ZodObject<{
|
|
|
39
38
|
geographicScope: string;
|
|
40
39
|
aiPolicy: "Allowed" | "Not Allowed" | "Training Only";
|
|
41
40
|
royalty: number;
|
|
41
|
+
value: string;
|
|
42
42
|
recipient: string;
|
|
43
43
|
description?: string | undefined;
|
|
44
44
|
external_url?: string | undefined;
|
|
@@ -16,7 +16,6 @@ declare const editionMintSchema: zod.ZodObject<{
|
|
|
16
16
|
royalty: zod.ZodNumber;
|
|
17
17
|
}, "strip", zod.ZodTypeAny, {
|
|
18
18
|
name: string;
|
|
19
|
-
value: string;
|
|
20
19
|
ipType: "Audio" | "Video" | "Art" | "Photography" | "NFT" | "Software" | "RWA" | "Patents" | "Posts" | "Publications" | "Documents" | "Custom";
|
|
21
20
|
licenseType: string;
|
|
22
21
|
commercialUse: "Yes" | "No";
|
|
@@ -25,12 +24,12 @@ declare const editionMintSchema: zod.ZodObject<{
|
|
|
25
24
|
geographicScope: string;
|
|
26
25
|
aiPolicy: "Allowed" | "Not Allowed" | "Training Only";
|
|
27
26
|
royalty: number;
|
|
27
|
+
value: string;
|
|
28
28
|
recipient: string;
|
|
29
29
|
description?: string | undefined;
|
|
30
30
|
external_url?: string | undefined;
|
|
31
31
|
}, {
|
|
32
32
|
name: string;
|
|
33
|
-
value: string;
|
|
34
33
|
ipType: "Audio" | "Video" | "Art" | "Photography" | "NFT" | "Software" | "RWA" | "Patents" | "Posts" | "Publications" | "Documents" | "Custom";
|
|
35
34
|
licenseType: string;
|
|
36
35
|
commercialUse: "Yes" | "No";
|
|
@@ -39,6 +38,7 @@ declare const editionMintSchema: zod.ZodObject<{
|
|
|
39
38
|
geographicScope: string;
|
|
40
39
|
aiPolicy: "Allowed" | "Not Allowed" | "Training Only";
|
|
41
40
|
royalty: number;
|
|
41
|
+
value: string;
|
|
42
42
|
recipient: string;
|
|
43
43
|
description?: string | undefined;
|
|
44
44
|
external_url?: string | undefined;
|
|
@@ -10,7 +10,7 @@ declare const SheetClose: React.ForwardRefExoticComponent<SheetPrimitive.DialogC
|
|
|
10
10
|
declare const SheetPortal: React.FC<SheetPrimitive.DialogPortalProps>;
|
|
11
11
|
declare const SheetOverlay: React.ForwardRefExoticComponent<Omit<SheetPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
12
12
|
declare const sheetVariants: (props?: ({
|
|
13
|
-
side?: "
|
|
13
|
+
side?: "bottom" | "left" | "right" | "top" | null | undefined;
|
|
14
14
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
15
15
|
interface SheetContentProps extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>, VariantProps<typeof sheetVariants> {
|
|
16
16
|
overlayClassName?: string;
|
|
@@ -10,7 +10,7 @@ declare const SheetClose: React.ForwardRefExoticComponent<SheetPrimitive.DialogC
|
|
|
10
10
|
declare const SheetPortal: React.FC<SheetPrimitive.DialogPortalProps>;
|
|
11
11
|
declare const SheetOverlay: React.ForwardRefExoticComponent<Omit<SheetPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
12
12
|
declare const sheetVariants: (props?: ({
|
|
13
|
-
side?: "
|
|
13
|
+
side?: "bottom" | "left" | "right" | "top" | null | undefined;
|
|
14
14
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
15
15
|
interface SheetContentProps extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>, VariantProps<typeof sheetVariants> {
|
|
16
16
|
overlayClassName?: string;
|
package/dist/data/activity.cjs
CHANGED
|
@@ -24,12 +24,12 @@ __export(activity_exports, {
|
|
|
24
24
|
module.exports = __toCommonJS(activity_exports);
|
|
25
25
|
var import_lucide_react = require("lucide-react");
|
|
26
26
|
const ACTIVITY_TYPE_CONFIG = {
|
|
27
|
-
mint: { label: "Mint", variant: "default", icon: import_lucide_react.Sparkles, colorClass: "text-
|
|
28
|
-
transfer: { label: "Transfer", variant: "secondary", icon: import_lucide_react.ArrowRightLeft, colorClass: "text-
|
|
29
|
-
listing: { label: "Listed", variant: "default", icon: import_lucide_react.Tag, colorClass: "text-
|
|
30
|
-
sale: { label: "Sale", variant: "default", icon: import_lucide_react.ShoppingCart, colorClass: "text-
|
|
31
|
-
offer: { label: "Offer", variant: "outline", icon: import_lucide_react.HandCoins, colorClass: "text-
|
|
32
|
-
cancelled: { label: "Cancelled", variant: "outline", icon: import_lucide_react.X, colorClass: "text-
|
|
27
|
+
mint: { label: "Mint", variant: "default", icon: import_lucide_react.Sparkles, colorClass: "text-brand-purple", bgClass: "bg-brand-purple/10" },
|
|
28
|
+
transfer: { label: "Transfer", variant: "secondary", icon: import_lucide_react.ArrowRightLeft, colorClass: "text-brand-blue", bgClass: "bg-brand-blue/10" },
|
|
29
|
+
listing: { label: "Listed", variant: "default", icon: import_lucide_react.Tag, colorClass: "text-brand-orange", bgClass: "bg-brand-orange/10" },
|
|
30
|
+
sale: { label: "Sale", variant: "default", icon: import_lucide_react.ShoppingCart, colorClass: "text-brand-rose", bgClass: "bg-brand-rose/10" },
|
|
31
|
+
offer: { label: "Offer", variant: "outline", icon: import_lucide_react.HandCoins, colorClass: "text-brand-maeve", bgClass: "bg-brand-maeve/10" },
|
|
32
|
+
cancelled: { label: "Cancelled", variant: "outline", icon: import_lucide_react.X, colorClass: "text-muted-foreground", bgClass: "bg-muted" }
|
|
33
33
|
};
|
|
34
34
|
const TYPE_FILTERS = [
|
|
35
35
|
{ label: "All", value: "" },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/data/activity.ts"],"sourcesContent":["import { ArrowRightLeft, Tag, ShoppingCart, HandCoins, X, Sparkles } from \"lucide-react\";\nimport type { ElementType } from \"react\";\n\nexport interface ActivityTypeConfig {\n label: string;\n variant: \"default\" | \"secondary\" | \"outline\";\n icon: ElementType;\n colorClass: string;\n bgClass: string;\n}\n\nexport const ACTIVITY_TYPE_CONFIG: Record<string, ActivityTypeConfig> = {\n mint: { label: \"Mint\", variant: \"default\", icon: Sparkles, colorClass: \"text-
|
|
1
|
+
{"version":3,"sources":["../../src/data/activity.ts"],"sourcesContent":["import { ArrowRightLeft, Tag, ShoppingCart, HandCoins, X, Sparkles } from \"lucide-react\";\nimport type { ElementType } from \"react\";\n\nexport interface ActivityTypeConfig {\n label: string;\n variant: \"default\" | \"secondary\" | \"outline\";\n icon: ElementType;\n colorClass: string;\n bgClass: string;\n}\n\nexport const ACTIVITY_TYPE_CONFIG: Record<string, ActivityTypeConfig> = {\n mint: { label: \"Mint\", variant: \"default\", icon: Sparkles, colorClass: \"text-brand-purple\", bgClass: \"bg-brand-purple/10\" },\n transfer: { label: \"Transfer\", variant: \"secondary\", icon: ArrowRightLeft, colorClass: \"text-brand-blue\", bgClass: \"bg-brand-blue/10\" },\n listing: { label: \"Listed\", variant: \"default\", icon: Tag, colorClass: \"text-brand-orange\", bgClass: \"bg-brand-orange/10\" },\n sale: { label: \"Sale\", variant: \"default\", icon: ShoppingCart, colorClass: \"text-brand-rose\", bgClass: \"bg-brand-rose/10\" },\n offer: { label: \"Offer\", variant: \"outline\", icon: HandCoins, colorClass: \"text-brand-maeve\", bgClass: \"bg-brand-maeve/10\" },\n cancelled: { label: \"Cancelled\", variant: \"outline\", icon: X, colorClass: \"text-muted-foreground\", bgClass: \"bg-muted\" },\n};\n\nexport const TYPE_FILTERS = [\n { label: \"All\", value: \"\" },\n { label: \"Mints\", value: \"mint\" },\n { label: \"Sales\", value: \"sale\" },\n { label: \"Listings\", value: \"listing\" },\n { label: \"Offers\", value: \"offer\" },\n { label: \"Transfers\", value: \"transfer\" },\n { label: \"Cancelled\", value: \"cancelled\" },\n];\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAA0E;AAWnE,MAAM,uBAA2D;AAAA,EACtE,MAAW,EAAE,OAAO,QAAa,SAAS,WAAa,MAAM,8BAAgB,YAAY,qBAAqB,SAAS,qBAAqB;AAAA,EAC5I,UAAW,EAAE,OAAO,YAAa,SAAS,aAAa,MAAM,oCAAgB,YAAY,mBAAqB,SAAS,mBAAmB;AAAA,EAC1I,SAAW,EAAE,OAAO,UAAa,SAAS,WAAa,MAAM,yBAAgB,YAAY,qBAAqB,SAAS,qBAAqB;AAAA,EAC5I,MAAW,EAAE,OAAO,QAAa,SAAS,WAAa,MAAM,kCAAgB,YAAY,mBAAqB,SAAS,mBAAmB;AAAA,EAC1I,OAAW,EAAE,OAAO,SAAa,SAAS,WAAa,MAAM,+BAAgB,YAAY,oBAAqB,SAAS,oBAAoB;AAAA,EAC3I,WAAW,EAAE,OAAO,aAAa,SAAS,WAAa,MAAM,uBAAgB,YAAY,yBAAyB,SAAS,WAAW;AACxI;AAEO,MAAM,eAAe;AAAA,EAC1B,EAAE,OAAO,OAAa,OAAO,GAAG;AAAA,EAChC,EAAE,OAAO,SAAa,OAAO,OAAO;AAAA,EACpC,EAAE,OAAO,SAAa,OAAO,OAAO;AAAA,EACpC,EAAE,OAAO,YAAa,OAAO,UAAU;AAAA,EACvC,EAAE,OAAO,UAAa,OAAO,QAAQ;AAAA,EACrC,EAAE,OAAO,aAAa,OAAO,WAAW;AAAA,EACxC,EAAE,OAAO,aAAa,OAAO,YAAY;AAC3C;","names":[]}
|