@medialane/ui 0.302.0 → 0.303.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.
@@ -62,7 +62,7 @@ function AssetCard({
62
62
  "div",
63
63
  {
64
64
  className: (0, import_cn.cn)(
65
- "group relative flex flex-col w-full overflow-hidden rounded-xl border border-border/50 bg-card transition-colors hover:border-border",
65
+ "group relative flex flex-col w-full overflow-hidden rounded-xl bg-card",
66
66
  className
67
67
  ),
68
68
  children: [
@@ -109,7 +109,7 @@ function AssetCard({
109
109
  );
110
110
  }
111
111
  function AssetCardSkeleton() {
112
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col w-full overflow-hidden rounded-xl border border-border/50 bg-card", children: [
112
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col w-full overflow-hidden rounded-xl bg-card", children: [
113
113
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "aspect-square w-full animate-pulse bg-muted" }),
114
114
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-3 py-3 space-y-1.5", children: [
115
115
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-4 w-3/4 rounded-md animate-pulse bg-muted" }),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/asset-card.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport { Loader2 } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { PriceChipContent } from \"./dual-price.js\";\nimport { IpTypeBadge } from \"./ip-type-badge.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nexport interface AssetCardPrice {\n formatted?: string | null;\n currency?: string | null;\n\n usdValue?: string | null;\n}\n\nexport interface AssetCardProps {\n\n href: string;\n\n name: string;\n\n image?: string | null;\n\n animationUrl?: string | null;\n\n live?: boolean;\n\n subtitle?: string | null;\n\n ipType?: string | null;\n\n price?: AssetCardPrice | null;\n\n fallbackId?: string | null;\n\n indexing?: boolean;\n\n ipTypeBaseUrl?: string;\n className?: string;\n}\n\nexport function AssetCard({\n href,\n name,\n image,\n animationUrl,\n live = false,\n subtitle,\n ipType,\n price,\n fallbackId,\n indexing = false,\n ipTypeBaseUrl = \"\",\n className,\n}: AssetCardProps) {\n const resolveImage = useImageUrl();\n const resolved = resolveImage(image, { width: 480 });\n const hasPrice = !!price?.formatted;\n\n return (\n <div\n className={cn(\n \"group relative flex flex-col w-full overflow-hidden rounded-xl border border-border/50 bg-card transition-colors hover:border-border\",\n className\n )}\n >\n\n {ipType && (\n <div className=\"absolute top-2 right-2 z-10\">\n <IpTypeBadge ipType={ipType} size=\"sm\" baseUrl={ipTypeBaseUrl} />\n </div>\n )}\n\n <Link href={href} className=\"block relative aspect-square bg-muted overflow-hidden\">\n <AnimatedTokenMedia\n image={resolved}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 22vw\"\n className=\"object-cover transition-transform duration-700 ease-out group-hover:scale-[1.03]\"\n fallback={\n <div className=\"absolute inset-0 flex items-center justify-center bg-gradient-to-br from-brand-blue/25 via-brand-purple/25 to-brand-rose/25\">\n <span className=\"text-sm font-semibold text-muted-foreground tabular-nums\">\n #{fallbackId ?? \"?\"}\n </span>\n </div>\n }\n />\n\n {indexing && (\n <div className=\"absolute bottom-0 inset-x-0 flex items-center justify-center gap-1.5 bg-black/50 backdrop-blur-sm py-1.5\">\n <Loader2 className=\"h-3 w-3 animate-spin text-white/70\" />\n <span className=\"text-2xs text-white/70\">Indexing…</span>\n </div>\n )}\n </Link>\n\n <div className=\"px-3 py-3 space-y-1\">\n <Link href={href} className=\"block min-w-0\">\n <p className=\"text-base font-semibold tracking-tight line-clamp-2 break-words leading-snug\">\n {name}\n </p>\n {subtitle && (\n <p className=\"text-xs text-muted-foreground line-clamp-1 leading-snug\">\n {subtitle}\n </p>\n )}\n </Link>\n\n {hasPrice && !indexing && (\n <div className=\"flex items-center gap-1.5 text-sm font-bold tabular-nums pt-0.5\">\n <PriceChipContent\n amountFormatted={price!.formatted}\n currency={price!.currency}\n usdValue={price!.usdValue}\n tone=\"solid\"\n />\n </div>\n )}\n </div>\n </div>\n );\n}\n\nexport function AssetCardSkeleton() {\n return (\n <div className=\"flex flex-col w-full overflow-hidden rounded-xl border border-border/50 bg-card\">\n <div className=\"aspect-square w-full animate-pulse bg-muted\" />\n <div className=\"px-3 py-3 space-y-1.5\">\n <div className=\"h-4 w-3/4 rounded-md animate-pulse bg-muted\" />\n <div className=\"h-3.5 w-2/5 rounded-md animate-pulse bg-muted\" />\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuEU;AArEV,kBAAiB;AACjB,0BAAwB;AACxB,gBAAmB;AACnB,wBAAiC;AACjC,2BAA4B;AAC5B,kCAAmC;AACnC,2BAA4B;AAmCrB,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,gBAAgB;AAAA,EAChB;AACF,GAAmB;AACjB,QAAM,mBAAe,kCAAY;AACjC,QAAM,WAAW,aAAa,OAAO,EAAE,OAAO,IAAI,CAAC;AACnD,QAAM,WAAW,CAAC,CAAC,OAAO;AAE1B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MAGC;AAAA,kBACC,4CAAC,SAAI,WAAU,+BACb,sDAAC,oCAAY,QAAgB,MAAK,MAAK,SAAS,eAAe,GACjE;AAAA,QAGF,6CAAC,YAAAA,SAAA,EAAK,MAAY,WAAU,yDAC1B;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,cACP;AAAA,cACA;AAAA,cACA,KAAK;AAAA,cACL,MAAK;AAAA,cACL,OAAM;AAAA,cACN,WAAU;AAAA,cACV,UACE,4CAAC,SAAI,WAAU,+HACb,uDAAC,UAAK,WAAU,4DAA2D;AAAA;AAAA,gBACvE,cAAc;AAAA,iBAClB,GACF;AAAA;AAAA,UAEJ;AAAA,UAEC,YACC,6CAAC,SAAI,WAAU,4GACb;AAAA,wDAAC,+BAAQ,WAAU,sCAAqC;AAAA,YACxD,4CAAC,UAAK,WAAU,0BAAyB,4BAAS;AAAA,aACpD;AAAA,WAEJ;AAAA,QAEA,6CAAC,SAAI,WAAU,uBACb;AAAA,uDAAC,YAAAA,SAAA,EAAK,MAAY,WAAU,iBAC1B;AAAA,wDAAC,OAAE,WAAU,gFACV,gBACH;AAAA,YACC,YACC,4CAAC,OAAE,WAAU,2DACV,oBACH;AAAA,aAEJ;AAAA,UAEC,YAAY,CAAC,YACZ,4CAAC,SAAI,WAAU,mEACb;AAAA,YAAC;AAAA;AAAA,cACC,iBAAiB,MAAO;AAAA,cACxB,UAAU,MAAO;AAAA,cACjB,UAAU,MAAO;AAAA,cACjB,MAAK;AAAA;AAAA,UACP,GACF;AAAA,WAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,oBAAoB;AAClC,SACE,6CAAC,SAAI,WAAU,mFACb;AAAA,gDAAC,SAAI,WAAU,+CAA8C;AAAA,IAC7D,6CAAC,SAAI,WAAU,yBACb;AAAA,kDAAC,SAAI,WAAU,+CAA8C;AAAA,MAC7D,4CAAC,SAAI,WAAU,iDAAgD;AAAA,OACjE;AAAA,KACF;AAEJ;","names":["Link"]}
1
+ {"version":3,"sources":["../../src/components/asset-card.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport { Loader2 } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { PriceChipContent } from \"./dual-price.js\";\nimport { IpTypeBadge } from \"./ip-type-badge.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nexport interface AssetCardPrice {\n formatted?: string | null;\n currency?: string | null;\n\n usdValue?: string | null;\n}\n\nexport interface AssetCardProps {\n\n href: string;\n\n name: string;\n\n image?: string | null;\n\n animationUrl?: string | null;\n\n live?: boolean;\n\n subtitle?: string | null;\n\n ipType?: string | null;\n\n price?: AssetCardPrice | null;\n\n fallbackId?: string | null;\n\n indexing?: boolean;\n\n ipTypeBaseUrl?: string;\n className?: string;\n}\n\nexport function AssetCard({\n href,\n name,\n image,\n animationUrl,\n live = false,\n subtitle,\n ipType,\n price,\n fallbackId,\n indexing = false,\n ipTypeBaseUrl = \"\",\n className,\n}: AssetCardProps) {\n const resolveImage = useImageUrl();\n const resolved = resolveImage(image, { width: 480 });\n const hasPrice = !!price?.formatted;\n\n return (\n <div\n className={cn(\n \"group relative flex flex-col w-full overflow-hidden rounded-xl bg-card\",\n className\n )}\n >\n\n {ipType && (\n <div className=\"absolute top-2 right-2 z-10\">\n <IpTypeBadge ipType={ipType} size=\"sm\" baseUrl={ipTypeBaseUrl} />\n </div>\n )}\n\n <Link href={href} className=\"block relative aspect-square bg-muted overflow-hidden\">\n <AnimatedTokenMedia\n image={resolved}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 22vw\"\n className=\"object-cover transition-transform duration-700 ease-out group-hover:scale-[1.03]\"\n fallback={\n <div className=\"absolute inset-0 flex items-center justify-center bg-gradient-to-br from-brand-blue/25 via-brand-purple/25 to-brand-rose/25\">\n <span className=\"text-sm font-semibold text-muted-foreground tabular-nums\">\n #{fallbackId ?? \"?\"}\n </span>\n </div>\n }\n />\n\n {indexing && (\n <div className=\"absolute bottom-0 inset-x-0 flex items-center justify-center gap-1.5 bg-black/50 backdrop-blur-sm py-1.5\">\n <Loader2 className=\"h-3 w-3 animate-spin text-white/70\" />\n <span className=\"text-2xs text-white/70\">Indexing…</span>\n </div>\n )}\n </Link>\n\n <div className=\"px-3 py-3 space-y-1\">\n <Link href={href} className=\"block min-w-0\">\n <p className=\"text-base font-semibold tracking-tight line-clamp-2 break-words leading-snug\">\n {name}\n </p>\n {subtitle && (\n <p className=\"text-xs text-muted-foreground line-clamp-1 leading-snug\">\n {subtitle}\n </p>\n )}\n </Link>\n\n {hasPrice && !indexing && (\n <div className=\"flex items-center gap-1.5 text-sm font-bold tabular-nums pt-0.5\">\n <PriceChipContent\n amountFormatted={price!.formatted}\n currency={price!.currency}\n usdValue={price!.usdValue}\n tone=\"solid\"\n />\n </div>\n )}\n </div>\n </div>\n );\n}\n\nexport function AssetCardSkeleton() {\n return (\n <div className=\"flex flex-col w-full overflow-hidden rounded-xl bg-card\">\n <div className=\"aspect-square w-full animate-pulse bg-muted\" />\n <div className=\"px-3 py-3 space-y-1.5\">\n <div className=\"h-4 w-3/4 rounded-md animate-pulse bg-muted\" />\n <div className=\"h-3.5 w-2/5 rounded-md animate-pulse bg-muted\" />\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuEU;AArEV,kBAAiB;AACjB,0BAAwB;AACxB,gBAAmB;AACnB,wBAAiC;AACjC,2BAA4B;AAC5B,kCAAmC;AACnC,2BAA4B;AAmCrB,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,gBAAgB;AAAA,EAChB;AACF,GAAmB;AACjB,QAAM,mBAAe,kCAAY;AACjC,QAAM,WAAW,aAAa,OAAO,EAAE,OAAO,IAAI,CAAC;AACnD,QAAM,WAAW,CAAC,CAAC,OAAO;AAE1B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MAGC;AAAA,kBACC,4CAAC,SAAI,WAAU,+BACb,sDAAC,oCAAY,QAAgB,MAAK,MAAK,SAAS,eAAe,GACjE;AAAA,QAGF,6CAAC,YAAAA,SAAA,EAAK,MAAY,WAAU,yDAC1B;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,cACP;AAAA,cACA;AAAA,cACA,KAAK;AAAA,cACL,MAAK;AAAA,cACL,OAAM;AAAA,cACN,WAAU;AAAA,cACV,UACE,4CAAC,SAAI,WAAU,+HACb,uDAAC,UAAK,WAAU,4DAA2D;AAAA;AAAA,gBACvE,cAAc;AAAA,iBAClB,GACF;AAAA;AAAA,UAEJ;AAAA,UAEC,YACC,6CAAC,SAAI,WAAU,4GACb;AAAA,wDAAC,+BAAQ,WAAU,sCAAqC;AAAA,YACxD,4CAAC,UAAK,WAAU,0BAAyB,4BAAS;AAAA,aACpD;AAAA,WAEJ;AAAA,QAEA,6CAAC,SAAI,WAAU,uBACb;AAAA,uDAAC,YAAAA,SAAA,EAAK,MAAY,WAAU,iBAC1B;AAAA,wDAAC,OAAE,WAAU,gFACV,gBACH;AAAA,YACC,YACC,4CAAC,OAAE,WAAU,2DACV,oBACH;AAAA,aAEJ;AAAA,UAEC,YAAY,CAAC,YACZ,4CAAC,SAAI,WAAU,mEACb;AAAA,YAAC;AAAA;AAAA,cACC,iBAAiB,MAAO;AAAA,cACxB,UAAU,MAAO;AAAA,cACjB,UAAU,MAAO;AAAA,cACjB,MAAK;AAAA;AAAA,UACP,GACF;AAAA,WAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,oBAAoB;AAClC,SACE,6CAAC,SAAI,WAAU,2DACb;AAAA,gDAAC,SAAI,WAAU,+CAA8C;AAAA,IAC7D,6CAAC,SAAI,WAAU,yBACb;AAAA,kDAAC,SAAI,WAAU,+CAA8C;AAAA,MAC7D,4CAAC,SAAI,WAAU,iDAAgD;AAAA,OACjE;AAAA,KACF;AAEJ;","names":["Link"]}
@@ -28,7 +28,7 @@ function AssetCard({
28
28
  "div",
29
29
  {
30
30
  className: cn(
31
- "group relative flex flex-col w-full overflow-hidden rounded-xl border border-border/50 bg-card transition-colors hover:border-border",
31
+ "group relative flex flex-col w-full overflow-hidden rounded-xl bg-card",
32
32
  className
33
33
  ),
34
34
  children: [
@@ -75,7 +75,7 @@ function AssetCard({
75
75
  );
76
76
  }
77
77
  function AssetCardSkeleton() {
78
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col w-full overflow-hidden rounded-xl border border-border/50 bg-card", children: [
78
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col w-full overflow-hidden rounded-xl bg-card", children: [
79
79
  /* @__PURE__ */ jsx("div", { className: "aspect-square w-full animate-pulse bg-muted" }),
80
80
  /* @__PURE__ */ jsxs("div", { className: "px-3 py-3 space-y-1.5", children: [
81
81
  /* @__PURE__ */ jsx("div", { className: "h-4 w-3/4 rounded-md animate-pulse bg-muted" }),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/asset-card.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport { Loader2 } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { PriceChipContent } from \"./dual-price.js\";\nimport { IpTypeBadge } from \"./ip-type-badge.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nexport interface AssetCardPrice {\n formatted?: string | null;\n currency?: string | null;\n\n usdValue?: string | null;\n}\n\nexport interface AssetCardProps {\n\n href: string;\n\n name: string;\n\n image?: string | null;\n\n animationUrl?: string | null;\n\n live?: boolean;\n\n subtitle?: string | null;\n\n ipType?: string | null;\n\n price?: AssetCardPrice | null;\n\n fallbackId?: string | null;\n\n indexing?: boolean;\n\n ipTypeBaseUrl?: string;\n className?: string;\n}\n\nexport function AssetCard({\n href,\n name,\n image,\n animationUrl,\n live = false,\n subtitle,\n ipType,\n price,\n fallbackId,\n indexing = false,\n ipTypeBaseUrl = \"\",\n className,\n}: AssetCardProps) {\n const resolveImage = useImageUrl();\n const resolved = resolveImage(image, { width: 480 });\n const hasPrice = !!price?.formatted;\n\n return (\n <div\n className={cn(\n \"group relative flex flex-col w-full overflow-hidden rounded-xl border border-border/50 bg-card transition-colors hover:border-border\",\n className\n )}\n >\n\n {ipType && (\n <div className=\"absolute top-2 right-2 z-10\">\n <IpTypeBadge ipType={ipType} size=\"sm\" baseUrl={ipTypeBaseUrl} />\n </div>\n )}\n\n <Link href={href} className=\"block relative aspect-square bg-muted overflow-hidden\">\n <AnimatedTokenMedia\n image={resolved}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 22vw\"\n className=\"object-cover transition-transform duration-700 ease-out group-hover:scale-[1.03]\"\n fallback={\n <div className=\"absolute inset-0 flex items-center justify-center bg-gradient-to-br from-brand-blue/25 via-brand-purple/25 to-brand-rose/25\">\n <span className=\"text-sm font-semibold text-muted-foreground tabular-nums\">\n #{fallbackId ?? \"?\"}\n </span>\n </div>\n }\n />\n\n {indexing && (\n <div className=\"absolute bottom-0 inset-x-0 flex items-center justify-center gap-1.5 bg-black/50 backdrop-blur-sm py-1.5\">\n <Loader2 className=\"h-3 w-3 animate-spin text-white/70\" />\n <span className=\"text-2xs text-white/70\">Indexing…</span>\n </div>\n )}\n </Link>\n\n <div className=\"px-3 py-3 space-y-1\">\n <Link href={href} className=\"block min-w-0\">\n <p className=\"text-base font-semibold tracking-tight line-clamp-2 break-words leading-snug\">\n {name}\n </p>\n {subtitle && (\n <p className=\"text-xs text-muted-foreground line-clamp-1 leading-snug\">\n {subtitle}\n </p>\n )}\n </Link>\n\n {hasPrice && !indexing && (\n <div className=\"flex items-center gap-1.5 text-sm font-bold tabular-nums pt-0.5\">\n <PriceChipContent\n amountFormatted={price!.formatted}\n currency={price!.currency}\n usdValue={price!.usdValue}\n tone=\"solid\"\n />\n </div>\n )}\n </div>\n </div>\n );\n}\n\nexport function AssetCardSkeleton() {\n return (\n <div className=\"flex flex-col w-full overflow-hidden rounded-xl border border-border/50 bg-card\">\n <div className=\"aspect-square w-full animate-pulse bg-muted\" />\n <div className=\"px-3 py-3 space-y-1.5\">\n <div className=\"h-4 w-3/4 rounded-md animate-pulse bg-muted\" />\n <div className=\"h-3.5 w-2/5 rounded-md animate-pulse bg-muted\" />\n </div>\n </div>\n );\n}\n"],"mappings":";AAuEU,cAeI,YAfJ;AArEV,OAAO,UAAU;AACjB,SAAS,eAAe;AACxB,SAAS,UAAU;AACnB,SAAS,wBAAwB;AACjC,SAAS,mBAAmB;AAC5B,SAAS,0BAA0B;AACnC,SAAS,mBAAmB;AAmCrB,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,gBAAgB;AAAA,EAChB;AACF,GAAmB;AACjB,QAAM,eAAe,YAAY;AACjC,QAAM,WAAW,aAAa,OAAO,EAAE,OAAO,IAAI,CAAC;AACnD,QAAM,WAAW,CAAC,CAAC,OAAO;AAE1B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MAGC;AAAA,kBACC,oBAAC,SAAI,WAAU,+BACb,8BAAC,eAAY,QAAgB,MAAK,MAAK,SAAS,eAAe,GACjE;AAAA,QAGF,qBAAC,QAAK,MAAY,WAAU,yDAC1B;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,cACP;AAAA,cACA;AAAA,cACA,KAAK;AAAA,cACL,MAAK;AAAA,cACL,OAAM;AAAA,cACN,WAAU;AAAA,cACV,UACE,oBAAC,SAAI,WAAU,+HACb,+BAAC,UAAK,WAAU,4DAA2D;AAAA;AAAA,gBACvE,cAAc;AAAA,iBAClB,GACF;AAAA;AAAA,UAEJ;AAAA,UAEC,YACC,qBAAC,SAAI,WAAU,4GACb;AAAA,gCAAC,WAAQ,WAAU,sCAAqC;AAAA,YACxD,oBAAC,UAAK,WAAU,0BAAyB,4BAAS;AAAA,aACpD;AAAA,WAEJ;AAAA,QAEA,qBAAC,SAAI,WAAU,uBACb;AAAA,+BAAC,QAAK,MAAY,WAAU,iBAC1B;AAAA,gCAAC,OAAE,WAAU,gFACV,gBACH;AAAA,YACC,YACC,oBAAC,OAAE,WAAU,2DACV,oBACH;AAAA,aAEJ;AAAA,UAEC,YAAY,CAAC,YACZ,oBAAC,SAAI,WAAU,mEACb;AAAA,YAAC;AAAA;AAAA,cACC,iBAAiB,MAAO;AAAA,cACxB,UAAU,MAAO;AAAA,cACjB,UAAU,MAAO;AAAA,cACjB,MAAK;AAAA;AAAA,UACP,GACF;AAAA,WAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,oBAAoB;AAClC,SACE,qBAAC,SAAI,WAAU,mFACb;AAAA,wBAAC,SAAI,WAAU,+CAA8C;AAAA,IAC7D,qBAAC,SAAI,WAAU,yBACb;AAAA,0BAAC,SAAI,WAAU,+CAA8C;AAAA,MAC7D,oBAAC,SAAI,WAAU,iDAAgD;AAAA,OACjE;AAAA,KACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/asset-card.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport { Loader2 } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { PriceChipContent } from \"./dual-price.js\";\nimport { IpTypeBadge } from \"./ip-type-badge.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nexport interface AssetCardPrice {\n formatted?: string | null;\n currency?: string | null;\n\n usdValue?: string | null;\n}\n\nexport interface AssetCardProps {\n\n href: string;\n\n name: string;\n\n image?: string | null;\n\n animationUrl?: string | null;\n\n live?: boolean;\n\n subtitle?: string | null;\n\n ipType?: string | null;\n\n price?: AssetCardPrice | null;\n\n fallbackId?: string | null;\n\n indexing?: boolean;\n\n ipTypeBaseUrl?: string;\n className?: string;\n}\n\nexport function AssetCard({\n href,\n name,\n image,\n animationUrl,\n live = false,\n subtitle,\n ipType,\n price,\n fallbackId,\n indexing = false,\n ipTypeBaseUrl = \"\",\n className,\n}: AssetCardProps) {\n const resolveImage = useImageUrl();\n const resolved = resolveImage(image, { width: 480 });\n const hasPrice = !!price?.formatted;\n\n return (\n <div\n className={cn(\n \"group relative flex flex-col w-full overflow-hidden rounded-xl bg-card\",\n className\n )}\n >\n\n {ipType && (\n <div className=\"absolute top-2 right-2 z-10\">\n <IpTypeBadge ipType={ipType} size=\"sm\" baseUrl={ipTypeBaseUrl} />\n </div>\n )}\n\n <Link href={href} className=\"block relative aspect-square bg-muted overflow-hidden\">\n <AnimatedTokenMedia\n image={resolved}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 22vw\"\n className=\"object-cover transition-transform duration-700 ease-out group-hover:scale-[1.03]\"\n fallback={\n <div className=\"absolute inset-0 flex items-center justify-center bg-gradient-to-br from-brand-blue/25 via-brand-purple/25 to-brand-rose/25\">\n <span className=\"text-sm font-semibold text-muted-foreground tabular-nums\">\n #{fallbackId ?? \"?\"}\n </span>\n </div>\n }\n />\n\n {indexing && (\n <div className=\"absolute bottom-0 inset-x-0 flex items-center justify-center gap-1.5 bg-black/50 backdrop-blur-sm py-1.5\">\n <Loader2 className=\"h-3 w-3 animate-spin text-white/70\" />\n <span className=\"text-2xs text-white/70\">Indexing…</span>\n </div>\n )}\n </Link>\n\n <div className=\"px-3 py-3 space-y-1\">\n <Link href={href} className=\"block min-w-0\">\n <p className=\"text-base font-semibold tracking-tight line-clamp-2 break-words leading-snug\">\n {name}\n </p>\n {subtitle && (\n <p className=\"text-xs text-muted-foreground line-clamp-1 leading-snug\">\n {subtitle}\n </p>\n )}\n </Link>\n\n {hasPrice && !indexing && (\n <div className=\"flex items-center gap-1.5 text-sm font-bold tabular-nums pt-0.5\">\n <PriceChipContent\n amountFormatted={price!.formatted}\n currency={price!.currency}\n usdValue={price!.usdValue}\n tone=\"solid\"\n />\n </div>\n )}\n </div>\n </div>\n );\n}\n\nexport function AssetCardSkeleton() {\n return (\n <div className=\"flex flex-col w-full overflow-hidden rounded-xl bg-card\">\n <div className=\"aspect-square w-full animate-pulse bg-muted\" />\n <div className=\"px-3 py-3 space-y-1.5\">\n <div className=\"h-4 w-3/4 rounded-md animate-pulse bg-muted\" />\n <div className=\"h-3.5 w-2/5 rounded-md animate-pulse bg-muted\" />\n </div>\n </div>\n );\n}\n"],"mappings":";AAuEU,cAeI,YAfJ;AArEV,OAAO,UAAU;AACjB,SAAS,eAAe;AACxB,SAAS,UAAU;AACnB,SAAS,wBAAwB;AACjC,SAAS,mBAAmB;AAC5B,SAAS,0BAA0B;AACnC,SAAS,mBAAmB;AAmCrB,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,gBAAgB;AAAA,EAChB;AACF,GAAmB;AACjB,QAAM,eAAe,YAAY;AACjC,QAAM,WAAW,aAAa,OAAO,EAAE,OAAO,IAAI,CAAC;AACnD,QAAM,WAAW,CAAC,CAAC,OAAO;AAE1B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MAGC;AAAA,kBACC,oBAAC,SAAI,WAAU,+BACb,8BAAC,eAAY,QAAgB,MAAK,MAAK,SAAS,eAAe,GACjE;AAAA,QAGF,qBAAC,QAAK,MAAY,WAAU,yDAC1B;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,cACP;AAAA,cACA;AAAA,cACA,KAAK;AAAA,cACL,MAAK;AAAA,cACL,OAAM;AAAA,cACN,WAAU;AAAA,cACV,UACE,oBAAC,SAAI,WAAU,+HACb,+BAAC,UAAK,WAAU,4DAA2D;AAAA;AAAA,gBACvE,cAAc;AAAA,iBAClB,GACF;AAAA;AAAA,UAEJ;AAAA,UAEC,YACC,qBAAC,SAAI,WAAU,4GACb;AAAA,gCAAC,WAAQ,WAAU,sCAAqC;AAAA,YACxD,oBAAC,UAAK,WAAU,0BAAyB,4BAAS;AAAA,aACpD;AAAA,WAEJ;AAAA,QAEA,qBAAC,SAAI,WAAU,uBACb;AAAA,+BAAC,QAAK,MAAY,WAAU,iBAC1B;AAAA,gCAAC,OAAE,WAAU,gFACV,gBACH;AAAA,YACC,YACC,oBAAC,OAAE,WAAU,2DACV,oBACH;AAAA,aAEJ;AAAA,UAEC,YAAY,CAAC,YACZ,oBAAC,SAAI,WAAU,mEACb;AAAA,YAAC;AAAA;AAAA,cACC,iBAAiB,MAAO;AAAA,cACxB,UAAU,MAAO;AAAA,cACjB,UAAU,MAAO;AAAA,cACjB,MAAK;AAAA;AAAA,UACP,GACF;AAAA,WAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,oBAAoB;AAClC,SACE,qBAAC,SAAI,WAAU,2DACb;AAAA,wBAAC,SAAI,WAAU,+CAA8C;AAAA,IAC7D,qBAAC,SAAI,WAAU,yBACb;AAAA,0BAAC,SAAI,WAAU,+CAA8C;AAAA,MAC7D,oBAAC,SAAI,WAAU,iDAAgD;AAAA,OACjE;AAAA,KACF;AAEJ;","names":[]}
@@ -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?: "default" | "link" | "destructive" | "outline" | "secondary" | "ghost" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
6
+ variant?: "link" | "default" | "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?: "default" | "link" | "destructive" | "outline" | "secondary" | "ghost" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
6
+ variant?: "link" | "default" | "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,50 +86,64 @@ 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: "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: [
89
+ const leadWithAsset = showAsset && !!name;
90
+ const assetLink = contract && tokenId ? (0, import_sdk.assetHref)(event.chain ?? "STARKNET", contract, tokenId) : null;
91
+ const actorLink = actor ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "text-sm font-normal text-muted-foreground", children: [
92
+ "by",
93
+ " ",
94
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
95
+ import_link.default,
96
+ {
97
+ href: (0, import_sdk.profileHref)({ address: actor }),
98
+ className: "font-medium text-foreground/80 hover:text-primary transition-colors",
99
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_address_display.AddressDisplay, { address: actor, chars: 6, showCopy: false, className: "text-sm" })
100
+ }
101
+ )
102
+ ] }) : null;
103
+ const tile = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
104
+ "span",
105
+ {
106
+ className: (0, import_cn.cn)(
107
+ "flex h-11 w-11 shrink-0 items-center justify-center rounded-xl",
108
+ config?.bgClass ?? "bg-muted"
109
+ ),
110
+ "aria-hidden": true,
111
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { className: (0, import_cn.cn)("h-5 w-5", config?.colorClass ?? "text-muted-foreground") })
112
+ }
113
+ );
114
+ const thumb = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "relative h-14 w-14 shrink-0", children: [
115
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "block h-full w-full overflow-hidden rounded-xl bg-gradient-to-br from-brand-blue/25 via-brand-purple/25 to-brand-rose/25", children: image ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_image.default, { src: image, alt: "", width: 56, height: 56, className: "h-full w-full object-cover", unoptimized: true }) : null }),
90
116
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
91
117
  "span",
92
118
  {
93
119
  className: (0, import_cn.cn)(
94
- "flex h-11 w-11 shrink-0 items-center justify-center rounded-xl",
95
- config?.bgClass ?? "bg-muted"
120
+ "absolute -bottom-1 -right-1 flex h-6 w-6 items-center justify-center rounded-full bg-card ring-2 ring-card"
96
121
  ),
97
122
  "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") })
