@medialane/ui 0.252.0 → 0.254.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.
Files changed (39) hide show
  1. package/dist/components/account/input-otp.d.cts +2 -2
  2. package/dist/components/account/input-otp.d.ts +2 -2
  3. package/dist/components/button.d.cts +2 -2
  4. package/dist/components/button.d.ts +2 -2
  5. package/dist/components/collection-card.cjs +11 -19
  6. package/dist/components/collection-card.cjs.map +1 -1
  7. package/dist/components/collection-card.js +11 -19
  8. package/dist/components/collection-card.js.map +1 -1
  9. package/dist/components/collections-page.cjs +181 -139
  10. package/dist/components/collections-page.cjs.map +1 -1
  11. package/dist/components/collections-page.js +172 -140
  12. package/dist/components/collections-page.js.map +1 -1
  13. package/dist/components/creator-page.cjs +1 -1
  14. package/dist/components/creator-page.cjs.map +1 -1
  15. package/dist/components/creator-page.js +1 -1
  16. package/dist/components/creator-page.js.map +1 -1
  17. package/dist/components/drop/create/drop-create.cjs +1 -1
  18. package/dist/components/drop/create/drop-create.cjs.map +1 -1
  19. package/dist/components/drop/create/drop-create.js +1 -1
  20. package/dist/components/drop/create/drop-create.js.map +1 -1
  21. package/dist/components/drop/create/launch-dialog.cjs +1 -1
  22. package/dist/components/drop/create/launch-dialog.cjs.map +1 -1
  23. package/dist/components/drop/create/launch-dialog.js +1 -1
  24. package/dist/components/drop/create/launch-dialog.js.map +1 -1
  25. package/dist/components/fast-mint/fast-mint.d.cts +2 -2
  26. package/dist/components/fast-mint/fast-mint.d.ts +2 -2
  27. package/dist/components/hero-slider.cjs +2 -1
  28. package/dist/components/hero-slider.cjs.map +1 -1
  29. package/dist/components/hero-slider.js +2 -1
  30. package/dist/components/hero-slider.js.map +1 -1
  31. package/dist/components/launchpad/edition-mint-schema.d.cts +2 -2
  32. package/dist/components/launchpad/edition-mint-schema.d.ts +2 -2
  33. package/dist/components/sheet.d.cts +1 -1
  34. package/dist/components/sheet.d.ts +1 -1
  35. package/dist/utils/use-collections.cjs +1 -2
  36. package/dist/utils/use-collections.cjs.map +1 -1
  37. package/dist/utils/use-collections.js +1 -2
  38. package/dist/utils/use-collections.js.map +1 -1
  39. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  import * as input_otp from 'input-otp';
2
2
  import * as React from 'react';
3
3
 
4
- declare const InputOTP: React.ForwardRefExoticComponent<(Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "onChange" | "value" | "maxLength" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
4
+ declare const InputOTP: React.ForwardRefExoticComponent<(Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "value" | "onChange" | "maxLength" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
5
5
  value?: string;
6
6
  onChange?: (newValue: string) => unknown;
7
7
  maxLength: number;
@@ -14,7 +14,7 @@ declare const InputOTP: React.ForwardRefExoticComponent<(Omit<Omit<React.InputHT
14
14
  } & {
15
15
  render: (props: input_otp.RenderProps) => React.ReactNode;
16
16
  children?: never;
17
- } & React.RefAttributes<HTMLInputElement>, "ref"> | Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "onChange" | "value" | "maxLength" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
17
+ } & React.RefAttributes<HTMLInputElement>, "ref"> | Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "value" | "onChange" | "maxLength" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
18
18
  value?: string;
19
19
  onChange?: (newValue: string) => unknown;
20
20
  maxLength: number;
@@ -1,7 +1,7 @@
1
1
  import * as input_otp from 'input-otp';
2
2
  import * as React from 'react';
3
3
 
4
- declare const InputOTP: React.ForwardRefExoticComponent<(Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "onChange" | "value" | "maxLength" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
4
+ declare const InputOTP: React.ForwardRefExoticComponent<(Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "value" | "onChange" | "maxLength" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
5
5
  value?: string;
6
6
  onChange?: (newValue: string) => unknown;
7
7
  maxLength: number;
@@ -14,7 +14,7 @@ declare const InputOTP: React.ForwardRefExoticComponent<(Omit<Omit<React.InputHT
14
14
  } & {
15
15
  render: (props: input_otp.RenderProps) => React.ReactNode;
16
16
  children?: never;
17
- } & React.RefAttributes<HTMLInputElement>, "ref"> | Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "onChange" | "value" | "maxLength" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
17
+ } & React.RefAttributes<HTMLInputElement>, "ref"> | Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "value" | "onChange" | "maxLength" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
18
18
  value?: string;
19
19
  onChange?: (newValue: string) => unknown;
20
20
  maxLength: number;
@@ -3,8 +3,8 @@ 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;
7
- size?: "default" | "icon" | "sm" | "lg" | null | undefined;
6
+ variant?: "ghost" | "link" | "default" | "destructive" | "outline" | "secondary" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
7
+ size?: "icon" | "default" | "sm" | "lg" | null | undefined;
8
8
  } & class_variance_authority_types.ClassProp) | undefined) => string;
