@medialane/ui 0.4.0 → 0.4.2

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 (36) hide show
  1. package/README.md +219 -0
  2. package/dist/components/activity-ticker.cjs +1 -2
  3. package/dist/components/activity-ticker.cjs.map +1 -1
  4. package/dist/components/activity-ticker.d.cts +2 -1
  5. package/dist/components/activity-ticker.d.ts +2 -1
  6. package/dist/components/activity-ticker.js +1 -2
  7. package/dist/components/activity-ticker.js.map +1 -1
  8. package/dist/components/discover-collections-strip.cjs +5 -3
  9. package/dist/components/discover-collections-strip.cjs.map +1 -1
  10. package/dist/components/discover-collections-strip.d.cts +3 -1
  11. package/dist/components/discover-collections-strip.d.ts +3 -1
  12. package/dist/components/discover-collections-strip.js +5 -3
  13. package/dist/components/discover-collections-strip.js.map +1 -1
  14. package/dist/components/discover-creators-strip.cjs +7 -5
  15. package/dist/components/discover-creators-strip.cjs.map +1 -1
  16. package/dist/components/discover-creators-strip.d.cts +3 -1
  17. package/dist/components/discover-creators-strip.d.ts +3 -1
  18. package/dist/components/discover-creators-strip.js +7 -5
  19. package/dist/components/discover-creators-strip.js.map +1 -1
  20. package/dist/components/discover-hero.cjs +3 -2
  21. package/dist/components/discover-hero.cjs.map +1 -1
  22. package/dist/components/discover-hero.d.cts +2 -1
  23. package/dist/components/discover-hero.d.ts +2 -1
  24. package/dist/components/discover-hero.js +3 -2
  25. package/dist/components/discover-hero.js.map +1 -1
  26. package/dist/components/hero-slider.cjs +8 -11
  27. package/dist/components/hero-slider.cjs.map +1 -1
  28. package/dist/components/hero-slider.d.cts +6 -1
  29. package/dist/components/hero-slider.d.ts +6 -1
  30. package/dist/components/hero-slider.js +7 -10
  31. package/dist/components/hero-slider.js.map +1 -1
  32. package/dist/data/launchpad-services.cjs +38 -38
  33. package/dist/data/launchpad-services.cjs.map +1 -1
  34. package/dist/data/launchpad-services.js +38 -38
  35. package/dist/data/launchpad-services.js.map +1 -1
  36. package/package.json +1 -1
package/README.md ADDED
@@ -0,0 +1,219 @@
1
+ # @medialane/ui
2
+
3
+ Shared UI component library for Medialane apps. Used by `medialane-dapp`, `medialane-io`, and `medialane-portal`.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@medialane/ui)](https://www.npmjs.com/package/@medialane/ui)
6
+
7
+ ---
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install @medialane/ui
13
+ # or
14
+ bun add @medialane/ui
15
+ ```
16
+
17
+ ### Tailwind preset
18
+
19
+ Add the preset in `tailwind.config.ts` to get all brand tokens and custom utilities:
20
+
21
+ ```ts
22
+ import uiPreset from "@medialane/ui/preset";
23
+
24
+ export default {
25
+ presets: [uiPreset],
26
+ content: ["./src/**/*.{ts,tsx}", "./node_modules/@medialane/ui/dist/**/*.js"],
27
+ };
28
+ ```
29
+
30
+ ### Global styles
31
+
32
+ ```ts
33
+ // app/layout.tsx or equivalent entry point
34
+ import "@medialane/ui/styles";
35
+ ```
36
+
37
+ ---
38
+
39
+ ## Peer Dependencies
40
+
41
+ | Package | Required |
42
+ |---|---|
43
+ | `react` | >=18.0.0 |
44
+ | `react-dom` | >=18.0.0 |
45
+ | `next` | >=14.0.0 |
46
+ | `framer-motion` | >=10.0.0 |
47
+ | `lucide-react` | >=0.400.0 |
48
+ | `sonner` | >=1.0.0 |
49
+ | `tailwind-merge` | >=2.0.0 |
50
+ | `clsx` | >=2.0.0 |
51
+ | `@medialane/sdk` | >=0.6.0 |
52
+
53
+ ---
54
+
55
+ ## Component Reference
56
+
57
+ ### Utils
58
+
59
+ ```ts
60
+ import { cn, formatDisplayPrice, shortenAddress, ipfsToHttp, timeAgo } from "@medialane/ui";
61
+ ```
62
+
63
+ | Export | Description |
64
+ |---|---|
65
+ | `cn(...classes)` | clsx + tailwind-merge class combiner |
66
+ | `formatDisplayPrice(price)` | Format price string for display |
67
+ | `shortenAddress(addr)` | Truncate 0x address — `0x1234…abcd` |
68
+ | `ipfsToHttp(uri)` | Convert `ipfs://` URI to Pinata HTTP gateway URL |
69
+ | `timeAgo(timestamp)` | Relative time string — "3 hours ago" |
70
+
71
+ ---
72
+
73
+ ### Data (server-safe — no React, safe in Server Components)
74
+
75
+ ```ts
76
+ import { IP_TYPE_DATA, IP_TYPE_DATA_MAP, BRAND, ACTIVITY_TYPE_CONFIG, TYPE_FILTERS, LAUNCHPAD_SERVICE_DEFINITIONS } from "@medialane/ui";
77
+ ```
78
+
79
+ | Export | Description |
80
+ |---|---|
81
+ | `IP_TYPE_DATA` | Array of IP type definitions (label, icon, color) |
82
+ | `IP_TYPE_DATA_MAP` | Map keyed by IP type string |
83
+ | `BRAND` | Brand color and design tokens |
84
+ | `ACTIVITY_TYPE_CONFIG` | Activity type config (mint/sale/offer/transfer/listing/cancelled) |
85
+ | `TYPE_FILTERS` | Activity filter options for UI |
86
+ | `LAUNCHPAD_SERVICE_DEFINITIONS` | All launchpad service card definitions |
87
+
88
+ ---
89
+
90
+ ### v0.1 — Base Components
91
+
92
+ ```ts
93
+ import { CurrencyIcon, CurrencyAmount, IpTypeBadge, AddressDisplay, MedialaneIcon, MedialaneLogoFull } from "@medialane/ui";
94
+ ```
95
+
96
+ | Component | Description |
97
+ |---|---|
98
+ | `<CurrencyIcon currency="ETH" />` | Token currency icon (ETH, STRK, USDC, USDT, WBTC) |
99
+ | `<CurrencyAmount amount="1.5" currency="ETH" />` | Formatted amount with icon |
100
+ | `<IpTypeBadge type="Music" />` | IP type pill badge with color and icon |
101
+ | `<AddressDisplay address="0x..." />` | Formatted address with copy-to-clipboard |
102
+ | `<MedialaneIcon size={24} />` | Medialane "M" brand icon |
103
+ | `<MedialaneLogoFull />` | Full Medialane wordmark |
104
+
105
+ ---
106
+
107
+ ### v0.2 — Motion + Cards
108
+
109
+ ```ts
110
+ import {
111
+ MotionCard, FadeIn, Stagger, StaggerItem, KineticWords, SPRING, EASE_OUT,
112
+ ScrollSection, ShareButton, CollectionCard, CollectionCardSkeleton,
113
+ TokenCard, TokenCardSkeleton,
114
+ } from "@medialane/ui";
115
+ ```
116
+
117
+ | Component | Description |
118
+ |---|---|
119
+ | `<MotionCard>` | Framer Motion card with hover lift |
120
+ | `<FadeIn>` | Fade-in entrance animation wrapper |
121
+ | `<Stagger>` / `<StaggerItem>` | Staggered list entrance animations |
122
+ | `<KineticWords>` | Animated word-by-word text reveal |
123
+ | `SPRING` / `EASE_OUT` | Reusable animation spring/easing constants |
124
+ | `<ScrollSection>` | Scroll-triggered section fade-in |
125
+ | `<ShareButton>` | Native share API with clipboard fallback |
126
+ | `<CollectionCard collection={c} />` | Collection grid card with image, name, stats |
127
+ | `<CollectionCardSkeleton />` | Loading skeleton for CollectionCard |
128
+ | `<TokenCard token={t} />` | Unified NFT/token card — used on marketplace, portfolio, collections |
129
+ | `<TokenCardSkeleton />` | Loading skeleton for TokenCard |
130
+
131
+ ---
132
+
133
+ ### v0.3 — Activity + Launchpad + Marketplace
134
+
135
+ ```ts
136
+ import {
137
+ HeroSlider, HeroSliderSkeleton, ActivityTicker, ListingCard, ListingCardSkeleton,
138
+ ActivityRow, ActivityFeedShell, LaunchpadGrid, CtaCardGrid,
139
+ } from "@medialane/ui";
140
+ ```
141
+
142
+ | Component | Description |
143
+ |---|---|
144
+ | `<HeroSlider slides={[...]} />` | Full-width hero carousel with auto-advance |
145
+ | `<HeroSliderSkeleton />` | Loading skeleton for HeroSlider |
146
+ | `<ActivityTicker activities={[...]} />` | Horizontal scrolling live activity feed ticker |
147
+ | `<ListingCard order={o} />` | Marketplace listing card (price, asset image, buy CTA) |
148
+ | `<ListingCardSkeleton />` | Loading skeleton for ListingCard |
149
+ | `<ActivityRow event={a} isLast={false} />` | Timeline activity row with spine connector |
150
+ | `<ActivityFeedShell activities={[...]} />` | Full activity feed with type filters |
151
+ | `<LaunchpadGrid items={[...]} />` | Launchpad feature grid |
152
+ | `<CtaCardGrid items={[...]} />` | CTA card grid section |
153
+
154
+ ---
155
+
156
+ ### v0.3.2 — Discover Components
157
+
158
+ ```ts
159
+ import {
160
+ DiscoverHero, FeaturedCarousel, FeaturedCarouselSkeleton,
161
+ DiscoverCollectionsStrip, DiscoverCreatorsStrip, DiscoverFeedSection,
162
+ } from "@medialane/ui";
163
+ ```
164
+
165
+ | Component | Description |
166
+ |---|---|
167
+ | `<DiscoverHero>` | Discover page hero with headline and search |
168
+ | `<FeaturedCarousel collections={[...]} />` | Featured collections horizontal carousel |
169
+ | `<FeaturedCarouselSkeleton />` | Loading skeleton for FeaturedCarousel |
170
+ | `<DiscoverCollectionsStrip collections={[...]} />` | Horizontal discovery strip for collections |
171
+ | `<DiscoverCreatorsStrip creators={[...]} />` | Horizontal discovery strip for creators |
172
+ | `<DiscoverFeedSection>` | Full discover page feed section |
173
+
174
+ ---
175
+
176
+ ### v0.4 — Launchpad Services
177
+
178
+ ```ts
179
+ import { LaunchpadServicesGrid, LAUNCHPAD_SERVICE_DEFINITIONS } from "@medialane/ui";
180
+ ```
181
+
182
+ | Export | Description |
183
+ |---|---|
184
+ | `<LaunchpadServicesGrid services={LAUNCHPAD_SERVICE_DEFINITIONS} />` | Launchpad services grid with live/coming-soon badges |
185
+ | `LAUNCHPAD_SERVICE_DEFINITIONS` | Pre-built service definitions for all launchpad products |
186
+
187
+ ---
188
+
189
+ ## Build & Publish
190
+
191
+ ```bash
192
+ cd medialane-ui
193
+
194
+ # Build (outputs to dist/)
195
+ ~/.bun/bin/bun run build
196
+
197
+ # Type-check
198
+ ~/.bun/bin/bun run typecheck
199
+
200
+ # Watch mode during development
201
+ ~/.bun/bin/bun run dev
202
+
203
+ # Publish to npm
204
+ npm publish
205
+ ```
206
+
207
+ The package uses [tsup](https://tsup.egoist.dev/) and outputs ESM + CJS + type declarations.
208
+
209
+ ---
210
+
211
+ ## Version History
212
+
213
+ | Version | Added |
214
+ |---|---|
215
+ | **v0.4.0** | `LaunchpadServicesGrid`, `LAUNCHPAD_SERVICE_DEFINITIONS` |
216
+ | **v0.3.2** | `DiscoverHero`, `FeaturedCarousel`, `DiscoverCollectionsStrip`, `DiscoverCreatorsStrip`, `DiscoverFeedSection` |
217
+ | **v0.3.0** | `ActivityRow`, `ActivityFeedShell`, `ActivityTicker`, `HeroSlider`, `ListingCard`, `LaunchpadGrid`, `CtaCardGrid`, `timeAgo`, `ACTIVITY_TYPE_CONFIG` |
218
+ | **v0.2.0** | `MotionCard`, `FadeIn`, `Stagger`, `StaggerItem`, `KineticWords`, `ScrollSection`, `ShareButton`, `CollectionCard`, `TokenCard` |
219
+ | **v0.1.0** | `cn`, `formatDisplayPrice`, `shortenAddress`, `ipfsToHttp`, `CurrencyIcon`, `CurrencyAmount`, `IpTypeBadge`, `AddressDisplay`, `MedialaneIcon`, `MedialaneLogoFull`, `IP_TYPE_DATA`, `BRAND` |
@@ -71,9 +71,8 @@ function ActivityPill({ listing, getHref }) {
71
71
  }
72
72
  );
73
73
  }
