Files
rubix-explore/src/pages/Home.jsx
YasinShaikh123 aaf3be3eb0 update
2024-11-05 20:12:36 +05:30

339 lines
11 KiB
JavaScript

import {
border,
Box,
Button,
Container,
FormControl,
Heading,
HStack,
Icon,
Input,
InputGroup,
InputLeftElement,
Text,
useColorMode,
useToast,
VStack,
} from "@chakra-ui/react";
import React, { useState } from "react";
import { IoSearch } from "react-icons/io5";
import LineChart from "../components/Doughnut/LineChart";
import AmountCard from "../components/AmountCard/AmountCard";
import SwitchCharts from "../components/SwitchBtn/SwitchCharts";
import LatestTransactions from "../components/LatestTransactions/LatestTransactions";
import { Link, useNavigate } from "react-router-dom";
import Pagination from "../components/Pagination";
import bannerImage from "../assets/images/bannerImg.png";
import bannerImageMobile from "../assets/images/bannerImgmobile.png";
import { BiSearchAlt } from "react-icons/bi";
import { MdContentCopy } from "react-icons/md";
import { RiFileCopyLine } from "react-icons/ri";
import { RiFileCopyFill } from "react-icons/ri";
import { motion, AnimatePresence } from "framer-motion"; // Import AnimatePresence and motion
import { useGnerateShortUrlMutation } from "../Services/api.service";
import ToastBox from "../components/ToastBox";
const AnimatedBox = motion(HStack); // Create an animated HStack
const Home = () => {
const [isSwitchOn, setIsSwitchOn] = useState(true);
const { colorMode, toggleColorMode } = useColorMode();
const [ linkVisible, setLinkVisible ] = useState(false)
const [ searchTerm, setSearchTerm] = useState(null)
const navigate = useNavigate()
const [ shortURL, setShortURL ] = useState("Invalid hash...")
const [ isLoading, setIsLoading ] = useState(false)
const [ isCopy, setIsCopy ] = useState(false)
const toast = useToast()
const[ genrateSortURL ] = useGnerateShortUrlMutation()
// const handleGenrateShortURL = async () => {
// try {
// // Ensure searchTerm is converted to a string before passing to the API
// const res = await genrateSortURL(JSON.stringify(searchTerm));
// console.log(res);
// } catch (error) {
// console.error("Error generating short URL:", error);
// }
// };
// function copyToClipboard(text) {
// if (!navigator.clipboard) {
// console.error("Clipboard API is not available.");
// return;
// }
// navigator.clipboard
// .writeText(text)
// .then(() => {
// toast({
// render: () => (
// <ToastBox status={"warn"} message={"Text copied to clipboard"} />
// ),
// });
// setIsCopy(true)
// })
// .catch((err) => {
// console.error("Failed to copy text: ", err);
// });
// }
function copyToClipboard(text) {
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard
.writeText(text)
.then(() => {
toast({
render: () => (
<ToastBox status={"warn"} message={"Text copied to clipboard"} />
),
});
setIsCopy(true)
})
.catch((err) => {
console.error("Failed to copy text: ", err);
});
} else {
// Fallback method for unsupported browsers
const textArea = document.createElement("textarea");
textArea.value = text;
document.body.appendChild(textArea);
textArea.select();
try {
document.execCommand("copy");
toast({
render: () => (
<ToastBox status={"warn"} message={"Text copied to clipboard"} />
),
});
setIsCopy(true)
} catch (err) {
console.error("Fallback: Failed to copy text: ", err);
}
document.body.removeChild(textArea);
}
}
const handleGenrateShortURL = async () => {
setLinkVisible(true)
setIsLoading(true)
try {
const response = await fetch(`${import.meta.env.VITE_BASE_URL}ShortUrl/create`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(searchTerm), // Sending searchTerm as a JSON string
});
if (!response.ok) {
throw new Error('Failed to generate short URL');
}
const result = await response.json();
console.log(result);
setShortURL(result?.shortUrl)
setIsLoading(false)
// You can handle the result here, e.g., by updating a state with the short URL
} catch (error) {
console.error("Error generating short URL:", error);
}
};
return (
<Box
minH={"100vh"}
bg={colorMode === "light" ? "#f5f5f7" : "none"}
backgroundImage={{base:colorMode !== "light" ? `url(${bannerImageMobile})` : "none",md:colorMode !== "light" ? `url(${bannerImage})` : "none"}}
backgroundSize="contain"
backgroundRepeat="no-repeat">
<Box>
<VStack pt={{base:colorMode === "light"?28:24,md:28}} mb={{base:8,md: false ?8: 14}}>
<Container maxW="3xl" position={"relative"}>
<Box w={'100%'} display={"flex"} alignItems={"center"} flexDirection={'column'} gap={6}>
<InputGroup
width={"100%"}
boxShadow={"sm"}
size="sm"
bg={colorMode === "light" ? "light.100" : "#393939"}
// border={"none"}
rounded={'lg'}
>
<Input
roundedLeft={8}
w={"76%"}
// border={`1px solid ${
// colorMode === "light" ? "#230A79" : "#393939"
// }`}
borderColor={colorMode === "light"? "#CED4DA" : "#565252"}
h={"42px"}
type="search"
placeholder="Search by Transaction hash, token hash , DID or smart contract"
onChange={(e) => setSearchTerm(e.target.value)}
_hover={{
borderColor:"#7f8c8d"
}}
_placeholder={{color:"#737C82"}}
_focusVisible={{
borderColor:
colorMode === "light" ? "#230A79" : "#7f8c8d",
}}
/>
<Button
zIndex={99}
h={"42px"}
w={{base :'205px',md :'24%'}}
fontWeight={400}
right={"0"}
top={"0"}
fontSize={"sm"}
rounded={0}
border="none"
bg={colorMode === "light" ? "#4023A6" : "#565252"}
_hover={{
opacity:0.9,
bg: colorMode !== "light" && "#333248",
cursor:!searchTerm?'not-allowed':"pointer"
}}
_focus={{ opacity:1, outline:'none', bg:colorMode === "light" ? "#4023A6" : "#565252" }}
_active={{ opacity:0.9, outline:'none', bg:colorMode === "light" ? "#4023A6" : "#565252" }}
color={'#fff'}
isLoading={isLoading}
onClick={handleGenrateShortURL}
// isDisabled={!searchTerm}
pointerEvents={!searchTerm?'none':"auto"}
>
Generate Short Url
</Button>
<Box
position={"inherit"}
right={"0"}
h={"42px"}
w={{base :'64px',md :'6%'}}
roundedRight={7}
display={"flex"}
justifyContent={"center"}
alignItems={"center"}
bg={colorMode === "light" ? "#DEDBEB" : "#393939"}
color={colorMode === "light" ? "#230A79" : "#fff"}
cursor={'pointer'}
onClick={()=>navigate(`/transaction/${searchTerm}`)}
border={`1px solid ${
colorMode === "light" ? "#230A79" : "#565252"
}`}
>
{/* <IoSearch fontSize={"20px"} /> */}
<BiSearchAlt fontSize={"20px"} />
</Box>
</InputGroup>
{/* Slide-down animated HStack */}
<AnimatePresence>
{isLoading || linkVisible && (
<AnimatedBox
initial={{ opacity: 0, y: -10 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -10 }}
transition={{ duration: 0.3 }}
shadow={"md"}
bg={colorMode === "light" ? "#DEDBEB" : "#575252"}
ps={5}
pe={3}
pt={4}
pb={4}
justifyContent={"space-between"}
rounded={"md"}
w={"100%"}
>
<Text as={"span"} color={colorMode==="light"?"#230A79":"#ccc"} fontSize={"sm"} textDecoration={"underline"}>
{shortURL}
</Text>
<Icon
_hover={{ bg: "#ccc" }}
transition={"0.5s"}
boxSize={7}
p={1.5}
cursor={"pointer"}
rounded={"md"}
as={isCopy ? RiFileCopyFill :RiFileCopyLine}
color={colorMode==="light"?"#230A79":"#ccc"}
onClick={()=>copyToClipboard(shortURL)}
/>
</AnimatedBox>
)}
</AnimatePresence>
</Box>
</Container>
</VStack>
<AmountCard />
<Container maxW="6xl" p={{base: "2rem 1rem",md:"4rem 1rem"}}>
<Box
boxShadow={
colorMode === "light"
? "rgba(99, 99, 99, 0.2) 0px 2px 8px 0px;"
: "none"
}
p={{base :1,md : 5}}
rounded={10}
bg={colorMode === "light" ? "#DEDBEB47" : "#232127"}
>
<LineChart />
</Box>
</Container>
</Box>
<Box w={'100%'} pb={"3rem"} pt={colorMode!=="light" &&10} bg={colorMode === "light" ? "light.100" : "#101015"}>
<Container
maxW="6xl"
color="white"
display={"flex"}
justifyContent={"space-between"}
mb={6}
>
<Heading
fontSize={"md"}
fontWeight={500}
color={colorMode === "light" ? "#000" : "#fff"}
>
Latest Transactions
</Heading>
<Link
to="/view-all-transaction"
style={{
fontSize: "14px",
color: colorMode === "light" ? "#000" : "#fff",
}}
>
<Box as="span" _hover={{color: colorMode === "light" ? "#000" : "#fff"}}> View all</Box>
</Link>
</Container>
<LatestTransactions />
</Box>
</Box>
);
};
export default Home;