9
9
  interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
10
10
  asChild?: boolean;
@@ -3,8 +3,8 @@ 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;
7
- size?: "default" | "icon" | "sm" | "lg" | null | undefined;
6
+ variant?: "ghost" | "link" | "default" | "destructive" | "outline" | "secondary" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
7
+ size?: "icon" | "default" | "sm" | "lg" | null | undefined;
8
8
  } & class_variance_authority_types.ClassProp) | undefined) => string;
9
9
  interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
10
10
  asChild?: boolean;
@@ -59,8 +59,7 @@ function CollectionCard({ collection, href, settingsHref, className }) {
59
59
  const showImage = imageUrl && !imgError;
60
60
  const initial = (collection.name ?? collection.contractAddress).charAt(0).toUpperCase();
61
61
  const floor = parseFloorPrice(collection.floorPrice);
62
- const hasExclusiveContent = !!collection.profile?.hasGatedContent;
63
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: (0, import_cn.cn)(hasExclusiveContent && "card-exclusive-wrapper btn-border-animated"), children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_motion_primitives.MotionCard, { className: (0, import_cn.cn)("card-base group relative", className), children: [
62
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_motion_primitives.MotionCard, { className: (0, import_cn.cn)("card-base group relative", className), children: [
64
63
  settingsHref && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
65
64
  import_link.default,
66
65
  {
@@ -83,33 +82,26 @@ function CollectionCard({ collection, href, settingsHref, className }) {
83
82
  unoptimized: true
84
83
  }
85
84
  ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute inset-0 bg-gradient-to-br from-brand-purple/30 via-brand-blue/20 to-brand-navy/40 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-8xl font-black text-white/10 select-none tracking-tighter", children: initial }) }),
86
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "absolute bottom-0 left-0 right-0 px-3 pb-3 flex flex-col gap-1.5 items-start", children: [
87
- !collection.name && collection.metadataStatus === "PENDING" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "flex items-center gap-1 text-2xs text-white/60 backdrop-blur-md bg-black/30 rounded-full px-2 py-0.5", children: [
85
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "absolute inset-x-0 bottom-0 flex flex-col items-start gap-1 bg-gradient-to-t from-black/85 via-black/45 to-transparent px-3 pb-3 pt-14", children: [
86
+ !collection.name && collection.metadataStatus === "PENDING" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "flex items-center gap-1 text-2xs text-white/70", children: [
88
87
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Loader2, { className: "h-2.5 w-2.5 animate-spin" }),
89
88
  "Indexing\u2026"
90
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
91
- "p",
92
- {
93
- className: "font-bold text-sm text-white leading-tight backdrop-blur-md bg-black/30 rounded-lg px-2.5 py-1 max-w-full truncate",
94
- style: { textShadow: "0 1px 6px rgba(0,0,0,0.5)" },
95
- children: collection.name ?? "Unnamed Collection"
96
- }
97
- ),
98
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-1.5 flex-wrap", children: [
99
- collection.totalSupply != null && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "text-2xs font-medium text-white/80 backdrop-blur-md bg-black/30 rounded-full px-2 py-0.5", children: [
89
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "max-w-full truncate text-sm font-bold leading-tight text-white", children: collection.name ?? "Unnamed Collection" }),
90
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-wrap items-center gap-x-2.5 gap-y-0.5 text-2xs font-medium text-white/80", children: [
91
+ collection.totalSupply != null && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
100
92
  collection.totalSupply.toLocaleString(),
101
- " items"
93
+ " ",
94
+ collection.totalSupply === 1 ? "item" : "items"
102
95
  ] }),
103
- floor && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "inline-flex items-center gap-1 text-2xs font-bold text-white/90 backdrop-blur-md bg-black/30 rounded-full px-2 py-0.5", children: [
96
+ floor && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "inline-flex items-center gap-1 font-bold text-white/90", children: [
104
97
  "Floor",
105
98
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_currency_icon.CurrencyIcon, { symbol: floor.symbol, size: 10 }),
106
99
  floor.amount
107
- ] }),
108
- hasExclusiveContent && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "inline-flex items-center gap-1 text-2xs font-bold text-white backdrop-blur-md bg-black/50 rounded-full px-2 py-0.5", children: "\u2726 Exclusive" })
100
+ ] })
109
101
  ] })
110
102
  ] })
111
103
  ] }) })
