Skip to content

Instantly share code, notes, and snippets.

@dicethedev
Last active July 14, 2023 09:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dicethedev/0406fb8c307fd8e6a95a197afd4072ec to your computer and use it in GitHub Desktop.
Save dicethedev/0406fb8c307fd8e6a95a197afd4072ec to your computer and use it in GitHub Desktop.
"use client";
import ContainerWrapper from "@/components/ContainerWrapper";
import { useState, useEffect } from "react";
import { Box, Text, Flex, Icon, Button, Input, Stack, HStack, Skeleton, useToast } from "@chakra-ui/react";
import { useAppSelector } from "@/hooks/rtkHooks";
import { Link } from "@chakra-ui/next-js";
import { ME_SVG } from "@/assets/svg";
import { CiSettings } from "react-icons/ci";
import TokenSelectOption from "@/components/SelectOptions/TokenSelect";
import { options } from "@/utils/tokens";
import { ethers } from "ethers";
import { shortenAddress } from "@/constants/shortenedAddress";
import { secretoryService } from "@/call/services/secretory";
import { magic } from "@/lib/magic";
import { createWeb3 } from "@/lib/web3";
import MyToast from "@/constants/CustomToast";
const contractABI = [
{
constant: true,
inputs: [{ name: "_owner", type: "address" }],
name: "balanceOf",
outputs: [{ name: "balance", type: "uint256" }],
type: "function",
},
];
type Props = {};
const RedeemUI = ({ pipelineData }: any) => {
const { appTheme } = useAppSelector((state) => state.themeReducer);
const [selectAddress, setSelectAddress] = useState<string>("");
const [selectAddress2, setSelectAddress2] = useState<string>("");
const [amountToSwap, setAmountToSwap] = useState<number>(0);
const [balance1, setBalance1] = useState<string | null>("0");
const [balance2, setBalance2] = useState<string | null>("0");
const [swapPositions, setSwapPositions] = useState<boolean>(false);
const [tokenContractAddress1, setTokenContractAddress1] = useState<string>("");
const [tokenContractAddress2, setTokenContractAddress2] = useState<string>("");
const [isLoadingBalance, setIsLoadingBalance] = useState<boolean>(false);
const toast = useToast();
const handleSelect = async (value: any) => {
setSelectAddress(value);
const selectedToken = options.find((option: any) => option.value === value);
if (selectedToken) {
setTokenContractAddress1(selectedToken.value || "");
console.log(selectedToken.value || "", "this is working")
await getBalance(); // Fetch balance after setting the token and contract address
}
};
const handleSelect2 = async (value: any) => {
setSelectAddress2(value);
const selectedToken = options.find((option: any) => option.value === value);
if (selectedToken) {
setTokenContractAddress2(selectedToken.value || "");
console.log(selectedToken.value || "", "this is working")
await getBalance(); // Fetch balance after setting the token and contract address
}
};
const handleSpend = () => {
const selectedToken1 = selectAddress;
const selectedToken2 = selectAddress2;
const inputValue = amountToSwap;
// Call the function to handle spend with the selectedToken1, selectedToken2, and inputValue
// Example: secretoryService.handleSpend(selectedToken1, selectedToken2, inputValue);
// Replace `secretoryService.handleSpend` with your actual function or service
};
const handleInput1Change = (event: React.ChangeEvent<HTMLInputElement>) => {
const value = event.target.value;
const amount = parseFloat(value);
if (!isNaN(amount)) {
setAmountToSwap(amount);
} else {
setAmountToSwap(0);
}
};
const getBalance = async () => {
setIsLoadingBalance(true);
const magicWeb3 = await createWeb3(magic);
try {
//@ts-ignore
const accounts = await magicWeb3.eth.getAccounts();
//@ts-ignore
const provider = new ethers.providers.Web3Provider(magic.rpcProvider);
if (tokenContractAddress1) {
const contract1 = new ethers.Contract(tokenContractAddress1, contractABI, provider);
const balanceResult1: ethers.BigNumber = await contract1.balanceOf(accounts[0]);
const tokenBalance1: string = formatBalance(balanceResult1);
setBalance1(tokenBalance1);
}
if (tokenContractAddress2) {
const contract2 = new ethers.Contract(tokenContractAddress2, contractABI, provider);
const balanceResult2: ethers.BigNumber = await contract2.balanceOf(accounts[0]);
const tokenBalance2: string = formatBalance(balanceResult2);
setBalance2(tokenBalance2);
}
} catch (error: any) {
console.error("Error fetching balance:", error);
if (error.code === -32603 && error.message.includes("429 Too Many Requests")) {
// Display a specific error message for rate limit exceeded
console.error("Rate limit exceeded. Please try again later.");
toast({
position: 'bottom-right',
duration: 5000,
isClosable: true,
render: () => <MyToast title="Rate limit exceeded" description=". Please try again later." />,
});
} else {
// Display a generic error message for other errors
console.error("An error occurred while fetching the balance.");
toast({
position: 'bottom-right',
duration: 5000,
isClosable: true,
render: () => <MyToast title="Rate limit exceeded" description=". Please try again later." />,
});
}
}
setIsLoadingBalance(false);
};
const formatBalance = (balance: ethers.BigNumber): string => {
const balanceInEther = ethers.utils.formatEther(balance);
const formattedBalance = parseFloat(balanceInEther).toLocaleString(undefined, {
maximumFractionDigits: 2,
});
return formattedBalance;
};
useEffect(() => {
getBalance();
}, []);
return (
<ContainerWrapper>
<Stack pt="50px" h="100vh">
<Flex flexDir="column">
<HStack mb="10px">
<Flex
w="30px"
h="30px"
justify="center"
alignItems="center"
border="1px solid black"
cursor="pointer"
>
<Link href={"/consumer"}>{ME_SVG().arrowRight()}</Link>
</Flex>
<Text fontSize="16px" lineHeight="20px" width="fit-content" fontWeight="500">
Back
</Text>
</HStack>
<Flex justify="center" alignItems="center">
<Box
pos="relative"
transition="transform 250ms ease 0s"
border="1px solid black"
maxWidth="480px"
width="100%"
borderRadius="20px"
bg="#F3F3F3"
padding="6px"
>
<Flex justifyContent="space-between" alignItems="center" p="8px 12px">
<Text fontSize="18px" fontWeight="500" color={appTheme.backgroundColorReverse}>
Spend
</Text>
<Flex cursor="pointer">
<Icon as={CiSettings} color="#000000" boxSize={"24px"} />
</Flex>
</Flex>
<Flex flexDir={swapPositions ? "column" : "column-reverse"}>
{/* ------------------ Box Swap one ---------------- */}
<Box
background="linear-gradient(90deg, rgba(196,196,196,1) 0%, rgba(221,219,219,1) 50%, rgba(201,201,201,1) 100%)"
borderRadius="12px"
p="16px"
lineHeight="20px"
fontWeight="500"
>
<Flex justifyContent="space-between" alignItems="center">
<Flex flexDir="column" textAlign="left">
<Input
type="text"
placeholder="0"
_placeholder={{ fontSize: "28px", lineHeight: "44px", opacity: "1" }}
fontSize="28px"
fontWeight="500"
textOverflow="ellipsis"
minLength={1}
position="relative"
outline="none"
flex="1 1 auto"
maxLength={79}
inputMode="decimal"
transition="opacity 0.2s ease-in-out 0s"
autoComplete="off"
autoCorrect="off"
pattern="^[0-9]*[.,]?[0-9]*$"
spellCheck="false"
color="black"
w="200px"
border="none"
_focus={{ outline: "none", boxShadow: "none" }}
value={amountToSwap * 2}
/>
</Flex>
<Flex flexDir="column" textAlign="right">
<TokenSelectOption options={options} onSelect={handleSelect} />
{isLoadingBalance ? (
// Show skeleton while loading
<Skeleton h="20px" w="80px" mt="10px" />
) : (
// Show actual balance
<Text fontWeight="400" mt="10px">
Balance: {balance1}
</Text>
)}
</Flex>
</Flex>
</Box>
{/* --------------- change select option modal switcher --------------- */}
<Flex
borderRadius="12px"
height="40px"
width="40px"
position="relative"
margin="-18px auto"
backgroundColor="#C3C3C3"
border="4px solid #F3F3F3"
zIndex="2"
cursor="pointer"
transition="all ease-in-out .2s"
_hover={{ opacity: "1", bg: "#F5F5F5", border: "4px solid black" }}
onClick={() => setSwapPositions(!swapPositions)}
as="button"
>
<Flex alignItems="center" justifyContent="center" ml="4px" alignSelf={"center"}>
<HStack> {ME_SVG().changeIcon()}</HStack>
</Flex>
</Flex>
{/* --------------- The end of change select option modal switcher --------------- */}
{/* ------------------ Box Swap two ---------------- */}
<Box
// bg="#C3C3C3"
background="linear-gradient(90deg, rgba(196,196,196,1) 0%, rgba(221,219,219,1) 50%, rgba(201,201,201,1) 100%)"
borderRadius="12px"
p="16px"
lineHeight="20px"
fontWeight="500"
>
<Flex justifyContent="space-between" alignItems="center">
<Flex flexDir="column" textAlign="left">
<Input
type="text"
placeholder="0"
_placeholder={{ fontSize: "28px", lineHeight: "44px", opacity: "1" }}
fontSize="28px"
fontWeight="500"
textOverflow="ellipsis"
textAlign="left"
minLength={1}
position="relative"
outline="none"
flex="1 1 auto"
maxLength={79}
inputMode="decimal"
transition="opacity 0.2s ease-in-out 0s"
autoComplete="off"
autoCorrect="off"
pattern="^[0-9]*[.,]?[0-9]*$"
spellCheck="false"
color="black"
w="200px"
border="none"
_focus={{ outline: "none", boxShadow: "none" }}
value={amountToSwap.toString()} // Set the value of the input
onChange={handleInput1Change} // Update the amountToSwap state
/>
</Flex>
<Flex flexDir="column" textAlign="right">
<TokenSelectOption options={options} onSelect={handleSelect2} />
{isLoadingBalance ? (
// Show skeleton while loading
<Skeleton h="20px" w="80px" mt="10px" />
) : (
// Show actual balance
<Text fontWeight="400" mt="10px">
Balance: {balance2}
</Text>
)}
</Flex>
</Flex>
</Box>
</Flex>
<Button
borderRadius="15px"
bg="#000000"
color="white"
w="100%"
h="50px"
fontWeight="600"
_hover={{ bg: "black", color: "white" }}
mt="4px"
onClick={handleSpend}
>
Spend
</Button>
</Box>
</Flex>
</Flex>
</Stack>
</ContainerWrapper>
);
};
export default RedeemUI;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment