@medialane/ui 0.2.0 → 0.3.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/activity-feed-shell.cjs +90 -0
- package/dist/components/activity-feed-shell.cjs.map +1 -0
- package/dist/components/activity-feed-shell.d.cts +13 -0
- package/dist/components/activity-feed-shell.d.ts +13 -0
- package/dist/components/activity-feed-shell.js +56 -0
- package/dist/components/activity-feed-shell.js.map +1 -0
- package/dist/components/activity-row.cjs +95 -0
- package/dist/components/activity-row.cjs.map +1 -0
- package/dist/components/activity-row.d.cts +20 -0
- package/dist/components/activity-row.d.ts +20 -0
- package/dist/components/activity-row.js +61 -0
- package/dist/components/activity-row.js.map +1 -0
- package/dist/components/activity-ticker.cjs +92 -0
- package/dist/components/activity-ticker.cjs.map +1 -0
- package/dist/components/activity-ticker.d.cts +12 -0
- package/dist/components/activity-ticker.d.ts +12 -0
- package/dist/components/activity-ticker.js +58 -0
- package/dist/components/activity-ticker.js.map +1 -0
- package/dist/components/collection-card.cjs +2 -5
- package/dist/components/collection-card.cjs.map +1 -1
- package/dist/components/collection-card.js +3 -6
- package/dist/components/collection-card.js.map +1 -1
- package/dist/components/cta-card-grid.cjs +67 -0
- package/dist/components/cta-card-grid.cjs.map +1 -0
- package/dist/components/cta-card-grid.d.cts +23 -0
- package/dist/components/cta-card-grid.d.ts +23 -0
- package/dist/components/cta-card-grid.js +33 -0
- package/dist/components/cta-card-grid.js.map +1 -0
- package/dist/components/hero-slider.cjs +133 -0
- package/dist/components/hero-slider.cjs.map +1 -0
- package/dist/components/hero-slider.d.cts +12 -0
- package/dist/components/hero-slider.d.ts +12 -0
- package/dist/components/hero-slider.js +98 -0
- package/dist/components/hero-slider.js.map +1 -0
- package/dist/components/launchpad-grid.cjs +77 -0
- package/dist/components/launchpad-grid.cjs.map +1 -0
- package/dist/components/launchpad-grid.d.cts +20 -0
- package/dist/components/launchpad-grid.d.ts +20 -0
- package/dist/components/launchpad-grid.js +43 -0
- package/dist/components/launchpad-grid.js.map +1 -0
- package/dist/components/listing-card.cjs +146 -0
- package/dist/components/listing-card.cjs.map +1 -0
- package/dist/components/listing-card.d.cts +16 -0
- package/dist/components/listing-card.d.ts +16 -0
- package/dist/components/listing-card.js +111 -0
- package/dist/components/listing-card.js.map +1 -0
- package/dist/data/activity.cjs +48 -0
- package/dist/data/activity.cjs.map +1 -0
- package/dist/data/activity.d.cts +16 -0
- package/dist/data/activity.d.ts +16 -0
- package/dist/data/activity.js +23 -0
- package/dist/data/activity.js.map +1 -0
- package/dist/index.cjs +35 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +22 -1
- package/dist/index.js.map +1 -1
- package/dist/medialane.css +184 -0
- package/dist/utils/time.cjs +42 -0
- package/dist/utils/time.cjs.map +1 -0
- package/dist/utils/time.d.cts +7 -0
- package/dist/utils/time.d.ts +7 -0
- package/dist/utils/time.js +18 -0
- package/dist/utils/time.js.map +1 -0
- package/package.json +3 -2
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useEffect, useCallback } from "react";
|
|
4
|
+
import Link from "next/link";
|
|
5
|
+
import Image from "next/image";
|
|
6
|
+
import { ChevronLeft, ChevronRight, ArrowRight } from "lucide-react";
|
|
7
|
+
import { cn } from "../utils/cn.js";
|
|
8
|
+
function formatFloorPrice(price) {
|
|
9
|
+
if (!price) return "";
|
|
10
|
+
const n = parseFloat(price);
|
|
11
|
+
if (isNaN(n)) return price;
|
|
12
|
+
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
|
|
13
|
+
if (n >= 1) return n.toFixed(2);
|
|
14
|
+
return n.toPrecision(3);
|
|
15
|
+
}
|
|
16
|
+
function ipfsToHttp(uri) {
|
|
17
|
+
if (!uri) return "";
|
|
18
|
+
if (uri.startsWith("ipfs://")) return uri.replace("ipfs://", "https://gateway.pinata.cloud/ipfs/");
|
|
19
|
+
return uri;
|
|
20
|
+
}
|
|
21
|
+
function HeroPlaceholder() {
|
|
22
|
+
return /* @__PURE__ */ jsxs("div", { className: "absolute inset-0 bg-gradient-to-br from-brand-purple/30 via-brand-blue/20 to-brand-navy/50 flex flex-col items-center justify-center gap-4 text-center px-6 overflow-hidden", children: [
|
|
23
|
+
/* @__PURE__ */ jsx("div", { className: "absolute aurora-purple w-[600px] h-[600px] opacity-20 -top-24 -left-24" }),
|
|
24
|
+
/* @__PURE__ */ jsx("div", { className: "absolute aurora-blue w-[400px] h-[400px] opacity-15 -bottom-16 -right-16" }),
|
|
25
|
+
/* @__PURE__ */ jsx("h2", { className: "text-4xl sm:text-6xl font-black gradient-text relative z-10", children: "Medialane" }),
|
|
26
|
+
/* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-lg relative z-10 max-w-md", children: "New monetization revenues for creative works" }),
|
|
27
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-3 relative z-10", children: [
|
|
28
|
+
/* @__PURE__ */ jsx(Link, { href: "/marketplace", className: "inline-flex items-center justify-center rounded-[11px] bg-brand-blue px-4 py-2 text-sm font-semibold text-white hover:brightness-110 active:scale-[0.98] transition-all", children: "Markets" }),
|
|
29
|
+
/* @__PURE__ */ jsx(Link, { href: "/create/asset", className: "inline-flex items-center justify-center rounded-[11px] border border-white/20 bg-background/20 backdrop-blur-sm px-4 py-2 text-sm font-semibold text-white hover:bg-white/10 transition-all", children: "Create" })
|
|
30
|
+
] })
|
|
31
|
+
] });
|
|
32
|
+
}
|
|
33
|
+
function HeroSlide({ collection, active, getHref }) {
|
|
34
|
+
const imageUrl = collection.image ? ipfsToHttp(collection.image) : null;
|
|
35
|
+
const name = collection.name ?? "Collection";
|
|
36
|
+
const floor = collection.floorPrice;
|
|
37
|
+
const supply = collection.totalSupply;
|
|
38
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("absolute inset-0 transition-opacity duration-700", active ? "opacity-100" : "opacity-0 pointer-events-none"), children: [
|
|
39
|
+
imageUrl ? /* @__PURE__ */ jsx("div", { className: "absolute inset-0 overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "animate-kenburns absolute inset-0", children: /* @__PURE__ */ jsx(Image, { src: imageUrl, alt: name, fill: true, className: "object-cover", priority: active, unoptimized: true }) }) }) : /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-br from-brand-purple/40 via-brand-blue/20 to-brand-navy/60" }),
|
|
40
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/40 via-black/30 to-black/0" }),
|
|
41
|
+
/* @__PURE__ */ jsxs("div", { className: "absolute bottom-0 left-0 right-0 p-6 sm:p-10 flex flex-col gap-3", children: [
|
|
42
|
+
/* @__PURE__ */ jsx("h2", { className: "text-4xl lg:text-5xl font-semibold text-white leading-tight", children: name }),
|
|
43
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 text-sm text-white/70", children: [
|
|
44
|
+
supply != null && /* @__PURE__ */ jsxs("span", { children: [
|
|
45
|
+
supply.toLocaleString(),
|
|
46
|
+
" items"
|
|
47
|
+
] }),
|
|
48
|
+
floor && /* @__PURE__ */ jsxs("span", { className: "text-white font-semibold", children: [
|
|
49
|
+
"Floor ",
|
|
50
|
+
formatFloorPrice(floor)
|
|
51
|
+
] })
|
|
52
|
+
] }),
|
|
53
|
+
/* @__PURE__ */ jsxs(
|
|
54
|
+
Link,
|
|
55
|
+
{
|
|
56
|
+
href: getHref(collection),
|
|
57
|
+
className: "self-start mt-2 inline-flex items-center gap-1.5 bg-white text-black hover:bg-white/90 font-semibold px-4 py-2 rounded-[11px] text-sm transition-all active:scale-[0.98]",
|
|
58
|
+
children: [
|
|
59
|
+
"View Collection ",
|
|
60
|
+
/* @__PURE__ */ jsx(ArrowRight, { className: "h-4 w-4" })
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
] })
|
|
65
|
+
] });
|
|
66
|
+
}
|
|
67
|
+
function HeroSliderSkeleton() {
|
|
68
|
+
return /* @__PURE__ */ jsx("section", { className: "relative w-full h-[78vw] min-h-[420px] max-h-[768px] sm:h-[72vh] sm:max-h-[816px] bg-muted animate-pulse" });
|
|
69
|
+
}
|
|
70
|
+
function HeroSlider({ collections, isLoading, getHref }) {
|
|
71
|
+
const [current, setCurrent] = useState(0);
|
|
72
|
+
const count = collections.length;
|
|
73
|
+
const next = useCallback(() => {
|
|
74
|
+
if (count > 1) setCurrent((c) => (c + 1) % count);
|
|
75
|
+
}, [count]);
|
|
76
|
+
const prev = useCallback(() => {
|
|
77
|
+
if (count > 1) setCurrent((c) => (c - 1 + count) % count);
|
|
78
|
+
}, [count]);
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
if (count <= 1) return;
|
|
81
|
+
const id = setInterval(next, 7e3);
|
|
82
|
+
return () => clearInterval(id);
|
|
83
|
+
}, [count, next]);
|
|
84
|
+
if (isLoading) return /* @__PURE__ */ jsx(HeroSliderSkeleton, {});
|
|
85
|
+
return /* @__PURE__ */ jsx("section", { className: "relative w-full h-[78vw] min-h-[420px] max-h-[768px] sm:h-[72vh] sm:max-h-[816px] overflow-hidden bg-muted", children: count === 0 ? /* @__PURE__ */ jsx(HeroPlaceholder, {}) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
86
|
+
collections.map((col, i) => /* @__PURE__ */ jsx(HeroSlide, { collection: col, active: i === current, getHref }, col.contractAddress)),
|
|
87
|
+
count > 1 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
88
|
+
/* @__PURE__ */ jsx("button", { onClick: prev, "aria-label": "Previous slide", className: "absolute left-3 top-1/2 -translate-y-1/2 z-10 h-9 w-9 rounded-full bg-black/40 hover:bg-black/60 backdrop-blur-sm flex items-center justify-center transition-colors", children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-5 w-5 text-white" }) }),
|
|
89
|
+
/* @__PURE__ */ jsx("button", { onClick: next, "aria-label": "Next slide", className: "absolute right-3 top-1/2 -translate-y-1/2 z-10 h-9 w-9 rounded-full bg-black/40 hover:bg-black/60 backdrop-blur-sm flex items-center justify-center transition-colors", children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-5 w-5 text-white" }) }),
|
|
90
|
+
/* @__PURE__ */ jsx("div", { className: "absolute bottom-4 left-1/2 -translate-x-1/2 flex gap-1.5 z-10", children: collections.map((_, i) => /* @__PURE__ */ jsx("button", { onClick: () => setCurrent(i), "aria-label": `Go to slide ${i + 1}`, className: cn("h-1.5 rounded-full transition-all", i === current ? "w-6 bg-white" : "w-1.5 bg-white/40") }, i)) })
|
|
91
|
+
] })
|
|
92
|
+
] }) });
|
|
93
|
+
}
|
|
94
|
+
export {
|
|
95
|
+
HeroSlider,
|
|
96
|
+
HeroSliderSkeleton
|
|
97
|
+
};
|
|
98
|
+
//# sourceMappingURL=hero-slider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/hero-slider.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState, useEffect, useCallback } from \"react\";\nimport Link from \"next/link\";\nimport Image from \"next/image\";\nimport { ChevronLeft, ChevronRight, ArrowRight } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport type { ApiCollection } from \"@medialane/sdk\";\n\nexport interface HeroSliderProps {\n collections: ApiCollection[];\n isLoading: boolean;\n getHref: (collection: ApiCollection) => string;\n}\n\nfunction formatFloorPrice(price: string | null | undefined): string {\n if (!price) return \"\";\n const n = parseFloat(price);\n if (isNaN(n)) return price;\n if (n >= 1000) return `${(n / 1000).toFixed(1)}K`;\n if (n >= 1) return n.toFixed(2);\n return n.toPrecision(3);\n}\n\nfunction ipfsToHttp(uri: string): string {\n if (!uri) return \"\";\n if (uri.startsWith(\"ipfs://\")) return uri.replace(\"ipfs://\", \"https://gateway.pinata.cloud/ipfs/\");\n return uri;\n}\n\nfunction HeroPlaceholder() {\n return (\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/30 via-brand-blue/20 to-brand-navy/50 flex flex-col items-center justify-center gap-4 text-center px-6 overflow-hidden\">\n <div className=\"absolute aurora-purple w-[600px] h-[600px] opacity-20 -top-24 -left-24\" />\n <div className=\"absolute aurora-blue w-[400px] h-[400px] opacity-15 -bottom-16 -right-16\" />\n <h2 className=\"text-4xl sm:text-6xl font-black gradient-text relative z-10\">Medialane</h2>\n <p className=\"text-muted-foreground text-lg relative z-10 max-w-md\">\n New monetization revenues for creative works\n </p>\n <div className=\"flex gap-3 relative z-10\">\n <Link href=\"/marketplace\" className=\"inline-flex items-center justify-center rounded-[11px] bg-brand-blue px-4 py-2 text-sm font-semibold text-white hover:brightness-110 active:scale-[0.98] transition-all\">\n Markets\n </Link>\n <Link href=\"/create/asset\" className=\"inline-flex items-center justify-center rounded-[11px] border border-white/20 bg-background/20 backdrop-blur-sm px-4 py-2 text-sm font-semibold text-white hover:bg-white/10 transition-all\">\n Create\n </Link>\n </div>\n </div>\n );\n}\n\nfunction HeroSlide({ collection, active, getHref }: { collection: ApiCollection; active: boolean; getHref: (col: ApiCollection) => string }) {\n const imageUrl = collection.image ? ipfsToHttp(collection.image) : null;\n const name = collection.name ?? \"Collection\";\n const floor = collection.floorPrice;\n const supply = collection.totalSupply;\n\n return (\n <div className={cn(\"absolute inset-0 transition-opacity duration-700\", active ? \"opacity-100\" : \"opacity-0 pointer-events-none\")}>\n {imageUrl ? (\n <div className=\"absolute inset-0 overflow-hidden\">\n <div className=\"animate-kenburns absolute inset-0\">\n <Image src={imageUrl} alt={name} fill className=\"object-cover\" priority={active} unoptimized />\n </div>\n </div>\n ) : (\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/40 via-brand-blue/20 to-brand-navy/60\" />\n )}\n <div className=\"absolute inset-0 bg-gradient-to-t from-black/40 via-black/30 to-black/0\" />\n <div className=\"absolute bottom-0 left-0 right-0 p-6 sm:p-10 flex flex-col gap-3\">\n <h2 className=\"text-4xl lg:text-5xl font-semibold text-white leading-tight\">{name}</h2>\n <div className=\"flex items-center gap-4 text-sm text-white/70\">\n {supply != null && <span>{supply.toLocaleString()} items</span>}\n {floor && <span className=\"text-white font-semibold\">Floor {formatFloorPrice(floor)}</span>}\n </div>\n <Link\n href={getHref(collection)}\n className=\"self-start mt-2 inline-flex items-center gap-1.5 bg-white text-black hover:bg-white/90 font-semibold px-4 py-2 rounded-[11px] text-sm transition-all active:scale-[0.98]\"\n >\n View Collection <ArrowRight className=\"h-4 w-4\" />\n </Link>\n </div>\n </div>\n );\n}\n\nexport function HeroSliderSkeleton() {\n return <section className=\"relative w-full h-[78vw] min-h-[420px] max-h-[768px] sm:h-[72vh] sm:max-h-[816px] bg-muted animate-pulse\" />;\n}\n\nexport function HeroSlider({ collections, isLoading, getHref }: HeroSliderProps) {\n const [current, setCurrent] = useState(0);\n const count = collections.length;\n\n const next = useCallback(() => { if (count > 1) setCurrent((c) => (c + 1) % count); }, [count]);\n const prev = useCallback(() => { if (count > 1) setCurrent((c) => (c - 1 + count) % count); }, [count]);\n\n useEffect(() => {\n if (count <= 1) return;\n const id = setInterval(next, 7000);\n return () => clearInterval(id);\n }, [count, next]);\n\n if (isLoading) return <HeroSliderSkeleton />;\n\n return (\n <section className=\"relative w-full h-[78vw] min-h-[420px] max-h-[768px] sm:h-[72vh] sm:max-h-[816px] overflow-hidden bg-muted\">\n {count === 0 ? (\n <HeroPlaceholder />\n ) : (\n <>\n {collections.map((col, i) => (\n <HeroSlide key={col.contractAddress} collection={col} active={i === current} getHref={getHref} />\n ))}\n {count > 1 && (\n <>\n <button onClick={prev} aria-label=\"Previous slide\" className=\"absolute left-3 top-1/2 -translate-y-1/2 z-10 h-9 w-9 rounded-full bg-black/40 hover:bg-black/60 backdrop-blur-sm flex items-center justify-center transition-colors\">\n <ChevronLeft className=\"h-5 w-5 text-white\" />\n </button>\n <button onClick={next} aria-label=\"Next slide\" className=\"absolute right-3 top-1/2 -translate-y-1/2 z-10 h-9 w-9 rounded-full bg-black/40 hover:bg-black/60 backdrop-blur-sm flex items-center justify-center transition-colors\">\n <ChevronRight className=\"h-5 w-5 text-white\" />\n </button>\n <div className=\"absolute bottom-4 left-1/2 -translate-x-1/2 flex gap-1.5 z-10\">\n {collections.map((_, i) => (\n <button key={i} onClick={() => setCurrent(i)} aria-label={`Go to slide ${i + 1}`} className={cn(\"h-1.5 rounded-full transition-all\", i === current ? \"w-6 bg-white\" : \"w-1.5 bg-white/40\")} />\n ))}\n </div>\n </>\n )}\n </>\n )}\n </section>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,77 @@
|
|
|
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_grid_exports = {};
|
|
31
|
+
__export(launchpad_grid_exports, {
|
|
32
|
+
LaunchpadGrid: () => LaunchpadGrid
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(launchpad_grid_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
|
+
function ServiceCard({ feature }) {
|
|
39
|
+
const { icon: Icon, label, subtitle, accent, href } = feature;
|
|
40
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_link.default, { href, className: "group block", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "card-base overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: `relative aspect-[3/4] w-full bg-gradient-to-br ${accent}`, children: [
|
|
41
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute inset-0 bg-[radial-gradient(ellipse_at_30%_25%,rgba(255,255,255,0.14),transparent_60%)]" }),
|
|
42
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute -bottom-6 -right-6 opacity-[0.12] pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { className: "h-36 w-36 text-white" }) }),
|
|
43
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "absolute inset-0 flex flex-col justify-between p-4", children: [
|
|
44
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-11 w-11 rounded-2xl bg-white/10 backdrop-blur-sm flex items-center justify-center ring-1 ring-white/20 group-hover:bg-white/[0.18] transition-colors duration-300", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { className: "h-5 w-5 text-white" }) }),
|
|
45
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
46
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-lg font-black text-white leading-tight tracking-tight", children: label }),
|
|
47
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs text-white/65 mt-1.5 leading-relaxed", children: subtitle })
|
|
48
|
+
] })
|
|
49
|
+
] })
|
|
50
|
+
] }) }) });
|
|
51
|
+
}
|
|
52
|
+
function LaunchpadGrid({
|
|
53
|
+
title = "Creator Launchpad",
|
|
54
|
+
titleHref = "/launchpad",
|
|
55
|
+
titleHrefLabel = "All services",
|
|
56
|
+
features
|
|
57
|
+
}) {
|
|
58
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "space-y-4", children: [
|
|
59
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
60
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2.5", children: [
|
|
61
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-7 w-7 rounded-lg bg-gradient-to-br from-primary to-purple-600 flex items-center justify-center shadow-md shadow-primary/20", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Rocket, { className: "h-3.5 w-3.5 text-white" }) }),
|
|
62
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "text-lg sm:text-xl font-semibold", children: title })
|
|
63
|
+
] }),
|
|
64
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_link.default, { href: titleHref, 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", children: [
|
|
65
|
+
titleHrefLabel,
|
|
66
|
+
" ",
|
|
67
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ArrowRight, { className: "h-3.5 w-3.5" })
|
|
68
|
+
] })
|
|
69
|
+
] }),
|
|
70
|
+
/* @__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-3 snap-x snap-mandatory pb-2", style: { width: "max-content" }, children: features.map((f) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "w-56 sm:w-64 snap-start shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ServiceCard, { feature: f }) }, f.label)) }) })
|
|
71
|
+
] });
|
|
72
|
+
}
|
|
73
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
74
|
+
0 && (module.exports = {
|
|
75
|
+
LaunchpadGrid
|
|
76
|
+
});
|
|
77
|
+
//# sourceMappingURL=launchpad-grid.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/launchpad-grid.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"next/link\";\nimport { ArrowRight, Rocket, type LucideIcon } from \"lucide-react\";\n\nexport interface FeatureItem {\n icon: LucideIcon;\n label: string;\n subtitle: string;\n /** Tailwind gradient string e.g. \"from-violet-500 to-purple-600\" */\n accent: string;\n href: string;\n}\n\nexport interface LaunchpadGridProps {\n title?: string;\n titleHref?: string;\n titleHrefLabel?: string;\n features: FeatureItem[];\n}\n\nfunction ServiceCard({ feature }: { feature: FeatureItem }) {\n const { icon: Icon, label, subtitle, accent, href } = feature;\n return (\n <Link href={href} className=\"group block\">\n <div className=\"card-base overflow-hidden\">\n <div className={`relative aspect-[3/4] w-full bg-gradient-to-br ${accent}`}>\n <div className=\"absolute inset-0 bg-[radial-gradient(ellipse_at_30%_25%,rgba(255,255,255,0.14),transparent_60%)]\" />\n <div className=\"absolute -bottom-6 -right-6 opacity-[0.12] pointer-events-none\">\n <Icon className=\"h-36 w-36 text-white\" />\n </div>\n <div className=\"absolute inset-0 flex flex-col justify-between p-4\">\n <div className=\"h-11 w-11 rounded-2xl bg-white/10 backdrop-blur-sm flex items-center justify-center ring-1 ring-white/20 group-hover:bg-white/[0.18] transition-colors duration-300\">\n <Icon className=\"h-5 w-5 text-white\" />\n </div>\n <div>\n <p className=\"text-lg font-black text-white leading-tight tracking-tight\">{label}</p>\n <p className=\"text-xs text-white/65 mt-1.5 leading-relaxed\">{subtitle}</p>\n </div>\n </div>\n </div>\n </div>\n </Link>\n );\n}\n\nexport function LaunchpadGrid({\n title = \"Creator Launchpad\",\n titleHref = \"/launchpad\",\n titleHrefLabel = \"All services\",\n features,\n}: LaunchpadGridProps) {\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 bg-gradient-to-br from-primary to-purple-600 flex items-center justify-center shadow-md shadow-primary/20\">\n <Rocket className=\"h-3.5 w-3.5 text-white\" />\n </div>\n <h2 className=\"text-lg sm:text-xl font-semibold\">{title}</h2>\n </div>\n <Link href={titleHref} 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 {titleHrefLabel} <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-3 snap-x snap-mandatory pb-2\" style={{ width: \"max-content\" }}>\n {features.map((f) => (\n <div key={f.label} className=\"w-56 sm:w-64 snap-start shrink-0\">\n <ServiceCard feature={f} />\n </div>\n ))}\n </div>\n </div>\n </section>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA2BU;AAzBV,kBAAiB;AACjB,0BAAoD;AAkBpD,SAAS,YAAY,EAAE,QAAQ,GAA6B;AAC1D,QAAM,EAAE,MAAM,MAAM,OAAO,UAAU,QAAQ,KAAK,IAAI;AACtD,SACE,4CAAC,YAAAA,SAAA,EAAK,MAAY,WAAU,eAC1B,sDAAC,SAAI,WAAU,6BACb,uDAAC,SAAI,WAAW,kDAAkD,MAAM,IACtE;AAAA,gDAAC,SAAI,WAAU,oGAAmG;AAAA,IAClH,4CAAC,SAAI,WAAU,kEACb,sDAAC,QAAK,WAAU,wBAAuB,GACzC;AAAA,IACA,6CAAC,SAAI,WAAU,sDACb;AAAA,kDAAC,SAAI,WAAU,uKACb,sDAAC,QAAK,WAAU,sBAAqB,GACvC;AAAA,MACA,6CAAC,SACC;AAAA,oDAAC,OAAE,WAAU,8DAA8D,iBAAM;AAAA,QACjF,4CAAC,OAAE,WAAU,gDAAgD,oBAAS;AAAA,SACxE;AAAA,OACF;AAAA,KACF,GACF,GACF;AAEJ;AAEO,SAAS,cAAc;AAAA,EAC5B,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB;AACF,GAAuB;AACrB,SACE,6CAAC,aAAQ,WAAU,aACjB;AAAA,iDAAC,SAAI,WAAU,qCACb;AAAA,mDAAC,SAAI,WAAU,6BACb;AAAA,oDAAC,SAAI,WAAU,gIACb,sDAAC,8BAAO,WAAU,0BAAyB,GAC7C;AAAA,QACA,4CAAC,QAAG,WAAU,oCAAoC,iBAAM;AAAA,SAC1D;AAAA,MACA,6CAAC,YAAAA,SAAA,EAAK,MAAM,WAAW,WAAU,+IAC9B;AAAA;AAAA,QAAe;AAAA,QAAC,4CAAC,kCAAW,WAAU,eAAc;AAAA,SACvD;AAAA,OACF;AAAA,IAEA,4CAAC,SAAI,WAAU,yCACb,sDAAC,SAAI,WAAU,yCAAwC,OAAO,EAAE,OAAO,cAAc,GAClF,mBAAS,IAAI,CAAC,MACb,4CAAC,SAAkB,WAAU,oCAC3B,sDAAC,eAAY,SAAS,GAAG,KADjB,EAAE,KAEZ,CACD,GACH,GACF;AAAA,KACF;AAEJ;","names":["Link"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { LucideIcon } from 'lucide-react';
|
|
3
|
+
|
|
4
|
+
interface FeatureItem {
|
|
5
|
+
icon: LucideIcon;
|
|
6
|
+
label: string;
|
|
7
|
+
subtitle: string;
|
|
8
|
+
/** Tailwind gradient string e.g. "from-violet-500 to-purple-600" */
|
|
9
|
+
accent: string;
|
|
10
|
+
href: string;
|
|
11
|
+
}
|
|
12
|
+
interface LaunchpadGridProps {
|
|
13
|
+
title?: string;
|
|
14
|
+
titleHref?: string;
|
|
15
|
+
titleHrefLabel?: string;
|
|
16
|
+
features: FeatureItem[];
|
|
17
|
+
}
|
|
18
|
+
declare function LaunchpadGrid({ title, titleHref, titleHrefLabel, features, }: LaunchpadGridProps): react_jsx_runtime.JSX.Element;
|
|
19
|
+
|
|
20
|
+
export { type FeatureItem, LaunchpadGrid, type LaunchpadGridProps };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { LucideIcon } from 'lucide-react';
|
|
3
|
+
|
|
4
|
+
interface FeatureItem {
|
|
5
|
+
icon: LucideIcon;
|
|
6
|
+
label: string;
|
|
7
|
+
subtitle: string;
|
|
8
|
+
/** Tailwind gradient string e.g. "from-violet-500 to-purple-600" */
|
|
9
|
+
accent: string;
|
|
10
|
+
href: string;
|
|
11
|
+
}
|
|
12
|
+
interface LaunchpadGridProps {
|
|
13
|
+
title?: string;
|
|
14
|
+
titleHref?: string;
|
|
15
|
+
titleHrefLabel?: string;
|
|
16
|
+
features: FeatureItem[];
|
|
17
|
+
}
|
|
18
|
+
declare function LaunchpadGrid({ title, titleHref, titleHrefLabel, features, }: LaunchpadGridProps): react_jsx_runtime.JSX.Element;
|
|
19
|
+
|
|
20
|
+
export { type FeatureItem, LaunchpadGrid, type LaunchpadGridProps };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import Link from "next/link";
|
|
4
|
+
import { ArrowRight, Rocket } from "lucide-react";
|
|
5
|
+
function ServiceCard({ feature }) {
|
|
6
|
+
const { icon: Icon, label, subtitle, accent, href } = feature;
|
|
7
|
+
return /* @__PURE__ */ jsx(Link, { href, className: "group block", children: /* @__PURE__ */ jsx("div", { className: "card-base overflow-hidden", children: /* @__PURE__ */ jsxs("div", { className: `relative aspect-[3/4] w-full bg-gradient-to-br ${accent}`, children: [
|
|
8
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-[radial-gradient(ellipse_at_30%_25%,rgba(255,255,255,0.14),transparent_60%)]" }),
|
|
9
|
+
/* @__PURE__ */ jsx("div", { className: "absolute -bottom-6 -right-6 opacity-[0.12] pointer-events-none", children: /* @__PURE__ */ jsx(Icon, { className: "h-36 w-36 text-white" }) }),
|
|
10
|
+
/* @__PURE__ */ jsxs("div", { className: "absolute inset-0 flex flex-col justify-between p-4", children: [
|
|
11
|
+
/* @__PURE__ */ jsx("div", { className: "h-11 w-11 rounded-2xl bg-white/10 backdrop-blur-sm flex items-center justify-center ring-1 ring-white/20 group-hover:bg-white/[0.18] transition-colors duration-300", children: /* @__PURE__ */ jsx(Icon, { className: "h-5 w-5 text-white" }) }),
|
|
12
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
13
|
+
/* @__PURE__ */ jsx("p", { className: "text-lg font-black text-white leading-tight tracking-tight", children: label }),
|
|
14
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-white/65 mt-1.5 leading-relaxed", children: subtitle })
|
|
15
|
+
] })
|
|
16
|
+
] })
|
|
17
|
+
] }) }) });
|
|
18
|
+
}
|
|
19
|
+
function LaunchpadGrid({
|
|
20
|
+
title = "Creator Launchpad",
|
|
21
|
+
titleHref = "/launchpad",
|
|
22
|
+
titleHrefLabel = "All services",
|
|
23
|
+
features
|
|
24
|
+
}) {
|
|
25
|
+
return /* @__PURE__ */ jsxs("section", { className: "space-y-4", children: [
|
|
26
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
27
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5", children: [
|
|
28
|
+
/* @__PURE__ */ jsx("div", { className: "h-7 w-7 rounded-lg bg-gradient-to-br from-primary to-purple-600 flex items-center justify-center shadow-md shadow-primary/20", children: /* @__PURE__ */ jsx(Rocket, { className: "h-3.5 w-3.5 text-white" }) }),
|
|
29
|
+
/* @__PURE__ */ jsx("h2", { className: "text-lg sm:text-xl font-semibold", children: title })
|
|
30
|
+
] }),
|
|
31
|
+
/* @__PURE__ */ jsxs(Link, { href: titleHref, 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", children: [
|
|
32
|
+
titleHrefLabel,
|
|
33
|
+
" ",
|
|
34
|
+
/* @__PURE__ */ jsx(ArrowRight, { className: "h-3.5 w-3.5" })
|
|
35
|
+
] })
|
|
36
|
+
] }),
|
|
37
|
+
/* @__PURE__ */ jsx("div", { className: "w-full overflow-x-auto scrollbar-hide", children: /* @__PURE__ */ jsx("div", { className: "flex gap-3 snap-x snap-mandatory pb-2", style: { width: "max-content" }, children: features.map((f) => /* @__PURE__ */ jsx("div", { className: "w-56 sm:w-64 snap-start shrink-0", children: /* @__PURE__ */ jsx(ServiceCard, { feature: f }) }, f.label)) }) })
|
|
38
|
+
] });
|
|
39
|
+
}
|
|
40
|
+
export {
|
|
41
|
+
LaunchpadGrid
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=launchpad-grid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/launchpad-grid.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"next/link\";\nimport { ArrowRight, Rocket, type LucideIcon } from \"lucide-react\";\n\nexport interface FeatureItem {\n icon: LucideIcon;\n label: string;\n subtitle: string;\n /** Tailwind gradient string e.g. \"from-violet-500 to-purple-600\" */\n accent: string;\n href: string;\n}\n\nexport interface LaunchpadGridProps {\n title?: string;\n titleHref?: string;\n titleHrefLabel?: string;\n features: FeatureItem[];\n}\n\nfunction ServiceCard({ feature }: { feature: FeatureItem }) {\n const { icon: Icon, label, subtitle, accent, href } = feature;\n return (\n <Link href={href} className=\"group block\">\n <div className=\"card-base overflow-hidden\">\n <div className={`relative aspect-[3/4] w-full bg-gradient-to-br ${accent}`}>\n <div className=\"absolute inset-0 bg-[radial-gradient(ellipse_at_30%_25%,rgba(255,255,255,0.14),transparent_60%)]\" />\n <div className=\"absolute -bottom-6 -right-6 opacity-[0.12] pointer-events-none\">\n <Icon className=\"h-36 w-36 text-white\" />\n </div>\n <div className=\"absolute inset-0 flex flex-col justify-between p-4\">\n <div className=\"h-11 w-11 rounded-2xl bg-white/10 backdrop-blur-sm flex items-center justify-center ring-1 ring-white/20 group-hover:bg-white/[0.18] transition-colors duration-300\">\n <Icon className=\"h-5 w-5 text-white\" />\n </div>\n <div>\n <p className=\"text-lg font-black text-white leading-tight tracking-tight\">{label}</p>\n <p className=\"text-xs text-white/65 mt-1.5 leading-relaxed\">{subtitle}</p>\n </div>\n </div>\n </div>\n </div>\n </Link>\n );\n}\n\nexport function LaunchpadGrid({\n title = \"Creator Launchpad\",\n titleHref = \"/launchpad\",\n titleHrefLabel = \"All services\",\n features,\n}: LaunchpadGridProps) {\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 bg-gradient-to-br from-primary to-purple-600 flex items-center justify-center shadow-md shadow-primary/20\">\n <Rocket className=\"h-3.5 w-3.5 text-white\" />\n </div>\n <h2 className=\"text-lg sm:text-xl font-semibold\">{title}</h2>\n </div>\n <Link href={titleHref} 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 {titleHrefLabel} <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-3 snap-x snap-mandatory pb-2\" style={{ width: \"max-content\" }}>\n {features.map((f) => (\n <div key={f.label} className=\"w-56 sm:w-64 snap-start shrink-0\">\n <ServiceCard feature={f} />\n </div>\n ))}\n </div>\n </div>\n </section>\n );\n}\n"],"mappings":";AA2BU,cAQE,YARF;AAzBV,OAAO,UAAU;AACjB,SAAS,YAAY,cAA+B;AAkBpD,SAAS,YAAY,EAAE,QAAQ,GAA6B;AAC1D,QAAM,EAAE,MAAM,MAAM,OAAO,UAAU,QAAQ,KAAK,IAAI;AACtD,SACE,oBAAC,QAAK,MAAY,WAAU,eAC1B,8BAAC,SAAI,WAAU,6BACb,+BAAC,SAAI,WAAW,kDAAkD,MAAM,IACtE;AAAA,wBAAC,SAAI,WAAU,oGAAmG;AAAA,IAClH,oBAAC,SAAI,WAAU,kEACb,8BAAC,QAAK,WAAU,wBAAuB,GACzC;AAAA,IACA,qBAAC,SAAI,WAAU,sDACb;AAAA,0BAAC,SAAI,WAAU,uKACb,8BAAC,QAAK,WAAU,sBAAqB,GACvC;AAAA,MACA,qBAAC,SACC;AAAA,4BAAC,OAAE,WAAU,8DAA8D,iBAAM;AAAA,QACjF,oBAAC,OAAE,WAAU,gDAAgD,oBAAS;AAAA,SACxE;AAAA,OACF;AAAA,KACF,GACF,GACF;AAEJ;AAEO,SAAS,cAAc;AAAA,EAC5B,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB;AACF,GAAuB;AACrB,SACE,qBAAC,aAAQ,WAAU,aACjB;AAAA,yBAAC,SAAI,WAAU,qCACb;AAAA,2BAAC,SAAI,WAAU,6BACb;AAAA,4BAAC,SAAI,WAAU,gIACb,8BAAC,UAAO,WAAU,0BAAyB,GAC7C;AAAA,QACA,oBAAC,QAAG,WAAU,oCAAoC,iBAAM;AAAA,SAC1D;AAAA,MACA,qBAAC,QAAK,MAAM,WAAW,WAAU,+IAC9B;AAAA;AAAA,QAAe;AAAA,QAAC,oBAAC,cAAW,WAAU,eAAc;AAAA,SACvD;AAAA,OACF;AAAA,IAEA,oBAAC,SAAI,WAAU,yCACb,8BAAC,SAAI,WAAU,yCAAwC,OAAO,EAAE,OAAO,cAAc,GAClF,mBAAS,IAAI,CAAC,MACb,oBAAC,SAAkB,WAAU,oCAC3B,8BAAC,eAAY,SAAS,GAAG,KADjB,EAAE,KAEZ,CACD,GACH,GACF;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -0,0 +1,146 @@
|
|
|
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 listing_card_exports = {};
|
|
31
|
+
__export(listing_card_exports, {
|
|
32
|
+
ListingCard: () => ListingCard,
|
|
33
|
+
ListingCardSkeleton: () => ListingCardSkeleton
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(listing_card_exports);
|
|
36
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
37
|
+
var import_react = require("react");
|
|
38
|
+
var import_link = __toESM(require("next/link"), 1);
|
|
39
|
+
var import_image = __toESM(require("next/image"), 1);
|
|
40
|
+
var import_lucide_react = require("lucide-react");
|
|
41
|
+
var import_motion_primitives = require("./motion-primitives.js");
|
|
42
|
+
var import_currency_icon = require("./currency-icon.js");
|
|
43
|
+
var import_cn = require("../utils/cn.js");
|
|
44
|
+
var import_ipfs = require("../utils/ipfs.js");
|
|
45
|
+
var import_format = require("../utils/format.js");
|
|
46
|
+
var import_time = require("../utils/time.js");
|
|
47
|
+
function ListingCard({ order, inCart = false, onBuy, onCart, overflowMenu, compact = false }) {
|
|
48
|
+
const [imgError, setImgError] = (0, import_react.useState)(false);
|
|
49
|
+
const isListing = order.offer.itemType === "ERC721" || order.offer.itemType === "ERC1155";
|
|
50
|
+
const name = order.token?.name ?? `Token #${order.nftTokenId}`;
|
|
51
|
+
const image = order.token?.image ? (0, import_ipfs.ipfsToHttp)(order.token.image) : null;
|
|
52
|
+
const assetHref = `/asset/${order.nftContract}/${order.nftTokenId}`;
|
|
53
|
+
const showActionBar = isListing && (onBuy || onCart || overflowMenu);
|
|
54
|
+
if (compact) {
|
|
55
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_motion_primitives.MotionCard, { className: "card-base", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_link.default, { href: assetHref, className: "block", children: [
|
|
56
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "relative aspect-square bg-muted overflow-hidden", children: image && !imgError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_image.default, { src: image, alt: name, fill: true, unoptimized: true, sizes: "(max-width: 640px) 33vw, 20vw", className: "object-cover group-hover:scale-105 transition-transform duration-500", onError: () => setImgError(true) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute inset-0 flex items-center justify-center bg-gradient-to-br from-brand-purple/15 to-brand-blue/15", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "text-xl font-mono text-muted-foreground", children: [
|
|
57
|
+
"#",
|
|
58
|
+
order.nftTokenId
|
|
59
|
+
] }) }) }),
|
|
60
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "p-2.5 space-y-0.5", children: [
|
|
61
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs font-semibold truncate", children: name }),
|
|
62
|
+
order.price?.formatted && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-[11px] font-bold price-value", children: [
|
|
63
|
+
(0, import_format.formatDisplayPrice)(order.price.formatted),
|
|
64
|
+
" ",
|
|
65
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-muted-foreground font-normal", children: order.price.currency })
|
|
66
|
+
] }),
|
|
67
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-[10px] text-muted-foreground", children: (0, import_time.timeAgo)(order.createdAt) })
|
|
68
|
+
] })
|
|
69
|
+
] }) });
|
|
70
|
+
}
|
|
71
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_motion_primitives.MotionCard, { className: "card-base", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_link.default, { href: assetHref, className: "block", children: [
|
|
72
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "relative aspect-square bg-muted overflow-hidden", children: image && !imgError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_image.default, { src: image, alt: name, fill: true, unoptimized: true, sizes: "(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 25vw", className: "object-cover group-hover:scale-105 transition-transform duration-500", onError: () => setImgError(true) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute inset-0 flex items-center justify-center bg-gradient-to-br from-brand-purple/15 to-brand-blue/15", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "text-2xl font-mono text-muted-foreground", children: [
|
|
73
|
+
"#",
|
|
74
|
+
order.nftTokenId
|
|
75
|
+
] }) }) }),
|
|
76
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "p-4 space-y-3", children: [
|
|
77
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
78
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "font-semibold text-base truncate leading-snug", children: name }),
|
|
79
|
+
order.token?.description ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-[11px] text-muted-foreground line-clamp-1 leading-snug mt-0.5", children: order.token.description }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-[11px] text-muted-foreground", children: [
|
|
80
|
+
"#",
|
|
81
|
+
order.nftTokenId
|
|
82
|
+
] })
|
|
83
|
+
] }),
|
|
84
|
+
order.price?.formatted && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
85
|
+
order.price.currency && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_currency_icon.CurrencyIcon, { symbol: order.price.currency, size: 14 }),
|
|
86
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-lg font-bold price-value leading-none", children: [
|
|
87
|
+
(0, import_format.formatDisplayPrice)(order.price.formatted),
|
|
88
|
+
" ",
|
|
89
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-muted-foreground font-normal text-sm", children: order.price.currency })
|
|
90
|
+
] })
|
|
91
|
+
] }),
|
|
92
|
+
showActionBar && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
93
|
+
onBuy && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "btn-border-animated p-[1.5px] rounded-[10px] flex-1 h-9", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
94
|
+
"button",
|
|
95
|
+
{
|
|
96
|
+
className: "w-full h-full rounded-[9px] bg-background flex items-center justify-center gap-1.5 text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]",
|
|
97
|
+
onClick: (e) => {
|
|
98
|
+
e.preventDefault();
|
|
99
|
+
onBuy(order);
|
|
100
|
+
},
|
|
101
|
+
children: [
|
|
102
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Zap, { className: "h-3.5 w-3.5 shrink-0" }),
|
|
103
|
+
" Buy"
|
|
104
|
+
]
|
|
105
|
+
}
|
|
106
|
+
) }),
|
|
107
|
+
onCart && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
108
|
+
"button",
|
|
109
|
+
{
|
|
110
|
+
className: (0, import_cn.cn)(
|
|
111
|
+
"h-9 w-9 shrink-0 rounded-[9px] border flex items-center justify-center transition-colors",
|
|
112
|
+
inCart ? "border-brand-orange/50 bg-brand-orange/10 text-brand-orange" : "border-border bg-background hover:bg-muted text-foreground"
|
|
113
|
+
),
|
|
114
|
+
onClick: (e) => {
|
|
115
|
+
e.preventDefault();
|
|
116
|
+
if (!inCart) onCart(order);
|
|
117
|
+
},
|
|
118
|
+
disabled: inCart,
|
|
119
|
+
"aria-label": inCart ? "Added to cart" : "Add to cart",
|
|
120
|
+
children: inCart ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Check, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ShoppingCart, { className: "h-3.5 w-3.5" })
|
|
121
|
+
}
|
|
122
|
+
),
|
|
123
|
+
overflowMenu
|
|
124
|
+
] })
|
|
125
|
+
] })
|
|
126
|
+
] }) });
|
|
127
|
+
}
|
|
128
|
+
function ListingCardSkeleton() {
|
|
129
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "card-base", children: [
|
|
130
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "aspect-square w-full bg-muted animate-pulse" }),
|
|
131
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "p-3 space-y-2.5", children: [
|
|
132
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-1", children: [
|
|
133
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-4 w-3/4 bg-muted animate-pulse rounded" }),
|
|
134
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-3 w-1/2 bg-muted animate-pulse rounded" })
|
|
135
|
+
] }),
|
|
136
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-6 w-1/2 bg-muted animate-pulse rounded" }),
|
|
137
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-3 w-2/3 bg-muted animate-pulse rounded" })
|
|
138
|
+
] })
|
|
139
|
+
] });
|
|
140
|
+
}
|
|
141
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
142
|
+
0 && (module.exports = {
|
|
143
|
+
ListingCard,
|
|
144
|
+
ListingCardSkeleton
|
|
145
|
+
});
|
|
146
|
+
//# sourceMappingURL=listing-card.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/listing-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"next/link\";\nimport Image from \"next/image\";\nimport { ShoppingCart, Check, Zap } from \"lucide-react\";\nimport { MotionCard } from \"./motion-primitives.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport type { ApiOrder } from \"@medialane/sdk\";\n\nexport interface ListingCardProps {\n order: ApiOrder;\n inCart?: boolean;\n onBuy?: (order: ApiOrder) => void;\n onCart?: (order: ApiOrder) => void;\n /** App passes a fully constructed <DropdownMenu> here */\n overflowMenu?: React.ReactNode;\n compact?: boolean;\n}\n\nexport function ListingCard({ order, inCart = false, onBuy, onCart, overflowMenu, compact = false }: ListingCardProps) {\n const [imgError, setImgError] = useState(false);\n const isListing = order.offer.itemType === \"ERC721\" || order.offer.itemType === \"ERC1155\";\n const name = order.token?.name ?? `Token #${order.nftTokenId}`;\n const image = order.token?.image ? ipfsToHttp(order.token.image) : null;\n const assetHref = `/asset/${order.nftContract}/${order.nftTokenId}`;\n\n const showActionBar = isListing && (onBuy || onCart || overflowMenu);\n\n // ─── Compact variant ──────────────────────────────────────────────────────\n if (compact) {\n return (\n <MotionCard className=\"card-base\">\n <Link href={assetHref} className=\"block\">\n <div className=\"relative aspect-square bg-muted overflow-hidden\">\n {image && !imgError ? (\n <Image src={image} alt={name} fill unoptimized sizes=\"(max-width: 640px) 33vw, 20vw\" className=\"object-cover group-hover:scale-105 transition-transform duration-500\" onError={() => setImgError(true)} />\n ) : (\n <div className=\"absolute inset-0 flex items-center justify-center bg-gradient-to-br from-brand-purple/15 to-brand-blue/15\">\n <span className=\"text-xl font-mono text-muted-foreground\">#{order.nftTokenId}</span>\n </div>\n )}\n </div>\n <div className=\"p-2.5 space-y-0.5\">\n <p className=\"text-xs font-semibold truncate\">{name}</p>\n {order.price?.formatted && (\n <p className=\"text-[11px] font-bold price-value\">\n {formatDisplayPrice(order.price.formatted)} <span className=\"text-muted-foreground font-normal\">{order.price.currency}</span>\n </p>\n )}\n <p className=\"text-[10px] text-muted-foreground\">{timeAgo(order.createdAt)}</p>\n </div>\n </Link>\n </MotionCard>\n );\n }\n\n // ─── Full variant ─────────────────────────────────────────────────────────\n return (\n <MotionCard className=\"card-base\">\n <Link href={assetHref} className=\"block\">\n <div className=\"relative aspect-square bg-muted overflow-hidden\">\n {image && !imgError ? (\n <Image src={image} alt={name} fill unoptimized sizes=\"(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 25vw\" className=\"object-cover group-hover:scale-105 transition-transform duration-500\" onError={() => setImgError(true)} />\n ) : (\n <div className=\"absolute inset-0 flex items-center justify-center bg-gradient-to-br from-brand-purple/15 to-brand-blue/15\">\n <span className=\"text-2xl font-mono text-muted-foreground\">#{order.nftTokenId}</span>\n </div>\n )}\n </div>\n\n <div className=\"p-4 space-y-3\">\n <div>\n <p className=\"font-semibold text-base truncate leading-snug\">{name}</p>\n {order.token?.description ? (\n <p className=\"text-[11px] text-muted-foreground line-clamp-1 leading-snug mt-0.5\">{order.token.description}</p>\n ) : (\n <p className=\"text-[11px] text-muted-foreground\">#{order.nftTokenId}</p>\n )}\n </div>\n\n {order.price?.formatted && (\n <div className=\"flex items-center gap-1.5\">\n {order.price.currency && <CurrencyIcon symbol={order.price.currency} size={14} />}\n <p className=\"text-lg font-bold price-value leading-none\">\n {formatDisplayPrice(order.price.formatted)} <span className=\"text-muted-foreground font-normal text-sm\">{order.price.currency}</span>\n </p>\n </div>\n )}\n\n {showActionBar && (\n <div className=\"flex items-center gap-1.5\">\n {onBuy && (\n <div className=\"btn-border-animated p-[1.5px] rounded-[10px] flex-1 h-9\">\n <button\n className=\"w-full h-full rounded-[9px] bg-background flex items-center justify-center gap-1.5 text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n onClick={(e) => { e.preventDefault(); onBuy(order); }}\n >\n <Zap className=\"h-3.5 w-3.5 shrink-0\" /> Buy\n </button>\n </div>\n )}\n {onCart && (\n <button\n className={cn(\n \"h-9 w-9 shrink-0 rounded-[9px] border flex items-center justify-center transition-colors\",\n inCart\n ? \"border-brand-orange/50 bg-brand-orange/10 text-brand-orange\"\n : \"border-border bg-background hover:bg-muted text-foreground\"\n )}\n onClick={(e) => { e.preventDefault(); if (!inCart) onCart(order); }}\n disabled={inCart}\n aria-label={inCart ? \"Added to cart\" : \"Add to cart\"}\n >\n {inCart ? <Check className=\"h-3.5 w-3.5\" /> : <ShoppingCart className=\"h-3.5 w-3.5\" />}\n </button>\n )}\n {overflowMenu}\n </div>\n )}\n </div>\n </Link>\n </MotionCard>\n );\n}\n\nexport function ListingCardSkeleton() {\n return (\n <div className=\"card-base\">\n <div className=\"aspect-square w-full bg-muted animate-pulse\" />\n <div className=\"p-3 space-y-2.5\">\n <div className=\"space-y-1\">\n <div className=\"h-4 w-3/4 bg-muted animate-pulse rounded\" />\n <div className=\"h-3 w-1/2 bg-muted animate-pulse rounded\" />\n </div>\n <div className=\"h-6 w-1/2 bg-muted animate-pulse rounded\" />\n <div className=\"h-3 w-2/3 bg-muted animate-pulse rounded\" />\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["Link","Image"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ApiOrder } from '@medialane/sdk';
|
|
3
|
+
|
|
4
|
+
interface ListingCardProps {
|
|
5
|
+
order: ApiOrder;
|
|
6
|
+
inCart?: boolean;
|
|
7
|
+
onBuy?: (order: ApiOrder) => void;
|
|
8
|
+
onCart?: (order: ApiOrder) => void;
|
|
9
|
+
/** App passes a fully constructed <DropdownMenu> here */
|
|
10
|
+
overflowMenu?: React.ReactNode;
|
|
11
|
+
compact?: boolean;
|
|
12
|
+
}
|
|
13
|
+
declare function ListingCard({ order, inCart, onBuy, onCart, overflowMenu, compact }: ListingCardProps): react_jsx_runtime.JSX.Element;
|
|
14
|
+
declare function ListingCardSkeleton(): react_jsx_runtime.JSX.Element;
|
|
15
|
+
|
|
16
|
+
export { ListingCard, type ListingCardProps, ListingCardSkeleton };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ApiOrder } from '@medialane/sdk';
|
|
3
|
+
|
|
4
|
+
interface ListingCardProps {
|
|
5
|
+
order: ApiOrder;
|
|
6
|
+
inCart?: boolean;
|
|
7
|
+
onBuy?: (order: ApiOrder) => void;
|
|
8
|
+
onCart?: (order: ApiOrder) => void;
|
|
9
|
+
/** App passes a fully constructed <DropdownMenu> here */
|
|
10
|
+
overflowMenu?: React.ReactNode;
|
|
11
|
+
compact?: boolean;
|
|
12
|
+
}
|
|
13
|
+
declare function ListingCard({ order, inCart, onBuy, onCart, overflowMenu, compact }: ListingCardProps): react_jsx_runtime.JSX.Element;
|
|
14
|
+
declare function ListingCardSkeleton(): react_jsx_runtime.JSX.Element;
|
|
15
|
+
|
|
16
|
+
export { ListingCard, type ListingCardProps, ListingCardSkeleton };
|