|
1 | 1 | "use client"; |
2 | 2 |
|
| 3 | +import { |
| 4 | + Sheet, |
| 5 | + SheetContent, |
| 6 | + SheetHeader, |
| 7 | + SheetTitle, |
| 8 | + SheetTrigger, |
| 9 | +} from "@/components/ui/sheet"; |
3 | 10 | import { MinterOnly } from "@3rdweb-sdk/react/components/roles/minter-only"; |
4 | | -import { useDisclosure } from "@chakra-ui/react"; |
| 11 | +import { FormControl, Input, Select } from "@chakra-ui/react"; |
| 12 | +import { TransactionButton } from "components/buttons/TransactionButton"; |
| 13 | +import { useTrack } from "hooks/analytics/useTrack"; |
5 | 14 | import { EyeIcon } from "lucide-react"; |
| 15 | +import { useState } from "react"; |
| 16 | +import { useForm } from "react-hook-form"; |
| 17 | +import { toast } from "sonner"; |
6 | 18 | import type { ThirdwebContract } from "thirdweb"; |
7 | | -import { getBatchesToReveal } from "thirdweb/extensions/erc721"; |
8 | | -import { useReadContract } from "thirdweb/react"; |
9 | | -import { Button, Drawer } from "tw-components"; |
10 | | -import { NFTRevealForm } from "./reveal-form"; |
| 19 | +import { getBatchesToReveal, reveal } from "thirdweb/extensions/erc721"; |
| 20 | +import { useReadContract, useSendAndConfirmTransaction } from "thirdweb/react"; |
| 21 | +import { Button, FormErrorMessage, FormLabel } from "tw-components"; |
11 | 22 |
|
12 | 23 | interface NFTRevealButtonProps { |
13 | 24 | contract: ThirdwebContract; |
14 | 25 | } |
15 | 26 |
|
| 27 | +const REVEAL_FORM_ID = "reveal-form"; |
| 28 | + |
16 | 29 | export const NFTRevealButton: React.FC<NFTRevealButtonProps> = ({ |
17 | 30 | contract, |
18 | 31 | }) => { |
19 | | - const { isOpen, onOpen, onClose } = useDisclosure(); |
20 | 32 | const batchesQuery = useReadContract(getBatchesToReveal, { |
21 | 33 | contract, |
22 | 34 | }); |
| 35 | + const trackEvent = useTrack(); |
| 36 | + |
| 37 | + const sendTxMutation = useSendAndConfirmTransaction(); |
| 38 | + |
| 39 | + const { |
| 40 | + register, |
| 41 | + handleSubmit, |
| 42 | + formState: { errors, isDirty }, |
| 43 | + } = useForm<{ batchId: string; password: string }>(); |
| 44 | + |
| 45 | + const [open, setOpen] = useState(false); |
| 46 | + |
23 | 47 | return batchesQuery.data?.length ? ( |
24 | 48 | <MinterOnly contract={contract}> |
25 | | - <Drawer |
26 | | - allowPinchZoom |
27 | | - preserveScrollBarGap |
28 | | - size="lg" |
29 | | - onClose={onClose} |
30 | | - isOpen={isOpen} |
31 | | - > |
32 | | - <NFTRevealForm |
33 | | - contract={contract} |
34 | | - batchesToReveal={batchesQuery.data} |
35 | | - /> |
36 | | - </Drawer> |
37 | | - <Button |
38 | | - colorScheme="primary" |
39 | | - leftIcon={<EyeIcon className="size-4" />} |
40 | | - onClick={onOpen} |
41 | | - > |
42 | | - Reveal NFTs |
43 | | - </Button> |
| 49 | + <Sheet open={open} onOpenChange={setOpen}> |
| 50 | + <SheetTrigger asChild> |
| 51 | + <Button |
| 52 | + colorScheme="primary" |
| 53 | + leftIcon={<EyeIcon className="size-4" />} |
| 54 | + > |
| 55 | + Reveal NFTs |
| 56 | + </Button> |
| 57 | + </SheetTrigger> |
| 58 | + <SheetContent className="z-[10000] overflow-y-auto sm:w-[540px] sm:max-w-[90%] lg:w-[700px]"> |
| 59 | + <SheetHeader> |
| 60 | + <SheetTitle>Reveal batch</SheetTitle> |
| 61 | + </SheetHeader> |
| 62 | + <form |
| 63 | + className="mt-10 flex flex-col gap-6" |
| 64 | + id={REVEAL_FORM_ID} |
| 65 | + onSubmit={handleSubmit((data) => { |
| 66 | + trackEvent({ |
| 67 | + category: "nft", |
| 68 | + action: "batch-upload-reveal", |
| 69 | + label: "attempt", |
| 70 | + }); |
| 71 | + |
| 72 | + const tx = reveal({ |
| 73 | + contract, |
| 74 | + batchId: BigInt(data.batchId), |
| 75 | + password: data.password, |
| 76 | + }); |
| 77 | + |
| 78 | + const promise = sendTxMutation.mutateAsync(tx, { |
| 79 | + onSuccess: () => { |
| 80 | + trackEvent({ |
| 81 | + category: "nft", |
| 82 | + action: "batch-upload-reveal", |
| 83 | + label: "success", |
| 84 | + }); |
| 85 | + setOpen(false); |
| 86 | + }, |
| 87 | + onError: (error) => { |
| 88 | + console.error(error); |
| 89 | + trackEvent({ |
| 90 | + category: "nft", |
| 91 | + action: "batch-upload-reveal", |
| 92 | + label: "error", |
| 93 | + }); |
| 94 | + }, |
| 95 | + }); |
| 96 | + |
| 97 | + toast.promise(promise, { |
| 98 | + loading: "Revealing batch", |
| 99 | + success: "Batch revealed successfully", |
| 100 | + error: "Failed to reveal batch", |
| 101 | + }); |
| 102 | + })} |
| 103 | + > |
| 104 | + <FormControl isRequired isInvalid={!!errors.password} mr={4}> |
| 105 | + <FormLabel>Select a batch</FormLabel> |
| 106 | + <Select {...register("batchId")} autoFocus> |
| 107 | + {batchesQuery.data.map((batch) => ( |
| 108 | + <option |
| 109 | + key={batch.batchId.toString()} |
| 110 | + value={batch.batchId.toString()} |
| 111 | + > |
| 112 | + {batch.placeholderMetadata?.name || |
| 113 | + batch.batchId.toString()} |
| 114 | + </option> |
| 115 | + ))} |
| 116 | + </Select> |
| 117 | + <FormErrorMessage>{errors?.password?.message}</FormErrorMessage> |
| 118 | + </FormControl> |
| 119 | + <FormControl isRequired isInvalid={!!errors.password} mr={4}> |
| 120 | + <FormLabel>Password</FormLabel> |
| 121 | + <Input |
| 122 | + {...register("password")} |
| 123 | + autoFocus |
| 124 | + placeholder="The one you used to upload this batch" |
| 125 | + type="password" |
| 126 | + /> |
| 127 | + <FormErrorMessage>{errors?.password?.message}</FormErrorMessage> |
| 128 | + </FormControl> |
| 129 | + </form> |
| 130 | + <div className="mt-4 flex justify-end"> |
| 131 | + <TransactionButton |
| 132 | + txChainID={contract.chain.id} |
| 133 | + transactionCount={1} |
| 134 | + isLoading={sendTxMutation.isPending} |
| 135 | + form={REVEAL_FORM_ID} |
| 136 | + type="submit" |
| 137 | + colorScheme="primary" |
| 138 | + isDisabled={!isDirty} |
| 139 | + > |
| 140 | + Reveal NFTs |
| 141 | + </TransactionButton> |
| 142 | + </div> |
| 143 | + </SheetContent> |
| 144 | + </Sheet> |
44 | 145 | </MinterOnly> |
45 | 146 | ) : null; |
46 | 147 | }; |
0 commit comments