@medialane/ui 0.307.0 → 0.309.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/asset-card.cjs +3 -0
- package/dist/components/asset-card.cjs.map +1 -1
- package/dist/components/asset-card.d.cts +2 -1
- package/dist/components/asset-card.d.ts +2 -1
- package/dist/components/asset-card.js +3 -0
- package/dist/components/asset-card.js.map +1 -1
- package/dist/components/asset-page.cjs +1 -1
- package/dist/components/asset-page.cjs.map +1 -1
- package/dist/components/asset-page.js +1 -1
- package/dist/components/asset-page.js.map +1 -1
- package/dist/components/button.d.cts +2 -2
- package/dist/components/button.d.ts +2 -2
- package/dist/components/collection-page.cjs +5 -3
- package/dist/components/collection-page.cjs.map +1 -1
- package/dist/components/collection-page.js +5 -3
- package/dist/components/collection-page.js.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/launchpad/edition-mint-schema.d.cts +2 -2
- package/dist/components/launchpad/edition-mint-schema.d.ts +2 -2
- package/dist/components/launchpad/single-edition-mint.cjs +14 -4
- package/dist/components/launchpad/single-edition-mint.cjs.map +1 -1
- package/dist/components/launchpad/single-edition-mint.js +14 -4
- package/dist/components/launchpad/single-edition-mint.js.map +1 -1
- package/dist/components/sheet.d.cts +1 -1
- package/dist/components/sheet.d.ts +1 -1
- package/dist/components/soulbound-card.cjs +33 -8
- package/dist/components/soulbound-card.cjs.map +1 -1
- package/dist/components/soulbound-card.d.cts +4 -2
- package/dist/components/soulbound-card.d.ts +4 -2
- package/dist/components/soulbound-card.js +24 -10
- package/dist/components/soulbound-card.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/launchpad/single-edition-mint.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport * as z from \"zod\";\nimport { Boxes, ChevronDown, ImagePlus, Layers, ShieldCheck, Upload } from \"lucide-react\";\nimport { assetHref, collectionHref, getService, profileHref } from \"@medialane/sdk\";\nimport { acceptFor, uploadError } from \"../../utils/upload-limits.js\";\nimport { FIELD_LIMITS } from \"../../utils/field-limits.js\";\nimport { mintedTokenIdFromReceipt } from \"@medialane/sdk/starknet\";\nimport Image from \"../image.js\";\nimport { Input } from \"../input.js\";\nimport { Textarea } from \"../textarea.js\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"../select.js\";\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"../collapsible.js\";\nimport { CollapsibleSection } from \"../collapsible-section.js\";\nimport { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from \"../form.js\";\nimport { ToggleGroup } from \"../create-form-primitives.js\";\nimport { IPTypeFields } from \"../ip-type-fields.js\";\nimport { ClaimRouteShell } from \"../claim-route-shell.js\";\nimport { TransactionSuccess } from \"../transaction-success.js\";\nimport { MedialaneCollectionCard } from \"../medialane-collection-card.js\";\nimport { TransactionDialog } from \"../transaction-dialog.js\";\nimport { WalletRequired } from \"../wallet-required.js\";\nimport { useMedialaneApp } from \"../medialane-app.js\";\nimport { RewardEarned } from \"../rewards/reward-earned.js\";\nimport { CollectionPicker } from \"./collection-picker.js\";\nimport { AI_POLICIES, DERIVATIVES_OPTIONS, IP_TYPES, LICENSE_TYPES, type IPType } from \"../../data/ip.js\";\nimport { cn } from \"../../utils/cn.js\";\nimport { runIntentCalls } from \"../../utils/run-intent-calls.js\";\nimport { pinAssetMetadata, uploadFileToIpfs } from \"../../utils/ipfs-upload.js\";\nimport { useCollectionsByOwner } from \"../../utils/use-collections.js\";\nimport { useTransaction } from \"../../utils/use-transaction.js\";\nimport { invalidatePortfolioCache } from \"../../utils/portfolio-cache.js\";\nimport type { MetadataField } from \"../ip-type-fields.js\";\n\nconst schema = z.object({\n collectionId: z.string().min(1, \"Select a collection\"),\n name: z.string().min(1, \"Name required\").max(FIELD_LIMITS.name),\n description: z.string().max(FIELD_LIMITS.description).optional(),\n external_url: z\n .string()\n .max(500)\n .refine((v) => !v || v.startsWith(\"http://\") || v.startsWith(\"https://\"), { message: \"Must start with http:// or https://\" })\n .optional(),\n ipType: z.enum(IP_TYPES),\n licenseType: z.string().min(1, \"License required\"),\n commercialUse: z.enum([\"Yes\", \"No\"]),\n derivatives: z.enum([\"Allowed\", \"Not Allowed\", \"Share-Alike\"]),\n attribution: z.enum([\"Required\", \"Not Required\"]),\n geographicScope: z.string(),\n aiPolicy: z.enum([\"Allowed\", \"Not Allowed\", \"Training Only\"]),\n royalty: z.coerce.number().min(0).max(50),\n image: z.instanceof(File).optional(),\n});\ntype FormValues = z.infer<typeof schema>;\n\nconst DEFAULTS: FormValues = {\n collectionId: \"\",\n name: \"\",\n description: \"\",\n external_url: \"\",\n ipType: \"NFT\",\n licenseType: \"CC BY-SA\",\n commercialUse: \"Yes\",\n derivatives: \"Share-Alike\",\n attribution: \"Required\",\n geographicScope: \"Worldwide\",\n aiPolicy: \"Allowed\",\n royalty: 0,\n};\n\nexport function SingleEditionMint({ aside }: { aside?: ReactNode }) {\n const app = useMedialaneApp();\n const walletAddress = app.walletAddress;\n const tx = useTransaction();\n const { collections: allCollections, isLoading: collectionsLoading } = useCollectionsByOwner(walletAddress ?? null);\n const collections = allCollections.filter((c) => getService(c.service)?.id === \"mip-erc721\" && c.collectionId != null);\n\n const [imageFile, setImageFile] = useState<File | null>(null);\n const [imagePreview, setImagePreview] = useState<string | null>(null);\n const [advancedOpen, setAdvancedOpen] = useState(false);\n const [licensingOpen, setLicensingOpen] = useState(false);\n const [ipTypeOpen, setIpTypeOpen] = useState(false);\n const [metadataResetKey, setMetadataResetKey] = useState(0);\n const metadataFieldsRef = useRef<MetadataField[]>([]);\n const previewUrlRef = useRef<string | null>(null);\n const imageInputRef = useRef<HTMLInputElement | null>(null);\n\n useEffect(() => {\n return () => {\n if (previewUrlRef.current) URL.revokeObjectURL(previewUrlRef.current);\n };\n }, []);\n\n const form = useForm<FormValues>({ resolver: zodResolver(schema), defaultValues: DEFAULTS });\n const selectedCollectionId = form.watch(\"collectionId\");\n const selectedCollection = collections.find((c) => c.collectionId === selectedCollectionId) ?? null;\n\n useEffect(() => {\n if (collections.length > 0 && !form.getValues(\"collectionId\")) form.setValue(\"collectionId\", collections[0]!.collectionId!);\n }, [collections, form]);\n\n useEffect(() => {\n if (selectedCollection?.contractAddress && !form.getValues(\"external_url\")) {\n form.setValue(\"external_url\", `https://medialane.io${collectionHref(\"STARKNET\", selectedCollection.contractAddress)}`);\n }\n }, [selectedCollection?.contractAddress, form]);\n\n const handleLicenseChange = (value: string) => {\n form.setValue(\"licenseType\", value);\n const def = LICENSE_TYPES.find((l) => l.value === value);\n if (def) {\n form.setValue(\"commercialUse\", def.commercialUse);\n form.setValue(\"derivatives\", def.derivatives);\n form.setValue(\"attribution\", def.attribution);\n }\n };\n\n const uploadDocument = async (file: File) => {\n await app.ensureSignedIn?.();\n return (await uploadFileToIpfs(app.getClient().api, file, \"document\")).uri;\n };\n\n const handleAgain = () => {\n tx.reset();\n form.reset({ ...DEFAULTS, collectionId: collections[0]?.collectionId ?? \"\" });\n metadataFieldsRef.current = [];\n setMetadataResetKey((key) => key + 1);\n setImageFile(null);\n setImagePreview(null);\n if (imageInputRef.current) imageInputRef.current.value = \"\";\n };\n\n const onSubmit = (values: FormValues) => {\n if (!walletAddress) return;\n void tx.run(async (signer) => {\n await app.ensureSignedIn?.();\n const api = app.getClient().api;\n const pinned = await pinAssetMetadata(api, {\n name: values.name,\n description: values.description ?? \"\",\n externalUrl: values.external_url,\n creator: walletAddress,\n ipType: values.ipType,\n licenseType: values.licenseType,\n commercialUse: values.commercialUse,\n derivatives: values.derivatives,\n attribution: values.attribution,\n geographicScope: values.geographicScope,\n aiPolicy: values.aiPolicy,\n royalty: String(values.royalty),\n imageFile,\n templateTraits: metadataFieldsRef.current.filter((f) => f.traitType.trim() && f.value.trim()).map((f) => ({ traitType: f.traitType.trim(), value: f.value.trim() })),\n });\n await runIntentCalls(signer, () =>\n api.intents.create(\"mint\", {\n owner: walletAddress,\n collectionId: values.collectionId,\n recipient: walletAddress,\n tokenUri: pinned.uri,\n royaltyBps: Math.round(values.royalty * 100),\n }),\n );\n invalidatePortfolioCache(walletAddress);\n });\n };\n\n const mintedTokenId = tx.receipt && selectedCollection ? mintedTokenIdFromReceipt(tx.receipt, selectedCollection.contractAddress) : null;\n const mintedHref = mintedTokenId && selectedCollection ? assetHref(\"STARKNET\", selectedCollection.contractAddress, mintedTokenId) : null;\n const busy = tx.phase !== \"idle\" || collectionsLoading || collections.length === 0;\n\n return (\n <WalletRequired\n icon={ImagePlus}\n iconClassName=\"text-brand-blue\"\n title=\"Secure your account to create\"\n description=\"Publish your creative work as a single-copy NFT in a collection you own.\"\n >\n <TransactionDialog tx={tx} title=\"Mint NFT\" workingLabel=\"Minting your work…\" firstStepLabel=\"Upload to IPFS\">\n <TransactionSuccess\n name={form.getValues(\"name\") || \"Your asset\"}\n image={imagePreview}\n title=\"Asset minted\"\n description=\"Your wallet is the owner. The license terms and royalty are recorded in its metadata.\"\n actions={[\n ...(mintedHref ? [{ href: mintedHref, label: \"View asset\" }] : []),\n { href: \"/portfolio/assets\", label: \"View portfolio\" },\n { label: \"Mint another\", onClick: handleAgain },\n ]}\n >\n <RewardEarned actionType=\"mint_asset\" />\n </TransactionSuccess>\n </TransactionDialog>\n\n <ClaimRouteShell\n icon={<ImagePlus className=\"h-4 w-4 text-white\" />}\n title=\"Mint NFT\"\n subtitle=\"Publish your creative work as a single-copy NFT in a collection you own — free to mint, and it's yours.\"\n aside={\n <>\n <MedialaneCollectionCard\n image={imagePreview}\n name={form.watch(\"name\")}\n collection={selectedCollection?.name || \"IP Asset\"}\n creator={walletAddress ? `${walletAddress.slice(0, 6)}…${walletAddress.slice(-4)}` : undefined}\n creatorHref={walletAddress ? profileHref({ address: walletAddress }) : undefined}\n />\n {aside}\n </>\n }\n >\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-6\">\n <FormField control={form.control} name=\"collectionId\" render={({ field }) => (\n <FormItem>\n <FormLabel className=\"flex items-center gap-1.5\"><Boxes className=\"h-4 w-4\" />Collection *</FormLabel>\n <CollectionPicker\n collections={collections}\n loading={collectionsLoading}\n value={field.value}\n onChange={field.onChange}\n newCollectionHref=\"/launchpad/single-editions/collection\"\n />\n <FormMessage />\n </FormItem>\n )} />\n\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\">Cover image</label>\n <div\n className=\"border-2 border-dashed border-border rounded-xl p-8 text-center cursor-pointer hover:border-primary/50 transition-colors\"\n role=\"button\"\n tabIndex={0}\n aria-label=\"Upload image\"\n onClick={() => imageInputRef.current?.click()}\n onKeyDown={(e) => { if (e.key === \"Enter\" || e.key === \" \") { e.preventDefault(); imageInputRef.current?.click(); } }}\n >\n {imagePreview ? (\n <div className=\"relative mx-auto h-48 w-48 overflow-hidden rounded-lg\">\n <Image src={imagePreview} alt=\"Preview\" fill unoptimized className=\"object-cover\" />\n </div>\n ) : (\n <div className=\"flex flex-col items-center gap-2 text-muted-foreground\">\n <Upload className=\"h-8 w-8\" />\n <p className=\"text-sm\">Click to upload (JPG, PNG, GIF, SVG, WebP)</p>\n </div>\n )}\n <input\n ref={imageInputRef}\n type=\"file\"\n accept={acceptFor(\"image\")}\n className=\"hidden\"\n onChange={(e) => {\n const file = e.target.files?.[0];\n if (!file) return;\n const fileError = uploadError(file, \"image\");\n if (fileError) {\n form.setError(\"image\", { message: fileError });\n e.target.value = \"\";\n return;\n }\n form.clearErrors(\"image\");\n setImageFile(file);\n form.setValue(\"image\", file);\n if (previewUrlRef.current) URL.revokeObjectURL(previewUrlRef.current);\n const objectUrl = URL.createObjectURL(file);\n previewUrlRef.current = objectUrl;\n setImagePreview(objectUrl);\n }}\n />\n </div>\n {form.formState.errors.image && <p role=\"alert\" className=\"text-sm text-destructive\">{form.formState.errors.image.message}</p>}\n </div>\n\n <FormField control={form.control} name=\"name\" render={({ field }) => (\n <FormItem>\n <FormLabel>Name *</FormLabel>\n <FormControl><Input placeholder=\"My Creative Work\" {...field} /></FormControl>\n <FormMessage />\n </FormItem>\n )} />\n\n <FormField control={form.control} name=\"description\" render={({ field }) => (\n <FormItem>\n <FormLabel>Description</FormLabel>\n <FormControl><Textarea placeholder=\"Describe your work, its story, and any context for buyers…\" rows={4} {...field} /></FormControl>\n <FormMessage />\n </FormItem>\n )} />\n\n <FormField control={form.control} name=\"external_url\" render={({ field }) => (\n <FormItem>\n <FormLabel>External link <span className=\"text-muted-foreground font-normal\">(optional)</span></FormLabel>\n <FormControl><Input placeholder=\"https://yourwebsite.com\" {...field} /></FormControl>\n <FormMessage />\n </FormItem>\n )} />\n\n <CollapsibleSection\n open={licensingOpen}\n onOpenChange={setLicensingOpen}\n icon={<ShieldCheck className=\"h-4 w-4 text-primary\" />}\n label=\"Licensing Terms\"\n hint=\"Optional · Berne Convention\"\n >\n <p className=\"text-xs text-muted-foreground\">Set how others can use your work. These terms are saved permanently with it as proof of authorship.</p>\n <FormField control={form.control} name=\"licenseType\" render={({ field }) => (\n <FormItem>\n <FormLabel>License</FormLabel>\n <Select value={field.value} onValueChange={handleLicenseChange}>\n <FormControl><SelectTrigger><SelectValue /></SelectTrigger></FormControl>\n <SelectContent>{LICENSE_TYPES.map((l) => <SelectItem key={l.value} value={l.value}>{l.label}</SelectItem>)}</SelectContent>\n </Select>\n {(() => { const def = LICENSE_TYPES.find((l) => l.value === field.value); return def ? <p className=\"text-xs text-muted-foreground mt-1\">{def.description}</p> : null; })()}\n <FormMessage />\n </FormItem>\n )} />\n <FormField control={form.control} name=\"commercialUse\" render={({ field }) => (\n <FormItem><FormLabel>Commercial Use</FormLabel><ToggleGroup value={field.value} options={[\"Yes\", \"No\"]} onChange={field.onChange} /></FormItem>\n )} />\n <FormField control={form.control} name=\"derivatives\" render={({ field }) => (\n <FormItem><FormLabel>Derivatives</FormLabel><ToggleGroup value={field.value} options={DERIVATIVES_OPTIONS} onChange={field.onChange} /></FormItem>\n )} />\n <FormField control={form.control} name=\"attribution\" render={({ field }) => (\n <FormItem><FormLabel>Attribution</FormLabel><ToggleGroup value={field.value} options={[\"Required\", \"Not Required\"]} onChange={field.onChange} /></FormItem>\n )} />\n <Collapsible open={advancedOpen} onOpenChange={setAdvancedOpen}>\n <CollapsibleTrigger asChild>\n <button type=\"button\" className=\"flex items-center gap-1.5 text-xs text-muted-foreground hover:text-foreground transition-colors\">\n <ChevronDown className={cn(\"h-3.5 w-3.5 transition-transform\", advancedOpen && \"rotate-180\")} />\n Advanced options\n </button>\n </CollapsibleTrigger>\n <CollapsibleContent className=\"space-y-4 pt-3\">\n <FormField control={form.control} name=\"geographicScope\" render={({ field }) => (\n <FormItem>\n <FormLabel>Territory</FormLabel>\n <FormControl><Input placeholder=\"Worldwide\" {...field} /></FormControl>\n </FormItem>\n )} />\n <FormField control={form.control} name=\"aiPolicy\" render={({ field }) => (\n <FormItem><FormLabel>AI & Data Mining</FormLabel><ToggleGroup value={field.value} options={AI_POLICIES} onChange={field.onChange} /></FormItem>\n )} />\n <FormField control={form.control} name=\"royalty\" render={({ field }) => (\n <FormItem>\n <FormLabel>Royalty % (0–50)</FormLabel>\n <FormControl>\n <Input type=\"number\" min={0} max={50} step={0.5} placeholder=\"0\" {...field} onChange={(e) => field.onChange(parseFloat(e.target.value) || 0)} />\n </FormControl>\n <FormMessage />\n </FormItem>\n )} />\n </CollapsibleContent>\n </Collapsible>\n </CollapsibleSection>\n\n <CollapsibleSection\n open={ipTypeOpen}\n onOpenChange={setIpTypeOpen}\n icon={<Layers className=\"h-4 w-4 text-primary\" />}\n label=\"IP Type & Metadata\"\n hint=\"Optional\"\n >\n <p className=\"text-xs text-muted-foreground\">Choose a content type, fill suggested metadata, or add your own trait pairs.</p>\n <FormField control={form.control} name=\"ipType\" render={({ field }) => (\n <FormItem>\n <FormLabel>IP Type</FormLabel>\n <Select onValueChange={field.onChange} value={field.value}>\n <FormControl><SelectTrigger><SelectValue /></SelectTrigger></FormControl>\n <SelectContent>{IP_TYPES.map((t) => <SelectItem key={t} value={t}>{t}</SelectItem>)}</SelectContent>\n </Select>\n </FormItem>\n )} />\n <IPTypeFields\n key={metadataResetKey}\n ipType={form.watch(\"ipType\") as IPType}\n onChange={(fields) => { metadataFieldsRef.current = fields; }}\n uploadDocument={uploadDocument}\n />\n </CollapsibleSection>\n\n <button\n type=\"submit\"\n disabled={busy}\n className={`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 ${busy ? \"opacity-40 pointer-events-none\" : \"\"}`}\n >\n Mint NFT\n </button>\n <p className=\"text-xs text-center text-muted-foreground\">Free to mint — protocol fee is zero.</p>\n </form>\n </Form>\n </ClaimRouteShell>\n </WalletRequired>\n );\n}\n"],"mappings":"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","names":["Image"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/launchpad/single-edition-mint.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport * as z from \"zod\";\nimport { Boxes, ChevronDown, ImagePlus, Layers, ShieldCheck, Upload } from \"lucide-react\";\nimport { assetHref, collectionHref, getService, profileHref } from \"@medialane/sdk\";\nimport { acceptFor, uploadError } from \"../../utils/upload-limits.js\";\nimport { FIELD_LIMITS } from \"../../utils/field-limits.js\";\nimport { mintedTokenIdFromReceipt } from \"@medialane/sdk/starknet\";\nimport Image from \"../image.js\";\nimport { Input } from \"../input.js\";\nimport { Textarea } from \"../textarea.js\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"../select.js\";\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"../collapsible.js\";\nimport { CollapsibleSection } from \"../collapsible-section.js\";\nimport { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from \"../form.js\";\nimport { ToggleGroup } from \"../create-form-primitives.js\";\nimport { IPTypeFields } from \"../ip-type-fields.js\";\nimport { ClaimRouteShell } from \"../claim-route-shell.js\";\nimport { TransactionSuccess } from \"../transaction-success.js\";\nimport { MedialaneCollectionCard } from \"../medialane-collection-card.js\";\nimport { TransactionDialog } from \"../transaction-dialog.js\";\nimport { WalletRequired } from \"../wallet-required.js\";\nimport { useMedialaneApp } from \"../medialane-app.js\";\nimport { RewardEarned } from \"../rewards/reward-earned.js\";\nimport { CollectionPicker } from \"./collection-picker.js\";\nimport { AI_POLICIES, DERIVATIVES_OPTIONS, IP_TYPES, LICENSE_TYPES, type IPType } from \"../../data/ip.js\";\nimport { cn } from \"../../utils/cn.js\";\nimport { runIntentCalls } from \"../../utils/run-intent-calls.js\";\nimport { pinAssetMetadata, uploadFileToIpfs } from \"../../utils/ipfs-upload.js\";\nimport { useCollectionsByOwner } from \"../../utils/use-collections.js\";\nimport { useTransaction } from \"../../utils/use-transaction.js\";\nimport { invalidatePortfolioCache } from \"../../utils/portfolio-cache.js\";\nimport type { MetadataField } from \"../ip-type-fields.js\";\n\nconst schema = z.object({\n collectionId: z.string().min(1, \"Select a collection\"),\n name: z.string().min(1, \"Name required\").max(FIELD_LIMITS.name),\n description: z.string().max(FIELD_LIMITS.description).optional(),\n external_url: z\n .string()\n .max(500)\n .refine((v) => !v || v.startsWith(\"http://\") || v.startsWith(\"https://\"), { message: \"Must start with http:// or https://\" })\n .optional(),\n ipType: z.enum(IP_TYPES),\n licenseType: z.string().min(1, \"License required\"),\n commercialUse: z.enum([\"Yes\", \"No\"]),\n derivatives: z.enum([\"Allowed\", \"Not Allowed\", \"Share-Alike\"]),\n attribution: z.enum([\"Required\", \"Not Required\"]),\n geographicScope: z.string(),\n aiPolicy: z.enum([\"Allowed\", \"Not Allowed\", \"Training Only\"]),\n royalty: z.coerce.number().min(0).max(50),\n image: z.instanceof(File).optional(),\n});\ntype FormValues = z.infer<typeof schema>;\n\nconst DEFAULTS: FormValues = {\n collectionId: \"\",\n name: \"\",\n description: \"\",\n external_url: \"\",\n ipType: \"NFT\",\n licenseType: \"CC BY-SA\",\n commercialUse: \"Yes\",\n derivatives: \"Share-Alike\",\n attribution: \"Required\",\n geographicScope: \"Worldwide\",\n aiPolicy: \"Allowed\",\n royalty: 0,\n};\n\nfunction suggestedExternalUrl(collection: { contractAddress?: string | null } | null): string {\n return collection?.contractAddress ? `https://medialane.io${collectionHref(\"STARKNET\", collection.contractAddress)}` : \"\";\n}\n\nexport function SingleEditionMint({ aside }: { aside?: ReactNode }) {\n const app = useMedialaneApp();\n const walletAddress = app.walletAddress;\n const tx = useTransaction();\n const { collections: allCollections, isLoading: collectionsLoading } = useCollectionsByOwner(walletAddress ?? null);\n const collections = allCollections.filter((c) => getService(c.service)?.id === \"mip-erc721\" && c.collectionId != null);\n\n const [imageFile, setImageFile] = useState<File | null>(null);\n const [imagePreview, setImagePreview] = useState<string | null>(null);\n const [advancedOpen, setAdvancedOpen] = useState(false);\n const [licensingOpen, setLicensingOpen] = useState(false);\n const [ipTypeOpen, setIpTypeOpen] = useState(false);\n const [metadataResetKey, setMetadataResetKey] = useState(0);\n const metadataFieldsRef = useRef<MetadataField[]>([]);\n const previewUrlRef = useRef<string | null>(null);\n const imageInputRef = useRef<HTMLInputElement | null>(null);\n\n useEffect(() => {\n return () => {\n if (previewUrlRef.current) URL.revokeObjectURL(previewUrlRef.current);\n };\n }, []);\n\n const form = useForm<FormValues>({ resolver: zodResolver(schema), defaultValues: DEFAULTS });\n const selectedCollectionId = form.watch(\"collectionId\");\n const selectedCollection = collections.find((c) => c.collectionId === selectedCollectionId) ?? null;\n\n useEffect(() => {\n if (collections.length > 0 && !form.getValues(\"collectionId\")) form.setValue(\"collectionId\", collections[0]!.collectionId!);\n }, [collections, form]);\n\n const suggestedUrl = suggestedExternalUrl(selectedCollection);\n const autoUrlRef = useRef(\"\");\n\n useEffect(() => {\n if (!suggestedUrl) return;\n const current = form.getValues(\"external_url\");\n if (!current || current === autoUrlRef.current) {\n form.setValue(\"external_url\", suggestedUrl);\n autoUrlRef.current = suggestedUrl;\n }\n }, [suggestedUrl, form]);\n\n const handleLicenseChange = (value: string) => {\n form.setValue(\"licenseType\", value);\n const def = LICENSE_TYPES.find((l) => l.value === value);\n if (def) {\n form.setValue(\"commercialUse\", def.commercialUse);\n form.setValue(\"derivatives\", def.derivatives);\n form.setValue(\"attribution\", def.attribution);\n }\n };\n\n const uploadDocument = async (file: File) => {\n await app.ensureSignedIn?.();\n return (await uploadFileToIpfs(app.getClient().api, file, \"document\")).uri;\n };\n\n const handleAgain = () => {\n tx.reset();\n const first = collections[0] ?? null;\n autoUrlRef.current = suggestedExternalUrl(first);\n form.reset({ ...DEFAULTS, collectionId: first?.collectionId ?? \"\", external_url: autoUrlRef.current });\n metadataFieldsRef.current = [];\n setMetadataResetKey((key) => key + 1);\n setImageFile(null);\n setImagePreview(null);\n if (imageInputRef.current) imageInputRef.current.value = \"\";\n };\n\n const onSubmit = (values: FormValues) => {\n if (!walletAddress) return;\n void tx.run(async (signer) => {\n await app.ensureSignedIn?.();\n const api = app.getClient().api;\n const pinned = await pinAssetMetadata(api, {\n name: values.name,\n description: values.description ?? \"\",\n externalUrl: values.external_url,\n creator: walletAddress,\n ipType: values.ipType,\n licenseType: values.licenseType,\n commercialUse: values.commercialUse,\n derivatives: values.derivatives,\n attribution: values.attribution,\n geographicScope: values.geographicScope,\n aiPolicy: values.aiPolicy,\n royalty: String(values.royalty),\n imageFile,\n templateTraits: metadataFieldsRef.current.filter((f) => f.traitType.trim() && f.value.trim()).map((f) => ({ traitType: f.traitType.trim(), value: f.value.trim() })),\n });\n await runIntentCalls(signer, () =>\n api.intents.create(\"mint\", {\n owner: walletAddress,\n collectionId: values.collectionId,\n recipient: walletAddress,\n tokenUri: pinned.uri,\n royaltyBps: Math.round(values.royalty * 100),\n }),\n );\n invalidatePortfolioCache(walletAddress);\n });\n };\n\n const mintedTokenId = tx.receipt && selectedCollection ? mintedTokenIdFromReceipt(tx.receipt, selectedCollection.contractAddress) : null;\n const mintedHref = mintedTokenId && selectedCollection ? assetHref(\"STARKNET\", selectedCollection.contractAddress, mintedTokenId) : null;\n const busy = tx.phase !== \"idle\" || collectionsLoading || collections.length === 0;\n\n return (\n <WalletRequired\n icon={ImagePlus}\n iconClassName=\"text-brand-blue\"\n title=\"Secure your account to create\"\n description=\"Publish your creative work as a single-copy NFT in a collection you own.\"\n >\n <TransactionDialog tx={tx} title=\"Mint NFT\" workingLabel=\"Minting your work…\" firstStepLabel=\"Upload to IPFS\">\n <TransactionSuccess\n name={form.getValues(\"name\") || \"Your asset\"}\n image={imagePreview}\n title=\"Asset minted\"\n description=\"Your wallet is the owner. The license terms and royalty are recorded in its metadata.\"\n actions={[\n ...(mintedHref ? [{ href: mintedHref, label: \"View asset\" }] : []),\n { href: \"/portfolio/assets\", label: \"View portfolio\" },\n { label: \"Mint another\", onClick: handleAgain },\n ]}\n >\n <RewardEarned actionType=\"mint_asset\" />\n </TransactionSuccess>\n </TransactionDialog>\n\n <ClaimRouteShell\n icon={<ImagePlus className=\"h-4 w-4 text-white\" />}\n title=\"Mint NFT\"\n subtitle=\"Publish your creative work as a single-copy NFT in a collection you own — free to mint, and it's yours.\"\n aside={\n <>\n <MedialaneCollectionCard\n image={imagePreview}\n name={form.watch(\"name\")}\n collection={selectedCollection?.name || \"IP Asset\"}\n creator={walletAddress ? `${walletAddress.slice(0, 6)}…${walletAddress.slice(-4)}` : undefined}\n creatorHref={walletAddress ? profileHref({ address: walletAddress }) : undefined}\n />\n {aside}\n </>\n }\n >\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-6\">\n <FormField control={form.control} name=\"collectionId\" render={({ field }) => (\n <FormItem>\n <FormLabel className=\"flex items-center gap-1.5\"><Boxes className=\"h-4 w-4\" />Collection *</FormLabel>\n <CollectionPicker\n collections={collections}\n loading={collectionsLoading}\n value={field.value}\n onChange={field.onChange}\n newCollectionHref=\"/launchpad/single-editions/collection\"\n />\n <FormMessage />\n </FormItem>\n )} />\n\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\">Cover image</label>\n <div\n className=\"border-2 border-dashed border-border rounded-xl p-8 text-center cursor-pointer hover:border-primary/50 transition-colors\"\n role=\"button\"\n tabIndex={0}\n aria-label=\"Upload image\"\n onClick={() => imageInputRef.current?.click()}\n onKeyDown={(e) => { if (e.key === \"Enter\" || e.key === \" \") { e.preventDefault(); imageInputRef.current?.click(); } }}\n >\n {imagePreview ? (\n <div className=\"relative mx-auto h-48 w-48 overflow-hidden rounded-lg\">\n <Image src={imagePreview} alt=\"Preview\" fill unoptimized className=\"object-cover\" />\n </div>\n ) : (\n <div className=\"flex flex-col items-center gap-2 text-muted-foreground\">\n <Upload className=\"h-8 w-8\" />\n <p className=\"text-sm\">Click to upload (JPG, PNG, GIF, SVG, WebP)</p>\n </div>\n )}\n <input\n ref={imageInputRef}\n type=\"file\"\n accept={acceptFor(\"image\")}\n className=\"hidden\"\n onChange={(e) => {\n const file = e.target.files?.[0];\n if (!file) return;\n const fileError = uploadError(file, \"image\");\n if (fileError) {\n form.setError(\"image\", { message: fileError });\n e.target.value = \"\";\n return;\n }\n form.clearErrors(\"image\");\n setImageFile(file);\n form.setValue(\"image\", file);\n if (previewUrlRef.current) URL.revokeObjectURL(previewUrlRef.current);\n const objectUrl = URL.createObjectURL(file);\n previewUrlRef.current = objectUrl;\n setImagePreview(objectUrl);\n }}\n />\n </div>\n {form.formState.errors.image && <p role=\"alert\" className=\"text-sm text-destructive\">{form.formState.errors.image.message}</p>}\n </div>\n\n <FormField control={form.control} name=\"name\" render={({ field }) => (\n <FormItem>\n <FormLabel>Name *</FormLabel>\n <FormControl><Input placeholder=\"My Creative Work\" {...field} /></FormControl>\n <FormMessage />\n </FormItem>\n )} />\n\n <FormField control={form.control} name=\"description\" render={({ field }) => (\n <FormItem>\n <FormLabel>Description</FormLabel>\n <FormControl><Textarea placeholder=\"Describe your work, its story, and any context for buyers…\" rows={4} {...field} /></FormControl>\n <FormMessage />\n </FormItem>\n )} />\n\n <FormField control={form.control} name=\"external_url\" render={({ field }) => (\n <FormItem>\n <FormLabel>External link <span className=\"text-muted-foreground font-normal\">(optional)</span></FormLabel>\n <FormControl><Input placeholder=\"https://yourwebsite.com\" {...field} /></FormControl>\n <FormMessage />\n </FormItem>\n )} />\n\n <CollapsibleSection\n open={licensingOpen}\n onOpenChange={setLicensingOpen}\n icon={<ShieldCheck className=\"h-4 w-4 text-primary\" />}\n label=\"Licensing Terms\"\n hint=\"Optional · Berne Convention\"\n >\n <p className=\"text-xs text-muted-foreground\">Set how others can use your work. These terms are saved permanently with it as proof of authorship.</p>\n <FormField control={form.control} name=\"licenseType\" render={({ field }) => (\n <FormItem>\n <FormLabel>License</FormLabel>\n <Select value={field.value} onValueChange={handleLicenseChange}>\n <FormControl><SelectTrigger><SelectValue /></SelectTrigger></FormControl>\n <SelectContent>{LICENSE_TYPES.map((l) => <SelectItem key={l.value} value={l.value}>{l.label}</SelectItem>)}</SelectContent>\n </Select>\n {(() => { const def = LICENSE_TYPES.find((l) => l.value === field.value); return def ? <p className=\"text-xs text-muted-foreground mt-1\">{def.description}</p> : null; })()}\n <FormMessage />\n </FormItem>\n )} />\n <FormField control={form.control} name=\"commercialUse\" render={({ field }) => (\n <FormItem><FormLabel>Commercial Use</FormLabel><ToggleGroup value={field.value} options={[\"Yes\", \"No\"]} onChange={field.onChange} /></FormItem>\n )} />\n <FormField control={form.control} name=\"derivatives\" render={({ field }) => (\n <FormItem><FormLabel>Derivatives</FormLabel><ToggleGroup value={field.value} options={DERIVATIVES_OPTIONS} onChange={field.onChange} /></FormItem>\n )} />\n <FormField control={form.control} name=\"attribution\" render={({ field }) => (\n <FormItem><FormLabel>Attribution</FormLabel><ToggleGroup value={field.value} options={[\"Required\", \"Not Required\"]} onChange={field.onChange} /></FormItem>\n )} />\n <Collapsible open={advancedOpen} onOpenChange={setAdvancedOpen}>\n <CollapsibleTrigger asChild>\n <button type=\"button\" className=\"flex items-center gap-1.5 text-xs text-muted-foreground hover:text-foreground transition-colors\">\n <ChevronDown className={cn(\"h-3.5 w-3.5 transition-transform\", advancedOpen && \"rotate-180\")} />\n Advanced options\n </button>\n </CollapsibleTrigger>\n <CollapsibleContent className=\"space-y-4 pt-3\">\n <FormField control={form.control} name=\"geographicScope\" render={({ field }) => (\n <FormItem>\n <FormLabel>Territory</FormLabel>\n <FormControl><Input placeholder=\"Worldwide\" {...field} /></FormControl>\n </FormItem>\n )} />\n <FormField control={form.control} name=\"aiPolicy\" render={({ field }) => (\n <FormItem><FormLabel>AI & Data Mining</FormLabel><ToggleGroup value={field.value} options={AI_POLICIES} onChange={field.onChange} /></FormItem>\n )} />\n <FormField control={form.control} name=\"royalty\" render={({ field }) => (\n <FormItem>\n <FormLabel>Royalty % (0–50)</FormLabel>\n <FormControl>\n <Input type=\"number\" min={0} max={50} step={0.5} placeholder=\"0\" {...field} onChange={(e) => field.onChange(parseFloat(e.target.value) || 0)} />\n </FormControl>\n <FormMessage />\n </FormItem>\n )} />\n </CollapsibleContent>\n </Collapsible>\n </CollapsibleSection>\n\n <CollapsibleSection\n open={ipTypeOpen}\n onOpenChange={setIpTypeOpen}\n icon={<Layers className=\"h-4 w-4 text-primary\" />}\n label=\"IP Type & Metadata\"\n hint=\"Optional\"\n >\n <p className=\"text-xs text-muted-foreground\">Choose a content type, fill suggested metadata, or add your own trait pairs.</p>\n <FormField control={form.control} name=\"ipType\" render={({ field }) => (\n <FormItem>\n <FormLabel>IP Type</FormLabel>\n <Select onValueChange={field.onChange} value={field.value}>\n <FormControl><SelectTrigger><SelectValue /></SelectTrigger></FormControl>\n <SelectContent>{IP_TYPES.map((t) => <SelectItem key={t} value={t}>{t}</SelectItem>)}</SelectContent>\n </Select>\n </FormItem>\n )} />\n <IPTypeFields\n key={metadataResetKey}\n ipType={form.watch(\"ipType\") as IPType}\n onChange={(fields) => { metadataFieldsRef.current = fields; }}\n uploadDocument={uploadDocument}\n />\n </CollapsibleSection>\n\n <button\n type=\"submit\"\n disabled={busy}\n className={`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 ${busy ? \"opacity-40 pointer-events-none\" : \"\"}`}\n >\n Mint NFT\n </button>\n <p className=\"text-xs text-center text-muted-foreground\">Free to mint — protocol fee is zero.</p>\n </form>\n </Form>\n </ClaimRouteShell>\n </WalletRequired>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA4MU;AA1MV,mBAA4D;AAC5D,6BAAwB;AACxB,iBAA4B;AAC5B,QAAmB;AACnB,0BAA2E;AAC3E,iBAAmE;AACnE,2BAAuC;AACvC,0BAA6B;AAC7B,sBAAyC;AACzC,mBAAkB;AAClB,mBAAsB;AACtB,sBAAyB;AACzB,oBAA8E;AAC9E,yBAAoE;AACpE,iCAAmC;AACnC,kBAA+E;AAC/E,oCAA4B;AAC5B,4BAA6B;AAC7B,+BAAgC;AAChC,iCAAmC;AACnC,uCAAwC;AACxC,gCAAkC;AAClC,6BAA+B;AAC/B,2BAAgC;AAChC,2BAA6B;AAC7B,+BAAiC;AACjC,gBAAuF;AACvF,gBAAmB;AACnB,8BAA+B;AAC/B,yBAAmD;AACnD,6BAAsC;AACtC,6BAA+B;AAC/B,6BAAyC;AAGzC,MAAM,SAAS,EAAE,OAAO;AAAA,EACtB,cAAc,EAAE,OAAO,EAAE,IAAI,GAAG,qBAAqB;AAAA,EACrD,MAAM,EAAE,OAAO,EAAE,IAAI,GAAG,eAAe,EAAE,IAAI,iCAAa,IAAI;AAAA,EAC9D,aAAa,EAAE,OAAO,EAAE,IAAI,iCAAa,WAAW,EAAE,SAAS;AAAA,EAC/D,cAAc,EACX,OAAO,EACP,IAAI,GAAG,EACP,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,SAAS,KAAK,EAAE,WAAW,UAAU,GAAG,EAAE,SAAS,sCAAsC,CAAC,EAC3H,SAAS;AAAA,EACZ,QAAQ,EAAE,KAAK,kBAAQ;AAAA,EACvB,aAAa,EAAE,OAAO,EAAE,IAAI,GAAG,kBAAkB;AAAA,EACjD,eAAe,EAAE,KAAK,CAAC,OAAO,IAAI,CAAC;AAAA,EACnC,aAAa,EAAE,KAAK,CAAC,WAAW,eAAe,aAAa,CAAC;AAAA,EAC7D,aAAa,EAAE,KAAK,CAAC,YAAY,cAAc,CAAC;AAAA,EAChD,iBAAiB,EAAE,OAAO;AAAA,EAC1B,UAAU,EAAE,KAAK,CAAC,WAAW,eAAe,eAAe,CAAC;AAAA,EAC5D,SAAS,EAAE,OAAO,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE;AAAA,EACxC,OAAO,EAAE,WAAW,IAAI,EAAE,SAAS;AACrC,CAAC;AAGD,MAAM,WAAuB;AAAA,EAC3B,cAAc;AAAA,EACd,MAAM;AAAA,EACN,aAAa;AAAA,EACb,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,eAAe;AAAA,EACf,aAAa;AAAA,EACb,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,UAAU;AAAA,EACV,SAAS;AACX;AAEA,SAAS,qBAAqB,YAAgE;AAC5F,SAAO,YAAY,kBAAkB,2BAAuB,2BAAe,YAAY,WAAW,eAAe,CAAC,KAAK;AACzH;AAEO,SAAS,kBAAkB,EAAE,MAAM,GAA0B;AAClE,QAAM,UAAM,sCAAgB;AAC5B,QAAM,gBAAgB,IAAI;AAC1B,QAAM,SAAK,uCAAe;AAC1B,QAAM,EAAE,aAAa,gBAAgB,WAAW,mBAAmB,QAAI,8CAAsB,iBAAiB,IAAI;AAClH,QAAM,cAAc,eAAe,OAAO,CAAC,UAAM,uBAAW,EAAE,OAAO,GAAG,OAAO,gBAAgB,EAAE,gBAAgB,IAAI;AAErH,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAsB,IAAI;AAC5D,QAAM,CAAC,cAAc,eAAe,QAAI,uBAAwB,IAAI;AACpE,QAAM,CAAC,cAAc,eAAe,QAAI,uBAAS,KAAK;AACtD,QAAM,CAAC,eAAe,gBAAgB,QAAI,uBAAS,KAAK;AACxD,QAAM,CAAC,YAAY,aAAa,QAAI,uBAAS,KAAK;AAClD,QAAM,CAAC,kBAAkB,mBAAmB,QAAI,uBAAS,CAAC;AAC1D,QAAM,wBAAoB,qBAAwB,CAAC,CAAC;AACpD,QAAM,oBAAgB,qBAAsB,IAAI;AAChD,QAAM,oBAAgB,qBAAgC,IAAI;AAE1D,8BAAU,MAAM;AACd,WAAO,MAAM;AACX,UAAI,cAAc,QAAS,KAAI,gBAAgB,cAAc,OAAO;AAAA,IACtE;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,WAAO,gCAAoB,EAAE,cAAU,wBAAY,MAAM,GAAG,eAAe,SAAS,CAAC;AAC3F,QAAM,uBAAuB,KAAK,MAAM,cAAc;AACtD,QAAM,qBAAqB,YAAY,KAAK,CAAC,MAAM,EAAE,iBAAiB,oBAAoB,KAAK;AAE/F,8BAAU,MAAM;AACd,QAAI,YAAY,SAAS,KAAK,CAAC,KAAK,UAAU,cAAc,EAAG,MAAK,SAAS,gBAAgB,YAAY,CAAC,EAAG,YAAa;AAAA,EAC5H,GAAG,CAAC,aAAa,IAAI,CAAC;AAEtB,QAAM,eAAe,qBAAqB,kBAAkB;AAC5D,QAAM,iBAAa,qBAAO,EAAE;AAE5B,8BAAU,MAAM;AACd,QAAI,CAAC,aAAc;AACnB,UAAM,UAAU,KAAK,UAAU,cAAc;AAC7C,QAAI,CAAC,WAAW,YAAY,WAAW,SAAS;AAC9C,WAAK,SAAS,gBAAgB,YAAY;AAC1C,iBAAW,UAAU;AAAA,IACvB;AAAA,EACF,GAAG,CAAC,cAAc,IAAI,CAAC;AAEvB,QAAM,sBAAsB,CAAC,UAAkB;AAC7C,SAAK,SAAS,eAAe,KAAK;AAClC,UAAM,MAAM,wBAAc,KAAK,CAAC,MAAM,EAAE,UAAU,KAAK;AACvD,QAAI,KAAK;AACP,WAAK,SAAS,iBAAiB,IAAI,aAAa;AAChD,WAAK,SAAS,eAAe,IAAI,WAAW;AAC5C,WAAK,SAAS,eAAe,IAAI,WAAW;AAAA,IAC9C;AAAA,EACF;AAEA,QAAM,iBAAiB,OAAO,SAAe;AAC3C,UAAM,IAAI,iBAAiB;AAC3B,YAAQ,UAAM,qCAAiB,IAAI,UAAU,EAAE,KAAK,MAAM,UAAU,GAAG;AAAA,EACzE;AAEA,QAAM,cAAc,MAAM;AACxB,OAAG,MAAM;AACT,UAAM,QAAQ,YAAY,CAAC,KAAK;AAChC,eAAW,UAAU,qBAAqB,KAAK;AAC/C,SAAK,MAAM,EAAE,GAAG,UAAU,cAAc,OAAO,gBAAgB,IAAI,cAAc,WAAW,QAAQ,CAAC;AACrG,sBAAkB,UAAU,CAAC;AAC7B,wBAAoB,CAAC,QAAQ,MAAM,CAAC;AACpC,iBAAa,IAAI;AACjB,oBAAgB,IAAI;AACpB,QAAI,cAAc,QAAS,eAAc,QAAQ,QAAQ;AAAA,EAC3D;AAEA,QAAM,WAAW,CAAC,WAAuB;AACvC,QAAI,CAAC,cAAe;AACpB,SAAK,GAAG,IAAI,OAAO,WAAW;AAC5B,YAAM,IAAI,iBAAiB;AAC3B,YAAM,MAAM,IAAI,UAAU,EAAE;AAC5B,YAAM,SAAS,UAAM,qCAAiB,KAAK;AAAA,QACzC,MAAM,OAAO;AAAA,QACb,aAAa,OAAO,eAAe;AAAA,QACnC,aAAa,OAAO;AAAA,QACpB,SAAS;AAAA,QACT,QAAQ,OAAO;AAAA,QACf,aAAa,OAAO;AAAA,QACpB,eAAe,OAAO;AAAA,QACtB,aAAa,OAAO;AAAA,QACpB,aAAa,OAAO;AAAA,QACpB,iBAAiB,OAAO;AAAA,QACxB,UAAU,OAAO;AAAA,QACjB,SAAS,OAAO,OAAO,OAAO;AAAA,QAC9B;AAAA,QACA,gBAAgB,kBAAkB,QAAQ,OAAO,CAAC,MAAM,EAAE,UAAU,KAAK,KAAK,EAAE,MAAM,KAAK,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,KAAK,GAAG,OAAO,EAAE,MAAM,KAAK,EAAE,EAAE;AAAA,MACrK,CAAC;AACD,gBAAM;AAAA,QAAe;AAAA,QAAQ,MAC3B,IAAI,QAAQ,OAAO,QAAQ;AAAA,UACzB,OAAO;AAAA,UACP,cAAc,OAAO;AAAA,UACrB,WAAW;AAAA,UACX,UAAU,OAAO;AAAA,UACjB,YAAY,KAAK,MAAM,OAAO,UAAU,GAAG;AAAA,QAC7C,CAAC;AAAA,MACH;AACA,2DAAyB,aAAa;AAAA,IACxC,CAAC;AAAA,EACH;AAEA,QAAM,gBAAgB,GAAG,WAAW,yBAAqB,0CAAyB,GAAG,SAAS,mBAAmB,eAAe,IAAI;AACpI,QAAM,aAAa,iBAAiB,yBAAqB,sBAAU,YAAY,mBAAmB,iBAAiB,aAAa,IAAI;AACpI,QAAM,OAAO,GAAG,UAAU,UAAU,sBAAsB,YAAY,WAAW;AAEjF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAM;AAAA,MACN,eAAc;AAAA,MACd,OAAM;AAAA,MACN,aAAY;AAAA,MAEZ;AAAA,oDAAC,+CAAkB,IAAQ,OAAM,YAAW,cAAa,2BAAqB,gBAAe,kBAC3F;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,KAAK,UAAU,MAAM,KAAK;AAAA,YAChC,OAAO;AAAA,YACP,OAAM;AAAA,YACN,aAAY;AAAA,YACZ,SAAS;AAAA,cACP,GAAI,aAAa,CAAC,EAAE,MAAM,YAAY,OAAO,aAAa,CAAC,IAAI,CAAC;AAAA,cAChE,EAAE,MAAM,qBAAqB,OAAO,iBAAiB;AAAA,cACrD,EAAE,OAAO,gBAAgB,SAAS,YAAY;AAAA,YAChD;AAAA,YAEA,sDAAC,qCAAa,YAAW,cAAa;AAAA;AAAA,QACxC,GACF;AAAA,QAEA;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,4CAAC,iCAAU,WAAU,sBAAqB;AAAA,YAChD,OAAM;AAAA,YACN,UAAS;AAAA,YACT,OACE,4EACE;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,kBACP,MAAM,KAAK,MAAM,MAAM;AAAA,kBACvB,YAAY,oBAAoB,QAAQ;AAAA,kBACxC,SAAS,gBAAgB,GAAG,cAAc,MAAM,GAAG,CAAC,CAAC,SAAI,cAAc,MAAM,EAAE,CAAC,KAAK;AAAA,kBACrF,aAAa,oBAAgB,wBAAY,EAAE,SAAS,cAAc,CAAC,IAAI;AAAA;AAAA,cACzE;AAAA,cACC;AAAA,eACH;AAAA,YAGF,sDAAC,oBAAM,GAAG,MACR,uDAAC,UAAK,UAAU,KAAK,aAAa,QAAQ,GAAG,WAAU,aACrD;AAAA,0DAAC,yBAAU,SAAS,KAAK,SAAS,MAAK,gBAAe,QAAQ,CAAC,EAAE,MAAM,MACrE,6CAAC,wBACC;AAAA,6DAAC,yBAAU,WAAU,6BAA4B;AAAA,8DAAC,6BAAM,WAAU,WAAU;AAAA,kBAAE;AAAA,mBAAY;AAAA,gBAC1F;AAAA,kBAAC;AAAA;AAAA,oBACC;AAAA,oBACA,SAAS;AAAA,oBACT,OAAO,MAAM;AAAA,oBACb,UAAU,MAAM;AAAA,oBAChB,mBAAkB;AAAA;AAAA,gBACpB;AAAA,gBACA,4CAAC,2BAAY;AAAA,iBACf,GACC;AAAA,cAEH,6CAAC,SAAI,WAAU,aACb;AAAA,4DAAC,WAAM,WAAU,uBAAsB,yBAAW;AAAA,gBAClD;AAAA,kBAAC;AAAA;AAAA,oBACC,WAAU;AAAA,oBACV,MAAK;AAAA,oBACL,UAAU;AAAA,oBACV,cAAW;AAAA,oBACX,SAAS,MAAM,cAAc,SAAS,MAAM;AAAA,oBAC5C,WAAW,CAAC,MAAM;AAAE,0BAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AAAE,0BAAE,eAAe;AAAG,sCAAc,SAAS,MAAM;AAAA,sBAAG;AAAA,oBAAE;AAAA,oBAEnH;AAAA,qCACC,4CAAC,SAAI,WAAU,yDACb,sDAAC,aAAAA,SAAA,EAAM,KAAK,cAAc,KAAI,WAAU,MAAI,MAAC,aAAW,MAAC,WAAU,gBAAe,GACpF,IAEA,6CAAC,SAAI,WAAU,0DACb;AAAA,oEAAC,8BAAO,WAAU,WAAU;AAAA,wBAC5B,4CAAC,OAAE,WAAU,WAAU,wDAA0C;AAAA,yBACnE;AAAA,sBAEF;AAAA,wBAAC;AAAA;AAAA,0BACC,KAAK;AAAA,0BACL,MAAK;AAAA,0BACL,YAAQ,gCAAU,OAAO;AAAA,0BACzB,WAAU;AAAA,0BACV,UAAU,CAAC,MAAM;AACf,kCAAM,OAAO,EAAE,OAAO,QAAQ,CAAC;AAC/B,gCAAI,CAAC,KAAM;AACX,kCAAM,gBAAY,kCAAY,MAAM,OAAO;AAC3C,gCAAI,WAAW;AACb,mCAAK,SAAS,SAAS,EAAE,SAAS,UAAU,CAAC;AAC7C,gCAAE,OAAO,QAAQ;AACjB;AAAA,4BACF;AACA,iCAAK,YAAY,OAAO;AACxB,yCAAa,IAAI;AACjB,iCAAK,SAAS,SAAS,IAAI;AAC3B,gCAAI,cAAc,QAAS,KAAI,gBAAgB,cAAc,OAAO;AACpE,kCAAM,YAAY,IAAI,gBAAgB,IAAI;AAC1C,0CAAc,UAAU;AACxB,4CAAgB,SAAS;AAAA,0BAC3B;AAAA;AAAA,sBACF;AAAA;AAAA;AAAA,gBACF;AAAA,gBACC,KAAK,UAAU,OAAO,SAAS,4CAAC,OAAE,MAAK,SAAQ,WAAU,4BAA4B,eAAK,UAAU,OAAO,MAAM,SAAQ;AAAA,iBAC5H;AAAA,cAEA,4CAAC,yBAAU,SAAS,KAAK,SAAS,MAAK,QAAO,QAAQ,CAAC,EAAE,MAAM,MAC7D,6CAAC,wBACC;AAAA,4DAAC,yBAAU,oBAAM;AAAA,gBACjB,4CAAC,2BAAY,sDAAC,sBAAM,aAAY,oBAAoB,GAAG,OAAO,GAAE;AAAA,gBAChE,4CAAC,2BAAY;AAAA,iBACf,GACC;AAAA,cAEH,4CAAC,yBAAU,SAAS,KAAK,SAAS,MAAK,eAAc,QAAQ,CAAC,EAAE,MAAM,MACpE,6CAAC,wBACC;AAAA,4DAAC,yBAAU,yBAAW;AAAA,gBACtB,4CAAC,2BAAY,sDAAC,4BAAS,aAAY,mEAA6D,MAAM,GAAI,GAAG,OAAO,GAAE;AAAA,gBACtH,4CAAC,2BAAY;AAAA,iBACf,GACC;AAAA,cAEH,4CAAC,yBAAU,SAAS,KAAK,SAAS,MAAK,gBAAe,QAAQ,CAAC,EAAE,MAAM,MACrE,6CAAC,wBACC;AAAA,6DAAC,yBAAU;AAAA;AAAA,kBAAc,4CAAC,UAAK,WAAU,qCAAoC,wBAAU;AAAA,mBAAO;AAAA,gBAC9F,4CAAC,2BAAY,sDAAC,sBAAM,aAAY,2BAA2B,GAAG,OAAO,GAAE;AAAA,gBACvE,4CAAC,2BAAY;AAAA,iBACf,GACC;AAAA,cAEH;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAM;AAAA,kBACN,cAAc;AAAA,kBACd,MAAM,4CAAC,mCAAY,WAAU,wBAAuB;AAAA,kBACpD,OAAM;AAAA,kBACN,MAAK;AAAA,kBAEL;AAAA,gEAAC,OAAE,WAAU,iCAAgC,iHAAmG;AAAA,oBAChJ,4CAAC,yBAAU,SAAS,KAAK,SAAS,MAAK,eAAc,QAAQ,CAAC,EAAE,MAAM,MACpE,6CAAC,wBACC;AAAA,kEAAC,yBAAU,qBAAO;AAAA,sBAClB,6CAAC,wBAAO,OAAO,MAAM,OAAO,eAAe,qBACzC;AAAA,oEAAC,2BAAY,sDAAC,+BAAc,sDAAC,6BAAY,GAAE,GAAgB;AAAA,wBAC3D,4CAAC,+BAAe,kCAAc,IAAI,CAAC,MAAM,4CAAC,4BAAyB,OAAO,EAAE,OAAQ,YAAE,SAA5B,EAAE,KAAgC,CAAa,GAAE;AAAA,yBAC7G;AAAA,uBACE,MAAM;AAAE,8BAAM,MAAM,wBAAc,KAAK,CAAC,MAAM,EAAE,UAAU,MAAM,KAAK;AAAG,+BAAO,MAAM,4CAAC,OAAE,WAAU,sCAAsC,cAAI,aAAY,IAAO;AAAA,sBAAM,GAAG;AAAA,sBAC1K,4CAAC,2BAAY;AAAA,uBACf,GACC;AAAA,oBACH,4CAAC,yBAAU,SAAS,KAAK,SAAS,MAAK,iBAAgB,QAAQ,CAAC,EAAE,MAAM,MACtE,6CAAC,wBAAS;AAAA,kEAAC,yBAAU,4BAAc;AAAA,sBAAY,4CAAC,6CAAY,OAAO,MAAM,OAAO,SAAS,CAAC,OAAO,IAAI,GAAG,UAAU,MAAM,UAAU;AAAA,uBAAE,GACnI;AAAA,oBACH,4CAAC,yBAAU,SAAS,KAAK,SAAS,MAAK,eAAc,QAAQ,CAAC,EAAE,MAAM,MACpE,6CAAC,wBAAS;AAAA,kEAAC,yBAAU,yBAAW;AAAA,sBAAY,4CAAC,6CAAY,OAAO,MAAM,OAAO,SAAS,+BAAqB,UAAU,MAAM,UAAU;AAAA,uBAAE,GACtI;AAAA,oBACH,4CAAC,yBAAU,SAAS,KAAK,SAAS,MAAK,eAAc,QAAQ,CAAC,EAAE,MAAM,MACpE,6CAAC,wBAAS;AAAA,kEAAC,yBAAU,yBAAW;AAAA,sBAAY,4CAAC,6CAAY,OAAO,MAAM,OAAO,SAAS,CAAC,YAAY,cAAc,GAAG,UAAU,MAAM,UAAU;AAAA,uBAAE,GAC/I;AAAA,oBACH,6CAAC,kCAAY,MAAM,cAAc,cAAc,iBAC7C;AAAA,kEAAC,yCAAmB,SAAO,MACzB,uDAAC,YAAO,MAAK,UAAS,WAAU,mGAC9B;AAAA,oEAAC,mCAAY,eAAW,cAAG,oCAAoC,gBAAgB,YAAY,GAAG;AAAA,wBAAE;AAAA,yBAElG,GACF;AAAA,sBACA,6CAAC,yCAAmB,WAAU,kBAC5B;AAAA,oEAAC,yBAAU,SAAS,KAAK,SAAS,MAAK,mBAAkB,QAAQ,CAAC,EAAE,MAAM,MACxE,6CAAC,wBACC;AAAA,sEAAC,yBAAU,uBAAS;AAAA,0BACpB,4CAAC,2BAAY,sDAAC,sBAAM,aAAY,aAAa,GAAG,OAAO,GAAE;AAAA,2BAC3D,GACC;AAAA,wBACH,4CAAC,yBAAU,SAAS,KAAK,SAAS,MAAK,YAAW,QAAQ,CAAC,EAAE,MAAM,MACjE,6CAAC,wBAAS;AAAA,sEAAC,yBAAU,8BAAoB;AAAA,0BAAY,4CAAC,6CAAY,OAAO,MAAM,OAAO,SAAS,uBAAa,UAAU,MAAM,UAAU;AAAA,2BAAE,GACvI;AAAA,wBACH,4CAAC,yBAAU,SAAS,KAAK,SAAS,MAAK,WAAU,QAAQ,CAAC,EAAE,MAAM,MAChE,6CAAC,wBACC;AAAA,sEAAC,yBAAU,mCAAgB;AAAA,0BAC3B,4CAAC,2BACC,sDAAC,sBAAM,MAAK,UAAS,KAAK,GAAG,KAAK,IAAI,MAAM,KAAK,aAAY,KAAK,GAAG,OAAO,UAAU,CAAC,MAAM,MAAM,SAAS,WAAW,EAAE,OAAO,KAAK,KAAK,CAAC,GAAG,GAChJ;AAAA,0BACA,4CAAC,2BAAY;AAAA,2BACf,GACC;AAAA,yBACL;AAAA,uBACF;AAAA;AAAA;AAAA,cACF;AAAA,cAEA;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAM;AAAA,kBACN,cAAc;AAAA,kBACd,MAAM,4CAAC,8BAAO,WAAU,wBAAuB;AAAA,kBAC/C,OAAM;AAAA,kBACN,MAAK;AAAA,kBAEL;AAAA,gEAAC,OAAE,WAAU,iCAAgC,0FAA4E;AAAA,oBACzH,4CAAC,yBAAU,SAAS,KAAK,SAAS,MAAK,UAAS,QAAQ,CAAC,EAAE,MAAM,MAC/D,6CAAC,wBACC;AAAA,kEAAC,yBAAU,qBAAO;AAAA,sBAClB,6CAAC,wBAAO,eAAe,MAAM,UAAU,OAAO,MAAM,OAClD;AAAA,oEAAC,2BAAY,sDAAC,+BAAc,sDAAC,6BAAY,GAAE,GAAgB;AAAA,wBAC3D,4CAAC,+BAAe,6BAAS,IAAI,CAAC,MAAM,4CAAC,4BAAmB,OAAO,GAAI,eAAd,CAAgB,CAAa,GAAE;AAAA,yBACtF;AAAA,uBACF,GACC;AAAA,oBACH;AAAA,sBAAC;AAAA;AAAA,wBAEC,QAAQ,KAAK,MAAM,QAAQ;AAAA,wBAC3B,UAAU,CAAC,WAAW;AAAE,4CAAkB,UAAU;AAAA,wBAAQ;AAAA,wBAC5D;AAAA;AAAA,sBAHK;AAAA,oBAIP;AAAA;AAAA;AAAA,cACF;AAAA,cAEA;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,UAAU;AAAA,kBACV,WAAW,0KAA0K,OAAO,mCAAmC,EAAE;AAAA,kBAClO;AAAA;AAAA,cAED;AAAA,cACA,4CAAC,OAAE,WAAU,6CAA4C,uDAAoC;AAAA,eAC/F,GACF;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF;AAEJ;","names":["Image"]}
|
|
@@ -62,6 +62,9 @@ const DEFAULTS = {
|
|
|
62
62
|
aiPolicy: "Allowed",
|
|
63
63
|
royalty: 0
|
|
64
64
|
};
|
|
65
|
+
function suggestedExternalUrl(collection) {
|
|
66
|
+
return collection?.contractAddress ? `https://medialane.io${collectionHref("STARKNET", collection.contractAddress)}` : "";
|
|
67
|
+
}
|
|
65
68
|
function SingleEditionMint({ aside }) {
|
|
66
69
|
const app = useMedialaneApp();
|
|
67
70
|
const walletAddress = app.walletAddress;
|
|
@@ -88,11 +91,16 @@ function SingleEditionMint({ aside }) {
|
|
|
88
91
|
useEffect(() => {
|
|
89
92
|
if (collections.length > 0 && !form.getValues("collectionId")) form.setValue("collectionId", collections[0].collectionId);
|
|
90
93
|
}, [collections, form]);
|
|
94
|
+
const suggestedUrl = suggestedExternalUrl(selectedCollection);
|
|
95
|
+
const autoUrlRef = useRef("");
|
|
91
96
|
useEffect(() => {
|
|
92
|
-
if (
|
|
93
|
-
|
|
97
|
+
if (!suggestedUrl) return;
|
|
98
|
+
const current = form.getValues("external_url");
|
|
99
|
+
if (!current || current === autoUrlRef.current) {
|
|
100
|
+
form.setValue("external_url", suggestedUrl);
|
|
101
|
+
autoUrlRef.current = suggestedUrl;
|
|
94
102
|
}
|
|
95
|
-
}, [
|
|
103
|
+
}, [suggestedUrl, form]);
|
|
96
104
|
const handleLicenseChange = (value) => {
|
|
97
105
|
form.setValue("licenseType", value);
|
|
98
106
|
const def = LICENSE_TYPES.find((l) => l.value === value);
|
|
@@ -108,7 +116,9 @@ function SingleEditionMint({ aside }) {
|
|
|
108
116
|
};
|
|
109
117
|
const handleAgain = () => {
|
|
110
118
|
tx.reset();
|
|
111
|
-
|
|
119
|
+
const first = collections[0] ?? null;
|
|
120
|
+
autoUrlRef.current = suggestedExternalUrl(first);
|
|
121
|
+
form.reset({ ...DEFAULTS, collectionId: first?.collectionId ?? "", external_url: autoUrlRef.current });
|
|
112
122
|
metadataFieldsRef.current = [];
|
|
113
123
|
setMetadataResetKey((key) => key + 1);
|
|
114
124
|
setImageFile(null);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/launchpad/single-edition-mint.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport * as z from \"zod\";\nimport { Boxes, ChevronDown, ImagePlus, Layers, ShieldCheck, Upload } from \"lucide-react\";\nimport { assetHref, collectionHref, getService, profileHref } from \"@medialane/sdk\";\nimport { acceptFor, uploadError } from \"../../utils/upload-limits.js\";\nimport { FIELD_LIMITS } from \"../../utils/field-limits.js\";\nimport { mintedTokenIdFromReceipt } from \"@medialane/sdk/starknet\";\nimport Image from \"../image.js\";\nimport { Input } from \"../input.js\";\nimport { Textarea } from \"../textarea.js\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"../select.js\";\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"../collapsible.js\";\nimport { CollapsibleSection } from \"../collapsible-section.js\";\nimport { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from \"../form.js\";\nimport { ToggleGroup } from \"../create-form-primitives.js\";\nimport { IPTypeFields } from \"../ip-type-fields.js\";\nimport { ClaimRouteShell } from \"../claim-route-shell.js\";\nimport { TransactionSuccess } from \"../transaction-success.js\";\nimport { MedialaneCollectionCard } from \"../medialane-collection-card.js\";\nimport { TransactionDialog } from \"../transaction-dialog.js\";\nimport { WalletRequired } from \"../wallet-required.js\";\nimport { useMedialaneApp } from \"../medialane-app.js\";\nimport { RewardEarned } from \"../rewards/reward-earned.js\";\nimport { CollectionPicker } from \"./collection-picker.js\";\nimport { AI_POLICIES, DERIVATIVES_OPTIONS, IP_TYPES, LICENSE_TYPES, type IPType } from \"../../data/ip.js\";\nimport { cn } from \"../../utils/cn.js\";\nimport { runIntentCalls } from \"../../utils/run-intent-calls.js\";\nimport { pinAssetMetadata, uploadFileToIpfs } from \"../../utils/ipfs-upload.js\";\nimport { useCollectionsByOwner } from \"../../utils/use-collections.js\";\nimport { useTransaction } from \"../../utils/use-transaction.js\";\nimport { invalidatePortfolioCache } from \"../../utils/portfolio-cache.js\";\nimport type { MetadataField } from \"../ip-type-fields.js\";\n\nconst schema = z.object({\n collectionId: z.string().min(1, \"Select a collection\"),\n name: z.string().min(1, \"Name required\").max(FIELD_LIMITS.name),\n description: z.string().max(FIELD_LIMITS.description).optional(),\n external_url: z\n .string()\n .max(500)\n .refine((v) => !v || v.startsWith(\"http://\") || v.startsWith(\"https://\"), { message: \"Must start with http:// or https://\" })\n .optional(),\n ipType: z.enum(IP_TYPES),\n licenseType: z.string().min(1, \"License required\"),\n commercialUse: z.enum([\"Yes\", \"No\"]),\n derivatives: z.enum([\"Allowed\", \"Not Allowed\", \"Share-Alike\"]),\n attribution: z.enum([\"Required\", \"Not Required\"]),\n geographicScope: z.string(),\n aiPolicy: z.enum([\"Allowed\", \"Not Allowed\", \"Training Only\"]),\n royalty: z.coerce.number().min(0).max(50),\n image: z.instanceof(File).optional(),\n});\ntype FormValues = z.infer<typeof schema>;\n\nconst DEFAULTS: FormValues = {\n collectionId: \"\",\n name: \"\",\n description: \"\",\n external_url: \"\",\n ipType: \"NFT\",\n licenseType: \"CC BY-SA\",\n commercialUse: \"Yes\",\n derivatives: \"Share-Alike\",\n attribution: \"Required\",\n geographicScope: \"Worldwide\",\n aiPolicy: \"Allowed\",\n royalty: 0,\n};\n\nexport function SingleEditionMint({ aside }: { aside?: ReactNode }) {\n const app = useMedialaneApp();\n const walletAddress = app.walletAddress;\n const tx = useTransaction();\n const { collections: allCollections, isLoading: collectionsLoading } = useCollectionsByOwner(walletAddress ?? null);\n const collections = allCollections.filter((c) => getService(c.service)?.id === \"mip-erc721\" && c.collectionId != null);\n\n const [imageFile, setImageFile] = useState<File | null>(null);\n const [imagePreview, setImagePreview] = useState<string | null>(null);\n const [advancedOpen, setAdvancedOpen] = useState(false);\n const [licensingOpen, setLicensingOpen] = useState(false);\n const [ipTypeOpen, setIpTypeOpen] = useState(false);\n const [metadataResetKey, setMetadataResetKey] = useState(0);\n const metadataFieldsRef = useRef<MetadataField[]>([]);\n const previewUrlRef = useRef<string | null>(null);\n const imageInputRef = useRef<HTMLInputElement | null>(null);\n\n useEffect(() => {\n return () => {\n if (previewUrlRef.current) URL.revokeObjectURL(previewUrlRef.current);\n };\n }, []);\n\n const form = useForm<FormValues>({ resolver: zodResolver(schema), defaultValues: DEFAULTS });\n const selectedCollectionId = form.watch(\"collectionId\");\n const selectedCollection = collections.find((c) => c.collectionId === selectedCollectionId) ?? null;\n\n useEffect(() => {\n if (collections.length > 0 && !form.getValues(\"collectionId\")) form.setValue(\"collectionId\", collections[0]!.collectionId!);\n }, [collections, form]);\n\n useEffect(() => {\n if (selectedCollection?.contractAddress && !form.getValues(\"external_url\")) {\n form.setValue(\"external_url\", `https://medialane.io${collectionHref(\"STARKNET\", selectedCollection.contractAddress)}`);\n }\n }, [selectedCollection?.contractAddress, form]);\n\n const handleLicenseChange = (value: string) => {\n form.setValue(\"licenseType\", value);\n const def = LICENSE_TYPES.find((l) => l.value === value);\n if (def) {\n form.setValue(\"commercialUse\", def.commercialUse);\n form.setValue(\"derivatives\", def.derivatives);\n form.setValue(\"attribution\", def.attribution);\n }\n };\n\n const uploadDocument = async (file: File) => {\n await app.ensureSignedIn?.();\n return (await uploadFileToIpfs(app.getClient().api, file, \"document\")).uri;\n };\n\n const handleAgain = () => {\n tx.reset();\n form.reset({ ...DEFAULTS, collectionId: collections[0]?.collectionId ?? \"\" });\n metadataFieldsRef.current = [];\n setMetadataResetKey((key) => key + 1);\n setImageFile(null);\n setImagePreview(null);\n if (imageInputRef.current) imageInputRef.current.value = \"\";\n };\n\n const onSubmit = (values: FormValues) => {\n if (!walletAddress) return;\n void tx.run(async (signer) => {\n await app.ensureSignedIn?.();\n const api = app.getClient().api;\n const pinned = await pinAssetMetadata(api, {\n name: values.name,\n description: values.description ?? \"\",\n externalUrl: values.external_url,\n creator: walletAddress,\n ipType: values.ipType,\n licenseType: values.licenseType,\n commercialUse: values.commercialUse,\n derivatives: values.derivatives,\n attribution: values.attribution,\n geographicScope: values.geographicScope,\n aiPolicy: values.aiPolicy,\n royalty: String(values.royalty),\n imageFile,\n templateTraits: metadataFieldsRef.current.filter((f) => f.traitType.trim() && f.value.trim()).map((f) => ({ traitType: f.traitType.trim(), value: f.value.trim() })),\n });\n await runIntentCalls(signer, () =>\n api.intents.create(\"mint\", {\n owner: walletAddress,\n collectionId: values.collectionId,\n recipient: walletAddress,\n tokenUri: pinned.uri,\n royaltyBps: Math.round(values.royalty * 100),\n }),\n );\n invalidatePortfolioCache(walletAddress);\n });\n };\n\n const mintedTokenId = tx.receipt && selectedCollection ? mintedTokenIdFromReceipt(tx.receipt, selectedCollection.contractAddress) : null;\n const mintedHref = mintedTokenId && selectedCollection ? assetHref(\"STARKNET\", selectedCollection.contractAddress, mintedTokenId) : null;\n const busy = tx.phase !== \"idle\" || collectionsLoading || collections.length === 0;\n\n return (\n <WalletRequired\n icon={ImagePlus}\n iconClassName=\"text-brand-blue\"\n title=\"Secure your account to create\"\n description=\"Publish your creative work as a single-copy NFT in a collection you own.\"\n >\n <TransactionDialog tx={tx} title=\"Mint NFT\" workingLabel=\"Minting your work…\" firstStepLabel=\"Upload to IPFS\">\n <TransactionSuccess\n name={form.getValues(\"name\") || \"Your asset\"}\n image={imagePreview}\n title=\"Asset minted\"\n description=\"Your wallet is the owner. The license terms and royalty are recorded in its metadata.\"\n actions={[\n ...(mintedHref ? [{ href: mintedHref, label: \"View asset\" }] : []),\n { href: \"/portfolio/assets\", label: \"View portfolio\" },\n { label: \"Mint another\", onClick: handleAgain },\n ]}\n >\n <RewardEarned actionType=\"mint_asset\" />\n </TransactionSuccess>\n </TransactionDialog>\n\n <ClaimRouteShell\n icon={<ImagePlus className=\"h-4 w-4 text-white\" />}\n title=\"Mint NFT\"\n subtitle=\"Publish your creative work as a single-copy NFT in a collection you own — free to mint, and it's yours.\"\n aside={\n <>\n <MedialaneCollectionCard\n image={imagePreview}\n name={form.watch(\"name\")}\n collection={selectedCollection?.name || \"IP Asset\"}\n creator={walletAddress ? `${walletAddress.slice(0, 6)}…${walletAddress.slice(-4)}` : undefined}\n creatorHref={walletAddress ? profileHref({ address: walletAddress }) : undefined}\n />\n {aside}\n </>\n }\n >\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-6\">\n <FormField control={form.control} name=\"collectionId\" render={({ field }) => (\n <FormItem>\n <FormLabel className=\"flex items-center gap-1.5\"><Boxes className=\"h-4 w-4\" />Collection *</FormLabel>\n <CollectionPicker\n collections={collections}\n loading={collectionsLoading}\n value={field.value}\n onChange={field.onChange}\n newCollectionHref=\"/launchpad/single-editions/collection\"\n />\n <FormMessage />\n </FormItem>\n )} />\n\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\">Cover image</label>\n <div\n className=\"border-2 border-dashed border-border rounded-xl p-8 text-center cursor-pointer hover:border-primary/50 transition-colors\"\n role=\"button\"\n tabIndex={0}\n aria-label=\"Upload image\"\n onClick={() => imageInputRef.current?.click()}\n onKeyDown={(e) => { if (e.key === \"Enter\" || e.key === \" \") { e.preventDefault(); imageInputRef.current?.click(); } }}\n >\n {imagePreview ? (\n <div className=\"relative mx-auto h-48 w-48 overflow-hidden rounded-lg\">\n <Image src={imagePreview} alt=\"Preview\" fill unoptimized className=\"object-cover\" />\n </div>\n ) : (\n <div className=\"flex flex-col items-center gap-2 text-muted-foreground\">\n <Upload className=\"h-8 w-8\" />\n <p className=\"text-sm\">Click to upload (JPG, PNG, GIF, SVG, WebP)</p>\n </div>\n )}\n <input\n ref={imageInputRef}\n type=\"file\"\n accept={acceptFor(\"image\")}\n className=\"hidden\"\n onChange={(e) => {\n const file = e.target.files?.[0];\n if (!file) return;\n const fileError = uploadError(file, \"image\");\n if (fileError) {\n form.setError(\"image\", { message: fileError });\n e.target.value = \"\";\n return;\n }\n form.clearErrors(\"image\");\n setImageFile(file);\n form.setValue(\"image\", file);\n if (previewUrlRef.current) URL.revokeObjectURL(previewUrlRef.current);\n const objectUrl = URL.createObjectURL(file);\n previewUrlRef.current = objectUrl;\n setImagePreview(objectUrl);\n }}\n />\n </div>\n {form.formState.errors.image && <p role=\"alert\" className=\"text-sm text-destructive\">{form.formState.errors.image.message}</p>}\n </div>\n\n <FormField control={form.control} name=\"name\" render={({ field }) => (\n <FormItem>\n <FormLabel>Name *</FormLabel>\n <FormControl><Input placeholder=\"My Creative Work\" {...field} /></FormControl>\n <FormMessage />\n </FormItem>\n )} />\n\n <FormField control={form.control} name=\"description\" render={({ field }) => (\n <FormItem>\n <FormLabel>Description</FormLabel>\n <FormControl><Textarea placeholder=\"Describe your work, its story, and any context for buyers…\" rows={4} {...field} /></FormControl>\n <FormMessage />\n </FormItem>\n )} />\n\n <FormField control={form.control} name=\"external_url\" render={({ field }) => (\n <FormItem>\n <FormLabel>External link <span className=\"text-muted-foreground font-normal\">(optional)</span></FormLabel>\n <FormControl><Input placeholder=\"https://yourwebsite.com\" {...field} /></FormControl>\n <FormMessage />\n </FormItem>\n )} />\n\n <CollapsibleSection\n open={licensingOpen}\n onOpenChange={setLicensingOpen}\n icon={<ShieldCheck className=\"h-4 w-4 text-primary\" />}\n label=\"Licensing Terms\"\n hint=\"Optional · Berne Convention\"\n >\n <p className=\"text-xs text-muted-foreground\">Set how others can use your work. These terms are saved permanently with it as proof of authorship.</p>\n <FormField control={form.control} name=\"licenseType\" render={({ field }) => (\n <FormItem>\n <FormLabel>License</FormLabel>\n <Select value={field.value} onValueChange={handleLicenseChange}>\n <FormControl><SelectTrigger><SelectValue /></SelectTrigger></FormControl>\n <SelectContent>{LICENSE_TYPES.map((l) => <SelectItem key={l.value} value={l.value}>{l.label}</SelectItem>)}</SelectContent>\n </Select>\n {(() => { const def = LICENSE_TYPES.find((l) => l.value === field.value); return def ? <p className=\"text-xs text-muted-foreground mt-1\">{def.description}</p> : null; })()}\n <FormMessage />\n </FormItem>\n )} />\n <FormField control={form.control} name=\"commercialUse\" render={({ field }) => (\n <FormItem><FormLabel>Commercial Use</FormLabel><ToggleGroup value={field.value} options={[\"Yes\", \"No\"]} onChange={field.onChange} /></FormItem>\n )} />\n <FormField control={form.control} name=\"derivatives\" render={({ field }) => (\n <FormItem><FormLabel>Derivatives</FormLabel><ToggleGroup value={field.value} options={DERIVATIVES_OPTIONS} onChange={field.onChange} /></FormItem>\n )} />\n <FormField control={form.control} name=\"attribution\" render={({ field }) => (\n <FormItem><FormLabel>Attribution</FormLabel><ToggleGroup value={field.value} options={[\"Required\", \"Not Required\"]} onChange={field.onChange} /></FormItem>\n )} />\n <Collapsible open={advancedOpen} onOpenChange={setAdvancedOpen}>\n <CollapsibleTrigger asChild>\n <button type=\"button\" className=\"flex items-center gap-1.5 text-xs text-muted-foreground hover:text-foreground transition-colors\">\n <ChevronDown className={cn(\"h-3.5 w-3.5 transition-transform\", advancedOpen && \"rotate-180\")} />\n Advanced options\n </button>\n </CollapsibleTrigger>\n <CollapsibleContent className=\"space-y-4 pt-3\">\n <FormField control={form.control} name=\"geographicScope\" render={({ field }) => (\n <FormItem>\n <FormLabel>Territory</FormLabel>\n <FormControl><Input placeholder=\"Worldwide\" {...field} /></FormControl>\n </FormItem>\n )} />\n <FormField control={form.control} name=\"aiPolicy\" render={({ field }) => (\n <FormItem><FormLabel>AI & Data Mining</FormLabel><ToggleGroup value={field.value} options={AI_POLICIES} onChange={field.onChange} /></FormItem>\n )} />\n <FormField control={form.control} name=\"royalty\" render={({ field }) => (\n <FormItem>\n <FormLabel>Royalty % (0–50)</FormLabel>\n <FormControl>\n <Input type=\"number\" min={0} max={50} step={0.5} placeholder=\"0\" {...field} onChange={(e) => field.onChange(parseFloat(e.target.value) || 0)} />\n </FormControl>\n <FormMessage />\n </FormItem>\n )} />\n </CollapsibleContent>\n </Collapsible>\n </CollapsibleSection>\n\n <CollapsibleSection\n open={ipTypeOpen}\n onOpenChange={setIpTypeOpen}\n icon={<Layers className=\"h-4 w-4 text-primary\" />}\n label=\"IP Type & Metadata\"\n hint=\"Optional\"\n >\n <p className=\"text-xs text-muted-foreground\">Choose a content type, fill suggested metadata, or add your own trait pairs.</p>\n <FormField control={form.control} name=\"ipType\" render={({ field }) => (\n <FormItem>\n <FormLabel>IP Type</FormLabel>\n <Select onValueChange={field.onChange} value={field.value}>\n <FormControl><SelectTrigger><SelectValue /></SelectTrigger></FormControl>\n <SelectContent>{IP_TYPES.map((t) => <SelectItem key={t} value={t}>{t}</SelectItem>)}</SelectContent>\n </Select>\n </FormItem>\n )} />\n <IPTypeFields\n key={metadataResetKey}\n ipType={form.watch(\"ipType\") as IPType}\n onChange={(fields) => { metadataFieldsRef.current = fields; }}\n uploadDocument={uploadDocument}\n />\n </CollapsibleSection>\n\n <button\n type=\"submit\"\n disabled={busy}\n className={`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 ${busy ? \"opacity-40 pointer-events-none\" : \"\"}`}\n >\n Mint NFT\n </button>\n <p className=\"text-xs text-center text-muted-foreground\">Free to mint — protocol fee is zero.</p>\n </form>\n </Form>\n </ClaimRouteShell>\n </WalletRequired>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/launchpad/single-edition-mint.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport * as z from \"zod\";\nimport { Boxes, ChevronDown, ImagePlus, Layers, ShieldCheck, Upload } from \"lucide-react\";\nimport { assetHref, collectionHref, getService, profileHref } from \"@medialane/sdk\";\nimport { acceptFor, uploadError } from \"../../utils/upload-limits.js\";\nimport { FIELD_LIMITS } from \"../../utils/field-limits.js\";\nimport { mintedTokenIdFromReceipt } from \"@medialane/sdk/starknet\";\nimport Image from \"../image.js\";\nimport { Input } from \"../input.js\";\nimport { Textarea } from \"../textarea.js\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"../select.js\";\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"../collapsible.js\";\nimport { CollapsibleSection } from \"../collapsible-section.js\";\nimport { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from \"../form.js\";\nimport { ToggleGroup } from \"../create-form-primitives.js\";\nimport { IPTypeFields } from \"../ip-type-fields.js\";\nimport { ClaimRouteShell } from \"../claim-route-shell.js\";\nimport { TransactionSuccess } from \"../transaction-success.js\";\nimport { MedialaneCollectionCard } from \"../medialane-collection-card.js\";\nimport { TransactionDialog } from \"../transaction-dialog.js\";\nimport { WalletRequired } from \"../wallet-required.js\";\nimport { useMedialaneApp } from \"../medialane-app.js\";\nimport { RewardEarned } from \"../rewards/reward-earned.js\";\nimport { CollectionPicker } from \"./collection-picker.js\";\nimport { AI_POLICIES, DERIVATIVES_OPTIONS, IP_TYPES, LICENSE_TYPES, type IPType } from \"../../data/ip.js\";\nimport { cn } from \"../../utils/cn.js\";\nimport { runIntentCalls } from \"../../utils/run-intent-calls.js\";\nimport { pinAssetMetadata, uploadFileToIpfs } from \"../../utils/ipfs-upload.js\";\nimport { useCollectionsByOwner } from \"../../utils/use-collections.js\";\nimport { useTransaction } from \"../../utils/use-transaction.js\";\nimport { invalidatePortfolioCache } from \"../../utils/portfolio-cache.js\";\nimport type { MetadataField } from \"../ip-type-fields.js\";\n\nconst schema = z.object({\n collectionId: z.string().min(1, \"Select a collection\"),\n name: z.string().min(1, \"Name required\").max(FIELD_LIMITS.name),\n description: z.string().max(FIELD_LIMITS.description).optional(),\n external_url: z\n .string()\n .max(500)\n .refine((v) => !v || v.startsWith(\"http://\") || v.startsWith(\"https://\"), { message: \"Must start with http:// or https://\" })\n .optional(),\n ipType: z.enum(IP_TYPES),\n licenseType: z.string().min(1, \"License required\"),\n commercialUse: z.enum([\"Yes\", \"No\"]),\n derivatives: z.enum([\"Allowed\", \"Not Allowed\", \"Share-Alike\"]),\n attribution: z.enum([\"Required\", \"Not Required\"]),\n geographicScope: z.string(),\n aiPolicy: z.enum([\"Allowed\", \"Not Allowed\", \"Training Only\"]),\n royalty: z.coerce.number().min(0).max(50),\n image: z.instanceof(File).optional(),\n});\ntype FormValues = z.infer<typeof schema>;\n\nconst DEFAULTS: FormValues = {\n collectionId: \"\",\n name: \"\",\n description: \"\",\n external_url: \"\",\n ipType: \"NFT\",\n licenseType: \"CC BY-SA\",\n commercialUse: \"Yes\",\n derivatives: \"Share-Alike\",\n attribution: \"Required\",\n geographicScope: \"Worldwide\",\n aiPolicy: \"Allowed\",\n royalty: 0,\n};\n\nfunction suggestedExternalUrl(collection: { contractAddress?: string | null } | null): string {\n return collection?.contractAddress ? `https://medialane.io${collectionHref(\"STARKNET\", collection.contractAddress)}` : \"\";\n}\n\nexport function SingleEditionMint({ aside }: { aside?: ReactNode }) {\n const app = useMedialaneApp();\n const walletAddress = app.walletAddress;\n const tx = useTransaction();\n const { collections: allCollections, isLoading: collectionsLoading } = useCollectionsByOwner(walletAddress ?? null);\n const collections = allCollections.filter((c) => getService(c.service)?.id === \"mip-erc721\" && c.collectionId != null);\n\n const [imageFile, setImageFile] = useState<File | null>(null);\n const [imagePreview, setImagePreview] = useState<string | null>(null);\n const [advancedOpen, setAdvancedOpen] = useState(false);\n const [licensingOpen, setLicensingOpen] = useState(false);\n const [ipTypeOpen, setIpTypeOpen] = useState(false);\n const [metadataResetKey, setMetadataResetKey] = useState(0);\n const metadataFieldsRef = useRef<MetadataField[]>([]);\n const previewUrlRef = useRef<string | null>(null);\n const imageInputRef = useRef<HTMLInputElement | null>(null);\n\n useEffect(() => {\n return () => {\n if (previewUrlRef.current) URL.revokeObjectURL(previewUrlRef.current);\n };\n }, []);\n\n const form = useForm<FormValues>({ resolver: zodResolver(schema), defaultValues: DEFAULTS });\n const selectedCollectionId = form.watch(\"collectionId\");\n const selectedCollection = collections.find((c) => c.collectionId === selectedCollectionId) ?? null;\n\n useEffect(() => {\n if (collections.length > 0 && !form.getValues(\"collectionId\")) form.setValue(\"collectionId\", collections[0]!.collectionId!);\n }, [collections, form]);\n\n const suggestedUrl = suggestedExternalUrl(selectedCollection);\n const autoUrlRef = useRef(\"\");\n\n useEffect(() => {\n if (!suggestedUrl) return;\n const current = form.getValues(\"external_url\");\n if (!current || current === autoUrlRef.current) {\n form.setValue(\"external_url\", suggestedUrl);\n autoUrlRef.current = suggestedUrl;\n }\n }, [suggestedUrl, form]);\n\n const handleLicenseChange = (value: string) => {\n form.setValue(\"licenseType\", value);\n const def = LICENSE_TYPES.find((l) => l.value === value);\n if (def) {\n form.setValue(\"commercialUse\", def.commercialUse);\n form.setValue(\"derivatives\", def.derivatives);\n form.setValue(\"attribution\", def.attribution);\n }\n };\n\n const uploadDocument = async (file: File) => {\n await app.ensureSignedIn?.();\n return (await uploadFileToIpfs(app.getClient().api, file, \"document\")).uri;\n };\n\n const handleAgain = () => {\n tx.reset();\n const first = collections[0] ?? null;\n autoUrlRef.current = suggestedExternalUrl(first);\n form.reset({ ...DEFAULTS, collectionId: first?.collectionId ?? \"\", external_url: autoUrlRef.current });\n metadataFieldsRef.current = [];\n setMetadataResetKey((key) => key + 1);\n setImageFile(null);\n setImagePreview(null);\n if (imageInputRef.current) imageInputRef.current.value = \"\";\n };\n\n const onSubmit = (values: FormValues) => {\n if (!walletAddress) return;\n void tx.run(async (signer) => {\n await app.ensureSignedIn?.();\n const api = app.getClient().api;\n const pinned = await pinAssetMetadata(api, {\n name: values.name,\n description: values.description ?? \"\",\n externalUrl: values.external_url,\n creator: walletAddress,\n ipType: values.ipType,\n licenseType: values.licenseType,\n commercialUse: values.commercialUse,\n derivatives: values.derivatives,\n attribution: values.attribution,\n geographicScope: values.geographicScope,\n aiPolicy: values.aiPolicy,\n royalty: String(values.royalty),\n imageFile,\n templateTraits: metadataFieldsRef.current.filter((f) => f.traitType.trim() && f.value.trim()).map((f) => ({ traitType: f.traitType.trim(), value: f.value.trim() })),\n });\n await runIntentCalls(signer, () =>\n api.intents.create(\"mint\", {\n owner: walletAddress,\n collectionId: values.collectionId,\n recipient: walletAddress,\n tokenUri: pinned.uri,\n royaltyBps: Math.round(values.royalty * 100),\n }),\n );\n invalidatePortfolioCache(walletAddress);\n });\n };\n\n const mintedTokenId = tx.receipt && selectedCollection ? mintedTokenIdFromReceipt(tx.receipt, selectedCollection.contractAddress) : null;\n const mintedHref = mintedTokenId && selectedCollection ? assetHref(\"STARKNET\", selectedCollection.contractAddress, mintedTokenId) : null;\n const busy = tx.phase !== \"idle\" || collectionsLoading || collections.length === 0;\n\n return (\n <WalletRequired\n icon={ImagePlus}\n iconClassName=\"text-brand-blue\"\n title=\"Secure your account to create\"\n description=\"Publish your creative work as a single-copy NFT in a collection you own.\"\n >\n <TransactionDialog tx={tx} title=\"Mint NFT\" workingLabel=\"Minting your work…\" firstStepLabel=\"Upload to IPFS\">\n <TransactionSuccess\n name={form.getValues(\"name\") || \"Your asset\"}\n image={imagePreview}\n title=\"Asset minted\"\n description=\"Your wallet is the owner. The license terms and royalty are recorded in its metadata.\"\n actions={[\n ...(mintedHref ? [{ href: mintedHref, label: \"View asset\" }] : []),\n { href: \"/portfolio/assets\", label: \"View portfolio\" },\n { label: \"Mint another\", onClick: handleAgain },\n ]}\n >\n <RewardEarned actionType=\"mint_asset\" />\n </TransactionSuccess>\n </TransactionDialog>\n\n <ClaimRouteShell\n icon={<ImagePlus className=\"h-4 w-4 text-white\" />}\n title=\"Mint NFT\"\n subtitle=\"Publish your creative work as a single-copy NFT in a collection you own — free to mint, and it's yours.\"\n aside={\n <>\n <MedialaneCollectionCard\n image={imagePreview}\n name={form.watch(\"name\")}\n collection={selectedCollection?.name || \"IP Asset\"}\n creator={walletAddress ? `${walletAddress.slice(0, 6)}…${walletAddress.slice(-4)}` : undefined}\n creatorHref={walletAddress ? profileHref({ address: walletAddress }) : undefined}\n />\n {aside}\n </>\n }\n >\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-6\">\n <FormField control={form.control} name=\"collectionId\" render={({ field }) => (\n <FormItem>\n <FormLabel className=\"flex items-center gap-1.5\"><Boxes className=\"h-4 w-4\" />Collection *</FormLabel>\n <CollectionPicker\n collections={collections}\n loading={collectionsLoading}\n value={field.value}\n onChange={field.onChange}\n newCollectionHref=\"/launchpad/single-editions/collection\"\n />\n <FormMessage />\n </FormItem>\n )} />\n\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\">Cover image</label>\n <div\n className=\"border-2 border-dashed border-border rounded-xl p-8 text-center cursor-pointer hover:border-primary/50 transition-colors\"\n role=\"button\"\n tabIndex={0}\n aria-label=\"Upload image\"\n onClick={() => imageInputRef.current?.click()}\n onKeyDown={(e) => { if (e.key === \"Enter\" || e.key === \" \") { e.preventDefault(); imageInputRef.current?.click(); } }}\n >\n {imagePreview ? (\n <div className=\"relative mx-auto h-48 w-48 overflow-hidden rounded-lg\">\n <Image src={imagePreview} alt=\"Preview\" fill unoptimized className=\"object-cover\" />\n </div>\n ) : (\n <div className=\"flex flex-col items-center gap-2 text-muted-foreground\">\n <Upload className=\"h-8 w-8\" />\n <p className=\"text-sm\">Click to upload (JPG, PNG, GIF, SVG, WebP)</p>\n </div>\n )}\n <input\n ref={imageInputRef}\n type=\"file\"\n accept={acceptFor(\"image\")}\n className=\"hidden\"\n onChange={(e) => {\n const file = e.target.files?.[0];\n if (!file) return;\n const fileError = uploadError(file, \"image\");\n if (fileError) {\n form.setError(\"image\", { message: fileError });\n e.target.value = \"\";\n return;\n }\n form.clearErrors(\"image\");\n setImageFile(file);\n form.setValue(\"image\", file);\n if (previewUrlRef.current) URL.revokeObjectURL(previewUrlRef.current);\n const objectUrl = URL.createObjectURL(file);\n previewUrlRef.current = objectUrl;\n setImagePreview(objectUrl);\n }}\n />\n </div>\n {form.formState.errors.image && <p role=\"alert\" className=\"text-sm text-destructive\">{form.formState.errors.image.message}</p>}\n </div>\n\n <FormField control={form.control} name=\"name\" render={({ field }) => (\n <FormItem>\n <FormLabel>Name *</FormLabel>\n <FormControl><Input placeholder=\"My Creative Work\" {...field} /></FormControl>\n <FormMessage />\n </FormItem>\n )} />\n\n <FormField control={form.control} name=\"description\" render={({ field }) => (\n <FormItem>\n <FormLabel>Description</FormLabel>\n <FormControl><Textarea placeholder=\"Describe your work, its story, and any context for buyers…\" rows={4} {...field} /></FormControl>\n <FormMessage />\n </FormItem>\n )} />\n\n <FormField control={form.control} name=\"external_url\" render={({ field }) => (\n <FormItem>\n <FormLabel>External link <span className=\"text-muted-foreground font-normal\">(optional)</span></FormLabel>\n <FormControl><Input placeholder=\"https://yourwebsite.com\" {...field} /></FormControl>\n <FormMessage />\n </FormItem>\n )} />\n\n <CollapsibleSection\n open={licensingOpen}\n onOpenChange={setLicensingOpen}\n icon={<ShieldCheck className=\"h-4 w-4 text-primary\" />}\n label=\"Licensing Terms\"\n hint=\"Optional · Berne Convention\"\n >\n <p className=\"text-xs text-muted-foreground\">Set how others can use your work. These terms are saved permanently with it as proof of authorship.</p>\n <FormField control={form.control} name=\"licenseType\" render={({ field }) => (\n <FormItem>\n <FormLabel>License</FormLabel>\n <Select value={field.value} onValueChange={handleLicenseChange}>\n <FormControl><SelectTrigger><SelectValue /></SelectTrigger></FormControl>\n <SelectContent>{LICENSE_TYPES.map((l) => <SelectItem key={l.value} value={l.value}>{l.label}</SelectItem>)}</SelectContent>\n </Select>\n {(() => { const def = LICENSE_TYPES.find((l) => l.value === field.value); return def ? <p className=\"text-xs text-muted-foreground mt-1\">{def.description}</p> : null; })()}\n <FormMessage />\n </FormItem>\n )} />\n <FormField control={form.control} name=\"commercialUse\" render={({ field }) => (\n <FormItem><FormLabel>Commercial Use</FormLabel><ToggleGroup value={field.value} options={[\"Yes\", \"No\"]} onChange={field.onChange} /></FormItem>\n )} />\n <FormField control={form.control} name=\"derivatives\" render={({ field }) => (\n <FormItem><FormLabel>Derivatives</FormLabel><ToggleGroup value={field.value} options={DERIVATIVES_OPTIONS} onChange={field.onChange} /></FormItem>\n )} />\n <FormField control={form.control} name=\"attribution\" render={({ field }) => (\n <FormItem><FormLabel>Attribution</FormLabel><ToggleGroup value={field.value} options={[\"Required\", \"Not Required\"]} onChange={field.onChange} /></FormItem>\n )} />\n <Collapsible open={advancedOpen} onOpenChange={setAdvancedOpen}>\n <CollapsibleTrigger asChild>\n <button type=\"button\" className=\"flex items-center gap-1.5 text-xs text-muted-foreground hover:text-foreground transition-colors\">\n <ChevronDown className={cn(\"h-3.5 w-3.5 transition-transform\", advancedOpen && \"rotate-180\")} />\n Advanced options\n </button>\n </CollapsibleTrigger>\n <CollapsibleContent className=\"space-y-4 pt-3\">\n <FormField control={form.control} name=\"geographicScope\" render={({ field }) => (\n <FormItem>\n <FormLabel>Territory</FormLabel>\n <FormControl><Input placeholder=\"Worldwide\" {...field} /></FormControl>\n </FormItem>\n )} />\n <FormField control={form.control} name=\"aiPolicy\" render={({ field }) => (\n <FormItem><FormLabel>AI & Data Mining</FormLabel><ToggleGroup value={field.value} options={AI_POLICIES} onChange={field.onChange} /></FormItem>\n )} />\n <FormField control={form.control} name=\"royalty\" render={({ field }) => (\n <FormItem>\n <FormLabel>Royalty % (0–50)</FormLabel>\n <FormControl>\n <Input type=\"number\" min={0} max={50} step={0.5} placeholder=\"0\" {...field} onChange={(e) => field.onChange(parseFloat(e.target.value) || 0)} />\n </FormControl>\n <FormMessage />\n </FormItem>\n )} />\n </CollapsibleContent>\n </Collapsible>\n </CollapsibleSection>\n\n <CollapsibleSection\n open={ipTypeOpen}\n onOpenChange={setIpTypeOpen}\n icon={<Layers className=\"h-4 w-4 text-primary\" />}\n label=\"IP Type & Metadata\"\n hint=\"Optional\"\n >\n <p className=\"text-xs text-muted-foreground\">Choose a content type, fill suggested metadata, or add your own trait pairs.</p>\n <FormField control={form.control} name=\"ipType\" render={({ field }) => (\n <FormItem>\n <FormLabel>IP Type</FormLabel>\n <Select onValueChange={field.onChange} value={field.value}>\n <FormControl><SelectTrigger><SelectValue /></SelectTrigger></FormControl>\n <SelectContent>{IP_TYPES.map((t) => <SelectItem key={t} value={t}>{t}</SelectItem>)}</SelectContent>\n </Select>\n </FormItem>\n )} />\n <IPTypeFields\n key={metadataResetKey}\n ipType={form.watch(\"ipType\") as IPType}\n onChange={(fields) => { metadataFieldsRef.current = fields; }}\n uploadDocument={uploadDocument}\n />\n </CollapsibleSection>\n\n <button\n type=\"submit\"\n disabled={busy}\n className={`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 ${busy ? \"opacity-40 pointer-events-none\" : \"\"}`}\n >\n Mint NFT\n </button>\n <p className=\"text-xs text-center text-muted-foreground\">Free to mint — protocol fee is zero.</p>\n </form>\n </Form>\n </ClaimRouteShell>\n </WalletRequired>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -10,7 +10,7 @@ declare const SheetClose: React.ForwardRefExoticComponent<SheetPrimitive.DialogC
|
|
|
10
10
|
declare const SheetPortal: React.FC<SheetPrimitive.DialogPortalProps>;
|
|
11
11
|
declare const SheetOverlay: React.ForwardRefExoticComponent<Omit<SheetPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
12
12
|
declare const sheetVariants: (props?: ({
|
|
13
|
-
side?: "
|
|
13
|
+
side?: "left" | "right" | "bottom" | "top" | null | undefined;
|
|
14
14
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
15
15
|
interface SheetContentProps extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>, VariantProps<typeof sheetVariants> {
|
|
16
16
|
overlayClassName?: string;
|
|
@@ -10,7 +10,7 @@ declare const SheetClose: React.ForwardRefExoticComponent<SheetPrimitive.DialogC
|
|
|
10
10
|
declare const SheetPortal: React.FC<SheetPrimitive.DialogPortalProps>;
|
|
11
11
|
declare const SheetOverlay: React.ForwardRefExoticComponent<Omit<SheetPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
12
12
|
declare const sheetVariants: (props?: ({
|
|
13
|
-
side?: "
|
|
13
|
+
side?: "left" | "right" | "bottom" | "top" | null | undefined;
|
|
14
14
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
15
15
|
interface SheetContentProps extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>, VariantProps<typeof sheetVariants> {
|
|
16
16
|
overlayClassName?: string;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
"use client";
|
|
3
|
+
var __create = Object.create;
|
|
3
4
|
var __defProp = Object.defineProperty;
|
|
4
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
9
|
var __export = (target, all) => {
|
|
8
10
|
for (var name in all)
|
|
@@ -16,36 +18,59 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
18
|
}
|
|
17
19
|
return to;
|
|
18
20
|
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
19
29
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
30
|
var soulbound_card_exports = {};
|
|
21
31
|
__export(soulbound_card_exports, {
|
|
32
|
+
SoulboundBadge: () => SoulboundBadge,
|
|
22
33
|
SoulboundCard: () => SoulboundCard,
|
|
23
34
|
issuedAt: () => issuedAt
|
|
24
35
|
});
|
|
25
36
|
module.exports = __toCommonJS(soulbound_card_exports);
|
|
26
37
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
27
38
|
var import_lucide_react = require("lucide-react");
|
|
39
|
+
var import_sdk = require("@medialane/sdk");
|
|
40
|
+
var import_link = __toESM(require("./link.js"), 1);
|
|
41
|
+
var import_address = require("../utils/address.js");
|
|
28
42
|
function issuedAt(history) {
|
|
29
43
|
const times = history.filter((event) => event.type === "mint").map((event) => new Date(event.timestamp).getTime()).filter((time) => Number.isFinite(time));
|
|
30
44
|
if (times.length === 0) return null;
|
|
31
45
|
return new Date(Math.min(...times)).toLocaleDateString("en-US", { day: "numeric", month: "short", year: "numeric" });
|
|
32
46
|
}
|
|
33
|
-
function
|
|
47
|
+
function SoulboundBadge() {
|
|
48
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "inline-flex items-center gap-1 text-xs font-semibold text-brand-purple", children: [
|
|
49
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Fingerprint, { className: "h-3.5 w-3.5", "aria-hidden": true }),
|
|
50
|
+
"Soulbound"
|
|
51
|
+
] });
|
|
52
|
+
}
|
|
53
|
+
function SoulboundCard({ history = [], ownerAddress }) {
|
|
34
54
|
const issued = issuedAt(history);
|
|
35
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { "aria-label": "Soulbound asset", className: "flex items-center gap-4 rounded-2xl bg-
|
|
36
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
55
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { "aria-label": "Soulbound asset", className: "flex items-center gap-4 overflow-hidden rounded-2xl bg-gradient-to-br from-muted/40 to-transparent p-4", children: [
|
|
56
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Fingerprint, { className: "h-7 w-7 shrink-0 text-brand-purple", strokeWidth: 1.5, "aria-hidden": true }),
|
|
37
57
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
38
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "font-display text-
|
|
39
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mt-0.5 text-xs text-muted-foreground", children:
|
|
58
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "font-display text-base font-bold leading-tight text-foreground", children: "Soulbound" }),
|
|
59
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mt-0.5 truncate text-xs text-muted-foreground", children: ownerAddress ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
60
|
+
"Permanently bound to",
|
|
61
|
+
" ",
|
|
62
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_link.default, { href: (0, import_sdk.profileHref)({ address: ownerAddress }), title: ownerAddress, className: "font-mono font-medium text-foreground transition-colors hover:text-primary", children: (0, import_address.shortenAddress)(ownerAddress) })
|
|
63
|
+
] }) : "Permanently bound to the wallet it was issued to." })
|
|
40
64
|
] }),
|
|
41
|
-
issued ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("
|
|
42
|
-
"
|
|
43
|
-
issued
|
|
65
|
+
issued ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "shrink-0 text-right", children: [
|
|
66
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs text-muted-foreground", children: "Issued" }),
|
|
67
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mt-0.5 text-sm font-semibold tabular-nums text-foreground", children: issued })
|
|
44
68
|
] }) : null
|
|
45
69
|
] });
|
|
46
70
|
}
|
|
47
71
|
// Annotate the CommonJS export names for ESM import in node:
|
|
48
72
|
0 && (module.exports = {
|
|
73
|
+
SoulboundBadge,
|
|
49
74
|
SoulboundCard,
|
|
50
75
|
issuedAt
|
|
51
76
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/soulbound-card.tsx"],"sourcesContent":["\"use client\";\n\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/components/soulbound-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { Fingerprint } from \"lucide-react\";\nimport { profileHref, type ApiActivity } from \"@medialane/sdk\";\nimport Link from \"./link.js\";\nimport { shortenAddress } from \"../utils/address.js\";\n\nexport function issuedAt(history: readonly ApiActivity[]): string | null {\n const times = history\n .filter((event) => event.type === \"mint\")\n .map((event) => new Date(event.timestamp).getTime())\n .filter((time) => Number.isFinite(time));\n if (times.length === 0) return null;\n return new Date(Math.min(...times)).toLocaleDateString(\"en-US\", { day: \"numeric\", month: \"short\", year: \"numeric\" });\n}\n\nexport function SoulboundBadge() {\n return (\n <span className=\"inline-flex items-center gap-1 text-xs font-semibold text-brand-purple\">\n <Fingerprint className=\"h-3.5 w-3.5\" aria-hidden />\n Soulbound\n </span>\n );\n}\n\nexport interface SoulboundCardProps {\n history?: readonly ApiActivity[];\n ownerAddress?: string | null;\n}\n\nexport function SoulboundCard({ history = [], ownerAddress }: SoulboundCardProps) {\n const issued = issuedAt(history);\n return (\n <section aria-label=\"Soulbound asset\" className=\"flex items-center gap-4 overflow-hidden rounded-2xl bg-gradient-to-br from-muted/40 to-transparent p-4\">\n <Fingerprint className=\"h-7 w-7 shrink-0 text-brand-purple\" strokeWidth={1.5} aria-hidden />\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"font-display text-base font-bold leading-tight text-foreground\">Soulbound</h3>\n <p className=\"mt-0.5 truncate text-xs text-muted-foreground\">\n {ownerAddress ? (\n <>\n Permanently bound to{\" \"}\n <Link href={profileHref({ address: ownerAddress })} title={ownerAddress} className=\"font-mono font-medium text-foreground transition-colors hover:text-primary\">\n {shortenAddress(ownerAddress)}\n </Link>\n </>\n ) : (\n \"Permanently bound to the wallet it was issued to.\"\n )}\n </p>\n </div>\n {issued ? (\n <div className=\"shrink-0 text-right\">\n <p className=\"text-xs text-muted-foreground\">Issued</p>\n <p className=\"mt-0.5 text-sm font-semibold tabular-nums text-foreground\">{issued}</p>\n </div>\n ) : null}\n </section>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBI;AAhBJ,0BAA4B;AAC5B,iBAA8C;AAC9C,kBAAiB;AACjB,qBAA+B;AAExB,SAAS,SAAS,SAAgD;AACvE,QAAM,QAAQ,QACX,OAAO,CAAC,UAAU,MAAM,SAAS,MAAM,EACvC,IAAI,CAAC,UAAU,IAAI,KAAK,MAAM,SAAS,EAAE,QAAQ,CAAC,EAClD,OAAO,CAAC,SAAS,OAAO,SAAS,IAAI,CAAC;AACzC,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,SAAO,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,CAAC,EAAE,mBAAmB,SAAS,EAAE,KAAK,WAAW,OAAO,SAAS,MAAM,UAAU,CAAC;AACrH;AAEO,SAAS,iBAAiB;AAC/B,SACE,6CAAC,UAAK,WAAU,0EACd;AAAA,gDAAC,mCAAY,WAAU,eAAc,eAAW,MAAC;AAAA,IAAE;AAAA,KAErD;AAEJ;AAOO,SAAS,cAAc,EAAE,UAAU,CAAC,GAAG,aAAa,GAAuB;AAChF,QAAM,SAAS,SAAS,OAAO;AAC/B,SACE,6CAAC,aAAQ,cAAW,mBAAkB,WAAU,0GAC9C;AAAA,gDAAC,mCAAY,WAAU,sCAAqC,aAAa,KAAK,eAAW,MAAC;AAAA,IAC1F,6CAAC,SAAI,WAAU,kBACb;AAAA,kDAAC,QAAG,WAAU,kEAAiE,uBAAS;AAAA,MACxF,4CAAC,OAAE,WAAU,iDACV,yBACC,4EAAE;AAAA;AAAA,QACqB;AAAA,QACrB,4CAAC,YAAAA,SAAA,EAAK,UAAM,wBAAY,EAAE,SAAS,aAAa,CAAC,GAAG,OAAO,cAAc,WAAU,8EAChF,6CAAe,YAAY,GAC9B;AAAA,SACF,IAEA,qDAEJ;AAAA,OACF;AAAA,IACC,SACC,6CAAC,SAAI,WAAU,uBACb;AAAA,kDAAC,OAAE,WAAU,iCAAgC,oBAAM;AAAA,MACnD,4CAAC,OAAE,WAAU,6DAA6D,kBAAO;AAAA,OACnF,IACE;AAAA,KACN;AAEJ;","names":["Link"]}
|
|
@@ -2,9 +2,11 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import { ApiActivity } from '@medialane/sdk';
|
|
3
3
|
|
|
4
4
|
declare function issuedAt(history: readonly ApiActivity[]): string | null;
|
|
5
|
+
declare function SoulboundBadge(): react_jsx_runtime.JSX.Element;
|
|
5
6
|
interface SoulboundCardProps {
|
|
6
7
|
history?: readonly ApiActivity[];
|
|
8
|
+
ownerAddress?: string | null;
|
|
7
9
|
}
|
|
8
|
-
declare function SoulboundCard({ history }: SoulboundCardProps): react_jsx_runtime.JSX.Element;
|
|
10
|
+
declare function SoulboundCard({ history, ownerAddress }: SoulboundCardProps): react_jsx_runtime.JSX.Element;
|
|
9
11
|
|
|
10
|
-
export { SoulboundCard, type SoulboundCardProps, issuedAt };
|
|
12
|
+
export { SoulboundBadge, SoulboundCard, type SoulboundCardProps, issuedAt };
|
|
@@ -2,9 +2,11 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import { ApiActivity } from '@medialane/sdk';
|
|
3
3
|
|
|
4
4
|
declare function issuedAt(history: readonly ApiActivity[]): string | null;
|
|
5
|
+
declare function SoulboundBadge(): react_jsx_runtime.JSX.Element;
|
|
5
6
|
interface SoulboundCardProps {
|
|
6
7
|
history?: readonly ApiActivity[];
|
|
8
|
+
ownerAddress?: string | null;
|
|
7
9
|
}
|
|
8
|
-
declare function SoulboundCard({ history }: SoulboundCardProps): react_jsx_runtime.JSX.Element;
|
|
10
|
+
declare function SoulboundCard({ history, ownerAddress }: SoulboundCardProps): react_jsx_runtime.JSX.Element;
|
|
9
11
|
|
|
10
|
-
export { SoulboundCard, type SoulboundCardProps, issuedAt };
|
|
12
|
+
export { SoulboundBadge, SoulboundCard, type SoulboundCardProps, issuedAt };
|
|
@@ -1,26 +1,40 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Fingerprint } from "lucide-react";
|
|
4
|
+
import { profileHref } from "@medialane/sdk";
|
|
5
|
+
import Link from "./link.js";
|
|
6
|
+
import { shortenAddress } from "../utils/address.js";
|
|
4
7
|
function issuedAt(history) {
|
|
5
8
|
const times = history.filter((event) => event.type === "mint").map((event) => new Date(event.timestamp).getTime()).filter((time) => Number.isFinite(time));
|
|
6
9
|
if (times.length === 0) return null;
|
|
7
10
|
return new Date(Math.min(...times)).toLocaleDateString("en-US", { day: "numeric", month: "short", year: "numeric" });
|
|
8
11
|
}
|
|
9
|
-
function
|
|
12
|
+
function SoulboundBadge() {
|
|
13
|
+
return /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-xs font-semibold text-brand-purple", children: [
|
|
14
|
+
/* @__PURE__ */ jsx(Fingerprint, { className: "h-3.5 w-3.5", "aria-hidden": true }),
|
|
15
|
+
"Soulbound"
|
|
16
|
+
] });
|
|
17
|
+
}
|
|
18
|
+
function SoulboundCard({ history = [], ownerAddress }) {
|
|
10
19
|
const issued = issuedAt(history);
|
|
11
|
-
return /* @__PURE__ */ jsxs("section", { "aria-label": "Soulbound asset", className: "flex items-center gap-4 rounded-2xl bg-
|
|
12
|
-
/* @__PURE__ */ jsx(
|
|
20
|
+
return /* @__PURE__ */ jsxs("section", { "aria-label": "Soulbound asset", className: "flex items-center gap-4 overflow-hidden rounded-2xl bg-gradient-to-br from-muted/40 to-transparent p-4", children: [
|
|
21
|
+
/* @__PURE__ */ jsx(Fingerprint, { className: "h-7 w-7 shrink-0 text-brand-purple", strokeWidth: 1.5, "aria-hidden": true }),
|
|
13
22
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
14
|
-
/* @__PURE__ */ jsx("h3", { className: "font-display text-
|
|
15
|
-
/* @__PURE__ */ jsx("p", { className: "mt-0.5 text-xs text-muted-foreground", children:
|
|
23
|
+
/* @__PURE__ */ jsx("h3", { className: "font-display text-base font-bold leading-tight text-foreground", children: "Soulbound" }),
|
|
24
|
+
/* @__PURE__ */ jsx("p", { className: "mt-0.5 truncate text-xs text-muted-foreground", children: ownerAddress ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
25
|
+
"Permanently bound to",
|
|
26
|
+
" ",
|
|
27
|
+
/* @__PURE__ */ jsx(Link, { href: profileHref({ address: ownerAddress }), title: ownerAddress, className: "font-mono font-medium text-foreground transition-colors hover:text-primary", children: shortenAddress(ownerAddress) })
|
|
28
|
+
] }) : "Permanently bound to the wallet it was issued to." })
|
|
16
29
|
] }),
|
|
17
|
-
issued ? /* @__PURE__ */ jsxs("
|
|
18
|
-
"
|
|
19
|
-
issued
|
|
30
|
+
issued ? /* @__PURE__ */ jsxs("div", { className: "shrink-0 text-right", children: [
|
|
31
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Issued" }),
|
|
32
|
+
/* @__PURE__ */ jsx("p", { className: "mt-0.5 text-sm font-semibold tabular-nums text-foreground", children: issued })
|
|
20
33
|
] }) : null
|
|
21
34
|
] });
|
|
22
35
|
}
|
|
23
36
|
export {
|
|
37
|
+
SoulboundBadge,
|
|
24
38
|
SoulboundCard,
|
|
25
39
|
issuedAt
|
|
26
40
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/soulbound-card.tsx"],"sourcesContent":["\"use client\";\n\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/components/soulbound-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { Fingerprint } from \"lucide-react\";\nimport { profileHref, type ApiActivity } from \"@medialane/sdk\";\nimport Link from \"./link.js\";\nimport { shortenAddress } from \"../utils/address.js\";\n\nexport function issuedAt(history: readonly ApiActivity[]): string | null {\n const times = history\n .filter((event) => event.type === \"mint\")\n .map((event) => new Date(event.timestamp).getTime())\n .filter((time) => Number.isFinite(time));\n if (times.length === 0) return null;\n return new Date(Math.min(...times)).toLocaleDateString(\"en-US\", { day: \"numeric\", month: \"short\", year: \"numeric\" });\n}\n\nexport function SoulboundBadge() {\n return (\n <span className=\"inline-flex items-center gap-1 text-xs font-semibold text-brand-purple\">\n <Fingerprint className=\"h-3.5 w-3.5\" aria-hidden />\n Soulbound\n </span>\n );\n}\n\nexport interface SoulboundCardProps {\n history?: readonly ApiActivity[];\n ownerAddress?: string | null;\n}\n\nexport function SoulboundCard({ history = [], ownerAddress }: SoulboundCardProps) {\n const issued = issuedAt(history);\n return (\n <section aria-label=\"Soulbound asset\" className=\"flex items-center gap-4 overflow-hidden rounded-2xl bg-gradient-to-br from-muted/40 to-transparent p-4\">\n <Fingerprint className=\"h-7 w-7 shrink-0 text-brand-purple\" strokeWidth={1.5} aria-hidden />\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"font-display text-base font-bold leading-tight text-foreground\">Soulbound</h3>\n <p className=\"mt-0.5 truncate text-xs text-muted-foreground\">\n {ownerAddress ? (\n <>\n Permanently bound to{\" \"}\n <Link href={profileHref({ address: ownerAddress })} title={ownerAddress} className=\"font-mono font-medium text-foreground transition-colors hover:text-primary\">\n {shortenAddress(ownerAddress)}\n </Link>\n </>\n ) : (\n \"Permanently bound to the wallet it was issued to.\"\n )}\n </p>\n </div>\n {issued ? (\n <div className=\"shrink-0 text-right\">\n <p className=\"text-xs text-muted-foreground\">Issued</p>\n <p className=\"mt-0.5 text-sm font-semibold tabular-nums text-foreground\">{issued}</p>\n </div>\n ) : null}\n </section>\n );\n}\n"],"mappings":";AAkBI,SAqBQ,UApBN,KADF;AAhBJ,SAAS,mBAAmB;AAC5B,SAAS,mBAAqC;AAC9C,OAAO,UAAU;AACjB,SAAS,sBAAsB;AAExB,SAAS,SAAS,SAAgD;AACvE,QAAM,QAAQ,QACX,OAAO,CAAC,UAAU,MAAM,SAAS,MAAM,EACvC,IAAI,CAAC,UAAU,IAAI,KAAK,MAAM,SAAS,EAAE,QAAQ,CAAC,EAClD,OAAO,CAAC,SAAS,OAAO,SAAS,IAAI,CAAC;AACzC,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,SAAO,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,CAAC,EAAE,mBAAmB,SAAS,EAAE,KAAK,WAAW,OAAO,SAAS,MAAM,UAAU,CAAC;AACrH;AAEO,SAAS,iBAAiB;AAC/B,SACE,qBAAC,UAAK,WAAU,0EACd;AAAA,wBAAC,eAAY,WAAU,eAAc,eAAW,MAAC;AAAA,IAAE;AAAA,KAErD;AAEJ;AAOO,SAAS,cAAc,EAAE,UAAU,CAAC,GAAG,aAAa,GAAuB;AAChF,QAAM,SAAS,SAAS,OAAO;AAC/B,SACE,qBAAC,aAAQ,cAAW,mBAAkB,WAAU,0GAC9C;AAAA,wBAAC,eAAY,WAAU,sCAAqC,aAAa,KAAK,eAAW,MAAC;AAAA,IAC1F,qBAAC,SAAI,WAAU,kBACb;AAAA,0BAAC,QAAG,WAAU,kEAAiE,uBAAS;AAAA,MACxF,oBAAC,OAAE,WAAU,iDACV,yBACC,iCAAE;AAAA;AAAA,QACqB;AAAA,QACrB,oBAAC,QAAK,MAAM,YAAY,EAAE,SAAS,aAAa,CAAC,GAAG,OAAO,cAAc,WAAU,8EAChF,yBAAe,YAAY,GAC9B;AAAA,SACF,IAEA,qDAEJ;AAAA,OACF;AAAA,IACC,SACC,qBAAC,SAAI,WAAU,uBACb;AAAA,0BAAC,OAAE,WAAU,iCAAgC,oBAAM;AAAA,MACnD,oBAAC,OAAE,WAAU,6DAA6D,kBAAO;AAAA,OACnF,IACE;AAAA,KACN;AAEJ;","names":[]}
|