diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/ContractSettingsPage.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/ContractSettingsPage.tsx index d6e8d5bde72..a7d35ccef97 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/ContractSettingsPage.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/ContractSettingsPage.tsx @@ -1,76 +1,62 @@ "use client"; -import { Flex, GridItem, SimpleGrid } from "@chakra-ui/react"; import type { ThirdwebContract } from "thirdweb"; import * as CommonExt from "thirdweb/extensions/common"; +import { cn } from "@/lib/utils"; import { SettingsMetadata } from "./components/metadata"; import { SettingsPlatformFees } from "./components/platform-fees"; import { SettingsPrimarySale } from "./components/primary-sale"; import { SettingsRoyalties } from "./components/royalties"; -interface ContractSettingsPageProps { +const ContractSettingsPageInner = (props: { contract: ThirdwebContract; isContractMetadataSupported: boolean; isPrimarySaleSupported: boolean; isRoyaltiesSupported: boolean; isPlatformFeesSupported: boolean; isLoggedIn: boolean; -} - -const ContractSettingsPageInner: React.FC = ({ - contract, - isContractMetadataSupported, - isPrimarySaleSupported, - isRoyaltiesSupported, - isPlatformFeesSupported, - isLoggedIn, }) => { return ( - - - - {contract && ( - - - - )} - {contract && ( - - - - )} +
+
+ +
- {contract && ( - - - - )} +
+ +
- {contract && ( - - - - )} - - - +
+ +
+ +
+ +
+
); }; @@ -83,28 +69,35 @@ export function ContractSettingsPage(props: { const { functionSelectors, contract, isLoggedIn, hasDefaultFeeConfig } = props; return ( - +
+

Settings

+

+ Configure the settings for your contract +

+ + +
); } diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/components/metadata.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/components/metadata.tsx index 807249aca2a..0b83b7b67fd 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/components/metadata.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/components/metadata.tsx @@ -1,21 +1,10 @@ "use client"; -import { - Flex, - FormControl, - IconButton, - Input, - Textarea, -} from "@chakra-ui/react"; import { zodResolver } from "@hookform/resolvers/zod"; -import { Button } from "chakra/button"; -import { Card } from "chakra/card"; -import { FormErrorMessage, FormLabel } from "chakra/form"; -import { Heading } from "chakra/heading"; -import { Text } from "chakra/text"; import { PlusIcon, Trash2Icon } from "lucide-react"; import { useMemo } from "react"; import { useFieldArray, useForm } from "react-hook-form"; +import { toast } from "sonner"; import type { ThirdwebContract } from "thirdweb"; import { getContractMetadata, @@ -27,9 +16,21 @@ import { z } from "zod"; import { FileInput } from "@/components/blocks/FileInput"; import { AdminOnly } from "@/components/contracts/roles/admin-only"; import { TransactionButton } from "@/components/tx-button"; -import { useTxNotifications } from "@/hooks/useTxNotifications"; +import { Button } from "@/components/ui/button"; +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { Skeleton } from "@/components/ui/skeleton"; +import { Textarea } from "@/components/ui/textarea"; import { CommonContractSchema } from "@/schema/schemas"; import type { ExtensionDetectedState } from "@/types/ExtensionDetectedState"; +import { parseError } from "@/utils/errorParser"; import { SettingDetectedState } from "./detected-state"; const DashboardCommonContractSchema = CommonContractSchema.extend({ @@ -105,15 +106,7 @@ export const SettingsMetadata = ({ }; }, [metadata.data, contract.client]); - const { - control, - setValue, - register, - watch, - handleSubmit, - formState, - getFieldState, - } = useForm>({ + const form = useForm>({ defaultValues: transformedQueryData, resetOptions: { keepDirty: true, @@ -124,205 +117,218 @@ export const SettingsMetadata = ({ }); const { fields, append, remove } = useFieldArray({ - control, + control: form.control, // @ts-expect-error - TODO: fix this name: "dashboard_social_urls", }); - const { onSuccess, onError } = useTxNotifications( - "Successfully updated metadata", - "Error updating metadata", - contract, - ); + const onSubmit = (d: z.input) => { + const { dashboard_social_urls, ...data } = d; - return ( - - - { - const { dashboard_social_urls, ...data } = d; + const socialUrlsArray = + Object.keys(dashboard_social_urls || {}).length > 0 + ? (dashboard_social_urls as unknown as { + key: string; + value: string; + }[]) + : []; - const socialUrlsArray = - Object.keys(dashboard_social_urls || {}).length > 0 - ? (dashboard_social_urls as unknown as { - key: string; - value: string; - }[]) - : []; + const socialUrlsObj = socialUrlsArray.reduce>( + (obj, item) => { + const platform = item.key || extractDomain(item.value); + if (platform && item.value.trim() !== "") { + obj[platform] = item.value; + } + return obj; + }, + {}, + ); - const socialUrlsObj = socialUrlsArray.reduce>( - (obj, item) => { - const domain = extractDomain(item.value); - if (domain && item.value.trim() !== "") { - obj[domain] = item.value; - } - return obj; - }, - {}, - ); + const tx = setContractMetadata({ + contract, + ...data, + social_urls: socialUrlsObj, + }); - const tx = setContractMetadata({ - contract, - ...data, - social_urls: socialUrlsObj, - }); + sendTransaction.mutate(tx, { + onError: (error) => { + toast.error("Error updating metadata", { + description: parseError(error), + }); + console.error(error); + }, + onSuccess: () => { + toast.success("Metadata updated"); + }, + }); + }; - sendTransaction.mutate(tx, { - onError: (error) => { - onError(error); - }, - onSuccess: () => { - onSuccess(); - }, - }); - })} - > - -
- Metadata - - Settings to organize and distinguish between your different - contracts. - -
- - - - Image - - setValue("image", file, { - shouldDirty: true, - shouldTouch: true, - }) - } - value={watch("image")} - /> - - {getFieldState("image", formState).error?.message} - - - + return ( +
+ +
+ +
+ {/* header */} +
+

Metadata

+

+ Settings to organize and distinguish between your different + contracts. +

+
- - - - Name - - - {getFieldState("name", formState).error?.message} - - - + {metadata.isPending ? ( + + ) : ( +
+
+ {/* image */} +
+ ( + + Image + + field.onChange(file)} + value={field.value} + /> + + + + )} + /> +
- - Description -