112
- ] }) });
104
+ ] });
113
105
  }
114
106
  function CollectionCardSkeleton() {
115
107
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "card-base overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative aspect-square w-full overflow-hidden bg-muted", children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/collection-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"./link.js\";\nimport Image from \"./image.js\";\nimport { Loader2, Settings2 } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { MotionCard } from \"./motion-primitives.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport type { ApiCollection } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nfunction parseFloorPrice(floor: string | null | undefined): { amount: string; symbol: string } | null {\n if (!floor) return null;\n const formatted = formatDisplayPrice(floor);\n const parts = formatted.trim().split(/\\s+/);\n if (parts.length < 2) return null;\n const symbol = parts[parts.length - 1];\n const amount = parts.slice(0, -1).join(\" \");\n return { amount, symbol };\n}\n\ntype CollectionWithProfile = ApiCollection & {\n profile?: { hasGatedContent?: boolean } | null;\n};\n\nexport interface CollectionCardProps {\n collection: ApiCollection;\n\n href?: string;\n\n settingsHref?: string;\n className?: string;\n}\n\nexport function CollectionCard({ collection, href, settingsHref, className }: CollectionCardProps) {\n const resolveImage = useImageUrl();\n const [imgError, setImgError] = useState(false);\n const imageUrl = resolveImage(collection.image, { width: 480 });\n const showImage = imageUrl && !imgError;\n const initial = (collection.name ?? collection.contractAddress).charAt(0).toUpperCase();\n const floor = parseFloorPrice(collection.floorPrice);\n const hasExclusiveContent = !!(collection as CollectionWithProfile).profile?.hasGatedContent;\n\n return (\n <div className={cn(hasExclusiveContent && \"card-exclusive-wrapper btn-border-animated\")}>\n <MotionCard className={cn(\"card-base group relative\", className)}>\n {settingsHref && (\n <Link\n href={settingsHref}\n onClick={(e) => e.stopPropagation()}\n className=\"absolute top-2 right-2 z-10 min-h-11 min-w-11 rounded-full flex items-center justify-center\"\n aria-label=\"Collection settings\"\n >\n <span className=\"flex h-7 w-7 items-center justify-center rounded-full bg-black/40 backdrop-blur-sm text-white/70 hover:text-white hover:bg-black/60 transition-colors\">\n <Settings2 className=\"h-3.5 w-3.5\" />\n </span>\n </Link>\n )}\n\n <Link href={href ?? `/collections/${collection.contractAddress}`} className=\"block relative h-full\">\n <div className=\"relative aspect-square w-full overflow-hidden bg-muted\">\n {showImage ? (\n <Image\n src={imageUrl}\n alt={collection.name ?? \"Collection\"}\n fill\n className=\"object-cover transition-transform duration-500 group-hover:scale-105\"\n onError={() => setImgError(true)}\n unoptimized\n />\n ) : (\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/30 via-brand-blue/20 to-brand-navy/40 flex items-center justify-center\">\n <span className=\"text-8xl font-black text-white/10 select-none tracking-tighter\">\n {initial}\n </span>\n </div>\n )}\n\n <div className=\"absolute bottom-0 left-0 right-0 px-3 pb-3 flex flex-col gap-1.5 items-start\">\n {!collection.name && collection.metadataStatus === \"PENDING\" ? (\n <span className=\"flex items-center gap-1 text-2xs text-white/60 backdrop-blur-md bg-black/30 rounded-full px-2 py-0.5\">\n <Loader2 className=\"h-2.5 w-2.5 animate-spin\" />\n Indexing…\n </span>\n ) : (\n <p\n className=\"font-bold text-sm text-white leading-tight backdrop-blur-md bg-black/30 rounded-lg px-2.5 py-1 max-w-full truncate\"\n style={{ textShadow: \"0 1px 6px rgba(0,0,0,0.5)\" }}\n >\n {collection.name ?? \"Unnamed Collection\"}\n </p>\n )}\n\n <div className=\"flex items-center gap-1.5 flex-wrap\">\n {collection.totalSupply != null && (\n <span className=\"text-2xs font-medium text-white/80 backdrop-blur-md bg-black/30 rounded-full px-2 py-0.5\">\n {collection.totalSupply.toLocaleString()} items\n </span>\n )}\n {floor && (\n <span className=\"inline-flex items-center gap-1 text-2xs font-bold text-white/90 backdrop-blur-md bg-black/30 rounded-full px-2 py-0.5\">\n Floor\n <CurrencyIcon symbol={floor.symbol} size={10} />\n {floor.amount}\n </span>\n )}\n {hasExclusiveContent && (\n <span className=\"inline-flex items-center gap-1 text-2xs font-bold text-white backdrop-blur-md bg-black/50 rounded-full px-2 py-0.5\">\n ✦ Exclusive\n </span>\n )}\n </div>\n </div>\n </div>\n </Link>\n </MotionCard>\n </div>\n );\n}\n\nexport function CollectionCardSkeleton() {\n return (\n <div className=\"card-base overflow-hidden\">\n <div className=\"relative aspect-square w-full overflow-hidden bg-muted\">\n <div className=\"absolute inset-0 animate-pulse bg-muted\" />\n <div className=\"absolute bottom-3 left-3 right-3 space-y-1.5\">\n <div className=\"h-4 w-2/3 rounded-md bg-muted-foreground/20 animate-pulse\" />\n <div className=\"h-3 w-1/3 rounded-md bg-muted-foreground/20 animate-pulse\" />\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["Link","Image"]}
1
+ {"version":3,"sources":["../../src/components/collection-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"./link.js\";\nimport Image from \"./image.js\";\nimport { Loader2, Settings2 } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { MotionCard } from \"./motion-primitives.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport type { ApiCollection } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nfunction parseFloorPrice(floor: string | null | undefined): { amount: string; symbol: string } | null {\n if (!floor) return null;\n const formatted = formatDisplayPrice(floor);\n const parts = formatted.trim().split(/\\s+/);\n if (parts.length < 2) return null;\n const symbol = parts[parts.length - 1];\n const amount = parts.slice(0, -1).join(\" \");\n return { amount, symbol };\n}\n\nexport interface CollectionCardProps {\n collection: ApiCollection;\n\n href?: string;\n\n settingsHref?: string;\n className?: string;\n}\n\nexport function CollectionCard({ collection, href, settingsHref, className }: CollectionCardProps) {\n const resolveImage = useImageUrl();\n const [imgError, setImgError] = useState(false);\n const imageUrl = resolveImage(collection.image, { width: 480 });\n const showImage = imageUrl && !imgError;\n const initial = (collection.name ?? collection.contractAddress).charAt(0).toUpperCase();\n const floor = parseFloorPrice(collection.floorPrice);\n\n return (\n <MotionCard className={cn(\"card-base group relative\", className)}>\n {settingsHref && (\n <Link\n href={settingsHref}\n onClick={(e) => e.stopPropagation()}\n className=\"absolute top-2 right-2 z-10 min-h-11 min-w-11 rounded-full flex items-center justify-center\"\n aria-label=\"Collection settings\"\n >\n <span className=\"flex h-7 w-7 items-center justify-center rounded-full bg-black/40 backdrop-blur-sm text-white/70 hover:text-white hover:bg-black/60 transition-colors\">\n <Settings2 className=\"h-3.5 w-3.5\" />\n </span>\n </Link>\n )}\n\n <Link href={href ?? `/collections/${collection.contractAddress}`} className=\"block relative h-full\">\n <div className=\"relative aspect-square w-full overflow-hidden bg-muted\">\n {showImage ? (\n <Image\n src={imageUrl}\n alt={collection.name ?? \"Collection\"}\n fill\n className=\"object-cover transition-transform duration-500 group-hover:scale-105\"\n onError={() => setImgError(true)}\n unoptimized\n />\n ) : (\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/30 via-brand-blue/20 to-brand-navy/40 flex items-center justify-center\">\n <span className=\"text-8xl font-black text-white/10 select-none tracking-tighter\">\n {initial}\n </span>\n </div>\n )}\n\n <div className=\"absolute inset-x-0 bottom-0 flex flex-col items-start gap-1 bg-gradient-to-t from-black/85 via-black/45 to-transparent px-3 pb-3 pt-14\">\n {!collection.name && collection.metadataStatus === \"PENDING\" ? (\n <span className=\"flex items-center gap-1 text-2xs text-white/70\">\n <Loader2 className=\"h-2.5 w-2.5 animate-spin\" />\n Indexing…\n </span>\n ) : (\n <p className=\"max-w-full truncate text-sm font-bold leading-tight text-white\">\n {collection.name ?? \"Unnamed Collection\"}\n </p>\n )}\n\n <div className=\"flex flex-wrap items-center gap-x-2.5 gap-y-0.5 text-2xs font-medium text-white/80\">\n {collection.totalSupply != null && (\n <span>\n {collection.totalSupply.toLocaleString()} {collection.totalSupply === 1 ? \"item\" : \"items\"}\n </span>\n )}\n {floor && (\n <span className=\"inline-flex items-center gap-1 font-bold text-white/90\">\n Floor\n <CurrencyIcon symbol={floor.symbol} size={10} />\n {floor.amount}\n </span>\n )}\n </div>\n </div>\n </div>\n </Link>\n </MotionCard>\n );\n}\n\nexport function CollectionCardSkeleton() {\n return (\n <div className=\"card-base overflow-hidden\">\n <div className=\"relative aspect-square w-full overflow-hidden bg-muted\">\n <div className=\"absolute inset-0 animate-pulse bg-muted\" />\n <div className=\"absolute bottom-3 left-3 right-3 space-y-1.5\">\n <div className=\"h-4 w-2/3 rounded-md bg-muted-foreground/20 animate-pulse\" />\n <div className=\"h-3 w-1/3 rounded-md bg-muted-foreground/20 animate-pulse\" />\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["Link","Image"]}
@@ -25,8 +25,7 @@ function CollectionCard({ collection, href, settingsHref, className }) {
25
25
  const showImage = imageUrl && !imgError;
26
26
  const initial = (collection.name ?? collection.contractAddress).charAt(0).toUpperCase();
27
27
  const floor = parseFloorPrice(collection.floorPrice);
28
- const hasExclusiveContent = !!collection.profile?.hasGatedContent;
29
- return /* @__PURE__ */ jsx("div", { className: cn(hasExclusiveContent && "card-exclusive-wrapper btn-border-animated"), children: /* @__PURE__ */ jsxs(MotionCard, { className: cn("card-base group relative", className), children: [
28
+ return /* @__PURE__ */ jsxs(MotionCard, { className: cn("card-base group relative", className), children: [
30
29
  settingsHref && /* @__PURE__ */ jsx(
31
30
  Link,
32
31
  {
@@ -49,33 +48,26 @@ function CollectionCard({ collection, href, settingsHref, className }) {
49
48
  unoptimized: true
50
49
  }
51
50
  ) : /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-br from-brand-purple/30 via-brand-blue/20 to-brand-navy/40 flex items-center justify-center", children: /* @__PURE__ */ jsx("span", { className: "text-8xl font-black text-white/10 select-none tracking-tighter", children: initial }) }),
52
- /* @__PURE__ */ jsxs("div", { className: "absolute bottom-0 left-0 right-0 px-3 pb-3 flex flex-col gap-1.5 items-start", children: [
53
- !collection.name && collection.metadataStatus === "PENDING" ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-2xs text-white/60 backdrop-blur-md bg-black/30 rounded-full px-2 py-0.5", children: [
51
+ /* @__PURE__ */ jsxs("div", { className: "absolute inset-x-0 bottom-0 flex flex-col items-start gap-1 bg-gradient-to-t from-black/85 via-black/45 to-transparent px-3 pb-3 pt-14", children: [
52
+ !collection.name && collection.metadataStatus === "PENDING" ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-2xs text-white/70", children: [
54
53
  /* @__PURE__ */ jsx(Loader2, { className: "h-2.5 w-2.5 animate-spin" }),
55
54
  "Indexing\u2026"
56
- ] }) : /* @__PURE__ */ jsx(
57
- "p",
58
- {
59
- className: "font-bold text-sm text-white leading-tight backdrop-blur-md bg-black/30 rounded-lg px-2.5 py-1 max-w-full truncate",
60
- style: { textShadow: "0 1px 6px rgba(0,0,0,0.5)" },
61
- children: collection.name ?? "Unnamed Collection"
62
- }
63
- ),
64
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 flex-wrap", children: [
65
- collection.totalSupply != null && /* @__PURE__ */ jsxs("span", { className: "text-2xs font-medium text-white/80 backdrop-blur-md bg-black/30 rounded-full px-2 py-0.5", children: [
55
+ ] }) : /* @__PURE__ */ jsx("p", { className: "max-w-full truncate text-sm font-bold leading-tight text-white", children: collection.name ?? "Unnamed Collection" }),
56
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-x-2.5 gap-y-0.5 text-2xs font-medium text-white/80", children: [
57
+ collection.totalSupply != null && /* @__PURE__ */ jsxs("span", { children: [
66
58
  collection.totalSupply.toLocaleString(),
67
- " items"
59
+ " ",
60
+ collection.totalSupply === 1 ? "item" : "items"
68
61
  ] }),
69
- floor && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-2xs font-bold text-white/90 backdrop-blur-md bg-black/30 rounded-full px-2 py-0.5", children: [
62
+ floor && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 font-bold text-white/90", children: [
70
63
  "Floor",
71
64
  /* @__PURE__ */ jsx(CurrencyIcon, { symbol: floor.symbol, size: 10 }),
72
65
  floor.amount
73
- ] }),
74
- hasExclusiveContent && /* @__PURE__ */ jsx("span", { className: "inline-flex items-center gap-1 text-2xs font-bold text-white backdrop-blur-md bg-black/50 rounded-full px-2 py-0.5", children: "\u2726 Exclusive" })
66
+ ] })
75
67
  ] })
76
68
  ] })
77
69
  ] }) })
