432 lines
14 KiB
JavaScript
432 lines
14 KiB
JavaScript
import {
|
|
Box,
|
|
Container,
|
|
Grid,
|
|
GridItem,
|
|
HStack,
|
|
Icon,
|
|
Image,
|
|
Text,
|
|
VStack,
|
|
keyframes,
|
|
useColorMode,
|
|
useToast,
|
|
} from "@chakra-ui/react";
|
|
import React, { useContext, useEffect, useState } from "react";
|
|
import { MdContentCopy, MdOutlineErrorOutline } from "react-icons/md";
|
|
import Pagination from "../Pagination";
|
|
import GlobalStateContext from "../../Contexts/GlobalStateContext";
|
|
import { Link, useLocation, useNavigate } from "react-router-dom";
|
|
import ToastBox from "../ToastBox";
|
|
import { formatRelativeDate } from "../../Constants/Constants";
|
|
import {
|
|
useGetTransAllQuery,
|
|
useGetTransCountQuery,
|
|
} from "../../Services/api.service";
|
|
import rbtLogoOutline from "../../assets/images/rubix-filled.svg";
|
|
import { HiOutlineRefresh } from "react-icons/hi";
|
|
|
|
export const rotate = keyframes`
|
|
from {
|
|
transform: rotate(0deg);
|
|
}
|
|
to {
|
|
transform: rotate(360deg);
|
|
}
|
|
`;
|
|
|
|
const LatestTransactions = () => {
|
|
const toast = useToast();
|
|
const navigate = useNavigate();
|
|
const location = useLocation();
|
|
useEffect(() => {
|
|
window.scrollTo({ top: 0, behavior: "smooth" }); // Scroll to top smoothly when params change
|
|
}, [location]);
|
|
|
|
const { colorMode } = useColorMode();
|
|
const [isRotating, setIsRotating] = useState(false);
|
|
const [currentPage, setCurrentPage] = useState(1); // Tracks the current page
|
|
const [pageSize, setPageSize] = useState(10); // Number of items per page
|
|
const [totalItems, setTotalItems] = useState(null); // Total items in the dataset
|
|
|
|
const {
|
|
data: transCount,
|
|
isLoading: isTransCountLoading,
|
|
refetch: transCountRefetch,
|
|
errors: transCountErrors,
|
|
} = useGetTransCountQuery();
|
|
|
|
// Fetch transactions based on the current page and page size
|
|
const {
|
|
data: transAll,
|
|
isLoading: isTransAllLoading,
|
|
refetch: transAllRefetch,
|
|
} = useGetTransAllQuery({
|
|
pageNumber: currentPage,
|
|
pageSize: pageSize,
|
|
});
|
|
|
|
// Set interval to refetch data every 30 seconds
|
|
// useEffect(() => {
|
|
// const intervalId = setInterval(() => {
|
|
// transCountRefetch(); // Refetch transaction count
|
|
// transAllRefetch(); // Refetch transactions
|
|
// }, 30000); // 30000 ms = 30 seconds
|
|
|
|
// return () => clearInterval(intervalId); // Clear interval on component unmount
|
|
// }, [transCountRefetch, transAllRefetch]);
|
|
|
|
useEffect(() => {
|
|
setTotalItems(transCount?.data?.transactionCount);
|
|
}, [transCount]);
|
|
|
|
function copyToClipboard(text) {
|
|
navigator.clipboard
|
|
.writeText(text)
|
|
.then(() => {
|
|
toast({
|
|
render: () => (
|
|
<ToastBox status={"warn"} message={"Text copied to clipboard"} />
|
|
),
|
|
});
|
|
})
|
|
.catch((err) => {
|
|
console.error("Failed to copy text: ", err);
|
|
});
|
|
}
|
|
|
|
|
|
const handleRefreshClick = () => {
|
|
setIsRotating(true); // Start rotation
|
|
// Simulate any refresh logic here
|
|
setTimeout(() => {
|
|
setIsRotating(false); // Stop rotation after 3 seconds
|
|
}, 3000); // 3 seconds = 3000ms
|
|
};
|
|
return (
|
|
<Container
|
|
mt={location?.pathname === "/view-all-transaction" ? 24 : 0}
|
|
mb={location?.pathname === "/view-all-transaction" ? 15 : 0}
|
|
maxW="6xl"
|
|
>
|
|
<Grid
|
|
position={"relative"}
|
|
templateColumns={{ base: "100% 0%", md: "10% 90%" }}
|
|
gap={0}
|
|
bg={colorMode === "light" ? "#230A79" : "#232127"}
|
|
// bg={"#232127"}
|
|
roundedTop={"lg"}
|
|
>
|
|
<GridItem display={{ base: "none", md: "grid" }} p={2}>
|
|
<Text color={"#fff"}>Sr. no</Text>
|
|
</GridItem>
|
|
<GridItem p={2}>
|
|
<Text color={"#fff"}>Transactions</Text>
|
|
</GridItem>
|
|
|
|
<Box
|
|
as="span"
|
|
cursor={"pointer"}
|
|
bg={"#434147"}
|
|
position={"absolute"}
|
|
right={0}
|
|
rounded={"md"}
|
|
m={1.5}
|
|
p={1.5}
|
|
|
|
onClick={handleRefreshClick} // Trigger the rotation when clicked
|
|
>
|
|
<HiOutlineRefresh
|
|
style={{
|
|
animation: true
|
|
? `${rotate} 1s linear infinite` // Apply the rotation animation
|
|
: "none",
|
|
}}
|
|
/>
|
|
</Box>
|
|
</Grid>
|
|
<Box
|
|
roundedBottom={"lg"}
|
|
overflow={"hidden"}
|
|
boxShadow={"rgba(99, 99, 99, 0.2) 0px 2px 8px 0px;"}
|
|
>
|
|
{transAll?.data?.items?.map(
|
|
(
|
|
{
|
|
transactionId,
|
|
smartContract,
|
|
sender,
|
|
receiver,
|
|
contract,
|
|
timestamp,
|
|
amount,
|
|
transactionType,
|
|
subNetworkId,
|
|
},
|
|
index
|
|
) => (
|
|
<Grid
|
|
bg={
|
|
index % 2 === 0
|
|
? colorMode === "light"
|
|
? "#F2EFFF"
|
|
: "#312F35"
|
|
: colorMode === "light"
|
|
? "#fff"
|
|
: "#232127"
|
|
}
|
|
key={transactionId}
|
|
templateColumns={{ base: "100% 0%", md: "10% 90%" }}
|
|
gap={0}
|
|
>
|
|
<GridItem
|
|
display={{ base: "none", md: "grid" }}
|
|
p={4}
|
|
color={colorMode === "light" ? "#000" : "#fff"}
|
|
>
|
|
{index + 1}.
|
|
</GridItem>
|
|
<GridItem p={4}>
|
|
{/* <Box> */}
|
|
<Text // This ensures the text is truncated with ellipsis when it overflows ss__298
|
|
display={"flex"}
|
|
fontSize={{ base: "xs", md: "sm" }}
|
|
mb={2}
|
|
color={colorMode === "light" ? "#230A79" : "#B09AFF"}
|
|
>
|
|
<Text
|
|
maxW={{ base: "100%", md: "100%" }} // Set a max-width to control when the truncation happens
|
|
// overflow={'hidden'} // Ensure overflow is hidden
|
|
whiteSpace={"nowrap"} // Prevent the text from wrapping
|
|
textOverflow={"ellipsis"}
|
|
isTruncated
|
|
cursor={"pointer"}
|
|
onClick={() => navigate(`/transaction/${transactionId}`)}
|
|
>
|
|
{transactionId}
|
|
</Text>
|
|
|
|
<Text
|
|
_hover={{ bg: "gray.50" }}
|
|
transition={"0.5s"}
|
|
rounded={"sm"}
|
|
p={1}
|
|
as={"span"}
|
|
ml={1}
|
|
cursor={"pointer"}
|
|
>
|
|
<MdContentCopy
|
|
onClick={() => copyToClipboard(transactionId)}
|
|
/>
|
|
</Text>
|
|
</Text>
|
|
|
|
<HStack
|
|
fontSize={{ base: "xs", md: "sm" }}
|
|
gap={{ base: 2, md: 4 }}
|
|
mb={2}
|
|
>
|
|
<Text color={colorMode === "light" ? "#0F0F0F" : "#E8E8E8"}>
|
|
Sender:
|
|
</Text>
|
|
|
|
<HStack
|
|
color={colorMode === "light" ? "#230A79" : "#B09AFF"}
|
|
textDecoration={"underline"}
|
|
w={"84%"}
|
|
// justifyContent={'space-between'}
|
|
fontSize={{ base: "xs", md: "sm" }}
|
|
>
|
|
<Text
|
|
cursor={"pointer"}
|
|
maxW={{ base: "90%", md: "100%" }} // Set a max-width to control when the truncation happens
|
|
// overflow={'hidden'} // Ensure overflow is hidden
|
|
whiteSpace={"nowrap"} // Prevent the text from wrapping
|
|
textOverflow={"ellipsis"}
|
|
isTruncated
|
|
onClick={() => navigate(`/did-info/${sender}`)}
|
|
>
|
|
{sender}
|
|
</Text>
|
|
<Text
|
|
_hover={{ bg: "gray.50" }}
|
|
transition={"0.5s"}
|
|
rounded={"sm"}
|
|
p={1}
|
|
as={"span"}
|
|
ml={1}
|
|
cursor={"pointer"}
|
|
>
|
|
<MdContentCopy onClick={() => copyToClipboard(sender)} />
|
|
</Text>
|
|
</HStack>
|
|
</HStack>
|
|
<HStack
|
|
fontSize={{ base: "xs", md: "sm" }}
|
|
cursor={"pointer"}
|
|
gap={{ base: 2, md: 4 }}
|
|
mb={3}
|
|
>
|
|
<Text color={colorMode === "light" ? "#0F0F0F" : "#E8E8E8"}>
|
|
Receiver:
|
|
</Text>
|
|
<HStack
|
|
color={colorMode === "light" ? "#230A79" : "#B09AFF"}
|
|
textDecoration={"underline"}
|
|
fontSize={{ base: "xs", md: "sm" }}
|
|
>
|
|
<Text
|
|
cursor={"pointer"}
|
|
maxW={{ base: "55%", md: "100%" }}
|
|
whiteSpace={"nowrap"} // Prevent the text from wrapping
|
|
textOverflow={"ellipsis"}
|
|
isTruncated
|
|
onClick={() => navigate(`/did-info/${receiver}`)}
|
|
>
|
|
{receiver}
|
|
</Text>
|
|
<Text
|
|
_hover={{ bg: "gray.50" }}
|
|
transition={"0.5s"}
|
|
rounded={"sm"}
|
|
p={1}
|
|
as={"span"}
|
|
ml={1}
|
|
cursor={"pointer"}
|
|
>
|
|
<MdContentCopy
|
|
onClick={() => copyToClipboard(receiver)}
|
|
/>
|
|
</Text>
|
|
</HStack>
|
|
</HStack>
|
|
<HStack
|
|
flexDirection={{ base: "column", md: "row" }}
|
|
justifyContent={{ base: "", md: "flex-start" }}
|
|
gap={44}
|
|
alignItems={{ base: "flex-start", md: "" }}
|
|
// flexWrap={'wrap'}
|
|
|
|
// w={"80%"}
|
|
w={{ base: "100%", md: "80%" }}
|
|
fontSize={{ base: "xs", md: "sm" }}
|
|
mb={3}
|
|
>
|
|
{smartContract && (
|
|
<Box>
|
|
<Text
|
|
mb={2}
|
|
// fontSize={{base:"xs", md:"sm" }}
|
|
color={colorMode === "light" ? "#7B7B7B" : "#E8E8E8"}
|
|
>
|
|
Smart contract ID :
|
|
</Text>
|
|
<Text
|
|
color={colorMode === "light" ? "#230A79" : "#B09AFF"}
|
|
>
|
|
<Link to="/smart-contract">{smartContract}</Link>
|
|
</Text>
|
|
</Box>
|
|
)}
|
|
<Box>
|
|
<Text
|
|
mb={2}
|
|
color={colorMode === "light" ? "#7B7B7B" : "#E8E8E8"}
|
|
>
|
|
Date and Time Stamp :
|
|
</Text>
|
|
<Text color={colorMode === "light" ? "#230A79" : "#B09AFF"}>
|
|
{formatRelativeDate(timestamp)}
|
|
</Text>
|
|
</Box>
|
|
<Box>
|
|
<Text
|
|
mb={2}
|
|
color={colorMode === "light" ? "#7B7B7B" : "#E8E8E8"}
|
|
>
|
|
Amount:
|
|
</Text>
|
|
<Text
|
|
display={"flex"}
|
|
gap={2}
|
|
alignItems={"center"}
|
|
color={colorMode === "light" ? "#230A79" : "#B09AFF"}
|
|
>
|
|
<Image src={rbtLogoOutline} />
|
|
{amount}
|
|
</Text>
|
|
</Box>
|
|
</HStack>
|
|
|
|
<HStack
|
|
fontSize={"sm"}
|
|
alignItems={"flex-start"}
|
|
position={"relative"}
|
|
>
|
|
<Icon
|
|
as={MdOutlineErrorOutline}
|
|
fontSize={"18px"}
|
|
display={{ base: "none", md: "block" }}
|
|
style={{
|
|
marginTop: "1px",
|
|
position: "absolute",
|
|
top: "2px",
|
|
left: "-24px",
|
|
}}
|
|
color="#7B7B7B"
|
|
/>
|
|
|
|
<VStack fontSize={{ base: "xs", md: "sm" }}>
|
|
<HStack w={"100%"} justifyContent={"flex-start"}>
|
|
<Text
|
|
color={colorMode === "light" ? "#7B7B7B" : "#E8E8E8"}
|
|
>
|
|
Transaction type :
|
|
</Text>
|
|
<Text
|
|
color={colorMode === "light" ? "#230A79" : "#B09AFF"}
|
|
>
|
|
<Text>{transactionType}</Text>
|
|
</Text>
|
|
</HStack>
|
|
|
|
<HStack>
|
|
<Text
|
|
color={colorMode === "light" ? "#7B7B7B" : "#E8E8E8"}
|
|
>
|
|
{subNetworkId === "MainNet" ? "Main net" : "Subnet ID"}{" "}
|
|
:
|
|
</Text>
|
|
<Text
|
|
color={colorMode === "light" ? "#230A79" : "#B09AFF"}
|
|
>
|
|
<Link
|
|
to={`/subnet-id-overview/${subNetworkId}`}
|
|
style={{ fontWeight: "inherit" }}
|
|
>
|
|
{subNetworkId}
|
|
</Link>
|
|
</Text>
|
|
</HStack>
|
|
</VStack>
|
|
</HStack>
|
|
{/* </Box> */}
|
|
</GridItem>
|
|
</Grid>
|
|
)
|
|
)}
|
|
</Box>
|
|
<Pagination
|
|
pageSize={pageSize}
|
|
setPageSize={setPageSize}
|
|
totalItems={totalItems}
|
|
isLoading={isTransCountLoading}
|
|
setCurrentPage={setCurrentPage}
|
|
currentPage={currentPage}
|
|
/>
|
|
</Container>
|
|
);
|
|
};
|
|
|
|
export default LatestTransactions;
|