74
- function ActivityTicker({ orders, minItems = 3, className }) {
74
+ function ActivityTicker({ orders, minItems = 3, className, getHref = (o) => `/asset/${o.nftContract}/${o.nftTokenId}` }) {
75
75
  if (orders.length < minItems) return null;
76
- const getHref = (order) => `/asset/${order.nftContract}/${order.nftTokenId}`;
77
76
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: (0, import_cn.cn)(className), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "relative overflow-hidden py-2.5", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
78
77
  "div",
79
78
  {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/activity-ticker.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"next/link\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { cn } from \"../utils/cn.js\";\nimport type { ApiOrder } from \"@medialane/sdk\";\n\nexport interface ActivityTickerProps {\n orders: ApiOrder[];\n /** Hide ticker if fewer items than this threshold. Default: 3 */\n minItems?: number;\n className?: string;\n}\n\nfunction ActivityPill({ listing, getHref }: { listing: ApiOrder; getHref: (order: ApiOrder) => string }) {\n const [imgError, setImgError] = useState(false);\n const image = listing.token?.image && !imgError ? ipfsToHttp(listing.token.image) : null;\n\n return (\n <Link\n href={getHref(listing)}\n className=\"flex-shrink-0 flex items-center gap-2 rounded-xl border border-border bg-card px-3 py-2 hover:bg-muted/60 active:scale-[0.98] transition-all duration-150 group\"\n >\n <div className=\"h-8 w-8 rounded-lg overflow-hidden bg-muted shrink-0\">\n {image ? (\n <img\n src={image}\n alt=\"\"\n loading=\"lazy\"\n className=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-300\"\n onError={() => setImgError(true)}\n />\n ) : (\n <div className=\"w-full h-full bg-gradient-to-br from-brand-purple/20 to-brand-blue/20\" />\n )}\n </div>\n <div className=\"min-w-0\">\n <p className=\"text-xs font-medium whitespace-nowrap max-w-[100px] truncate\">\n {listing.token?.name ?? `#${listing.nftTokenId}`}\n </p>\n {listing.price?.formatted && (\n <p className=\"text-[10px] font-bold text-brand-orange whitespace-nowrap flex items-center gap-0.5\">\n {listing.price.currency && <CurrencyIcon symbol={listing.price.currency} size={10} />}\n {formatDisplayPrice(listing.price.formatted)} {listing.price.currency}\n </p>\n )}\n </div>\n </Link>\n );\n}\n\nexport function ActivityTicker({ orders, minItems = 3, className }: ActivityTickerProps) {\n if (orders.length < minItems) return null;\n\n const getHref = (order: ApiOrder) => `/asset/${order.nftContract}/${order.nftTokenId}`;\n\n return (\n <div className={cn(className)}>\n <div className=\"relative overflow-hidden py-2.5\">\n <div\n className=\"flex gap-2 w-max px-2\"\n style={{ animation: \"scroll-strip 50s linear infinite\" }}\n onMouseEnter={(e) => (e.currentTarget.style.animationPlayState = \"paused\")}\n onMouseLeave={(e) => (e.currentTarget.style.animationPlayState = \"running\")}\n >\n {[...orders, ...orders].map((listing, i) => (\n <ActivityPill key={`${listing.orderHash}-${i}`} listing={listing} getHref={getHref} />\n ))}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA4BU;AA1BV,mBAAyB;AACzB,kBAAiB;AACjB,2BAA6B;AAC7B,oBAAmC;AACnC,kBAA2B;AAC3B,gBAAmB;AAUnB,SAAS,aAAa,EAAE,SAAS,QAAQ,GAAgE;AACvG,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,KAAK;AAC9C,QAAM,QAAQ,QAAQ,OAAO,SAAS,CAAC,eAAW,wBAAW,QAAQ,MAAM,KAAK,IAAI;AAEpF,SACE;AAAA,IAAC,YAAAA;AAAA,IAAA;AAAA,MACC,MAAM,QAAQ,OAAO;AAAA,MACrB,WAAU;AAAA,MAEV;AAAA,oDAAC,SAAI,WAAU,wDACZ,kBACC;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,KAAI;AAAA,YACJ,SAAQ;AAAA,YACR,WAAU;AAAA,YACV,SAAS,MAAM,YAAY,IAAI;AAAA;AAAA,QACjC,IAEA,4CAAC,SAAI,WAAU,yEAAwE,GAE3F;AAAA,QACA,6CAAC,SAAI,WAAU,WACb;AAAA,sDAAC,OAAE,WAAU,gEACV,kBAAQ,OAAO,QAAQ,IAAI,QAAQ,UAAU,IAChD;AAAA,UACC,QAAQ,OAAO,aACd,6CAAC,OAAE,WAAU,uFACV;AAAA,oBAAQ,MAAM,YAAY,4CAAC,qCAAa,QAAQ,QAAQ,MAAM,UAAU,MAAM,IAAI;AAAA,gBAClF,kCAAmB,QAAQ,MAAM,SAAS;AAAA,YAAE;AAAA,YAAE,QAAQ,MAAM;AAAA,aAC/D;AAAA,WAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,eAAe,EAAE,QAAQ,WAAW,GAAG,UAAU,GAAwB;AACvF,MAAI,OAAO,SAAS,SAAU,QAAO;AAErC,QAAM,UAAU,CAAC,UAAoB,UAAU,MAAM,WAAW,IAAI,MAAM,UAAU;AAEpF,SACE,4CAAC,SAAI,eAAW,cAAG,SAAS,GAC1B,sDAAC,SAAI,WAAU,mCACb;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,WAAW,mCAAmC;AAAA,MACvD,cAAc,CAAC,MAAO,EAAE,cAAc,MAAM,qBAAqB;AAAA,MACjE,cAAc,CAAC,MAAO,EAAE,cAAc,MAAM,qBAAqB;AAAA,MAEhE,WAAC,GAAG,QAAQ,GAAG,MAAM,EAAE,IAAI,CAAC,SAAS,MACpC,4CAAC,gBAA+C,SAAkB,WAA/C,GAAG,QAAQ,SAAS,IAAI,CAAC,EAAwC,CACrF;AAAA;AAAA,EACH,GACF,GACF;AAEJ;","names":["Link"]}
1
+ {"version":3,"sources":["../../src/components/activity-ticker.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"next/link\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { cn } from \"../utils/cn.js\";\nimport type { ApiOrder } from \"@medialane/sdk\";\n\nexport interface ActivityTickerProps {\n orders: ApiOrder[];\n /** Hide ticker if fewer items than this threshold. Default: 3 */\n minItems?: number;\n className?: string;\n getHref?: (order: ApiOrder) => string;\n}\n\nfunction ActivityPill({ listing, getHref }: { listing: ApiOrder; getHref: (order: ApiOrder) => string }) {\n const [imgError, setImgError] = useState(false);\n const image = listing.token?.image && !imgError ? ipfsToHttp(listing.token.image) : null;\n\n return (\n <Link\n href={getHref(listing)}\n className=\"flex-shrink-0 flex items-center gap-2 rounded-xl border border-border bg-card px-3 py-2 hover:bg-muted/60 active:scale-[0.98] transition-all duration-150 group\"\n >\n <div className=\"h-8 w-8 rounded-lg overflow-hidden bg-muted shrink-0\">\n {image ? (\n <img\n src={image}\n alt=\"\"\n loading=\"lazy\"\n className=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-300\"\n onError={() => setImgError(true)}\n />\n ) : (\n <div className=\"w-full h-full bg-gradient-to-br from-brand-purple/20 to-brand-blue/20\" />\n )}\n </div>\n <div className=\"min-w-0\">\n <p className=\"text-xs font-medium whitespace-nowrap max-w-[100px] truncate\">\n {listing.token?.name ?? `#${listing.nftTokenId}`}\n </p>\n {listing.price?.formatted && (\n <p className=\"text-[10px] font-bold text-brand-orange whitespace-nowrap flex items-center gap-0.5\">\n {listing.price.currency && <CurrencyIcon symbol={listing.price.currency} size={10} />}\n {formatDisplayPrice(listing.price.formatted)} {listing.price.currency}\n </p>\n )}\n </div>\n </Link>\n );\n}\n\nexport function ActivityTicker({ orders, minItems = 3, className, getHref = (o) => `/asset/${o.nftContract}/${o.nftTokenId}` }: ActivityTickerProps) {\n if (orders.length < minItems) return null;\n\n return (\n <div className={cn(className)}>\n <div className=\"relative overflow-hidden py-2.5\">\n <div\n className=\"flex gap-2 w-max px-2\"\n style={{ animation: \"scroll-strip 50s linear infinite\" }}\n onMouseEnter={(e) => (e.currentTarget.style.animationPlayState = \"paused\")}\n onMouseLeave={(e) => (e.currentTarget.style.animationPlayState = \"running\")}\n >\n {[...orders, ...orders].map((listing, i) => (\n <ActivityPill key={`${listing.orderHash}-${i}`} listing={listing} getHref={getHref} />\n ))}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA6BU;AA3BV,mBAAyB;AACzB,kBAAiB;AACjB,2BAA6B;AAC7B,oBAAmC;AACnC,kBAA2B;AAC3B,gBAAmB;AAWnB,SAAS,aAAa,EAAE,SAAS,QAAQ,GAAgE;AACvG,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,KAAK;AAC9C,QAAM,QAAQ,QAAQ,OAAO,SAAS,CAAC,eAAW,wBAAW,QAAQ,MAAM,KAAK,IAAI;AAEpF,SACE;AAAA,IAAC,YAAAA;AAAA,IAAA;AAAA,MACC,MAAM,QAAQ,OAAO;AAAA,MACrB,WAAU;AAAA,MAEV;AAAA,oDAAC,SAAI,WAAU,wDACZ,kBACC;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,KAAI;AAAA,YACJ,SAAQ;AAAA,YACR,WAAU;AAAA,YACV,SAAS,MAAM,YAAY,IAAI;AAAA;AAAA,QACjC,IAEA,4CAAC,SAAI,WAAU,yEAAwE,GAE3F;AAAA,QACA,6CAAC,SAAI,WAAU,WACb;AAAA,sDAAC,OAAE,WAAU,gEACV,kBAAQ,OAAO,QAAQ,IAAI,QAAQ,UAAU,IAChD;AAAA,UACC,QAAQ,OAAO,aACd,6CAAC,OAAE,WAAU,uFACV;AAAA,oBAAQ,MAAM,YAAY,4CAAC,qCAAa,QAAQ,QAAQ,MAAM,UAAU,MAAM,IAAI;AAAA,gBAClF,kCAAmB,QAAQ,MAAM,SAAS;AAAA,YAAE;AAAA,YAAE,QAAQ,MAAM;AAAA,aAC/D;AAAA,WAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,eAAe,EAAE,QAAQ,WAAW,GAAG,WAAW,UAAU,CAAC,MAAM,UAAU,EAAE,WAAW,IAAI,EAAE,UAAU,GAAG,GAAwB;AACnJ,MAAI,OAAO,SAAS,SAAU,QAAO;AAErC,SACE,4CAAC,SAAI,eAAW,cAAG,SAAS,GAC1B,sDAAC,SAAI,WAAU,mCACb;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,WAAW,mCAAmC;AAAA,MACvD,cAAc,CAAC,MAAO,EAAE,cAAc,MAAM,qBAAqB;AAAA,MACjE,cAAc,CAAC,MAAO,EAAE,cAAc,MAAM,qBAAqB;AAAA,MAEhE,WAAC,GAAG,QAAQ,GAAG,MAAM,EAAE,IAAI,CAAC,SAAS,MACpC,4CAAC,gBAA+C,SAAkB,WAA/C,GAAG,QAAQ,SAAS,IAAI,CAAC,EAAwC,CACrF;AAAA;AAAA,EACH,GACF,GACF;AAEJ;","names":["Link"]}
@@ -6,7 +6,8 @@ interface ActivityTickerProps {
6
6
  /** Hide ticker if fewer items than this threshold. Default: 3 */
7
7
  minItems?: number;
8
8
  className?: string;
9
+ getHref?: (order: ApiOrder) => string;
9
10
  }
10
- declare function ActivityTicker({ orders, minItems, className }: ActivityTickerProps): react_jsx_runtime.JSX.Element | null;
11
+ declare function ActivityTicker({ orders, minItems, className, getHref }: ActivityTickerProps): react_jsx_runtime.JSX.Element | null;
11
12
 
12
13
  export { ActivityTicker, type ActivityTickerProps };
@@ -6,7 +6,8 @@ interface ActivityTickerProps {
6
6
  /** Hide ticker if fewer items than this threshold. Default: 3 */
7
7
  minItems?: number;
8
8
  className?: string;
9
+ getHref?: (order: ApiOrder) => string;
9
10
  }
10
- declare function ActivityTicker({ orders, minItems, className }: ActivityTickerProps): react_jsx_runtime.JSX.Element | null;
11
+ declare function ActivityTicker({ orders, minItems, className, getHref }: ActivityTickerProps): react_jsx_runtime.JSX.Element | null;
11
12
 
12
13
  export { ActivityTicker, type ActivityTickerProps };
@@ -38,9 +38,8 @@ function ActivityPill({ listing, getHref }) {
38
38
  }
39
39
  );
40
40
  }
41
- function ActivityTicker({ orders, minItems = 3, className }) {
41
+ function ActivityTicker({ orders, minItems = 3, className, getHref = (o) => `/asset/${o.nftContract}/${o.nftTokenId}` }) {
42
42
  if (orders.length < minItems) return null;
43
- const getHref = (order) => `/asset/${order.nftContract}/${order.nftTokenId}`;
44
43
  return /* @__PURE__ */ jsx("div", { className: cn(className), children: /* @__PURE__ */ jsx("div", { className: "relative overflow-hidden py-2.5", children: /* @__PURE__ */ jsx(
45
44
  "div",
46
45
  {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/activity-ticker.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"next/link\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { cn } from \"../utils/cn.js\";\nimport type { ApiOrder } from \"@medialane/sdk\";\n\nexport interface ActivityTickerProps {\n orders: ApiOrder[];\n /** Hide ticker if fewer items than this threshold. Default: 3 */\n minItems?: number;\n className?: string;\n}\n\nfunction ActivityPill({ listing, getHref }: { listing: ApiOrder; getHref: (order: ApiOrder) => string }) {\n const [imgError, setImgError] = useState(false);\n const image = listing.token?.image && !imgError ? ipfsToHttp(listing.token.image) : null;\n\n return (\n <Link\n href={getHref(listing)}\n className=\"flex-shrink-0 flex items-center gap-2 rounded-xl border border-border bg-card px-3 py-2 hover:bg-muted/60 active:scale-[0.98] transition-all duration-150 group\"\n >\n <div className=\"h-8 w-8 rounded-lg overflow-hidden bg-muted shrink-0\">\n {image ? (\n <img\n src={image}\n alt=\"\"\n loading=\"lazy\"\n className=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-300\"\n onError={() => setImgError(true)}\n />\n ) : (\n <div className=\"w-full h-full bg-gradient-to-br from-brand-purple/20 to-brand-blue/20\" />\n )}\n </div>\n <div className=\"min-w-0\">\n <p className=\"text-xs font-medium whitespace-nowrap max-w-[100px] truncate\">\n {listing.token?.name ?? `#${listing.nftTokenId}`}\n </p>\n {listing.price?.formatted && (\n <p className=\"text-[10px] font-bold text-brand-orange whitespace-nowrap flex items-center gap-0.5\">\n {listing.price.currency && <CurrencyIcon symbol={listing.price.currency} size={10} />}\n {formatDisplayPrice(listing.price.formatted)} {listing.price.currency}\n </p>\n )}\n </div>\n </Link>\n );\n}\n\nexport function ActivityTicker({ orders, minItems = 3, className }: ActivityTickerProps) {\n if (orders.length < minItems) return null;\n\n const getHref = (order: ApiOrder) => `/asset/${order.nftContract}/${order.nftTokenId}`;\n\n return (\n <div className={cn(className)}>\n <div className=\"relative overflow-hidden py-2.5\">\n <div\n className=\"flex gap-2 w-max px-2\"\n style={{ animation: \"scroll-strip 50s linear infinite\" }}\n onMouseEnter={(e) => (e.currentTarget.style.animationPlayState = \"paused\")}\n onMouseLeave={(e) => (e.currentTarget.style.animationPlayState = \"running\")}\n >\n {[...orders, ...orders].map((listing, i) => (\n <ActivityPill key={`${listing.orderHash}-${i}`} listing={listing} getHref={getHref} />\n ))}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";AA4BU,cAgBA,YAhBA;AA1BV,SAAS,gBAAgB;AACzB,OAAO,UAAU;AACjB,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,kBAAkB;AAC3B,SAAS,UAAU;AAUnB,SAAS,aAAa,EAAE,SAAS,QAAQ,GAAgE;AACvG,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,QAAM,QAAQ,QAAQ,OAAO,SAAS,CAAC,WAAW,WAAW,QAAQ,MAAM,KAAK,IAAI;AAEpF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAM,QAAQ,OAAO;AAAA,MACrB,WAAU;AAAA,MAEV;AAAA,4BAAC,SAAI,WAAU,wDACZ,kBACC;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,KAAI;AAAA,YACJ,SAAQ;AAAA,YACR,WAAU;AAAA,YACV,SAAS,MAAM,YAAY,IAAI;AAAA;AAAA,QACjC,IAEA,oBAAC,SAAI,WAAU,yEAAwE,GAE3F;AAAA,QACA,qBAAC,SAAI,WAAU,WACb;AAAA,8BAAC,OAAE,WAAU,gEACV,kBAAQ,OAAO,QAAQ,IAAI,QAAQ,UAAU,IAChD;AAAA,UACC,QAAQ,OAAO,aACd,qBAAC,OAAE,WAAU,uFACV;AAAA,oBAAQ,MAAM,YAAY,oBAAC,gBAAa,QAAQ,QAAQ,MAAM,UAAU,MAAM,IAAI;AAAA,YAClF,mBAAmB,QAAQ,MAAM,SAAS;AAAA,YAAE;AAAA,YAAE,QAAQ,MAAM;AAAA,aAC/D;AAAA,WAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,eAAe,EAAE,QAAQ,WAAW,GAAG,UAAU,GAAwB;AACvF,MAAI,OAAO,SAAS,SAAU,QAAO;AAErC,QAAM,UAAU,CAAC,UAAoB,UAAU,MAAM,WAAW,IAAI,MAAM,UAAU;AAEpF,SACE,oBAAC,SAAI,WAAW,GAAG,SAAS,GAC1B,8BAAC,SAAI,WAAU,mCACb;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,WAAW,mCAAmC;AAAA,MACvD,cAAc,CAAC,MAAO,EAAE,cAAc,MAAM,qBAAqB;AAAA,MACjE,cAAc,CAAC,MAAO,EAAE,cAAc,MAAM,qBAAqB;AAAA,MAEhE,WAAC,GAAG,QAAQ,GAAG,MAAM,EAAE,IAAI,CAAC,SAAS,MACpC,oBAAC,gBAA+C,SAAkB,WAA/C,GAAG,QAAQ,SAAS,IAAI,CAAC,EAAwC,CACrF;AAAA;AAAA,EACH,GACF,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/activity-ticker.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"next/link\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { cn } from \"../utils/cn.js\";\nimport type { ApiOrder } from \"@medialane/sdk\";\n\nexport interface ActivityTickerProps {\n orders: ApiOrder[];\n /** Hide ticker if fewer items than this threshold. Default: 3 */\n minItems?: number;\n className?: string;\n getHref?: (order: ApiOrder) => string;\n}\n\nfunction ActivityPill({ listing, getHref }: { listing: ApiOrder; getHref: (order: ApiOrder) => string }) {\n const [imgError, setImgError] = useState(false);\n const image = listing.token?.image && !imgError ? ipfsToHttp(listing.token.image) : null;\n\n return (\n <Link\n href={getHref(listing)}\n className=\"flex-shrink-0 flex items-center gap-2 rounded-xl border border-border bg-card px-3 py-2 hover:bg-muted/60 active:scale-[0.98] transition-all duration-150 group\"\n >\n <div className=\"h-8 w-8 rounded-lg overflow-hidden bg-muted shrink-0\">\n {image ? (\n <img\n src={image}\n alt=\"\"\n loading=\"lazy\"\n className=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-300\"\n onError={() => setImgError(true)}\n />\n ) : (\n <div className=\"w-full h-full bg-gradient-to-br from-brand-purple/20 to-brand-blue/20\" />\n )}\n </div>\n <div className=\"min-w-0\">\n <p className=\"text-xs font-medium whitespace-nowrap max-w-[100px] truncate\">\n {listing.token?.name ?? `#${listing.nftTokenId}`}\n </p>\n {listing.price?.formatted && (\n <p className=\"text-[10px] font-bold text-brand-orange whitespace-nowrap flex items-center gap-0.5\">\n {listing.price.currency && <CurrencyIcon symbol={listing.price.currency} size={10} />}\n {formatDisplayPrice(listing.price.formatted)} {listing.price.currency}\n </p>\n )}\n </div>\n </Link>\n );\n}\n\nexport function ActivityTicker({ orders, minItems = 3, className, getHref = (o) => `/asset/${o.nftContract}/${o.nftTokenId}` }: ActivityTickerProps) {\n if (orders.length < minItems) return null;\n\n return (\n <div className={cn(className)}>\n <div className=\"relative overflow-hidden py-2.5\">\n <div\n className=\"flex gap-2 w-max px-2\"\n style={{ animation: \"scroll-strip 50s linear infinite\" }}\n onMouseEnter={(e) => (e.currentTarget.style.animationPlayState = \"paused\")}\n onMouseLeave={(e) => (e.currentTarget.style.animationPlayState = \"running\")}\n >\n {[...orders, ...orders].map((listing, i) => (\n <ActivityPill key={`${listing.orderHash}-${i}`} listing={listing} getHref={getHref} />\n ))}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";AA6BU,cAgBA,YAhBA;AA3BV,SAAS,gBAAgB;AACzB,OAAO,UAAU;AACjB,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,kBAAkB;AAC3B,SAAS,UAAU;AAWnB,SAAS,aAAa,EAAE,SAAS,QAAQ,GAAgE;AACvG,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,QAAM,QAAQ,QAAQ,OAAO,SAAS,CAAC,WAAW,WAAW,QAAQ,MAAM,KAAK,IAAI;AAEpF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAM,QAAQ,OAAO;AAAA,MACrB,WAAU;AAAA,MAEV;AAAA,4BAAC,SAAI,WAAU,wDACZ,kBACC;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,KAAI;AAAA,YACJ,SAAQ;AAAA,YACR,WAAU;AAAA,YACV,SAAS,MAAM,YAAY,IAAI;AAAA;AAAA,QACjC,IAEA,oBAAC,SAAI,WAAU,yEAAwE,GAE3F;AAAA,QACA,qBAAC,SAAI,WAAU,WACb;AAAA,8BAAC,OAAE,WAAU,gEACV,kBAAQ,OAAO,QAAQ,IAAI,QAAQ,UAAU,IAChD;AAAA,UACC,QAAQ,OAAO,aACd,qBAAC,OAAE,WAAU,uFACV;AAAA,oBAAQ,MAAM,YAAY,oBAAC,gBAAa,QAAQ,QAAQ,MAAM,UAAU,MAAM,IAAI;AAAA,YAClF,mBAAmB,QAAQ,MAAM,SAAS;AAAA,YAAE;AAAA,YAAE,QAAQ,MAAM;AAAA,aAC/D;AAAA,WAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,eAAe,EAAE,QAAQ,WAAW,GAAG,WAAW,UAAU,CAAC,MAAM,UAAU,EAAE,WAAW,IAAI,EAAE,UAAU,GAAG,GAAwB;AACnJ,MAAI,OAAO,SAAS,SAAU,QAAO;AAErC,SACE,oBAAC,SAAI,WAAW,GAAG,SAAS,GAC1B,8BAAC,SAAI,WAAU,mCACb;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,WAAW,mCAAmC;AAAA,MACvD,cAAc,CAAC,MAAO,EAAE,cAAc,MAAM,qBAAqB;AAAA,MACjE,cAAc,CAAC,MAAO,EAAE,cAAc,MAAM,qBAAqB;AAAA,MAEhE,WAAC,GAAG,QAAQ,GAAG,MAAM,EAAE,IAAI,CAAC,SAAS,MACpC,oBAAC,gBAA+C,SAAkB,WAA/C,GAAG,QAAQ,SAAS,IAAI,CAAC,EAAwC,CACrF;AAAA;AAAA,EACH,GACF,GACF;AAEJ;","names":[]}
@@ -78,15 +78,17 @@ function DiscoverCollectionsStrip({
78
78
  collections,
79
79
  isLoading,
80
80
  getHref,
81
- allCollectionsHref = "/collections"
81
+ allCollectionsHref = "/collections",
82
+ sectionLabel = "NFT",
83
+ title = "Collections"
82
84
  }) {
83
85
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_motion_primitives.FadeIn, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-3", children: [
84
86
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center justify-between", children: [
85
87
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
86
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "section-label", children: "NFT" }),
88
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "section-label", children: sectionLabel }),
87
89
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2 mt-0.5", children: [
88
90
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Layers, { className: "h-4 w-4 text-brand-blue" }),
89
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "text-lg font-bold", children: "Collections" })
91
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "text-lg font-bold", children: title })
90
92
  ] })