123
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: (0, import_cn.cn)("flex h-full w-full items-center justify-center rounded-full", config?.bgClass ?? "bg-muted"), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { className: (0, import_cn.cn)("h-3 w-3", config?.colorClass ?? "text-muted-foreground") }) })
99
124
  }
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: [
125
+ )
126
+ ] });
127
+ 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: [
128
+ leadWithAsset ? assetLink ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_link.default, { href: assetLink, className: "shrink-0", children: thumb }) : thumb : tile,
129
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "min-w-0 flex-1", children: leadWithAsset ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
130
+ assetLink ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_link.default, { href: assetLink, className: "block truncate text-base font-semibold leading-tight hover:text-primary transition-colors", children: name }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "truncate text-base font-semibold leading-tight", children: name }),
131
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "mt-1 flex flex-wrap items-baseline gap-x-1.5 text-sm", children: [
132
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: (0, import_cn.cn)("font-medium", config?.colorClass), children: EVENT_TITLE[event.type] ?? event.type }),
133
+ amount ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "text-muted-foreground", children: [
105
134
  "\xD7",
106
135
  amount
107
136
  ] }) : 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
- ] }),
137
+ actorLink
138
+ ] })
139
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "flex flex-wrap items-baseline gap-x-1.5 text-base font-semibold leading-tight", children: [
140
+ EVENT_TITLE[event.type] ?? event.type,
141
+ amount ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "text-sm font-medium text-muted-foreground", children: [
142
+ "\xD7",
143
+ amount
144
+ ] }) : null,
145
+ actorLink
146
+ ] }) }),
133
147
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex shrink-0 flex-col items-end gap-1", children: [
134
148
  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