78
- ] }) });
70
+ ] });
79
71
  }
80
72
  function CollectionCardSkeleton() {
81
73
  return /* @__PURE__ */ jsx("div", { className: "card-base overflow-hidden", children: /* @__PURE__ */ jsxs("div", { className: "relative aspect-square w-full overflow-hidden bg-muted", children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/collection-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"./link.js\";\nimport Image from \"./image.js\";\nimport { Loader2, Settings2 } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { MotionCard } from \"./motion-primitives.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport type { ApiCollection } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nfunction parseFloorPrice(floor: string | null | undefined): { amount: string; symbol: string } | null {\n if (!floor) return null;\n const formatted = formatDisplayPrice(floor);\n const parts = formatted.trim().split(/\\s+/);\n if (parts.length < 2) return null;\n const symbol = parts[parts.length - 1];\n const amount = parts.slice(0, -1).join(\" \");\n return { amount, symbol };\n}\n\ntype CollectionWithProfile = ApiCollection & {\n profile?: { hasGatedContent?: boolean } | null;\n};\n\nexport interface CollectionCardProps {\n collection: ApiCollection;\n\n href?: string;\n\n settingsHref?: string;\n className?: string;\n}\n\nexport function CollectionCard({ collection, href, settingsHref, className }: CollectionCardProps) {\n const resolveImage = useImageUrl();\n const [imgError, setImgError] = useState(false);\n const imageUrl = resolveImage(collection.image, { width: 480 });\n const showImage = imageUrl && !imgError;\n const initial = (collection.name ?? collection.contractAddress).charAt(0).toUpperCase();\n const floor = parseFloorPrice(collection.floorPrice);\n const hasExclusiveContent = !!(collection as CollectionWithProfile).profile?.hasGatedContent;\n\n return (\n <div className={cn(hasExclusiveContent && \"card-exclusive-wrapper btn-border-animated\")}>\n <MotionCard className={cn(\"card-base group relative\", className)}>\n {settingsHref && (\n <Link\n href={settingsHref}\n onClick={(e) => e.stopPropagation()}\n className=\"absolute top-2 right-2 z-10 min-h-11 min-w-11 rounded-full flex items-center justify-center\"\n aria-label=\"Collection settings\"\n >\n <span className=\"flex h-7 w-7 items-center justify-center rounded-full bg-black/40 backdrop-blur-sm text-white/70 hover:text-white hover:bg-black/60 transition-colors\">\n <Settings2 className=\"h-3.5 w-3.5\" />\n </span>\n </Link>\n )}\n\n <Link href={href ?? `/collections/${collection.contractAddress}`} className=\"block relative h-full\">\n <div className=\"relative aspect-square w-full overflow-hidden bg-muted\">\n {showImage ? (\n <Image\n src={imageUrl}\n alt={collection.name ?? \"Collection\"}\n fill\n className=\"object-cover transition-transform duration-500 group-hover:scale-105\"\n onError={() => setImgError(true)}\n unoptimized\n />\n ) : (\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/30 via-brand-blue/20 to-brand-navy/40 flex items-center justify-center\">\n <span className=\"text-8xl font-black text-white/10 select-none tracking-tighter\">\n {initial}\n </span>\n </div>\n )}\n\n <div className=\"absolute bottom-0 left-0 right-0 px-3 pb-3 flex flex-col gap-1.5 items-start\">\n {!collection.name && collection.metadataStatus === \"PENDING\" ? (\n <span className=\"flex items-center gap-1 text-2xs text-white/60 backdrop-blur-md bg-black/30 rounded-full px-2 py-0.5\">\n <Loader2 className=\"h-2.5 w-2.5 animate-spin\" />\n Indexing…\n </span>\n ) : (\n <p\n className=\"font-bold text-sm text-white leading-tight backdrop-blur-md bg-black/30 rounded-lg px-2.5 py-1 max-w-full truncate\"\n style={{ textShadow: \"0 1px 6px rgba(0,0,0,0.5)\" }}\n >\n {collection.name ?? \"Unnamed Collection\"}\n </p>\n )}\n\n <div className=\"flex items-center gap-1.5 flex-wrap\">\n {collection.totalSupply != null && (\n <span className=\"text-2xs font-medium text-white/80 backdrop-blur-md bg-black/30 rounded-full px-2 py-0.5\">\n {collection.totalSupply.toLocaleString()} items\n </span>\n )}\n {floor && (\n <span className=\"inline-flex items-center gap-1 text-2xs font-bold text-white/90 backdrop-blur-md bg-black/30 rounded-full px-2 py-0.5\">\n Floor\n <CurrencyIcon symbol={floor.symbol} size={10} />\n {floor.amount}\n </span>\n )}\n {hasExclusiveContent && (\n <span className=\"inline-flex items-center gap-1 text-2xs font-bold text-white backdrop-blur-md bg-black/50 rounded-full px-2 py-0.5\">\n ✦ Exclusive\n </span>\n )}\n </div>\n </div>\n </div>\n </Link>\n </MotionCard>\n </div>\n );\n}\n\nexport function CollectionCardSkeleton() {\n return (\n <div className=\"card-base overflow-hidden\">\n <div className=\"relative aspect-square w-full overflow-hidden bg-muted\">\n <div className=\"absolute inset-0 animate-pulse bg-muted\" />\n <div className=\"absolute bottom-3 left-3 right-3 space-y-1.5\">\n <div className=\"h-4 w-2/3 rounded-md bg-muted-foreground/20 animate-pulse\" />\n <div className=\"h-3 w-1/3 rounded-md bg-muted-foreground/20 animate-pulse\" />\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/collection-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"./link.js\";\nimport Image from \"./image.js\";\nimport { Loader2, Settings2 } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { MotionCard } from \"./motion-primitives.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport type { ApiCollection } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nfunction parseFloorPrice(floor: string | null | undefined): { amount: string; symbol: string } | null {\n if (!floor) return null;\n const formatted = formatDisplayPrice(floor);\n const parts = formatted.trim().split(/\\s+/);\n if (parts.length < 2) return null;\n const symbol = parts[parts.length - 1];\n const amount = parts.slice(0, -1).join(\" \");\n return { amount, symbol };\n}\n\nexport interface CollectionCardProps {\n collection: ApiCollection;\n\n href?: string;\n\n settingsHref?: string;\n className?: string;\n}\n\nexport function CollectionCard({ collection, href, settingsHref, className }: CollectionCardProps) {\n const resolveImage = useImageUrl();\n const [imgError, setImgError] = useState(false);\n const imageUrl = resolveImage(collection.image, { width: 480 });\n const showImage = imageUrl && !imgError;\n const initial = (collection.name ?? collection.contractAddress).charAt(0).toUpperCase();\n const floor = parseFloorPrice(collection.floorPrice);\n\n return (\n <MotionCard className={cn(\"card-base group relative\", className)}>\n {settingsHref && (\n <Link\n href={settingsHref}\n onClick={(e) => e.stopPropagation()}\n className=\"absolute top-2 right-2 z-10 min-h-11 min-w-11 rounded-full flex items-center justify-center\"\n aria-label=\"Collection settings\"\n >\n <span className=\"flex h-7 w-7 items-center justify-center rounded-full bg-black/40 backdrop-blur-sm text-white/70 hover:text-white hover:bg-black/60 transition-colors\">\n <Settings2 className=\"h-3.5 w-3.5\" />\n </span>\n </Link>\n )}\n\n <Link href={href ?? `/collections/${collection.contractAddress}`} className=\"block relative h-full\">\n <div className=\"relative aspect-square w-full overflow-hidden bg-muted\">\n {showImage ? (\n <Image\n src={imageUrl}\n alt={collection.name ?? \"Collection\"}\n fill\n className=\"object-cover transition-transform duration-500 group-hover:scale-105\"\n onError={() => setImgError(true)}\n unoptimized\n />\n ) : (\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/30 via-brand-blue/20 to-brand-navy/40 flex items-center justify-center\">\n <span className=\"text-8xl font-black text-white/10 select-none tracking-tighter\">\n {initial}\n </span>\n </div>\n )}\n\n <div className=\"absolute inset-x-0 bottom-0 flex flex-col items-start gap-1 bg-gradient-to-t from-black/85 via-black/45 to-transparent px-3 pb-3 pt-14\">\n {!collection.name && collection.metadataStatus === \"PENDING\" ? (\n <span className=\"flex items-center gap-1 text-2xs text-white/70\">\n <Loader2 className=\"h-2.5 w-2.5 animate-spin\" />\n Indexing…\n </span>\n ) : (\n <p className=\"max-w-full truncate text-sm font-bold leading-tight text-white\">\n {collection.name ?? \"Unnamed Collection\"}\n </p>\n )}\n\n <div className=\"flex flex-wrap items-center gap-x-2.5 gap-y-0.5 text-2xs font-medium text-white/80\">\n {collection.totalSupply != null && (\n <span>\n {collection.totalSupply.toLocaleString()} {collection.totalSupply === 1 ? \"item\" : \"items\"}\n </span>\n )}\n {floor && (\n <span className=\"inline-flex items-center gap-1 font-bold text-white/90\">\n Floor\n <CurrencyIcon symbol={floor.symbol} size={10} />\n {floor.amount}\n </span>\n )}\n </div>\n </div>\n </div>\n </Link>\n </MotionCard>\n );\n}\n\nexport function CollectionCardSkeleton() {\n return (\n <div className=\"card-base overflow-hidden\">\n <div className=\"relative aspect-square w-full overflow-hidden bg-muted\">\n <div className=\"absolute inset-0 animate-pulse bg-muted\" />\n <div className=\"absolute bottom-3 left-3 right-3 space-y-1.5\">\n <div className=\"h-4 w-2/3 rounded-md bg-muted-foreground/20 animate-pulse\" />\n <div className=\"h-3 w-1/3 rounded-md bg-muted-foreground/20 animate-pulse\" />\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";AAkDY,cA0BE,YA1BF;AAhDZ,SAAS,gBAAgB;AACzB,OAAO,UAAU;AACjB,OAAO,WAAW;AAClB,SAAS,SAAS,iBAAiB;AACnC,SAAS,UAAU;AACnB,SAAS,0BAA0B;AACnC,SAAS,kBAAkB;AAC3B,SAAS,oBAAoB;AAE7B,SAAS,mBAAmB;AAE5B,SAAS,gBAAgB,OAA6E;AACpG,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,YAAY,mBAAmB,KAAK;AAC1C,QAAM,QAAQ,UAAU,KAAK,EAAE,MAAM,KAAK;AAC1C,MAAI,MAAM,SAAS,EAAG,QAAO;AAC7B,QAAM,SAAS,MAAM,MAAM,SAAS,CAAC;AACrC,QAAM,SAAS,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG;AAC1C,SAAO,EAAE,QAAQ,OAAO;AAC1B;AAWO,SAAS,eAAe,EAAE,YAAY,MAAM,cAAc,UAAU,GAAwB;AACjG,QAAM,eAAe,YAAY;AACjC,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,QAAM,WAAW,aAAa,WAAW,OAAO,EAAE,OAAO,IAAI,CAAC;AAC9D,QAAM,YAAY,YAAY,CAAC;AAC/B,QAAM,WAAW,WAAW,QAAQ,WAAW,iBAAiB,OAAO,CAAC,EAAE,YAAY;AACtF,QAAM,QAAQ,gBAAgB,WAAW,UAAU;AAEnD,SACE,qBAAC,cAAW,WAAW,GAAG,4BAA4B,SAAS,GAC5D;AAAA,oBACC;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,QAClC,WAAU;AAAA,QACV,cAAW;AAAA,QAEX,8BAAC,UAAK,WAAU,yJACd,8BAAC,aAAU,WAAU,eAAc,GACrC;AAAA;AAAA,IACF;AAAA,IAGF,oBAAC,QAAK,MAAM,QAAQ,gBAAgB,WAAW,eAAe,IAAI,WAAU,yBAC1E,+BAAC,SAAI,WAAU,0DACZ;AAAA,kBACC;AAAA,QAAC;AAAA;AAAA,UACC,KAAK;AAAA,UACL,KAAK,WAAW,QAAQ;AAAA,UACxB,MAAI;AAAA,UACJ,WAAU;AAAA,UACV,SAAS,MAAM,YAAY,IAAI;AAAA,UAC/B,aAAW;AAAA;AAAA,MACb,IAEA,oBAAC,SAAI,WAAU,+HACb,8BAAC,UAAK,WAAU,kEACb,mBACH,GACF;AAAA,MAGF,qBAAC,SAAI,WAAU,0IACZ;AAAA,SAAC,WAAW,QAAQ,WAAW,mBAAmB,YACjD,qBAAC,UAAK,WAAU,kDACd;AAAA,8BAAC,WAAQ,WAAU,4BAA2B;AAAA,UAAE;AAAA,WAElD,IAEA,oBAAC,OAAE,WAAU,kEACV,qBAAW,QAAQ,sBACtB;AAAA,QAGF,qBAAC,SAAI,WAAU,sFACZ;AAAA,qBAAW,eAAe,QACzB,qBAAC,UACE;AAAA,uBAAW,YAAY,eAAe;AAAA,YAAE;AAAA,YAAE,WAAW,gBAAgB,IAAI,SAAS;AAAA,aACrF;AAAA,UAED,SACC,qBAAC,UAAK,WAAU,0DAAyD;AAAA;AAAA,YAEvE,oBAAC,gBAAa,QAAQ,MAAM,QAAQ,MAAM,IAAI;AAAA,YAC7C,MAAM;AAAA,aACT;AAAA,WAEJ;AAAA,SACF;AAAA,OACF,GACF;AAAA,KACF;AAEJ;AAEO,SAAS,yBAAyB;AACvC,SACE,oBAAC,SAAI,WAAU,6BACb,+BAAC,SAAI,WAAU,0DACb;AAAA,wBAAC,SAAI,WAAU,2CAA0C;AAAA,IACzD,qBAAC,SAAI,WAAU,gDACb;AAAA,0BAAC,SAAI,WAAU,6DAA4D;AAAA,MAC3E,oBAAC,SAAI,WAAU,6DAA4D;AAAA,OAC7E;AAAA,KACF,GACF;AAEJ;","names":[]}