@medialane/ui 0.16.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/asset-license-summary.cjs +78 -0
- package/dist/components/asset-license-summary.cjs.map +1 -0
- package/dist/components/asset-license-summary.d.cts +19 -0
- package/dist/components/asset-license-summary.d.ts +19 -0
- package/dist/components/asset-license-summary.js +54 -0
- package/dist/components/asset-license-summary.js.map +1 -0
- package/dist/components/asset-overview-content.cjs +41 -33
- package/dist/components/asset-overview-content.cjs.map +1 -1
- package/dist/components/asset-overview-content.d.cts +6 -0
- package/dist/components/asset-overview-content.d.ts +6 -0
- package/dist/components/asset-overview-content.js +41 -33
- package/dist/components/asset-overview-content.js.map +1 -1
- package/dist/components/listing-card.cjs +3 -3
- package/dist/components/listing-card.cjs.map +1 -1
- package/dist/components/listing-card.d.cts +8 -1
- package/dist/components/listing-card.d.ts +8 -1
- package/dist/components/listing-card.js +3 -3
- package/dist/components/listing-card.js.map +1 -1
- package/dist/index.cjs +6 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/license-summary.cjs +41 -0
- package/dist/utils/license-summary.cjs.map +1 -0
- package/dist/utils/license-summary.d.cts +15 -0
- package/dist/utils/license-summary.d.ts +15 -0
- package/dist/utils/license-summary.js +17 -0
- package/dist/utils/license-summary.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
var asset_license_summary_exports = {};
|
|
21
|
+
__export(asset_license_summary_exports, {
|
|
22
|
+
AssetLicenseSummary: () => AssetLicenseSummary
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(asset_license_summary_exports);
|
|
25
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
26
|
+
var import_lucide_react = require("lucide-react");
|
|
27
|
+
var import_license_summary = require("../utils/license-summary.js");
|
|
28
|
+
function AssetLicenseSummary({ attributes }) {
|
|
29
|
+
const summary = (0, import_license_summary.licenseSummary)(attributes);
|
|
30
|
+
if (!summary) return null;
|
|
31
|
+
const get = (key) => attributes.find((a) => a.trait_type?.toLowerCase() === key.toLowerCase())?.value;
|
|
32
|
+
const commercialRaw = get("Commercial Use");
|
|
33
|
+
const derivatives = (get("Derivatives") ?? "").toLowerCase();
|
|
34
|
+
const ai = (get("AI Policy") ?? get("AI & Data Mining") ?? "").toLowerCase();
|
|
35
|
+
const territory = get("Territory");
|
|
36
|
+
const pills = [];
|
|
37
|
+
if (commercialRaw) {
|
|
38
|
+
pills.push({
|
|
39
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.DollarSign, { className: "h-3.5 w-3.5" }),
|
|
40
|
+
label: commercialRaw.toLowerCase() === "yes" ? "Commercial use" : "Non-commercial"
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
if (derivatives) {
|
|
44
|
+
pills.push({
|
|
45
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.GitBranch, { className: "h-3.5 w-3.5" }),
|
|
46
|
+
label: derivatives === "not allowed" ? "No remixing" : "Remixable"
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
if (ai) {
|
|
50
|
+
pills.push({
|
|
51
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Bot, { className: "h-3.5 w-3.5" }),
|
|
52
|
+
label: ai.includes("not") ? "No AI training" : "AI allowed"
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (territory) {
|
|
56
|
+
pills.push({ icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Globe, { className: "h-3.5 w-3.5" }), label: territory });
|
|
57
|
+
}
|
|
58
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-2.5", children: [
|
|
59
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-[10px] font-medium uppercase tracking-wider text-muted-foreground", children: "License" }),
|
|
60
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-[15px] font-medium leading-relaxed text-foreground/90", children: summary }),
|
|
61
|
+
pills.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex flex-wrap gap-2 pt-0.5", children: pills.map((pill) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
62
|
+
"span",
|
|
63
|
+
{
|
|
64
|
+
className: "inline-flex items-center gap-1.5 rounded-full border border-border/60 bg-muted/30 px-3 py-1 text-xs font-medium text-foreground/80",
|
|
65
|
+
children: [
|
|
66
|
+
pill.icon,
|
|
67
|
+
pill.label
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
pill.label
|
|
71
|
+
)) }) : null
|
|
72
|
+
] });
|
|
73
|
+
}
|
|
74
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
75
|
+
0 && (module.exports = {
|
|
76
|
+
AssetLicenseSummary
|
|
77
|
+
});
|
|
78
|
+
//# sourceMappingURL=asset-license-summary.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/asset-license-summary.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport { Bot, DollarSign, GitBranch, Globe } from \"lucide-react\";\nimport { licenseSummary } from \"../utils/license-summary.js\";\n\ntype AssetAttribute = { trait_type?: string; value?: string };\n\n/**\n * Human-first license callout for the asset hero column. Leads with one\n * plain-language sentence (the same one the metadata implies), then a row of\n * glanceable fact pills — so a buyer understands the rights at a glance without\n * digging into the Overview tab. The detailed receipts (full license bento +\n * worldwide-protection banner) still live in the Overview tab. Renders nothing\n * when the asset carries no license data.\n */\nexport function AssetLicenseSummary({ attributes }: { attributes: AssetAttribute[] }) {\n const summary = licenseSummary(attributes);\n if (!summary) return null;\n\n const get = (key: string) =>\n attributes.find((a) => a.trait_type?.toLowerCase() === key.toLowerCase())?.value;\n\n const commercialRaw = get(\"Commercial Use\");\n const derivatives = (get(\"Derivatives\") ?? \"\").toLowerCase();\n const ai = (get(\"AI Policy\") ?? get(\"AI & Data Mining\") ?? \"\").toLowerCase();\n const territory = get(\"Territory\");\n\n const pills: { icon: ReactNode; label: string }[] = [];\n if (commercialRaw) {\n pills.push({\n icon: <DollarSign className=\"h-3.5 w-3.5\" />,\n label: commercialRaw.toLowerCase() === \"yes\" ? \"Commercial use\" : \"Non-commercial\",\n });\n }\n if (derivatives) {\n pills.push({\n icon: <GitBranch className=\"h-3.5 w-3.5\" />,\n label: derivatives === \"not allowed\" ? \"No remixing\" : \"Remixable\",\n });\n }\n if (ai) {\n pills.push({\n icon: <Bot className=\"h-3.5 w-3.5\" />,\n label: ai.includes(\"not\") ? \"No AI training\" : \"AI allowed\",\n });\n }\n if (territory) {\n pills.push({ icon: <Globe className=\"h-3.5 w-3.5\" />, label: territory });\n }\n\n return (\n <div className=\"space-y-2.5\">\n <p className=\"text-[10px] font-medium uppercase tracking-wider text-muted-foreground\">License</p>\n <p className=\"text-[15px] font-medium leading-relaxed text-foreground/90\">{summary}</p>\n {pills.length > 0 ? (\n <div className=\"flex flex-wrap gap-2 pt-0.5\">\n {pills.map((pill) => (\n <span\n key={pill.label}\n className=\"inline-flex items-center gap-1.5 rounded-full border border-border/60 bg-muted/30 px-3 py-1 text-xs font-medium text-foreground/80\"\n >\n {pill.icon}\n {pill.label}\n </span>\n ))}\n </div>\n ) : null}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA+BY;AA5BZ,0BAAkD;AAClD,6BAA+B;AAYxB,SAAS,oBAAoB,EAAE,WAAW,GAAqC;AACpF,QAAM,cAAU,uCAAe,UAAU;AACzC,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,MAAM,CAAC,QACX,WAAW,KAAK,CAAC,MAAM,EAAE,YAAY,YAAY,MAAM,IAAI,YAAY,CAAC,GAAG;AAE7E,QAAM,gBAAgB,IAAI,gBAAgB;AAC1C,QAAM,eAAe,IAAI,aAAa,KAAK,IAAI,YAAY;AAC3D,QAAM,MAAM,IAAI,WAAW,KAAK,IAAI,kBAAkB,KAAK,IAAI,YAAY;AAC3E,QAAM,YAAY,IAAI,WAAW;AAEjC,QAAM,QAA8C,CAAC;AACrD,MAAI,eAAe;AACjB,UAAM,KAAK;AAAA,MACT,MAAM,4CAAC,kCAAW,WAAU,eAAc;AAAA,MAC1C,OAAO,cAAc,YAAY,MAAM,QAAQ,mBAAmB;AAAA,IACpE,CAAC;AAAA,EACH;AACA,MAAI,aAAa;AACf,UAAM,KAAK;AAAA,MACT,MAAM,4CAAC,iCAAU,WAAU,eAAc;AAAA,MACzC,OAAO,gBAAgB,gBAAgB,gBAAgB;AAAA,IACzD,CAAC;AAAA,EACH;AACA,MAAI,IAAI;AACN,UAAM,KAAK;AAAA,MACT,MAAM,4CAAC,2BAAI,WAAU,eAAc;AAAA,MACnC,OAAO,GAAG,SAAS,KAAK,IAAI,mBAAmB;AAAA,IACjD,CAAC;AAAA,EACH;AACA,MAAI,WAAW;AACb,UAAM,KAAK,EAAE,MAAM,4CAAC,6BAAM,WAAU,eAAc,GAAI,OAAO,UAAU,CAAC;AAAA,EAC1E;AAEA,SACE,6CAAC,SAAI,WAAU,eACb;AAAA,gDAAC,OAAE,WAAU,0EAAyE,qBAAO;AAAA,IAC7F,4CAAC,OAAE,WAAU,8DAA8D,mBAAQ;AAAA,IAClF,MAAM,SAAS,IACd,4CAAC,SAAI,WAAU,+BACZ,gBAAM,IAAI,CAAC,SACV;AAAA,MAAC;AAAA;AAAA,QAEC,WAAU;AAAA,QAET;AAAA,eAAK;AAAA,UACL,KAAK;AAAA;AAAA;AAAA,MAJD,KAAK;AAAA,IAKZ,CACD,GACH,IACE;AAAA,KACN;AAEJ;","names":[]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
type AssetAttribute = {
|
|
4
|
+
trait_type?: string;
|
|
5
|
+
value?: string;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Human-first license callout for the asset hero column. Leads with one
|
|
9
|
+
* plain-language sentence (the same one the metadata implies), then a row of
|
|
10
|
+
* glanceable fact pills — so a buyer understands the rights at a glance without
|
|
11
|
+
* digging into the Overview tab. The detailed receipts (full license bento +
|
|
12
|
+
* worldwide-protection banner) still live in the Overview tab. Renders nothing
|
|
13
|
+
* when the asset carries no license data.
|
|
14
|
+
*/
|
|
15
|
+
declare function AssetLicenseSummary({ attributes }: {
|
|
16
|
+
attributes: AssetAttribute[];
|
|
17
|
+
}): react_jsx_runtime.JSX.Element | null;
|
|
18
|
+
|
|
19
|
+
export { AssetLicenseSummary };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
type AssetAttribute = {
|
|
4
|
+
trait_type?: string;
|
|
5
|
+
value?: string;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Human-first license callout for the asset hero column. Leads with one
|
|
9
|
+
* plain-language sentence (the same one the metadata implies), then a row of
|
|
10
|
+
* glanceable fact pills — so a buyer understands the rights at a glance without
|
|
11
|
+
* digging into the Overview tab. The detailed receipts (full license bento +
|
|
12
|
+
* worldwide-protection banner) still live in the Overview tab. Renders nothing
|
|
13
|
+
* when the asset carries no license data.
|
|
14
|
+
*/
|
|
15
|
+
declare function AssetLicenseSummary({ attributes }: {
|
|
16
|
+
attributes: AssetAttribute[];
|
|
17
|
+
}): react_jsx_runtime.JSX.Element | null;
|
|
18
|
+
|
|
19
|
+
export { AssetLicenseSummary };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Bot, DollarSign, GitBranch, Globe } from "lucide-react";
|
|
4
|
+
import { licenseSummary } from "../utils/license-summary.js";
|
|
5
|
+
function AssetLicenseSummary({ attributes }) {
|
|
6
|
+
const summary = licenseSummary(attributes);
|
|
7
|
+
if (!summary) return null;
|
|
8
|
+
const get = (key) => attributes.find((a) => a.trait_type?.toLowerCase() === key.toLowerCase())?.value;
|
|
9
|
+
const commercialRaw = get("Commercial Use");
|
|
10
|
+
const derivatives = (get("Derivatives") ?? "").toLowerCase();
|
|
11
|
+
const ai = (get("AI Policy") ?? get("AI & Data Mining") ?? "").toLowerCase();
|
|
12
|
+
const territory = get("Territory");
|
|
13
|
+
const pills = [];
|
|
14
|
+
if (commercialRaw) {
|
|
15
|
+
pills.push({
|
|
16
|
+
icon: /* @__PURE__ */ jsx(DollarSign, { className: "h-3.5 w-3.5" }),
|
|
17
|
+
label: commercialRaw.toLowerCase() === "yes" ? "Commercial use" : "Non-commercial"
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
if (derivatives) {
|
|
21
|
+
pills.push({
|
|
22
|
+
icon: /* @__PURE__ */ jsx(GitBranch, { className: "h-3.5 w-3.5" }),
|
|
23
|
+
label: derivatives === "not allowed" ? "No remixing" : "Remixable"
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
if (ai) {
|
|
27
|
+
pills.push({
|
|
28
|
+
icon: /* @__PURE__ */ jsx(Bot, { className: "h-3.5 w-3.5" }),
|
|
29
|
+
label: ai.includes("not") ? "No AI training" : "AI allowed"
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
if (territory) {
|
|
33
|
+
pills.push({ icon: /* @__PURE__ */ jsx(Globe, { className: "h-3.5 w-3.5" }), label: territory });
|
|
34
|
+
}
|
|
35
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2.5", children: [
|
|
36
|
+
/* @__PURE__ */ jsx("p", { className: "text-[10px] font-medium uppercase tracking-wider text-muted-foreground", children: "License" }),
|
|
37
|
+
/* @__PURE__ */ jsx("p", { className: "text-[15px] font-medium leading-relaxed text-foreground/90", children: summary }),
|
|
38
|
+
pills.length > 0 ? /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2 pt-0.5", children: pills.map((pill) => /* @__PURE__ */ jsxs(
|
|
39
|
+
"span",
|
|
40
|
+
{
|
|
41
|
+
className: "inline-flex items-center gap-1.5 rounded-full border border-border/60 bg-muted/30 px-3 py-1 text-xs font-medium text-foreground/80",
|
|
42
|
+
children: [
|
|
43
|
+
pill.icon,
|
|
44
|
+
pill.label
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
pill.label
|
|
48
|
+
)) }) : null
|
|
49
|
+
] });
|
|
50
|
+
}
|
|
51
|
+
export {
|
|
52
|
+
AssetLicenseSummary
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=asset-license-summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/asset-license-summary.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport { Bot, DollarSign, GitBranch, Globe } from \"lucide-react\";\nimport { licenseSummary } from \"../utils/license-summary.js\";\n\ntype AssetAttribute = { trait_type?: string; value?: string };\n\n/**\n * Human-first license callout for the asset hero column. Leads with one\n * plain-language sentence (the same one the metadata implies), then a row of\n * glanceable fact pills — so a buyer understands the rights at a glance without\n * digging into the Overview tab. The detailed receipts (full license bento +\n * worldwide-protection banner) still live in the Overview tab. Renders nothing\n * when the asset carries no license data.\n */\nexport function AssetLicenseSummary({ attributes }: { attributes: AssetAttribute[] }) {\n const summary = licenseSummary(attributes);\n if (!summary) return null;\n\n const get = (key: string) =>\n attributes.find((a) => a.trait_type?.toLowerCase() === key.toLowerCase())?.value;\n\n const commercialRaw = get(\"Commercial Use\");\n const derivatives = (get(\"Derivatives\") ?? \"\").toLowerCase();\n const ai = (get(\"AI Policy\") ?? get(\"AI & Data Mining\") ?? \"\").toLowerCase();\n const territory = get(\"Territory\");\n\n const pills: { icon: ReactNode; label: string }[] = [];\n if (commercialRaw) {\n pills.push({\n icon: <DollarSign className=\"h-3.5 w-3.5\" />,\n label: commercialRaw.toLowerCase() === \"yes\" ? \"Commercial use\" : \"Non-commercial\",\n });\n }\n if (derivatives) {\n pills.push({\n icon: <GitBranch className=\"h-3.5 w-3.5\" />,\n label: derivatives === \"not allowed\" ? \"No remixing\" : \"Remixable\",\n });\n }\n if (ai) {\n pills.push({\n icon: <Bot className=\"h-3.5 w-3.5\" />,\n label: ai.includes(\"not\") ? \"No AI training\" : \"AI allowed\",\n });\n }\n if (territory) {\n pills.push({ icon: <Globe className=\"h-3.5 w-3.5\" />, label: territory });\n }\n\n return (\n <div className=\"space-y-2.5\">\n <p className=\"text-[10px] font-medium uppercase tracking-wider text-muted-foreground\">License</p>\n <p className=\"text-[15px] font-medium leading-relaxed text-foreground/90\">{summary}</p>\n {pills.length > 0 ? (\n <div className=\"flex flex-wrap gap-2 pt-0.5\">\n {pills.map((pill) => (\n <span\n key={pill.label}\n className=\"inline-flex items-center gap-1.5 rounded-full border border-border/60 bg-muted/30 px-3 py-1 text-xs font-medium text-foreground/80\"\n >\n {pill.icon}\n {pill.label}\n </span>\n ))}\n </div>\n ) : null}\n </div>\n );\n}\n"],"mappings":";AA+BY,cA2BA,YA3BA;AA5BZ,SAAS,KAAK,YAAY,WAAW,aAAa;AAClD,SAAS,sBAAsB;AAYxB,SAAS,oBAAoB,EAAE,WAAW,GAAqC;AACpF,QAAM,UAAU,eAAe,UAAU;AACzC,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,MAAM,CAAC,QACX,WAAW,KAAK,CAAC,MAAM,EAAE,YAAY,YAAY,MAAM,IAAI,YAAY,CAAC,GAAG;AAE7E,QAAM,gBAAgB,IAAI,gBAAgB;AAC1C,QAAM,eAAe,IAAI,aAAa,KAAK,IAAI,YAAY;AAC3D,QAAM,MAAM,IAAI,WAAW,KAAK,IAAI,kBAAkB,KAAK,IAAI,YAAY;AAC3E,QAAM,YAAY,IAAI,WAAW;AAEjC,QAAM,QAA8C,CAAC;AACrD,MAAI,eAAe;AACjB,UAAM,KAAK;AAAA,MACT,MAAM,oBAAC,cAAW,WAAU,eAAc;AAAA,MAC1C,OAAO,cAAc,YAAY,MAAM,QAAQ,mBAAmB;AAAA,IACpE,CAAC;AAAA,EACH;AACA,MAAI,aAAa;AACf,UAAM,KAAK;AAAA,MACT,MAAM,oBAAC,aAAU,WAAU,eAAc;AAAA,MACzC,OAAO,gBAAgB,gBAAgB,gBAAgB;AAAA,IACzD,CAAC;AAAA,EACH;AACA,MAAI,IAAI;AACN,UAAM,KAAK;AAAA,MACT,MAAM,oBAAC,OAAI,WAAU,eAAc;AAAA,MACnC,OAAO,GAAG,SAAS,KAAK,IAAI,mBAAmB;AAAA,IACjD,CAAC;AAAA,EACH;AACA,MAAI,WAAW;AACb,UAAM,KAAK,EAAE,MAAM,oBAAC,SAAM,WAAU,eAAc,GAAI,OAAO,UAAU,CAAC;AAAA,EAC1E;AAEA,SACE,qBAAC,SAAI,WAAU,eACb;AAAA,wBAAC,OAAE,WAAU,0EAAyE,qBAAO;AAAA,IAC7F,oBAAC,OAAE,WAAU,8DAA8D,mBAAQ;AAAA,IAClF,MAAM,SAAS,IACd,oBAAC,SAAI,WAAU,+BACZ,gBAAM,IAAI,CAAC,SACV;AAAA,MAAC;AAAA;AAAA,QAEC,WAAU;AAAA,QAET;AAAA,eAAK;AAAA,UACL,KAAK;AAAA;AAAA;AAAA,MAJD,KAAK;AAAA,IAKZ,CACD,GACH,IACE;AAAA,KACN;AAEJ;","names":[]}
|
|
@@ -23,8 +23,10 @@ __export(asset_overview_content_exports, {
|
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(asset_overview_content_exports);
|
|
25
25
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
26
|
-
var import_ip_type_display = require("./ip-type-display.js");
|
|
27
26
|
var import_lucide_react = require("lucide-react");
|
|
27
|
+
var import_ip_type_display = require("./ip-type-display.js");
|
|
28
|
+
var import_address_display = require("./address-display.js");
|
|
29
|
+
const isAddressLike = (v) => !!v && /^0x[0-9a-fA-F]{16,}$/.test(v.trim());
|
|
28
30
|
function AssetOverviewContent({
|
|
29
31
|
attributes,
|
|
30
32
|
hasTemplateData,
|
|
@@ -43,7 +45,7 @@ function AssetOverviewContent({
|
|
|
43
45
|
const hasLicenseData = licenseType || commercialUse || derivatives || attribution;
|
|
44
46
|
const displayAttributes = attributes.filter((attribute) => isDisplayAttr(attribute));
|
|
45
47
|
const rows = [
|
|
46
|
-
{ icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.
|
|
48
|
+
{ icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ShieldCheck, { className: "h-4 w-4" }), label: "License", value: licenseType },
|
|
47
49
|
{ icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.DollarSign, { className: "h-4 w-4" }), label: "Commercial Use", value: commercialUse },
|
|
48
50
|
{ icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.GitBranch, { className: "h-4 w-4" }), label: "Derivatives", value: derivatives },
|
|
49
51
|
{ icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.UserCheck, { className: "h-4 w-4" }), label: "Attribution", value: attribution },
|
|
@@ -55,44 +57,50 @@ function AssetOverviewContent({
|
|
|
55
57
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mt-4 space-y-6", children: [
|
|
56
58
|
hasTemplateData ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ip_type_display.IPTypeDisplay, { attributes }) : null,
|
|
57
59
|
hasLicenseData ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-3", children: [
|
|
58
|
-
standard ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-
|
|
59
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.
|
|
60
|
+
standard ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-start gap-3 rounded-xl border border-primary/15 bg-primary/5 px-4 py-3.5", children: [
|
|
61
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ShieldCheck, { className: "h-5 w-5 text-primary shrink-0 mt-0.5" }),
|
|
60
62
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
61
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
62
|
-
|
|
63
|
-
" Compliant"
|
|
64
|
-
] }),
|
|
65
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs text-muted-foreground", children: "Licensing terms are immutably embedded in IPFS metadata and compliant with international copyright law." })
|
|
63
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm font-semibold", children: "Your intellectual property is protected worldwide" }),
|
|
64
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs text-muted-foreground mt-0.5 leading-relaxed", children: "Licensing terms are immutably stored on IPFS and recognized under international copyright law." })
|
|
66
65
|
] })
|
|
67
66
|
] }) : null,
|
|
68
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid grid-cols-2 sm:grid-cols-3 gap-2", children: rows.map(({ icon, label, value }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
67
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid grid-cols-2 sm:grid-cols-3 gap-2.5", children: rows.map(({ icon, label, value }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
68
|
+
"div",
|
|
69
|
+
{
|
|
70
|
+
className: "rounded-xl border border-border/50 bg-muted/15 px-3.5 py-3 overflow-hidden transition-colors hover:bg-muted/30",
|
|
71
|
+
children: [
|
|
72
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-1.5 mb-1 text-muted-foreground/70", children: [
|
|
73
|
+
icon,
|
|
74
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-[10px] font-medium uppercase tracking-wider truncate", children: label })
|
|
75
|
+
] }),
|
|
76
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm font-semibold truncate", title: value, children: value })
|
|
77
|
+
]
|
|
78
|
+
},
|
|
79
|
+
label
|
|
80
|
+
)) })
|
|
73
81
|
] }) : null,
|
|
74
82
|
displayAttributes.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
75
83
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-2", children: "Attributes" }),
|
|
76
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid grid-cols-2 sm:grid-cols-3 gap-2", children: displayAttributes.map((attribute, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
title: attribute.value ?? "\u2014",
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
84
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid grid-cols-2 sm:grid-cols-3 gap-2.5", children: displayAttributes.map((attribute, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
85
|
+
"div",
|
|
86
|
+
{
|
|
87
|
+
className: "rounded-xl border border-border/50 bg-muted/15 px-3.5 py-3 overflow-hidden transition-colors hover:bg-muted/30",
|
|
88
|
+
children: [
|
|
89
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
90
|
+
"p",
|
|
91
|
+
{
|
|
92
|
+
className: "text-[10px] font-medium uppercase tracking-wider text-muted-foreground/70 truncate",
|
|
93
|
+
title: attribute.trait_type ?? "Trait",
|
|
94
|
+
children: attribute.trait_type ?? "Trait"
|
|
95
|
+
}
|
|
96
|
+
),
|
|
97
|
+
isAddressLike(attribute.value) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_address_display.AddressDisplay, { address: attribute.value, chars: 4, className: "text-sm font-semibold mt-1" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm font-semibold mt-1 truncate", title: attribute.value ?? "\u2014", children: attribute.value ?? "\u2014" })
|
|
98
|
+
]
|
|
99
|
+
},
|
|
100
|
+
index
|
|
101
|
+
)) })
|
|
94
102
|
] }) : null,
|
|
95
|
-
!hasTemplateData && displayAttributes.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm text-muted-foreground", children: "No additional details available." }) : null
|
|
103
|
+
!hasTemplateData && !hasLicenseData && displayAttributes.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm text-muted-foreground", children: "No additional details available." }) : null
|
|
96
104
|
] });
|
|
97
105
|
}
|
|
98
106
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/asset-overview-content.tsx"],"sourcesContent":["\"use client\";\n\nimport
|
|
1
|
+
{"version":3,"sources":["../../src/components/asset-overview-content.tsx"],"sourcesContent":["\"use client\";\n\nimport { Bot, Calendar, DollarSign, GitBranch, Globe, Percent, ShieldCheck, UserCheck } from \"lucide-react\";\nimport { IPTypeDisplay } from \"./ip-type-display.js\";\nimport { AddressDisplay } from \"./address-display.js\";\n\ninterface AssetAttribute {\n trait_type?: string;\n value?: string;\n}\n\ninterface AssetOverviewContentProps {\n attributes: AssetAttribute[];\n hasTemplateData: boolean;\n isDisplayAttr: (attribute: AssetAttribute) => boolean;\n}\n\nconst isAddressLike = (v?: string): boolean => !!v && /^0x[0-9a-fA-F]{16,}$/.test(v.trim());\n\n/**\n * Asset Overview tab — the license receipts. A worldwide-protection banner, the\n * full license bento, then a refined attributes grid (uniform cards, copyable\n * address-like values, no rarity). The human one-line summary lives in the hero\n * column (see AssetLicenseSummary), not here.\n */\nexport function AssetOverviewContent({\n attributes,\n hasTemplateData,\n isDisplayAttr,\n}: AssetOverviewContentProps) {\n const attr = (trait: string) => attributes.find((attribute) => attribute.trait_type === trait)?.value;\n const licenseType = attr(\"License\");\n const commercialUse = attr(\"Commercial Use\");\n const derivatives = attr(\"Derivatives\");\n const attribution = attr(\"Attribution\");\n const territory = attr(\"Territory\");\n const aiPolicy = attr(\"AI Policy\");\n const royalty = attr(\"Royalty\");\n const standard = attr(\"Standard\");\n const registration = attr(\"Registration\");\n const hasLicenseData = licenseType || commercialUse || derivatives || attribution;\n const displayAttributes = attributes.filter((attribute) => isDisplayAttr(attribute));\n\n const rows = [\n { icon: <ShieldCheck className=\"h-4 w-4\" />, label: \"License\", value: licenseType },\n { icon: <DollarSign className=\"h-4 w-4\" />, label: \"Commercial Use\", value: commercialUse },\n { icon: <GitBranch className=\"h-4 w-4\" />, label: \"Derivatives\", value: derivatives },\n { icon: <UserCheck className=\"h-4 w-4\" />, label: \"Attribution\", value: attribution },\n { icon: <Globe className=\"h-4 w-4\" />, label: \"Territory\", value: territory },\n { icon: <Bot className=\"h-4 w-4\" />, label: \"AI & Data Mining\", value: aiPolicy },\n { icon: <Percent className=\"h-4 w-4\" />, label: \"Royalty\", value: royalty },\n { icon: <Calendar className=\"h-4 w-4\" />, label: \"Registration\", value: registration },\n ].filter((row) => !!row.value);\n\n return (\n <div className=\"mt-4 space-y-6\">\n {hasTemplateData ? <IPTypeDisplay attributes={attributes} /> : null}\n\n {hasLicenseData ? (\n <div className=\"space-y-3\">\n {standard ? (\n <div className=\"flex items-start gap-3 rounded-xl border border-primary/15 bg-primary/5 px-4 py-3.5\">\n <ShieldCheck className=\"h-5 w-5 text-primary shrink-0 mt-0.5\" />\n <div>\n <p className=\"text-sm font-semibold\">Your intellectual property is protected worldwide</p>\n <p className=\"text-xs text-muted-foreground mt-0.5 leading-relaxed\">\n Licensing terms are immutably stored on IPFS and recognized under international copyright law.\n </p>\n </div>\n </div>\n ) : null}\n\n <div className=\"grid grid-cols-2 sm:grid-cols-3 gap-2.5\">\n {rows.map(({ icon, label, value }) => (\n <div\n key={label}\n className=\"rounded-xl border border-border/50 bg-muted/15 px-3.5 py-3 overflow-hidden transition-colors hover:bg-muted/30\"\n >\n <div className=\"flex items-center gap-1.5 mb-1 text-muted-foreground/70\">\n {icon}\n <p className=\"text-[10px] font-medium uppercase tracking-wider truncate\">{label}</p>\n </div>\n <p className=\"text-sm font-semibold truncate\" title={value}>{value}</p>\n </div>\n ))}\n </div>\n </div>\n ) : null}\n\n {/* Refined attributes — uniform cards, copyable address values, no rarity. */}\n {displayAttributes.length > 0 ? (\n <div>\n <p className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-2\">Attributes</p>\n <div className=\"grid grid-cols-2 sm:grid-cols-3 gap-2.5\">\n {displayAttributes.map((attribute, index) => (\n <div\n key={index}\n className=\"rounded-xl border border-border/50 bg-muted/15 px-3.5 py-3 overflow-hidden transition-colors hover:bg-muted/30\"\n >\n <p\n className=\"text-[10px] font-medium uppercase tracking-wider text-muted-foreground/70 truncate\"\n title={attribute.trait_type ?? \"Trait\"}\n >\n {attribute.trait_type ?? \"Trait\"}\n </p>\n {isAddressLike(attribute.value) ? (\n <AddressDisplay address={attribute.value!} chars={4} className=\"text-sm font-semibold mt-1\" />\n ) : (\n <p className=\"text-sm font-semibold mt-1 truncate\" title={attribute.value ?? \"—\"}>\n {attribute.value ?? \"—\"}\n </p>\n )}\n </div>\n ))}\n </div>\n </div>\n ) : null}\n\n {!hasTemplateData && !hasLicenseData && displayAttributes.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">No additional details available.</p>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -9,6 +9,12 @@ interface AssetOverviewContentProps {
|
|
|
9
9
|
hasTemplateData: boolean;
|
|
10
10
|
isDisplayAttr: (attribute: AssetAttribute) => boolean;
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Asset Overview tab — the license receipts. A worldwide-protection banner, the
|
|
14
|
+
* full license bento, then a refined attributes grid (uniform cards, copyable
|
|
15
|
+
* address-like values, no rarity). The human one-line summary lives in the hero
|
|
16
|
+
* column (see AssetLicenseSummary), not here.
|
|
17
|
+
*/
|
|
12
18
|
declare function AssetOverviewContent({ attributes, hasTemplateData, isDisplayAttr, }: AssetOverviewContentProps): react_jsx_runtime.JSX.Element;
|
|
13
19
|
|
|
14
20
|
export { AssetOverviewContent };
|
|
@@ -9,6 +9,12 @@ interface AssetOverviewContentProps {
|
|
|
9
9
|
hasTemplateData: boolean;
|
|
10
10
|
isDisplayAttr: (attribute: AssetAttribute) => boolean;
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Asset Overview tab — the license receipts. A worldwide-protection banner, the
|
|
14
|
+
* full license bento, then a refined attributes grid (uniform cards, copyable
|
|
15
|
+
* address-like values, no rarity). The human one-line summary lives in the hero
|
|
16
|
+
* column (see AssetLicenseSummary), not here.
|
|
17
|
+
*/
|
|
12
18
|
declare function AssetOverviewContent({ attributes, hasTemplateData, isDisplayAttr, }: AssetOverviewContentProps): react_jsx_runtime.JSX.Element;
|
|
13
19
|
|
|
14
20
|
export { AssetOverviewContent };
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Bot, Calendar, DollarSign, GitBranch, Globe, Percent, ShieldCheck, UserCheck } from "lucide-react";
|
|
3
4
|
import { IPTypeDisplay } from "./ip-type-display.js";
|
|
4
|
-
import {
|
|
5
|
+
import { AddressDisplay } from "./address-display.js";
|
|
6
|
+
const isAddressLike = (v) => !!v && /^0x[0-9a-fA-F]{16,}$/.test(v.trim());
|
|
5
7
|
function AssetOverviewContent({
|
|
6
8
|
attributes,
|
|
7
9
|
hasTemplateData,
|
|
@@ -20,7 +22,7 @@ function AssetOverviewContent({
|
|
|
20
22
|
const hasLicenseData = licenseType || commercialUse || derivatives || attribution;
|
|
21
23
|
const displayAttributes = attributes.filter((attribute) => isDisplayAttr(attribute));
|
|
22
24
|
const rows = [
|
|
23
|
-
{ icon: /* @__PURE__ */ jsx(
|
|
25
|
+
{ icon: /* @__PURE__ */ jsx(ShieldCheck, { className: "h-4 w-4" }), label: "License", value: licenseType },
|
|
24
26
|
{ icon: /* @__PURE__ */ jsx(DollarSign, { className: "h-4 w-4" }), label: "Commercial Use", value: commercialUse },
|
|
25
27
|
{ icon: /* @__PURE__ */ jsx(GitBranch, { className: "h-4 w-4" }), label: "Derivatives", value: derivatives },
|
|
26
28
|
{ icon: /* @__PURE__ */ jsx(UserCheck, { className: "h-4 w-4" }), label: "Attribution", value: attribution },
|
|
@@ -32,44 +34,50 @@ function AssetOverviewContent({
|
|
|
32
34
|
return /* @__PURE__ */ jsxs("div", { className: "mt-4 space-y-6", children: [
|
|
33
35
|
hasTemplateData ? /* @__PURE__ */ jsx(IPTypeDisplay, { attributes }) : null,
|
|
34
36
|
hasLicenseData ? /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
35
|
-
standard ? /* @__PURE__ */ jsxs("div", { className: "flex items-
|
|
36
|
-
/* @__PURE__ */ jsx(
|
|
37
|
+
standard ? /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 rounded-xl border border-primary/15 bg-primary/5 px-4 py-3.5", children: [
|
|
38
|
+
/* @__PURE__ */ jsx(ShieldCheck, { className: "h-5 w-5 text-primary shrink-0 mt-0.5" }),
|
|
37
39
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
38
|
-
/* @__PURE__ */
|
|
39
|
-
|
|
40
|
-
" Compliant"
|
|
41
|
-
] }),
|
|
42
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Licensing terms are immutably embedded in IPFS metadata and compliant with international copyright law." })
|
|
40
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-semibold", children: "Your intellectual property is protected worldwide" }),
|
|
41
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-0.5 leading-relaxed", children: "Licensing terms are immutably stored on IPFS and recognized under international copyright law." })
|
|
43
42
|
] })
|
|
44
43
|
] }) : null,
|
|
45
|
-
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 sm:grid-cols-3 gap-2", children: rows.map(({ icon, label, value }) => /* @__PURE__ */ jsxs(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 sm:grid-cols-3 gap-2.5", children: rows.map(({ icon, label, value }) => /* @__PURE__ */ jsxs(
|
|
45
|
+
"div",
|
|
46
|
+
{
|
|
47
|
+
className: "rounded-xl border border-border/50 bg-muted/15 px-3.5 py-3 overflow-hidden transition-colors hover:bg-muted/30",
|
|
48
|
+
children: [
|
|
49
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 mb-1 text-muted-foreground/70", children: [
|
|
50
|
+
icon,
|
|
51
|
+
/* @__PURE__ */ jsx("p", { className: "text-[10px] font-medium uppercase tracking-wider truncate", children: label })
|
|
52
|
+
] }),
|
|
53
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-semibold truncate", title: value, children: value })
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
label
|
|
57
|
+
)) })
|
|
50
58
|
] }) : null,
|
|
51
59
|
displayAttributes.length > 0 ? /* @__PURE__ */ jsxs("div", { children: [
|
|
52
60
|
/* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-2", children: "Attributes" }),
|
|
53
|
-
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 sm:grid-cols-3 gap-2", children: displayAttributes.map((attribute, index) => /* @__PURE__ */ jsxs(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
title: attribute.value ?? "\u2014",
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
61
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 sm:grid-cols-3 gap-2.5", children: displayAttributes.map((attribute, index) => /* @__PURE__ */ jsxs(
|
|
62
|
+
"div",
|
|
63
|
+
{
|
|
64
|
+
className: "rounded-xl border border-border/50 bg-muted/15 px-3.5 py-3 overflow-hidden transition-colors hover:bg-muted/30",
|
|
65
|
+
children: [
|
|
66
|
+
/* @__PURE__ */ jsx(
|
|
67
|
+
"p",
|
|
68
|
+
{
|
|
69
|
+
className: "text-[10px] font-medium uppercase tracking-wider text-muted-foreground/70 truncate",
|
|
70
|
+
title: attribute.trait_type ?? "Trait",
|
|
71
|
+
children: attribute.trait_type ?? "Trait"
|
|
72
|
+
}
|
|
73
|
+
),
|
|
74
|
+
isAddressLike(attribute.value) ? /* @__PURE__ */ jsx(AddressDisplay, { address: attribute.value, chars: 4, className: "text-sm font-semibold mt-1" }) : /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold mt-1 truncate", title: attribute.value ?? "\u2014", children: attribute.value ?? "\u2014" })
|
|
75
|
+
]
|
|
76
|
+
},
|
|
77
|
+
index
|
|
78
|
+
)) })
|
|
71
79
|
] }) : null,
|
|
72
|
-
!hasTemplateData && displayAttributes.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "No additional details available." }) : null
|
|
80
|
+
!hasTemplateData && !hasLicenseData && displayAttributes.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "No additional details available." }) : null
|
|
73
81
|
] });
|
|
74
82
|
}
|
|
75
83
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/asset-overview-content.tsx"],"sourcesContent":["\"use client\";\n\nimport
|
|
1
|
+
{"version":3,"sources":["../../src/components/asset-overview-content.tsx"],"sourcesContent":["\"use client\";\n\nimport { Bot, Calendar, DollarSign, GitBranch, Globe, Percent, ShieldCheck, UserCheck } from \"lucide-react\";\nimport { IPTypeDisplay } from \"./ip-type-display.js\";\nimport { AddressDisplay } from \"./address-display.js\";\n\ninterface AssetAttribute {\n trait_type?: string;\n value?: string;\n}\n\ninterface AssetOverviewContentProps {\n attributes: AssetAttribute[];\n hasTemplateData: boolean;\n isDisplayAttr: (attribute: AssetAttribute) => boolean;\n}\n\nconst isAddressLike = (v?: string): boolean => !!v && /^0x[0-9a-fA-F]{16,}$/.test(v.trim());\n\n/**\n * Asset Overview tab — the license receipts. A worldwide-protection banner, the\n * full license bento, then a refined attributes grid (uniform cards, copyable\n * address-like values, no rarity). The human one-line summary lives in the hero\n * column (see AssetLicenseSummary), not here.\n */\nexport function AssetOverviewContent({\n attributes,\n hasTemplateData,\n isDisplayAttr,\n}: AssetOverviewContentProps) {\n const attr = (trait: string) => attributes.find((attribute) => attribute.trait_type === trait)?.value;\n const licenseType = attr(\"License\");\n const commercialUse = attr(\"Commercial Use\");\n const derivatives = attr(\"Derivatives\");\n const attribution = attr(\"Attribution\");\n const territory = attr(\"Territory\");\n const aiPolicy = attr(\"AI Policy\");\n const royalty = attr(\"Royalty\");\n const standard = attr(\"Standard\");\n const registration = attr(\"Registration\");\n const hasLicenseData = licenseType || commercialUse || derivatives || attribution;\n const displayAttributes = attributes.filter((attribute) => isDisplayAttr(attribute));\n\n const rows = [\n { icon: <ShieldCheck className=\"h-4 w-4\" />, label: \"License\", value: licenseType },\n { icon: <DollarSign className=\"h-4 w-4\" />, label: \"Commercial Use\", value: commercialUse },\n { icon: <GitBranch className=\"h-4 w-4\" />, label: \"Derivatives\", value: derivatives },\n { icon: <UserCheck className=\"h-4 w-4\" />, label: \"Attribution\", value: attribution },\n { icon: <Globe className=\"h-4 w-4\" />, label: \"Territory\", value: territory },\n { icon: <Bot className=\"h-4 w-4\" />, label: \"AI & Data Mining\", value: aiPolicy },\n { icon: <Percent className=\"h-4 w-4\" />, label: \"Royalty\", value: royalty },\n { icon: <Calendar className=\"h-4 w-4\" />, label: \"Registration\", value: registration },\n ].filter((row) => !!row.value);\n\n return (\n <div className=\"mt-4 space-y-6\">\n {hasTemplateData ? <IPTypeDisplay attributes={attributes} /> : null}\n\n {hasLicenseData ? (\n <div className=\"space-y-3\">\n {standard ? (\n <div className=\"flex items-start gap-3 rounded-xl border border-primary/15 bg-primary/5 px-4 py-3.5\">\n <ShieldCheck className=\"h-5 w-5 text-primary shrink-0 mt-0.5\" />\n <div>\n <p className=\"text-sm font-semibold\">Your intellectual property is protected worldwide</p>\n <p className=\"text-xs text-muted-foreground mt-0.5 leading-relaxed\">\n Licensing terms are immutably stored on IPFS and recognized under international copyright law.\n </p>\n </div>\n </div>\n ) : null}\n\n <div className=\"grid grid-cols-2 sm:grid-cols-3 gap-2.5\">\n {rows.map(({ icon, label, value }) => (\n <div\n key={label}\n className=\"rounded-xl border border-border/50 bg-muted/15 px-3.5 py-3 overflow-hidden transition-colors hover:bg-muted/30\"\n >\n <div className=\"flex items-center gap-1.5 mb-1 text-muted-foreground/70\">\n {icon}\n <p className=\"text-[10px] font-medium uppercase tracking-wider truncate\">{label}</p>\n </div>\n <p className=\"text-sm font-semibold truncate\" title={value}>{value}</p>\n </div>\n ))}\n </div>\n </div>\n ) : null}\n\n {/* Refined attributes — uniform cards, copyable address values, no rarity. */}\n {displayAttributes.length > 0 ? (\n <div>\n <p className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-2\">Attributes</p>\n <div className=\"grid grid-cols-2 sm:grid-cols-3 gap-2.5\">\n {displayAttributes.map((attribute, index) => (\n <div\n key={index}\n className=\"rounded-xl border border-border/50 bg-muted/15 px-3.5 py-3 overflow-hidden transition-colors hover:bg-muted/30\"\n >\n <p\n className=\"text-[10px] font-medium uppercase tracking-wider text-muted-foreground/70 truncate\"\n title={attribute.trait_type ?? \"Trait\"}\n >\n {attribute.trait_type ?? \"Trait\"}\n </p>\n {isAddressLike(attribute.value) ? (\n <AddressDisplay address={attribute.value!} chars={4} className=\"text-sm font-semibold mt-1\" />\n ) : (\n <p className=\"text-sm font-semibold mt-1 truncate\" title={attribute.value ?? \"—\"}>\n {attribute.value ?? \"—\"}\n </p>\n )}\n </div>\n ))}\n </div>\n </div>\n ) : null}\n\n {!hasTemplateData && !hasLicenseData && displayAttributes.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">No additional details available.</p>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -44,13 +44,13 @@ var import_cn = require("../utils/cn.js");
|
|
|
44
44
|
var import_ipfs = require("../utils/ipfs.js");
|
|
45
45
|
var import_format = require("../utils/format.js");
|
|
46
46
|
var import_time = require("../utils/time.js");
|
|
47
|
-
function ListingCard({ order, inCart = false, onBuy, onCart, overflowMenu, compact = false }) {
|
|
47
|
+
function ListingCard({ order, inCart = false, onBuy, onCart, overflowMenu, primaryAction, compact = false }) {
|
|
48
48
|
const [imgError, setImgError] = (0, import_react.useState)(false);
|
|
49
49
|
const isListing = order.offer.itemType === "ERC721" || order.offer.itemType === "ERC1155";
|
|
50
50
|
const name = order.token?.name ?? `Token #${order.nftTokenId}`;
|
|
51
51
|
const image = order.token?.image ? (0, import_ipfs.ipfsToHttp)(order.token.image) : null;
|
|
52
52
|
const assetHref = `/asset/${order.nftContract}/${order.nftTokenId}`;
|
|
53
|
-
const showActionBar = !!(onBuy || onCart || overflowMenu);
|
|
53
|
+
const showActionBar = !!(onBuy || onCart || overflowMenu || primaryAction);
|
|
54
54
|
if (compact) {
|
|
55
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
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: [
|
|
@@ -89,7 +89,7 @@ function ListingCard({ order, inCart = false, onBuy, onCart, overflowMenu, compa
|
|
|
89
89
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-[10px] text-muted-foreground/60 whitespace-nowrap shrink-0", children: (0, import_time.timeAgo)(order.createdAt) })
|
|
90
90
|
] }),
|
|
91
91
|
showActionBar && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
92
|
-
isListing ? 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)(
|
|
92
|
+
isListing ? primaryAction ? primaryAction : 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)(
|
|
93
93
|
"button",
|
|
94
94
|
{
|
|
95
95
|
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]",
|
|
@@ -1 +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, ArrowUpRight } 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 // Show the action bar for listings (Buy/View) and for offers (View asset),\n // whenever the host wired any action or an overflow menu.\n const showActionBar = !!(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 inline-flex items-center gap-1\">\n {order.price.currency && <CurrencyIcon symbol={order.price.currency} size={11} />}\n {formatDisplayPrice(order.price.formatted)}\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-3.5 space-y-3\">\n <div className=\"min-w-0\">\n <p className=\"font-semibold text-[15px] truncate leading-snug\">{name}</p>\n <p className=\"text-[11px] text-muted-foreground truncate leading-snug mt-0.5\">\n {order.token?.description ? order.token.description : `#${order.nftTokenId}`}\n </p>\n </div>\n\n {/* Price / Offer + age */}\n {order.price?.formatted && (\n <div className=\"flex items-end justify-between gap-2\">\n <div className=\"min-w-0\">\n <p className=\"text-[10px] uppercase tracking-widest text-muted-foreground/55 leading-none\">\n {isListing ? \"Price\" : \"Offer\"}\n </p>\n <p className=\"text-lg font-bold price-value leading-none inline-flex items-center gap-1.5 mt-1.5\">\n {order.price.currency && <CurrencyIcon symbol={order.price.currency} size={18} />}\n {formatDisplayPrice(order.price.formatted)}\n <span className=\"sr-only\">{order.price.currency}</span>\n </p>\n </div>\n <p className=\"text-[10px] text-muted-foreground/60 whitespace-nowrap shrink-0\">\n {timeAgo(order.createdAt)}\n </p>\n </div>\n )}\n\n {showActionBar && (\n <div className=\"flex items-center gap-1.5\">\n {isListing ? (\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 <Link\n href={assetHref}\n className=\"flex-1 h-9 inline-flex items-center justify-center gap-1.5 rounded-[9px] border border-border bg-background text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0\" /> View\n </Link>\n )\n ) : (\n <Link\n href={assetHref}\n className=\"flex-1 h-9 inline-flex items-center justify-center gap-1.5 rounded-[9px] border border-border bg-background text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0\" /> View asset\n </Link>\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"]}
|
|
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, ArrowUpRight } 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 /**\n * Optional flex-1 primary control for listings, replacing the default\n * Buy/View button — lets a host inject its own action (e.g. an owner\n * \"Cancel\" with an app-specific, auth-coupled handler) while keeping this\n * card's layout. Ignored for offers (which always render \"View asset\").\n */\n primaryAction?: React.ReactNode;\n compact?: boolean;\n}\n\nexport function ListingCard({ order, inCart = false, onBuy, onCart, overflowMenu, primaryAction, 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 // Show the action bar for listings (Buy/View) and for offers (View asset),\n // whenever the host wired any action or an overflow menu.\n const showActionBar = !!(onBuy || onCart || overflowMenu || primaryAction);\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 inline-flex items-center gap-1\">\n {order.price.currency && <CurrencyIcon symbol={order.price.currency} size={11} />}\n {formatDisplayPrice(order.price.formatted)}\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-3.5 space-y-3\">\n <div className=\"min-w-0\">\n <p className=\"font-semibold text-[15px] truncate leading-snug\">{name}</p>\n <p className=\"text-[11px] text-muted-foreground truncate leading-snug mt-0.5\">\n {order.token?.description ? order.token.description : `#${order.nftTokenId}`}\n </p>\n </div>\n\n {/* Price / Offer + age */}\n {order.price?.formatted && (\n <div className=\"flex items-end justify-between gap-2\">\n <div className=\"min-w-0\">\n <p className=\"text-[10px] uppercase tracking-widest text-muted-foreground/55 leading-none\">\n {isListing ? \"Price\" : \"Offer\"}\n </p>\n <p className=\"text-lg font-bold price-value leading-none inline-flex items-center gap-1.5 mt-1.5\">\n {order.price.currency && <CurrencyIcon symbol={order.price.currency} size={18} />}\n {formatDisplayPrice(order.price.formatted)}\n <span className=\"sr-only\">{order.price.currency}</span>\n </p>\n </div>\n <p className=\"text-[10px] text-muted-foreground/60 whitespace-nowrap shrink-0\">\n {timeAgo(order.createdAt)}\n </p>\n </div>\n )}\n\n {showActionBar && (\n <div className=\"flex items-center gap-1.5\">\n {isListing ? (\n primaryAction ? (\n primaryAction\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 <Link\n href={assetHref}\n className=\"flex-1 h-9 inline-flex items-center justify-center gap-1.5 rounded-[9px] border border-border bg-background text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0\" /> View\n </Link>\n )\n ) : (\n <Link\n href={assetHref}\n className=\"flex-1 h-9 inline-flex items-center justify-center gap-1.5 rounded-[9px] border border-border bg-background text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0\" /> View asset\n </Link>\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiDc;AA/Cd,mBAAyB;AACzB,kBAAiB;AACjB,mBAAkB;AAClB,0BAAuD;AACvD,+BAA2B;AAC3B,2BAA6B;AAC7B,gBAAmB;AACnB,kBAA2B;AAC3B,oBAAmC;AACnC,kBAAwB;AAoBjB,SAAS,YAAY,EAAE,OAAO,SAAS,OAAO,OAAO,QAAQ,cAAc,eAAe,UAAU,MAAM,GAAqB;AACpI,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,KAAK;AAC9C,QAAM,YAAY,MAAM,MAAM,aAAa,YAAY,MAAM,MAAM,aAAa;AAChF,QAAM,OAAO,MAAM,OAAO,QAAQ,UAAU,MAAM,UAAU;AAC5D,QAAM,QAAQ,MAAM,OAAO,YAAQ,wBAAW,MAAM,MAAM,KAAK,IAAI;AACnE,QAAM,YAAY,UAAU,MAAM,WAAW,IAAI,MAAM,UAAU;AAIjE,QAAM,gBAAgB,CAAC,EAAE,SAAS,UAAU,gBAAgB;AAG5D,MAAI,SAAS;AACX,WACE,4CAAC,uCAAW,WAAU,aACpB,uDAAC,YAAAA,SAAA,EAAK,MAAM,WAAW,WAAU,SAC/B;AAAA,kDAAC,SAAI,WAAU,mDACZ,mBAAS,CAAC,WACT,4CAAC,aAAAC,SAAA,EAAM,KAAK,OAAO,KAAK,MAAM,MAAI,MAAC,aAAW,MAAC,OAAM,iCAAgC,WAAU,wEAAuE,SAAS,MAAM,YAAY,IAAI,GAAG,IAExM,4CAAC,SAAI,WAAU,6GACb,uDAAC,UAAK,WAAU,2CAA0C;AAAA;AAAA,QAAE,MAAM;AAAA,SAAW,GAC/E,GAEJ;AAAA,MACA,6CAAC,SAAI,WAAU,qBACb;AAAA,oDAAC,OAAE,WAAU,kCAAkC,gBAAK;AAAA,QACnD,MAAM,OAAO,aACZ,6CAAC,OAAE,WAAU,oEACV;AAAA,gBAAM,MAAM,YAAY,4CAAC,qCAAa,QAAQ,MAAM,MAAM,UAAU,MAAM,IAAI;AAAA,cAC9E,kCAAmB,MAAM,MAAM,SAAS;AAAA,WAC3C;AAAA,QAEF,4CAAC,OAAE,WAAU,qCAAqC,mCAAQ,MAAM,SAAS,GAAE;AAAA,SAC7E;AAAA,OACF,GACF;AAAA,EAEJ;AAGA,SACE,4CAAC,uCAAW,WAAU,aACpB,uDAAC,YAAAD,SAAA,EAAK,MAAM,WAAW,WAAU,SAC/B;AAAA,gDAAC,SAAI,WAAU,mDACZ,mBAAS,CAAC,WACT,4CAAC,aAAAC,SAAA,EAAM,KAAK,OAAO,KAAK,MAAM,MAAI,MAAC,aAAW,MAAC,OAAM,2DAA0D,WAAU,wEAAuE,SAAS,MAAM,YAAY,IAAI,GAAG,IAElO,4CAAC,SAAI,WAAU,6GACb,uDAAC,UAAK,WAAU,4CAA2C;AAAA;AAAA,MAAE,MAAM;AAAA,OAAW,GAChF,GAEJ;AAAA,IAEA,6CAAC,SAAI,WAAU,mBACb;AAAA,mDAAC,SAAI,WAAU,WACb;AAAA,oDAAC,OAAE,WAAU,mDAAmD,gBAAK;AAAA,QACrE,4CAAC,OAAE,WAAU,kEACV,gBAAM,OAAO,cAAc,MAAM,MAAM,cAAc,IAAI,MAAM,UAAU,IAC5E;AAAA,SACF;AAAA,MAGC,MAAM,OAAO,aACZ,6CAAC,SAAI,WAAU,wCACb;AAAA,qDAAC,SAAI,WAAU,WACb;AAAA,sDAAC,OAAE,WAAU,+EACV,sBAAY,UAAU,SACzB;AAAA,UACA,6CAAC,OAAE,WAAU,sFACV;AAAA,kBAAM,MAAM,YAAY,4CAAC,qCAAa,QAAQ,MAAM,MAAM,UAAU,MAAM,IAAI;AAAA,gBAC9E,kCAAmB,MAAM,MAAM,SAAS;AAAA,YACzC,4CAAC,UAAK,WAAU,WAAW,gBAAM,MAAM,UAAS;AAAA,aAClD;AAAA,WACF;AAAA,QACA,4CAAC,OAAE,WAAU,mEACV,mCAAQ,MAAM,SAAS,GAC1B;AAAA,SACF;AAAA,MAGD,iBACC,6CAAC,SAAI,WAAU,6BACZ;AAAA,oBACC,gBACE,gBACE,QACF,4CAAC,SAAI,WAAU,2DACb;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,SAAS,CAAC,MAAM;AAAE,gBAAE,eAAe;AAAG,oBAAM,KAAK;AAAA,YAAG;AAAA,YAEpD;AAAA,0DAAC,2BAAI,WAAU,wBAAuB;AAAA,cAAE;AAAA;AAAA;AAAA,QAC1C,GACF,IAEA;AAAA,UAAC,YAAAD;AAAA,UAAA;AAAA,YACC,MAAM;AAAA,YACN,WAAU;AAAA,YAEV;AAAA,0DAAC,oCAAa,WAAU,wBAAuB;AAAA,cAAE;AAAA;AAAA;AAAA,QACnD,IAGF;AAAA,UAAC,YAAAA;AAAA,UAAA;AAAA,YACC,MAAM;AAAA,YACN,WAAU;AAAA,YAEV;AAAA,0DAAC,oCAAa,WAAU,wBAAuB;AAAA,cAAE;AAAA;AAAA;AAAA,QACnD;AAAA,QAED,UACC;AAAA,UAAC;AAAA;AAAA,YACC,eAAW;AAAA,cACT;AAAA,cACA,SACI,gEACA;AAAA,YACN;AAAA,YACA,SAAS,CAAC,MAAM;AAAE,gBAAE,eAAe;AAAG,kBAAI,CAAC,OAAQ,QAAO,KAAK;AAAA,YAAG;AAAA,YAClE,UAAU;AAAA,YACV,cAAY,SAAS,kBAAkB;AAAA,YAEtC,mBAAS,4CAAC,6BAAM,WAAU,eAAc,IAAK,4CAAC,oCAAa,WAAU,eAAc;AAAA;AAAA,QACtF;AAAA,QAED;AAAA,SACH;AAAA,OAEJ;AAAA,KACF,GACF;AAEJ;AAEO,SAAS,sBAAsB;AACpC,SACE,6CAAC,SAAI,WAAU,aACb;AAAA,gDAAC,SAAI,WAAU,+CAA8C;AAAA,IAC7D,6CAAC,SAAI,WAAU,mBACb;AAAA,mDAAC,SAAI,WAAU,aACb;AAAA,oDAAC,SAAI,WAAU,4CAA2C;AAAA,QAC1D,4CAAC,SAAI,WAAU,4CAA2C;AAAA,SAC5D;AAAA,MACA,4CAAC,SAAI,WAAU,4CAA2C;AAAA,MAC1D,4CAAC,SAAI,WAAU,4CAA2C;AAAA,OAC5D;AAAA,KACF;AAEJ;","names":["Link","Image"]}
|
|
@@ -8,9 +8,16 @@ interface ListingCardProps {
|
|
|
8
8
|
onCart?: (order: ApiOrder) => void;
|
|
9
9
|
/** App passes a fully constructed <DropdownMenu> here */
|
|
10
10
|
overflowMenu?: React.ReactNode;
|
|
11
|
+
/**
|
|
12
|
+
* Optional flex-1 primary control for listings, replacing the default
|
|
13
|
+
* Buy/View button — lets a host inject its own action (e.g. an owner
|
|
14
|
+
* "Cancel" with an app-specific, auth-coupled handler) while keeping this
|
|
15
|
+
* card's layout. Ignored for offers (which always render "View asset").
|
|
16
|
+
*/
|
|
17
|
+
primaryAction?: React.ReactNode;
|
|
11
18
|
compact?: boolean;
|
|
12
19
|
}
|
|
13
|
-
declare function ListingCard({ order, inCart, onBuy, onCart, overflowMenu, compact }: ListingCardProps): react_jsx_runtime.JSX.Element;
|
|
20
|
+
declare function ListingCard({ order, inCart, onBuy, onCart, overflowMenu, primaryAction, compact }: ListingCardProps): react_jsx_runtime.JSX.Element;
|
|
14
21
|
declare function ListingCardSkeleton(): react_jsx_runtime.JSX.Element;
|
|
15
22
|
|
|
16
23
|
export { ListingCard, type ListingCardProps, ListingCardSkeleton };
|
|
@@ -8,9 +8,16 @@ interface ListingCardProps {
|
|
|
8
8
|
onCart?: (order: ApiOrder) => void;
|
|
9
9
|
/** App passes a fully constructed <DropdownMenu> here */
|
|
10
10
|
overflowMenu?: React.ReactNode;
|
|
11
|
+
/**
|
|
12
|
+
* Optional flex-1 primary control for listings, replacing the default
|
|
13
|
+
* Buy/View button — lets a host inject its own action (e.g. an owner
|
|
14
|
+
* "Cancel" with an app-specific, auth-coupled handler) while keeping this
|
|
15
|
+
* card's layout. Ignored for offers (which always render "View asset").
|
|
16
|
+
*/
|
|
17
|
+
primaryAction?: React.ReactNode;
|
|
11
18
|
compact?: boolean;
|
|
12
19
|
}
|
|
13
|
-
declare function ListingCard({ order, inCart, onBuy, onCart, overflowMenu, compact }: ListingCardProps): react_jsx_runtime.JSX.Element;
|
|
20
|
+
declare function ListingCard({ order, inCart, onBuy, onCart, overflowMenu, primaryAction, compact }: ListingCardProps): react_jsx_runtime.JSX.Element;
|
|
14
21
|
declare function ListingCardSkeleton(): react_jsx_runtime.JSX.Element;
|
|
15
22
|
|
|
16
23
|
export { ListingCard, type ListingCardProps, ListingCardSkeleton };
|
|
@@ -10,13 +10,13 @@ import { cn } from "../utils/cn.js";
|
|
|
10
10
|
import { ipfsToHttp } from "../utils/ipfs.js";
|
|
11
11
|
import { formatDisplayPrice } from "../utils/format.js";
|
|
12
12
|
import { timeAgo } from "../utils/time.js";
|
|
13
|
-
function ListingCard({ order, inCart = false, onBuy, onCart, overflowMenu, compact = false }) {
|
|
13
|
+
function ListingCard({ order, inCart = false, onBuy, onCart, overflowMenu, primaryAction, compact = false }) {
|
|
14
14
|
const [imgError, setImgError] = useState(false);
|
|
15
15
|
const isListing = order.offer.itemType === "ERC721" || order.offer.itemType === "ERC1155";
|
|
16
16
|
const name = order.token?.name ?? `Token #${order.nftTokenId}`;
|
|
17
17
|
const image = order.token?.image ? ipfsToHttp(order.token.image) : null;
|
|
18
18
|
const assetHref = `/asset/${order.nftContract}/${order.nftTokenId}`;
|
|
19
|
-
const showActionBar = !!(onBuy || onCart || overflowMenu);
|
|
19
|
+
const showActionBar = !!(onBuy || onCart || overflowMenu || primaryAction);
|
|
20
20
|
if (compact) {
|
|
21
21
|
return /* @__PURE__ */ jsx(MotionCard, { className: "card-base", children: /* @__PURE__ */ jsxs(Link, { href: assetHref, className: "block", children: [
|
|
22
22
|
/* @__PURE__ */ jsx("div", { className: "relative aspect-square bg-muted overflow-hidden", children: image && !imgError ? /* @__PURE__ */ jsx(Image, { 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__ */ 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__ */ jsxs("span", { className: "text-xl font-mono text-muted-foreground", children: [
|
|
@@ -55,7 +55,7 @@ function ListingCard({ order, inCart = false, onBuy, onCart, overflowMenu, compa
|
|
|
55
55
|
/* @__PURE__ */ jsx("p", { className: "text-[10px] text-muted-foreground/60 whitespace-nowrap shrink-0", children: timeAgo(order.createdAt) })
|
|
56
56
|
] }),
|
|
57
57
|
showActionBar && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
58
|
-
isListing ? onBuy ? /* @__PURE__ */ jsx("div", { className: "btn-border-animated p-[1.5px] rounded-[10px] flex-1 h-9", children: /* @__PURE__ */ jsxs(
|
|
58
|
+
isListing ? primaryAction ? primaryAction : onBuy ? /* @__PURE__ */ jsx("div", { className: "btn-border-animated p-[1.5px] rounded-[10px] flex-1 h-9", children: /* @__PURE__ */ jsxs(
|
|
59
59
|
"button",
|
|
60
60
|
{
|
|
61
61
|
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]",
|
|
@@ -1 +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, ArrowUpRight } 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 // Show the action bar for listings (Buy/View) and for offers (View asset),\n // whenever the host wired any action or an overflow menu.\n const showActionBar = !!(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 inline-flex items-center gap-1\">\n {order.price.currency && <CurrencyIcon symbol={order.price.currency} size={11} />}\n {formatDisplayPrice(order.price.formatted)}\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-3.5 space-y-3\">\n <div className=\"min-w-0\">\n <p className=\"font-semibold text-[15px] truncate leading-snug\">{name}</p>\n <p className=\"text-[11px] text-muted-foreground truncate leading-snug mt-0.5\">\n {order.token?.description ? order.token.description : `#${order.nftTokenId}`}\n </p>\n </div>\n\n {/* Price / Offer + age */}\n {order.price?.formatted && (\n <div className=\"flex items-end justify-between gap-2\">\n <div className=\"min-w-0\">\n <p className=\"text-[10px] uppercase tracking-widest text-muted-foreground/55 leading-none\">\n {isListing ? \"Price\" : \"Offer\"}\n </p>\n <p className=\"text-lg font-bold price-value leading-none inline-flex items-center gap-1.5 mt-1.5\">\n {order.price.currency && <CurrencyIcon symbol={order.price.currency} size={18} />}\n {formatDisplayPrice(order.price.formatted)}\n <span className=\"sr-only\">{order.price.currency}</span>\n </p>\n </div>\n <p className=\"text-[10px] text-muted-foreground/60 whitespace-nowrap shrink-0\">\n {timeAgo(order.createdAt)}\n </p>\n </div>\n )}\n\n {showActionBar && (\n <div className=\"flex items-center gap-1.5\">\n {isListing ? (\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 <Link\n href={assetHref}\n className=\"flex-1 h-9 inline-flex items-center justify-center gap-1.5 rounded-[9px] border border-border bg-background text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0\" /> View\n </Link>\n )\n ) : (\n <Link\n href={assetHref}\n className=\"flex-1 h-9 inline-flex items-center justify-center gap-1.5 rounded-[9px] border border-border bg-background text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0\" /> View asset\n </Link>\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":[]}
|
|
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, ArrowUpRight } 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 /**\n * Optional flex-1 primary control for listings, replacing the default\n * Buy/View button — lets a host inject its own action (e.g. an owner\n * \"Cancel\" with an app-specific, auth-coupled handler) while keeping this\n * card's layout. Ignored for offers (which always render \"View asset\").\n */\n primaryAction?: React.ReactNode;\n compact?: boolean;\n}\n\nexport function ListingCard({ order, inCart = false, onBuy, onCart, overflowMenu, primaryAction, 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 // Show the action bar for listings (Buy/View) and for offers (View asset),\n // whenever the host wired any action or an overflow menu.\n const showActionBar = !!(onBuy || onCart || overflowMenu || primaryAction);\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 inline-flex items-center gap-1\">\n {order.price.currency && <CurrencyIcon symbol={order.price.currency} size={11} />}\n {formatDisplayPrice(order.price.formatted)}\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-3.5 space-y-3\">\n <div className=\"min-w-0\">\n <p className=\"font-semibold text-[15px] truncate leading-snug\">{name}</p>\n <p className=\"text-[11px] text-muted-foreground truncate leading-snug mt-0.5\">\n {order.token?.description ? order.token.description : `#${order.nftTokenId}`}\n </p>\n </div>\n\n {/* Price / Offer + age */}\n {order.price?.formatted && (\n <div className=\"flex items-end justify-between gap-2\">\n <div className=\"min-w-0\">\n <p className=\"text-[10px] uppercase tracking-widest text-muted-foreground/55 leading-none\">\n {isListing ? \"Price\" : \"Offer\"}\n </p>\n <p className=\"text-lg font-bold price-value leading-none inline-flex items-center gap-1.5 mt-1.5\">\n {order.price.currency && <CurrencyIcon symbol={order.price.currency} size={18} />}\n {formatDisplayPrice(order.price.formatted)}\n <span className=\"sr-only\">{order.price.currency}</span>\n </p>\n </div>\n <p className=\"text-[10px] text-muted-foreground/60 whitespace-nowrap shrink-0\">\n {timeAgo(order.createdAt)}\n </p>\n </div>\n )}\n\n {showActionBar && (\n <div className=\"flex items-center gap-1.5\">\n {isListing ? (\n primaryAction ? (\n primaryAction\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 <Link\n href={assetHref}\n className=\"flex-1 h-9 inline-flex items-center justify-center gap-1.5 rounded-[9px] border border-border bg-background text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0\" /> View\n </Link>\n )\n ) : (\n <Link\n href={assetHref}\n className=\"flex-1 h-9 inline-flex items-center justify-center gap-1.5 rounded-[9px] border border-border bg-background text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0\" /> View asset\n </Link>\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":[]}
|
package/dist/index.cjs
CHANGED
|
@@ -28,6 +28,7 @@ __export(index_exports, {
|
|
|
28
28
|
ActivityTicker: () => import_activity_ticker.ActivityTicker,
|
|
29
29
|
AddressDisplay: () => import_address_display.AddressDisplay,
|
|
30
30
|
AssetHeaderBlock: () => import_asset_top_sections.AssetHeaderBlock,
|
|
31
|
+
AssetLicenseSummary: () => import_asset_license_summary.AssetLicenseSummary,
|
|
31
32
|
AssetMarketsTab: () => import_asset_markets_tab.AssetMarketsTab,
|
|
32
33
|
AssetMediaColumn: () => import_asset_top_sections.AssetMediaColumn,
|
|
33
34
|
AssetOverviewContent: () => import_asset_overview_content.AssetOverviewContent,
|
|
@@ -99,6 +100,7 @@ __export(index_exports, {
|
|
|
99
100
|
formatDisplayPrice: () => import_format.formatDisplayPrice,
|
|
100
101
|
formatFdv: () => import_coins.formatFdv,
|
|
101
102
|
ipfsToHttp: () => import_ipfs.ipfsToHttp,
|
|
103
|
+
licenseSummary: () => import_license_summary.licenseSummary,
|
|
102
104
|
shortenAddress: () => import_address.shortenAddress,
|
|
103
105
|
timeAgo: () => import_time.timeAgo,
|
|
104
106
|
timeUntil: () => import_time.timeUntil,
|
|
@@ -109,11 +111,13 @@ var import_cn = require("./utils/cn.js");
|
|
|
109
111
|
var import_format = require("./utils/format.js");
|
|
110
112
|
var import_address = require("./utils/address.js");
|
|
111
113
|
var import_ipfs = require("./utils/ipfs.js");
|
|
114
|
+
var import_license_summary = require("./utils/license-summary.js");
|
|
112
115
|
var import_ip_types = require("./data/ip-types.js");
|
|
113
116
|
var import_ip = require("./data/ip.js");
|
|
114
117
|
var import_ip_templates = require("./data/ip-templates.js");
|
|
115
118
|
var import_ip_type_display = require("./components/ip-type-display.js");
|
|
116
119
|
var import_asset_overview_content = require("./components/asset-overview-content.js");
|
|
120
|
+
var import_asset_license_summary = require("./components/asset-license-summary.js");
|
|
117
121
|
var import_asset_markets_tab = require("./components/asset-markets-tab.js");
|
|
118
122
|
var import_parent_attribution_banner = require("./components/parent-attribution-banner.js");
|
|
119
123
|
var import_asset_top_sections = require("./components/asset-top-sections.js");
|
|
@@ -164,6 +168,7 @@ var import_portfolio_counts = require("./utils/portfolio-counts.js");
|
|
|
164
168
|
ActivityTicker,
|
|
165
169
|
AddressDisplay,
|
|
166
170
|
AssetHeaderBlock,
|
|
171
|
+
AssetLicenseSummary,
|
|
167
172
|
AssetMarketsTab,
|
|
168
173
|
AssetMediaColumn,
|
|
169
174
|
AssetOverviewContent,
|
|
@@ -235,6 +240,7 @@ var import_portfolio_counts = require("./utils/portfolio-counts.js");
|
|
|
235
240
|
formatDisplayPrice,
|
|
236
241
|
formatFdv,
|
|
237
242
|
ipfsToHttp,
|
|
243
|
+
licenseSummary,
|
|
238
244
|
shortenAddress,
|
|
239
245
|
timeAgo,
|
|
240
246
|
timeUntil,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// ── Utils ─────────────────────────────────────────────────────────────────────\nexport { cn } from \"./utils/cn.js\";\nexport { formatDisplayPrice } from \"./utils/format.js\";\nexport { shortenAddress } from \"./utils/address.js\";\nexport { ipfsToHttp } from \"./utils/ipfs.js\";\n\n// ── Data (server-safe — no React, safe in Server Components) ──────────────────\nexport { IP_TYPE_DATA, IP_TYPE_DATA_MAP } from \"./data/ip-types.js\";\nexport type { IpTypeData } from \"./data/ip-types.js\";\nexport {\n IP_TYPES, LICENSE_TYPES, GEOGRAPHIC_SCOPES, AI_POLICIES,\n DERIVATIVES_OPTIONS, LICENSE_TRAIT_TYPES,\n} from \"./data/ip.js\";\nexport type { IPType, LicenseType } from \"./data/ip.js\";\nexport {\n IP_TEMPLATES, EMBED_PLATFORM_META, SOCIAL_PLATFORM_META, TEMPLATE_TRAIT_TYPES, DOC_UPLOAD,\n} from \"./data/ip-templates.js\";\nexport type { EmbedPlatform, SocialPlatform, TraitSuggestion, IPTemplate, DocUploadConfig } from \"./data/ip-templates.js\";\nexport { IPTypeDisplay } from \"./components/ip-type-display.js\";\nexport { AssetOverviewContent } from \"./components/asset-overview-content.js\";\nexport { AssetMarketsTab } from \"./components/asset-markets-tab.js\";\nexport { ParentAttributionBanner } from \"./components/parent-attribution-banner.js\";\nexport type { ParentBannerProps } from \"./components/parent-attribution-banner.js\";\nexport { AssetMediaColumn, AssetHeaderBlock, buildEditionStats } from \"./components/asset-top-sections.js\";\nexport { BRAND } from \"./data/brand.js\";\n\n// ── Components (client-only — all have \"use client\") ─────────────────────────\nexport { CurrencyIcon, CurrencyAmount } from \"./components/currency-icon.js\";\nexport type { CurrencyIconProps, CurrencyAmountProps } from \"./components/currency-icon.js\";\n\nexport { IpTypeBadge, IP_TYPE_CONFIG, IP_TYPE_MAP } from \"./components/ip-type-badge.js\";\nexport type { IpTypeBadgeProps, IpTypeConfig } from \"./components/ip-type-badge.js\";\n\nexport { AddressDisplay } from \"./components/address-display.js\";\nexport type { AddressDisplayProps } from \"./components/address-display.js\";\n\nexport { MedialaneIcon } from \"./components/brand-icon.js\";\nexport type { MedialaneIconProps } from \"./components/brand-icon.js\";\nexport { MedialaneLogoFull } from \"./components/brand-logo.js\";\nexport type { MedialaneLogoFullProps } from \"./components/brand-logo.js\";\n\n// ── v0.2 additions ────────────────────────────────────────────────────────────\nexport { MotionCard, FadeIn, Stagger, StaggerItem, KineticWords, SPRING, EASE_OUT } from \"./components/motion-primitives.js\";\nexport { PageContainer } from \"./components/page-container.js\";\nexport type { PageContainerProps } from \"./components/page-container.js\";\nexport { ScrollSection } from \"./components/scroll-section.js\";\nexport type { ScrollSectionProps } from \"./components/scroll-section.js\";\nexport { ShareButton } from \"./components/share-button.js\";\nexport type { ShareButtonProps } from \"./components/share-button.js\";\nexport { CollectionCard, CollectionCardSkeleton } from \"./components/collection-card.js\";\nexport type { CollectionCardProps } from \"./components/collection-card.js\";\nexport { TokenCard, TokenCardSkeleton } from \"./components/token-card.js\";\nexport type { TokenCardProps, RarityTier } from \"./components/token-card.js\";\n// ── Coin discovery (chain-agnostic; price/data/href injected by the app) ─────\nexport {\n coinKind, formatCoinPrice, formatFdv,\n type CoinKind, type CoinCollectionLike, type CoinPriceLike,\n} from \"./data/coins.js\";\nexport { CoinCard, CoinRow, CoinCardSkeleton, type UseCoinPrice, type CoinTileProps } from \"./components/coin-card.js\";\nexport {\n CoinsExplorer,\n type CoinsExplorerProps, type CoinFilter, type CoinSort, type UseCoins,\n} from \"./components/coins-explorer.js\";\n\n// ── v0.3 additions ────────────────────────────────────────────────────────────\nexport { timeAgo, timeUntil } from \"./utils/time.js\";\nexport { ACTIVITY_TYPE_CONFIG, TYPE_FILTERS } from \"./data/activity.js\";\nexport type { ActivityTypeConfig } from \"./data/activity.js\";\nexport { HeroSlider, HeroSliderSkeleton } from \"./components/hero-slider.js\";\nexport type { HeroSliderProps } from \"./components/hero-slider.js\";\nexport { ActivityTicker } from \"./components/activity-ticker.js\";\nexport type { ActivityTickerProps } from \"./components/activity-ticker.js\";\nexport { ListingCard, ListingCardSkeleton } from \"./components/listing-card.js\";\nexport type { ListingCardProps } from \"./components/listing-card.js\";\nexport { ActivityRow } from \"./components/activity-row.js\";\nexport type { ActivityRowProps } from \"./components/activity-row.js\";\nexport { ActivityFeedShell } from \"./components/activity-feed-shell.js\";\nexport type { ActivityFeedShellProps } from \"./components/activity-feed-shell.js\";\nexport { CtaCardGrid } from \"./components/cta-card-grid.js\";\nexport type { CtaCardGridProps, CtaCardItem } from \"./components/cta-card-grid.js\";\n\n// ── v0.3.2 additions ─────────────────────────────────────────────────────────\nexport { DiscoverHero } from \"./components/discover-hero.js\";\nexport type { DiscoverHeroProps } from \"./components/discover-hero.js\";\nexport { FeaturedCarousel, FeaturedCarouselSkeleton } from \"./components/featured-carousel.js\";\nexport type { FeaturedCarouselProps } from \"./components/featured-carousel.js\";\nexport { DiscoverCollectionsStrip } from \"./components/discover-collections-strip.js\";\nexport type { DiscoverCollectionsStripProps } from \"./components/discover-collections-strip.js\";\nexport { DiscoverCreatorsStrip } from \"./components/discover-creators-strip.js\";\nexport type { DiscoverCreatorsStripProps } from \"./components/discover-creators-strip.js\";\nexport { DiscoverFeedSection } from \"./components/discover-feed-section.js\";\nexport type { DiscoverFeedSectionProps } from \"./components/discover-feed-section.js\";\nexport { ActivityCard, ActivityCardSkeleton, ACTIVITY_MESSAGES } from \"./components/activity-card.js\";\nexport type { ActivityCardProps } from \"./components/activity-card.js\";\n\n// ── Launchpad (grouped sections — single page-UI source since 0.8.0) ─────────\nexport { LaunchpadGroupedSections, LaunchpadServiceCard, SERVICE_HUES } from \"./components/launchpad-services.js\";\nexport { LaunchpadStrip } from \"./components/launchpad-strip.js\";\nexport type { LaunchpadStripProps } from \"./components/launchpad-strip.js\";\nexport type { LaunchpadGroupedSectionsProps, LaunchpadServiceCardProps, ServiceOverride, ServiceOverrides } from \"./components/launchpad-services.js\";\nexport { LAUNCHPAD_SERVICE_DEFINITIONS, LAUNCHPAD_SERVICE_GROUPS } from \"./data/launchpad-services.js\";\nexport type { ServiceDefinition, ServiceStatus, ServiceCategory, ServiceGroup, ServiceGroupDefinition } from \"./data/launchpad-services.js\";\n\n// ── v0.5.0 additions ─────────────────────────────────────────────────────────\nexport { NavCommandMenu, useNavCommandMenu } from \"./components/nav-command-menu.js\";\nexport type { NavCommand, NavCommandGroup, NavCommandMenuProps } from \"./components/nav-command-menu.js\";\n\n// ── v0.6.0 additions — portfolio subnav + counts ────────────────────────────\nexport { PortfolioSubnav } from \"./components/portfolio-subnav.js\";\nexport type {\n PortfolioSubnavProps,\n PortfolioNavItem,\n PortfolioNavGroup,\n PortfolioBadgeVariant,\n} from \"./components/portfolio-subnav.js\";\nexport { derivePortfolioCounts } from \"./utils/portfolio-counts.js\";\nexport type { PortfolioCounts, CountableOrder } from \"./utils/portfolio-counts.js\";\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,gBAAmB;AACnB,oBAAmC;AACnC,qBAA+B;AAC/B,kBAA2B;
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// ── Utils ─────────────────────────────────────────────────────────────────────\nexport { cn } from \"./utils/cn.js\";\nexport { formatDisplayPrice } from \"./utils/format.js\";\nexport { shortenAddress } from \"./utils/address.js\";\nexport { ipfsToHttp } from \"./utils/ipfs.js\";\nexport { licenseSummary } from \"./utils/license-summary.js\";\n\n// ── Data (server-safe — no React, safe in Server Components) ──────────────────\nexport { IP_TYPE_DATA, IP_TYPE_DATA_MAP } from \"./data/ip-types.js\";\nexport type { IpTypeData } from \"./data/ip-types.js\";\nexport {\n IP_TYPES, LICENSE_TYPES, GEOGRAPHIC_SCOPES, AI_POLICIES,\n DERIVATIVES_OPTIONS, LICENSE_TRAIT_TYPES,\n} from \"./data/ip.js\";\nexport type { IPType, LicenseType } from \"./data/ip.js\";\nexport {\n IP_TEMPLATES, EMBED_PLATFORM_META, SOCIAL_PLATFORM_META, TEMPLATE_TRAIT_TYPES, DOC_UPLOAD,\n} from \"./data/ip-templates.js\";\nexport type { EmbedPlatform, SocialPlatform, TraitSuggestion, IPTemplate, DocUploadConfig } from \"./data/ip-templates.js\";\nexport { IPTypeDisplay } from \"./components/ip-type-display.js\";\nexport { AssetOverviewContent } from \"./components/asset-overview-content.js\";\nexport { AssetLicenseSummary } from \"./components/asset-license-summary.js\";\nexport { AssetMarketsTab } from \"./components/asset-markets-tab.js\";\nexport { ParentAttributionBanner } from \"./components/parent-attribution-banner.js\";\nexport type { ParentBannerProps } from \"./components/parent-attribution-banner.js\";\nexport { AssetMediaColumn, AssetHeaderBlock, buildEditionStats } from \"./components/asset-top-sections.js\";\nexport { BRAND } from \"./data/brand.js\";\n\n// ── Components (client-only — all have \"use client\") ─────────────────────────\nexport { CurrencyIcon, CurrencyAmount } from \"./components/currency-icon.js\";\nexport type { CurrencyIconProps, CurrencyAmountProps } from \"./components/currency-icon.js\";\n\nexport { IpTypeBadge, IP_TYPE_CONFIG, IP_TYPE_MAP } from \"./components/ip-type-badge.js\";\nexport type { IpTypeBadgeProps, IpTypeConfig } from \"./components/ip-type-badge.js\";\n\nexport { AddressDisplay } from \"./components/address-display.js\";\nexport type { AddressDisplayProps } from \"./components/address-display.js\";\n\nexport { MedialaneIcon } from \"./components/brand-icon.js\";\nexport type { MedialaneIconProps } from \"./components/brand-icon.js\";\nexport { MedialaneLogoFull } from \"./components/brand-logo.js\";\nexport type { MedialaneLogoFullProps } from \"./components/brand-logo.js\";\n\n// ── v0.2 additions ────────────────────────────────────────────────────────────\nexport { MotionCard, FadeIn, Stagger, StaggerItem, KineticWords, SPRING, EASE_OUT } from \"./components/motion-primitives.js\";\nexport { PageContainer } from \"./components/page-container.js\";\nexport type { PageContainerProps } from \"./components/page-container.js\";\nexport { ScrollSection } from \"./components/scroll-section.js\";\nexport type { ScrollSectionProps } from \"./components/scroll-section.js\";\nexport { ShareButton } from \"./components/share-button.js\";\nexport type { ShareButtonProps } from \"./components/share-button.js\";\nexport { CollectionCard, CollectionCardSkeleton } from \"./components/collection-card.js\";\nexport type { CollectionCardProps } from \"./components/collection-card.js\";\nexport { TokenCard, TokenCardSkeleton } from \"./components/token-card.js\";\nexport type { TokenCardProps, RarityTier } from \"./components/token-card.js\";\n// ── Coin discovery (chain-agnostic; price/data/href injected by the app) ─────\nexport {\n coinKind, formatCoinPrice, formatFdv,\n type CoinKind, type CoinCollectionLike, type CoinPriceLike,\n} from \"./data/coins.js\";\nexport { CoinCard, CoinRow, CoinCardSkeleton, type UseCoinPrice, type CoinTileProps } from \"./components/coin-card.js\";\nexport {\n CoinsExplorer,\n type CoinsExplorerProps, type CoinFilter, type CoinSort, type UseCoins,\n} from \"./components/coins-explorer.js\";\n\n// ── v0.3 additions ────────────────────────────────────────────────────────────\nexport { timeAgo, timeUntil } from \"./utils/time.js\";\nexport { ACTIVITY_TYPE_CONFIG, TYPE_FILTERS } from \"./data/activity.js\";\nexport type { ActivityTypeConfig } from \"./data/activity.js\";\nexport { HeroSlider, HeroSliderSkeleton } from \"./components/hero-slider.js\";\nexport type { HeroSliderProps } from \"./components/hero-slider.js\";\nexport { ActivityTicker } from \"./components/activity-ticker.js\";\nexport type { ActivityTickerProps } from \"./components/activity-ticker.js\";\nexport { ListingCard, ListingCardSkeleton } from \"./components/listing-card.js\";\nexport type { ListingCardProps } from \"./components/listing-card.js\";\nexport { ActivityRow } from \"./components/activity-row.js\";\nexport type { ActivityRowProps } from \"./components/activity-row.js\";\nexport { ActivityFeedShell } from \"./components/activity-feed-shell.js\";\nexport type { ActivityFeedShellProps } from \"./components/activity-feed-shell.js\";\nexport { CtaCardGrid } from \"./components/cta-card-grid.js\";\nexport type { CtaCardGridProps, CtaCardItem } from \"./components/cta-card-grid.js\";\n\n// ── v0.3.2 additions ─────────────────────────────────────────────────────────\nexport { DiscoverHero } from \"./components/discover-hero.js\";\nexport type { DiscoverHeroProps } from \"./components/discover-hero.js\";\nexport { FeaturedCarousel, FeaturedCarouselSkeleton } from \"./components/featured-carousel.js\";\nexport type { FeaturedCarouselProps } from \"./components/featured-carousel.js\";\nexport { DiscoverCollectionsStrip } from \"./components/discover-collections-strip.js\";\nexport type { DiscoverCollectionsStripProps } from \"./components/discover-collections-strip.js\";\nexport { DiscoverCreatorsStrip } from \"./components/discover-creators-strip.js\";\nexport type { DiscoverCreatorsStripProps } from \"./components/discover-creators-strip.js\";\nexport { DiscoverFeedSection } from \"./components/discover-feed-section.js\";\nexport type { DiscoverFeedSectionProps } from \"./components/discover-feed-section.js\";\nexport { ActivityCard, ActivityCardSkeleton, ACTIVITY_MESSAGES } from \"./components/activity-card.js\";\nexport type { ActivityCardProps } from \"./components/activity-card.js\";\n\n// ── Launchpad (grouped sections — single page-UI source since 0.8.0) ─────────\nexport { LaunchpadGroupedSections, LaunchpadServiceCard, SERVICE_HUES } from \"./components/launchpad-services.js\";\nexport { LaunchpadStrip } from \"./components/launchpad-strip.js\";\nexport type { LaunchpadStripProps } from \"./components/launchpad-strip.js\";\nexport type { LaunchpadGroupedSectionsProps, LaunchpadServiceCardProps, ServiceOverride, ServiceOverrides } from \"./components/launchpad-services.js\";\nexport { LAUNCHPAD_SERVICE_DEFINITIONS, LAUNCHPAD_SERVICE_GROUPS } from \"./data/launchpad-services.js\";\nexport type { ServiceDefinition, ServiceStatus, ServiceCategory, ServiceGroup, ServiceGroupDefinition } from \"./data/launchpad-services.js\";\n\n// ── v0.5.0 additions ─────────────────────────────────────────────────────────\nexport { NavCommandMenu, useNavCommandMenu } from \"./components/nav-command-menu.js\";\nexport type { NavCommand, NavCommandGroup, NavCommandMenuProps } from \"./components/nav-command-menu.js\";\n\n// ── v0.6.0 additions — portfolio subnav + counts ────────────────────────────\nexport { PortfolioSubnav } from \"./components/portfolio-subnav.js\";\nexport type {\n PortfolioSubnavProps,\n PortfolioNavItem,\n PortfolioNavGroup,\n PortfolioBadgeVariant,\n} from \"./components/portfolio-subnav.js\";\nexport { derivePortfolioCounts } from \"./utils/portfolio-counts.js\";\nexport type { PortfolioCounts, CountableOrder } from \"./utils/portfolio-counts.js\";\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,gBAAmB;AACnB,oBAAmC;AACnC,qBAA+B;AAC/B,kBAA2B;AAC3B,6BAA+B;AAG/B,sBAA+C;AAE/C,gBAGO;AAEP,0BAEO;AAEP,6BAA8B;AAC9B,oCAAqC;AACrC,mCAAoC;AACpC,+BAAgC;AAChC,uCAAwC;AAExC,gCAAsE;AACtE,mBAAsB;AAGtB,2BAA6C;AAG7C,2BAAyD;AAGzD,6BAA+B;AAG/B,wBAA8B;AAE9B,wBAAkC;AAIlC,+BAAyF;AACzF,4BAA8B;AAE9B,4BAA8B;AAE9B,0BAA4B;AAE5B,6BAAuD;AAEvD,wBAA6C;AAG7C,mBAGO;AACP,uBAA2F;AAC3F,4BAGO;AAGP,kBAAmC;AACnC,sBAAmD;AAEnD,yBAA+C;AAE/C,6BAA+B;AAE/B,0BAAiD;AAEjD,0BAA4B;AAE5B,iCAAkC;AAElC,2BAA4B;AAI5B,2BAA6B;AAE7B,+BAA2D;AAE3D,wCAAyC;AAEzC,qCAAsC;AAEtC,mCAAoC;AAEpC,2BAAsE;AAItE,gCAA6E;AAC7E,6BAA+B;AAG/B,IAAAA,6BAAwE;AAIxE,8BAAkD;AAIlD,8BAAgC;AAOhC,8BAAsC;","names":["import_launchpad_services"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -2,11 +2,13 @@ export { cn } from './utils/cn.cjs';
|
|
|
2
2
|
export { formatDisplayPrice } from './utils/format.cjs';
|
|
3
3
|
export { shortenAddress } from './utils/address.cjs';
|
|
4
4
|
export { ipfsToHttp } from './utils/ipfs.cjs';
|
|
5
|
+
export { licenseSummary } from './utils/license-summary.cjs';
|
|
5
6
|
export { IP_TYPE_DATA, IP_TYPE_DATA_MAP, IpTypeData } from './data/ip-types.cjs';
|
|
6
7
|
export { AI_POLICIES, DERIVATIVES_OPTIONS, GEOGRAPHIC_SCOPES, IPType, IP_TYPES, LICENSE_TRAIT_TYPES, LICENSE_TYPES, LicenseType } from './data/ip.cjs';
|
|
7
8
|
export { DOC_UPLOAD, DocUploadConfig, EMBED_PLATFORM_META, EmbedPlatform, IPTemplate, IP_TEMPLATES, SOCIAL_PLATFORM_META, SocialPlatform, TEMPLATE_TRAIT_TYPES, TraitSuggestion } from './data/ip-templates.cjs';
|
|
8
9
|
export { IPTypeDisplay } from './components/ip-type-display.cjs';
|
|
9
10
|
export { AssetOverviewContent } from './components/asset-overview-content.cjs';
|
|
11
|
+
export { AssetLicenseSummary } from './components/asset-license-summary.cjs';
|
|
10
12
|
export { AssetMarketsTab } from './components/asset-markets-tab.cjs';
|
|
11
13
|
export { ParentAttributionBanner, ParentBannerProps } from './components/parent-attribution-banner.cjs';
|
|
12
14
|
export { AssetHeaderBlock, AssetMediaColumn, buildEditionStats } from './components/asset-top-sections.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -2,11 +2,13 @@ export { cn } from './utils/cn.js';
|
|
|
2
2
|
export { formatDisplayPrice } from './utils/format.js';
|
|
3
3
|
export { shortenAddress } from './utils/address.js';
|
|
4
4
|
export { ipfsToHttp } from './utils/ipfs.js';
|
|
5
|
+
export { licenseSummary } from './utils/license-summary.js';
|
|
5
6
|
export { IP_TYPE_DATA, IP_TYPE_DATA_MAP, IpTypeData } from './data/ip-types.js';
|
|
6
7
|
export { AI_POLICIES, DERIVATIVES_OPTIONS, GEOGRAPHIC_SCOPES, IPType, IP_TYPES, LICENSE_TRAIT_TYPES, LICENSE_TYPES, LicenseType } from './data/ip.js';
|
|
7
8
|
export { DOC_UPLOAD, DocUploadConfig, EMBED_PLATFORM_META, EmbedPlatform, IPTemplate, IP_TEMPLATES, SOCIAL_PLATFORM_META, SocialPlatform, TEMPLATE_TRAIT_TYPES, TraitSuggestion } from './data/ip-templates.js';
|
|
8
9
|
export { IPTypeDisplay } from './components/ip-type-display.js';
|
|
9
10
|
export { AssetOverviewContent } from './components/asset-overview-content.js';
|
|
11
|
+
export { AssetLicenseSummary } from './components/asset-license-summary.js';
|
|
10
12
|
export { AssetMarketsTab } from './components/asset-markets-tab.js';
|
|
11
13
|
export { ParentAttributionBanner, ParentBannerProps } from './components/parent-attribution-banner.js';
|
|
12
14
|
export { AssetHeaderBlock, AssetMediaColumn, buildEditionStats } from './components/asset-top-sections.js';
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import { cn } from "./utils/cn.js";
|
|
|
2
2
|
import { formatDisplayPrice } from "./utils/format.js";
|
|
3
3
|
import { shortenAddress } from "./utils/address.js";
|
|
4
4
|
import { ipfsToHttp } from "./utils/ipfs.js";
|
|
5
|
+
import { licenseSummary } from "./utils/license-summary.js";
|
|
5
6
|
import { IP_TYPE_DATA, IP_TYPE_DATA_MAP } from "./data/ip-types.js";
|
|
6
7
|
import {
|
|
7
8
|
IP_TYPES,
|
|
@@ -20,6 +21,7 @@ import {
|
|
|
20
21
|
} from "./data/ip-templates.js";
|
|
21
22
|
import { IPTypeDisplay } from "./components/ip-type-display.js";
|
|
22
23
|
import { AssetOverviewContent } from "./components/asset-overview-content.js";
|
|
24
|
+
import { AssetLicenseSummary } from "./components/asset-license-summary.js";
|
|
23
25
|
import { AssetMarketsTab } from "./components/asset-markets-tab.js";
|
|
24
26
|
import { ParentAttributionBanner } from "./components/parent-attribution-banner.js";
|
|
25
27
|
import { AssetMediaColumn, AssetHeaderBlock, buildEditionStats } from "./components/asset-top-sections.js";
|
|
@@ -75,6 +77,7 @@ export {
|
|
|
75
77
|
ActivityTicker,
|
|
76
78
|
AddressDisplay,
|
|
77
79
|
AssetHeaderBlock,
|
|
80
|
+
AssetLicenseSummary,
|
|
78
81
|
AssetMarketsTab,
|
|
79
82
|
AssetMediaColumn,
|
|
80
83
|
AssetOverviewContent,
|
|
@@ -146,6 +149,7 @@ export {
|
|
|
146
149
|
formatDisplayPrice,
|
|
147
150
|
formatFdv,
|
|
148
151
|
ipfsToHttp,
|
|
152
|
+
licenseSummary,
|
|
149
153
|
shortenAddress,
|
|
150
154
|
timeAgo,
|
|
151
155
|
timeUntil,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// ── Utils ─────────────────────────────────────────────────────────────────────\nexport { cn } from \"./utils/cn.js\";\nexport { formatDisplayPrice } from \"./utils/format.js\";\nexport { shortenAddress } from \"./utils/address.js\";\nexport { ipfsToHttp } from \"./utils/ipfs.js\";\n\n// ── Data (server-safe — no React, safe in Server Components) ──────────────────\nexport { IP_TYPE_DATA, IP_TYPE_DATA_MAP } from \"./data/ip-types.js\";\nexport type { IpTypeData } from \"./data/ip-types.js\";\nexport {\n IP_TYPES, LICENSE_TYPES, GEOGRAPHIC_SCOPES, AI_POLICIES,\n DERIVATIVES_OPTIONS, LICENSE_TRAIT_TYPES,\n} from \"./data/ip.js\";\nexport type { IPType, LicenseType } from \"./data/ip.js\";\nexport {\n IP_TEMPLATES, EMBED_PLATFORM_META, SOCIAL_PLATFORM_META, TEMPLATE_TRAIT_TYPES, DOC_UPLOAD,\n} from \"./data/ip-templates.js\";\nexport type { EmbedPlatform, SocialPlatform, TraitSuggestion, IPTemplate, DocUploadConfig } from \"./data/ip-templates.js\";\nexport { IPTypeDisplay } from \"./components/ip-type-display.js\";\nexport { AssetOverviewContent } from \"./components/asset-overview-content.js\";\nexport { AssetMarketsTab } from \"./components/asset-markets-tab.js\";\nexport { ParentAttributionBanner } from \"./components/parent-attribution-banner.js\";\nexport type { ParentBannerProps } from \"./components/parent-attribution-banner.js\";\nexport { AssetMediaColumn, AssetHeaderBlock, buildEditionStats } from \"./components/asset-top-sections.js\";\nexport { BRAND } from \"./data/brand.js\";\n\n// ── Components (client-only — all have \"use client\") ─────────────────────────\nexport { CurrencyIcon, CurrencyAmount } from \"./components/currency-icon.js\";\nexport type { CurrencyIconProps, CurrencyAmountProps } from \"./components/currency-icon.js\";\n\nexport { IpTypeBadge, IP_TYPE_CONFIG, IP_TYPE_MAP } from \"./components/ip-type-badge.js\";\nexport type { IpTypeBadgeProps, IpTypeConfig } from \"./components/ip-type-badge.js\";\n\nexport { AddressDisplay } from \"./components/address-display.js\";\nexport type { AddressDisplayProps } from \"./components/address-display.js\";\n\nexport { MedialaneIcon } from \"./components/brand-icon.js\";\nexport type { MedialaneIconProps } from \"./components/brand-icon.js\";\nexport { MedialaneLogoFull } from \"./components/brand-logo.js\";\nexport type { MedialaneLogoFullProps } from \"./components/brand-logo.js\";\n\n// ── v0.2 additions ────────────────────────────────────────────────────────────\nexport { MotionCard, FadeIn, Stagger, StaggerItem, KineticWords, SPRING, EASE_OUT } from \"./components/motion-primitives.js\";\nexport { PageContainer } from \"./components/page-container.js\";\nexport type { PageContainerProps } from \"./components/page-container.js\";\nexport { ScrollSection } from \"./components/scroll-section.js\";\nexport type { ScrollSectionProps } from \"./components/scroll-section.js\";\nexport { ShareButton } from \"./components/share-button.js\";\nexport type { ShareButtonProps } from \"./components/share-button.js\";\nexport { CollectionCard, CollectionCardSkeleton } from \"./components/collection-card.js\";\nexport type { CollectionCardProps } from \"./components/collection-card.js\";\nexport { TokenCard, TokenCardSkeleton } from \"./components/token-card.js\";\nexport type { TokenCardProps, RarityTier } from \"./components/token-card.js\";\n// ── Coin discovery (chain-agnostic; price/data/href injected by the app) ─────\nexport {\n coinKind, formatCoinPrice, formatFdv,\n type CoinKind, type CoinCollectionLike, type CoinPriceLike,\n} from \"./data/coins.js\";\nexport { CoinCard, CoinRow, CoinCardSkeleton, type UseCoinPrice, type CoinTileProps } from \"./components/coin-card.js\";\nexport {\n CoinsExplorer,\n type CoinsExplorerProps, type CoinFilter, type CoinSort, type UseCoins,\n} from \"./components/coins-explorer.js\";\n\n// ── v0.3 additions ────────────────────────────────────────────────────────────\nexport { timeAgo, timeUntil } from \"./utils/time.js\";\nexport { ACTIVITY_TYPE_CONFIG, TYPE_FILTERS } from \"./data/activity.js\";\nexport type { ActivityTypeConfig } from \"./data/activity.js\";\nexport { HeroSlider, HeroSliderSkeleton } from \"./components/hero-slider.js\";\nexport type { HeroSliderProps } from \"./components/hero-slider.js\";\nexport { ActivityTicker } from \"./components/activity-ticker.js\";\nexport type { ActivityTickerProps } from \"./components/activity-ticker.js\";\nexport { ListingCard, ListingCardSkeleton } from \"./components/listing-card.js\";\nexport type { ListingCardProps } from \"./components/listing-card.js\";\nexport { ActivityRow } from \"./components/activity-row.js\";\nexport type { ActivityRowProps } from \"./components/activity-row.js\";\nexport { ActivityFeedShell } from \"./components/activity-feed-shell.js\";\nexport type { ActivityFeedShellProps } from \"./components/activity-feed-shell.js\";\nexport { CtaCardGrid } from \"./components/cta-card-grid.js\";\nexport type { CtaCardGridProps, CtaCardItem } from \"./components/cta-card-grid.js\";\n\n// ── v0.3.2 additions ─────────────────────────────────────────────────────────\nexport { DiscoverHero } from \"./components/discover-hero.js\";\nexport type { DiscoverHeroProps } from \"./components/discover-hero.js\";\nexport { FeaturedCarousel, FeaturedCarouselSkeleton } from \"./components/featured-carousel.js\";\nexport type { FeaturedCarouselProps } from \"./components/featured-carousel.js\";\nexport { DiscoverCollectionsStrip } from \"./components/discover-collections-strip.js\";\nexport type { DiscoverCollectionsStripProps } from \"./components/discover-collections-strip.js\";\nexport { DiscoverCreatorsStrip } from \"./components/discover-creators-strip.js\";\nexport type { DiscoverCreatorsStripProps } from \"./components/discover-creators-strip.js\";\nexport { DiscoverFeedSection } from \"./components/discover-feed-section.js\";\nexport type { DiscoverFeedSectionProps } from \"./components/discover-feed-section.js\";\nexport { ActivityCard, ActivityCardSkeleton, ACTIVITY_MESSAGES } from \"./components/activity-card.js\";\nexport type { ActivityCardProps } from \"./components/activity-card.js\";\n\n// ── Launchpad (grouped sections — single page-UI source since 0.8.0) ─────────\nexport { LaunchpadGroupedSections, LaunchpadServiceCard, SERVICE_HUES } from \"./components/launchpad-services.js\";\nexport { LaunchpadStrip } from \"./components/launchpad-strip.js\";\nexport type { LaunchpadStripProps } from \"./components/launchpad-strip.js\";\nexport type { LaunchpadGroupedSectionsProps, LaunchpadServiceCardProps, ServiceOverride, ServiceOverrides } from \"./components/launchpad-services.js\";\nexport { LAUNCHPAD_SERVICE_DEFINITIONS, LAUNCHPAD_SERVICE_GROUPS } from \"./data/launchpad-services.js\";\nexport type { ServiceDefinition, ServiceStatus, ServiceCategory, ServiceGroup, ServiceGroupDefinition } from \"./data/launchpad-services.js\";\n\n// ── v0.5.0 additions ─────────────────────────────────────────────────────────\nexport { NavCommandMenu, useNavCommandMenu } from \"./components/nav-command-menu.js\";\nexport type { NavCommand, NavCommandGroup, NavCommandMenuProps } from \"./components/nav-command-menu.js\";\n\n// ── v0.6.0 additions — portfolio subnav + counts ────────────────────────────\nexport { PortfolioSubnav } from \"./components/portfolio-subnav.js\";\nexport type {\n PortfolioSubnavProps,\n PortfolioNavItem,\n PortfolioNavGroup,\n PortfolioBadgeVariant,\n} from \"./components/portfolio-subnav.js\";\nexport { derivePortfolioCounts } from \"./utils/portfolio-counts.js\";\nexport type { PortfolioCounts, CountableOrder } from \"./utils/portfolio-counts.js\";\n"],"mappings":"AACA,SAAS,UAAU;AACnB,SAAS,0BAA0B;AACnC,SAAS,sBAAsB;AAC/B,SAAS,kBAAkB;
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// ── Utils ─────────────────────────────────────────────────────────────────────\nexport { cn } from \"./utils/cn.js\";\nexport { formatDisplayPrice } from \"./utils/format.js\";\nexport { shortenAddress } from \"./utils/address.js\";\nexport { ipfsToHttp } from \"./utils/ipfs.js\";\nexport { licenseSummary } from \"./utils/license-summary.js\";\n\n// ── Data (server-safe — no React, safe in Server Components) ──────────────────\nexport { IP_TYPE_DATA, IP_TYPE_DATA_MAP } from \"./data/ip-types.js\";\nexport type { IpTypeData } from \"./data/ip-types.js\";\nexport {\n IP_TYPES, LICENSE_TYPES, GEOGRAPHIC_SCOPES, AI_POLICIES,\n DERIVATIVES_OPTIONS, LICENSE_TRAIT_TYPES,\n} from \"./data/ip.js\";\nexport type { IPType, LicenseType } from \"./data/ip.js\";\nexport {\n IP_TEMPLATES, EMBED_PLATFORM_META, SOCIAL_PLATFORM_META, TEMPLATE_TRAIT_TYPES, DOC_UPLOAD,\n} from \"./data/ip-templates.js\";\nexport type { EmbedPlatform, SocialPlatform, TraitSuggestion, IPTemplate, DocUploadConfig } from \"./data/ip-templates.js\";\nexport { IPTypeDisplay } from \"./components/ip-type-display.js\";\nexport { AssetOverviewContent } from \"./components/asset-overview-content.js\";\nexport { AssetLicenseSummary } from \"./components/asset-license-summary.js\";\nexport { AssetMarketsTab } from \"./components/asset-markets-tab.js\";\nexport { ParentAttributionBanner } from \"./components/parent-attribution-banner.js\";\nexport type { ParentBannerProps } from \"./components/parent-attribution-banner.js\";\nexport { AssetMediaColumn, AssetHeaderBlock, buildEditionStats } from \"./components/asset-top-sections.js\";\nexport { BRAND } from \"./data/brand.js\";\n\n// ── Components (client-only — all have \"use client\") ─────────────────────────\nexport { CurrencyIcon, CurrencyAmount } from \"./components/currency-icon.js\";\nexport type { CurrencyIconProps, CurrencyAmountProps } from \"./components/currency-icon.js\";\n\nexport { IpTypeBadge, IP_TYPE_CONFIG, IP_TYPE_MAP } from \"./components/ip-type-badge.js\";\nexport type { IpTypeBadgeProps, IpTypeConfig } from \"./components/ip-type-badge.js\";\n\nexport { AddressDisplay } from \"./components/address-display.js\";\nexport type { AddressDisplayProps } from \"./components/address-display.js\";\n\nexport { MedialaneIcon } from \"./components/brand-icon.js\";\nexport type { MedialaneIconProps } from \"./components/brand-icon.js\";\nexport { MedialaneLogoFull } from \"./components/brand-logo.js\";\nexport type { MedialaneLogoFullProps } from \"./components/brand-logo.js\";\n\n// ── v0.2 additions ────────────────────────────────────────────────────────────\nexport { MotionCard, FadeIn, Stagger, StaggerItem, KineticWords, SPRING, EASE_OUT } from \"./components/motion-primitives.js\";\nexport { PageContainer } from \"./components/page-container.js\";\nexport type { PageContainerProps } from \"./components/page-container.js\";\nexport { ScrollSection } from \"./components/scroll-section.js\";\nexport type { ScrollSectionProps } from \"./components/scroll-section.js\";\nexport { ShareButton } from \"./components/share-button.js\";\nexport type { ShareButtonProps } from \"./components/share-button.js\";\nexport { CollectionCard, CollectionCardSkeleton } from \"./components/collection-card.js\";\nexport type { CollectionCardProps } from \"./components/collection-card.js\";\nexport { TokenCard, TokenCardSkeleton } from \"./components/token-card.js\";\nexport type { TokenCardProps, RarityTier } from \"./components/token-card.js\";\n// ── Coin discovery (chain-agnostic; price/data/href injected by the app) ─────\nexport {\n coinKind, formatCoinPrice, formatFdv,\n type CoinKind, type CoinCollectionLike, type CoinPriceLike,\n} from \"./data/coins.js\";\nexport { CoinCard, CoinRow, CoinCardSkeleton, type UseCoinPrice, type CoinTileProps } from \"./components/coin-card.js\";\nexport {\n CoinsExplorer,\n type CoinsExplorerProps, type CoinFilter, type CoinSort, type UseCoins,\n} from \"./components/coins-explorer.js\";\n\n// ── v0.3 additions ────────────────────────────────────────────────────────────\nexport { timeAgo, timeUntil } from \"./utils/time.js\";\nexport { ACTIVITY_TYPE_CONFIG, TYPE_FILTERS } from \"./data/activity.js\";\nexport type { ActivityTypeConfig } from \"./data/activity.js\";\nexport { HeroSlider, HeroSliderSkeleton } from \"./components/hero-slider.js\";\nexport type { HeroSliderProps } from \"./components/hero-slider.js\";\nexport { ActivityTicker } from \"./components/activity-ticker.js\";\nexport type { ActivityTickerProps } from \"./components/activity-ticker.js\";\nexport { ListingCard, ListingCardSkeleton } from \"./components/listing-card.js\";\nexport type { ListingCardProps } from \"./components/listing-card.js\";\nexport { ActivityRow } from \"./components/activity-row.js\";\nexport type { ActivityRowProps } from \"./components/activity-row.js\";\nexport { ActivityFeedShell } from \"./components/activity-feed-shell.js\";\nexport type { ActivityFeedShellProps } from \"./components/activity-feed-shell.js\";\nexport { CtaCardGrid } from \"./components/cta-card-grid.js\";\nexport type { CtaCardGridProps, CtaCardItem } from \"./components/cta-card-grid.js\";\n\n// ── v0.3.2 additions ─────────────────────────────────────────────────────────\nexport { DiscoverHero } from \"./components/discover-hero.js\";\nexport type { DiscoverHeroProps } from \"./components/discover-hero.js\";\nexport { FeaturedCarousel, FeaturedCarouselSkeleton } from \"./components/featured-carousel.js\";\nexport type { FeaturedCarouselProps } from \"./components/featured-carousel.js\";\nexport { DiscoverCollectionsStrip } from \"./components/discover-collections-strip.js\";\nexport type { DiscoverCollectionsStripProps } from \"./components/discover-collections-strip.js\";\nexport { DiscoverCreatorsStrip } from \"./components/discover-creators-strip.js\";\nexport type { DiscoverCreatorsStripProps } from \"./components/discover-creators-strip.js\";\nexport { DiscoverFeedSection } from \"./components/discover-feed-section.js\";\nexport type { DiscoverFeedSectionProps } from \"./components/discover-feed-section.js\";\nexport { ActivityCard, ActivityCardSkeleton, ACTIVITY_MESSAGES } from \"./components/activity-card.js\";\nexport type { ActivityCardProps } from \"./components/activity-card.js\";\n\n// ── Launchpad (grouped sections — single page-UI source since 0.8.0) ─────────\nexport { LaunchpadGroupedSections, LaunchpadServiceCard, SERVICE_HUES } from \"./components/launchpad-services.js\";\nexport { LaunchpadStrip } from \"./components/launchpad-strip.js\";\nexport type { LaunchpadStripProps } from \"./components/launchpad-strip.js\";\nexport type { LaunchpadGroupedSectionsProps, LaunchpadServiceCardProps, ServiceOverride, ServiceOverrides } from \"./components/launchpad-services.js\";\nexport { LAUNCHPAD_SERVICE_DEFINITIONS, LAUNCHPAD_SERVICE_GROUPS } from \"./data/launchpad-services.js\";\nexport type { ServiceDefinition, ServiceStatus, ServiceCategory, ServiceGroup, ServiceGroupDefinition } from \"./data/launchpad-services.js\";\n\n// ── v0.5.0 additions ─────────────────────────────────────────────────────────\nexport { NavCommandMenu, useNavCommandMenu } from \"./components/nav-command-menu.js\";\nexport type { NavCommand, NavCommandGroup, NavCommandMenuProps } from \"./components/nav-command-menu.js\";\n\n// ── v0.6.0 additions — portfolio subnav + counts ────────────────────────────\nexport { PortfolioSubnav } from \"./components/portfolio-subnav.js\";\nexport type {\n PortfolioSubnavProps,\n PortfolioNavItem,\n PortfolioNavGroup,\n PortfolioBadgeVariant,\n} from \"./components/portfolio-subnav.js\";\nexport { derivePortfolioCounts } from \"./utils/portfolio-counts.js\";\nexport type { PortfolioCounts, CountableOrder } from \"./utils/portfolio-counts.js\";\n"],"mappings":"AACA,SAAS,UAAU;AACnB,SAAS,0BAA0B;AACnC,SAAS,sBAAsB;AAC/B,SAAS,kBAAkB;AAC3B,SAAS,sBAAsB;AAG/B,SAAS,cAAc,wBAAwB;AAE/C;AAAA,EACE;AAAA,EAAU;AAAA,EAAe;AAAA,EAAmB;AAAA,EAC5C;AAAA,EAAqB;AAAA,OAChB;AAEP;AAAA,EACE;AAAA,EAAc;AAAA,EAAqB;AAAA,EAAsB;AAAA,EAAsB;AAAA,OAC1E;AAEP,SAAS,qBAAqB;AAC9B,SAAS,4BAA4B;AACrC,SAAS,2BAA2B;AACpC,SAAS,uBAAuB;AAChC,SAAS,+BAA+B;AAExC,SAAS,kBAAkB,kBAAkB,yBAAyB;AACtE,SAAS,aAAa;AAGtB,SAAS,cAAc,sBAAsB;AAG7C,SAAS,aAAa,gBAAgB,mBAAmB;AAGzD,SAAS,sBAAsB;AAG/B,SAAS,qBAAqB;AAE9B,SAAS,yBAAyB;AAIlC,SAAS,YAAY,QAAQ,SAAS,aAAa,cAAc,QAAQ,gBAAgB;AACzF,SAAS,qBAAqB;AAE9B,SAAS,qBAAqB;AAE9B,SAAS,mBAAmB;AAE5B,SAAS,gBAAgB,8BAA8B;AAEvD,SAAS,WAAW,yBAAyB;AAG7C;AAAA,EACE;AAAA,EAAU;AAAA,EAAiB;AAAA,OAEtB;AACP,SAAS,UAAU,SAAS,wBAA+D;AAC3F;AAAA,EACE;AAAA,OAEK;AAGP,SAAS,SAAS,iBAAiB;AACnC,SAAS,sBAAsB,oBAAoB;AAEnD,SAAS,YAAY,0BAA0B;AAE/C,SAAS,sBAAsB;AAE/B,SAAS,aAAa,2BAA2B;AAEjD,SAAS,mBAAmB;AAE5B,SAAS,yBAAyB;AAElC,SAAS,mBAAmB;AAI5B,SAAS,oBAAoB;AAE7B,SAAS,kBAAkB,gCAAgC;AAE3D,SAAS,gCAAgC;AAEzC,SAAS,6BAA6B;AAEtC,SAAS,2BAA2B;AAEpC,SAAS,cAAc,sBAAsB,yBAAyB;AAItE,SAAS,0BAA0B,sBAAsB,oBAAoB;AAC7E,SAAS,sBAAsB;AAG/B,SAAS,+BAA+B,gCAAgC;AAIxE,SAAS,gBAAgB,yBAAyB;AAIlD,SAAS,uBAAuB;AAOhC,SAAS,6BAA6B;","names":[]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var license_summary_exports = {};
|
|
20
|
+
__export(license_summary_exports, {
|
|
21
|
+
licenseSummary: () => licenseSummary
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(license_summary_exports);
|
|
24
|
+
const get = (a, key) => a.find((x) => x.trait_type?.toLowerCase() === key)?.value;
|
|
25
|
+
function licenseSummary(attributes) {
|
|
26
|
+
const commercialRaw = get(attributes, "commercial use");
|
|
27
|
+
const derivatives = (get(attributes, "derivatives") ?? "").toLowerCase();
|
|
28
|
+
const ai = (get(attributes, "ai policy") ?? get(attributes, "ai & data mining") ?? "").toLowerCase();
|
|
29
|
+
const territory = get(attributes, "territory") ?? "";
|
|
30
|
+
if (!commercialRaw && !derivatives && !ai) return null;
|
|
31
|
+
const commercial = (commercialRaw ?? "").toLowerCase() === "yes";
|
|
32
|
+
const remix = derivatives === "not allowed" ? "No remixing" : commercial ? "Open to remix and commercial use" : "Open to remix";
|
|
33
|
+
const where = territory ? `, ${territory.toLowerCase()}` : "";
|
|
34
|
+
const aiClause = ai.includes("not") ? " \u2014 no AI training" : "";
|
|
35
|
+
return `${remix}${where}${aiClause}.`;
|
|
36
|
+
}
|
|
37
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
38
|
+
0 && (module.exports = {
|
|
39
|
+
licenseSummary
|
|
40
|
+
});
|
|
41
|
+
//# sourceMappingURL=license-summary.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/license-summary.ts"],"sourcesContent":["type Attr = { trait_type?: string; value?: string };\n\nconst get = (a: Attr[], key: string): string | undefined =>\n a.find((x) => x.trait_type?.toLowerCase() === key)?.value;\n\n/**\n * One plain-language sentence summarizing the license, derived from the license\n * traits. Deliberately omits attribution/credit wording (not the place for it).\n * Returns null when there's no license data to summarize.\n *\n * Trait keys match the asset metadata: \"Commercial Use\", \"Derivatives\",\n * \"AI Policy\", \"Territory\".\n */\nexport function licenseSummary(attributes: Attr[]): string | null {\n const commercialRaw = get(attributes, \"commercial use\");\n const derivatives = (get(attributes, \"derivatives\") ?? \"\").toLowerCase();\n const ai = (get(attributes, \"ai policy\") ?? get(attributes, \"ai & data mining\") ?? \"\").toLowerCase();\n const territory = get(attributes, \"territory\") ?? \"\";\n\n if (!commercialRaw && !derivatives && !ai) return null;\n\n const commercial = (commercialRaw ?? \"\").toLowerCase() === \"yes\";\n const remix =\n derivatives === \"not allowed\"\n ? \"No remixing\"\n : commercial\n ? \"Open to remix and commercial use\"\n : \"Open to remix\";\n const where = territory ? `, ${territory.toLowerCase()}` : \"\";\n const aiClause = ai.includes(\"not\") ? \" — no AI training\" : \"\";\n return `${remix}${where}${aiClause}.`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,MAAM,MAAM,CAAC,GAAW,QACtB,EAAE,KAAK,CAAC,MAAM,EAAE,YAAY,YAAY,MAAM,GAAG,GAAG;AAU/C,SAAS,eAAe,YAAmC;AAChE,QAAM,gBAAgB,IAAI,YAAY,gBAAgB;AACtD,QAAM,eAAe,IAAI,YAAY,aAAa,KAAK,IAAI,YAAY;AACvE,QAAM,MAAM,IAAI,YAAY,WAAW,KAAK,IAAI,YAAY,kBAAkB,KAAK,IAAI,YAAY;AACnG,QAAM,YAAY,IAAI,YAAY,WAAW,KAAK;AAElD,MAAI,CAAC,iBAAiB,CAAC,eAAe,CAAC,GAAI,QAAO;AAElD,QAAM,cAAc,iBAAiB,IAAI,YAAY,MAAM;AAC3D,QAAM,QACJ,gBAAgB,gBACZ,gBACA,aACE,qCACA;AACR,QAAM,QAAQ,YAAY,KAAK,UAAU,YAAY,CAAC,KAAK;AAC3D,QAAM,WAAW,GAAG,SAAS,KAAK,IAAI,2BAAsB;AAC5D,SAAO,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ;AACpC;","names":[]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
type Attr = {
|
|
2
|
+
trait_type?: string;
|
|
3
|
+
value?: string;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* One plain-language sentence summarizing the license, derived from the license
|
|
7
|
+
* traits. Deliberately omits attribution/credit wording (not the place for it).
|
|
8
|
+
* Returns null when there's no license data to summarize.
|
|
9
|
+
*
|
|
10
|
+
* Trait keys match the asset metadata: "Commercial Use", "Derivatives",
|
|
11
|
+
* "AI Policy", "Territory".
|
|
12
|
+
*/
|
|
13
|
+
declare function licenseSummary(attributes: Attr[]): string | null;
|
|
14
|
+
|
|
15
|
+
export { licenseSummary };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
type Attr = {
|
|
2
|
+
trait_type?: string;
|
|
3
|
+
value?: string;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* One plain-language sentence summarizing the license, derived from the license
|
|
7
|
+
* traits. Deliberately omits attribution/credit wording (not the place for it).
|
|
8
|
+
* Returns null when there's no license data to summarize.
|
|
9
|
+
*
|
|
10
|
+
* Trait keys match the asset metadata: "Commercial Use", "Derivatives",
|
|
11
|
+
* "AI Policy", "Territory".
|
|
12
|
+
*/
|
|
13
|
+
declare function licenseSummary(attributes: Attr[]): string | null;
|
|
14
|
+
|
|
15
|
+
export { licenseSummary };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const get = (a, key) => a.find((x) => x.trait_type?.toLowerCase() === key)?.value;
|
|
2
|
+
function licenseSummary(attributes) {
|
|
3
|
+
const commercialRaw = get(attributes, "commercial use");
|
|
4
|
+
const derivatives = (get(attributes, "derivatives") ?? "").toLowerCase();
|
|
5
|
+
const ai = (get(attributes, "ai policy") ?? get(attributes, "ai & data mining") ?? "").toLowerCase();
|
|
6
|
+
const territory = get(attributes, "territory") ?? "";
|
|
7
|
+
if (!commercialRaw && !derivatives && !ai) return null;
|
|
8
|
+
const commercial = (commercialRaw ?? "").toLowerCase() === "yes";
|
|
9
|
+
const remix = derivatives === "not allowed" ? "No remixing" : commercial ? "Open to remix and commercial use" : "Open to remix";
|
|
10
|
+
const where = territory ? `, ${territory.toLowerCase()}` : "";
|
|
11
|
+
const aiClause = ai.includes("not") ? " \u2014 no AI training" : "";
|
|
12
|
+
return `${remix}${where}${aiClause}.`;
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
licenseSummary
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=license-summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/license-summary.ts"],"sourcesContent":["type Attr = { trait_type?: string; value?: string };\n\nconst get = (a: Attr[], key: string): string | undefined =>\n a.find((x) => x.trait_type?.toLowerCase() === key)?.value;\n\n/**\n * One plain-language sentence summarizing the license, derived from the license\n * traits. Deliberately omits attribution/credit wording (not the place for it).\n * Returns null when there's no license data to summarize.\n *\n * Trait keys match the asset metadata: \"Commercial Use\", \"Derivatives\",\n * \"AI Policy\", \"Territory\".\n */\nexport function licenseSummary(attributes: Attr[]): string | null {\n const commercialRaw = get(attributes, \"commercial use\");\n const derivatives = (get(attributes, \"derivatives\") ?? \"\").toLowerCase();\n const ai = (get(attributes, \"ai policy\") ?? get(attributes, \"ai & data mining\") ?? \"\").toLowerCase();\n const territory = get(attributes, \"territory\") ?? \"\";\n\n if (!commercialRaw && !derivatives && !ai) return null;\n\n const commercial = (commercialRaw ?? \"\").toLowerCase() === \"yes\";\n const remix =\n derivatives === \"not allowed\"\n ? \"No remixing\"\n : commercial\n ? \"Open to remix and commercial use\"\n : \"Open to remix\";\n const where = territory ? `, ${territory.toLowerCase()}` : \"\";\n const aiClause = ai.includes(\"not\") ? \" — no AI training\" : \"\";\n return `${remix}${where}${aiClause}.`;\n}\n"],"mappings":"AAEA,MAAM,MAAM,CAAC,GAAW,QACtB,EAAE,KAAK,CAAC,MAAM,EAAE,YAAY,YAAY,MAAM,GAAG,GAAG;AAU/C,SAAS,eAAe,YAAmC;AAChE,QAAM,gBAAgB,IAAI,YAAY,gBAAgB;AACtD,QAAM,eAAe,IAAI,YAAY,aAAa,KAAK,IAAI,YAAY;AACvE,QAAM,MAAM,IAAI,YAAY,WAAW,KAAK,IAAI,YAAY,kBAAkB,KAAK,IAAI,YAAY;AACnG,QAAM,YAAY,IAAI,YAAY,WAAW,KAAK;AAElD,MAAI,CAAC,iBAAiB,CAAC,eAAe,CAAC,GAAI,QAAO;AAElD,QAAM,cAAc,iBAAiB,IAAI,YAAY,MAAM;AAC3D,QAAM,QACJ,gBAAgB,gBACZ,gBACA,aACE,qCACA;AACR,QAAM,QAAQ,YAAY,KAAK,UAAU,YAAY,CAAC,KAAK;AAC3D,QAAM,WAAW,GAAG,SAAS,KAAK,IAAI,2BAAsB;AAC5D,SAAO,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ;AACpC;","names":[]}
|