91
93
  ] }),
92
94
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/discover-collections-strip.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { Layers, ArrowRight } from \"lucide-react\";\nimport { FadeIn } from \"./motion-primitives.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport type { ApiCollection } from \"@medialane/sdk\";\n\nexport interface DiscoverCollectionsStripProps {\n collections: ApiCollection[];\n isLoading: boolean;\n getHref: (collection: ApiCollection) => string;\n allCollectionsHref?: string;\n}\n\nfunction CollectionChipSkeleton() {\n return (\n <div className=\"shrink-0 w-80 rounded-xl border border-border overflow-hidden\">\n <div className=\"aspect-square w-full bg-muted animate-pulse\" />\n <div className=\"p-3 space-y-1.5\">\n <div className=\"h-3.5 w-28 bg-muted animate-pulse rounded\" />\n <div className=\"h-3 w-16 bg-muted animate-pulse rounded\" />\n </div>\n </div>\n );\n}\n\nfunction CollectionChip({\n collection,\n href,\n}: {\n collection: ApiCollection;\n href: string;\n}) {\n const [imgError, setImgError] = useState(false);\n const image = collection.image && !imgError ? ipfsToHttp(collection.image) : null;\n const initial = (collection.name ?? \"?\").charAt(0).toUpperCase();\n\n return (\n <a\n href={href}\n className=\"block shrink-0 w-80 snap-start active:scale-[0.97] transition-transform duration-150\"\n >\n <div className=\"rounded-xl border border-border overflow-hidden group bg-card hover:border-border/80 transition-colors\">\n <div className=\"aspect-square bg-muted relative overflow-hidden\">\n {image ? (\n <img\n src={image}\n alt={collection.name ?? \"\"}\n loading=\"lazy\"\n className=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-500\"\n onError={() => setImgError(true)}\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-5xl font-black text-white/10 select-none\">{initial}</span>\n </div>\n )}\n </div>\n <div className=\"p-3 space-y-0.5\">\n <p className=\"text-sm font-semibold truncate\">{collection.name ?? \"Unnamed\"}</p>\n <div className=\"flex items-center justify-between text-xs text-muted-foreground\">\n <span>{collection.totalSupply ?? 0} items</span>\n {collection.floorPrice && (\n <span className=\"font-semibold text-brand-orange\">\n {formatDisplayPrice(collection.floorPrice)}\n </span>\n )}\n </div>\n </div>\n </div>\n </a>\n );\n}\n\nexport function DiscoverCollectionsStrip({\n collections,\n isLoading,\n getHref,\n allCollectionsHref = \"/collections\",\n}: DiscoverCollectionsStripProps) {\n return (\n <FadeIn>\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"section-label\">NFT</p>\n <div className=\"flex items-center gap-2 mt-0.5\">\n <Layers className=\"h-4 w-4 text-brand-blue\" />\n <h2 className=\"text-lg font-bold\">Collections</h2>\n </div>\n </div>\n <a\n href={allCollectionsHref}\n className=\"inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground px-3 py-1.5 rounded-md hover:bg-accent transition-colors\"\n >\n View all <ArrowRight className=\"h-3.5 w-3.5\" />\n </a>\n </div>\n <div className=\"overflow-x-auto scrollbar-hide snap-x snap-mandatory -mx-4 px-4 md:mx-0 md:px-0\">\n <div className=\"flex gap-3 w-max pb-1\">\n {isLoading\n ? Array.from({ length: 6 }).map((_, i) => <CollectionChipSkeleton key={i} />)\n : collections.map((col) => (\n <CollectionChip key={col.contractAddress} collection={col} href={getHref(col)} />\n ))}\n </div>\n </div>\n </div>\n </FadeIn>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBM;AAjBN,mBAAyB;AACzB,0BAAmC;AACnC,+BAAuB;AACvB,kBAA2B;AAC3B,oBAAmC;AAUnC,SAAS,yBAAyB;AAChC,SACE,6CAAC,SAAI,WAAU,iEACb;AAAA,gDAAC,SAAI,WAAU,+CAA8C;AAAA,IAC7D,6CAAC,SAAI,WAAU,mBACb;AAAA,kDAAC,SAAI,WAAU,6CAA4C;AAAA,MAC3D,4CAAC,SAAI,WAAU,2CAA0C;AAAA,OAC3D;AAAA,KACF;AAEJ;AAEA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA;AACF,GAGG;AACD,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,KAAK;AAC9C,QAAM,QAAQ,WAAW,SAAS,CAAC,eAAW,wBAAW,WAAW,KAAK,IAAI;AAC7E,QAAM,WAAW,WAAW,QAAQ,KAAK,OAAO,CAAC,EAAE,YAAY;AAE/D,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAU;AAAA,MAEV,uDAAC,SAAI,WAAU,0GACb;AAAA,oDAAC,SAAI,WAAU,mDACZ,kBACC;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,KAAK,WAAW,QAAQ;AAAA,YACxB,SAAQ;AAAA,YACR,WAAU;AAAA,YACV,SAAS,MAAM,YAAY,IAAI;AAAA;AAAA,QACjC,IAEA,4CAAC,SAAI,WAAU,+HACb,sDAAC,UAAK,WAAU,iDAAiD,mBAAQ,GAC3E,GAEJ;AAAA,QACA,6CAAC,SAAI,WAAU,mBACb;AAAA,sDAAC,OAAE,WAAU,kCAAkC,qBAAW,QAAQ,WAAU;AAAA,UAC5E,6CAAC,SAAI,WAAU,mEACb;AAAA,yDAAC,UAAM;AAAA,yBAAW,eAAe;AAAA,cAAE;AAAA,eAAM;AAAA,YACxC,WAAW,cACV,4CAAC,UAAK,WAAU,mCACb,gDAAmB,WAAW,UAAU,GAC3C;AAAA,aAEJ;AAAA,WACF;AAAA,SACF;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,yBAAyB;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA,qBAAqB;AACvB,GAAkC;AAChC,SACE,4CAAC,mCACC,uDAAC,SAAI,WAAU,aACb;AAAA,iDAAC,SAAI,WAAU,qCACb;AAAA,mDAAC,SACC;AAAA,oDAAC,OAAE,WAAU,iBAAgB,iBAAG;AAAA,QAChC,6CAAC,SAAI,WAAU,kCACb;AAAA,sDAAC,8BAAO,WAAU,2BAA0B;AAAA,UAC5C,4CAAC,QAAG,WAAU,qBAAoB,yBAAW;AAAA,WAC/C;AAAA,SACF;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,MAAM;AAAA,UACN,WAAU;AAAA,UACX;AAAA;AAAA,YACU,4CAAC,kCAAW,WAAU,eAAc;AAAA;AAAA;AAAA,MAC/C;AAAA,OACF;AAAA,IACA,4CAAC,SAAI,WAAU,mFACb,sDAAC,SAAI,WAAU,yBACZ,sBACG,MAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,MAAM,4CAAC,4BAA4B,CAAG,CAAE,IAC1E,YAAY,IAAI,CAAC,QACf,4CAAC,kBAAyC,YAAY,KAAK,MAAM,QAAQ,GAAG,KAAvD,IAAI,eAAsD,CAChF,GACP,GACF;AAAA,KACF,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/discover-collections-strip.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { Layers, ArrowRight } from \"lucide-react\";\nimport { FadeIn } from \"./motion-primitives.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport type { ApiCollection } from \"@medialane/sdk\";\n\nexport interface DiscoverCollectionsStripProps {\n collections: ApiCollection[];\n isLoading: boolean;\n getHref: (collection: ApiCollection) => string;\n allCollectionsHref?: string;\n sectionLabel?: string;\n title?: string;\n}\n\nfunction CollectionChipSkeleton() {\n return (\n <div className=\"shrink-0 w-80 rounded-xl border border-border overflow-hidden\">\n <div className=\"aspect-square w-full bg-muted animate-pulse\" />\n <div className=\"p-3 space-y-1.5\">\n <div className=\"h-3.5 w-28 bg-muted animate-pulse rounded\" />\n <div className=\"h-3 w-16 bg-muted animate-pulse rounded\" />\n </div>\n </div>\n );\n}\n\nfunction CollectionChip({\n collection,\n href,\n}: {\n collection: ApiCollection;\n href: string;\n}) {\n const [imgError, setImgError] = useState(false);\n const image = collection.image && !imgError ? ipfsToHttp(collection.image) : null;\n const initial = (collection.name ?? \"?\").charAt(0).toUpperCase();\n\n return (\n <a\n href={href}\n className=\"block shrink-0 w-80 snap-start active:scale-[0.97] transition-transform duration-150\"\n >\n <div className=\"rounded-xl border border-border overflow-hidden group bg-card hover:border-border/80 transition-colors\">\n <div className=\"aspect-square bg-muted relative overflow-hidden\">\n {image ? (\n <img\n src={image}\n alt={collection.name ?? \"\"}\n loading=\"lazy\"\n className=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-500\"\n onError={() => setImgError(true)}\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-5xl font-black text-white/10 select-none\">{initial}</span>\n </div>\n )}\n </div>\n <div className=\"p-3 space-y-0.5\">\n <p className=\"text-sm font-semibold truncate\">{collection.name ?? \"Unnamed\"}</p>\n <div className=\"flex items-center justify-between text-xs text-muted-foreground\">\n <span>{collection.totalSupply ?? 0} items</span>\n {collection.floorPrice && (\n <span className=\"font-semibold text-brand-orange\">\n {formatDisplayPrice(collection.floorPrice)}\n </span>\n )}\n </div>\n </div>\n </div>\n </a>\n );\n}\n\nexport function DiscoverCollectionsStrip({\n collections,\n isLoading,\n getHref,\n allCollectionsHref = \"/collections\",\n sectionLabel = \"NFT\",\n title = \"Collections\",\n}: DiscoverCollectionsStripProps) {\n return (\n <FadeIn>\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"section-label\">{sectionLabel}</p>\n <div className=\"flex items-center gap-2 mt-0.5\">\n <Layers className=\"h-4 w-4 text-brand-blue\" />\n <h2 className=\"text-lg font-bold\">{title}</h2>\n </div>\n </div>\n <a\n href={allCollectionsHref}\n className=\"inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground px-3 py-1.5 rounded-md hover:bg-accent transition-colors\"\n >\n View all <ArrowRight className=\"h-3.5 w-3.5\" />\n </a>\n </div>\n <div className=\"overflow-x-auto scrollbar-hide snap-x snap-mandatory -mx-4 px-4 md:mx-0 md:px-0\">\n <div className=\"flex gap-3 w-max pb-1\">\n {isLoading\n ? Array.from({ length: 6 }).map((_, i) => <CollectionChipSkeleton key={i} />)\n : collections.map((col) => (\n <CollectionChip key={col.contractAddress} collection={col} href={getHref(col)} />\n ))}\n </div>\n </div>\n </div>\n </FadeIn>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAqBM;AAnBN,mBAAyB;AACzB,0BAAmC;AACnC,+BAAuB;AACvB,kBAA2B;AAC3B,oBAAmC;AAYnC,SAAS,yBAAyB;AAChC,SACE,6CAAC,SAAI,WAAU,iEACb;AAAA,gDAAC,SAAI,WAAU,+CAA8C;AAAA,IAC7D,6CAAC,SAAI,WAAU,mBACb;AAAA,kDAAC,SAAI,WAAU,6CAA4C;AAAA,MAC3D,4CAAC,SAAI,WAAU,2CAA0C;AAAA,OAC3D;AAAA,KACF;AAEJ;AAEA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA;AACF,GAGG;AACD,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,KAAK;AAC9C,QAAM,QAAQ,WAAW,SAAS,CAAC,eAAW,wBAAW,WAAW,KAAK,IAAI;AAC7E,QAAM,WAAW,WAAW,QAAQ,KAAK,OAAO,CAAC,EAAE,YAAY;AAE/D,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAU;AAAA,MAEV,uDAAC,SAAI,WAAU,0GACb;AAAA,oDAAC,SAAI,WAAU,mDACZ,kBACC;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,KAAK,WAAW,QAAQ;AAAA,YACxB,SAAQ;AAAA,YACR,WAAU;AAAA,YACV,SAAS,MAAM,YAAY,IAAI;AAAA;AAAA,QACjC,IAEA,4CAAC,SAAI,WAAU,+HACb,sDAAC,UAAK,WAAU,iDAAiD,mBAAQ,GAC3E,GAEJ;AAAA,QACA,6CAAC,SAAI,WAAU,mBACb;AAAA,sDAAC,OAAE,WAAU,kCAAkC,qBAAW,QAAQ,WAAU;AAAA,UAC5E,6CAAC,SAAI,WAAU,mEACb;AAAA,yDAAC,UAAM;AAAA,yBAAW,eAAe;AAAA,cAAE;AAAA,eAAM;AAAA,YACxC,WAAW,cACV,4CAAC,UAAK,WAAU,mCACb,gDAAmB,WAAW,UAAU,GAC3C;AAAA,aAEJ;AAAA,WACF;AAAA,SACF;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,yBAAyB;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA,qBAAqB;AAAA,EACrB,eAAe;AAAA,EACf,QAAQ;AACV,GAAkC;AAChC,SACE,4CAAC,mCACC,uDAAC,SAAI,WAAU,aACb;AAAA,iDAAC,SAAI,WAAU,qCACb;AAAA,mDAAC,SACC;AAAA,oDAAC,OAAE,WAAU,iBAAiB,wBAAa;AAAA,QAC3C,6CAAC,SAAI,WAAU,kCACb;AAAA,sDAAC,8BAAO,WAAU,2BAA0B;AAAA,UAC5C,4CAAC,QAAG,WAAU,qBAAqB,iBAAM;AAAA,WAC3C;AAAA,SACF;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,MAAM;AAAA,UACN,WAAU;AAAA,UACX;AAAA;AAAA,YACU,4CAAC,kCAAW,WAAU,eAAc;AAAA;AAAA;AAAA,MAC/C;AAAA,OACF;AAAA,IACA,4CAAC,SAAI,WAAU,mFACb,sDAAC,SAAI,WAAU,yBACZ,sBACG,MAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,MAAM,4CAAC,4BAA4B,CAAG,CAAE,IAC1E,YAAY,IAAI,CAAC,QACf,4CAAC,kBAAyC,YAAY,KAAK,MAAM,QAAQ,GAAG,KAAvD,IAAI,eAAsD,CAChF,GACP,GACF;AAAA,KACF,GACF;AAEJ;","names":[]}
@@ -6,7 +6,9 @@ interface DiscoverCollectionsStripProps {
6
6
  isLoading: boolean;
7
7
  getHref: (collection: ApiCollection) => string;
8
8
  allCollectionsHref?: string;
9
+ sectionLabel?: string;
10
+ title?: string;
9
11
  }
