@medialane/ui 0.78.0 → 0.78.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/license-terms-builder.cjs +38 -65
- package/dist/components/license-terms-builder.cjs.map +1 -1
- package/dist/components/license-terms-builder.d.cts +4 -0
- package/dist/components/license-terms-builder.d.ts +4 -0
- package/dist/components/license-terms-builder.js +39 -66
- package/dist/components/license-terms-builder.js.map +1 -1
- package/package.json +1 -1
|
@@ -26,7 +26,6 @@ __export(license_terms_builder_exports, {
|
|
|
26
26
|
});
|
|
27
27
|
module.exports = __toCommonJS(license_terms_builder_exports);
|
|
28
28
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
29
|
-
var import_react = require("react");
|
|
30
29
|
var import_lucide_react = require("lucide-react");
|
|
31
30
|
var import_cn = require("../utils/cn.js");
|
|
32
31
|
var import_currency_icon = require("./currency-icon.js");
|
|
@@ -44,9 +43,9 @@ const MEDIA_TYPES = [
|
|
|
44
43
|
const EMPTY_SPONSORSHIP_TERMS = {
|
|
45
44
|
amount: "",
|
|
46
45
|
paymentTokenSymbol: "",
|
|
47
|
-
durationDays: "
|
|
46
|
+
durationDays: "",
|
|
48
47
|
transferable: true,
|
|
49
|
-
royaltyPercent: "
|
|
48
|
+
royaltyPercent: "0",
|
|
50
49
|
licenseText: "",
|
|
51
50
|
licenseType: "CC BY-SA",
|
|
52
51
|
commercialUse: "Yes",
|
|
@@ -115,7 +114,6 @@ function LicenseTermsBuilder({
|
|
|
115
114
|
disabled,
|
|
116
115
|
className
|
|
117
116
|
}) {
|
|
118
|
-
const [panelOpen, setPanelOpen] = (0, import_react.useState)(false);
|
|
119
117
|
const set = (key, v) => onChange({ ...value, [key]: v });
|
|
120
118
|
const handleLicenseTypeChange = (licenseType) => {
|
|
121
119
|
const def = import_ip.LICENSE_TYPES.find((l) => l.value === licenseType);
|
|
@@ -131,61 +129,43 @@ function LicenseTermsBuilder({
|
|
|
131
129
|
set("media", next);
|
|
132
130
|
};
|
|
133
131
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: (0, import_cn.cn)("space-y-4", className), children: [
|
|
134
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid grid-cols-[1fr_auto] gap-2 items-end", children: [
|
|
135
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-1.5", children: [
|
|
136
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: FIELD_LABEL, children: amountLabel }),
|
|
137
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
138
|
-
"input",
|
|
139
|
-
{
|
|
140
|
-
type: "number",
|
|
141
|
-
min: 0,
|
|
142
|
-
step: "0.01",
|
|
143
|
-
inputMode: "decimal",
|
|
144
|
-
disabled,
|
|
145
|
-
value: value.amount,
|
|
146
|
-
onChange: (e) => set("amount", e.target.value),
|
|
147
|
-
placeholder: "0.00",
|
|
148
|
-
className: INPUT_BASE
|
|
149
|
-
}
|
|
150
|
-
)
|
|
151
|
-
] }),
|
|
152
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-1.5", children: [
|
|
153
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: FIELD_LABEL, children: "Currency" }),
|
|
154
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex gap-1 flex-wrap justify-end max-w-[220px]", children: tokenOptions.map((symbol) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
155
|
-
"button",
|
|
156
|
-
{
|
|
157
|
-
type: "button",
|
|
158
|
-
disabled,
|
|
159
|
-
onClick: () => set("paymentTokenSymbol", symbol),
|
|
160
|
-
className: (0, import_cn.cn)(
|
|
161
|
-
"h-10 px-2.5 rounded-xl border text-xs font-semibold flex items-center gap-1.5 transition-colors disabled:opacity-50",
|
|
162
|
-
value.paymentTokenSymbol === symbol ? "border-brand-purple bg-brand-purple/10 text-foreground" : "border-border bg-card text-muted-foreground hover:text-foreground"
|
|
163
|
-
),
|
|
164
|
-
children: [
|
|
165
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_currency_icon.CurrencyIcon, { symbol, size: 14 }),
|
|
166
|
-
symbol
|
|
167
|
-
]
|
|
168
|
-
},
|
|
169
|
-
symbol
|
|
170
|
-
)) })
|
|
171
|
-
] })
|
|
172
|
-
] }),
|
|
173
132
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-1.5", children: [
|
|
174
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: FIELD_LABEL, children:
|
|
133
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: FIELD_LABEL, children: amountLabel }),
|
|
175
134
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
176
135
|
"input",
|
|
177
136
|
{
|
|
178
137
|
type: "number",
|
|
179
138
|
min: 0,
|
|
180
|
-
|
|
181
|
-
|
|
139
|
+
step: "0.01",
|
|
140
|
+
inputMode: "decimal",
|
|
182
141
|
disabled,
|
|
183
|
-
value: value.
|
|
184
|
-
onChange: (e) => set("
|
|
142
|
+
value: value.amount,
|
|
143
|
+
onChange: (e) => set("amount", e.target.value),
|
|
144
|
+
placeholder: "0.00",
|
|
185
145
|
className: INPUT_BASE
|
|
186
146
|
}
|
|
187
|
-
)
|
|
188
|
-
|
|
147
|
+
)
|
|
148
|
+
] }),
|
|
149
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-1.5", children: [
|
|
150
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: FIELD_LABEL, children: "Currency" }),
|
|
151
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid grid-cols-3 sm:grid-cols-5 gap-1.5", children: tokenOptions.map((symbol) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
152
|
+
"button",
|
|
153
|
+
{
|
|
154
|
+
type: "button",
|
|
155
|
+
disabled,
|
|
156
|
+
onClick: () => set("paymentTokenSymbol", symbol),
|
|
157
|
+
"aria-pressed": value.paymentTokenSymbol === symbol,
|
|
158
|
+
className: (0, import_cn.cn)(
|
|
159
|
+
"h-10 px-2 rounded-xl border text-xs font-semibold flex items-center justify-center gap-1.5 transition-colors disabled:opacity-50",
|
|
160
|
+
value.paymentTokenSymbol === symbol ? "border-brand-purple bg-brand-purple/10 text-foreground" : "border-border bg-card text-muted-foreground hover:text-foreground"
|
|
161
|
+
),
|
|
162
|
+
children: [
|
|
163
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_currency_icon.CurrencyIcon, { symbol, size: 14 }),
|
|
164
|
+
symbol
|
|
165
|
+
]
|
|
166
|
+
},
|
|
167
|
+
symbol
|
|
168
|
+
)) })
|
|
189
169
|
] }),
|
|
190
170
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "flex items-start gap-2.5 cursor-pointer select-none", children: [
|
|
191
171
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -203,20 +183,12 @@ function LicenseTermsBuilder({
|
|
|
203
183
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: (0, import_cn.cn)(FIELD_HELP, "block"), children: "Off means it's meant to stay with the sponsor who accepts it \u2014 resale still isn't blocked on-chain, this is just the stated intent." })
|
|
204
184
|
] })
|
|
205
185
|
] }),
|
|
206
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "rounded-xl border border-border overflow-hidden", children: [
|
|
207
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
208
|
-
"
|
|
209
|
-
{
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
className: "w-full flex items-center justify-between px-4 py-3 text-sm font-semibold",
|
|
213
|
-
children: [
|
|
214
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "How long, where, and what for" }),
|
|
215
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ChevronDown, { className: (0, import_cn.cn)("h-4 w-4 transition-transform text-muted-foreground", panelOpen && "rotate-180") })
|
|
216
|
-
]
|
|
217
|
-
}
|
|
218
|
-
),
|
|
219
|
-
panelOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-4 pb-4 space-y-4 border-t border-border pt-4", children: [
|
|
186
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "rounded-xl border border-border overflow-hidden bg-card/40", children: [
|
|
187
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2.5 px-4 py-3 border-b border-border", children: [
|
|
188
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ScrollText, { className: "h-4 w-4 text-brand-purple shrink-0" }),
|
|
189
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-sm font-semibold", children: "How long, where, and what for" })
|
|
190
|
+
] }),
|
|
191
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-4 pb-4 space-y-4 pt-4", children: [
|
|
220
192
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-1.5", children: [
|
|
221
193
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: FIELD_LABEL, children: "License length (days)" }),
|
|
222
194
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -227,6 +199,7 @@ function LicenseTermsBuilder({
|
|
|
227
199
|
disabled,
|
|
228
200
|
value: value.durationDays,
|
|
229
201
|
onChange: (e) => set("durationDays", e.target.value),
|
|
202
|
+
placeholder: "e.g. 30",
|
|
230
203
|
className: INPUT_BASE
|
|
231
204
|
}
|
|
232
205
|
),
|
|
@@ -388,7 +361,7 @@ function LicenseTermsBuilder({
|
|
|
388
361
|
),
|
|
389
362
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: FIELD_HELP, children: "Saved permanently and shown to anyone who holds the license." })
|
|
390
363
|
] })
|
|
391
|
-
] })
|
|
364
|
+
] })
|
|
392
365
|
] })
|
|
393
366
|
] });
|
|
394
367
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/license-terms-builder.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { ChevronDown } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { LICENSE_TYPES, GEOGRAPHIC_SCOPES, AI_POLICIES } from \"../data/ip.js\";\n\n/** Common sponsorship media/channel types — deliberately not part of the\n * general IP taxonomy in `data/ip.ts` (that's about the asset itself;\n * this is about the sponsorship deal's channels), so it stays local here. */\nexport const MEDIA_TYPES = [\n \"Social Media\", \"Video\", \"Photo\", \"Article/Blog\", \"Print\", \"Broadcast\", \"Podcast/Audio\", \"Livestream\",\n] as const;\n\n/**\n * The deal terms a sponsorship offer/proposal needs, in plain-language shape\n * — no bps, no IPFS, no ByteArray. `royaltyPercent` is a plain 0–100 number\n * (multiply by 100 for the contract's basis-points argument). Every field\n * here is declarative metadata carried in the pinned IPFS document (see\n * `toLicenseMetadata`) — the contract never reads any of it, so none of it\n * is enforced beyond the atomic accept-and-mint payment itself. This\n * component only collects and validates the data, it never fetches or\n * uploads anything itself.\n */\nexport interface SponsorshipTerms {\n amount: string;\n paymentTokenSymbol: string;\n durationDays: string;\n transferable: boolean;\n royaltyPercent: string;\n /** Free-text notes that don't fit any structured field below. */\n licenseText: string;\n licenseType: string;\n commercialUse: \"Yes\" | \"No\";\n derivatives: \"Allowed\" | \"Not Allowed\" | \"Share-Alike\";\n attribution: \"Required\" | \"Not Required\";\n territory: string;\n aiPolicy: string;\n /** e.g. \"Instagram + YouTube only\" — too deal-specific to bound into an enum. */\n scope: string;\n /** e.g. \"3 posts, 1 video\" */\n deliverables: string;\n exclusive: boolean;\n approvalRequired: boolean;\n media: string[];\n mediaOther: string;\n}\n\nexport const EMPTY_SPONSORSHIP_TERMS: SponsorshipTerms = {\n amount: \"\",\n paymentTokenSymbol: \"\",\n durationDays: \"30\",\n transferable: true,\n royaltyPercent: \"5\",\n licenseText: \"\",\n licenseType: \"CC BY-SA\",\n commercialUse: \"Yes\",\n derivatives: \"Share-Alike\",\n attribution: \"Required\",\n territory: \"Worldwide\",\n aiPolicy: \"Allowed\",\n scope: \"\",\n deliverables: \"\",\n exclusive: false,\n approvalRequired: false,\n media: [],\n mediaOther: \"\",\n};\n\n/** Shapes the pinned-IPFS-JSON payload — the single place both apps build\n * this object, so it can't drift across call sites. Purely additive; the\n * contract never reads any of it. */\nexport function toLicenseMetadata(terms: SponsorshipTerms): Record<string, unknown> {\n return {\n terms: terms.licenseText,\n transferable: terms.transferable,\n royaltyPercent: Number(terms.royaltyPercent || \"0\"),\n licenseType: terms.licenseType,\n commercialUse: terms.commercialUse,\n derivatives: terms.derivatives,\n attribution: terms.attribution,\n territory: terms.territory,\n aiPolicy: terms.aiPolicy,\n scope: terms.scope,\n deliverables: terms.deliverables,\n exclusive: terms.exclusive,\n approvalRequired: terms.approvalRequired,\n media: terms.media,\n mediaOther: terms.mediaOther,\n };\n}\n\nexport interface LicenseTermsBuilderProps {\n value: SponsorshipTerms;\n onChange: (next: SponsorshipTerms) => void;\n /** Payment token symbols to offer — e.g. from SUPPORTED_TOKENS. */\n tokenOptions: string[];\n /** Copy override for the amount field — \"Minimum bid\" for an owner's\n * offer, \"Amount you'll pay\" for a sponsor's proposal. Default: \"Amount\". */\n amountLabel?: string;\n disabled?: boolean;\n className?: string;\n}\n\nconst FIELD_LABEL = \"text-xs font-semibold text-foreground\";\nconst FIELD_HELP = \"text-xs text-muted-foreground\";\nconst INPUT_BASE =\n \"w-full h-10 rounded-xl border border-border bg-card px-3 text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-brand-purple/40 focus:border-brand-purple/40 disabled:opacity-50\";\n\nfunction ToggleGroup({ value, options, onChange, disabled }: { value: string; options: readonly string[]; onChange: (v: string) => void; disabled?: boolean }) {\n return (\n <div className=\"flex rounded-lg border border-border overflow-hidden w-full\">\n {options.map((opt, i) => (\n <button\n key={opt}\n type=\"button\"\n disabled={disabled}\n onClick={() => onChange(opt)}\n className={cn(\n \"flex-1 px-3 py-2 text-xs sm:text-sm transition-colors disabled:opacity-50\",\n i > 0 && \"border-l border-border\",\n value === opt\n ? \"bg-primary text-primary-foreground font-medium\"\n : \"bg-background hover:bg-muted text-muted-foreground\",\n )}\n >\n {opt}\n </button>\n ))}\n </div>\n );\n}\n\nfunction YesNoToggle({ label, help, checked, onChange, disabled }: { label: string; help: string; checked: boolean; onChange: (v: boolean) => void; disabled?: boolean }) {\n return (\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>{label}</label>\n <ToggleGroup value={checked ? \"Yes\" : \"No\"} options={[\"Yes\", \"No\"]} onChange={(v) => onChange(v === \"Yes\")} disabled={disabled} />\n <p className={FIELD_HELP}>{help}</p>\n </div>\n );\n}\n\nexport function LicenseTermsBuilder({\n value, onChange, tokenOptions, amountLabel = \"Amount\", disabled, className,\n}: LicenseTermsBuilderProps) {\n const [panelOpen, setPanelOpen] = useState(false);\n const set = <K extends keyof SponsorshipTerms>(key: K, v: SponsorshipTerms[K]) =>\n onChange({ ...value, [key]: v });\n\n const handleLicenseTypeChange = (licenseType: string) => {\n const def = LICENSE_TYPES.find((l) => l.value === licenseType);\n onChange({\n ...value,\n licenseType,\n ...(def ? { commercialUse: def.commercialUse, derivatives: def.derivatives, attribution: def.attribution } : {}),\n });\n };\n\n const selectedLicense = LICENSE_TYPES.find((l) => l.value === value.licenseType);\n const toggleMedia = (m: string) => {\n const next = value.media.includes(m) ? value.media.filter((x) => x !== m) : [...value.media, m];\n set(\"media\", next);\n };\n\n return (\n <div className={cn(\"space-y-4\", className)}>\n <div className=\"grid grid-cols-[1fr_auto] gap-2 items-end\">\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>{amountLabel}</label>\n <input\n type=\"number\"\n min={0}\n step=\"0.01\"\n inputMode=\"decimal\"\n disabled={disabled}\n value={value.amount}\n onChange={(e) => set(\"amount\", e.target.value)}\n placeholder=\"0.00\"\n className={INPUT_BASE}\n />\n </div>\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Currency</label>\n <div className=\"flex gap-1 flex-wrap justify-end max-w-[220px]\">\n {tokenOptions.map((symbol) => (\n <button\n key={symbol}\n type=\"button\"\n disabled={disabled}\n onClick={() => set(\"paymentTokenSymbol\", symbol)}\n className={cn(\n \"h-10 px-2.5 rounded-xl border text-xs font-semibold flex items-center gap-1.5 transition-colors disabled:opacity-50\",\n value.paymentTokenSymbol === symbol\n ? \"border-brand-purple bg-brand-purple/10 text-foreground\"\n : \"border-border bg-card text-muted-foreground hover:text-foreground\",\n )}\n >\n <CurrencyIcon symbol={symbol} size={14} />\n {symbol}\n </button>\n ))}\n </div>\n </div>\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Resale royalty (%)</label>\n <input\n type=\"number\"\n min={0}\n max={100}\n step=\"0.1\"\n disabled={disabled}\n value={value.royaltyPercent}\n onChange={(e) => set(\"royaltyPercent\", e.target.value)}\n className={INPUT_BASE}\n />\n <p className={FIELD_HELP}>You get this share automatically if the license is ever resold.</p>\n </div>\n\n <label className=\"flex items-start gap-2.5 cursor-pointer select-none\">\n <input\n type=\"checkbox\"\n disabled={disabled}\n checked={value.transferable}\n onChange={(e) => set(\"transferable\", e.target.checked)}\n className=\"mt-0.5 h-4 w-4 rounded border-border text-brand-purple focus:ring-brand-purple/40\"\n />\n <span className=\"text-sm\">\n <span className=\"font-medium\">Sponsor can resell this license</span>\n <span className={cn(FIELD_HELP, \"block\")}>Off means it's meant to stay with the sponsor who accepts it — resale still isn't blocked on-chain, this is just the stated intent.</span>\n </span>\n </label>\n\n <div className=\"rounded-xl border border-border overflow-hidden\">\n <button\n type=\"button\"\n onClick={() => setPanelOpen((o) => !o)}\n className=\"w-full flex items-center justify-between px-4 py-3 text-sm font-semibold\"\n >\n <span>How long, where, and what for</span>\n <ChevronDown className={cn(\"h-4 w-4 transition-transform text-muted-foreground\", panelOpen && \"rotate-180\")} />\n </button>\n\n {panelOpen ? (\n <div className=\"px-4 pb-4 space-y-4 border-t border-border pt-4\">\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>License length (days)</label>\n <input\n type=\"number\"\n min={1}\n disabled={disabled}\n value={value.durationDays}\n onChange={(e) => set(\"durationDays\", e.target.value)}\n className={INPUT_BASE}\n />\n <p className={FIELD_HELP}>Counted from the moment the deal is accepted, not from today.</p>\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>License type</label>\n <select\n disabled={disabled}\n value={value.licenseType}\n onChange={(e) => handleLicenseTypeChange(e.target.value)}\n className={INPUT_BASE}\n >\n {LICENSE_TYPES.map((l) => (\n <option key={l.value} value={l.value}>{l.label}</option>\n ))}\n </select>\n {selectedLicense ? <p className={FIELD_HELP}>{selectedLicense.description}</p> : null}\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Commercial use</label>\n <ToggleGroup value={value.commercialUse} options={[\"Yes\", \"No\"]} onChange={(v) => set(\"commercialUse\", v as SponsorshipTerms[\"commercialUse\"])} disabled={disabled} />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Derivatives</label>\n <ToggleGroup value={value.derivatives} options={[\"Allowed\", \"Not Allowed\", \"Share-Alike\"]} onChange={(v) => set(\"derivatives\", v as SponsorshipTerms[\"derivatives\"])} disabled={disabled} />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Attribution</label>\n <ToggleGroup value={value.attribution} options={[\"Required\", \"Not Required\"]} onChange={(v) => set(\"attribution\", v as SponsorshipTerms[\"attribution\"])} disabled={disabled} />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Territory</label>\n <select\n disabled={disabled}\n value={value.territory}\n onChange={(e) => set(\"territory\", e.target.value)}\n className={INPUT_BASE}\n >\n {GEOGRAPHIC_SCOPES.map((t) => (\n <option key={t} value={t}>{t}</option>\n ))}\n </select>\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>AI policy</label>\n <select\n disabled={disabled}\n value={value.aiPolicy}\n onChange={(e) => set(\"aiPolicy\", e.target.value)}\n className={INPUT_BASE}\n >\n {AI_POLICIES.map((p) => (\n <option key={p} value={p}>{p}</option>\n ))}\n </select>\n <p className={FIELD_HELP}>Whether this work can be used to train AI models.</p>\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Scope <span className=\"font-normal text-muted-foreground\">(optional)</span></label>\n <input\n type=\"text\"\n disabled={disabled}\n value={value.scope}\n onChange={(e) => set(\"scope\", e.target.value)}\n placeholder=\"e.g. Instagram + YouTube only\"\n className={INPUT_BASE}\n />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Deliverables <span className=\"font-normal text-muted-foreground\">(optional)</span></label>\n <textarea\n disabled={disabled}\n value={value.deliverables}\n onChange={(e) => set(\"deliverables\", e.target.value)}\n placeholder=\"e.g. 3 posts, 1 video\"\n rows={2}\n className={cn(INPUT_BASE, \"h-auto py-2.5 resize-y\")}\n />\n </div>\n\n <YesNoToggle\n label=\"Exclusive to this sponsor\"\n help=\"No other sponsors during the license term.\"\n checked={value.exclusive}\n onChange={(v) => set(\"exclusive\", v)}\n disabled={disabled}\n />\n\n <YesNoToggle\n label=\"Content approval required\"\n help=\"Sponsor reviews content before it's published.\"\n checked={value.approvalRequired}\n onChange={(v) => set(\"approvalRequired\", v)}\n disabled={disabled}\n />\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Media <span className=\"font-normal text-muted-foreground\">(optional)</span></label>\n <div className=\"flex flex-wrap gap-1.5\">\n {MEDIA_TYPES.map((m) => (\n <button\n key={m}\n type=\"button\"\n disabled={disabled}\n onClick={() => toggleMedia(m)}\n className={cn(\n \"h-8 px-2.5 rounded-full border text-xs font-medium transition-colors disabled:opacity-50\",\n value.media.includes(m)\n ? \"border-brand-purple bg-brand-purple/10 text-foreground\"\n : \"border-border bg-card text-muted-foreground hover:text-foreground\",\n )}\n >\n {m}\n </button>\n ))}\n </div>\n <input\n type=\"text\"\n disabled={disabled}\n value={value.mediaOther}\n onChange={(e) => set(\"mediaOther\", e.target.value)}\n placeholder=\"Other media type\"\n className={cn(INPUT_BASE, \"mt-1.5\")}\n />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Additional terms <span className=\"font-normal text-muted-foreground\">(optional)</span></label>\n <textarea\n disabled={disabled}\n value={value.licenseText}\n onChange={(e) => set(\"licenseText\", e.target.value)}\n placeholder=\"Anything else worth spelling out.\"\n rows={3}\n className={cn(INPUT_BASE, \"h-auto py-2.5 resize-y\")}\n />\n <p className={FIELD_HELP}>Saved permanently and shown to anyone who holds the license.</p>\n </div>\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/license-terms-builder.tsx"],"sourcesContent":["\"use client\";\n\nimport { ScrollText } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { LICENSE_TYPES, GEOGRAPHIC_SCOPES, AI_POLICIES } from \"../data/ip.js\";\n\n/** Common sponsorship media/channel types — deliberately not part of the\n * general IP taxonomy in `data/ip.ts` (that's about the asset itself;\n * this is about the sponsorship deal's channels), so it stays local here. */\nexport const MEDIA_TYPES = [\n \"Social Media\", \"Video\", \"Photo\", \"Article/Blog\", \"Print\", \"Broadcast\", \"Podcast/Audio\", \"Livestream\",\n] as const;\n\n/**\n * The deal terms a sponsorship offer/proposal needs, in plain-language shape\n * — no bps, no IPFS, no ByteArray. `royaltyPercent` is a plain 0–100 number\n * (multiply by 100 for the contract's basis-points argument). Every field\n * here is declarative metadata carried in the pinned IPFS document (see\n * `toLicenseMetadata`) — the contract never reads any of it, so none of it\n * is enforced beyond the atomic accept-and-mint payment itself. This\n * component only collects and validates the data, it never fetches or\n * uploads anything itself.\n */\nexport interface SponsorshipTerms {\n amount: string;\n paymentTokenSymbol: string;\n /** No default — the user must explicitly set this, never silently inherit one. */\n durationDays: string;\n transferable: boolean;\n /** Not surfaced in the UI (no resale-royalty concept here) — always \"0\". Kept\n * on the type because `create_offer`/`propose_sponsorship` still take a\n * `royaltyBps` argument. */\n royaltyPercent: string;\n /** Free-text notes that don't fit any structured field below. */\n licenseText: string;\n licenseType: string;\n commercialUse: \"Yes\" | \"No\";\n derivatives: \"Allowed\" | \"Not Allowed\" | \"Share-Alike\";\n attribution: \"Required\" | \"Not Required\";\n territory: string;\n aiPolicy: string;\n /** e.g. \"Instagram + YouTube only\" — too deal-specific to bound into an enum. */\n scope: string;\n /** e.g. \"3 posts, 1 video\" */\n deliverables: string;\n exclusive: boolean;\n approvalRequired: boolean;\n media: string[];\n mediaOther: string;\n}\n\nexport const EMPTY_SPONSORSHIP_TERMS: SponsorshipTerms = {\n amount: \"\",\n paymentTokenSymbol: \"\",\n durationDays: \"\",\n transferable: true,\n royaltyPercent: \"0\",\n licenseText: \"\",\n licenseType: \"CC BY-SA\",\n commercialUse: \"Yes\",\n derivatives: \"Share-Alike\",\n attribution: \"Required\",\n territory: \"Worldwide\",\n aiPolicy: \"Allowed\",\n scope: \"\",\n deliverables: \"\",\n exclusive: false,\n approvalRequired: false,\n media: [],\n mediaOther: \"\",\n};\n\n/** Shapes the pinned-IPFS-JSON payload — the single place both apps build\n * this object, so it can't drift across call sites. Purely additive; the\n * contract never reads any of it. */\nexport function toLicenseMetadata(terms: SponsorshipTerms): Record<string, unknown> {\n return {\n terms: terms.licenseText,\n transferable: terms.transferable,\n royaltyPercent: Number(terms.royaltyPercent || \"0\"),\n licenseType: terms.licenseType,\n commercialUse: terms.commercialUse,\n derivatives: terms.derivatives,\n attribution: terms.attribution,\n territory: terms.territory,\n aiPolicy: terms.aiPolicy,\n scope: terms.scope,\n deliverables: terms.deliverables,\n exclusive: terms.exclusive,\n approvalRequired: terms.approvalRequired,\n media: terms.media,\n mediaOther: terms.mediaOther,\n };\n}\n\nexport interface LicenseTermsBuilderProps {\n value: SponsorshipTerms;\n onChange: (next: SponsorshipTerms) => void;\n /** Payment token symbols to offer — e.g. from SUPPORTED_TOKENS. */\n tokenOptions: string[];\n /** Copy override for the amount field — \"Minimum bid\" for an owner's\n * offer, \"Amount you'll pay\" for a sponsor's proposal. Default: \"Amount\". */\n amountLabel?: string;\n disabled?: boolean;\n className?: string;\n}\n\nconst FIELD_LABEL = \"text-xs font-semibold text-foreground\";\nconst FIELD_HELP = \"text-xs text-muted-foreground\";\nconst INPUT_BASE =\n \"w-full h-10 rounded-xl border border-border bg-card px-3 text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-brand-purple/40 focus:border-brand-purple/40 disabled:opacity-50\";\n\nfunction ToggleGroup({ value, options, onChange, disabled }: { value: string; options: readonly string[]; onChange: (v: string) => void; disabled?: boolean }) {\n return (\n <div className=\"flex rounded-lg border border-border overflow-hidden w-full\">\n {options.map((opt, i) => (\n <button\n key={opt}\n type=\"button\"\n disabled={disabled}\n onClick={() => onChange(opt)}\n className={cn(\n \"flex-1 px-3 py-2 text-xs sm:text-sm transition-colors disabled:opacity-50\",\n i > 0 && \"border-l border-border\",\n value === opt\n ? \"bg-primary text-primary-foreground font-medium\"\n : \"bg-background hover:bg-muted text-muted-foreground\",\n )}\n >\n {opt}\n </button>\n ))}\n </div>\n );\n}\n\nfunction YesNoToggle({ label, help, checked, onChange, disabled }: { label: string; help: string; checked: boolean; onChange: (v: boolean) => void; disabled?: boolean }) {\n return (\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>{label}</label>\n <ToggleGroup value={checked ? \"Yes\" : \"No\"} options={[\"Yes\", \"No\"]} onChange={(v) => onChange(v === \"Yes\")} disabled={disabled} />\n <p className={FIELD_HELP}>{help}</p>\n </div>\n );\n}\n\nexport function LicenseTermsBuilder({\n value, onChange, tokenOptions, amountLabel = \"Amount\", disabled, className,\n}: LicenseTermsBuilderProps) {\n const set = <K extends keyof SponsorshipTerms>(key: K, v: SponsorshipTerms[K]) =>\n onChange({ ...value, [key]: v });\n\n const handleLicenseTypeChange = (licenseType: string) => {\n const def = LICENSE_TYPES.find((l) => l.value === licenseType);\n onChange({\n ...value,\n licenseType,\n ...(def ? { commercialUse: def.commercialUse, derivatives: def.derivatives, attribution: def.attribution } : {}),\n });\n };\n\n const selectedLicense = LICENSE_TYPES.find((l) => l.value === value.licenseType);\n const toggleMedia = (m: string) => {\n const next = value.media.includes(m) ? value.media.filter((x) => x !== m) : [...value.media, m];\n set(\"media\", next);\n };\n\n return (\n <div className={cn(\"space-y-4\", className)}>\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>{amountLabel}</label>\n <input\n type=\"number\"\n min={0}\n step=\"0.01\"\n inputMode=\"decimal\"\n disabled={disabled}\n value={value.amount}\n onChange={(e) => set(\"amount\", e.target.value)}\n placeholder=\"0.00\"\n className={INPUT_BASE}\n />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Currency</label>\n <div className=\"grid grid-cols-3 sm:grid-cols-5 gap-1.5\">\n {tokenOptions.map((symbol) => (\n <button\n key={symbol}\n type=\"button\"\n disabled={disabled}\n onClick={() => set(\"paymentTokenSymbol\", symbol)}\n aria-pressed={value.paymentTokenSymbol === symbol}\n className={cn(\n \"h-10 px-2 rounded-xl border text-xs font-semibold flex items-center justify-center gap-1.5 transition-colors disabled:opacity-50\",\n value.paymentTokenSymbol === symbol\n ? \"border-brand-purple bg-brand-purple/10 text-foreground\"\n : \"border-border bg-card text-muted-foreground hover:text-foreground\",\n )}\n >\n <CurrencyIcon symbol={symbol} size={14} />\n {symbol}\n </button>\n ))}\n </div>\n </div>\n\n <label className=\"flex items-start gap-2.5 cursor-pointer select-none\">\n <input\n type=\"checkbox\"\n disabled={disabled}\n checked={value.transferable}\n onChange={(e) => set(\"transferable\", e.target.checked)}\n className=\"mt-0.5 h-4 w-4 rounded border-border text-brand-purple focus:ring-brand-purple/40\"\n />\n <span className=\"text-sm\">\n <span className=\"font-medium\">Sponsor can resell this license</span>\n <span className={cn(FIELD_HELP, \"block\")}>Off means it's meant to stay with the sponsor who accepts it — resale still isn't blocked on-chain, this is just the stated intent.</span>\n </span>\n </label>\n\n <div className=\"rounded-xl border border-border overflow-hidden bg-card/40\">\n <div className=\"flex items-center gap-2.5 px-4 py-3 border-b border-border\">\n <ScrollText className=\"h-4 w-4 text-brand-purple shrink-0\" />\n <span className=\"text-sm font-semibold\">How long, where, and what for</span>\n </div>\n\n <div className=\"px-4 pb-4 space-y-4 pt-4\">\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>License length (days)</label>\n <input\n type=\"number\"\n min={1}\n disabled={disabled}\n value={value.durationDays}\n onChange={(e) => set(\"durationDays\", e.target.value)}\n placeholder=\"e.g. 30\"\n className={INPUT_BASE}\n />\n <p className={FIELD_HELP}>Counted from the moment the deal is accepted, not from today.</p>\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>License type</label>\n <select\n disabled={disabled}\n value={value.licenseType}\n onChange={(e) => handleLicenseTypeChange(e.target.value)}\n className={INPUT_BASE}\n >\n {LICENSE_TYPES.map((l) => (\n <option key={l.value} value={l.value}>{l.label}</option>\n ))}\n </select>\n {selectedLicense ? <p className={FIELD_HELP}>{selectedLicense.description}</p> : null}\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Commercial use</label>\n <ToggleGroup value={value.commercialUse} options={[\"Yes\", \"No\"]} onChange={(v) => set(\"commercialUse\", v as SponsorshipTerms[\"commercialUse\"])} disabled={disabled} />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Derivatives</label>\n <ToggleGroup value={value.derivatives} options={[\"Allowed\", \"Not Allowed\", \"Share-Alike\"]} onChange={(v) => set(\"derivatives\", v as SponsorshipTerms[\"derivatives\"])} disabled={disabled} />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Attribution</label>\n <ToggleGroup value={value.attribution} options={[\"Required\", \"Not Required\"]} onChange={(v) => set(\"attribution\", v as SponsorshipTerms[\"attribution\"])} disabled={disabled} />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Territory</label>\n <select\n disabled={disabled}\n value={value.territory}\n onChange={(e) => set(\"territory\", e.target.value)}\n className={INPUT_BASE}\n >\n {GEOGRAPHIC_SCOPES.map((t) => (\n <option key={t} value={t}>{t}</option>\n ))}\n </select>\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>AI policy</label>\n <select\n disabled={disabled}\n value={value.aiPolicy}\n onChange={(e) => set(\"aiPolicy\", e.target.value)}\n className={INPUT_BASE}\n >\n {AI_POLICIES.map((p) => (\n <option key={p} value={p}>{p}</option>\n ))}\n </select>\n <p className={FIELD_HELP}>Whether this work can be used to train AI models.</p>\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Scope <span className=\"font-normal text-muted-foreground\">(optional)</span></label>\n <input\n type=\"text\"\n disabled={disabled}\n value={value.scope}\n onChange={(e) => set(\"scope\", e.target.value)}\n placeholder=\"e.g. Instagram + YouTube only\"\n className={INPUT_BASE}\n />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Deliverables <span className=\"font-normal text-muted-foreground\">(optional)</span></label>\n <textarea\n disabled={disabled}\n value={value.deliverables}\n onChange={(e) => set(\"deliverables\", e.target.value)}\n placeholder=\"e.g. 3 posts, 1 video\"\n rows={2}\n className={cn(INPUT_BASE, \"h-auto py-2.5 resize-y\")}\n />\n </div>\n\n <YesNoToggle\n label=\"Exclusive to this sponsor\"\n help=\"No other sponsors during the license term.\"\n checked={value.exclusive}\n onChange={(v) => set(\"exclusive\", v)}\n disabled={disabled}\n />\n\n <YesNoToggle\n label=\"Content approval required\"\n help=\"Sponsor reviews content before it's published.\"\n checked={value.approvalRequired}\n onChange={(v) => set(\"approvalRequired\", v)}\n disabled={disabled}\n />\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Media <span className=\"font-normal text-muted-foreground\">(optional)</span></label>\n <div className=\"flex flex-wrap gap-1.5\">\n {MEDIA_TYPES.map((m) => (\n <button\n key={m}\n type=\"button\"\n disabled={disabled}\n onClick={() => toggleMedia(m)}\n className={cn(\n \"h-8 px-2.5 rounded-full border text-xs font-medium transition-colors disabled:opacity-50\",\n value.media.includes(m)\n ? \"border-brand-purple bg-brand-purple/10 text-foreground\"\n : \"border-border bg-card text-muted-foreground hover:text-foreground\",\n )}\n >\n {m}\n </button>\n ))}\n </div>\n <input\n type=\"text\"\n disabled={disabled}\n value={value.mediaOther}\n onChange={(e) => set(\"mediaOther\", e.target.value)}\n placeholder=\"Other media type\"\n className={cn(INPUT_BASE, \"mt-1.5\")}\n />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Additional terms <span className=\"font-normal text-muted-foreground\">(optional)</span></label>\n <textarea\n disabled={disabled}\n value={value.licenseText}\n onChange={(e) => set(\"licenseText\", e.target.value)}\n placeholder=\"Anything else worth spelling out.\"\n rows={3}\n className={cn(INPUT_BASE, \"h-auto py-2.5 resize-y\")}\n />\n <p className={FIELD_HELP}>Saved permanently and shown to anyone who holds the license.</p>\n </div>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -17,8 +17,12 @@ declare const MEDIA_TYPES: readonly ["Social Media", "Video", "Photo", "Article/
|
|
|
17
17
|
interface SponsorshipTerms {
|
|
18
18
|
amount: string;
|
|
19
19
|
paymentTokenSymbol: string;
|
|
20
|
+
/** No default — the user must explicitly set this, never silently inherit one. */
|
|
20
21
|
durationDays: string;
|
|
21
22
|
transferable: boolean;
|
|
23
|
+
/** Not surfaced in the UI (no resale-royalty concept here) — always "0". Kept
|
|
24
|
+
* on the type because `create_offer`/`propose_sponsorship` still take a
|
|
25
|
+
* `royaltyBps` argument. */
|
|
22
26
|
royaltyPercent: string;
|
|
23
27
|
/** Free-text notes that don't fit any structured field below. */
|
|
24
28
|
licenseText: string;
|
|
@@ -17,8 +17,12 @@ declare const MEDIA_TYPES: readonly ["Social Media", "Video", "Photo", "Article/
|
|
|
17
17
|
interface SponsorshipTerms {
|
|
18
18
|
amount: string;
|
|
19
19
|
paymentTokenSymbol: string;
|
|
20
|
+
/** No default — the user must explicitly set this, never silently inherit one. */
|
|
20
21
|
durationDays: string;
|
|
21
22
|
transferable: boolean;
|
|
23
|
+
/** Not surfaced in the UI (no resale-royalty concept here) — always "0". Kept
|
|
24
|
+
* on the type because `create_offer`/`propose_sponsorship` still take a
|
|
25
|
+
* `royaltyBps` argument. */
|
|
22
26
|
royaltyPercent: string;
|
|
23
27
|
/** Free-text notes that don't fit any structured field below. */
|
|
24
28
|
licenseText: string;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
4
|
-
import { ChevronDown } from "lucide-react";
|
|
3
|
+
import { ScrollText } from "lucide-react";
|
|
5
4
|
import { cn } from "../utils/cn.js";
|
|
6
5
|
import { CurrencyIcon } from "./currency-icon.js";
|
|
7
6
|
import { LICENSE_TYPES, GEOGRAPHIC_SCOPES, AI_POLICIES } from "../data/ip.js";
|
|
@@ -18,9 +17,9 @@ const MEDIA_TYPES = [
|
|
|
18
17
|
const EMPTY_SPONSORSHIP_TERMS = {
|
|
19
18
|
amount: "",
|
|
20
19
|
paymentTokenSymbol: "",
|
|
21
|
-
durationDays: "
|
|
20
|
+
durationDays: "",
|
|
22
21
|
transferable: true,
|
|
23
|
-
royaltyPercent: "
|
|
22
|
+
royaltyPercent: "0",
|
|
24
23
|
licenseText: "",
|
|
25
24
|
licenseType: "CC BY-SA",
|
|
26
25
|
commercialUse: "Yes",
|
|
@@ -89,7 +88,6 @@ function LicenseTermsBuilder({
|
|
|
89
88
|
disabled,
|
|
90
89
|
className
|
|
91
90
|
}) {
|
|
92
|
-
const [panelOpen, setPanelOpen] = useState(false);
|
|
93
91
|
const set = (key, v) => onChange({ ...value, [key]: v });
|
|
94
92
|
const handleLicenseTypeChange = (licenseType) => {
|
|
95
93
|
const def = LICENSE_TYPES.find((l) => l.value === licenseType);
|
|
@@ -105,61 +103,43 @@ function LicenseTermsBuilder({
|
|
|
105
103
|
set("media", next);
|
|
106
104
|
};
|
|
107
105
|
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-4", className), children: [
|
|
108
|
-
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_auto] gap-2 items-end", children: [
|
|
109
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
110
|
-
/* @__PURE__ */ jsx("label", { className: FIELD_LABEL, children: amountLabel }),
|
|
111
|
-
/* @__PURE__ */ jsx(
|
|
112
|
-
"input",
|
|
113
|
-
{
|
|
114
|
-
type: "number",
|
|
115
|
-
min: 0,
|
|
116
|
-
step: "0.01",
|
|
117
|
-
inputMode: "decimal",
|
|
118
|
-
disabled,
|
|
119
|
-
value: value.amount,
|
|
120
|
-
onChange: (e) => set("amount", e.target.value),
|
|
121
|
-
placeholder: "0.00",
|
|
122
|
-
className: INPUT_BASE
|
|
123
|
-
}
|
|
124
|
-
)
|
|
125
|
-
] }),
|
|
126
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
127
|
-
/* @__PURE__ */ jsx("label", { className: FIELD_LABEL, children: "Currency" }),
|
|
128
|
-
/* @__PURE__ */ jsx("div", { className: "flex gap-1 flex-wrap justify-end max-w-[220px]", children: tokenOptions.map((symbol) => /* @__PURE__ */ jsxs(
|
|
129
|
-
"button",
|
|
130
|
-
{
|
|
131
|
-
type: "button",
|
|
132
|
-
disabled,
|
|
133
|
-
onClick: () => set("paymentTokenSymbol", symbol),
|
|
134
|
-
className: cn(
|
|
135
|
-
"h-10 px-2.5 rounded-xl border text-xs font-semibold flex items-center gap-1.5 transition-colors disabled:opacity-50",
|
|
136
|
-
value.paymentTokenSymbol === symbol ? "border-brand-purple bg-brand-purple/10 text-foreground" : "border-border bg-card text-muted-foreground hover:text-foreground"
|
|
137
|
-
),
|
|
138
|
-
children: [
|
|
139
|
-
/* @__PURE__ */ jsx(CurrencyIcon, { symbol, size: 14 }),
|
|
140
|
-
symbol
|
|
141
|
-
]
|
|
142
|
-
},
|
|
143
|
-
symbol
|
|
144
|
-
)) })
|
|
145
|
-
] })
|
|
146
|
-
] }),
|
|
147
106
|
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
148
|
-
/* @__PURE__ */ jsx("label", { className: FIELD_LABEL, children:
|
|
107
|
+
/* @__PURE__ */ jsx("label", { className: FIELD_LABEL, children: amountLabel }),
|
|
149
108
|
/* @__PURE__ */ jsx(
|
|
150
109
|
"input",
|
|
151
110
|
{
|
|
152
111
|
type: "number",
|
|
153
112
|
min: 0,
|
|
154
|
-
|
|
155
|
-
|
|
113
|
+
step: "0.01",
|
|
114
|
+
inputMode: "decimal",
|
|
156
115
|
disabled,
|
|
157
|
-
value: value.
|
|
158
|
-
onChange: (e) => set("
|
|
116
|
+
value: value.amount,
|
|
117
|
+
onChange: (e) => set("amount", e.target.value),
|
|
118
|
+
placeholder: "0.00",
|
|
159
119
|
className: INPUT_BASE
|
|
160
120
|
}
|
|
161
|
-
)
|
|
162
|
-
|
|
121
|
+
)
|
|
122
|
+
] }),
|
|
123
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
124
|
+
/* @__PURE__ */ jsx("label", { className: FIELD_LABEL, children: "Currency" }),
|
|
125
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-3 sm:grid-cols-5 gap-1.5", children: tokenOptions.map((symbol) => /* @__PURE__ */ jsxs(
|
|
126
|
+
"button",
|
|
127
|
+
{
|
|
128
|
+
type: "button",
|
|
129
|
+
disabled,
|
|
130
|
+
onClick: () => set("paymentTokenSymbol", symbol),
|
|
131
|
+
"aria-pressed": value.paymentTokenSymbol === symbol,
|
|
132
|
+
className: cn(
|
|
133
|
+
"h-10 px-2 rounded-xl border text-xs font-semibold flex items-center justify-center gap-1.5 transition-colors disabled:opacity-50",
|
|
134
|
+
value.paymentTokenSymbol === symbol ? "border-brand-purple bg-brand-purple/10 text-foreground" : "border-border bg-card text-muted-foreground hover:text-foreground"
|
|
135
|
+
),
|
|
136
|
+
children: [
|
|
137
|
+
/* @__PURE__ */ jsx(CurrencyIcon, { symbol, size: 14 }),
|
|
138
|
+
symbol
|
|
139
|
+
]
|
|
140
|
+
},
|
|
141
|
+
symbol
|
|
142
|
+
)) })
|
|
163
143
|
] }),
|
|
164
144
|
/* @__PURE__ */ jsxs("label", { className: "flex items-start gap-2.5 cursor-pointer select-none", children: [
|
|
165
145
|
/* @__PURE__ */ jsx(
|
|
@@ -177,20 +157,12 @@ function LicenseTermsBuilder({
|
|
|
177
157
|
/* @__PURE__ */ jsx("span", { className: cn(FIELD_HELP, "block"), children: "Off means it's meant to stay with the sponsor who accepts it \u2014 resale still isn't blocked on-chain, this is just the stated intent." })
|
|
178
158
|
] })
|
|
179
159
|
] }),
|
|
180
|
-
/* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-border overflow-hidden", children: [
|
|
181
|
-
/* @__PURE__ */ jsxs(
|
|
182
|
-
"
|
|
183
|
-
{
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
className: "w-full flex items-center justify-between px-4 py-3 text-sm font-semibold",
|
|
187
|
-
children: [
|
|
188
|
-
/* @__PURE__ */ jsx("span", { children: "How long, where, and what for" }),
|
|
189
|
-
/* @__PURE__ */ jsx(ChevronDown, { className: cn("h-4 w-4 transition-transform text-muted-foreground", panelOpen && "rotate-180") })
|
|
190
|
-
]
|
|
191
|
-
}
|
|
192
|
-
),
|
|
193
|
-
panelOpen ? /* @__PURE__ */ jsxs("div", { className: "px-4 pb-4 space-y-4 border-t border-border pt-4", children: [
|
|
160
|
+
/* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-border overflow-hidden bg-card/40", children: [
|
|
161
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 px-4 py-3 border-b border-border", children: [
|
|
162
|
+
/* @__PURE__ */ jsx(ScrollText, { className: "h-4 w-4 text-brand-purple shrink-0" }),
|
|
163
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: "How long, where, and what for" })
|
|
164
|
+
] }),
|
|
165
|
+
/* @__PURE__ */ jsxs("div", { className: "px-4 pb-4 space-y-4 pt-4", children: [
|
|
194
166
|
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
195
167
|
/* @__PURE__ */ jsx("label", { className: FIELD_LABEL, children: "License length (days)" }),
|
|
196
168
|
/* @__PURE__ */ jsx(
|
|
@@ -201,6 +173,7 @@ function LicenseTermsBuilder({
|
|
|
201
173
|
disabled,
|
|
202
174
|
value: value.durationDays,
|
|
203
175
|
onChange: (e) => set("durationDays", e.target.value),
|
|
176
|
+
placeholder: "e.g. 30",
|
|
204
177
|
className: INPUT_BASE
|
|
205
178
|
}
|
|
206
179
|
),
|
|
@@ -362,7 +335,7 @@ function LicenseTermsBuilder({
|
|
|
362
335
|
),
|
|
363
336
|
/* @__PURE__ */ jsx("p", { className: FIELD_HELP, children: "Saved permanently and shown to anyone who holds the license." })
|
|
364
337
|
] })
|
|
365
|
-
] })
|
|
338
|
+
] })
|
|
366
339
|
] })
|
|
367
340
|
] });
|
|
368
341
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/license-terms-builder.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { ChevronDown } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { LICENSE_TYPES, GEOGRAPHIC_SCOPES, AI_POLICIES } from \"../data/ip.js\";\n\n/** Common sponsorship media/channel types — deliberately not part of the\n * general IP taxonomy in `data/ip.ts` (that's about the asset itself;\n * this is about the sponsorship deal's channels), so it stays local here. */\nexport const MEDIA_TYPES = [\n \"Social Media\", \"Video\", \"Photo\", \"Article/Blog\", \"Print\", \"Broadcast\", \"Podcast/Audio\", \"Livestream\",\n] as const;\n\n/**\n * The deal terms a sponsorship offer/proposal needs, in plain-language shape\n * — no bps, no IPFS, no ByteArray. `royaltyPercent` is a plain 0–100 number\n * (multiply by 100 for the contract's basis-points argument). Every field\n * here is declarative metadata carried in the pinned IPFS document (see\n * `toLicenseMetadata`) — the contract never reads any of it, so none of it\n * is enforced beyond the atomic accept-and-mint payment itself. This\n * component only collects and validates the data, it never fetches or\n * uploads anything itself.\n */\nexport interface SponsorshipTerms {\n amount: string;\n paymentTokenSymbol: string;\n durationDays: string;\n transferable: boolean;\n royaltyPercent: string;\n /** Free-text notes that don't fit any structured field below. */\n licenseText: string;\n licenseType: string;\n commercialUse: \"Yes\" | \"No\";\n derivatives: \"Allowed\" | \"Not Allowed\" | \"Share-Alike\";\n attribution: \"Required\" | \"Not Required\";\n territory: string;\n aiPolicy: string;\n /** e.g. \"Instagram + YouTube only\" — too deal-specific to bound into an enum. */\n scope: string;\n /** e.g. \"3 posts, 1 video\" */\n deliverables: string;\n exclusive: boolean;\n approvalRequired: boolean;\n media: string[];\n mediaOther: string;\n}\n\nexport const EMPTY_SPONSORSHIP_TERMS: SponsorshipTerms = {\n amount: \"\",\n paymentTokenSymbol: \"\",\n durationDays: \"30\",\n transferable: true,\n royaltyPercent: \"5\",\n licenseText: \"\",\n licenseType: \"CC BY-SA\",\n commercialUse: \"Yes\",\n derivatives: \"Share-Alike\",\n attribution: \"Required\",\n territory: \"Worldwide\",\n aiPolicy: \"Allowed\",\n scope: \"\",\n deliverables: \"\",\n exclusive: false,\n approvalRequired: false,\n media: [],\n mediaOther: \"\",\n};\n\n/** Shapes the pinned-IPFS-JSON payload — the single place both apps build\n * this object, so it can't drift across call sites. Purely additive; the\n * contract never reads any of it. */\nexport function toLicenseMetadata(terms: SponsorshipTerms): Record<string, unknown> {\n return {\n terms: terms.licenseText,\n transferable: terms.transferable,\n royaltyPercent: Number(terms.royaltyPercent || \"0\"),\n licenseType: terms.licenseType,\n commercialUse: terms.commercialUse,\n derivatives: terms.derivatives,\n attribution: terms.attribution,\n territory: terms.territory,\n aiPolicy: terms.aiPolicy,\n scope: terms.scope,\n deliverables: terms.deliverables,\n exclusive: terms.exclusive,\n approvalRequired: terms.approvalRequired,\n media: terms.media,\n mediaOther: terms.mediaOther,\n };\n}\n\nexport interface LicenseTermsBuilderProps {\n value: SponsorshipTerms;\n onChange: (next: SponsorshipTerms) => void;\n /** Payment token symbols to offer — e.g. from SUPPORTED_TOKENS. */\n tokenOptions: string[];\n /** Copy override for the amount field — \"Minimum bid\" for an owner's\n * offer, \"Amount you'll pay\" for a sponsor's proposal. Default: \"Amount\". */\n amountLabel?: string;\n disabled?: boolean;\n className?: string;\n}\n\nconst FIELD_LABEL = \"text-xs font-semibold text-foreground\";\nconst FIELD_HELP = \"text-xs text-muted-foreground\";\nconst INPUT_BASE =\n \"w-full h-10 rounded-xl border border-border bg-card px-3 text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-brand-purple/40 focus:border-brand-purple/40 disabled:opacity-50\";\n\nfunction ToggleGroup({ value, options, onChange, disabled }: { value: string; options: readonly string[]; onChange: (v: string) => void; disabled?: boolean }) {\n return (\n <div className=\"flex rounded-lg border border-border overflow-hidden w-full\">\n {options.map((opt, i) => (\n <button\n key={opt}\n type=\"button\"\n disabled={disabled}\n onClick={() => onChange(opt)}\n className={cn(\n \"flex-1 px-3 py-2 text-xs sm:text-sm transition-colors disabled:opacity-50\",\n i > 0 && \"border-l border-border\",\n value === opt\n ? \"bg-primary text-primary-foreground font-medium\"\n : \"bg-background hover:bg-muted text-muted-foreground\",\n )}\n >\n {opt}\n </button>\n ))}\n </div>\n );\n}\n\nfunction YesNoToggle({ label, help, checked, onChange, disabled }: { label: string; help: string; checked: boolean; onChange: (v: boolean) => void; disabled?: boolean }) {\n return (\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>{label}</label>\n <ToggleGroup value={checked ? \"Yes\" : \"No\"} options={[\"Yes\", \"No\"]} onChange={(v) => onChange(v === \"Yes\")} disabled={disabled} />\n <p className={FIELD_HELP}>{help}</p>\n </div>\n );\n}\n\nexport function LicenseTermsBuilder({\n value, onChange, tokenOptions, amountLabel = \"Amount\", disabled, className,\n}: LicenseTermsBuilderProps) {\n const [panelOpen, setPanelOpen] = useState(false);\n const set = <K extends keyof SponsorshipTerms>(key: K, v: SponsorshipTerms[K]) =>\n onChange({ ...value, [key]: v });\n\n const handleLicenseTypeChange = (licenseType: string) => {\n const def = LICENSE_TYPES.find((l) => l.value === licenseType);\n onChange({\n ...value,\n licenseType,\n ...(def ? { commercialUse: def.commercialUse, derivatives: def.derivatives, attribution: def.attribution } : {}),\n });\n };\n\n const selectedLicense = LICENSE_TYPES.find((l) => l.value === value.licenseType);\n const toggleMedia = (m: string) => {\n const next = value.media.includes(m) ? value.media.filter((x) => x !== m) : [...value.media, m];\n set(\"media\", next);\n };\n\n return (\n <div className={cn(\"space-y-4\", className)}>\n <div className=\"grid grid-cols-[1fr_auto] gap-2 items-end\">\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>{amountLabel}</label>\n <input\n type=\"number\"\n min={0}\n step=\"0.01\"\n inputMode=\"decimal\"\n disabled={disabled}\n value={value.amount}\n onChange={(e) => set(\"amount\", e.target.value)}\n placeholder=\"0.00\"\n className={INPUT_BASE}\n />\n </div>\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Currency</label>\n <div className=\"flex gap-1 flex-wrap justify-end max-w-[220px]\">\n {tokenOptions.map((symbol) => (\n <button\n key={symbol}\n type=\"button\"\n disabled={disabled}\n onClick={() => set(\"paymentTokenSymbol\", symbol)}\n className={cn(\n \"h-10 px-2.5 rounded-xl border text-xs font-semibold flex items-center gap-1.5 transition-colors disabled:opacity-50\",\n value.paymentTokenSymbol === symbol\n ? \"border-brand-purple bg-brand-purple/10 text-foreground\"\n : \"border-border bg-card text-muted-foreground hover:text-foreground\",\n )}\n >\n <CurrencyIcon symbol={symbol} size={14} />\n {symbol}\n </button>\n ))}\n </div>\n </div>\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Resale royalty (%)</label>\n <input\n type=\"number\"\n min={0}\n max={100}\n step=\"0.1\"\n disabled={disabled}\n value={value.royaltyPercent}\n onChange={(e) => set(\"royaltyPercent\", e.target.value)}\n className={INPUT_BASE}\n />\n <p className={FIELD_HELP}>You get this share automatically if the license is ever resold.</p>\n </div>\n\n <label className=\"flex items-start gap-2.5 cursor-pointer select-none\">\n <input\n type=\"checkbox\"\n disabled={disabled}\n checked={value.transferable}\n onChange={(e) => set(\"transferable\", e.target.checked)}\n className=\"mt-0.5 h-4 w-4 rounded border-border text-brand-purple focus:ring-brand-purple/40\"\n />\n <span className=\"text-sm\">\n <span className=\"font-medium\">Sponsor can resell this license</span>\n <span className={cn(FIELD_HELP, \"block\")}>Off means it's meant to stay with the sponsor who accepts it — resale still isn't blocked on-chain, this is just the stated intent.</span>\n </span>\n </label>\n\n <div className=\"rounded-xl border border-border overflow-hidden\">\n <button\n type=\"button\"\n onClick={() => setPanelOpen((o) => !o)}\n className=\"w-full flex items-center justify-between px-4 py-3 text-sm font-semibold\"\n >\n <span>How long, where, and what for</span>\n <ChevronDown className={cn(\"h-4 w-4 transition-transform text-muted-foreground\", panelOpen && \"rotate-180\")} />\n </button>\n\n {panelOpen ? (\n <div className=\"px-4 pb-4 space-y-4 border-t border-border pt-4\">\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>License length (days)</label>\n <input\n type=\"number\"\n min={1}\n disabled={disabled}\n value={value.durationDays}\n onChange={(e) => set(\"durationDays\", e.target.value)}\n className={INPUT_BASE}\n />\n <p className={FIELD_HELP}>Counted from the moment the deal is accepted, not from today.</p>\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>License type</label>\n <select\n disabled={disabled}\n value={value.licenseType}\n onChange={(e) => handleLicenseTypeChange(e.target.value)}\n className={INPUT_BASE}\n >\n {LICENSE_TYPES.map((l) => (\n <option key={l.value} value={l.value}>{l.label}</option>\n ))}\n </select>\n {selectedLicense ? <p className={FIELD_HELP}>{selectedLicense.description}</p> : null}\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Commercial use</label>\n <ToggleGroup value={value.commercialUse} options={[\"Yes\", \"No\"]} onChange={(v) => set(\"commercialUse\", v as SponsorshipTerms[\"commercialUse\"])} disabled={disabled} />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Derivatives</label>\n <ToggleGroup value={value.derivatives} options={[\"Allowed\", \"Not Allowed\", \"Share-Alike\"]} onChange={(v) => set(\"derivatives\", v as SponsorshipTerms[\"derivatives\"])} disabled={disabled} />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Attribution</label>\n <ToggleGroup value={value.attribution} options={[\"Required\", \"Not Required\"]} onChange={(v) => set(\"attribution\", v as SponsorshipTerms[\"attribution\"])} disabled={disabled} />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Territory</label>\n <select\n disabled={disabled}\n value={value.territory}\n onChange={(e) => set(\"territory\", e.target.value)}\n className={INPUT_BASE}\n >\n {GEOGRAPHIC_SCOPES.map((t) => (\n <option key={t} value={t}>{t}</option>\n ))}\n </select>\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>AI policy</label>\n <select\n disabled={disabled}\n value={value.aiPolicy}\n onChange={(e) => set(\"aiPolicy\", e.target.value)}\n className={INPUT_BASE}\n >\n {AI_POLICIES.map((p) => (\n <option key={p} value={p}>{p}</option>\n ))}\n </select>\n <p className={FIELD_HELP}>Whether this work can be used to train AI models.</p>\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Scope <span className=\"font-normal text-muted-foreground\">(optional)</span></label>\n <input\n type=\"text\"\n disabled={disabled}\n value={value.scope}\n onChange={(e) => set(\"scope\", e.target.value)}\n placeholder=\"e.g. Instagram + YouTube only\"\n className={INPUT_BASE}\n />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Deliverables <span className=\"font-normal text-muted-foreground\">(optional)</span></label>\n <textarea\n disabled={disabled}\n value={value.deliverables}\n onChange={(e) => set(\"deliverables\", e.target.value)}\n placeholder=\"e.g. 3 posts, 1 video\"\n rows={2}\n className={cn(INPUT_BASE, \"h-auto py-2.5 resize-y\")}\n />\n </div>\n\n <YesNoToggle\n label=\"Exclusive to this sponsor\"\n help=\"No other sponsors during the license term.\"\n checked={value.exclusive}\n onChange={(v) => set(\"exclusive\", v)}\n disabled={disabled}\n />\n\n <YesNoToggle\n label=\"Content approval required\"\n help=\"Sponsor reviews content before it's published.\"\n checked={value.approvalRequired}\n onChange={(v) => set(\"approvalRequired\", v)}\n disabled={disabled}\n />\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Media <span className=\"font-normal text-muted-foreground\">(optional)</span></label>\n <div className=\"flex flex-wrap gap-1.5\">\n {MEDIA_TYPES.map((m) => (\n <button\n key={m}\n type=\"button\"\n disabled={disabled}\n onClick={() => toggleMedia(m)}\n className={cn(\n \"h-8 px-2.5 rounded-full border text-xs font-medium transition-colors disabled:opacity-50\",\n value.media.includes(m)\n ? \"border-brand-purple bg-brand-purple/10 text-foreground\"\n : \"border-border bg-card text-muted-foreground hover:text-foreground\",\n )}\n >\n {m}\n </button>\n ))}\n </div>\n <input\n type=\"text\"\n disabled={disabled}\n value={value.mediaOther}\n onChange={(e) => set(\"mediaOther\", e.target.value)}\n placeholder=\"Other media type\"\n className={cn(INPUT_BASE, \"mt-1.5\")}\n />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Additional terms <span className=\"font-normal text-muted-foreground\">(optional)</span></label>\n <textarea\n disabled={disabled}\n value={value.licenseText}\n onChange={(e) => set(\"licenseText\", e.target.value)}\n placeholder=\"Anything else worth spelling out.\"\n rows={3}\n className={cn(INPUT_BASE, \"h-auto py-2.5 resize-y\")}\n />\n <p className={FIELD_HELP}>Saved permanently and shown to anyone who holds the license.</p>\n </div>\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/license-terms-builder.tsx"],"sourcesContent":["\"use client\";\n\nimport { ScrollText } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { LICENSE_TYPES, GEOGRAPHIC_SCOPES, AI_POLICIES } from \"../data/ip.js\";\n\n/** Common sponsorship media/channel types — deliberately not part of the\n * general IP taxonomy in `data/ip.ts` (that's about the asset itself;\n * this is about the sponsorship deal's channels), so it stays local here. */\nexport const MEDIA_TYPES = [\n \"Social Media\", \"Video\", \"Photo\", \"Article/Blog\", \"Print\", \"Broadcast\", \"Podcast/Audio\", \"Livestream\",\n] as const;\n\n/**\n * The deal terms a sponsorship offer/proposal needs, in plain-language shape\n * — no bps, no IPFS, no ByteArray. `royaltyPercent` is a plain 0–100 number\n * (multiply by 100 for the contract's basis-points argument). Every field\n * here is declarative metadata carried in the pinned IPFS document (see\n * `toLicenseMetadata`) — the contract never reads any of it, so none of it\n * is enforced beyond the atomic accept-and-mint payment itself. This\n * component only collects and validates the data, it never fetches or\n * uploads anything itself.\n */\nexport interface SponsorshipTerms {\n amount: string;\n paymentTokenSymbol: string;\n /** No default — the user must explicitly set this, never silently inherit one. */\n durationDays: string;\n transferable: boolean;\n /** Not surfaced in the UI (no resale-royalty concept here) — always \"0\". Kept\n * on the type because `create_offer`/`propose_sponsorship` still take a\n * `royaltyBps` argument. */\n royaltyPercent: string;\n /** Free-text notes that don't fit any structured field below. */\n licenseText: string;\n licenseType: string;\n commercialUse: \"Yes\" | \"No\";\n derivatives: \"Allowed\" | \"Not Allowed\" | \"Share-Alike\";\n attribution: \"Required\" | \"Not Required\";\n territory: string;\n aiPolicy: string;\n /** e.g. \"Instagram + YouTube only\" — too deal-specific to bound into an enum. */\n scope: string;\n /** e.g. \"3 posts, 1 video\" */\n deliverables: string;\n exclusive: boolean;\n approvalRequired: boolean;\n media: string[];\n mediaOther: string;\n}\n\nexport const EMPTY_SPONSORSHIP_TERMS: SponsorshipTerms = {\n amount: \"\",\n paymentTokenSymbol: \"\",\n durationDays: \"\",\n transferable: true,\n royaltyPercent: \"0\",\n licenseText: \"\",\n licenseType: \"CC BY-SA\",\n commercialUse: \"Yes\",\n derivatives: \"Share-Alike\",\n attribution: \"Required\",\n territory: \"Worldwide\",\n aiPolicy: \"Allowed\",\n scope: \"\",\n deliverables: \"\",\n exclusive: false,\n approvalRequired: false,\n media: [],\n mediaOther: \"\",\n};\n\n/** Shapes the pinned-IPFS-JSON payload — the single place both apps build\n * this object, so it can't drift across call sites. Purely additive; the\n * contract never reads any of it. */\nexport function toLicenseMetadata(terms: SponsorshipTerms): Record<string, unknown> {\n return {\n terms: terms.licenseText,\n transferable: terms.transferable,\n royaltyPercent: Number(terms.royaltyPercent || \"0\"),\n licenseType: terms.licenseType,\n commercialUse: terms.commercialUse,\n derivatives: terms.derivatives,\n attribution: terms.attribution,\n territory: terms.territory,\n aiPolicy: terms.aiPolicy,\n scope: terms.scope,\n deliverables: terms.deliverables,\n exclusive: terms.exclusive,\n approvalRequired: terms.approvalRequired,\n media: terms.media,\n mediaOther: terms.mediaOther,\n };\n}\n\nexport interface LicenseTermsBuilderProps {\n value: SponsorshipTerms;\n onChange: (next: SponsorshipTerms) => void;\n /** Payment token symbols to offer — e.g. from SUPPORTED_TOKENS. */\n tokenOptions: string[];\n /** Copy override for the amount field — \"Minimum bid\" for an owner's\n * offer, \"Amount you'll pay\" for a sponsor's proposal. Default: \"Amount\". */\n amountLabel?: string;\n disabled?: boolean;\n className?: string;\n}\n\nconst FIELD_LABEL = \"text-xs font-semibold text-foreground\";\nconst FIELD_HELP = \"text-xs text-muted-foreground\";\nconst INPUT_BASE =\n \"w-full h-10 rounded-xl border border-border bg-card px-3 text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-brand-purple/40 focus:border-brand-purple/40 disabled:opacity-50\";\n\nfunction ToggleGroup({ value, options, onChange, disabled }: { value: string; options: readonly string[]; onChange: (v: string) => void; disabled?: boolean }) {\n return (\n <div className=\"flex rounded-lg border border-border overflow-hidden w-full\">\n {options.map((opt, i) => (\n <button\n key={opt}\n type=\"button\"\n disabled={disabled}\n onClick={() => onChange(opt)}\n className={cn(\n \"flex-1 px-3 py-2 text-xs sm:text-sm transition-colors disabled:opacity-50\",\n i > 0 && \"border-l border-border\",\n value === opt\n ? \"bg-primary text-primary-foreground font-medium\"\n : \"bg-background hover:bg-muted text-muted-foreground\",\n )}\n >\n {opt}\n </button>\n ))}\n </div>\n );\n}\n\nfunction YesNoToggle({ label, help, checked, onChange, disabled }: { label: string; help: string; checked: boolean; onChange: (v: boolean) => void; disabled?: boolean }) {\n return (\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>{label}</label>\n <ToggleGroup value={checked ? \"Yes\" : \"No\"} options={[\"Yes\", \"No\"]} onChange={(v) => onChange(v === \"Yes\")} disabled={disabled} />\n <p className={FIELD_HELP}>{help}</p>\n </div>\n );\n}\n\nexport function LicenseTermsBuilder({\n value, onChange, tokenOptions, amountLabel = \"Amount\", disabled, className,\n}: LicenseTermsBuilderProps) {\n const set = <K extends keyof SponsorshipTerms>(key: K, v: SponsorshipTerms[K]) =>\n onChange({ ...value, [key]: v });\n\n const handleLicenseTypeChange = (licenseType: string) => {\n const def = LICENSE_TYPES.find((l) => l.value === licenseType);\n onChange({\n ...value,\n licenseType,\n ...(def ? { commercialUse: def.commercialUse, derivatives: def.derivatives, attribution: def.attribution } : {}),\n });\n };\n\n const selectedLicense = LICENSE_TYPES.find((l) => l.value === value.licenseType);\n const toggleMedia = (m: string) => {\n const next = value.media.includes(m) ? value.media.filter((x) => x !== m) : [...value.media, m];\n set(\"media\", next);\n };\n\n return (\n <div className={cn(\"space-y-4\", className)}>\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>{amountLabel}</label>\n <input\n type=\"number\"\n min={0}\n step=\"0.01\"\n inputMode=\"decimal\"\n disabled={disabled}\n value={value.amount}\n onChange={(e) => set(\"amount\", e.target.value)}\n placeholder=\"0.00\"\n className={INPUT_BASE}\n />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Currency</label>\n <div className=\"grid grid-cols-3 sm:grid-cols-5 gap-1.5\">\n {tokenOptions.map((symbol) => (\n <button\n key={symbol}\n type=\"button\"\n disabled={disabled}\n onClick={() => set(\"paymentTokenSymbol\", symbol)}\n aria-pressed={value.paymentTokenSymbol === symbol}\n className={cn(\n \"h-10 px-2 rounded-xl border text-xs font-semibold flex items-center justify-center gap-1.5 transition-colors disabled:opacity-50\",\n value.paymentTokenSymbol === symbol\n ? \"border-brand-purple bg-brand-purple/10 text-foreground\"\n : \"border-border bg-card text-muted-foreground hover:text-foreground\",\n )}\n >\n <CurrencyIcon symbol={symbol} size={14} />\n {symbol}\n </button>\n ))}\n </div>\n </div>\n\n <label className=\"flex items-start gap-2.5 cursor-pointer select-none\">\n <input\n type=\"checkbox\"\n disabled={disabled}\n checked={value.transferable}\n onChange={(e) => set(\"transferable\", e.target.checked)}\n className=\"mt-0.5 h-4 w-4 rounded border-border text-brand-purple focus:ring-brand-purple/40\"\n />\n <span className=\"text-sm\">\n <span className=\"font-medium\">Sponsor can resell this license</span>\n <span className={cn(FIELD_HELP, \"block\")}>Off means it's meant to stay with the sponsor who accepts it — resale still isn't blocked on-chain, this is just the stated intent.</span>\n </span>\n </label>\n\n <div className=\"rounded-xl border border-border overflow-hidden bg-card/40\">\n <div className=\"flex items-center gap-2.5 px-4 py-3 border-b border-border\">\n <ScrollText className=\"h-4 w-4 text-brand-purple shrink-0\" />\n <span className=\"text-sm font-semibold\">How long, where, and what for</span>\n </div>\n\n <div className=\"px-4 pb-4 space-y-4 pt-4\">\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>License length (days)</label>\n <input\n type=\"number\"\n min={1}\n disabled={disabled}\n value={value.durationDays}\n onChange={(e) => set(\"durationDays\", e.target.value)}\n placeholder=\"e.g. 30\"\n className={INPUT_BASE}\n />\n <p className={FIELD_HELP}>Counted from the moment the deal is accepted, not from today.</p>\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>License type</label>\n <select\n disabled={disabled}\n value={value.licenseType}\n onChange={(e) => handleLicenseTypeChange(e.target.value)}\n className={INPUT_BASE}\n >\n {LICENSE_TYPES.map((l) => (\n <option key={l.value} value={l.value}>{l.label}</option>\n ))}\n </select>\n {selectedLicense ? <p className={FIELD_HELP}>{selectedLicense.description}</p> : null}\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Commercial use</label>\n <ToggleGroup value={value.commercialUse} options={[\"Yes\", \"No\"]} onChange={(v) => set(\"commercialUse\", v as SponsorshipTerms[\"commercialUse\"])} disabled={disabled} />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Derivatives</label>\n <ToggleGroup value={value.derivatives} options={[\"Allowed\", \"Not Allowed\", \"Share-Alike\"]} onChange={(v) => set(\"derivatives\", v as SponsorshipTerms[\"derivatives\"])} disabled={disabled} />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Attribution</label>\n <ToggleGroup value={value.attribution} options={[\"Required\", \"Not Required\"]} onChange={(v) => set(\"attribution\", v as SponsorshipTerms[\"attribution\"])} disabled={disabled} />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Territory</label>\n <select\n disabled={disabled}\n value={value.territory}\n onChange={(e) => set(\"territory\", e.target.value)}\n className={INPUT_BASE}\n >\n {GEOGRAPHIC_SCOPES.map((t) => (\n <option key={t} value={t}>{t}</option>\n ))}\n </select>\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>AI policy</label>\n <select\n disabled={disabled}\n value={value.aiPolicy}\n onChange={(e) => set(\"aiPolicy\", e.target.value)}\n className={INPUT_BASE}\n >\n {AI_POLICIES.map((p) => (\n <option key={p} value={p}>{p}</option>\n ))}\n </select>\n <p className={FIELD_HELP}>Whether this work can be used to train AI models.</p>\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Scope <span className=\"font-normal text-muted-foreground\">(optional)</span></label>\n <input\n type=\"text\"\n disabled={disabled}\n value={value.scope}\n onChange={(e) => set(\"scope\", e.target.value)}\n placeholder=\"e.g. Instagram + YouTube only\"\n className={INPUT_BASE}\n />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Deliverables <span className=\"font-normal text-muted-foreground\">(optional)</span></label>\n <textarea\n disabled={disabled}\n value={value.deliverables}\n onChange={(e) => set(\"deliverables\", e.target.value)}\n placeholder=\"e.g. 3 posts, 1 video\"\n rows={2}\n className={cn(INPUT_BASE, \"h-auto py-2.5 resize-y\")}\n />\n </div>\n\n <YesNoToggle\n label=\"Exclusive to this sponsor\"\n help=\"No other sponsors during the license term.\"\n checked={value.exclusive}\n onChange={(v) => set(\"exclusive\", v)}\n disabled={disabled}\n />\n\n <YesNoToggle\n label=\"Content approval required\"\n help=\"Sponsor reviews content before it's published.\"\n checked={value.approvalRequired}\n onChange={(v) => set(\"approvalRequired\", v)}\n disabled={disabled}\n />\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Media <span className=\"font-normal text-muted-foreground\">(optional)</span></label>\n <div className=\"flex flex-wrap gap-1.5\">\n {MEDIA_TYPES.map((m) => (\n <button\n key={m}\n type=\"button\"\n disabled={disabled}\n onClick={() => toggleMedia(m)}\n className={cn(\n \"h-8 px-2.5 rounded-full border text-xs font-medium transition-colors disabled:opacity-50\",\n value.media.includes(m)\n ? \"border-brand-purple bg-brand-purple/10 text-foreground\"\n : \"border-border bg-card text-muted-foreground hover:text-foreground\",\n )}\n >\n {m}\n </button>\n ))}\n </div>\n <input\n type=\"text\"\n disabled={disabled}\n value={value.mediaOther}\n onChange={(e) => set(\"mediaOther\", e.target.value)}\n placeholder=\"Other media type\"\n className={cn(INPUT_BASE, \"mt-1.5\")}\n />\n </div>\n\n <div className=\"space-y-1.5\">\n <label className={FIELD_LABEL}>Additional terms <span className=\"font-normal text-muted-foreground\">(optional)</span></label>\n <textarea\n disabled={disabled}\n value={value.licenseText}\n onChange={(e) => set(\"licenseText\", e.target.value)}\n placeholder=\"Anything else worth spelling out.\"\n rows={3}\n className={cn(INPUT_BASE, \"h-auto py-2.5 resize-y\")}\n />\n <p className={FIELD_HELP}>Saved permanently and shown to anyone who holds the license.</p>\n </div>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|