@medialane/ui 0.301.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/button.d.cts +1 -1
- package/dist/components/button.d.ts +1 -1
- package/dist/components/collection-provenance-tab.cjs +61 -60
- package/dist/components/collection-provenance-tab.cjs.map +1 -1
- package/dist/components/collection-provenance-tab.js +61 -60
- package/dist/components/collection-provenance-tab.js.map +1 -1
- package/dist/components/fast-mint/fast-mint.d.cts +2 -2
- package/dist/components/fast-mint/fast-mint.d.ts +2 -2
- 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/utils/media-wallet/use-erc20-balance.d.cts +1 -1
- package/dist/utils/media-wallet/use-erc20-balance.d.ts +1 -1
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ import * as React from 'react';
|
|
|
3
3
|
import { VariantProps } from 'class-variance-authority';
|
|
4
4
|
|
|
5
5
|
declare const buttonVariants: (props?: ({
|
|
6
|
-
variant?: "
|
|
6
|
+
variant?: "default" | "link" | "destructive" | "outline" | "secondary" | "ghost" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
|
|
7
7
|
size?: "default" | "icon" | "sm" | "lg" | null | undefined;
|
|
8
8
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
9
|
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
|
@@ -3,7 +3,7 @@ import * as React from 'react';
|
|
|
3
3
|
import { VariantProps } from 'class-variance-authority';
|
|
4
4
|
|
|
5
5
|
declare const buttonVariants: (props?: ({
|
|
6
|
-
variant?: "
|
|
6
|
+
variant?: "default" | "link" | "destructive" | "outline" | "secondary" | "ghost" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
|
|
7
7
|
size?: "default" | "icon" | "sm" | "lg" | null | undefined;
|
|
8
8
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
9
|
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
|
@@ -86,80 +86,81 @@ function ProvenanceEvent({ event, showAsset }) {
|
|
|
86
86
|
const amount = event.amount && Number(event.amount) > 1 ? event.amount : null;
|
|
87
87
|
const name = event.token?.name ?? (tokenId ? `#${tokenId}` : null);
|
|
88
88
|
const image = resolveImage(event.token?.image ?? null);
|
|
89
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", { className: "
|
|
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
90
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
91
91
|
"span",
|
|
92
92
|
{
|
|
93
93
|
className: (0, import_cn.cn)(
|
|
94
|
-
"
|
|
94
|
+
"flex h-11 w-11 shrink-0 items-center justify-center rounded-xl",
|
|
95
95
|
config?.bgClass ?? "bg-muted"
|
|
96
96
|
),
|
|
97
97
|
"aria-hidden": true,
|
|
98
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { className: (0, import_cn.cn)("h-
|
|
98
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { className: (0, import_cn.cn)("h-5 w-5", config?.colorClass ?? "text-muted-foreground") })
|
|
99
99
|
}
|
|
100
100
|
),
|
|
101
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "
|
|
102
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
amount
|
|
108
|
-
] }) : null,
|
|
109
|
-
actor ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "font-normal text-muted-foreground", children: [
|
|
110
|
-
" by ",
|
|
111
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
112
|
-
import_link.default,
|
|
113
|
-
{
|
|
114
|
-
href: (0, import_sdk.profileHref)({ address: actor }),
|
|
115
|
-
className: "hover:text-primary transition-colors",
|
|
116
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_address_display.AddressDisplay, { address: actor, chars: 4, showCopy: false, className: "text-xs" })
|
|
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-1 inline-flex max-w-full items-center gap-2 rounded-lg bg-muted/40 py-1 pl-1 pr-3 hover:bg-muted transition-colors",
|
|
126
|
-
children: [
|
|
127
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "relative h-8 w-8 shrink-0 overflow-hidden rounded-md bg-muted", children: image ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_image.default, { src: image, alt: "", width: 32, height: 32, 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-0.5 pt-1.5", children: [
|
|
134
|
-
event.price?.formatted ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "flex items-center gap-1.5 text-sm font-bold tabular-nums", children: [
|
|
135
|
-
event.price.currency ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_currency_icon.CurrencyIcon, { symbol: event.price.currency, size: 13, "aria-hidden": true }) : null,
|
|
136
|
-
(0, import_format.formatDisplayPrice)(event.price.formatted)
|
|
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
|
|
137
107
|
] }) : null,
|
|
138
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
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,
|
|
142
113
|
{
|
|
143
|
-
href:
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
className: "rounded p-0.5 hover:bg-muted hover:text-foreground transition-colors",
|
|
147
|
-
"aria-label": "View transaction",
|
|
148
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ExternalLink, { className: "h-3 w-3", "aria-hidden": true })
|
|
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" })
|
|
149
117
|
}
|
|
150
|
-
)
|
|
151
|
-
] })
|
|
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
152
|
] })
|
|
153
153
|
] })
|
|
154
154
|
] });
|
|
155
155
|
}
|
|
156
156
|
function ProvenanceSkeleton() {
|
|
157
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "space-y-
|
|
158
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-
|
|
159
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex-1 space-y-2
|
|
160
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-
|
|
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
161
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-3 w-24 rounded bg-muted animate-pulse" })
|
|
162
|
-
] })
|
|
162
|
+
] }),
|
|
163
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-4 w-16 rounded bg-muted animate-pulse" })
|
|
163
164
|
] }, i)) });
|
|
164
165
|
}
|
|
165
166
|
function CollectionProvenanceTab({ contract }) {
|
|
@@ -184,10 +185,10 @@ function CollectionProvenanceTab({ contract }) {
|
|
|
184
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." })
|
|
185
186
|
] });
|
|
186
187
|
}
|
|
187
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "
|
|
188
|
-
groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
|
|
189
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "mb-
|
|
190
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { className: "
|
|
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)(
|
|
191
192
|
ProvenanceEvent,
|
|
192
193
|
{
|
|
193
194
|
event,
|
|
@@ -1 +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=\"relative pl-12 pb-6 last:pb-0\">\n <span\n className={cn(\n \"absolute left-0 top-0 flex h-8 w-8 items-center justify-center rounded-full ring-4 ring-background\",\n config?.bgClass ?? \"bg-muted\"\n )}\n aria-hidden\n >\n <Icon className={cn(\"h-4 w-4\", config?.colorClass ?? \"text-muted-foreground\")} />\n </span>\n\n <div className=\"flex items-start gap-3\">\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-semibold leading-8 sm:leading-8\">\n {EVENT_TITLE[event.type] ?? event.type}\n {amount ? <span className=\"ml-1.5 text-xs font-medium text-muted-foreground\">×{amount}</span> : null}\n {actor ? (\n <span className=\"font-normal text-muted-foreground\">\n {\" by \"}\n <Link\n href={profileHref({ address: actor })}\n className=\"hover:text-primary transition-colors\"\n >\n <AddressDisplay address={actor} chars={4} showCopy={false} className=\"text-xs\" />\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-1 inline-flex max-w-full items-center gap-2 rounded-lg bg-muted/40 py-1 pl-1 pr-3 hover:bg-muted transition-colors\"\n >\n <span className=\"relative h-8 w-8 shrink-0 overflow-hidden rounded-md bg-muted\">\n {image ? (\n <Image src={image} alt=\"\" width={32} height={32} 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-0.5 pt-1.5\">\n {event.price?.formatted ? (\n <span className=\"flex items-center gap-1.5 text-sm font-bold tabular-nums\">\n {event.price.currency ? <CurrencyIcon symbol={event.price.currency} size={13} aria-hidden /> : null}\n {formatDisplayPrice(event.price.formatted)}\n </span>\n ) : null}\n <span className=\"flex items-center gap-1.5 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 p-0.5 hover:bg-muted hover:text-foreground transition-colors\"\n aria-label=\"View transaction\"\n >\n <ExternalLink className=\"h-3 w-3\" aria-hidden />\n </a>\n ) : null}\n </span>\n </div>\n </div>\n </li>\n );\n}\n\nfunction ProvenanceSkeleton() {\n return (\n <div className=\"space-y-6\" aria-hidden>\n {Array.from({ length: 6 }).map((_, i) => (\n <div key={i} className=\"flex items-start gap-4\">\n <div className=\"h-8 w-8 shrink-0 rounded-full bg-muted animate-pulse\" />\n <div className=\"flex-1 space-y-2 pt-1\">\n <div className=\"h-3.5 w-40 rounded bg-muted animate-pulse\" />\n <div className=\"h-3 w-24 rounded bg-muted animate-pulse\" />\n </div>\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=\"mx-auto max-w-2xl\">\n {groups.map((group) => (\n <section key={group.label} className=\"mb-8 last:mb-0\">\n <h3 className=\"mb-4 pl-12 text-xs font-medium text-muted-foreground\">{group.label}</h3>\n <ol className=\"relative before:absolute before:left-4 before:top-4 before:bottom-4 before:w-px before:bg-border\">\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"]}
|
|
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"]}
|
|
@@ -53,80 +53,81 @@ function ProvenanceEvent({ event, showAsset }) {
|
|
|
53
53
|
const amount = event.amount && Number(event.amount) > 1 ? event.amount : null;
|
|
54
54
|
const name = event.token?.name ?? (tokenId ? `#${tokenId}` : null);
|
|
55
55
|
const image = resolveImage(event.token?.image ?? null);
|
|
56
|
-
return /* @__PURE__ */ jsxs("li", { className: "
|
|
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
57
|
/* @__PURE__ */ jsx(
|
|
58
58
|
"span",
|
|
59
59
|
{
|
|
60
60
|
className: cn(
|
|
61
|
-
"
|
|
61
|
+
"flex h-11 w-11 shrink-0 items-center justify-center rounded-xl",
|
|
62
62
|
config?.bgClass ?? "bg-muted"
|
|
63
63
|
),
|
|
64
64
|
"aria-hidden": true,
|
|
65
|
-
children: /* @__PURE__ */ jsx(Icon, { className: cn("h-
|
|
65
|
+
children: /* @__PURE__ */ jsx(Icon, { className: cn("h-5 w-5", config?.colorClass ?? "text-muted-foreground") })
|
|
66
66
|
}
|
|
67
67
|
),
|
|
68
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
69
|
-
/* @__PURE__ */ jsxs("
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
amount
|
|
75
|
-
] }) : null,
|
|
76
|
-
actor ? /* @__PURE__ */ jsxs("span", { className: "font-normal text-muted-foreground", children: [
|
|
77
|
-
" by ",
|
|
78
|
-
/* @__PURE__ */ jsx(
|
|
79
|
-
Link,
|
|
80
|
-
{
|
|
81
|
-
href: profileHref({ address: actor }),
|
|
82
|
-
className: "hover:text-primary transition-colors",
|
|
83
|
-
children: /* @__PURE__ */ jsx(AddressDisplay, { address: actor, chars: 4, showCopy: false, className: "text-xs" })
|
|
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-1 inline-flex max-w-full items-center gap-2 rounded-lg bg-muted/40 py-1 pl-1 pr-3 hover:bg-muted transition-colors",
|
|
93
|
-
children: [
|
|
94
|
-
/* @__PURE__ */ jsx("span", { className: "relative h-8 w-8 shrink-0 overflow-hidden rounded-md bg-muted", children: image ? /* @__PURE__ */ jsx(Image, { src: image, alt: "", width: 32, height: 32, 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-0.5 pt-1.5", children: [
|
|
101
|
-
event.price?.formatted ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5 text-sm font-bold tabular-nums", children: [
|
|
102
|
-
event.price.currency ? /* @__PURE__ */ jsx(CurrencyIcon, { symbol: event.price.currency, size: 13, "aria-hidden": true }) : null,
|
|
103
|
-
formatDisplayPrice(event.price.formatted)
|
|
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
|
|
104
74
|
] }) : null,
|
|
105
|
-
/* @__PURE__ */ jsxs("span", { className: "
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
75
|
+
actor ? /* @__PURE__ */ jsxs("span", { className: "text-sm font-normal text-muted-foreground", children: [
|
|
76
|
+
"by",
|
|
77
|
+
" ",
|
|
78
|
+
/* @__PURE__ */ jsx(
|
|
79
|
+
Link,
|
|
109
80
|
{
|
|
110
|
-
href:
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
className: "rounded p-0.5 hover:bg-muted hover:text-foreground transition-colors",
|
|
114
|
-
"aria-label": "View transaction",
|
|
115
|
-
children: /* @__PURE__ */ jsx(ExternalLink, { className: "h-3 w-3", "aria-hidden": true })
|
|
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" })
|
|
116
84
|
}
|
|
117
|
-
)
|
|
118
|
-
] })
|
|
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
119
|
] })
|
|
120
120
|
] })
|
|
121
121
|
] });
|
|
122
122
|
}
|
|
123
123
|
function ProvenanceSkeleton() {
|
|
124
|
-
return /* @__PURE__ */ jsx("div", { className: "space-y-
|
|
125
|
-
/* @__PURE__ */ jsx("div", { className: "h-
|
|
126
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-2
|
|
127
|
-
/* @__PURE__ */ jsx("div", { className: "h-
|
|
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
128
|
/* @__PURE__ */ jsx("div", { className: "h-3 w-24 rounded bg-muted animate-pulse" })
|
|
129
|
-
] })
|
|
129
|
+
] }),
|
|
130
|
+
/* @__PURE__ */ jsx("div", { className: "h-4 w-16 rounded bg-muted animate-pulse" })
|
|
130
131
|
] }, i)) });
|
|
131
132
|
}
|
|
132
133
|
function CollectionProvenanceTab({ contract }) {
|
|
@@ -151,10 +152,10 @@ function CollectionProvenanceTab({ contract }) {
|
|
|
151
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." })
|
|
152
153
|
] });
|
|
153
154
|
}
|
|
154
|
-
return /* @__PURE__ */ jsxs("div", { className: "
|
|
155
|
-
groups.map((group) => /* @__PURE__ */ jsxs("section", {
|
|
156
|
-
/* @__PURE__ */ jsx("h3", { className: "mb-
|
|
157
|
-
/* @__PURE__ */ jsx("ol", { className: "
|
|
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(
|
|
158
159
|
ProvenanceEvent,
|
|
159
160
|
{
|
|
160
161
|
event,
|
|
@@ -1 +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=\"relative pl-12 pb-6 last:pb-0\">\n <span\n className={cn(\n \"absolute left-0 top-0 flex h-8 w-8 items-center justify-center rounded-full ring-4 ring-background\",\n config?.bgClass ?? \"bg-muted\"\n )}\n aria-hidden\n >\n <Icon className={cn(\"h-4 w-4\", config?.colorClass ?? \"text-muted-foreground\")} />\n </span>\n\n <div className=\"flex items-start gap-3\">\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-semibold leading-8 sm:leading-8\">\n {EVENT_TITLE[event.type] ?? event.type}\n {amount ? <span className=\"ml-1.5 text-xs font-medium text-muted-foreground\">×{amount}</span> : null}\n {actor ? (\n <span className=\"font-normal text-muted-foreground\">\n {\" by \"}\n <Link\n href={profileHref({ address: actor })}\n className=\"hover:text-primary transition-colors\"\n >\n <AddressDisplay address={actor} chars={4} showCopy={false} className=\"text-xs\" />\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-1 inline-flex max-w-full items-center gap-2 rounded-lg bg-muted/40 py-1 pl-1 pr-3 hover:bg-muted transition-colors\"\n >\n <span className=\"relative h-8 w-8 shrink-0 overflow-hidden rounded-md bg-muted\">\n {image ? (\n <Image src={image} alt=\"\" width={32} height={32} 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-0.5 pt-1.5\">\n {event.price?.formatted ? (\n <span className=\"flex items-center gap-1.5 text-sm font-bold tabular-nums\">\n {event.price.currency ? <CurrencyIcon symbol={event.price.currency} size={13} aria-hidden /> : null}\n {formatDisplayPrice(event.price.formatted)}\n </span>\n ) : null}\n <span className=\"flex items-center gap-1.5 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 p-0.5 hover:bg-muted hover:text-foreground transition-colors\"\n aria-label=\"View transaction\"\n >\n <ExternalLink className=\"h-3 w-3\" aria-hidden />\n </a>\n ) : null}\n </span>\n </div>\n </div>\n </li>\n );\n}\n\nfunction ProvenanceSkeleton() {\n return (\n <div className=\"space-y-6\" aria-hidden>\n {Array.from({ length: 6 }).map((_, i) => (\n <div key={i} className=\"flex items-start gap-4\">\n <div className=\"h-8 w-8 shrink-0 rounded-full bg-muted animate-pulse\" />\n <div className=\"flex-1 space-y-2 pt-1\">\n <div className=\"h-3.5 w-40 rounded bg-muted animate-pulse\" />\n <div className=\"h-3 w-24 rounded bg-muted animate-pulse\" />\n </div>\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=\"mx-auto max-w-2xl\">\n {groups.map((group) => (\n <section key={group.label} className=\"mb-8 last:mb-0\">\n <h3 className=\"mb-4 pl-12 text-xs font-medium text-muted-foreground\">{group.label}</h3>\n <ol className=\"relative before:absolute before:left-4 before:top-4 before:bottom-4 before:w-px before:bg-border\">\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
|
+
{"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":";AAwEQ,cAMY,YANZ;AAtER,SAAS,UAAU,WAAW,eAAe;AAE7C,SAAS,WAAW,mBAAmB;AACvC,SAAS,cAAc,aAAa;AACpC,OAAO,WAAW;AAClB,OAAO,UAAU;AACjB,SAAS,sBAAsB;AAC/B,SAAS,oBAAoB;AAC7B,SAAS,wBAAwB;AACjC,SAAS,qBAAqB;AAC9B,SAAS,mBAAmB;AAC5B,SAAS,4BAA4B;AACrC,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,eAAe;AACxB,SAAS,UAAU;AAEnB,MAAM,YAAY;AAElB,MAAM,cAAsC;AAAA,EAC1C,MAAM;AAAA,EACN,SAAS;AAAA,EACT,MAAM;AAAA,EACN,OAAO;AAAA,EACP,UAAU;AAAA,EACV,WAAW;AACb;AAEA,SAAS,SAAS,KAAqB;AACrC,QAAM,OAAO,IAAI,KAAK,GAAG;AACzB,QAAM,QAAQ,oBAAI,KAAK;AACvB,QAAM,YAAY,oBAAI,KAAK;AAC3B,YAAU,QAAQ,MAAM,QAAQ,IAAI,CAAC;AACrC,MAAI,KAAK,aAAa,MAAM,MAAM,aAAa,EAAG,QAAO;AACzD,MAAI,KAAK,aAAa,MAAM,UAAU,aAAa,EAAG,QAAO;AAC7D,SAAO,KAAK,mBAAmB,QAAW,EAAE,KAAK,WAAW,OAAO,QAAQ,MAAM,UAAU,CAAC;AAC9F;AAEA,SAAS,WAAW,QAAuB;AACzC,QAAM,SAAqD,CAAC;AAC5D,aAAW,SAAS,QAAQ;AAC1B,UAAM,QAAQ,SAAS,MAAM,SAAS;AACtC,UAAM,OAAO,OAAO,OAAO,SAAS,CAAC;AACrC,QAAI,QAAQ,KAAK,UAAU,MAAO,MAAK,OAAO,KAAK,KAAK;AAAA,QACnD,QAAO,KAAK,EAAE,OAAO,QAAQ,CAAC,KAAK,EAAE,CAAC;AAAA,EAC7C;AACA,SAAO;AACT;AAEA,SAAS,gBAAgB,EAAE,OAAO,UAAU,GAA+C;AACzF,QAAM,eAAe,YAAY;AACjC,QAAM,SAAS,qBAAqB,MAAM,IAAI;AAC9C,QAAM,OAAO,QAAQ,QAAQ;AAC7B,QAAM,WAAW,MAAM,eAAe,MAAM,mBAAmB;AAC/D,QAAM,UAAU,MAAM,cAAc,MAAM,WAAW;AACrD,QAAM,QACJ,MAAM,WAAW,MAAM,cAAc,MAAM,SAAS,SAAS,MAAM,KAAK,MAAM,SAAS;AACzF,QAAM,SAAS,MAAM,UAAU,OAAO,MAAM,MAAM,IAAI,IAAI,MAAM,SAAS;AACzE,QAAM,OAAO,MAAM,OAAO,SAAS,UAAU,IAAI,OAAO,KAAK;AAC7D,QAAM,QAAQ,aAAa,MAAM,OAAO,SAAS,IAAI;AAErD,SACE,qBAAC,QAAG,WAAU,kIACZ;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,UACT;AAAA,UACA,QAAQ,WAAW;AAAA,QACrB;AAAA,QACA,eAAW;AAAA,QAEX,8BAAC,QAAK,WAAW,GAAG,WAAW,QAAQ,cAAc,uBAAuB,GAAG;AAAA;AAAA,IACjF;AAAA,IAEA,qBAAC,SAAI,WAAU,kBACb;AAAA,2BAAC,OAAE,WAAU,iFACV;AAAA,oBAAY,MAAM,IAAI,KAAK,MAAM;AAAA,QACjC,SAAS,qBAAC,UAAK,WAAU,6CAA4C;AAAA;AAAA,UAAE;AAAA,WAAO,IAAU;AAAA,QACxF,QACC,qBAAC,UAAK,WAAU,6CAA4C;AAAA;AAAA,UACvD;AAAA,UACH;AAAA,YAAC;AAAA;AAAA,cACC,MAAM,YAAY,EAAE,SAAS,MAAM,CAAC;AAAA,cACpC,WAAU;AAAA,cAEV,8BAAC,kBAAe,SAAS,OAAO,OAAO,GAAG,UAAU,OAAO,WAAU,WAAU;AAAA;AAAA,UACjF;AAAA,WACF,IACE;AAAA,SACN;AAAA,MAEC,aAAa,OACZ;AAAA,QAAC;AAAA;AAAA,UACC,MAAM,YAAY,UAAU,UAAU,MAAM,SAAS,YAAY,UAAU,OAAO,IAAI;AAAA,UACtF,WAAU;AAAA,UAEV;AAAA,gCAAC,UAAK,WAAU,mEACb,kBACC,oBAAC,SAAM,KAAK,OAAO,KAAI,IAAG,OAAO,IAAI,QAAQ,IAAI,WAAU,8BAA6B,aAAW,MAAC,IAClG,MACN;AAAA,YACA,oBAAC,UAAK,WAAU,gCAAgC,gBAAK;AAAA;AAAA;AAAA,MACvD,IACE;AAAA,OACN;AAAA,IAEA,qBAAC,SAAI,WAAU,0CACZ;AAAA,YAAM,OAAO,YACZ,qBAAC,UAAK,WAAU,8DACb;AAAA,cAAM,MAAM,WAAW,oBAAC,gBAAa,QAAQ,MAAM,MAAM,UAAU,MAAM,IAAI,eAAW,MAAC,IAAK;AAAA,QAC9F,mBAAmB,MAAM,MAAM,SAAS;AAAA,QACxC,MAAM,MAAM,WACX,oBAAC,UAAK,WAAU,6CAA6C,gBAAM,MAAM,UAAS,IAChF;AAAA,SACN,IACE;AAAA,MACJ,qBAAC,UAAK,WAAU,yDACd;AAAA,4BAAC,UAAK,UAAU,MAAM,WAAW,OAAO,IAAI,KAAK,MAAM,SAAS,EAAE,eAAe,GAC9E,kBAAQ,MAAM,SAAS,GAC1B;AAAA,QACC,MAAM,SACL;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,GAAG,YAAY,OAAO,MAAM,MAAM;AAAA,YACxC,QAAO;AAAA,YACP,KAAI;AAAA,YACJ,WAAU;AAAA,YACV,cAAW;AAAA,YAEX,8BAAC,gBAAa,WAAU,eAAc,eAAW,MAAC;AAAA;AAAA,QACpD,IACE;AAAA,SACN;AAAA,OACF;AAAA,KACF;AAEJ;AAEA,SAAS,qBAAqB;AAC5B,SACE,oBAAC,SAAI,WAAU,eAAc,eAAW,MACrC,gBAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,MACjC,qBAAC,SAAY,WAAU,8EACrB;AAAA,wBAAC,SAAI,WAAU,wDAAuD;AAAA,IACtE,qBAAC,SAAI,WAAU,oBACb;AAAA,0BAAC,SAAI,WAAU,2CAA0C;AAAA,MACzD,oBAAC,SAAI,WAAU,2CAA0C;AAAA,OAC3D;AAAA,IACA,oBAAC,SAAI,WAAU,2CAA0C;AAAA,OANjD,CAOV,CACD,GACH;AAEJ;AAMO,SAAS,wBAAwB,EAAE,SAAS,GAAiC;AAClF,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,CAAC;AAClC,QAAM,CAAC,KAAK,MAAM,IAAI,SAAwB,CAAC,CAAC;AAChD,QAAM,EAAE,YAAY,MAAM,UAAU,IAAI,cAAc,EAAE,UAAU,MAAM,OAAO,UAAU,CAAC;AAE1F,YAAU,MAAM;AACd,QAAI,WAAW,WAAW,EAAG;AAC7B,WAAO,CAAC,SAAU,SAAS,IAAI,aAAa,CAAC,GAAG,MAAM,GAAG,UAAU,CAAE;AAAA,EACvE,GAAG,CAAC,YAAY,IAAI,CAAC;AAErB,QAAM,SAAS,QAAQ,MAAM,WAAW,GAAG,GAAG,CAAC,GAAG,CAAC;AACnD,QAAM,YAAY;AAAA,IAChB,MAAM,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,EAAE,OAAO;AAAA,IACtE,CAAC,GAAG;AAAA,EACN;AACA,QAAM,UAAU,OAAO,IAAI,UAAU,KAAK,SAAS,KAAK;AAExD,MAAI,aAAa,IAAI,WAAW,EAAG,QAAO,oBAAC,sBAAmB;AAE9D,MAAI,IAAI,WAAW,GAAG;AACpB,WACE,qBAAC,SAAI,WAAU,sDACb;AAAA,0BAAC,SAAM,WAAU,sCAAqC;AAAA,MACtD,oBAAC,OAAE,WAAU,6CAA4C,4BAAc;AAAA,MACvE,oBAAC,OAAE,WAAU,6CAA4C,mFAEzD;AAAA,OACF;AAAA,EAEJ;AAEA,SACE,qBAAC,SAAI,WAAU,aACZ;AAAA,WAAO,IAAI,CAAC,UACX,qBAAC,aACC;AAAA,0BAAC,QAAG,WAAU,uCAAuC,gBAAM,OAAM;AAAA,MACjE,oBAAC,QAAG,WAAU,eACX,gBAAM,OAAO,IAAI,CAAC,OAAO,MACxB;AAAA,QAAC;AAAA;AAAA,UAEC;AAAA,UACA;AAAA;AAAA,QAFK,GAAG,MAAM,UAAU,MAAM,SAAS,IAAI,MAAM,IAAI,IAAI,CAAC;AAAA,MAG5D,CACD,GACH;AAAA,SAVY,MAAM,KAWpB,CACD;AAAA,IACD,oBAAC,oBAAiB,SAAkB,WAAsB,YAAY,MAAM,QAAQ,CAAC,MAAM,IAAI,CAAC,GAAG;AAAA,KACrG;AAEJ;","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 };
|
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":[]}
|
package/dist/data/activity.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { ArrowRightLeft, Tag, ShoppingCart, HandCoins, X, Sparkles } from "lucide-react";
|
|
2
2
|
const ACTIVITY_TYPE_CONFIG = {
|
|
3
|
-
mint: { label: "Mint", variant: "default", icon: Sparkles, colorClass: "text-
|
|
4
|
-
transfer: { label: "Transfer", variant: "secondary", icon: ArrowRightLeft, colorClass: "text-
|
|
5
|
-
listing: { label: "Listed", variant: "default", icon: Tag, colorClass: "text-
|
|
6
|
-
sale: { label: "Sale", variant: "default", icon: ShoppingCart, colorClass: "text-
|
|
7
|
-
offer: { label: "Offer", variant: "outline", icon: HandCoins, colorClass: "text-
|
|
8
|
-
cancelled: { label: "Cancelled", variant: "outline", icon: X, colorClass: "text-
|
|
3
|
+
mint: { label: "Mint", variant: "default", icon: Sparkles, colorClass: "text-brand-purple", bgClass: "bg-brand-purple/10" },
|
|
4
|
+
transfer: { label: "Transfer", variant: "secondary", icon: ArrowRightLeft, colorClass: "text-brand-blue", bgClass: "bg-brand-blue/10" },
|
|
5
|
+
listing: { label: "Listed", variant: "default", icon: Tag, colorClass: "text-brand-orange", bgClass: "bg-brand-orange/10" },
|
|
6
|
+
sale: { label: "Sale", variant: "default", icon: ShoppingCart, colorClass: "text-brand-rose", bgClass: "bg-brand-rose/10" },
|
|
7
|
+
offer: { label: "Offer", variant: "outline", icon: HandCoins, colorClass: "text-brand-maeve", bgClass: "bg-brand-maeve/10" },
|
|
8
|
+
cancelled: { label: "Cancelled", variant: "outline", icon: X, colorClass: "text-muted-foreground", bgClass: "bg-muted" }
|
|
9
9
|
};
|
|
10
10
|
const TYPE_FILTERS = [
|
|
11
11
|
{ 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,SAAS,gBAAgB,KAAK,cAAc,WAAW,GAAG,gBAAgB;AAWnE,MAAM,uBAA2D;AAAA,EACtE,MAAW,EAAE,OAAO,QAAa,SAAS,WAAa,MAAM,UAAgB,YAAY,qBAAqB,SAAS,qBAAqB;AAAA,EAC5I,UAAW,EAAE,OAAO,YAAa,SAAS,aAAa,MAAM,gBAAgB,YAAY,mBAAqB,SAAS,mBAAmB;AAAA,EAC1I,SAAW,EAAE,OAAO,UAAa,SAAS,WAAa,MAAM,KAAgB,YAAY,qBAAqB,SAAS,qBAAqB;AAAA,EAC5I,MAAW,EAAE,OAAO,QAAa,SAAS,WAAa,MAAM,cAAgB,YAAY,mBAAqB,SAAS,mBAAmB;AAAA,EAC1I,OAAW,EAAE,OAAO,SAAa,SAAS,WAAa,MAAM,WAAgB,YAAY,oBAAqB,SAAS,oBAAoB;AAAA,EAC3I,WAAW,EAAE,OAAO,aAAa,SAAS,WAAa,MAAM,GAAgB,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":[]}
|
|
@@ -7,7 +7,7 @@ declare function useTokenBalance(symbol: string | null, holderAddress: string |
|
|
|
7
7
|
rawBalance: bigint | null;
|
|
8
8
|
isLoading: boolean;
|
|
9
9
|
error: any;
|
|
10
|
-
decimals:
|
|
10
|
+
decimals: 8 | 6 | 18;
|
|
11
11
|
};
|
|
12
12
|
declare function hasSufficientBalance(rawBalance: bigint | null, requiredHuman: string, decimals: number): boolean | null;
|
|
13
13
|
|
|
@@ -7,7 +7,7 @@ declare function useTokenBalance(symbol: string | null, holderAddress: string |
|
|
|
7
7
|
rawBalance: bigint | null;
|
|
8
8
|
isLoading: boolean;
|
|
9
9
|
error: any;
|
|
10
|
-
decimals:
|
|
10
|
+
decimals: 8 | 6 | 18;
|
|
11
11
|
};
|
|
12
12
|
declare function hasSufficientBalance(rawBalance: bigint | null, requiredHuman: string, decimals: number): boolean | null;
|
|
13
13
|
|