10
- declare function DiscoverCollectionsStrip({ collections, isLoading, getHref, allCollectionsHref, }: DiscoverCollectionsStripProps): react_jsx_runtime.JSX.Element;
12
+ declare function DiscoverCollectionsStrip({ collections, isLoading, getHref, allCollectionsHref, sectionLabel, title, }: DiscoverCollectionsStripProps): react_jsx_runtime.JSX.Element;
11
13
 
12
14
  export { DiscoverCollectionsStrip, type DiscoverCollectionsStripProps };
@@ -6,7 +6,9 @@ interface DiscoverCollectionsStripProps {
6
6
  isLoading: boolean;
7
7
  getHref: (collection: ApiCollection) => string;
8
8
  allCollectionsHref?: string;
9
+ sectionLabel?: string;
10
+ title?: string;
9
11
  }
10
- declare function DiscoverCollectionsStrip({ collections, isLoading, getHref, allCollectionsHref, }: DiscoverCollectionsStripProps): react_jsx_runtime.JSX.Element;
12
+ declare function DiscoverCollectionsStrip({ collections, isLoading, getHref, allCollectionsHref, sectionLabel, title, }: DiscoverCollectionsStripProps): react_jsx_runtime.JSX.Element;
11
13
 
12
14
  export { DiscoverCollectionsStrip, type DiscoverCollectionsStripProps };
