Skip to content

Commit ee95192

Browse files
committed
[TOOL-3453] Dashboard: Fix NFT Metadata issues when adding media URLs instead of uploading (#6288)
= <!-- start pr-codex --> --- ## PR-Codex overview This PR focuses on updating the NFT metadata handling in the dashboard application, specifically renaming and refactoring properties related to custom images and animations, improving form handling, and enhancing user interface elements. ### Detailed summary - Updated documentation link in `next-env.d.ts`. - Changed `customImage` and `customAnimationUrl` to `image` and `animation_url` in multiple components. - Updated titles and headers for improved clarity in forms. - Enhanced form controls with better error handling and user feedback. - Adjusted layout and spacing in several components for better usability. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex -->
1 parent 5abbae7 commit ee95192

File tree

10 files changed

+193
-128
lines changed

10 files changed

+193
-128
lines changed

apps/dashboard/next-env.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
/// <reference types="next/image-types/global" />
33

44
// NOTE: This file should not be edited
5-
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
5+
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/BatchMetadata.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ const uploadMetadataFormSchema = z.object({
4141
image: fileBufferOrStringSchema.optional(),
4242
animationUri: fileBufferOrStringSchema.optional(),
4343
external_url: fileBufferOrStringSchema.optional(),
44-
customImage: z.string().optional(),
45-
customAnimationUrl: z.string().optional(),
4644
background_color: z
4745
.string()
4846
.refine(

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/Mintable.tsx

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,6 @@ export type MintFormValues = NFTMetadataInputLimited & {
5454
useNextTokenId: boolean;
5555
recipient: string;
5656
amount: number;
57-
customImage: string;
58-
customAnimationUrl: string;
5957
attributes: { trait_type: string; value: string }[];
6058
tokenId?: string;
6159
};
@@ -65,8 +63,7 @@ const isValidNft = (values: MintFormValues) =>
6563
values.description ||
6664
values.image ||
6765
values.animation_url ||
68-
values.external_url ||
69-
values.customAnimationUrl;
66+
values.external_url;
7067

7168
const MINTER_ROLE = 1n;
7269

@@ -334,8 +331,6 @@ function PrimarySalesSection(props: {
334331

335332
const mintFormSchema = z.object({
336333
useNextTokenId: z.boolean(),
337-
customImage: z.string().optional(),
338-
customAnimationUrl: z.string().optional(),
339334
recipient: addressSchema,
340335
tokenId: z.coerce.number().min(0, { message: "Invalid tokenId" }).optional(),
341336
});
@@ -351,8 +346,6 @@ function MintNFTSection(props: {
351346
resolver: zodResolver(mintFormSchema),
352347
values: {
353348
useNextTokenId: false,
354-
customImage: "",
355-
customAnimationUrl: "",
356349
recipient: "",
357350
attributes: [{ trait_type: "", value: "" }],
358351
amount: 1,

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/nft/AdvancedNFTMetadataFormGroup.tsx

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ import type { UseFormReturn } from "react-hook-form";
1414
import type { NFTInput } from "thirdweb/utils";
1515

1616
type AdvancedNFTMetadataFormGroupValues = {
17-
customImage?: string;
18-
customAnimationUrl?: string;
17+
image?: NFTInput["image"];
18+
animation_url?: NFTInput["animation_url"];
1919
background_color?: NFTInput["background_color"];
2020
external_url?: NFTInput["external_url"];
2121
};
@@ -56,12 +56,15 @@ export function AdvancedNFTMetadataFormGroup<
5656

5757
<FormField
5858
control={form.control}
59-
name="customImage"
59+
name="image"
6060
render={({ field }) => (
6161
<FormItem>
6262
<FormLabel>Image URI</FormLabel>
6363
<FormControl>
64-
<Input {...field} />
64+
<Input
65+
{...field}
66+
value={typeof field.value === "string" ? field.value : ""}
67+
/>
6568
</FormControl>
6669
<FormDescription>
6770
If you already have your NFT image pre-uploaded, you can set the
@@ -74,12 +77,15 @@ export function AdvancedNFTMetadataFormGroup<
7477

7578
<FormField
7679
control={form.control}
77-
name="customAnimationUrl"
80+
name="animation_url"
7881
render={({ field }) => (
7982
<FormItem>
8083
<FormLabel>Animation URI</FormLabel>
8184
<FormControl>
82-
<Input {...field} />
85+
<Input
86+
{...field}
87+
value={typeof field.value === "string" ? field.value : ""}
88+
/>
8389
</FormControl>
8490
<FormDescription>
8591
If you already have your NFT Animation URL pre-uploaded, you can

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/update-metadata-form.tsx

Lines changed: 62 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
AccordionIcon,
88
AccordionItem,
99
AccordionPanel,
10-
Divider,
1110
FormControl,
1211
Input,
1312
Textarea,
@@ -32,6 +31,7 @@ import {
3231
updateTokenURI as updateTokenURI1155,
3332
} from "thirdweb/extensions/erc1155";
3433
import { useActiveAccount, useSendAndConfirmTransaction } from "thirdweb/react";
34+
import type { NFTMetadata } from "thirdweb/utils";
3535
import {
3636
Button,
3737
FormErrorMessage,
@@ -68,20 +68,20 @@ export const UpdateNftMetadata: React.FC<UpdateNftMetadataForm> = ({
6868
const address = useActiveAccount()?.address;
6969

7070
const transformedQueryData = useMemo(() => {
71-
return {
72-
name: nft?.metadata.name || "",
73-
description: nft?.metadata.description || "",
74-
external_url: nft?.metadata.external_url || "",
75-
background_color: nft?.metadata.background_color || "",
76-
attributes: nft?.metadata.attributes || [],
77-
// We override these in the submit if they haven't been changed
78-
image: nft?.metadata.image || undefined,
79-
animation_url: nft?.metadata.animation_url || undefined,
80-
// No need for these, but we need to pass them to the form
81-
supply: 0,
82-
customImage: "",
83-
customAnimationUrl: "",
71+
const nftMetadata: Partial<NFTMetadata> = {
72+
// basic
73+
name: nft.metadata.name || "",
74+
description: nft.metadata.description || "",
75+
// media
76+
image: nft.metadata.image,
77+
animation_url: nft.metadata.animation_url,
78+
// advanced
79+
external_url: nft.metadata.external_url || "",
80+
background_color: nft.metadata.background_color || "",
81+
attributes: nft.metadata.attributes,
8482
};
83+
84+
return nftMetadata;
8585
}, [nft]);
8686

8787
const {
@@ -91,13 +91,7 @@ export const UpdateNftMetadata: React.FC<UpdateNftMetadataForm> = ({
9191
watch,
9292
handleSubmit,
9393
formState: { errors, isDirty },
94-
} = useForm<
95-
NFTMetadataInputLimited & {
96-
supply: number;
97-
customImage: string;
98-
customAnimationUrl: string;
99-
}
100-
>({
94+
} = useForm<NFTMetadataInputLimited>({
10195
defaultValues: transformedQueryData,
10296
values: transformedQueryData,
10397
});
@@ -140,6 +134,9 @@ export const UpdateNftMetadata: React.FC<UpdateNftMetadataForm> = ({
140134
};
141135

142136
const imageUrl = useImageFileOrUrl(watch("image") as File | string);
137+
const animationUrlFormValue = watch("animation_url");
138+
const imageUrlFormValue = watch("image");
139+
143140
const mediaFileUrl =
144141
watch("animation_url") instanceof File
145142
? watch("animation_url")
@@ -190,11 +187,8 @@ export const UpdateNftMetadata: React.FC<UpdateNftMetadataForm> = ({
190187
try {
191188
const newMetadata = parseAttributes({
192189
...data,
193-
image: data.image || data.customImage || nft.metadata.image,
194-
animation_url:
195-
data.animation_url ||
196-
data.customAnimationUrl ||
197-
nft.metadata.animation_url,
190+
image: data.image || nft.metadata.image,
191+
animation_url: data.animation_url || nft.metadata.animation_url,
198192
});
199193

200194
const transaction = useUpdateMetadata
@@ -249,10 +243,6 @@ export const UpdateNftMetadata: React.FC<UpdateNftMetadataForm> = ({
249243
}
250244
})}
251245
>
252-
<div className="flex flex-col gap-2">
253-
<Heading size="subtitle.md">Metadata</Heading>
254-
<Divider />
255-
</div>
256246
<FormControl isRequired isInvalid={!!errors.name}>
257247
<FormLabel>Name</FormLabel>
258248
<Input autoFocus {...register("name")} />
@@ -263,22 +253,34 @@ export const UpdateNftMetadata: React.FC<UpdateNftMetadataForm> = ({
263253
<div className="flex flex-row flex-wrap gap-3">
264254
{nft?.metadata && !mediaFileUrl && (
265255
<NFTMediaWithEmptyState
266-
metadata={nft.metadata}
256+
metadata={{
257+
name: nft.metadata.name,
258+
animation_url:
259+
typeof animationUrlFormValue === "string"
260+
? animationUrlFormValue
261+
: nft.metadata.animation_url,
262+
image:
263+
typeof imageUrlFormValue === "string"
264+
? imageUrlFormValue
265+
: nft.metadata.image,
266+
}}
267267
width="200px"
268268
height="200px"
269269
/>
270270
)}
271+
271272
<FileInput
272273
previewMaxWidth="200px"
273274
value={mediaFileUrl as File | string}
274275
showUploadButton
275276
showPreview={nft?.metadata ? !!mediaFileUrl : true}
276277
setValue={setFile}
277-
className="rounded border border-border transition-all duration-200"
278+
className="shrink-0 rounded border border-border transition-all duration-200"
278279
selectOrUpload="Upload"
279280
helperText={nft?.metadata ? "New Media" : "Media"}
280281
/>
281282
</div>
283+
282284
<FormHelperText>
283285
You can upload image, audio, video, html, text, pdf, and 3d model
284286
files here.
@@ -319,6 +321,7 @@ export const UpdateNftMetadata: React.FC<UpdateNftMetadataForm> = ({
319321
register={register}
320322
setValue={setValue}
321323
/>
324+
322325
<Accordion
323326
allowToggle={!(errors.background_color || errors.external_url)}
324327
index={errors.background_color || errors.external_url ? [0] : undefined}
@@ -328,7 +331,7 @@ export const UpdateNftMetadata: React.FC<UpdateNftMetadataForm> = ({
328331
<Heading size="subtitle.md">Advanced Options</Heading>
329332
<AccordionIcon />
330333
</AccordionButton>
331-
<AccordionPanel className="flex flex-col gap-6 px-0">
334+
<AccordionPanel className="!px-0 flex flex-col gap-6">
332335
<FormControl isInvalid={!!errors.background_color}>
333336
<FormLabel>
334337
Background Color <OpenSeaPropertyBadge />
@@ -357,26 +360,40 @@ export const UpdateNftMetadata: React.FC<UpdateNftMetadataForm> = ({
357360
</FormErrorMessage>
358361
</FormControl>
359362
)}
360-
<FormControl isInvalid={!!errors.customImage}>
363+
<FormControl isInvalid={!!errors.image}>
361364
<FormLabel>Image URL</FormLabel>
362-
<Input max="6" {...register("customImage")} />
365+
<Input
366+
value={
367+
typeof imageUrlFormValue === "string" ? imageUrlFormValue : ""
368+
}
369+
onChange={(e) => {
370+
setValue("image", e.target.value);
371+
}}
372+
/>
363373
<FormHelperText>
364-
If you already have your NFT image pre-uploaded, you can set the
365-
URL or URI here.
374+
If you already have your NFT image pre-uploaded to a URL, you
375+
can specify it here instead of uploading the media file
366376
</FormHelperText>
367-
<FormErrorMessage>
368-
{errors?.customImage?.message}
369-
</FormErrorMessage>
377+
<FormErrorMessage>{errors?.image?.message}</FormErrorMessage>
370378
</FormControl>
371-
<FormControl isInvalid={!!errors.customAnimationUrl}>
379+
<FormControl isInvalid={!!errors.animation_url}>
372380
<FormLabel>Animation URL</FormLabel>
373-
<Input max="6" {...register("customAnimationUrl")} />
381+
<Input
382+
value={
383+
typeof animationUrlFormValue === "string"
384+
? animationUrlFormValue
385+
: ""
386+
}
387+
onChange={(e) => {
388+
setValue("animation_url", e.target.value);
389+
}}
390+
/>
374391
<FormHelperText>
375-
If you already have your NFT Animation URL pre-uploaded, you can
376-
set the URL or URI here.
392+
If you already have your NFT Animation URL pre-uploaded to a
393+
URL, you can specify it here instead of uploading the media file
377394
</FormHelperText>
378395
<FormErrorMessage>
379-
{errors?.customAnimationUrl?.message}
396+
{errors?.animation_url?.message}
380397
</FormErrorMessage>
381398
</FormControl>
382399
</AccordionPanel>

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/update-metadata-tab.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ const UpdateMetadataTab: React.FC<UpdateMetadataTabProps> = ({
3636
<Button variant="primary">Update Metadata</Button>
3737
</SheetTrigger>
3838
<SheetContent className="w-full overflow-y-auto sm:min-w-[540px] lg:min-w-[700px]">
39-
<SheetHeader>
40-
<SheetTitle className="text-left">Mint NFT</SheetTitle>
39+
<SheetHeader className="mb-5">
40+
<SheetTitle className="text-left">Update NFT Metadata</SheetTitle>
4141
</SheetHeader>
4242
<UpdateNftMetadata
4343
twAccount={twAccount}

0 commit comments

Comments
 (0)