@medialane/ui 0.11.3 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/collection-card.cjs +20 -14
- package/dist/components/collection-card.cjs.map +1 -1
- package/dist/components/collection-card.js +21 -15
- package/dist/components/collection-card.js.map +1 -1
- package/dist/components/discover-collections-strip.cjs +13 -75
- package/dist/components/discover-collections-strip.cjs.map +1 -1
- package/dist/components/discover-collections-strip.d.cts +6 -2
- package/dist/components/discover-collections-strip.d.ts +6 -2
- package/dist/components/discover-collections-strip.js +15 -77
- package/dist/components/discover-collections-strip.js.map +1 -1
- package/dist/components/discover-creators-strip.cjs +4 -27
- package/dist/components/discover-creators-strip.cjs.map +1 -1
- package/dist/components/discover-creators-strip.js +5 -28
- package/dist/components/discover-creators-strip.js.map +1 -1
- package/dist/components/launchpad-strip.cjs +150 -0
- package/dist/components/launchpad-strip.cjs.map +1 -0
- package/dist/components/launchpad-strip.d.cts +16 -0
- package/dist/components/launchpad-strip.d.ts +16 -0
- package/dist/components/launchpad-strip.js +116 -0
- package/dist/components/launchpad-strip.js.map +1 -0
- package/dist/components/scroll-section.cjs +6 -2
- package/dist/components/scroll-section.cjs.map +1 -1
- package/dist/components/scroll-section.d.cts +3 -1
- package/dist/components/scroll-section.d.ts +3 -1
- package/dist/components/scroll-section.js +6 -2
- package/dist/components/scroll-section.js.map +1 -1
- package/dist/index.cjs +3 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/medialane.css +6 -0
- package/package.json +1 -1
|
@@ -34,13 +34,9 @@ function CreatorChip({
|
|
|
34
34
|
creator,
|
|
35
35
|
href
|
|
36
36
|
}) {
|
|
37
|
-
const [avatarError, setAvatarError] = (0, import_react.useState)(false);
|
|
38
37
|
const [bannerError, setBannerError] = (0, import_react.useState)(false);
|
|
39
|
-
const
|
|
40
|
-
const
|
|
41
|
-
const bannerUrl = bannerSrc && !bannerError ? (0, import_ipfs.ipfsToHttp)(bannerSrc) : null;
|
|
42
|
-
const avatarUrl = avatarSrc && !avatarError ? (0, import_ipfs.ipfsToHttp)(avatarSrc) : null;
|
|
43
|
-
const displayName = creator.displayName || `@${creator.username}`;
|
|
38
|
+
const rawSrc = creator.bannerImage || creator.collectionImage || null;
|
|
39
|
+
const bannerUrl = rawSrc && !bannerError ? (0, import_ipfs.ipfsToHttp)(rawSrc) : null;
|
|
44
40
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
45
41
|
"a",
|
|
46
42
|
{
|
|
@@ -58,26 +54,7 @@ function CreatorChip({
|
|
|
58
54
|
onError: () => setBannerError(true)
|
|
59
55
|
}
|
|
60
56
|
),
|
|
61
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute inset-0
|
|
62
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "absolute bottom-0 inset-x-0 p-2.5 space-y-1.5", children: [
|
|
63
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-8 w-8 rounded-full ring-2 ring-white/20 overflow-hidden bg-muted flex items-center justify-center", children: avatarUrl ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
64
|
-
"img",
|
|
65
|
-
{
|
|
66
|
-
src: avatarUrl,
|
|
67
|
-
alt: displayName ?? "",
|
|
68
|
-
loading: "lazy",
|
|
69
|
-
className: "h-full w-full object-cover",
|
|
70
|
-
onError: () => setAvatarError(true)
|
|
71
|
-
}
|
|
72
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-xs font-black text-white/60", children: (displayName ?? "?").charAt(0).toUpperCase() }) }),
|
|
73
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
74
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "font-bold text-white text-xs truncate", children: displayName }),
|
|
75
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-[10px] text-white/55 flex items-center gap-0.5", children: [
|
|
76
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.AtSign, { className: "h-2 w-2 shrink-0" }),
|
|
77
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "truncate", children: creator.username })
|
|
78
|
-
] })
|
|
79
|
-
] })
|
|
80
|
-
] })
|
|
57
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute bottom-0 inset-x-0 px-3 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "font-bold text-2xl text-white truncate", children: creator.username }) })
|
|
81
58
|
] })
|
|
82
59
|
}
|
|
83
60
|
);
|
|
@@ -87,7 +64,7 @@ function DiscoverCreatorsStrip({
|
|
|
87
64
|
isLoading,
|
|
88
65
|
getHref,
|
|
89
66
|
allCreatorsHref = "/creators",
|
|
90
|
-
sectionLabel = "
|
|
67
|
+
sectionLabel = "Explore",
|
|
91
68
|
title = "Creators"
|
|
92
69
|
}) {
|
|
93
70
|
if (!isLoading && creators.length === 0) return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/discover-creators-strip.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { Users, ArrowRight
|
|
1
|
+
{"version":3,"sources":["../../src/components/discover-creators-strip.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { Users, ArrowRight } 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 [bannerError, setBannerError] = useState(false);\n\n // bannerImage with collectionImage fallback — io-approved big-username design\n const rawSrc =\n creator.bannerImage ||\n (creator as ApiCreatorProfile & { collectionImage?: string | null }).collectionImage ||\n null;\n const bannerUrl = rawSrc && !bannerError ? ipfsToHttp(rawSrc) : null;\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 bottom-0 inset-x-0 px-3 py-3\">\n <p className=\"font-bold text-2xl text-white truncate\">{creator.username}</p>\n </div>\n </div>\n </a>\n );\n}\n\nexport function DiscoverCreatorsStrip({\n creators,\n isLoading,\n getHref,\n allCreatorsHref = \"/creators\",\n sectionLabel = \"Explore\",\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-5 sm:gap-6 w-max pb-2\">\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,0BAAkC;AAClC,+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;AAGpD,QAAM,SACJ,QAAQ,eACP,QAAoE,mBACrE;AACF,QAAM,YAAY,UAAU,CAAC,kBAAc,wBAAW,MAAM,IAAI;AAEhE,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,yCACb,sDAAC,OAAE,WAAU,0CAA0C,kBAAQ,UAAS,GAC1E;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,kCACZ,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,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState } from "react";
|
|
4
|
-
import { Users, ArrowRight
|
|
4
|
+
import { Users, ArrowRight } from "lucide-react";
|
|
5
5
|
import { FadeIn } from "./motion-primitives.js";
|
|
6
6
|
import { ipfsToHttp } from "../utils/ipfs.js";
|
|
7
7
|
function CreatorChipSkeleton() {
|
|
@@ -11,13 +11,9 @@ function CreatorChip({
|
|
|
11
11
|
creator,
|
|
12
12
|
href
|
|
13
13
|
}) {
|
|
14
|
-
const [avatarError, setAvatarError] = useState(false);
|
|
15
14
|
const [bannerError, setBannerError] = useState(false);
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const bannerUrl = bannerSrc && !bannerError ? ipfsToHttp(bannerSrc) : null;
|
|
19
|
-
const avatarUrl = avatarSrc && !avatarError ? ipfsToHttp(avatarSrc) : null;
|
|
20
|
-
const displayName = creator.displayName || `@${creator.username}`;
|
|
15
|
+
const rawSrc = creator.bannerImage || creator.collectionImage || null;
|
|
16
|
+
const bannerUrl = rawSrc && !bannerError ? ipfsToHttp(rawSrc) : null;
|
|
21
17
|
return /* @__PURE__ */ jsx(
|
|
22
18
|
"a",
|
|
23
19
|
{
|
|
@@ -35,26 +31,7 @@ function CreatorChip({
|
|
|
35
31
|
onError: () => setBannerError(true)
|
|
36
32
|
}
|
|
37
33
|
),
|
|
38
|
-
/* @__PURE__ */ jsx("div", { className: "absolute inset-0
|
|
39
|
-
/* @__PURE__ */ jsxs("div", { className: "absolute bottom-0 inset-x-0 p-2.5 space-y-1.5", children: [
|
|
40
|
-
/* @__PURE__ */ jsx("div", { className: "h-8 w-8 rounded-full ring-2 ring-white/20 overflow-hidden bg-muted flex items-center justify-center", children: avatarUrl ? /* @__PURE__ */ jsx(
|
|
41
|
-
"img",
|
|
42
|
-
{
|
|
43
|
-
src: avatarUrl,
|
|
44
|
-
alt: displayName ?? "",
|
|
45
|
-
loading: "lazy",
|
|
46
|
-
className: "h-full w-full object-cover",
|
|
47
|
-
onError: () => setAvatarError(true)
|
|
48
|
-
}
|
|
49
|
-
) : /* @__PURE__ */ jsx("span", { className: "text-xs font-black text-white/60", children: (displayName ?? "?").charAt(0).toUpperCase() }) }),
|
|
50
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
51
|
-
/* @__PURE__ */ jsx("p", { className: "font-bold text-white text-xs truncate", children: displayName }),
|
|
52
|
-
/* @__PURE__ */ jsxs("p", { className: "text-[10px] text-white/55 flex items-center gap-0.5", children: [
|
|
53
|
-
/* @__PURE__ */ jsx(AtSign, { className: "h-2 w-2 shrink-0" }),
|
|
54
|
-
/* @__PURE__ */ jsx("span", { className: "truncate", children: creator.username })
|
|
55
|
-
] })
|
|
56
|
-
] })
|
|
57
|
-
] })
|
|
34
|
+
/* @__PURE__ */ jsx("div", { className: "absolute bottom-0 inset-x-0 px-3 py-3", children: /* @__PURE__ */ jsx("p", { className: "font-bold text-2xl text-white truncate", children: creator.username }) })
|
|
58
35
|
] })
|
|
59
36
|
}
|
|
60
37
|
);
|
|
@@ -64,7 +41,7 @@ function DiscoverCreatorsStrip({
|
|
|
64
41
|
isLoading,
|
|
65
42
|
getHref,
|
|
66
43
|
allCreatorsHref = "/creators",
|
|
67
|
-
sectionLabel = "
|
|
44
|
+
sectionLabel = "Explore",
|
|
68
45
|
title = "Creators"
|
|
69
46
|
}) {
|
|
70
47
|
if (!isLoading && creators.length === 0) return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/discover-creators-strip.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { Users, ArrowRight
|
|
1
|
+
{"version":3,"sources":["../../src/components/discover-creators-strip.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { Users, ArrowRight } 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 [bannerError, setBannerError] = useState(false);\n\n // bannerImage with collectionImage fallback — io-approved big-username design\n const rawSrc =\n creator.bannerImage ||\n (creator as ApiCreatorProfile & { collectionImage?: string | null }).collectionImage ||\n null;\n const bannerUrl = rawSrc && !bannerError ? ipfsToHttp(rawSrc) : null;\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 bottom-0 inset-x-0 px-3 py-3\">\n <p className=\"font-bold text-2xl text-white truncate\">{creator.username}</p>\n </div>\n </div>\n </a>\n );\n}\n\nexport function DiscoverCreatorsStrip({\n creators,\n isLoading,\n getHref,\n allCreatorsHref = \"/creators\",\n sectionLabel = \"Explore\",\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-5 sm:gap-6 w-max pb-2\">\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":";AAmBI,cAyBE,YAzBF;AAjBJ,SAAS,gBAAgB;AACzB,SAAS,OAAO,kBAAkB;AAClC,SAAS,cAAc;AACvB,SAAS,kBAAkB;AAY3B,SAAS,sBAAsB;AAC7B,SACE,oBAAC,SAAI,WAAU,gEAA+D;AAElF;AAEA,SAAS,YAAY;AAAA,EACnB;AAAA,EACA;AACF,GAGG;AACD,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,KAAK;AAGpD,QAAM,SACJ,QAAQ,eACP,QAAoE,mBACrE;AACF,QAAM,YAAY,UAAU,CAAC,cAAc,WAAW,MAAM,IAAI;AAEhE,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAU;AAAA,MAEV,+BAAC,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,oBAAC,SAAI,WAAU,yCACb,8BAAC,OAAE,WAAU,0CAA0C,kBAAQ,UAAS,GAC1E;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,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,SAAM,WAAU,6BAA4B;AAAA,UAC7C,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,kCACZ,sBACG,MAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,MAAM,oBAAC,yBAAyB,CAAG,CAAE,IACvE,SAAS,IAAI,CAAC,MACZ,oBAAC,eAAkC,SAAS,GAAG,MAAM,QAAQ,CAAC,KAA5C,EAAE,aAA6C,CAClE,GACP,GACF;AAAA,KACF,GACF;AAEJ;","names":[]}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
var launchpad_strip_exports = {};
|
|
31
|
+
__export(launchpad_strip_exports, {
|
|
32
|
+
LaunchpadStrip: () => LaunchpadStrip
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(launchpad_strip_exports);
|
|
35
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
36
|
+
var import_link = __toESM(require("next/link"), 1);
|
|
37
|
+
var import_lucide_react = require("lucide-react");
|
|
38
|
+
var import_scroll_section = require("./scroll-section.js");
|
|
39
|
+
var import_launchpad_services = require("./launchpad-services.js");
|
|
40
|
+
var import_launchpad_services2 = require("../data/launchpad-services.js");
|
|
41
|
+
var import_cn = require("../utils/cn.js");
|
|
42
|
+
const DEF_BY_KEY = Object.fromEntries(import_launchpad_services2.LAUNCHPAD_SERVICE_DEFINITIONS.map((d) => [d.key, d]));
|
|
43
|
+
const STRIP_ORDER = [
|
|
44
|
+
"mint-ip-asset",
|
|
45
|
+
"create-collection",
|
|
46
|
+
"ip-collection-1155",
|
|
47
|
+
"mint-editions",
|
|
48
|
+
"collection-drop",
|
|
49
|
+
"pop-protocol"
|
|
50
|
+
];
|
|
51
|
+
const MARKETPLACE_HUE = {
|
|
52
|
+
text: "text-indigo-600 dark:text-indigo-400",
|
|
53
|
+
solid: "bg-indigo-500",
|
|
54
|
+
border: "border-indigo-500/25",
|
|
55
|
+
pill: "bg-gradient-to-r from-indigo-500 to-blue-600"
|
|
56
|
+
};
|
|
57
|
+
function ServiceCard({ card }) {
|
|
58
|
+
const { icon: Icon, title, blurb, example, cta, hue, href } = card;
|
|
59
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
60
|
+
import_link.default,
|
|
61
|
+
{
|
|
62
|
+
href,
|
|
63
|
+
className: (0, import_cn.cn)(
|
|
64
|
+
"relative rounded-2xl border bg-card overflow-hidden flex flex-col h-full min-h-[280px]",
|
|
65
|
+
"transition-transform active:scale-[0.99]",
|
|
66
|
+
hue.border
|
|
67
|
+
),
|
|
68
|
+
children: [
|
|
69
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { "aria-hidden": true, className: "absolute -right-7 -bottom-9 opacity-[0.04] select-none pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { className: "h-36 w-36" }) }),
|
|
70
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative flex flex-col flex-1 p-6 gap-3.5", children: [
|
|
71
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative w-fit", children: [
|
|
72
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { "aria-hidden": true, className: (0, import_cn.cn)("absolute -inset-3 rounded-full blur-2xl opacity-30", hue.solid) }),
|
|
73
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { className: (0, import_cn.cn)("relative h-8 w-8", hue.text) })
|
|
74
|
+
] }),
|
|
75
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-1.5", children: [
|
|
76
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "text-xl font-black tracking-tight leading-snug", children: title }),
|
|
77
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm text-muted-foreground leading-relaxed", children: blurb }),
|
|
78
|
+
example && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-xs text-muted-foreground/70 italic leading-relaxed", children: [
|
|
79
|
+
"e.g. ",
|
|
80
|
+
example
|
|
81
|
+
] })
|
|
82
|
+
] }),
|
|
83
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mt-auto pt-1 flex justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
84
|
+
"span",
|
|
85
|
+
{
|
|
86
|
+
className: (0, import_cn.cn)(
|
|
87
|
+
"inline-flex items-center gap-2 h-9 px-4 rounded-full",
|
|
88
|
+
"text-sm font-semibold text-white shadow-lg shadow-black/25",
|
|
89
|
+
hue.pill
|
|
90
|
+
),
|
|
91
|
+
children: [
|
|
92
|
+
cta,
|
|
93
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ArrowRight, { className: "h-3.5 w-3.5" })
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
) })
|
|
97
|
+
] })
|
|
98
|
+
]
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
function LaunchpadStrip({
|
|
103
|
+
hrefs,
|
|
104
|
+
marketplaceHref,
|
|
105
|
+
launchpadHref = "/launchpad"
|
|
106
|
+
}) {
|
|
107
|
+
const cards = [
|
|
108
|
+
...STRIP_ORDER.flatMap((key) => {
|
|
109
|
+
const def = DEF_BY_KEY[key];
|
|
110
|
+
const href = hrefs[key];
|
|
111
|
+
if (!def || !href) return [];
|
|
112
|
+
return [{
|
|
113
|
+
key,
|
|
114
|
+
href,
|
|
115
|
+
icon: def.icon,
|
|
116
|
+
title: def.title,
|
|
117
|
+
blurb: def.blurb,
|
|
118
|
+
example: def.example,
|
|
119
|
+
cta: def.cta,
|
|
120
|
+
hue: import_launchpad_services.SERVICE_HUES[key] ?? MARKETPLACE_HUE
|
|
121
|
+
}];
|
|
122
|
+
}),
|
|
123
|
+
...marketplaceHref ? [{
|
|
124
|
+
key: "marketplace",
|
|
125
|
+
href: marketplaceHref,
|
|
126
|
+
icon: import_lucide_react.ShoppingBag,
|
|
127
|
+
title: "Marketplace",
|
|
128
|
+
blurb: "Discover and trade works from creators \u2014 gasless, instantly settled.",
|
|
129
|
+
example: "Buy an art print, make an offer on a music track",
|
|
130
|
+
cta: "Browse",
|
|
131
|
+
hue: MARKETPLACE_HUE
|
|
132
|
+
}] : []
|
|
133
|
+
];
|
|
134
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
135
|
+
import_scroll_section.ScrollSection,
|
|
136
|
+
{
|
|
137
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Rocket, { className: "h-3.5 w-3.5 text-white" }),
|
|
138
|
+
iconBg: "bg-gradient-to-br from-primary to-blue-600 shadow-md shadow-primary/20",
|
|
139
|
+
title: "Launchpad",
|
|
140
|
+
href: launchpadHref,
|
|
141
|
+
linkLabel: "Explore",
|
|
142
|
+
children: cards.map((card) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "w-64 sm:w-72 snap-start shrink-0 flex", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ServiceCard, { card }) }, card.key))
|
|
143
|
+
}
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
147
|
+
0 && (module.exports = {
|
|
148
|
+
LaunchpadStrip
|
|
149
|
+
});
|
|
150
|
+
//# sourceMappingURL=launchpad-strip.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/launchpad-strip.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"next/link\";\nimport { ShoppingBag, ArrowRight, Rocket } from \"lucide-react\";\nimport type { LucideIcon } from \"lucide-react\";\nimport { ScrollSection } from \"./scroll-section.js\";\nimport { SERVICE_HUES } from \"./launchpad-services.js\";\nimport { LAUNCHPAD_SERVICE_DEFINITIONS } from \"../data/launchpad-services.js\";\nimport { cn } from \"../utils/cn.js\";\n\n/** Homepage launchpad strip — cards derive from the shared launchpad service\n * definitions: creator language, one blurb, one example, one vivid verb pill.\n * No tech chips, no long descriptions. Apps inject only hrefs. */\n\nexport interface LaunchpadStripProps {\n /** Per-service destinations, keyed by service key. Services without an href are skipped. */\n hrefs: Record<string, string>;\n /** Marketplace card destination (omit to hide the marketplace card) */\n marketplaceHref?: string;\n /** \"Explore\" header link */\n launchpadHref?: string;\n}\n\ninterface StripCard {\n key: string;\n href: string;\n icon: LucideIcon;\n title: string;\n blurb: string;\n example?: string;\n cta: string;\n hue: { text: string; solid: string; border: string; pill: string };\n}\n\nconst DEF_BY_KEY = Object.fromEntries(LAUNCHPAD_SERVICE_DEFINITIONS.map((d) => [d.key, d]));\n\n/** Display order on the homepage strip */\nconst STRIP_ORDER = [\n \"mint-ip-asset\",\n \"create-collection\",\n \"ip-collection-1155\",\n \"mint-editions\",\n \"collection-drop\",\n \"pop-protocol\",\n];\n\nconst MARKETPLACE_HUE = {\n text: \"text-indigo-600 dark:text-indigo-400\",\n solid: \"bg-indigo-500\",\n border: \"border-indigo-500/25\",\n pill: \"bg-gradient-to-r from-indigo-500 to-blue-600\",\n};\n\nfunction ServiceCard({ card }: { card: StripCard }) {\n const { icon: Icon, title, blurb, example, cta, hue, href } = card;\n return (\n <Link\n href={href}\n className={cn(\n \"relative rounded-2xl border bg-card overflow-hidden flex flex-col h-full min-h-[280px]\",\n \"transition-transform active:scale-[0.99]\",\n hue.border,\n )}\n >\n {/* Ghosted watermark icon (launchpad card language) */}\n <div aria-hidden className=\"absolute -right-7 -bottom-9 opacity-[0.04] select-none pointer-events-none\">\n <Icon className=\"h-36 w-36\" />\n </div>\n\n <div className=\"relative flex flex-col flex-1 p-6 gap-3.5\">\n <div className=\"relative w-fit\">\n <div aria-hidden className={cn(\"absolute -inset-3 rounded-full blur-2xl opacity-30\", hue.solid)} />\n <Icon className={cn(\"relative h-8 w-8\", hue.text)} />\n </div>\n\n <div className=\"space-y-1.5\">\n <h3 className=\"text-xl font-black tracking-tight leading-snug\">{title}</h3>\n <p className=\"text-sm text-muted-foreground leading-relaxed\">{blurb}</p>\n {example && (\n <p className=\"text-xs text-muted-foreground/70 italic leading-relaxed\">e.g. {example}</p>\n )}\n </div>\n\n <div className=\"mt-auto pt-1 flex justify-end\">\n <span\n className={cn(\n \"inline-flex items-center gap-2 h-9 px-4 rounded-full\",\n \"text-sm font-semibold text-white shadow-lg shadow-black/25\",\n hue.pill,\n )}\n >\n {cta}\n <ArrowRight className=\"h-3.5 w-3.5\" />\n </span>\n </div>\n </div>\n </Link>\n );\n}\n\nexport function LaunchpadStrip({\n hrefs,\n marketplaceHref,\n launchpadHref = \"/launchpad\",\n}: LaunchpadStripProps) {\n const cards: StripCard[] = [\n ...STRIP_ORDER.flatMap((key) => {\n const def = DEF_BY_KEY[key];\n const href = hrefs[key];\n if (!def || !href) return [];\n return [{\n key,\n href,\n icon: def.icon,\n title: def.title,\n blurb: def.blurb,\n example: def.example,\n cta: def.cta,\n hue: SERVICE_HUES[key] ?? MARKETPLACE_HUE,\n }];\n }),\n ...(marketplaceHref\n ? [{\n key: \"marketplace\",\n href: marketplaceHref,\n icon: ShoppingBag,\n title: \"Marketplace\",\n blurb: \"Discover and trade works from creators — gasless, instantly settled.\",\n example: \"Buy an art print, make an offer on a music track\",\n cta: \"Browse\",\n hue: MARKETPLACE_HUE,\n }]\n : []),\n ];\n\n return (\n <ScrollSection\n icon={<Rocket className=\"h-3.5 w-3.5 text-white\" />}\n iconBg=\"bg-gradient-to-br from-primary to-blue-600 shadow-md shadow-primary/20\"\n title=\"Launchpad\"\n href={launchpadHref}\n linkLabel=\"Explore\"\n >\n {cards.map((card) => (\n <div key={card.key} className=\"w-64 sm:w-72 snap-start shrink-0 flex\">\n <ServiceCard card={card} />\n </div>\n ))}\n </ScrollSection>\n );\n}\n"],"mappings":"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","names":["import_launchpad_services","Link"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
/** Homepage launchpad strip — cards derive from the shared launchpad service
|
|
4
|
+
* definitions: creator language, one blurb, one example, one vivid verb pill.
|
|
5
|
+
* No tech chips, no long descriptions. Apps inject only hrefs. */
|
|
6
|
+
interface LaunchpadStripProps {
|
|
7
|
+
/** Per-service destinations, keyed by service key. Services without an href are skipped. */
|
|
8
|
+
hrefs: Record<string, string>;
|
|
9
|
+
/** Marketplace card destination (omit to hide the marketplace card) */
|
|
10
|
+
marketplaceHref?: string;
|
|
11
|
+
/** "Explore" header link */
|
|
12
|
+
launchpadHref?: string;
|
|
13
|
+
}
|
|
14
|
+
declare function LaunchpadStrip({ hrefs, marketplaceHref, launchpadHref, }: LaunchpadStripProps): react_jsx_runtime.JSX.Element;
|
|
15
|
+
|
|
16
|
+
export { LaunchpadStrip, type LaunchpadStripProps };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
/** Homepage launchpad strip — cards derive from the shared launchpad service
|
|
4
|
+
* definitions: creator language, one blurb, one example, one vivid verb pill.
|
|
5
|
+
* No tech chips, no long descriptions. Apps inject only hrefs. */
|
|
6
|
+
interface LaunchpadStripProps {
|
|
7
|
+
/** Per-service destinations, keyed by service key. Services without an href are skipped. */
|
|
8
|
+
hrefs: Record<string, string>;
|
|
9
|
+
/** Marketplace card destination (omit to hide the marketplace card) */
|
|
10
|
+
marketplaceHref?: string;
|
|
11
|
+
/** "Explore" header link */
|
|
12
|
+
launchpadHref?: string;
|
|
13
|
+
}
|
|
14
|
+
declare function LaunchpadStrip({ hrefs, marketplaceHref, launchpadHref, }: LaunchpadStripProps): react_jsx_runtime.JSX.Element;
|
|
15
|
+
|
|
16
|
+
export { LaunchpadStrip, type LaunchpadStripProps };
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import Link from "next/link";
|
|
4
|
+
import { ShoppingBag, ArrowRight, Rocket } from "lucide-react";
|
|
5
|
+
import { ScrollSection } from "./scroll-section.js";
|
|
6
|
+
import { SERVICE_HUES } from "./launchpad-services.js";
|
|
7
|
+
import { LAUNCHPAD_SERVICE_DEFINITIONS } from "../data/launchpad-services.js";
|
|
8
|
+
import { cn } from "../utils/cn.js";
|
|
9
|
+
const DEF_BY_KEY = Object.fromEntries(LAUNCHPAD_SERVICE_DEFINITIONS.map((d) => [d.key, d]));
|
|
10
|
+
const STRIP_ORDER = [
|
|
11
|
+
"mint-ip-asset",
|
|
12
|
+
"create-collection",
|
|
13
|
+
"ip-collection-1155",
|
|
14
|
+
"mint-editions",
|
|
15
|
+
"collection-drop",
|
|
16
|
+
"pop-protocol"
|
|
17
|
+
];
|
|
18
|
+
const MARKETPLACE_HUE = {
|
|
19
|
+
text: "text-indigo-600 dark:text-indigo-400",
|
|
20
|
+
solid: "bg-indigo-500",
|
|
21
|
+
border: "border-indigo-500/25",
|
|
22
|
+
pill: "bg-gradient-to-r from-indigo-500 to-blue-600"
|
|
23
|
+
};
|
|
24
|
+
function ServiceCard({ card }) {
|
|
25
|
+
const { icon: Icon, title, blurb, example, cta, hue, href } = card;
|
|
26
|
+
return /* @__PURE__ */ jsxs(
|
|
27
|
+
Link,
|
|
28
|
+
{
|
|
29
|
+
href,
|
|
30
|
+
className: cn(
|
|
31
|
+
"relative rounded-2xl border bg-card overflow-hidden flex flex-col h-full min-h-[280px]",
|
|
32
|
+
"transition-transform active:scale-[0.99]",
|
|
33
|
+
hue.border
|
|
34
|
+
),
|
|
35
|
+
children: [
|
|
36
|
+
/* @__PURE__ */ jsx("div", { "aria-hidden": true, className: "absolute -right-7 -bottom-9 opacity-[0.04] select-none pointer-events-none", children: /* @__PURE__ */ jsx(Icon, { className: "h-36 w-36" }) }),
|
|
37
|
+
/* @__PURE__ */ jsxs("div", { className: "relative flex flex-col flex-1 p-6 gap-3.5", children: [
|
|
38
|
+
/* @__PURE__ */ jsxs("div", { className: "relative w-fit", children: [
|
|
39
|
+
/* @__PURE__ */ jsx("div", { "aria-hidden": true, className: cn("absolute -inset-3 rounded-full blur-2xl opacity-30", hue.solid) }),
|
|
40
|
+
/* @__PURE__ */ jsx(Icon, { className: cn("relative h-8 w-8", hue.text) })
|
|
41
|
+
] }),
|
|
42
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
43
|
+
/* @__PURE__ */ jsx("h3", { className: "text-xl font-black tracking-tight leading-snug", children: title }),
|
|
44
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground leading-relaxed", children: blurb }),
|
|
45
|
+
example && /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground/70 italic leading-relaxed", children: [
|
|
46
|
+
"e.g. ",
|
|
47
|
+
example
|
|
48
|
+
] })
|
|
49
|
+
] }),
|
|
50
|
+
/* @__PURE__ */ jsx("div", { className: "mt-auto pt-1 flex justify-end", children: /* @__PURE__ */ jsxs(
|
|
51
|
+
"span",
|
|
52
|
+
{
|
|
53
|
+
className: cn(
|
|
54
|
+
"inline-flex items-center gap-2 h-9 px-4 rounded-full",
|
|
55
|
+
"text-sm font-semibold text-white shadow-lg shadow-black/25",
|
|
56
|
+
hue.pill
|
|
57
|
+
),
|
|
58
|
+
children: [
|
|
59
|
+
cta,
|
|
60
|
+
/* @__PURE__ */ jsx(ArrowRight, { className: "h-3.5 w-3.5" })
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
) })
|
|
64
|
+
] })
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
function LaunchpadStrip({
|
|
70
|
+
hrefs,
|
|
71
|
+
marketplaceHref,
|
|
72
|
+
launchpadHref = "/launchpad"
|
|
73
|
+
}) {
|
|
74
|
+
const cards = [
|
|
75
|
+
...STRIP_ORDER.flatMap((key) => {
|
|
76
|
+
const def = DEF_BY_KEY[key];
|
|
77
|
+
const href = hrefs[key];
|
|
78
|
+
if (!def || !href) return [];
|
|
79
|
+
return [{
|
|
80
|
+
key,
|
|
81
|
+
href,
|
|
82
|
+
icon: def.icon,
|
|
83
|
+
title: def.title,
|
|
84
|
+
blurb: def.blurb,
|
|
85
|
+
example: def.example,
|
|
86
|
+
cta: def.cta,
|
|
87
|
+
hue: SERVICE_HUES[key] ?? MARKETPLACE_HUE
|
|
88
|
+
}];
|
|
89
|
+
}),
|
|
90
|
+
...marketplaceHref ? [{
|
|
91
|
+
key: "marketplace",
|
|
92
|
+
href: marketplaceHref,
|
|
93
|
+
icon: ShoppingBag,
|
|
94
|
+
title: "Marketplace",
|
|
95
|
+
blurb: "Discover and trade works from creators \u2014 gasless, instantly settled.",
|
|
96
|
+
example: "Buy an art print, make an offer on a music track",
|
|
97
|
+
cta: "Browse",
|
|
98
|
+
hue: MARKETPLACE_HUE
|
|
99
|
+
}] : []
|
|
100
|
+
];
|
|
101
|
+
return /* @__PURE__ */ jsx(
|
|
102
|
+
ScrollSection,
|
|
103
|
+
{
|
|
104
|
+
icon: /* @__PURE__ */ jsx(Rocket, { className: "h-3.5 w-3.5 text-white" }),
|
|
105
|
+
iconBg: "bg-gradient-to-br from-primary to-blue-600 shadow-md shadow-primary/20",
|
|
106
|
+
title: "Launchpad",
|
|
107
|
+
href: launchpadHref,
|
|
108
|
+
linkLabel: "Explore",
|
|
109
|
+
children: cards.map((card) => /* @__PURE__ */ jsx("div", { className: "w-64 sm:w-72 snap-start shrink-0 flex", children: /* @__PURE__ */ jsx(ServiceCard, { card }) }, card.key))
|
|
110
|
+
}
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
export {
|
|
114
|
+
LaunchpadStrip
|
|
115
|
+
};
|
|
116
|
+
//# sourceMappingURL=launchpad-strip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/launchpad-strip.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"next/link\";\nimport { ShoppingBag, ArrowRight, Rocket } from \"lucide-react\";\nimport type { LucideIcon } from \"lucide-react\";\nimport { ScrollSection } from \"./scroll-section.js\";\nimport { SERVICE_HUES } from \"./launchpad-services.js\";\nimport { LAUNCHPAD_SERVICE_DEFINITIONS } from \"../data/launchpad-services.js\";\nimport { cn } from \"../utils/cn.js\";\n\n/** Homepage launchpad strip — cards derive from the shared launchpad service\n * definitions: creator language, one blurb, one example, one vivid verb pill.\n * No tech chips, no long descriptions. Apps inject only hrefs. */\n\nexport interface LaunchpadStripProps {\n /** Per-service destinations, keyed by service key. Services without an href are skipped. */\n hrefs: Record<string, string>;\n /** Marketplace card destination (omit to hide the marketplace card) */\n marketplaceHref?: string;\n /** \"Explore\" header link */\n launchpadHref?: string;\n}\n\ninterface StripCard {\n key: string;\n href: string;\n icon: LucideIcon;\n title: string;\n blurb: string;\n example?: string;\n cta: string;\n hue: { text: string; solid: string; border: string; pill: string };\n}\n\nconst DEF_BY_KEY = Object.fromEntries(LAUNCHPAD_SERVICE_DEFINITIONS.map((d) => [d.key, d]));\n\n/** Display order on the homepage strip */\nconst STRIP_ORDER = [\n \"mint-ip-asset\",\n \"create-collection\",\n \"ip-collection-1155\",\n \"mint-editions\",\n \"collection-drop\",\n \"pop-protocol\",\n];\n\nconst MARKETPLACE_HUE = {\n text: \"text-indigo-600 dark:text-indigo-400\",\n solid: \"bg-indigo-500\",\n border: \"border-indigo-500/25\",\n pill: \"bg-gradient-to-r from-indigo-500 to-blue-600\",\n};\n\nfunction ServiceCard({ card }: { card: StripCard }) {\n const { icon: Icon, title, blurb, example, cta, hue, href } = card;\n return (\n <Link\n href={href}\n className={cn(\n \"relative rounded-2xl border bg-card overflow-hidden flex flex-col h-full min-h-[280px]\",\n \"transition-transform active:scale-[0.99]\",\n hue.border,\n )}\n >\n {/* Ghosted watermark icon (launchpad card language) */}\n <div aria-hidden className=\"absolute -right-7 -bottom-9 opacity-[0.04] select-none pointer-events-none\">\n <Icon className=\"h-36 w-36\" />\n </div>\n\n <div className=\"relative flex flex-col flex-1 p-6 gap-3.5\">\n <div className=\"relative w-fit\">\n <div aria-hidden className={cn(\"absolute -inset-3 rounded-full blur-2xl opacity-30\", hue.solid)} />\n <Icon className={cn(\"relative h-8 w-8\", hue.text)} />\n </div>\n\n <div className=\"space-y-1.5\">\n <h3 className=\"text-xl font-black tracking-tight leading-snug\">{title}</h3>\n <p className=\"text-sm text-muted-foreground leading-relaxed\">{blurb}</p>\n {example && (\n <p className=\"text-xs text-muted-foreground/70 italic leading-relaxed\">e.g. {example}</p>\n )}\n </div>\n\n <div className=\"mt-auto pt-1 flex justify-end\">\n <span\n className={cn(\n \"inline-flex items-center gap-2 h-9 px-4 rounded-full\",\n \"text-sm font-semibold text-white shadow-lg shadow-black/25\",\n hue.pill,\n )}\n >\n {cta}\n <ArrowRight className=\"h-3.5 w-3.5\" />\n </span>\n </div>\n </div>\n </Link>\n );\n}\n\nexport function LaunchpadStrip({\n hrefs,\n marketplaceHref,\n launchpadHref = \"/launchpad\",\n}: LaunchpadStripProps) {\n const cards: StripCard[] = [\n ...STRIP_ORDER.flatMap((key) => {\n const def = DEF_BY_KEY[key];\n const href = hrefs[key];\n if (!def || !href) return [];\n return [{\n key,\n href,\n icon: def.icon,\n title: def.title,\n blurb: def.blurb,\n example: def.example,\n cta: def.cta,\n hue: SERVICE_HUES[key] ?? MARKETPLACE_HUE,\n }];\n }),\n ...(marketplaceHref\n ? [{\n key: \"marketplace\",\n href: marketplaceHref,\n icon: ShoppingBag,\n title: \"Marketplace\",\n blurb: \"Discover and trade works from creators — gasless, instantly settled.\",\n example: \"Buy an art print, make an offer on a music track\",\n cta: \"Browse\",\n hue: MARKETPLACE_HUE,\n }]\n : []),\n ];\n\n return (\n <ScrollSection\n icon={<Rocket className=\"h-3.5 w-3.5 text-white\" />}\n iconBg=\"bg-gradient-to-br from-primary to-blue-600 shadow-md shadow-primary/20\"\n title=\"Launchpad\"\n href={launchpadHref}\n linkLabel=\"Explore\"\n >\n {cards.map((card) => (\n <div key={card.key} className=\"w-64 sm:w-72 snap-start shrink-0 flex\">\n <ServiceCard card={card} />\n </div>\n ))}\n </ScrollSection>\n );\n}\n"],"mappings":";AAkEQ,cAIA,YAJA;AAhER,OAAO,UAAU;AACjB,SAAS,aAAa,YAAY,cAAc;AAEhD,SAAS,qBAAqB;AAC9B,SAAS,oBAAoB;AAC7B,SAAS,qCAAqC;AAC9C,SAAS,UAAU;AA0BnB,MAAM,aAAa,OAAO,YAAY,8BAA8B,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;AAG1F,MAAM,cAAc;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,MAAM,kBAAkB;AAAA,EACtB,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AACR;AAEA,SAAS,YAAY,EAAE,KAAK,GAAwB;AAClD,QAAM,EAAE,MAAM,MAAM,OAAO,OAAO,SAAS,KAAK,KAAK,KAAK,IAAI;AAC9D,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA,IAAI;AAAA,MACN;AAAA,MAGA;AAAA,4BAAC,SAAI,eAAW,MAAC,WAAU,8EACzB,8BAAC,QAAK,WAAU,aAAY,GAC9B;AAAA,QAEA,qBAAC,SAAI,WAAU,6CACb;AAAA,+BAAC,SAAI,WAAU,kBACb;AAAA,gCAAC,SAAI,eAAW,MAAC,WAAW,GAAG,sDAAsD,IAAI,KAAK,GAAG;AAAA,YACjG,oBAAC,QAAK,WAAW,GAAG,oBAAoB,IAAI,IAAI,GAAG;AAAA,aACrD;AAAA,UAEA,qBAAC,SAAI,WAAU,eACb;AAAA,gCAAC,QAAG,WAAU,kDAAkD,iBAAM;AAAA,YACtE,oBAAC,OAAE,WAAU,iDAAiD,iBAAM;AAAA,YACnE,WACC,qBAAC,OAAE,WAAU,2DAA0D;AAAA;AAAA,cAAM;AAAA,eAAQ;AAAA,aAEzF;AAAA,UAEA,oBAAC,SAAI,WAAU,iCACb;AAAA,YAAC;AAAA;AAAA,cACC,WAAW;AAAA,gBACT;AAAA,gBACA;AAAA,gBACA,IAAI;AAAA,cACN;AAAA,cAEC;AAAA;AAAA,gBACD,oBAAC,cAAW,WAAU,eAAc;AAAA;AAAA;AAAA,UACtC,GACF;AAAA,WACF;AAAA;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA,gBAAgB;AAClB,GAAwB;AACtB,QAAM,QAAqB;AAAA,IACzB,GAAG,YAAY,QAAQ,CAAC,QAAQ;AAC9B,YAAM,MAAM,WAAW,GAAG;AAC1B,YAAM,OAAO,MAAM,GAAG;AACtB,UAAI,CAAC,OAAO,CAAC,KAAM,QAAO,CAAC;AAC3B,aAAO,CAAC;AAAA,QACN;AAAA,QACA;AAAA,QACA,MAAM,IAAI;AAAA,QACV,OAAO,IAAI;AAAA,QACX,OAAO,IAAI;AAAA,QACX,SAAS,IAAI;AAAA,QACb,KAAK,IAAI;AAAA,QACT,KAAK,aAAa,GAAG,KAAK;AAAA,MAC5B,CAAC;AAAA,IACH,CAAC;AAAA,IACD,GAAI,kBACA,CAAC;AAAA,MACC,KAAK;AAAA,MACL,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO;AAAA,MACP,OAAO;AAAA,MACP,SAAS;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,IACP,CAAC,IACD,CAAC;AAAA,EACP;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAM,oBAAC,UAAO,WAAU,0BAAyB;AAAA,MACjD,QAAO;AAAA,MACP,OAAM;AAAA,MACN,MAAM;AAAA,MACN,WAAU;AAAA,MAET,gBAAM,IAAI,CAAC,SACV,oBAAC,SAAmB,WAAU,yCAC5B,8BAAC,eAAY,MAAY,KADjB,KAAK,GAEf,CACD;AAAA;AAAA,EACH;AAEJ;","names":[]}
|
|
@@ -39,6 +39,7 @@ function ScrollSection({
|
|
|
39
39
|
icon,
|
|
40
40
|
iconBg,
|
|
41
41
|
title,
|
|
42
|
+
subtitle,
|
|
42
43
|
href,
|
|
43
44
|
linkLabel = "See all",
|
|
44
45
|
children
|
|
@@ -47,7 +48,10 @@ function ScrollSection({
|
|
|
47
48
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
48
49
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2.5", children: [
|
|
49
50
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `h-7 w-7 rounded-lg flex items-center justify-center ${iconBg}`, children: icon }),
|
|
50
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
51
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
52
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "text-lg sm:text-xl font-semibold leading-none", children: title }),
|
|
53
|
+
subtitle && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-[10px] text-muted-foreground mt-1", children: subtitle })
|
|
54
|
+
] })
|
|
51
55
|
] }),
|
|
52
56
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
53
57
|
import_link.default,
|
|
@@ -62,7 +66,7 @@ function ScrollSection({
|
|
|
62
66
|
}
|
|
63
67
|
)
|
|
64
68
|
] }),
|
|
65
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "w-full overflow-x-auto scrollbar-hide", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex gap-
|
|
69
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "w-full overflow-x-auto scrollbar-hide", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex gap-5 sm:gap-6 snap-x snap-mandatory pb-2", style: { width: "max-content" }, children }) })
|
|
66
70
|
] });
|
|
67
71
|
}
|
|
68
72
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/scroll-section.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"next/link\";\nimport { ArrowRight } from \"lucide-react\";\n\nexport interface ScrollSectionProps {\n /** Icon element rendered inside the colored badge */\n icon: React.ReactNode;\n /** Tailwind classes for the icon badge (background + shadow) */\n iconBg: string;\n title: string;\n /** \"See all\" link destination */\n href: string;\n /** Button label — defaults to \"See all\" */\n linkLabel?: string;\n /** Scroll items: wrap each in a sized snap-start div */\n children: React.ReactNode;\n}\n\nexport function ScrollSection({\n icon,\n iconBg,\n title,\n href,\n linkLabel = \"See all\",\n children,\n}: ScrollSectionProps) {\n return (\n <section className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2.5\">\n <div className={`h-7 w-7 rounded-lg flex items-center justify-center ${iconBg}`}>\n {icon}\n </div>\n <h2 className=\"text-lg sm:text-xl font-semibold\">{title}</h2>\n </div>\n <Link\n href={href}\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 {linkLabel} <ArrowRight className=\"h-3.5 w-3.5\" />\n </Link>\n </div>\n\n <div className=\"w-full overflow-x-auto scrollbar-hide\">\n <div className=\"flex gap-
|
|
1
|
+
{"version":3,"sources":["../../src/components/scroll-section.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"next/link\";\nimport { ArrowRight } from \"lucide-react\";\n\nexport interface ScrollSectionProps {\n /** Icon element rendered inside the colored badge */\n icon: React.ReactNode;\n /** Tailwind classes for the icon badge (background + shadow) */\n iconBg: string;\n title: string;\n /** Optional small line under the title (e.g. \"Updated 1m ago\") */\n subtitle?: React.ReactNode;\n /** \"See all\" link destination */\n href: string;\n /** Button label — defaults to \"See all\" */\n linkLabel?: string;\n /** Scroll items: wrap each in a sized snap-start div */\n children: React.ReactNode;\n}\n\nexport function ScrollSection({\n icon,\n iconBg,\n title,\n subtitle,\n href,\n linkLabel = \"See all\",\n children,\n}: ScrollSectionProps) {\n return (\n <section className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2.5\">\n <div className={`h-7 w-7 rounded-lg flex items-center justify-center ${iconBg}`}>\n {icon}\n </div>\n <div>\n <h2 className=\"text-lg sm:text-xl font-semibold leading-none\">{title}</h2>\n {subtitle && <p className=\"text-[10px] text-muted-foreground mt-1\">{subtitle}</p>}\n </div>\n </div>\n <Link\n href={href}\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 {linkLabel} <ArrowRight className=\"h-3.5 w-3.5\" />\n </Link>\n </div>\n\n <div className=\"w-full overflow-x-auto scrollbar-hide\">\n <div className=\"flex gap-5 sm:gap-6 snap-x snap-mandatory pb-2\" style={{ width: \"max-content\" }}>\n {children}\n </div>\n </div>\n </section>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAkCU;AAhCV,kBAAiB;AACjB,0BAA2B;AAkBpB,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ;AACF,GAAuB;AACrB,SACE,6CAAC,aAAQ,WAAU,aACjB;AAAA,iDAAC,SAAI,WAAU,qCACb;AAAA,mDAAC,SAAI,WAAU,6BACb;AAAA,oDAAC,SAAI,WAAW,uDAAuD,MAAM,IAC1E,gBACH;AAAA,QACA,6CAAC,SACC;AAAA,sDAAC,QAAG,WAAU,iDAAiD,iBAAM;AAAA,UACpE,YAAY,4CAAC,OAAE,WAAU,0CAA0C,oBAAS;AAAA,WAC/E;AAAA,SACF;AAAA,MACA;AAAA,QAAC,YAAAA;AAAA,QAAA;AAAA,UACC;AAAA,UACA,WAAU;AAAA,UAET;AAAA;AAAA,YAAU;AAAA,YAAC,4CAAC,kCAAW,WAAU,eAAc;AAAA;AAAA;AAAA,MAClD;AAAA,OACF;AAAA,IAEA,4CAAC,SAAI,WAAU,yCACb,sDAAC,SAAI,WAAU,kDAAiD,OAAO,EAAE,OAAO,cAAc,GAC3F,UACH,GACF;AAAA,KACF;AAEJ;","names":["Link"]}
|
|
@@ -6,6 +6,8 @@ interface ScrollSectionProps {
|
|
|
6
6
|
/** Tailwind classes for the icon badge (background + shadow) */
|
|
7
7
|
iconBg: string;
|
|
8
8
|
title: string;
|
|
9
|
+
/** Optional small line under the title (e.g. "Updated 1m ago") */
|
|
10
|
+
subtitle?: React.ReactNode;
|
|
9
11
|
/** "See all" link destination */
|
|
10
12
|
href: string;
|
|
11
13
|
/** Button label — defaults to "See all" */
|
|
@@ -13,6 +15,6 @@ interface ScrollSectionProps {
|
|
|
13
15
|
/** Scroll items: wrap each in a sized snap-start div */
|
|
14
16
|
children: React.ReactNode;
|
|
15
17
|
}
|
|
16
|
-
declare function ScrollSection({ icon, iconBg, title, href, linkLabel, children, }: ScrollSectionProps): react_jsx_runtime.JSX.Element;
|
|
18
|
+
declare function ScrollSection({ icon, iconBg, title, subtitle, href, linkLabel, children, }: ScrollSectionProps): react_jsx_runtime.JSX.Element;
|
|
17
19
|
|
|
18
20
|
export { ScrollSection, type ScrollSectionProps };
|
|
@@ -6,6 +6,8 @@ interface ScrollSectionProps {
|
|
|
6
6
|
/** Tailwind classes for the icon badge (background + shadow) */
|
|
7
7
|
iconBg: string;
|
|
8
8
|
title: string;
|
|
9
|
+
/** Optional small line under the title (e.g. "Updated 1m ago") */
|
|
10
|
+
subtitle?: React.ReactNode;
|
|
9
11
|
/** "See all" link destination */
|
|
10
12
|
href: string;
|
|
11
13
|
/** Button label — defaults to "See all" */
|
|
@@ -13,6 +15,6 @@ interface ScrollSectionProps {
|
|
|
13
15
|
/** Scroll items: wrap each in a sized snap-start div */
|
|
14
16
|
children: React.ReactNode;
|
|
15
17
|
}
|
|
16
|
-
declare function ScrollSection({ icon, iconBg, title, href, linkLabel, children, }: ScrollSectionProps): react_jsx_runtime.JSX.Element;
|
|
18
|
+
declare function ScrollSection({ icon, iconBg, title, subtitle, href, linkLabel, children, }: ScrollSectionProps): react_jsx_runtime.JSX.Element;
|
|
17
19
|
|
|
18
20
|
export { ScrollSection, type ScrollSectionProps };
|