@@ -55,15 +55,17 @@ function DiscoverCollectionsStrip({
55
55
  collections,
56
56
  isLoading,
57
57
  getHref,
58
- allCollectionsHref = "/collections"
58
+ allCollectionsHref = "/collections",
59
+ sectionLabel = "NFT",
60
+ title = "Collections"
59
61
  }) {
60
62
  return /* @__PURE__ */ jsx(FadeIn, { children: /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
61
63
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
62
64
  /* @__PURE__ */ jsxs("div", { children: [
63
- /* @__PURE__ */ jsx("p", { className: "section-label", children: "NFT" }),
65
+ /* @__PURE__ */ jsx("p", { className: "section-label", children: sectionLabel }),
64
66
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-0.5", children: [
65
67
  /* @__PURE__ */ jsx(Layers, { className: "h-4 w-4 text-brand-blue" }),
66
- /* @__PURE__ */ jsx("h2", { className: "text-lg font-bold", children: "Collections" })
68
+ /* @__PURE__ */ jsx("h2", { className: "text-lg font-bold", children: title })
67
69
  ] })
68
70
  ] }),
69
71
  /* @__PURE__ */ jsxs(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/discover-collections-strip.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { Layers, ArrowRight } from \"lucide-react\";\nimport { FadeIn } from \"./motion-primitives.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport type { ApiCollection } from \"@medialane/sdk\";\n\nexport interface DiscoverCollectionsStripProps {\n collections: ApiCollection[];\n isLoading: boolean;\n getHref: (collection: ApiCollection) => string;\n allCollectionsHref?: string;\n}\n\nfunction CollectionChipSkeleton() {\n return (\n <div className=\"shrink-0 w-80 rounded-xl border border-border overflow-hidden\">\n <div className=\"aspect-square w-full bg-muted animate-pulse\" />\n <div className=\"p-3 space-y-1.5\">\n <div className=\"h-3.5 w-28 bg-muted animate-pulse rounded\" />\n <div className=\"h-3 w-16 bg-muted animate-pulse rounded\" />\n </div>\n </div>\n );\n}\n\nfunction CollectionChip({\n collection,\n href,\n}: {\n collection: ApiCollection;\n href: string;\n}) {\n const [imgError, setImgError] = useState(false);\n const image = collection.image && !imgError ? ipfsToHttp(collection.image) : null;\n const initial = (collection.name ?? \"?\").charAt(0).toUpperCase();\n\n return (\n <a\n href={href}\n className=\"block shrink-0 w-80 snap-start active:scale-[0.97] transition-transform duration-150\"\n >\n <div className=\"rounded-xl border border-border overflow-hidden group bg-card hover:border-border/80 transition-colors\">\n <div className=\"aspect-square bg-muted relative overflow-hidden\">\n {image ? (\n <img\n src={image}\n alt={collection.name ?? \"\"}\n loading=\"lazy\"\n className=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-500\"\n onError={() => setImgError(true)}\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-5xl font-black text-white/10 select-none\">{initial}</span>\n </div>\n )}\n </div>\n <div className=\"p-3 space-y-0.5\">\n <p className=\"text-sm font-semibold truncate\">{collection.name ?? \"Unnamed\"}</p>\n <div className=\"flex items-center justify-between text-xs text-muted-foreground\">\n <span>{collection.totalSupply ?? 0} items</span>\n {collection.floorPrice && (\n <span className=\"font-semibold text-brand-orange\">\n {formatDisplayPrice(collection.floorPrice)}\n </span>\n )}\n </div>\n </div>\n </div>\n </a>\n );\n}\n\nexport function DiscoverCollectionsStrip({\n collections,\n isLoading,\n getHref,\n allCollectionsHref = \"/collections\",\n}: DiscoverCollectionsStripProps) {\n return (\n <FadeIn>\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"section-label\">NFT</p>\n <div className=\"flex items-center gap-2 mt-0.5\">\n <Layers className=\"h-4 w-4 text-brand-blue\" />\n <h2 className=\"text-lg font-bold\">Collections</h2>\n </div>\n </div>\n <a\n href={allCollectionsHref}\n className=\"inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground px-3 py-1.5 rounded-md hover:bg-accent transition-colors\"\n >\n View all <ArrowRight className=\"h-3.5 w-3.5\" />\n </a>\n </div>\n <div className=\"overflow-x-auto scrollbar-hide snap-x snap-mandatory -mx-4 px-4 md:mx-0 md:px-0\">\n <div className=\"flex gap-3 w-max pb-1\">\n {isLoading\n ? Array.from({ length: 6 }).map((_, i) => <CollectionChipSkeleton key={i} />)\n : collections.map((col) => (\n <CollectionChip key={col.contractAddress} collection={col} href={getHref(col)} />\n ))}\n </div>\n </div>\n </div>\n </FadeIn>\n );\n}\n"],"mappings":";AAmBM,cACA,YADA;AAjBN,SAAS,gBAAgB;AACzB,SAAS,QAAQ,kBAAkB;AACnC,SAAS,cAAc;AACvB,SAAS,kBAAkB;AAC3B,SAAS,0BAA0B;AAUnC,SAAS,yBAAyB;AAChC,SACE,qBAAC,SAAI,WAAU,iEACb;AAAA,wBAAC,SAAI,WAAU,+CAA8C;AAAA,IAC7D,qBAAC,SAAI,WAAU,mBACb;AAAA,0BAAC,SAAI,WAAU,6CAA4C;AAAA,MAC3D,oBAAC,SAAI,WAAU,2CAA0C;AAAA,OAC3D;AAAA,KACF;AAEJ;AAEA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA;AACF,GAGG;AACD,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,QAAM,QAAQ,WAAW,SAAS,CAAC,WAAW,WAAW,WAAW,KAAK,IAAI;AAC7E,QAAM,WAAW,WAAW,QAAQ,KAAK,OAAO,CAAC,EAAE,YAAY;AAE/D,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAU;AAAA,MAEV,+BAAC,SAAI,WAAU,0GACb;AAAA,4BAAC,SAAI,WAAU,mDACZ,kBACC;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,KAAK,WAAW,QAAQ;AAAA,YACxB,SAAQ;AAAA,YACR,WAAU;AAAA,YACV,SAAS,MAAM,YAAY,IAAI;AAAA;AAAA,QACjC,IAEA,oBAAC,SAAI,WAAU,+HACb,8BAAC,UAAK,WAAU,iDAAiD,mBAAQ,GAC3E,GAEJ;AAAA,QACA,qBAAC,SAAI,WAAU,mBACb;AAAA,8BAAC,OAAE,WAAU,kCAAkC,qBAAW,QAAQ,WAAU;AAAA,UAC5E,qBAAC,SAAI,WAAU,mEACb;AAAA,iCAAC,UAAM;AAAA,yBAAW,eAAe;AAAA,cAAE;AAAA,eAAM;AAAA,YACxC,WAAW,cACV,oBAAC,UAAK,WAAU,mCACb,6BAAmB,WAAW,UAAU,GAC3C;AAAA,aAEJ;AAAA,WACF;AAAA,SACF;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,yBAAyB;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA,qBAAqB;AACvB,GAAkC;AAChC,SACE,oBAAC,UACC,+BAAC,SAAI,WAAU,aACb;AAAA,yBAAC,SAAI,WAAU,qCACb;AAAA,2BAAC,SACC;AAAA,4BAAC,OAAE,WAAU,iBAAgB,iBAAG;AAAA,QAChC,qBAAC,SAAI,WAAU,kCACb;AAAA,8BAAC,UAAO,WAAU,2BAA0B;AAAA,UAC5C,oBAAC,QAAG,WAAU,qBAAoB,yBAAW;AAAA,WAC/C;AAAA,SACF;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,MAAM;AAAA,UACN,WAAU;AAAA,UACX;AAAA;AAAA,YACU,oBAAC,cAAW,WAAU,eAAc;AAAA;AAAA;AAAA,MAC/C;AAAA,OACF;AAAA,IACA,oBAAC,SAAI,WAAU,mFACb,8BAAC,SAAI,WAAU,yBACZ,sBACG,MAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,MAAM,oBAAC,4BAA4B,CAAG,CAAE,IAC1E,YAAY,IAAI,CAAC,QACf,oBAAC,kBAAyC,YAAY,KAAK,MAAM,QAAQ,GAAG,KAAvD,IAAI,eAAsD,CAChF,GACP,GACF;AAAA,KACF,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/discover-collections-strip.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { Layers, ArrowRight } from \"lucide-react\";\nimport { FadeIn } from \"./motion-primitives.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport type { ApiCollection } from \"@medialane/sdk\";\n\nexport interface DiscoverCollectionsStripProps {\n collections: ApiCollection[];\n isLoading: boolean;\n getHref: (collection: ApiCollection) => string;\n allCollectionsHref?: string;\n sectionLabel?: string;\n title?: string;\n}\n\nfunction CollectionChipSkeleton() {\n return (\n <div className=\"shrink-0 w-80 rounded-xl border border-border overflow-hidden\">\n <div className=\"aspect-square w-full bg-muted animate-pulse\" />\n <div className=\"p-3 space-y-1.5\">\n <div className=\"h-3.5 w-28 bg-muted animate-pulse rounded\" />\n <div className=\"h-3 w-16 bg-muted animate-pulse rounded\" />\n </div>\n </div>\n );\n}\n\nfunction CollectionChip({\n collection,\n href,\n}: {\n collection: ApiCollection;\n href: string;\n}) {\n const [imgError, setImgError] = useState(false);\n const image = collection.image && !imgError ? ipfsToHttp(collection.image) : null;\n const initial = (collection.name ?? \"?\").charAt(0).toUpperCase();\n\n return (\n <a\n href={href}\n className=\"block shrink-0 w-80 snap-start active:scale-[0.97] transition-transform duration-150\"\n >\n <div className=\"rounded-xl border border-border overflow-hidden group bg-card hover:border-border/80 transition-colors\">\n <div className=\"aspect-square bg-muted relative overflow-hidden\">\n {image ? (\n <img\n src={image}\n alt={collection.name ?? \"\"}\n loading=\"lazy\"\n className=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-500\"\n onError={() => setImgError(true)}\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-5xl font-black text-white/10 select-none\">{initial}</span>\n </div>\n )}\n </div>\n <div className=\"p-3 space-y-0.5\">\n <p className=\"text-sm font-semibold truncate\">{collection.name ?? \"Unnamed\"}</p>\n <div className=\"flex items-center justify-between text-xs text-muted-foreground\">\n <span>{collection.totalSupply ?? 0} items</span>\n {collection.floorPrice && (\n <span className=\"font-semibold text-brand-orange\">\n {formatDisplayPrice(collection.floorPrice)}\n </span>\n )}\n </div>\n </div>\n </div>\n </a>\n );\n}\n\nexport function DiscoverCollectionsStrip({\n collections,\n isLoading,\n getHref,\n allCollectionsHref = \"/collections\",\n sectionLabel = \"NFT\",\n title = \"Collections\",\n}: DiscoverCollectionsStripProps) {\n return (\n <FadeIn>\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"section-label\">{sectionLabel}</p>\n <div className=\"flex items-center gap-2 mt-0.5\">\n <Layers className=\"h-4 w-4 text-brand-blue\" />\n <h2 className=\"text-lg font-bold\">{title}</h2>\n </div>\n </div>\n <a\n href={allCollectionsHref}\n className=\"inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground px-3 py-1.5 rounded-md hover:bg-accent transition-colors\"\n >\n View all <ArrowRight className=\"h-3.5 w-3.5\" />\n </a>\n </div>\n <div className=\"overflow-x-auto scrollbar-hide snap-x snap-mandatory -mx-4 px-4 md:mx-0 md:px-0\">\n <div className=\"flex gap-3 w-max pb-1\">\n {isLoading\n ? Array.from({ length: 6 }).map((_, i) => <CollectionChipSkeleton key={i} />)\n : collections.map((col) => (\n <CollectionChip key={col.contractAddress} collection={col} href={getHref(col)} />\n ))}\n </div>\n </div>\n </div>\n </FadeIn>\n );\n}\n"],"mappings":";AAqBM,cACA,YADA;AAnBN,SAAS,gBAAgB;AACzB,SAAS,QAAQ,kBAAkB;AACnC,SAAS,cAAc;AACvB,SAAS,kBAAkB;AAC3B,SAAS,0BAA0B;AAYnC,SAAS,yBAAyB;AAChC,SACE,qBAAC,SAAI,WAAU,iEACb;AAAA,wBAAC,SAAI,WAAU,+CAA8C;AAAA,IAC7D,qBAAC,SAAI,WAAU,mBACb;AAAA,0BAAC,SAAI,WAAU,6CAA4C;AAAA,MAC3D,oBAAC,SAAI,WAAU,2CAA0C;AAAA,OAC3D;AAAA,KACF;AAEJ;AAEA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA;AACF,GAGG;AACD,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,QAAM,QAAQ,WAAW,SAAS,CAAC,WAAW,WAAW,WAAW,KAAK,IAAI;AAC7E,QAAM,WAAW,WAAW,QAAQ,KAAK,OAAO,CAAC,EAAE,YAAY;AAE/D,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAU;AAAA,MAEV,+BAAC,SAAI,WAAU,0GACb;AAAA,4BAAC,SAAI,WAAU,mDACZ,kBACC;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,KAAK,WAAW,QAAQ;AAAA,YACxB,SAAQ;AAAA,YACR,WAAU;AAAA,YACV,SAAS,MAAM,YAAY,IAAI;AAAA;AAAA,QACjC,IAEA,oBAAC,SAAI,WAAU,+HACb,8BAAC,UAAK,WAAU,iDAAiD,mBAAQ,GAC3E,GAEJ;AAAA,QACA,qBAAC,SAAI,WAAU,mBACb;AAAA,8BAAC,OAAE,WAAU,kCAAkC,qBAAW,QAAQ,WAAU;AAAA,UAC5E,qBAAC,SAAI,WAAU,mEACb;AAAA,iCAAC,UAAM;AAAA,yBAAW,eAAe;AAAA,cAAE;AAAA,eAAM;AAAA,YACxC,WAAW,cACV,oBAAC,UAAK,WAAU,mCACb,6BAAmB,WAAW,UAAU,GAC3C;AAAA,aAEJ;AAAA,WACF;AAAA,SACF;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,yBAAyB;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA,qBAAqB;AAAA,EACrB,eAAe;AAAA,EACf,QAAQ;AACV,GAAkC;AAChC,SACE,oBAAC,UACC,+BAAC,SAAI,WAAU,aACb;AAAA,yBAAC,SAAI,WAAU,qCACb;AAAA,2BAAC,SACC;AAAA,4BAAC,OAAE,WAAU,iBAAiB,wBAAa;AAAA,QAC3C,qBAAC,SAAI,WAAU,kCACb;AAAA,8BAAC,UAAO,WAAU,2BAA0B;AAAA,UAC5C,oBAAC,QAAG,WAAU,qBAAqB,iBAAM;AAAA,WAC3C;AAAA,SACF;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,MAAM;AAAA,UACN,WAAU;AAAA,UACX;AAAA;AAAA,YACU,oBAAC,cAAW,WAAU,eAAc;AAAA;AAAA;AAAA,MAC/C;AAAA,OACF;AAAA,IACA,oBAAC,SAAI,WAAU,mFACb,8BAAC,SAAI,WAAU,yBACZ,sBACG,MAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,MAAM,oBAAC,4BAA4B,CAAG,CAAE,IAC1E,YAAY,IAAI,CAAC,QACf,oBAAC,kBAAyC,YAAY,KAAK,MAAM,QAAQ,GAAG,KAAvD,IAAI,eAAsD,CAChF,GACP,GACF;AAAA,KACF,GACF;AAEJ;","names":[]}
