@medialane/ui 0.295.0 → 0.296.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/account/input-otp.d.cts +2 -2
- package/dist/components/account/input-otp.d.ts +2 -2
- package/dist/components/badge.d.cts +1 -1
- package/dist/components/badge.d.ts +1 -1
- package/dist/components/button.d.cts +2 -2
- package/dist/components/button.d.ts +2 -2
- package/dist/components/fast-mint/asset-form-parts.cjs +194 -0
- package/dist/components/fast-mint/asset-form-parts.cjs.map +1 -0
- package/dist/components/fast-mint/asset-form-parts.d.cts +33 -0
- package/dist/components/fast-mint/asset-form-parts.d.ts +33 -0
- package/dist/components/fast-mint/asset-form-parts.js +158 -0
- package/dist/components/fast-mint/asset-form-parts.js.map +1 -0
- package/dist/components/fast-mint/collection-section.cjs +211 -0
- package/dist/components/fast-mint/collection-section.cjs.map +1 -0
- package/dist/components/fast-mint/collection-section.d.cts +27 -0
- package/dist/components/fast-mint/collection-section.d.ts +27 -0
- package/dist/components/fast-mint/collection-section.js +176 -0
- package/dist/components/fast-mint/collection-section.js.map +1 -0
- package/dist/components/fast-mint/fast-mint.cjs +116 -653
- package/dist/components/fast-mint/fast-mint.cjs.map +1 -1
- package/dist/components/fast-mint/fast-mint.d.cts +2 -2
- package/dist/components/fast-mint/fast-mint.d.ts +2 -2
- package/dist/components/fast-mint/fast-mint.js +115 -661
- package/dist/components/fast-mint/fast-mint.js.map +1 -1
- package/dist/components/fast-mint/form.cjs +40 -0
- package/dist/components/fast-mint/form.cjs.map +1 -0
- package/dist/components/fast-mint/form.d.cts +15 -0
- package/dist/components/fast-mint/form.d.ts +15 -0
- package/dist/components/fast-mint/form.js +16 -0
- package/dist/components/fast-mint/form.js.map +1 -0
- package/dist/components/fast-mint/ip-type-section.cjs +76 -0
- package/dist/components/fast-mint/ip-type-section.cjs.map +1 -0
- package/dist/components/fast-mint/ip-type-section.d.cts +17 -0
- package/dist/components/fast-mint/ip-type-section.d.ts +17 -0
- package/dist/components/fast-mint/ip-type-section.js +52 -0
- package/dist/components/fast-mint/ip-type-section.js.map +1 -0
- package/dist/components/fast-mint/licensing-section.cjs +124 -0
- package/dist/components/fast-mint/licensing-section.cjs.map +1 -0
- package/dist/components/fast-mint/licensing-section.d.cts +14 -0
- package/dist/components/fast-mint/licensing-section.d.ts +14 -0
- package/dist/components/fast-mint/licensing-section.js +99 -0
- package/dist/components/fast-mint/licensing-section.js.map +1 -0
- package/dist/components/fast-mint/media-kind.cjs +48 -0
- package/dist/components/fast-mint/media-kind.cjs.map +1 -0
- package/dist/components/fast-mint/media-kind.d.cts +12 -0
- package/dist/components/fast-mint/media-kind.d.ts +12 -0
- package/dist/components/fast-mint/media-kind.js +22 -0
- package/dist/components/fast-mint/media-kind.js.map +1 -0
- package/dist/components/fast-mint/mint-asset.cjs +124 -0
- package/dist/components/fast-mint/mint-asset.cjs.map +1 -0
- package/dist/components/fast-mint/mint-asset.d.cts +41 -0
- package/dist/components/fast-mint/mint-asset.d.ts +41 -0
- package/dist/components/fast-mint/mint-asset.js +100 -0
- package/dist/components/fast-mint/mint-asset.js.map +1 -0
- package/dist/components/fast-mint/use-ipfs-upload.cjs +64 -0
- package/dist/components/fast-mint/use-ipfs-upload.cjs.map +1 -0
- package/dist/components/fast-mint/use-ipfs-upload.d.cts +9 -0
- package/dist/components/fast-mint/use-ipfs-upload.d.ts +9 -0
- package/dist/components/fast-mint/use-ipfs-upload.js +40 -0
- package/dist/components/fast-mint/use-ipfs-upload.js.map +1 -0
- package/dist/components/fast-mint/use-new-collection-draft.cjs +66 -0
- package/dist/components/fast-mint/use-new-collection-draft.cjs.map +1 -0
- package/dist/components/fast-mint/use-new-collection-draft.d.cts +13 -0
- package/dist/components/fast-mint/use-new-collection-draft.d.ts +13 -0
- package/dist/components/fast-mint/use-new-collection-draft.js +42 -0
- package/dist/components/fast-mint/use-new-collection-draft.js.map +1 -0
- package/dist/components/sheet.d.cts +1 -1
- package/dist/components/sheet.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1,156 +1,29 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect, useRef, useState } from "react";
|
|
4
|
-
import Image from "next/image";
|
|
5
4
|
import { useForm } from "react-hook-form";
|
|
6
|
-
import {
|
|
5
|
+
import { Loader2 } from "lucide-react";
|
|
6
|
+
import { profileHref } from "@medialane/sdk";
|
|
7
7
|
import { describeError } from "../../utils/describe-error.js";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
ImagePlus,
|
|
13
|
-
Music,
|
|
14
|
-
Video,
|
|
15
|
-
FileText,
|
|
16
|
-
Loader2,
|
|
17
|
-
Layers,
|
|
18
|
-
ImagePlus as SingleIcon,
|
|
19
|
-
ChevronDown,
|
|
20
|
-
Boxes,
|
|
21
|
-
Plus,
|
|
22
|
-
Check,
|
|
23
|
-
ShieldCheck
|
|
24
|
-
} from "lucide-react";
|
|
8
|
+
import { uploadError } from "../../utils/upload-limits.js";
|
|
9
|
+
import { uploadFileToIpfs } from "../../utils/ipfs-upload.js";
|
|
10
|
+
import { cn } from "../../utils/cn.js";
|
|
25
11
|
import { Input } from "../input.js";
|
|
26
12
|
import { Textarea } from "../textarea.js";
|
|
27
|
-
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../select.js";
|
|
28
|
-
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../collapsible.js";
|
|
29
|
-
import { Popover, PopoverContent, PopoverTrigger } from "../popover.js";
|
|
30
13
|
import { MedialaneCollectionCard } from "../medialane-collection-card.js";
|
|
31
14
|
import { Dialog, DialogContent, DialogDescription, DialogTitle } from "../dialog.js";
|
|
32
|
-
import { IPTypeFields } from "../ip-type-fields.js";
|
|
33
|
-
import {
|
|
34
|
-
IP_TYPES,
|
|
35
|
-
LICENSE_TYPES,
|
|
36
|
-
GEOGRAPHIC_SCOPES,
|
|
37
|
-
AI_POLICIES,
|
|
38
|
-
DERIVATIVES_OPTIONS
|
|
39
|
-
} from "../../data/ip.js";
|
|
40
|
-
import { IP_TEMPLATES } from "../../data/ip-templates.js";
|
|
41
|
-
import { suggestLaunchpadSymbol } from "../../utils/launchpad-defaults.js";
|
|
42
|
-
import { uploadFileToIpfs, uploadJsonToIpfs, uploadFailureToast } from "../../utils/ipfs-upload.js";
|
|
43
|
-
import { cn } from "../../utils/cn.js";
|
|
44
15
|
import { Dropzone } from "./dropzone.js";
|
|
45
16
|
import { SuccessView } from "./success-view.js";
|
|
46
|
-
import {
|
|
47
|
-
import {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
const IP_TYPE_BY_KIND = {
|
|
58
|
-
image: "NFT",
|
|
59
|
-
audio: "Audio",
|
|
60
|
-
video: "Video",
|
|
61
|
-
document: "Documents"
|
|
62
|
-
};
|
|
63
|
-
const MEDIA_KIND_ICON = {
|
|
64
|
-
image: ImagePlus,
|
|
65
|
-
audio: Music,
|
|
66
|
-
video: Video,
|
|
67
|
-
document: FileText
|
|
68
|
-
};
|
|
69
|
-
function ToggleGroup({
|
|
70
|
-
value,
|
|
71
|
-
options,
|
|
72
|
-
onChange
|
|
73
|
-
}) {
|
|
74
|
-
return /* @__PURE__ */ jsx("div", { className: "flex rounded-lg border border-border overflow-hidden w-full", children: options.map((opt, i) => /* @__PURE__ */ jsx(
|
|
75
|
-
"button",
|
|
76
|
-
{
|
|
77
|
-
type: "button",
|
|
78
|
-
onClick: () => onChange(opt),
|
|
79
|
-
className: cn(
|
|
80
|
-
"flex-1 px-3 py-2 text-sm transition-colors",
|
|
81
|
-
i > 0 && "border-l border-border",
|
|
82
|
-
value === opt ? "bg-primary text-primary-foreground font-medium" : "bg-background hover:bg-muted text-muted-foreground"
|
|
83
|
-
),
|
|
84
|
-
children: opt
|
|
85
|
-
},
|
|
86
|
-
opt
|
|
87
|
-
)) });
|
|
88
|
-
}
|
|
89
|
-
function collectionDisplayLabel(col) {
|
|
90
|
-
return col.name || col.symbol || `Collection #${col.collectionId}`;
|
|
91
|
-
}
|
|
92
|
-
function CollectionThumb({ image }) {
|
|
93
|
-
const resolveImage = useImageUrl();
|
|
94
|
-
const imageUrl = resolveImage(image);
|
|
95
|
-
return /* @__PURE__ */ jsx("div", { className: "relative h-10 w-10 rounded-lg overflow-hidden bg-muted shrink-0", children: imageUrl ? /* @__PURE__ */ jsx(Image, { src: imageUrl, alt: "", fill: true, className: "object-cover", unoptimized: true }) : /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx(Boxes, { className: "h-4 w-4 text-muted-foreground/40" }) }) });
|
|
96
|
-
}
|
|
97
|
-
function CollectionPicker({
|
|
98
|
-
collections,
|
|
99
|
-
value,
|
|
100
|
-
onChange,
|
|
101
|
-
valueOf
|
|
102
|
-
}) {
|
|
103
|
-
const [open, setOpen] = useState(false);
|
|
104
|
-
const selected = value ? collections.find((c) => valueOf(c) === value) ?? null : null;
|
|
105
|
-
return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
|
|
106
|
-
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
107
|
-
"button",
|
|
108
|
-
{
|
|
109
|
-
type: "button",
|
|
110
|
-
"aria-expanded": open,
|
|
111
|
-
className: "flex w-full items-center gap-3 rounded-xl border border-border p-3 text-left transition-colors hover:bg-muted/40",
|
|
112
|
-
children: [
|
|
113
|
-
/* @__PURE__ */ jsx(CollectionThumb, { image: selected?.image }),
|
|
114
|
-
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
115
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm font-semibold truncate", children: selected ? collectionDisplayLabel(selected) : collections.length ? "Choose a collection" : "No collections yet" }),
|
|
116
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: selected ? `${selected.totalSupply ?? 0} work${selected.totalSupply === 1 ? "" : "s"}` : "Where this work will live" })
|
|
117
|
-
] }),
|
|
118
|
-
/* @__PURE__ */ jsx(ChevronDown, { className: "h-3.5 w-3.5 text-muted-foreground shrink-0" })
|
|
119
|
-
]
|
|
120
|
-
}
|
|
121
|
-
) }),
|
|
122
|
-
/* @__PURE__ */ jsx(PopoverContent, { className: "w-[var(--radix-popover-trigger-width)] p-0", align: "start", children: /* @__PURE__ */ jsx("div", { className: "max-h-64 overflow-y-auto p-1", children: collections.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-3 py-4 text-center text-sm text-muted-foreground", children: "No collections yet \u2014 create one instead." }) : collections.map((col) => {
|
|
123
|
-
const id = valueOf(col);
|
|
124
|
-
const isSelected = !!id && value === id;
|
|
125
|
-
return /* @__PURE__ */ jsxs(
|
|
126
|
-
"button",
|
|
127
|
-
{
|
|
128
|
-
type: "button",
|
|
129
|
-
disabled: !id,
|
|
130
|
-
onClick: () => {
|
|
131
|
-
if (!id) return;
|
|
132
|
-
onChange(id);
|
|
133
|
-
setOpen(false);
|
|
134
|
-
},
|
|
135
|
-
className: "flex w-full items-center gap-2.5 rounded-lg px-2 py-2 text-left transition-colors hover:bg-muted/60",
|
|
136
|
-
children: [
|
|
137
|
-
/* @__PURE__ */ jsx(CollectionThumb, { image: col.image }),
|
|
138
|
-
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
139
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium truncate", children: collectionDisplayLabel(col) }),
|
|
140
|
-
/* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
|
|
141
|
-
col.totalSupply ?? 0,
|
|
142
|
-
" work",
|
|
143
|
-
col.totalSupply === 1 ? "" : "s"
|
|
144
|
-
] })
|
|
145
|
-
] }),
|
|
146
|
-
isSelected && /* @__PURE__ */ jsx(Check, { className: "h-4 w-4 text-brand-blue shrink-0" })
|
|
147
|
-
]
|
|
148
|
-
},
|
|
149
|
-
id ?? col.contractAddress ?? col.name
|
|
150
|
-
);
|
|
151
|
-
}) }) })
|
|
152
|
-
] });
|
|
153
|
-
}
|
|
17
|
+
import { AssetTypePicker, CoverUpload, MediaRow } from "./asset-form-parts.js";
|
|
18
|
+
import { CollectionSection } from "./collection-section.js";
|
|
19
|
+
import { LicensingSection } from "./licensing-section.js";
|
|
20
|
+
import { IpTypeSection } from "./ip-type-section.js";
|
|
21
|
+
import { DEFAULT_VALUES } from "./form.js";
|
|
22
|
+
import { IP_TYPE_BY_KIND, MEDIA_ROUTE_MIME_TYPES, detectMediaKind } from "./media-kind.js";
|
|
23
|
+
import { mintAsset } from "./mint-asset.js";
|
|
24
|
+
import { mintableCollections } from "./mintable-collections.js";
|
|
25
|
+
import { useIpfsUpload } from "./use-ipfs-upload.js";
|
|
26
|
+
import { useNewCollectionDraft } from "./use-new-collection-draft.js";
|
|
154
27
|
function FastMint(props) {
|
|
155
28
|
const {
|
|
156
29
|
presentation = "inline",
|
|
@@ -171,79 +44,36 @@ function FastMint(props) {
|
|
|
171
44
|
} = props;
|
|
172
45
|
const [status, setStatus] = useState("idle");
|
|
173
46
|
const [errorMsg, setErrorMsg] = useState(null);
|
|
47
|
+
const media = useIpfsUpload();
|
|
48
|
+
const feature = useIpfsUpload();
|
|
174
49
|
const [mediaFile, setMediaFile] = useState(null);
|
|
175
|
-
const [mediaPreview, setMediaPreview] = useState(null);
|
|
176
|
-
const [mediaUri, setMediaUri] = useState(null);
|
|
177
50
|
const [mediaKind, setMediaKind] = useState("image");
|
|
178
|
-
const [mediaUploading, setMediaUploading] = useState(false);
|
|
179
|
-
const previewUrlRef = useRef(null);
|
|
180
51
|
const mediaInputRef = useRef(null);
|
|
181
|
-
const [featurePreview, setFeaturePreview] = useState(null);
|
|
182
|
-
const [featureUri, setFeatureUri] = useState(null);
|
|
183
|
-
const [featureUploading, setFeatureUploading] = useState(false);
|
|
184
|
-
const featurePreviewRef = useRef(null);
|
|
185
52
|
const featureInputRef = useRef(null);
|
|
186
53
|
const [assetType, setAssetType] = useState("single");
|
|
187
54
|
const [editionCount, setEditionCount] = useState("10");
|
|
188
55
|
const [collectionMode, setCollectionMode] = useState("existing");
|
|
189
56
|
const [existingCollectionId, setExistingCollectionId] = useState("");
|
|
190
57
|
const [existingCollectionContract, setExistingCollectionContract] = useState("");
|
|
191
|
-
const [newCollectionName, setNewCollectionName] = useState("");
|
|
192
|
-
const [newCollectionSymbol, setNewCollectionSymbol] = useState("");
|
|
193
|
-
const [newCollectionDescription, setNewCollectionDescription] = useState("");
|
|
194
|
-
const [autoSymbol, setAutoSymbol] = useState("");
|
|
195
|
-
const [autoCollectionName, setAutoCollectionName] = useState("");
|
|
196
|
-
const [autoCollectionDescription, setAutoCollectionDescription] = useState("");
|
|
197
58
|
const [ipType, setIpType] = useState("NFT");
|
|
198
|
-
const [advancedOpen, setAdvancedOpen] = useState(false);
|
|
199
|
-
const [ipTypeOpen, setIpTypeOpen] = useState(false);
|
|
200
59
|
const templateFieldsRef = useRef([]);
|
|
201
60
|
const [mintedAsset, setMintedAsset] = useState(null);
|
|
202
|
-
|
|
203
|
-
if (previewUrlRef.current) URL.revokeObjectURL(previewUrlRef.current);
|
|
204
|
-
if (featurePreviewRef.current) URL.revokeObjectURL(featurePreviewRef.current);
|
|
205
|
-
}, []);
|
|
206
|
-
const form = useForm({
|
|
207
|
-
defaultValues: {
|
|
208
|
-
name: "",
|
|
209
|
-
description: "",
|
|
210
|
-
external_url: "",
|
|
211
|
-
licenseType: "CC BY-SA",
|
|
212
|
-
commercialUse: "Yes",
|
|
213
|
-
derivatives: "Share-Alike",
|
|
214
|
-
attribution: "Required",
|
|
215
|
-
geographicScope: "Worldwide",
|
|
216
|
-
aiPolicy: "Allowed",
|
|
217
|
-
royalty: 0
|
|
218
|
-
}
|
|
219
|
-
});
|
|
61
|
+
const form = useForm({ defaultValues: DEFAULT_VALUES });
|
|
220
62
|
const name = form.watch("name");
|
|
63
|
+
const description = form.watch("description");
|
|
64
|
+
const draft = useNewCollectionDraft(name, description);
|
|
221
65
|
useEffect(() => {
|
|
222
66
|
if (walletAddress && !form.getValues("external_url")) {
|
|
223
67
|
form.setValue("external_url", `https://medialane.io/account/${walletAddress}`);
|
|
224
68
|
}
|
|
225
69
|
}, [walletAddress, form]);
|
|
226
|
-
useEffect(() => {
|
|
227
|
-
const s = suggestLaunchpadSymbol(name);
|
|
228
|
-
if (!s) return;
|
|
229
|
-
if (!newCollectionSymbol || newCollectionSymbol === autoSymbol) {
|
|
230
|
-
setNewCollectionSymbol(s);
|
|
231
|
-
setAutoSymbol(s);
|
|
232
|
-
}
|
|
233
|
-
if (!newCollectionName || newCollectionName === autoCollectionName) {
|
|
234
|
-
setNewCollectionName(name);
|
|
235
|
-
setAutoCollectionName(name);
|
|
236
|
-
}
|
|
237
|
-
}, [name, autoSymbol, autoCollectionName, newCollectionSymbol, newCollectionName]);
|
|
238
|
-
const description = form.watch("description");
|
|
239
|
-
useEffect(() => {
|
|
240
|
-
if (!newCollectionDescription || newCollectionDescription === autoCollectionDescription) {
|
|
241
|
-
setNewCollectionDescription(description);
|
|
242
|
-
setAutoCollectionDescription(description);
|
|
243
|
-
}
|
|
244
|
-
}, [description, autoCollectionDescription, newCollectionDescription]);
|
|
245
70
|
const erc721Collections = mintableCollections("single", collections);
|
|
246
71
|
const erc1155Collections = mintableCollections("editions", collections);
|
|
72
|
+
const uploadFile = async (file, kind) => {
|
|
73
|
+
const token = await getUploadToken();
|
|
74
|
+
if (!token) throw new Error("Sign in first");
|
|
75
|
+
return (await uploadFileToIpfs(client.api, file, kind)).uri;
|
|
76
|
+
};
|
|
247
77
|
const handleMediaSelect = async (file) => {
|
|
248
78
|
const kind = detectMediaKind(file.type);
|
|
249
79
|
if (!kind) {
|
|
@@ -254,8 +84,8 @@ function FastMint(props) {
|
|
|
254
84
|
setErrorMsg(`Please upload a${mediaKindLock === "image" ? "n" : ""} ${mediaKindLock}.`);
|
|
255
85
|
return;
|
|
256
86
|
}
|
|
257
|
-
const
|
|
258
|
-
const fileError = uploadError(file,
|
|
87
|
+
const route = MEDIA_ROUTE_MIME_TYPES.has(file.type) ? "media" : "document";
|
|
88
|
+
const fileError = uploadError(file, route);
|
|
259
89
|
if (fileError) {
|
|
260
90
|
setErrorMsg(fileError);
|
|
261
91
|
return;
|
|
@@ -263,74 +93,20 @@ function FastMint(props) {
|
|
|
263
93
|
setMediaFile(file);
|
|
264
94
|
setMediaKind(kind);
|
|
265
95
|
setIpType(IP_TYPE_BY_KIND[kind]);
|
|
266
|
-
|
|
267
|
-
const objectUrl = URL.createObjectURL(file);
|
|
268
|
-
previewUrlRef.current = objectUrl;
|
|
269
|
-
setMediaPreview(objectUrl);
|
|
270
|
-
setMediaUri(null);
|
|
271
|
-
setMediaUploading(true);
|
|
272
|
-
try {
|
|
273
|
-
const token = await getUploadToken();
|
|
274
|
-
if (!token) throw new Error("Sign in first");
|
|
275
|
-
const { uri } = await uploadFileToIpfs(client.api, file, viaMediaRoute ? "media" : "document");
|
|
276
|
-
setMediaUri(uri);
|
|
277
|
-
} catch (err) {
|
|
278
|
-
const t = uploadFailureToast(err);
|
|
279
|
-
setErrorMsg(t.description ?? t.title);
|
|
280
|
-
} finally {
|
|
281
|
-
setMediaUploading(false);
|
|
282
|
-
}
|
|
96
|
+
await media.start(file, (f) => uploadFile(f, route), setErrorMsg);
|
|
283
97
|
};
|
|
284
98
|
const clearMedia = () => {
|
|
285
99
|
setMediaFile(null);
|
|
286
|
-
|
|
287
|
-
setMediaUri(null);
|
|
100
|
+
media.clear();
|
|
288
101
|
if (mediaInputRef.current) mediaInputRef.current.value = "";
|
|
289
102
|
};
|
|
290
|
-
const
|
|
291
|
-
if (featurePreviewRef.current) URL.revokeObjectURL(featurePreviewRef.current);
|
|
292
|
-
const objectUrl = URL.createObjectURL(file);
|
|
293
|
-
featurePreviewRef.current = objectUrl;
|
|
294
|
-
setFeaturePreview(objectUrl);
|
|
295
|
-
setFeatureUri(null);
|
|
296
|
-
setFeatureUploading(true);
|
|
297
|
-
try {
|
|
298
|
-
const token = await getUploadToken();
|
|
299
|
-
if (!token) throw new Error("Sign in first");
|
|
300
|
-
const { uri } = await uploadFileToIpfs(client.api, file, "image");
|
|
301
|
-
setFeatureUri(uri);
|
|
302
|
-
} catch (err) {
|
|
303
|
-
const t = uploadFailureToast(err);
|
|
304
|
-
setErrorMsg(t.description ?? t.title);
|
|
305
|
-
} finally {
|
|
306
|
-
setFeatureUploading(false);
|
|
307
|
-
}
|
|
308
|
-
};
|
|
309
|
-
const handleLicenseChange = (value) => {
|
|
310
|
-
form.setValue("licenseType", value);
|
|
311
|
-
const def = LICENSE_TYPES.find((l) => l.value === value);
|
|
312
|
-
if (def) {
|
|
313
|
-
form.setValue("commercialUse", def.commercialUse);
|
|
314
|
-
form.setValue("derivatives", def.derivatives);
|
|
315
|
-
form.setValue("attribution", def.attribution);
|
|
316
|
-
}
|
|
317
|
-
};
|
|
318
|
-
const ready = !!mediaUri && !mediaUploading && name.trim().length > 0 && (mediaKind === "image" || !!featureUri) && (collectionMode === "existing" ? assetType === "single" ? !!existingCollectionId : !!existingCollectionContract : newCollectionName.trim().length > 0 && newCollectionSymbol.trim().length > 0);
|
|
319
|
-
async function pollForNewCollection(name2, symbol) {
|
|
320
|
-
for (let attempt = 0; attempt < 8; attempt++) {
|
|
321
|
-
const list = await refetchCollections();
|
|
322
|
-
const match = list.find((c) => c.name === name2 && c.symbol === symbol);
|
|
323
|
-
if (match?.collectionId) return match;
|
|
324
|
-
await new Promise((r) => setTimeout(r, 1500));
|
|
325
|
-
}
|
|
326
|
-
return null;
|
|
327
|
-
}
|
|
103
|
+
const ready = !!media.uri && !media.uploading && name.trim().length > 0 && (mediaKind === "image" || !!feature.uri) && (collectionMode === "existing" ? assetType === "single" ? !!existingCollectionId : !!existingCollectionContract : draft.name.trim().length > 0 && draft.symbol.trim().length > 0);
|
|
328
104
|
const onSubmit = async (values) => {
|
|
329
105
|
if (!hasWallet) {
|
|
330
106
|
onRequireWallet();
|
|
331
107
|
return;
|
|
332
108
|
}
|
|
333
|
-
if (!walletAddress || !
|
|
109
|
+
if (!walletAddress || !media.uri) return;
|
|
334
110
|
if (values.external_url && !values.external_url.startsWith("http://") && !values.external_url.startsWith("https://")) {
|
|
335
111
|
setErrorMsg("External link must start with http:// or https://");
|
|
336
112
|
return;
|
|
@@ -338,93 +114,24 @@ function FastMint(props) {
|
|
|
338
114
|
setStatus("minting");
|
|
339
115
|
setErrorMsg(null);
|
|
340
116
|
try {
|
|
341
|
-
const
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
description: values.description || "",
|
|
347
|
-
externalUrl: values.external_url || "",
|
|
348
|
-
imageUri: image,
|
|
349
|
-
creator: walletAddress,
|
|
117
|
+
const asset = await mintAsset({
|
|
118
|
+
client,
|
|
119
|
+
signer: await getSigner(),
|
|
120
|
+
walletAddress,
|
|
121
|
+
values,
|
|
350
122
|
ipType,
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
123
|
+
templateFields: templateFieldsRef.current,
|
|
124
|
+
mediaKind,
|
|
125
|
+
mediaUri: media.uri,
|
|
126
|
+
featureUri: feature.uri,
|
|
127
|
+
assetType,
|
|
128
|
+
editionCount,
|
|
129
|
+
destination: collectionMode === "new" ? { mode: "new", name: draft.name, symbol: draft.symbol, description: draft.description } : { mode: "existing", collectionId: existingCollectionId, collectionContract: existingCollectionContract },
|
|
130
|
+
singleCollections: erc721Collections,
|
|
131
|
+
refetchCollections,
|
|
132
|
+
getUploadToken
|
|
359
133
|
});
|
|
360
|
-
|
|
361
|
-
if (animationUrl) metadata.animation_url = animationUrl;
|
|
362
|
-
const uploadToken = await getUploadToken();
|
|
363
|
-
if (!uploadToken) throw new Error("Sign in first");
|
|
364
|
-
const tokenUri = await uploadJsonToIpfs(client.api, metadata);
|
|
365
|
-
let result;
|
|
366
|
-
let finalContractAddress;
|
|
367
|
-
let finalTokenId = null;
|
|
368
|
-
if (assetType === "single") {
|
|
369
|
-
let collectionId = existingCollectionId;
|
|
370
|
-
let contractAddress = erc721Collections.find((c) => c.collectionId === existingCollectionId)?.contractAddress ?? null;
|
|
371
|
-
if (collectionMode === "new") {
|
|
372
|
-
const intentRes2 = await client.api.intents.create("create-collection", {
|
|
373
|
-
owner: walletAddress,
|
|
374
|
-
name: newCollectionName,
|
|
375
|
-
symbol: newCollectionSymbol,
|
|
376
|
-
description: newCollectionDescription || void 0,
|
|
377
|
-
image
|
|
378
|
-
});
|
|
379
|
-
await executeIntent(signer, client, intentRes2);
|
|
380
|
-
const found = await pollForNewCollection(newCollectionName, newCollectionSymbol);
|
|
381
|
-
if (!found) throw new Error("Collection created, but it's still indexing \u2014 try minting again in a moment from My Collections.");
|
|
382
|
-
collectionId = found.collectionId;
|
|
383
|
-
contractAddress = found.contractAddress ?? null;
|
|
384
|
-
}
|
|
385
|
-
const intentRes = await client.api.intents.create("mint", {
|
|
386
|
-
owner: walletAddress,
|
|
387
|
-
collectionId,
|
|
388
|
-
recipient: walletAddress,
|
|
389
|
-
tokenUri,
|
|
390
|
-
royaltyBps: Math.round(values.royalty * 100)
|
|
391
|
-
});
|
|
392
|
-
result = await executeIntent(signer, client, intentRes);
|
|
393
|
-
finalContractAddress = contractAddress;
|
|
394
|
-
if (finalContractAddress) {
|
|
395
|
-
finalTokenId = mintedTokenIdFromReceipt(result.receipt, finalContractAddress);
|
|
396
|
-
}
|
|
397
|
-
} else {
|
|
398
|
-
let collectionContract = existingCollectionContract;
|
|
399
|
-
if (collectionMode === "new") {
|
|
400
|
-
const intentRes2 = await client.api.intents.create("create-collection", {
|
|
401
|
-
owner: walletAddress,
|
|
402
|
-
name: newCollectionName,
|
|
403
|
-
symbol: newCollectionSymbol,
|
|
404
|
-
description: newCollectionDescription || void 0,
|
|
405
|
-
image,
|
|
406
|
-
baseUri: "",
|
|
407
|
-
service: "mip-erc1155"
|
|
408
|
-
});
|
|
409
|
-
const deployResult = await executeIntent(signer, client, intentRes2);
|
|
410
|
-
const deployed = deployedCollectionFromReceipt(deployResult.receipt, "mip-erc1155");
|
|
411
|
-
if (!deployed) throw new Error("Collection deployed, but its address couldn't be read \u2014 check My Collections to mint into it.");
|
|
412
|
-
collectionContract = deployed;
|
|
413
|
-
}
|
|
414
|
-
const intentRes = await client.api.intents.create("mint", {
|
|
415
|
-
owner: walletAddress,
|
|
416
|
-
recipient: walletAddress,
|
|
417
|
-
collectionContract,
|
|
418
|
-
tokenUri,
|
|
419
|
-
value: editionCount,
|
|
420
|
-
royaltyBps: Math.round(values.royalty * 100)
|
|
421
|
-
});
|
|
422
|
-
result = await executeIntent(signer, client, intentRes);
|
|
423
|
-
finalContractAddress = collectionContract;
|
|
424
|
-
finalTokenId = mintedTokenIdFromReceipt(result.receipt, collectionContract);
|
|
425
|
-
}
|
|
426
|
-
if (finalContractAddress && finalTokenId) {
|
|
427
|
-
const asset = { contract: finalContractAddress, tokenId: finalTokenId, image };
|
|
134
|
+
if (asset) {
|
|
428
135
|
setMintedAsset(asset);
|
|
429
136
|
onMinted?.(asset);
|
|
430
137
|
}
|
|
@@ -440,25 +147,19 @@ function FastMint(props) {
|
|
|
440
147
|
setMintedAsset(null);
|
|
441
148
|
form.reset();
|
|
442
149
|
clearMedia();
|
|
443
|
-
|
|
444
|
-
setFeatureUri(null);
|
|
150
|
+
feature.clear();
|
|
445
151
|
setAssetType("single");
|
|
446
152
|
setEditionCount("10");
|
|
447
153
|
setCollectionMode("existing");
|
|
448
154
|
setExistingCollectionId("");
|
|
449
155
|
setExistingCollectionContract("");
|
|
450
|
-
|
|
451
|
-
setNewCollectionSymbol("");
|
|
452
|
-
setNewCollectionDescription("");
|
|
453
|
-
setAutoSymbol("");
|
|
454
|
-
setAutoCollectionName("");
|
|
455
|
-
setAutoCollectionDescription("");
|
|
156
|
+
draft.reset();
|
|
456
157
|
templateFieldsRef.current = [];
|
|
457
158
|
};
|
|
458
159
|
const busy = status === "minting";
|
|
459
|
-
const
|
|
160
|
+
const previewImage = mediaKind === "image" ? media.preview : feature.preview;
|
|
460
161
|
const selectedExistingCollection = assetType === "single" ? erc721Collections.find((c) => c.collectionId === existingCollectionId) : erc1155Collections.find((c) => c.contractAddress === existingCollectionContract);
|
|
461
|
-
const collectionLabel =
|
|
162
|
+
const collectionLabel = media.uri ? collectionMode === "new" ? draft.name || "New collection" : selectedExistingCollection?.name || "IP Asset" : void 0;
|
|
462
163
|
const wrap = (node) => {
|
|
463
164
|
if (presentation !== "dialog") return node;
|
|
464
165
|
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: (next) => {
|
|
@@ -476,7 +177,7 @@ function FastMint(props) {
|
|
|
476
177
|
{
|
|
477
178
|
footer: successFooter,
|
|
478
179
|
presentation,
|
|
479
|
-
previewImage
|
|
180
|
+
previewImage,
|
|
480
181
|
name,
|
|
481
182
|
collectionLabel,
|
|
482
183
|
mintedAsset,
|
|
@@ -500,53 +201,23 @@ function FastMint(props) {
|
|
|
500
201
|
)
|
|
501
202
|
);
|
|
502
203
|
}
|
|
204
|
+
const submitBlocked = !ready || busy || !hasWallet;
|
|
503
205
|
return wrap(
|
|
504
206
|
/* @__PURE__ */ jsxs("section", { className: "space-y-6", children: [
|
|
505
|
-
/* @__PURE__ */
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
{
|
|
520
|
-
className: cn(
|
|
521
|
-
"inline-flex shrink-0 items-center gap-1 rounded-full border px-2 py-0.5 text-2xs font-medium",
|
|
522
|
-
template.color.bg,
|
|
523
|
-
template.color.text,
|
|
524
|
-
template.color.border
|
|
525
|
-
),
|
|
526
|
-
children: [
|
|
527
|
-
/* @__PURE__ */ jsx(TemplateIcon, { className: "h-3 w-3" }),
|
|
528
|
-
template.label
|
|
529
|
-
]
|
|
530
|
-
}
|
|
531
|
-
);
|
|
532
|
-
})()
|
|
533
|
-
] })
|
|
534
|
-
] }),
|
|
535
|
-
/* @__PURE__ */ jsx(
|
|
536
|
-
"button",
|
|
537
|
-
{
|
|
538
|
-
type: "button",
|
|
539
|
-
onClick: () => mediaInputRef.current?.click(),
|
|
540
|
-
className: "text-xs font-semibold text-brand-blue hover:underline shrink-0",
|
|
541
|
-
children: "Change"
|
|
542
|
-
}
|
|
543
|
-
),
|
|
544
|
-
/* @__PURE__ */ jsx("input", { ref: mediaInputRef, type: "file", className: "hidden", onChange: (e) => {
|
|
545
|
-
const f = e.target.files?.[0];
|
|
546
|
-
if (f) handleMediaSelect(f);
|
|
547
|
-
} })
|
|
548
|
-
] }),
|
|
549
|
-
mediaUri && /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-[1fr_320px] gap-8 items-start", children: [
|
|
207
|
+
/* @__PURE__ */ jsx(
|
|
208
|
+
MediaRow,
|
|
209
|
+
{
|
|
210
|
+
file: mediaFile,
|
|
211
|
+
kind: mediaKind,
|
|
212
|
+
preview: media.preview,
|
|
213
|
+
uri: media.uri,
|
|
214
|
+
uploading: media.uploading,
|
|
215
|
+
ipType,
|
|
216
|
+
inputRef: mediaInputRef,
|
|
217
|
+
onSelect: handleMediaSelect
|
|
218
|
+
}
|
|
219
|
+
),
|
|
220
|
+
media.uri && /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-[1fr_320px] gap-8 items-start", children: [
|
|
550
221
|
/* @__PURE__ */ jsxs("div", { className: "space-y-5", children: [
|
|
551
222
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
552
223
|
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: "Title *" }),
|
|
@@ -564,7 +235,7 @@ function FastMint(props) {
|
|
|
564
235
|
/* @__PURE__ */ jsx(
|
|
565
236
|
Textarea,
|
|
566
237
|
{
|
|
567
|
-
value:
|
|
238
|
+
value: description,
|
|
568
239
|
onChange: (e) => form.setValue("description", e.target.value),
|
|
569
240
|
placeholder: "Describe your work, its story, and any context for buyers\u2026",
|
|
570
241
|
rows: 3
|
|
@@ -585,277 +256,60 @@ function FastMint(props) {
|
|
|
585
256
|
}
|
|
586
257
|
)
|
|
587
258
|
] }),
|
|
588
|
-
mediaKind !== "image" && /* @__PURE__ */
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
/* @__PURE__ */ jsx("span", { className: "block text-sm font-semibold", children: "Single Edition NFT" }),
|
|
633
|
-
/* @__PURE__ */ jsx("span", { className: "block text-xs mt-0.5 text-muted-foreground", children: "Minted once" })
|
|
634
|
-
] })
|
|
635
|
-
]
|
|
636
|
-
}
|
|
637
|
-
),
|
|
638
|
-
/* @__PURE__ */ jsxs(
|
|
639
|
-
"button",
|
|
640
|
-
{
|
|
641
|
-
type: "button",
|
|
642
|
-
onClick: () => setAssetType("editions"),
|
|
643
|
-
className: cn(
|
|
644
|
-
"flex items-start gap-3 rounded-xl border p-4 text-left transition-colors",
|
|
645
|
-
assetType === "editions" ? "border-brand-blue bg-brand-blue/5" : "border-border hover:bg-muted/40"
|
|
646
|
-
),
|
|
647
|
-
children: [
|
|
648
|
-
/* @__PURE__ */ jsx(Layers, { className: cn("h-5 w-5 shrink-0 mt-0.5", assetType === "editions" ? "text-brand-blue" : "text-muted-foreground") }),
|
|
649
|
-
/* @__PURE__ */ jsxs("span", { children: [
|
|
650
|
-
/* @__PURE__ */ jsx("span", { className: "block text-sm font-semibold", children: "Limited Editions NFT" }),
|
|
651
|
-
/* @__PURE__ */ jsx("span", { className: "block text-xs mt-0.5 text-muted-foreground", children: "Several numbered copies" })
|
|
652
|
-
] })
|
|
653
|
-
]
|
|
654
|
-
}
|
|
655
|
-
)
|
|
656
|
-
] })
|
|
657
|
-
] }),
|
|
658
|
-
assetType === "editions" && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
659
|
-
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: "Number of copies" }),
|
|
660
|
-
/* @__PURE__ */ jsx(
|
|
661
|
-
Input,
|
|
662
|
-
{
|
|
663
|
-
type: "number",
|
|
664
|
-
min: 1,
|
|
665
|
-
value: editionCount,
|
|
666
|
-
onChange: (e) => setEditionCount(e.target.value),
|
|
667
|
-
className: "max-w-[140px]"
|
|
668
|
-
}
|
|
669
|
-
)
|
|
670
|
-
] }),
|
|
671
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
672
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
673
|
-
/* @__PURE__ */ jsxs("label", { className: "text-sm font-medium flex items-center gap-1.5", children: [
|
|
674
|
-
/* @__PURE__ */ jsx(Boxes, { className: "h-4 w-4" }),
|
|
675
|
-
"Collection *"
|
|
676
|
-
] }),
|
|
677
|
-
/* @__PURE__ */ jsxs("div", { className: "flex rounded-lg border border-border overflow-hidden", children: [
|
|
678
|
-
/* @__PURE__ */ jsx(
|
|
679
|
-
"button",
|
|
680
|
-
{
|
|
681
|
-
type: "button",
|
|
682
|
-
onClick: () => setCollectionMode("existing"),
|
|
683
|
-
className: cn(
|
|
684
|
-
"px-3 h-7 text-xs font-medium transition-colors",
|
|
685
|
-
collectionMode === "existing" ? "bg-primary text-primary-foreground" : "bg-background hover:bg-muted text-muted-foreground"
|
|
686
|
-
),
|
|
687
|
-
children: "Existing"
|
|
688
|
-
}
|
|
689
|
-
),
|
|
690
|
-
/* @__PURE__ */ jsxs(
|
|
691
|
-
"button",
|
|
692
|
-
{
|
|
693
|
-
type: "button",
|
|
694
|
-
onClick: () => setCollectionMode("new"),
|
|
695
|
-
className: cn(
|
|
696
|
-
"px-3 h-7 text-xs font-medium border-l border-border transition-colors flex items-center gap-1",
|
|
697
|
-
collectionMode === "new" ? "bg-primary text-primary-foreground" : "bg-background hover:bg-muted text-muted-foreground"
|
|
698
|
-
),
|
|
699
|
-
children: [
|
|
700
|
-
/* @__PURE__ */ jsx(Plus, { className: "h-3 w-3" }),
|
|
701
|
-
"New"
|
|
702
|
-
]
|
|
703
|
-
}
|
|
704
|
-
)
|
|
705
|
-
] })
|
|
706
|
-
] }),
|
|
707
|
-
collectionMode === "existing" ? /* @__PURE__ */ jsx(
|
|
708
|
-
CollectionPicker,
|
|
709
|
-
{
|
|
710
|
-
collections: assetType === "single" ? erc721Collections : erc1155Collections,
|
|
711
|
-
value: assetType === "single" ? existingCollectionId : existingCollectionContract,
|
|
712
|
-
onChange: assetType === "single" ? setExistingCollectionId : setExistingCollectionContract,
|
|
713
|
-
valueOf: collectionKey(assetType === "single" ? "single" : "editions")
|
|
714
|
-
}
|
|
715
|
-
) : /* @__PURE__ */ jsxs("div", { className: "flex gap-3 rounded-xl border border-border p-3", children: [
|
|
716
|
-
/* @__PURE__ */ jsx("div", { className: "relative h-16 w-16 rounded-lg overflow-hidden bg-muted shrink-0", children: (mediaKind === "image" ? mediaPreview : featurePreview) ? /* @__PURE__ */ jsx(
|
|
717
|
-
Image,
|
|
718
|
-
{
|
|
719
|
-
src: mediaKind === "image" ? mediaPreview : featurePreview,
|
|
720
|
-
alt: "",
|
|
721
|
-
fill: true,
|
|
722
|
-
className: "object-cover",
|
|
723
|
-
unoptimized: true
|
|
724
|
-
}
|
|
725
|
-
) : /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx(Boxes, { className: "h-5 w-5 text-muted-foreground/40" }) }) }),
|
|
726
|
-
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1 space-y-2", children: [
|
|
727
|
-
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_100px] gap-2", children: [
|
|
728
|
-
/* @__PURE__ */ jsx(
|
|
729
|
-
Input,
|
|
730
|
-
{
|
|
731
|
-
value: newCollectionName,
|
|
732
|
-
onChange: (e) => setNewCollectionName(e.target.value),
|
|
733
|
-
placeholder: "Collection name",
|
|
734
|
-
className: "h-9 text-sm"
|
|
735
|
-
}
|
|
736
|
-
),
|
|
737
|
-
/* @__PURE__ */ jsx(
|
|
738
|
-
Input,
|
|
739
|
-
{
|
|
740
|
-
value: newCollectionSymbol,
|
|
741
|
-
onChange: (e) => setNewCollectionSymbol(e.target.value.toUpperCase()),
|
|
742
|
-
placeholder: "SYMBOL",
|
|
743
|
-
className: "h-9 text-sm"
|
|
744
|
-
}
|
|
745
|
-
)
|
|
746
|
-
] }),
|
|
747
|
-
/* @__PURE__ */ jsx(
|
|
748
|
-
Textarea,
|
|
749
|
-
{
|
|
750
|
-
value: newCollectionDescription,
|
|
751
|
-
onChange: (e) => setNewCollectionDescription(e.target.value),
|
|
752
|
-
placeholder: "Describe this collection\u2026",
|
|
753
|
-
rows: 2,
|
|
754
|
-
className: "text-sm resize-none"
|
|
755
|
-
}
|
|
756
|
-
),
|
|
757
|
-
/* @__PURE__ */ jsx("p", { className: "text-2xs text-muted-foreground", children: "Prefilled from your asset \u2014 edit anything above." })
|
|
758
|
-
] })
|
|
759
|
-
] })
|
|
760
|
-
] }),
|
|
761
|
-
/* @__PURE__ */ jsx(Collapsible, { open: advancedOpen, onOpenChange: setAdvancedOpen, children: /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-border overflow-hidden", children: [
|
|
762
|
-
/* @__PURE__ */ jsx(CollapsibleTrigger, { asChild: true, children: /* @__PURE__ */ jsxs("button", { type: "button", className: "w-full flex items-center justify-between px-4 py-3.5 hover:bg-muted/30 transition-colors", children: [
|
|
763
|
-
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
|
|
764
|
-
/* @__PURE__ */ jsx(ShieldCheck, { className: "h-4 w-4 text-primary" }),
|
|
765
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: "Licensing Terms" }),
|
|
766
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground font-normal", children: "Optional \xB7 Berne Convention" })
|
|
767
|
-
] }),
|
|
768
|
-
/* @__PURE__ */ jsx(ChevronDown, { className: cn("h-4 w-4 text-muted-foreground transition-transform", advancedOpen && "rotate-180") })
|
|
769
|
-
] }) }),
|
|
770
|
-
/* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsxs("div", { className: "px-4 pb-4 space-y-4 border-t border-border/60 pt-4", children: [
|
|
771
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
772
|
-
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-muted-foreground", children: "License" }),
|
|
773
|
-
/* @__PURE__ */ jsxs(Select, { value: form.watch("licenseType"), onValueChange: handleLicenseChange, children: [
|
|
774
|
-
/* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
775
|
-
/* @__PURE__ */ jsx(SelectContent, { children: LICENSE_TYPES.map((l) => /* @__PURE__ */ jsx(SelectItem, { value: l.value, children: l.label }, l.value)) })
|
|
776
|
-
] })
|
|
777
|
-
] }),
|
|
778
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
779
|
-
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-muted-foreground", children: "Commercial use" }),
|
|
780
|
-
/* @__PURE__ */ jsx(ToggleGroup, { value: form.watch("commercialUse"), options: ["Yes", "No"], onChange: (v) => form.setValue("commercialUse", v) })
|
|
781
|
-
] }),
|
|
782
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
783
|
-
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-muted-foreground", children: "Derivatives" }),
|
|
784
|
-
/* @__PURE__ */ jsx(ToggleGroup, { value: form.watch("derivatives"), options: DERIVATIVES_OPTIONS, onChange: (v) => form.setValue("derivatives", v) })
|
|
785
|
-
] }),
|
|
786
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
787
|
-
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-muted-foreground", children: "Territory" }),
|
|
788
|
-
/* @__PURE__ */ jsxs(Select, { value: form.watch("geographicScope"), onValueChange: (v) => form.setValue("geographicScope", v), children: [
|
|
789
|
-
/* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
790
|
-
/* @__PURE__ */ jsx(SelectContent, { children: GEOGRAPHIC_SCOPES.map((s) => /* @__PURE__ */ jsx(SelectItem, { value: s, children: s }, s)) })
|
|
791
|
-
] })
|
|
792
|
-
] }),
|
|
793
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
794
|
-
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-muted-foreground", children: "AI & data mining" }),
|
|
795
|
-
/* @__PURE__ */ jsx(ToggleGroup, { value: form.watch("aiPolicy"), options: AI_POLICIES, onChange: (v) => form.setValue("aiPolicy", v) })
|
|
796
|
-
] }),
|
|
797
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
798
|
-
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-muted-foreground", children: "Royalty % (0\u201350)" }),
|
|
799
|
-
/* @__PURE__ */ jsx(
|
|
800
|
-
Input,
|
|
801
|
-
{
|
|
802
|
-
type: "number",
|
|
803
|
-
min: 0,
|
|
804
|
-
max: 50,
|
|
805
|
-
step: 0.5,
|
|
806
|
-
value: form.watch("royalty"),
|
|
807
|
-
onChange: (e) => form.setValue("royalty", parseFloat(e.target.value) || 0),
|
|
808
|
-
className: "max-w-[120px]"
|
|
809
|
-
}
|
|
810
|
-
)
|
|
811
|
-
] })
|
|
812
|
-
] }) })
|
|
813
|
-
] }) }),
|
|
814
|
-
/* @__PURE__ */ jsx(Collapsible, { open: ipTypeOpen, onOpenChange: setIpTypeOpen, children: /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-border overflow-hidden", children: [
|
|
815
|
-
/* @__PURE__ */ jsx(CollapsibleTrigger, { asChild: true, children: /* @__PURE__ */ jsxs("button", { type: "button", className: "w-full flex items-center justify-between px-4 py-3.5 hover:bg-muted/30 transition-colors", children: [
|
|
816
|
-
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
|
|
817
|
-
/* @__PURE__ */ jsx(Layers, { className: "h-4 w-4 text-primary" }),
|
|
818
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: "IP Type & Metadata" }),
|
|
819
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground font-normal", children: "Optional" })
|
|
820
|
-
] }),
|
|
821
|
-
/* @__PURE__ */ jsx(ChevronDown, { className: cn("h-4 w-4 text-muted-foreground transition-transform", ipTypeOpen && "rotate-180") })
|
|
822
|
-
] }) }),
|
|
823
|
-
/* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsxs("div", { className: "px-4 pb-4 space-y-4 border-t border-border/60 pt-4", children: [
|
|
824
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
825
|
-
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-muted-foreground", children: "IP Type" }),
|
|
826
|
-
/* @__PURE__ */ jsxs(Select, { value: ipType, onValueChange: (v) => setIpType(v), children: [
|
|
827
|
-
/* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
828
|
-
/* @__PURE__ */ jsx(SelectContent, { children: IP_TYPES.map((t) => /* @__PURE__ */ jsx(SelectItem, { value: t, children: t }, t)) })
|
|
829
|
-
] })
|
|
830
|
-
] }),
|
|
831
|
-
/* @__PURE__ */ jsx(
|
|
832
|
-
IPTypeFields,
|
|
833
|
-
{
|
|
834
|
-
ipType,
|
|
835
|
-
onChange: (fields) => {
|
|
836
|
-
templateFieldsRef.current = fields;
|
|
837
|
-
},
|
|
838
|
-
uploadDocument: async (file) => {
|
|
839
|
-
const token = await getUploadToken();
|
|
840
|
-
if (!token) throw new Error("Sign in first");
|
|
841
|
-
const { uri } = await uploadFileToIpfs(client.api, file, "document");
|
|
842
|
-
return uri;
|
|
843
|
-
},
|
|
844
|
-
existingDocument: mediaKind === "document" && mediaUri && mediaFile ? { uri: mediaUri, name: mediaFile.name } : null
|
|
845
|
-
}
|
|
846
|
-
)
|
|
847
|
-
] }) })
|
|
848
|
-
] }) }),
|
|
259
|
+
mediaKind !== "image" && /* @__PURE__ */ jsx(
|
|
260
|
+
CoverUpload,
|
|
261
|
+
{
|
|
262
|
+
preview: feature.preview,
|
|
263
|
+
uploading: feature.uploading,
|
|
264
|
+
inputRef: featureInputRef,
|
|
265
|
+
onSelect: (file) => void feature.start(file, (f) => uploadFile(f, "image"), setErrorMsg)
|
|
266
|
+
}
|
|
267
|
+
),
|
|
268
|
+
/* @__PURE__ */ jsx(
|
|
269
|
+
AssetTypePicker,
|
|
270
|
+
{
|
|
271
|
+
value: assetType,
|
|
272
|
+
onChange: setAssetType,
|
|
273
|
+
editionCount,
|
|
274
|
+
onEditionCount: setEditionCount
|
|
275
|
+
}
|
|
276
|
+
),
|
|
277
|
+
/* @__PURE__ */ jsx(
|
|
278
|
+
CollectionSection,
|
|
279
|
+
{
|
|
280
|
+
assetType,
|
|
281
|
+
mode: collectionMode,
|
|
282
|
+
onModeChange: setCollectionMode,
|
|
283
|
+
collections: assetType === "single" ? erc721Collections : erc1155Collections,
|
|
284
|
+
existingId: existingCollectionId,
|
|
285
|
+
existingContract: existingCollectionContract,
|
|
286
|
+
onExistingId: setExistingCollectionId,
|
|
287
|
+
onExistingContract: setExistingCollectionContract,
|
|
288
|
+
draft,
|
|
289
|
+
previewImage
|
|
290
|
+
}
|
|
291
|
+
),
|
|
292
|
+
/* @__PURE__ */ jsx(LicensingSection, { form }),
|
|
293
|
+
/* @__PURE__ */ jsx(
|
|
294
|
+
IpTypeSection,
|
|
295
|
+
{
|
|
296
|
+
ipType,
|
|
297
|
+
onIpTypeChange: setIpType,
|
|
298
|
+
fieldsRef: templateFieldsRef,
|
|
299
|
+
uploadDocument: (file) => uploadFile(file, "document"),
|
|
300
|
+
existingDocument: mediaKind === "document" ? { uri: media.uri, name: mediaFile.name } : null
|
|
301
|
+
}
|
|
302
|
+
),
|
|
849
303
|
status === "error" && errorMsg && /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", children: errorMsg }),
|
|
850
304
|
/* @__PURE__ */ jsx(
|
|
851
305
|
"button",
|
|
852
306
|
{
|
|
853
307
|
type: "button",
|
|
854
|
-
disabled:
|
|
308
|
+
disabled: submitBlocked,
|
|
855
309
|
onClick: form.handleSubmit(onSubmit),
|
|
856
310
|
className: cn(
|
|
857
311
|
"w-full h-12 text-base font-semibold text-white rounded-xl flex items-center justify-center gap-2 transition-all hover:brightness-110 active:scale-[0.98] bg-brand-blue",
|
|
858
|
-
|
|
312
|
+
submitBlocked && "opacity-40 pointer-events-none"
|
|
859
313
|
),
|
|
860
314
|
children: busy ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
861
315
|
/* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }),
|
|
@@ -868,7 +322,7 @@ function FastMint(props) {
|
|
|
868
322
|
/* @__PURE__ */ jsx("div", { className: "order-first lg:order-last lg:sticky lg:top-20 max-w-[260px] mx-auto w-full lg:max-w-none lg:mx-0", children: /* @__PURE__ */ jsx(
|
|
869
323
|
MedialaneCollectionCard,
|
|
870
324
|
{
|
|
871
|
-
image:
|
|
325
|
+
image: previewImage,
|
|
872
326
|
name,
|
|
873
327
|
collection: collectionLabel,
|
|
874
328
|
creator: walletAddress ? `${walletAddress.slice(0, 6)}\u2026${walletAddress.slice(-4)}` : void 0,
|