Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
kien-ngo committed Sep 20, 2024
2 parents 2bb558b + 8fa6227 commit 86b4d24
Show file tree
Hide file tree
Showing 4 changed files with 211 additions and 194 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import {
SheetContent,
SheetHeader,
SheetTitle,
SheetTrigger,
} from "@/components/ui/sheet";
import { Icon } from "@chakra-ui/react";
import { Droplet } from "lucide-react";
import { useState } from "react";
import { FiDroplet } from "react-icons/fi";
import type { ThirdwebContract } from "thirdweb";
import { balanceOf } from "thirdweb/extensions/erc20";
import { useActiveAccount, useReadContract } from "thirdweb/react";
Expand All @@ -33,24 +33,23 @@ export const TokenAirdropButton: React.FC<TokenAirdropButtonProps> = ({
const [open, setOpen] = useState(false);

return (
<>
<Sheet open={open} onOpenChange={setOpen}>
<SheetContent className="z-[10000] lg:w-[700px] sm:w-[540px] sm:max-w-[90%]">
<SheetHeader>
<SheetTitle>Aidrop tokens</SheetTitle>
</SheetHeader>
<TokenAirdropForm contract={contract} />
</SheetContent>
</Sheet>
<Button
colorScheme="primary"
leftIcon={<Icon as={FiDroplet} />}
{...restButtonProps}
onClick={() => setOpen(true)}
isDisabled={!hasBalance}
>
Airdrop
</Button>
</>
<Sheet open={open} onOpenChange={setOpen}>
<SheetTrigger>
<Button
colorScheme="primary"
leftIcon={<Droplet size={16} />}
{...restButtonProps}
isDisabled={!hasBalance}
>
Airdrop
</Button>
</SheetTrigger>
<SheetContent className="z-[10000] lg:w-[700px] sm:w-[540px] sm:max-w-[90%]">
<SheetHeader>
<SheetTitle>Aidrop tokens</SheetTitle>
</SheetHeader>
<TokenAirdropForm contract={contract} toggle={setOpen} />
</SheetContent>
</Sheet>
);
};
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { Flex, Icon, Stack } from "@chakra-ui/react";
import { TransactionButton } from "components/buttons/TransactionButton";
import { useTrack } from "hooks/analytics/useTrack";
import { useTxNotifications } from "hooks/useTxNotifications";
import { useState } from "react";
import { CircleCheck, Upload } from "lucide-react";
import { type Dispatch, type SetStateAction, useState } from "react";
import { useForm } from "react-hook-form";
import { BsCircleFill } from "react-icons/bs";
import { FiUpload } from "react-icons/fi";
import { toast } from "sonner";
import type { ThirdwebContract } from "thirdweb";
import { transferBatch } from "thirdweb/extensions/erc20";
import { useActiveAccount, useSendAndConfirmTransaction } from "thirdweb/react";
Expand All @@ -17,10 +15,12 @@ import {

interface TokenAirdropFormProps {
contract: ThirdwebContract;
toggle?: Dispatch<SetStateAction<boolean>>;
}

export const TokenAirdropForm: React.FC<TokenAirdropFormProps> = ({
contract,
toggle,
}) => {
const address = useActiveAccount()?.address;
const { handleSubmit, setValue, watch, formState } = useForm<{
Expand All @@ -30,15 +30,7 @@ export const TokenAirdropForm: React.FC<TokenAirdropFormProps> = ({
});
const trackEvent = useTrack();
const sendTransaction = useSendAndConfirmTransaction();

const { onSuccess, onError } = useTxNotifications(
"Airdrop successful",
"Error transferring",
contract,
);

const addresses = watch("addresses");

const [airdropFormOpen, setAirdropFormOpen] = useState(false);

return (
Expand All @@ -63,15 +55,19 @@ export const TokenAirdropForm: React.FC<TokenAirdropFormProps> = ({
})),
});

sendTransaction.mutate(tx, {
const promise = sendTransaction.mutateAsync(tx, {
onSuccess: () => {
onSuccess();
trackEvent({
category: "token",
action: "airdrop",
label: "success",
contract_address: contract.address,
});

// Close the sheet/modal on success
if (toggle) {
toggle(false);
}
},
onError: (error) => {
trackEvent({
Expand All @@ -81,17 +77,18 @@ export const TokenAirdropForm: React.FC<TokenAirdropFormProps> = ({
contract_address: contract.address,
error,
});
onError(error);
console.error(error);
},
});

toast.promise(promise, {
loading: "Airdropping tokens",
success: "Tokens airdropped successfully",
error: "Failed to airdrop tokens",
});
})}
>
<Stack
spacing={6}
w="100%"
direction={{ base: "column", md: "row" }}
mb={3}
>
<div className="flex flex-col md:flex-row w-full gap-6 mb-3">
{airdropFormOpen ? (
<AirdropUploadERC20
onClose={() => setAirdropFormOpen(false)}
Expand All @@ -100,37 +97,31 @@ export const TokenAirdropForm: React.FC<TokenAirdropFormProps> = ({
}
/>
) : (
<Flex direction={{ base: "column", md: "row" }} gap={4}>
<div className="flex flex-col md:flex-row gap-4">
<Button
colorScheme="primary"
borderRadius="md"
onClick={() => setAirdropFormOpen(true)}
rightIcon={<Icon as={FiUpload} />}
rightIcon={<Upload size={16} />}
>
Upload addresses
</Button>

<Flex
gap={2}
direction="row"
align="center"
justify="center"
color={addresses.length === 0 ? "orange.500" : "green.500"}
>
{addresses.length > 0 && (
<>
<Icon as={BsCircleFill} boxSize={2} />
<Text size="body.sm" color="inherit">
<strong>{addresses.length} addresses</strong> ready to
be airdropped
</Text>
</>
)}
</Flex>
</Flex>
{addresses.length > 0 && (
<div className="gap-2 flex flex-row items-center justify-center text-green-500">
<CircleCheck className="text-green-500" size={16} />
<Text size="body.sm" color="inherit">
<strong>{addresses.length} addresses</strong> ready to be
airdropped
</Text>
</div>
)}
</div>
)}
</Stack>
</div>
{!airdropFormOpen && (
// Todo: for erc20 you definitely can airdrop to more than 250 recipients in 1 tx
// maybe tweak this number?
<Text>
You can airdrop to a maximum of 250 addresses at a time. If you
have more, please do it in multiple transactions.
Expand Down
Loading

0 comments on commit 86b4d24

Please sign in to comment.