@@ -36,8 +36,8 @@ function CreatorChip({
36
36
  }) {
37
37
  const [avatarError, setAvatarError] = (0, import_react.useState)(false);
38
38
  const [bannerError, setBannerError] = (0, import_react.useState)(false);
39
- const bannerSrc = creator.bannerImage ?? creator.collectionImage ?? null;
40
- const avatarSrc = creator.avatarImage ?? creator.collectionImage ?? null;
39
+ const bannerSrc = creator.bannerImage ?? null;
40
+ const avatarSrc = creator.avatarImage ?? creator.bannerImage ?? null;
41
41
  const bannerUrl = bannerSrc && !bannerError ? (0, import_ipfs.ipfsToHttp)(bannerSrc) : null;
42
42
  const avatarUrl = avatarSrc && !avatarError ? (0, import_ipfs.ipfsToHttp)(avatarSrc) : null;
43
43
  const displayName = creator.displayName || `@${creator.username}`;
@@ -86,16 +86,18 @@ function DiscoverCreatorsStrip({
86
86
  creators,
87
87
  isLoading,
88
88
  getHref,
89
- allCreatorsHref = "/creators"
89
+ allCreatorsHref = "/creators",
90
+ sectionLabel = "Creator network",
91
+ title = "Creators"
90
92
  }) {
91
93
  if (!isLoading && creators.length === 0) return null;
92
94
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_motion_primitives.FadeIn, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-3", children: [
93
95
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center justify-between", children: [
94
96
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
95
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "section-label", children: "Creator network" }),
97
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "section-label", children: sectionLabel }),
96
98
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2 mt-0.5", children: [
97
99
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Users, { className: "h-4 w-4 text-brand-purple" }),
98
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "text-lg font-bold", children: "Creators" })
100
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "text-lg font-bold", children: title })
99
101
  ] })
