Skip to content

Commit

Permalink
[Dashboard] Replace erc721 claim Drawer with Sheet
Browse files Browse the repository at this point in the history
  • Loading branch information
kien-ngo committed Oct 6, 2024
1 parent 715000a commit 685b1f6
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 175 deletions.
170 changes: 147 additions & 23 deletions apps/dashboard/src/contract-ui/tabs/nfts/components/claim-button.tsx
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -15,26 +32,133 @@ interface NFTClaimButtonProps {
* For Edition Drop we have a dedicated ClaimTabERC1155 inside each Edition's page
*/
export const NFTClaimButton: React.FC<NFTClaimButtonProps> = ({ 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 (
<>
<Drawer
allowPinchZoom
preserveScrollBarGap
size="lg"
onClose={onClose}
isOpen={isOpen}
>
<NFTClaimForm contract={contract} />
</Drawer>
<Button
colorScheme="primary"
leftIcon={<GemIcon className="size-4" />}
onClick={onOpen}
>
Claim
</Button>
</>
<Sheet open={open} onOpenChange={setOpen}>
<SheetTrigger asChild>
<Button colorScheme="primary" leftIcon={<GemIcon className="size-4" />}>
Claim
</Button>
</SheetTrigger>
<SheetContent className="z-[10000] overflow-y-auto sm:w-[540px] sm:max-w-[90%] lg:w-[700px]">
<SheetHeader>
<SheetTitle>Claim NFTs</SheetTitle>
</SheetHeader>
<form className="mt-8 flex w-full flex-col gap-3 md:flex-row">
<div className="flex w-full flex-col gap-6 md:flex-row">
<FormControl isRequired isInvalid={!!errors.to}>
<FormLabel>To Address</FormLabel>
<Input placeholder={ZERO_ADDRESS} {...register("to")} />
<FormHelperText>Enter the address to claim to.</FormHelperText>
<FormErrorMessage>{errors.to?.message}</FormErrorMessage>
</FormControl>
<FormControl isRequired isInvalid={!!errors.amount}>
<FormLabel>Amount</FormLabel>
<Input
type="text"
{...register("amount", {
validate: (value) => {
const valueNum = Number(value);
if (!Number.isInteger(valueNum)) {
return "Amount must be an integer";
}
},
})}
/>
<FormHelperText>How many would you like to claim?</FormHelperText>
<FormErrorMessage>{errors.amount?.message}</FormErrorMessage>
</FormControl>
</div>
</form>
<div className="mt-4 flex justify-end">
<TransactionButton
txChainID={contract.chain.id}
transactionCount={1}
form={CLAIM_FORM_ID}
isLoading={formState.isSubmitting}
type="submit"
colorScheme="primary"
onClick={handleSubmit(async (d) => {
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
</TransactionButton>
</div>
</SheetContent>
</Sheet>
);
};
152 changes: 0 additions & 152 deletions apps/dashboard/src/contract-ui/tabs/nfts/components/claim-form.tsx

This file was deleted.

0 comments on commit 685b1f6

Please sign in to comment.