diff --git a/apps/dashboard/src/contract-ui/tabs/nfts/components/claim-button.tsx b/apps/dashboard/src/contract-ui/tabs/nfts/components/claim-button.tsx index eeba7cd75d5..41e239e5ab2 100644 --- a/apps/dashboard/src/contract-ui/tabs/nfts/components/claim-button.tsx +++ b/apps/dashboard/src/contract-ui/tabs/nfts/components/claim-button.tsx @@ -1,10 +1,27 @@ "use client"; -import { useDisclosure } from "@chakra-ui/react"; +import { + Sheet, + SheetContent, + SheetHeader, + SheetTitle, + SheetTrigger, +} from "@/components/ui/sheet"; +import { FormControl, Input } from "@chakra-ui/react"; +import { TransactionButton } from "components/buttons/TransactionButton"; +import { useTrack } from "hooks/analytics/useTrack"; import { GemIcon } from "lucide-react"; -import type { ThirdwebContract } from "thirdweb"; -import { Button, Drawer } from "tw-components"; -import { NFTClaimForm } from "./claim-form"; +import { useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { type ThirdwebContract, ZERO_ADDRESS } from "thirdweb"; +import { getApprovalForTransaction } from "thirdweb/extensions/erc20"; +import { claimTo } from "thirdweb/extensions/erc721"; +import { useActiveAccount, useSendAndConfirmTransaction } from "thirdweb/react"; +import { Button } from "tw-components"; +import { FormErrorMessage, FormHelperText, FormLabel } from "tw-components"; + +const CLAIM_FORM_ID = "nft-claim-form"; interface NFTClaimButtonProps { contract: ThirdwebContract; @@ -15,26 +32,133 @@ interface NFTClaimButtonProps { * For Edition Drop we have a dedicated ClaimTabERC1155 inside each Edition's page */ export const NFTClaimButton: React.FC = ({ contract }) => { - const { isOpen, onOpen, onClose } = useDisclosure(); + const trackEvent = useTrack(); + const address = useActiveAccount()?.address; + const { register, handleSubmit, formState } = useForm({ + defaultValues: { amount: "1", to: address }, + }); + const { errors } = formState; + const sendAndConfirmTx = useSendAndConfirmTransaction(); + const account = useActiveAccount(); + const [open, setOpen] = useState(false); return ( - <> - - - - - + + + + + + + Claim NFTs + +
+
+ + To Address + + Enter the address to claim to. + {errors.to?.message} + + + Amount + { + const valueNum = Number(value); + if (!Number.isInteger(valueNum)) { + return "Amount must be an integer"; + } + }, + })} + /> + How many would you like to claim? + {errors.amount?.message} + +
+
+
+ { + trackEvent({ + category: "nft", + action: "claim", + label: "attempt", + }); + if (!account) { + return toast.error("No account detected"); + } + if (!d.to) { + return toast.error( + "Please enter the address that will receive the NFT", + ); + } + + const transaction = claimTo({ + contract, + to: d.to, + quantity: BigInt(d.amount), + from: account.address, + }); + + const approveTx = await getApprovalForTransaction({ + transaction, + account, + }); + + if (approveTx) { + const promise = sendAndConfirmTx.mutateAsync(approveTx, { + onError: (error) => { + console.error(error); + }, + }); + toast.promise(promise, { + loading: "Approving ERC20 tokens for this claim", + success: "Tokens approved successfully", + error: "Failed to approve token", + }); + + await promise; + } + + const promise = sendAndConfirmTx.mutateAsync(transaction, { + onSuccess: () => { + trackEvent({ + category: "nft", + action: "claim", + label: "success", + }); + setOpen(false); + }, + onError: (error) => { + trackEvent({ + category: "nft", + action: "claim", + label: "error", + error, + }); + }, + }); + + toast.promise(promise, { + loading: "Claiming NFT(s)", + success: "NFT(s) claimed successfully", + error: "Failed to claim NFT(s)", + }); + })} + > + Claim NFT + +
+
+
); }; diff --git a/apps/dashboard/src/contract-ui/tabs/nfts/components/claim-form.tsx b/apps/dashboard/src/contract-ui/tabs/nfts/components/claim-form.tsx deleted file mode 100644 index 9e8752aa367..00000000000 --- a/apps/dashboard/src/contract-ui/tabs/nfts/components/claim-form.tsx +++ /dev/null @@ -1,152 +0,0 @@ -"use client"; - -import { - DrawerBody, - DrawerFooter, - DrawerHeader, - FormControl, - Input, - useModalContext, -} from "@chakra-ui/react"; -import { TransactionButton } from "components/buttons/TransactionButton"; -import { useTrack } from "hooks/analytics/useTrack"; -import { useTxNotifications } from "hooks/useTxNotifications"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { type ThirdwebContract, ZERO_ADDRESS } from "thirdweb"; -import { getApprovalForTransaction } from "thirdweb/extensions/erc20"; -import { claimTo } from "thirdweb/extensions/erc721"; -import { useActiveAccount, useSendAndConfirmTransaction } from "thirdweb/react"; -import { - FormErrorMessage, - FormHelperText, - FormLabel, - Heading, -} from "tw-components"; - -const CLAIM_FORM_ID = "nft-claim-form"; -interface NFTClaimFormProps { - contract: ThirdwebContract; -} - -export const NFTClaimForm: React.FC = ({ contract }) => { - const trackEvent = useTrack(); - const address = useActiveAccount()?.address; - const { register, handleSubmit, formState } = useForm({ - defaultValues: { amount: "1", to: address }, - }); - const { errors } = formState; - const modalContext = useModalContext(); - - const txNotifications = useTxNotifications( - "Successfully claimed NFTs", - "Failed to claim NFT", - contract, - ); - const sendAndConfirmTx = useSendAndConfirmTransaction(); - const account = useActiveAccount(); - - return ( - <> - - Claim NFTs - - -
-
- - To Address - - Enter the address to claim to. - {errors.to?.message} - - - Amount - { - const valueNum = Number(value); - if (!Number.isInteger(valueNum)) { - return "Amount must be an integer"; - } - }, - })} - /> - How many would you like to claim? - {errors.amount?.message} - -
-
-
- - { - trackEvent({ - category: "nft", - action: "claim", - label: "attempt", - }); - if (!account) { - return toast.error("No account detected"); - } - if (!d.to) { - return txNotifications.onError( - new Error("Please enter the address that will receive the NFT"), - ); - } - - try { - const transaction = claimTo({ - contract, - to: d.to, - quantity: BigInt(d.amount), - from: account.address, - }); - - const approveTx = await getApprovalForTransaction({ - transaction, - account, - }); - - if (approveTx) { - try { - await sendAndConfirmTx.mutateAsync(approveTx); - } catch { - return toast.error("Error approving ERC20 token"); - } - } - - await sendAndConfirmTx.mutateAsync(transaction); - - trackEvent({ - category: "nft", - action: "claim", - label: "success", - }); - txNotifications.onSuccess(); - modalContext.onClose(); - } catch (error) { - trackEvent({ - category: "nft", - action: "claim", - label: "error", - error, - }); - - txNotifications.onError(error); - } - })} - > - Claim NFT - - - - ); -};