100
102
  ] }),
101
103
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/discover-creators-strip.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { Users, ArrowRight, AtSign } from \"lucide-react\";\nimport { FadeIn } from \"./motion-primitives.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport type { ApiCreatorProfile } from \"@medialane/sdk\";\n\nexport interface DiscoverCreatorsStripProps {\n creators: ApiCreatorProfile[];\n isLoading: boolean;\n getHref: (creator: ApiCreatorProfile) => string;\n allCreatorsHref?: string;\n}\n\nfunction CreatorChipSkeleton() {\n return (\n <div className=\"shrink-0 w-64 aspect-[3/4] rounded-xl bg-muted animate-pulse\" />\n );\n}\n\nfunction CreatorChip({\n creator,\n href,\n}: {\n creator: ApiCreatorProfile;\n href: string;\n}) {\n const [avatarError, setAvatarError] = useState(false);\n const [bannerError, setBannerError] = useState(false);\n\n const bannerSrc = creator.bannerImage ?? creator.collectionImage ?? null;\n const avatarSrc = creator.avatarImage ?? creator.collectionImage ?? null;\n\n const bannerUrl = bannerSrc && !bannerError ? ipfsToHttp(bannerSrc) : null;\n const avatarUrl = avatarSrc && !avatarError ? ipfsToHttp(avatarSrc) : null;\n\n const displayName = creator.displayName || `@${creator.username}`;\n\n return (\n <a\n href={href}\n className=\"block shrink-0 w-64 snap-start active:scale-[0.97] transition-transform duration-150 select-none\"\n >\n <div className=\"relative aspect-[3/4] rounded-xl overflow-hidden bg-muted\">\n {bannerUrl && (\n <img\n src={bannerUrl}\n alt=\"\"\n aria-hidden\n loading=\"lazy\"\n className=\"absolute inset-0 w-full h-full object-cover\"\n onError={() => setBannerError(true)}\n />\n )}\n <div className=\"absolute inset-0 bg-gradient-to-t from-black/80 via-black/10 to-transparent\" />\n <div className=\"absolute bottom-0 inset-x-0 p-2.5 space-y-1.5\">\n <div className=\"h-8 w-8 rounded-full ring-2 ring-white/20 overflow-hidden bg-muted flex items-center justify-center\">\n {avatarUrl ? (\n <img\n src={avatarUrl}\n alt={displayName ?? \"\"}\n loading=\"lazy\"\n className=\"h-full w-full object-cover\"\n onError={() => setAvatarError(true)}\n />\n ) : (\n <span className=\"text-xs font-black text-white/60\">\n {(displayName ?? \"?\").charAt(0).toUpperCase()}\n </span>\n )}\n </div>\n <div>\n <p className=\"font-bold text-white text-xs truncate\">{displayName}</p>\n <p className=\"text-[10px] text-white/55 flex items-center gap-0.5\">\n <AtSign className=\"h-2 w-2 shrink-0\" />\n <span className=\"truncate\">{creator.username}</span>\n </p>\n </div>\n </div>\n </div>\n </a>\n );\n}\n\nexport function DiscoverCreatorsStrip({\n creators,\n isLoading,\n getHref,\n allCreatorsHref = \"/creators\",\n}: DiscoverCreatorsStripProps) {\n if (!isLoading && creators.length === 0) return null;\n\n return (\n <FadeIn>\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"section-label\">Creator network</p>\n <div className=\"flex items-center gap-2 mt-0.5\">\n <Users className=\"h-4 w-4 text-brand-purple\" />\n <h2 className=\"text-lg font-bold\">Creators</h2>\n </div>\n </div>\n <a\n href={allCreatorsHref}\n className=\"inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground px-3 py-1.5 rounded-md hover:bg-accent transition-colors\"\n >\n View all <ArrowRight className=\"h-3.5 w-3.5\" />\n </a>\n </div>\n <div className=\"overflow-x-auto scrollbar-hide snap-x snap-mandatory -mx-4 px-4 md:mx-0 md:px-0\">\n <div className=\"flex gap-3 w-max pb-1\">\n {isLoading\n ? Array.from({ length: 6 }).map((_, i) => <CreatorChipSkeleton key={i} />)\n : creators.map((c) => (\n <CreatorChip key={c.walletAddress} creator={c} href={getHref(c)} />\n ))}\n </div>\n </div>\n </div>\n </FadeIn>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBI;AAfJ,mBAAyB;AACzB,0BAA0C;AAC1C,+BAAuB;AACvB,kBAA2B;AAU3B,SAAS,sBAAsB;AAC7B,SACE,4CAAC,SAAI,WAAU,gEAA+D;AAElF;AAEA,SAAS,YAAY;AAAA,EACnB;AAAA,EACA;AACF,GAGG;AACD,QAAM,CAAC,aAAa,cAAc,QAAI,uBAAS,KAAK;AACpD,QAAM,CAAC,aAAa,cAAc,QAAI,uBAAS,KAAK;AAEpD,QAAM,YAAY,QAAQ,eAAe,QAAQ,mBAAmB;AACpE,QAAM,YAAY,QAAQ,eAAe,QAAQ,mBAAmB;AAEpE,QAAM,YAAY,aAAa,CAAC,kBAAc,wBAAW,SAAS,IAAI;AACtE,QAAM,YAAY,aAAa,CAAC,kBAAc,wBAAW,SAAS,IAAI;AAEtE,QAAM,cAAc,QAAQ,eAAe,IAAI,QAAQ,QAAQ;AAE/D,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAU;AAAA,MAEV,uDAAC,SAAI,WAAU,6DACZ;AAAA,qBACC;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,KAAI;AAAA,YACJ,eAAW;AAAA,YACX,SAAQ;AAAA,YACR,WAAU;AAAA,YACV,SAAS,MAAM,eAAe,IAAI;AAAA;AAAA,QACpC;AAAA,QAEF,4CAAC,SAAI,WAAU,+EAA8E;AAAA,QAC7F,6CAAC,SAAI,WAAU,iDACb;AAAA,sDAAC,SAAI,WAAU,uGACZ,sBACC;AAAA,YAAC;AAAA;AAAA,cACC,KAAK;AAAA,cACL,KAAK,eAAe;AAAA,cACpB,SAAQ;AAAA,cACR,WAAU;AAAA,cACV,SAAS,MAAM,eAAe,IAAI;AAAA;AAAA,UACpC,IAEA,4CAAC,UAAK,WAAU,oCACZ,0BAAe,KAAK,OAAO,CAAC,EAAE,YAAY,GAC9C,GAEJ;AAAA,UACA,6CAAC,SACC;AAAA,wDAAC,OAAE,WAAU,yCAAyC,uBAAY;AAAA,YAClE,6CAAC,OAAE,WAAU,uDACX;AAAA,0DAAC,8BAAO,WAAU,oBAAmB;AAAA,cACrC,4CAAC,UAAK,WAAU,YAAY,kBAAQ,UAAS;AAAA,eAC/C;AAAA,aACF;AAAA,WACF;AAAA,SACF;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA,kBAAkB;AACpB,GAA+B;AAC7B,MAAI,CAAC,aAAa,SAAS,WAAW,EAAG,QAAO;AAEhD,SACE,4CAAC,mCACC,uDAAC,SAAI,WAAU,aACb;AAAA,iDAAC,SAAI,WAAU,qCACb;AAAA,mDAAC,SACC;AAAA,oDAAC,OAAE,WAAU,iBAAgB,6BAAe;AAAA,QAC5C,6CAAC,SAAI,WAAU,kCACb;AAAA,sDAAC,6BAAM,WAAU,6BAA4B;AAAA,UAC7C,4CAAC,QAAG,WAAU,qBAAoB,sBAAQ;AAAA,WAC5C;AAAA,SACF;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,MAAM;AAAA,UACN,WAAU;AAAA,UACX;AAAA;AAAA,YACU,4CAAC,kCAAW,WAAU,eAAc;AAAA;AAAA;AAAA,MAC/C;AAAA,OACF;AAAA,IACA,4CAAC,SAAI,WAAU,mFACb,sDAAC,SAAI,WAAU,yBACZ,sBACG,MAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,MAAM,4CAAC,yBAAyB,CAAG,CAAE,IACvE,SAAS,IAAI,CAAC,MACZ,4CAAC,eAAkC,SAAS,GAAG,MAAM,QAAQ,CAAC,KAA5C,EAAE,aAA6C,CAClE,GACP,GACF;AAAA,KACF,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/discover-creators-strip.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { Users, ArrowRight, AtSign } from \"lucide-react\";\nimport { FadeIn } from \"./motion-primitives.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport type { ApiCreatorProfile } from \"@medialane/sdk\";\n\nexport interface DiscoverCreatorsStripProps {\n creators: ApiCreatorProfile[];\n isLoading: boolean;\n getHref: (creator: ApiCreatorProfile) => string;\n allCreatorsHref?: string;\n sectionLabel?: string;\n title?: string;\n}\n\nfunction CreatorChipSkeleton() {\n return (\n <div className=\"shrink-0 w-64 aspect-[3/4] rounded-xl bg-muted animate-pulse\" />\n );\n}\n\nfunction CreatorChip({\n creator,\n href,\n}: {\n creator: ApiCreatorProfile;\n href: string;\n}) {\n const [avatarError, setAvatarError] = useState(false);\n const [bannerError, setBannerError] = useState(false);\n\n const bannerSrc = creator.bannerImage ?? null;\n const avatarSrc = creator.avatarImage ?? creator.bannerImage ?? null;\n\n const bannerUrl = bannerSrc && !bannerError ? ipfsToHttp(bannerSrc) : null;\n const avatarUrl = avatarSrc && !avatarError ? ipfsToHttp(avatarSrc) : null;\n\n const displayName = creator.displayName || `@${creator.username}`;\n\n return (\n <a\n href={href}\n className=\"block shrink-0 w-64 snap-start active:scale-[0.97] transition-transform duration-150 select-none\"\n >\n <div className=\"relative aspect-[3/4] rounded-xl overflow-hidden bg-muted\">\n {bannerUrl && (\n <img\n src={bannerUrl}\n alt=\"\"\n aria-hidden\n loading=\"lazy\"\n className=\"absolute inset-0 w-full h-full object-cover\"\n onError={() => setBannerError(true)}\n />\n )}\n <div className=\"absolute inset-0 bg-gradient-to-t from-black/80 via-black/10 to-transparent\" />\n <div className=\"absolute bottom-0 inset-x-0 p-2.5 space-y-1.5\">\n <div className=\"h-8 w-8 rounded-full ring-2 ring-white/20 overflow-hidden bg-muted flex items-center justify-center\">\n {avatarUrl ? (\n <img\n src={avatarUrl}\n alt={displayName ?? \"\"}\n loading=\"lazy\"\n className=\"h-full w-full object-cover\"\n onError={() => setAvatarError(true)}\n />\n ) : (\n <span className=\"text-xs font-black text-white/60\">\n {(displayName ?? \"?\").charAt(0).toUpperCase()}\n </span>\n )}\n </div>\n <div>\n <p className=\"font-bold text-white text-xs truncate\">{displayName}</p>\n <p className=\"text-[10px] text-white/55 flex items-center gap-0.5\">\n <AtSign className=\"h-2 w-2 shrink-0\" />\n <span className=\"truncate\">{creator.username}</span>\n </p>\n </div>\n </div>\n </div>\n </a>\n );\n}\n\nexport function DiscoverCreatorsStrip({\n creators,\n isLoading,\n getHref,\n allCreatorsHref = \"/creators\",\n sectionLabel = \"Creator network\",\n title = \"Creators\",\n}: DiscoverCreatorsStripProps) {\n if (!isLoading && creators.length === 0) return null;\n\n return (\n <FadeIn>\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"section-label\">{sectionLabel}</p>\n <div className=\"flex items-center gap-2 mt-0.5\">\n <Users className=\"h-4 w-4 text-brand-purple\" />\n <h2 className=\"text-lg font-bold\">{title}</h2>\n </div>\n </div>\n <a\n href={allCreatorsHref}\n className=\"inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground px-3 py-1.5 rounded-md hover:bg-accent transition-colors\"\n >\n View all <ArrowRight className=\"h-3.5 w-3.5\" />\n </a>\n </div>\n <div className=\"overflow-x-auto scrollbar-hide snap-x snap-mandatory -mx-4 px-4 md:mx-0 md:px-0\">\n <div className=\"flex gap-3 w-max pb-1\">\n {isLoading\n ? Array.from({ length: 6 }).map((_, i) => <CreatorChipSkeleton key={i} />)\n : creators.map((c) => (\n <CreatorChip key={c.walletAddress} creator={c} href={getHref(c)} />\n ))}\n </div>\n </div>\n </div>\n </FadeIn>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBI;AAjBJ,mBAAyB;AACzB,0BAA0C;AAC1C,+BAAuB;AACvB,kBAA2B;AAY3B,SAAS,sBAAsB;AAC7B,SACE,4CAAC,SAAI,WAAU,gEAA+D;AAElF;AAEA,SAAS,YAAY;AAAA,EACnB;AAAA,EACA;AACF,GAGG;AACD,QAAM,CAAC,aAAa,cAAc,QAAI,uBAAS,KAAK;AACpD,QAAM,CAAC,aAAa,cAAc,QAAI,uBAAS,KAAK;AAEpD,QAAM,YAAY,QAAQ,eAAe;AACzC,QAAM,YAAY,QAAQ,eAAe,QAAQ,eAAe;AAEhE,QAAM,YAAY,aAAa,CAAC,kBAAc,wBAAW,SAAS,IAAI;AACtE,QAAM,YAAY,aAAa,CAAC,kBAAc,wBAAW,SAAS,IAAI;AAEtE,QAAM,cAAc,QAAQ,eAAe,IAAI,QAAQ,QAAQ;AAE/D,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAU;AAAA,MAEV,uDAAC,SAAI,WAAU,6DACZ;AAAA,qBACC;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,KAAI;AAAA,YACJ,eAAW;AAAA,YACX,SAAQ;AAAA,YACR,WAAU;AAAA,YACV,SAAS,MAAM,eAAe,IAAI;AAAA;AAAA,QACpC;AAAA,QAEF,4CAAC,SAAI,WAAU,+EAA8E;AAAA,QAC7F,6CAAC,SAAI,WAAU,iDACb;AAAA,sDAAC,SAAI,WAAU,uGACZ,sBACC;AAAA,YAAC;AAAA;AAAA,cACC,KAAK;AAAA,cACL,KAAK,eAAe;AAAA,cACpB,SAAQ;AAAA,cACR,WAAU;AAAA,cACV,SAAS,MAAM,eAAe,IAAI;AAAA;AAAA,UACpC,IAEA,4CAAC,UAAK,WAAU,oCACZ,0BAAe,KAAK,OAAO,CAAC,EAAE,YAAY,GAC9C,GAEJ;AAAA,UACA,6CAAC,SACC;AAAA,wDAAC,OAAE,WAAU,yCAAyC,uBAAY;AAAA,YAClE,6CAAC,OAAE,WAAU,uDACX;AAAA,0DAAC,8BAAO,WAAU,oBAAmB;AAAA,cACrC,4CAAC,UAAK,WAAU,YAAY,kBAAQ,UAAS;AAAA,eAC/C;AAAA,aACF;AAAA,WACF;AAAA,SACF;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,QAAQ;AACV,GAA+B;AAC7B,MAAI,CAAC,aAAa,SAAS,WAAW,EAAG,QAAO;AAEhD,SACE,4CAAC,mCACC,uDAAC,SAAI,WAAU,aACb;AAAA,iDAAC,SAAI,WAAU,qCACb;AAAA,mDAAC,SACC;AAAA,oDAAC,OAAE,WAAU,iBAAiB,wBAAa;AAAA,QAC3C,6CAAC,SAAI,WAAU,kCACb;AAAA,sDAAC,6BAAM,WAAU,6BAA4B;AAAA,UAC7C,4CAAC,QAAG,WAAU,qBAAqB,iBAAM;AAAA,WAC3C;AAAA,SACF;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,MAAM;AAAA,UACN,WAAU;AAAA,UACX;AAAA;AAAA,YACU,4CAAC,kCAAW,WAAU,eAAc;AAAA;AAAA;AAAA,MAC/C;AAAA,OACF;AAAA,IACA,4CAAC,SAAI,WAAU,mFACb,sDAAC,SAAI,WAAU,yBACZ,sBACG,MAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,MAAM,4CAAC,yBAAyB,CAAG,CAAE,IACvE,SAAS,IAAI,CAAC,MACZ,4CAAC,eAAkC,SAAS,GAAG,MAAM,QAAQ,CAAC,KAA5C,EAAE,aAA6C,CAClE,GACP,GACF;AAAA,KACF,GACF;AAEJ;","names":[]}
@@ -6,7 +6,9 @@ interface DiscoverCreatorsStripProps {
6
6
  isLoading: boolean;
7
7
  getHref: (creator: ApiCreatorProfile) => string;
8
8
  allCreatorsHref?: string;
9
+ sectionLabel?: string;
10
+ title?: string;
9
11
  }
