Last active
July 14, 2023 09:18
-
-
Save dicethedev/0406fb8c307fd8e6a95a197afd4072ec to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"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