149
  event.price.currency ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_currency_icon.CurrencyIcon, { symbol: event.price.currency, size: 15, "aria-hidden": true }) : null,
@@ -154,7 +168,7 @@ function ProvenanceEvent({ event, showAsset }) {
154
168
  ] });
155
169
  }
156
170
  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: [
171
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid gap-2.5 lg:grid-cols-2", "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
172
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-11 w-11 shrink-0 rounded-xl bg-muted animate-pulse" }),
159
173
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex-1 space-y-2", children: [
160
174
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-4 w-44 rounded bg-muted animate-pulse" }),
@@ -188,7 +202,7 @@ function CollectionProvenanceTab({ contract }) {
188
202
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-8", children: [
189
203
  groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { children: [
190
204
  /* @__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)(
205
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { className: "grid gap-2.5 lg:grid-cols-2", children: group.events.map((event, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
192
206
  ProvenanceEvent,
193
207
  {
194
208
  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=\"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"]}
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 const leadWithAsset = showAsset && !!name;\n const assetLink = contract && tokenId ? assetHref(event.chain ?? \"STARKNET\", contract, tokenId) : null;\n\n const actorLink = 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\n const tile = (\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\n const thumb = (\n <span className=\"relative h-14 w-14 shrink-0\">\n <span className=\"block h-full w-full overflow-hidden rounded-xl bg-gradient-to-br from-brand-blue/25 via-brand-purple/25 to-brand-rose/25\">\n {image ? (\n <Image src={image} alt=\"\" width={56} height={56} className=\"h-full w-full object-cover\" unoptimized />\n ) : null}\n </span>\n <span\n className={cn(\n \"absolute -bottom-1 -right-1 flex h-6 w-6 items-center justify-center rounded-full bg-card ring-2 ring-card\"\n )}\n aria-hidden\n >\n <span className={cn(\"flex h-full w-full items-center justify-center rounded-full\", config?.bgClass ?? \"bg-muted\")}>\n <Icon className={cn(\"h-3 w-3\", config?.colorClass ?? \"text-muted-foreground\")} />\n </span>\n </span>\n </span>\n );\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 {leadWithAsset ? (assetLink ? <Link href={assetLink} className=\"shrink-0\">{thumb}</Link> : thumb) : tile}\n\n <div className=\"min-w-0 flex-1\">\n {leadWithAsset ? (\n <>\n {assetLink ? (\n <Link href={assetLink} className=\"block truncate text-base font-semibold leading-tight hover:text-primary transition-colors\">\n {name}\n </Link>\n ) : (\n <p className=\"truncate text-base font-semibold leading-tight\">{name}</p>\n )}\n <p className=\"mt-1 flex flex-wrap items-baseline gap-x-1.5 text-sm\">\n <span className={cn(\"font-medium\", config?.colorClass)}>{EVENT_TITLE[event.type] ?? event.type}</span>\n {amount ? <span className=\"text-muted-foreground\">×{amount}</span> : null}\n {actorLink}\n </p>\n </>\n ) : (\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 {actorLink}\n </p>\n )}\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=\"grid gap-2.5 lg:grid-cols-2\" 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=\"grid gap-2.5 lg:grid-cols-2\">\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,5 +1,5 @@
1
1
  "use client";
2
- import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useState, useEffect, useMemo } from "react";
4
4
  import { assetHref, profileHref } from "@medialane/sdk";
5
5
  import { ExternalLink, Inbox } from "lucide-react";
@@ -53,50 +53,64 @@ 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: "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: [
56
+ const leadWithAsset = showAsset && !!name;
57
+ const assetLink = contract && tokenId ? assetHref(event.chain ?? "STARKNET", contract, tokenId) : null;
58
+ const actorLink = actor ? /* @__PURE__ */ jsxs("span", { className: "text-sm font-normal text-muted-foreground", children: [
59
+ "by",
60
+ " ",
61
+ /* @__PURE__ */ jsx(
62
+ Link,
63
+ {
64
+ href: profileHref({ address: actor }),
65
+ className: "font-medium text-foreground/80 hover:text-primary transition-colors",
66
+ children: /* @__PURE__ */ jsx(AddressDisplay, { address: actor, chars: 6, showCopy: false, className: "text-sm" })
67
+ }
68
+ )
69
+ ] }) : null;
70
+ const tile = /* @__PURE__ */ jsx(
71
+ "span",
72
+ {
73
+ className: cn(
74
+ "flex h-11 w-11 shrink-0 items-center justify-center rounded-xl",
75
+ config?.bgClass ?? "bg-muted"
76
+ ),
77
+ "aria-hidden": true,
78
+ children: /* @__PURE__ */ jsx(Icon, { className: cn("h-5 w-5", config?.colorClass ?? "text-muted-foreground") })
79
+ }
80
+ );
81
+ const thumb = /* @__PURE__ */ jsxs("span", { className: "relative h-14 w-14 shrink-0", children: [
82
+ /* @__PURE__ */ jsx("span", { className: "block h-full w-full overflow-hidden rounded-xl bg-gradient-to-br from-brand-blue/25 via-brand-purple/25 to-brand-rose/25", children: image ? /* @__PURE__ */ jsx(Image, { src: image, alt: "", width: 56, height: 56, className: "h-full w-full object-cover", unoptimized: true }) : null }),
57
83
  /* @__PURE__ */ jsx(
58
84
  "span",
59
85
  {
60
86
  className: cn(
61
- "flex h-11 w-11 shrink-0 items-center justify-center rounded-xl",
62
- config?.bgClass ?? "bg-muted"
87
+ "absolute -bottom-1 -right-1 flex h-6 w-6 items-center justify-center rounded-full bg-card ring-2 ring-card"
63
88
  ),
64
89
  "aria-hidden": true,
65
- children: /* @__PURE__ */ jsx(Icon, { className: cn("h-5 w-5", config?.colorClass ?? "text-muted-foreground") })
90
+ children: /* @__PURE__ */ jsx("span", { className: cn("flex h-full w-full items-center justify-center rounded-full", config?.bgClass ?? "bg-muted"), children: /* @__PURE__ */ jsx(Icon, { className: cn("h-3 w-3", config?.colorClass ?? "text-muted-foreground") }) })
66
91
  }
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: [
92
+ )
93
+ ] });
94
+ 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: [
95
+ leadWithAsset ? assetLink ? /* @__PURE__ */ jsx(Link, { href: assetLink, className: "shrink-0", children: thumb }) : thumb : tile,
96
+ /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: leadWithAsset ? /* @__PURE__ */ jsxs(Fragment, { children: [
97
+ assetLink ? /* @__PURE__ */ jsx(Link, { href: assetLink, className: "block truncate text-base font-semibold leading-tight hover:text-primary transition-colors", children: name }) : /* @__PURE__ */ jsx("p", { className: "truncate text-base font-semibold leading-tight", children: name }),
98
+ /* @__PURE__ */ jsxs("p", { className: "mt-1 flex flex-wrap items-baseline gap-x-1.5 text-sm", children: [
99
+ /* @__PURE__ */ jsx("span", { className: cn("font-medium", config?.colorClass), children: EVENT_TITLE[event.type] ?? event.type }),
100
+ amount ? /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
72
101
  "\xD7",
73
102
  amount
74
103
  ] }) : 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
- ] }),
104
+ actorLink
105
+ ] })
106
+ ] }) : /* @__PURE__ */ jsxs("p", { className: "flex flex-wrap items-baseline gap-x-1.5 text-base font-semibold leading-tight", children: [
107
+ EVENT_TITLE[event.type] ?? event.type,
108
+ amount ? /* @__PURE__ */ jsxs("span", { className: "text-sm font-medium text-muted-foreground", children: [
109
+ "\xD7",
110
+ amount
111
+ ] }) : null,
112
+ actorLink
113
+ ] }) }),
100
114
  /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 flex-col items-end gap-1", children: [
101
115
  event.price?.formatted ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5 text-base font-bold tabular-nums", children: [
102
116
  event.price.currency ? /* @__PURE__ */ jsx(CurrencyIcon, { symbol: event.price.currency, size: 15, "aria-hidden": true }) : null,
@@ -121,7 +135,7 @@ function ProvenanceEvent({ event, showAsset }) {
121
135
  ] });
122
136
  }
123
137
  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: [
138
+ return /* @__PURE__ */ jsx("div", { className: "grid gap-2.5 lg:grid-cols-2", "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
139
  /* @__PURE__ */ jsx("div", { className: "h-11 w-11 shrink-0 rounded-xl bg-muted animate-pulse" }),
126
140
  /* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-2", children: [
127
141
  /* @__PURE__ */ jsx("div", { className: "h-4 w-44 rounded bg-muted animate-pulse" }),
@@ -155,7 +169,7 @@ function CollectionProvenanceTab({ contract }) {
155
169
  return /* @__PURE__ */ jsxs("div", { className: "space-y-8", children: [
156
170
  groups.map((group) => /* @__PURE__ */ jsxs("section", { children: [
157
171
  /* @__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(
172
+ /* @__PURE__ */ jsx("ol", { className: "grid gap-2.5 lg:grid-cols-2", children: group.events.map((event, i) => /* @__PURE__ */ jsx(
159
173
  ProvenanceEvent,
160
174
  {
161
175
  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=\"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
+ {"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 const leadWithAsset = showAsset && !!name;\n const assetLink = contract && tokenId ? assetHref(event.chain ?? \"STARKNET\", contract, tokenId) : null;\n\n const actorLink = 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\n const tile = (\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\n const thumb = (\n <span className=\"relative h-14 w-14 shrink-0\">\n <span className=\"block h-full w-full overflow-hidden rounded-xl bg-gradient-to-br from-brand-blue/25 via-brand-purple/25 to-brand-rose/25\">\n {image ? (\n <Image src={image} alt=\"\" width={56} height={56} className=\"h-full w-full object-cover\" unoptimized />\n ) : null}\n </span>\n <span\n className={cn(\n \"absolute -bottom-1 -right-1 flex h-6 w-6 items-center justify-center rounded-full bg-card ring-2 ring-card\"\n )}\n aria-hidden\n >\n <span className={cn(\"flex h-full w-full items-center justify-center rounded-full\", config?.bgClass ?? \"bg-muted\")}>\n <Icon className={cn(\"h-3 w-3\", config?.colorClass ?? \"text-muted-foreground\")} />\n </span>\n </span>\n </span>\n );\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 {leadWithAsset ? (assetLink ? <Link href={assetLink} className=\"shrink-0\">{thumb}</Link> : thumb) : tile}\n\n <div className=\"min-w-0 flex-1\">\n {leadWithAsset ? (\n <>\n {assetLink ? (\n <Link href={assetLink} className=\"block truncate text-base font-semibold leading-tight hover:text-primary transition-colors\">\n {name}\n </Link>\n ) : (\n <p className=\"truncate text-base font-semibold leading-tight\">{name}</p>\n )}\n <p className=\"mt-1 flex flex-wrap items-baseline gap-x-1.5 text-sm\">\n <span className={cn(\"font-medium\", config?.colorClass)}>{EVENT_TITLE[event.type] ?? event.type}</span>\n {amount ? <span className=\"text-muted-foreground\">×{amount}</span> : null}\n {actorLink}\n </p>\n </>\n ) : (\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 {actorLink}\n </p>\n )}\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=\"grid gap-2.5 lg:grid-cols-2\" 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=\"grid gap-2.5 lg:grid-cols-2\">\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 from 'react';
2
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
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 | 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;
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> | react_jsx_runtime.JSX.Element | null | undefined;
9
9
 
10
10
  export { FastMint };
@@ -1,10 +1,10 @@
1
- import * as React from 'react';
2
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
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 | 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;
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> | react_jsx_runtime.JSX.Element | null | undefined;
9
9
 
10
10
  export { FastMint };
@@ -24,11 +24,11 @@ __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-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" },
27
+ mint: { label: "Mint", variant: "default", icon: import_lucide_react.Sparkles, colorClass: "text-brand-purple", bgClass: "bg-brand-purple/15 dark:bg-brand-purple/25" },
28
+ transfer: { label: "Transfer", variant: "secondary", icon: import_lucide_react.ArrowRightLeft, colorClass: "text-brand-blue", bgClass: "bg-brand-blue/15 dark:bg-brand-blue/25" },
29
+ listing: { label: "Listed", variant: "default", icon: import_lucide_react.Tag, colorClass: "text-brand-orange", bgClass: "bg-brand-orange/15 dark:bg-brand-orange/25" },
30
+ sale: { label: "Sale", variant: "default", icon: import_lucide_react.ShoppingCart, colorClass: "text-brand-rose", bgClass: "bg-brand-rose/15 dark:bg-brand-rose/25" },
31
+ offer: { label: "Offer", variant: "outline", icon: import_lucide_react.HandCoins, colorClass: "text-brand-maeve", bgClass: "bg-brand-maeve/15 dark:bg-brand-maeve/25" },
32
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 = [
@@ -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-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":[]}
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/15 dark:bg-brand-purple/25\" },\n transfer: { label: \"Transfer\", variant: \"secondary\", icon: ArrowRightLeft, colorClass: \"text-brand-blue\", bgClass: \"bg-brand-blue/15 dark:bg-brand-blue/25\" },\n listing: { label: \"Listed\", variant: \"default\", icon: Tag, colorClass: \"text-brand-orange\", bgClass: \"bg-brand-orange/15 dark:bg-brand-orange/25\" },\n sale: { label: \"Sale\", variant: \"default\", icon: ShoppingCart, colorClass: \"text-brand-rose\", bgClass: \"bg-brand-rose/15 dark:bg-brand-rose/25\" },\n offer: { label: \"Offer\", variant: \"outline\", icon: HandCoins, colorClass: \"text-brand-maeve\", bgClass: \"bg-brand-maeve/15 dark:bg-brand-maeve/25\" },\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,6CAA6C;AAAA,EACpK,UAAW,EAAE,OAAO,YAAa,SAAS,aAAa,MAAM,oCAAgB,YAAY,mBAAqB,SAAS,yCAAyC;AAAA,EAChK,SAAW,EAAE,OAAO,UAAa,SAAS,WAAa,MAAM,yBAAgB,YAAY,qBAAqB,SAAS,6CAA6C;AAAA,EACpK,MAAW,EAAE,OAAO,QAAa,SAAS,WAAa,MAAM,kCAAgB,YAAY,mBAAqB,SAAS,yCAAyC;AAAA,EAChK,OAAW,EAAE,OAAO,SAAa,SAAS,WAAa,MAAM,+BAAgB,YAAY,oBAAqB,SAAS,2CAA2C;AAAA,EAClK,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":[]}
@@ -1,10 +1,10 @@
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-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" },
3
+ mint: { label: "Mint", variant: "default", icon: Sparkles, colorClass: "text-brand-purple", bgClass: "bg-brand-purple/15 dark:bg-brand-purple/25" },
4
+ transfer: { label: "Transfer", variant: "secondary", icon: ArrowRightLeft, colorClass: "text-brand-blue", bgClass: "bg-brand-blue/15 dark:bg-brand-blue/25" },
5
+ listing: { label: "Listed", variant: "default", icon: Tag, colorClass: "text-brand-orange", bgClass: "bg-brand-orange/15 dark:bg-brand-orange/25" },
6
+ sale: { label: "Sale", variant: "default", icon: ShoppingCart, colorClass: "text-brand-rose", bgClass: "bg-brand-rose/15 dark:bg-brand-rose/25" },
7
+ offer: { label: "Offer", variant: "outline", icon: HandCoins, colorClass: "text-brand-maeve", bgClass: "bg-brand-maeve/15 dark:bg-brand-maeve/25" },
8
8
  cancelled: { label: "Cancelled", variant: "outline", icon: X, colorClass: "text-muted-foreground", bgClass: "bg-muted" }
9
9
  };
10
10
  const TYPE_FILTERS = [
@@ -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-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":[]}
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/15 dark:bg-brand-purple/25\" },\n transfer: { label: \"Transfer\", variant: \"secondary\", icon: ArrowRightLeft, colorClass: \"text-brand-blue\", bgClass: \"bg-brand-blue/15 dark:bg-brand-blue/25\" },\n listing: { label: \"Listed\", variant: \"default\", icon: Tag, colorClass: \"text-brand-orange\", bgClass: \"bg-brand-orange/15 dark:bg-brand-orange/25\" },\n sale: { label: \"Sale\", variant: \"default\", icon: ShoppingCart, colorClass: \"text-brand-rose\", bgClass: \"bg-brand-rose/15 dark:bg-brand-rose/25\" },\n offer: { label: \"Offer\", variant: \"outline\", icon: HandCoins, colorClass: \"text-brand-maeve\", bgClass: \"bg-brand-maeve/15 dark:bg-brand-maeve/25\" },\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,6CAA6C;AAAA,EACpK,UAAW,EAAE,OAAO,YAAa,SAAS,aAAa,MAAM,gBAAgB,YAAY,mBAAqB,SAAS,yCAAyC;AAAA,EAChK,SAAW,EAAE,OAAO,UAAa,SAAS,WAAa,MAAM,KAAgB,YAAY,qBAAqB,SAAS,6CAA6C;AAAA,EACpK,MAAW,EAAE,OAAO,QAAa,SAAS,WAAa,MAAM,cAAgB,YAAY,mBAAqB,SAAS,yCAAyC;AAAA,EAChK,OAAW,EAAE,OAAO,SAAa,SAAS,WAAa,MAAM,WAAgB,YAAY,oBAAqB,SAAS,2CAA2C;AAAA,EAClK,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: 8 | 6 | 18;
10
+ decimals: 6 | 8 | 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: 8 | 6 | 18;
10
+ decimals: 6 | 8 | 18;
11
11
  };
12
12
  declare function hasSufficientBalance(rawBalance: bigint | null, requiredHuman: string, decimals: number): boolean | null;
13
13
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@medialane/ui",
3
- "version": "0.302.0",
3
+ "version": "0.303.0",
4
4
  "description": "Shared UI components for Medialane apps",
5
5
  "type": "module",
6
6
  "sideEffects": false,