10
- declare function DiscoverCreatorsStrip({ creators, isLoading, getHref, allCreatorsHref, }: DiscoverCreatorsStripProps): react_jsx_runtime.JSX.Element | null;
12
+ declare function DiscoverCreatorsStrip({ creators, isLoading, getHref, allCreatorsHref, sectionLabel, title, }: DiscoverCreatorsStripProps): react_jsx_runtime.JSX.Element | null;
11
13
 
12
14
  export { DiscoverCreatorsStrip, type DiscoverCreatorsStripProps };
@@ -6,7 +6,9 @@ interface DiscoverCreatorsStripProps {
6
6
  isLoading: boolean;
7
7
  getHref: (creator: ApiCreatorProfile) => string;
8
8
  allCreatorsHref?: string;
9
+ sectionLabel?: string;
10
+ title?: string;
9
11
  }
10
- declare function DiscoverCreatorsStrip({ creators, isLoading, getHref, allCreatorsHref, }: DiscoverCreatorsStripProps): react_jsx_runtime.JSX.Element | null;
12
+ declare function DiscoverCreatorsStrip({ creators, isLoading, getHref, allCreatorsHref, sectionLabel, title, }: DiscoverCreatorsStripProps): react_jsx_runtime.JSX.Element | null;
11
13
 
12
14
  export { DiscoverCreatorsStrip, type DiscoverCreatorsStripProps };
@@ -13,8 +13,8 @@ function CreatorChip({
13
13
  }) {
14
14
  const [avatarError, setAvatarError] = useState(false);
15
15
  const [bannerError, setBannerError] = useState(false);
16
- const bannerSrc = creator.bannerImage ?? creator.collectionImage ?? null;
17
- const avatarSrc = creator.avatarImage ?? creator.collectionImage ?? null;
16
+ const bannerSrc = creator.bannerImage ?? null;
17
+ const avatarSrc = creator.avatarImage ?? creator.bannerImage ?? null;
18
18
  const bannerUrl = bannerSrc && !bannerError ? ipfsToHttp(bannerSrc) : null;
19
19
  const avatarUrl = avatarSrc && !avatarError ? ipfsToHttp(avatarSrc) : null;
20
20
  const displayName = creator.displayName || `@${creator.username}`;
@@ -63,16 +63,18 @@ function DiscoverCreatorsStrip({
63
63
  creators,
64
64
  isLoading,
65
65
  getHref,
66
- allCreatorsHref = "/creators"
66
+ allCreatorsHref = "/creators",
67
+ sectionLabel = "Creator network",
68
+ title = "Creators"
67
69
  }) {
68
70
  if (!isLoading && creators.length === 0) return null;
69
71
  return /* @__PURE__ */ jsx(FadeIn, { children: /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
70
72
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
71
73
  /* @__PURE__ */ jsxs("div", { children: [
72
- /* @__PURE__ */ jsx("p", { className: "section-label", children: "Creator network" }),
74
+ /* @__PURE__ */ jsx("p", { className: "section-label", children: sectionLabel }),
73
75
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-0.5", children: [
74
76
  /* @__PURE__ */ jsx(Users, { className: "h-4 w-4 text-brand-purple" }),
75
- /* @__PURE__ */ jsx("h2", { className: "text-lg font-bold", children: "Creators" })
77
+ /* @__PURE__ */ jsx("h2", { className: "text-lg font-bold", children: title })
76
78
  ] })
77
79
  ] }),
78
80
  /* @__PURE__ */ jsxs(