Merge branch 'backend_2.0' of https://github.com/hyle-team/zano-explorer-zarcanum into backend_2.0
This commit is contained in:
commit
aec34bcd53
12 changed files with 93 additions and 79 deletions
|
|
@ -160,7 +160,7 @@ export async function getTxPoolDetails(count: number) {
|
|||
// When count is 0, retrieve all records ordered by timestamp DESC
|
||||
if (count === 0) {
|
||||
const result = await Pool.findAll({
|
||||
attributes: ['blob_size', 'fee', 'id', 'timestamp'],
|
||||
attributes: ['blob_size', 'fee', 'id', 'timestamp', 'tx_id'],
|
||||
order: [['timestamp', 'DESC']]
|
||||
});
|
||||
return result.length > 0 ? result : [];
|
||||
|
|
@ -173,6 +173,7 @@ export async function getTxPoolDetails(count: number) {
|
|||
'fee',
|
||||
'id',
|
||||
'timestamp',
|
||||
'tx_id',
|
||||
[literal('false'), 'isNew'] // Adding a literal false as "isNew"
|
||||
],
|
||||
order: [['timestamp', 'DESC']],
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ function App() {
|
|||
<Route path="/block/:hash" element={<Block />} />
|
||||
<Route path="/transaction/:hash" element={<Transaction />} />
|
||||
<Route path="/alt-blocks/:hash" element={<Block alt />} />
|
||||
<Route path="/charts" element={<Charts />} />
|
||||
<Route path="/charts/:name" element={<ChartsPage />} />
|
||||
{/* <Route path="/charts" element={<Charts />} />
|
||||
<Route path="/charts/:name" element={<ChartsPage />} /> */}
|
||||
{/* {NET_MODE === "TEST" &&
|
||||
<Route path="/assets" element={<Assets />} />
|
||||
} */}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { Link, LinkProps } from "react-router-dom";
|
||||
import "./AliasText.scss";
|
||||
|
||||
interface AliasTextProps extends React.HTMLProps<HTMLAnchorElement> {
|
||||
interface AliasTextProps extends LinkProps {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
|
|
@ -9,9 +10,9 @@ function AliasText(props: AliasTextProps) {
|
|||
|
||||
return (
|
||||
<span className="alias__text">
|
||||
<a {...restProps}>
|
||||
<Link {...restProps}>
|
||||
{children}
|
||||
</a>
|
||||
</Link>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { ReactComponent as BurgerImg } from "../../../assets/images/UI/burger.sv
|
|||
import HeaderProps from "./Header.props";
|
||||
import Button from "../../UI/Button/Button";
|
||||
import { NET_MODE } from "../../../config/config";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
function Header(props: HeaderProps) {
|
||||
const { page, burgerOpened, setBurgerOpened } = props;
|
||||
|
|
@ -11,53 +12,53 @@ function Header(props: HeaderProps) {
|
|||
function Nav({ className }: { className?: string }) {
|
||||
return (
|
||||
<nav className={className}>
|
||||
<a
|
||||
<Link
|
||||
className={page === "Blockchain" ? "selected" : undefined}
|
||||
href="/"
|
||||
to="/"
|
||||
>
|
||||
Blockchain
|
||||
</a>
|
||||
<a
|
||||
</Link>
|
||||
<Link
|
||||
className={page === "Alt-blocks" ? "selected" : undefined}
|
||||
href="/alt-blocks"
|
||||
to="/alt-blocks"
|
||||
>
|
||||
Alt-blocks
|
||||
</a>
|
||||
<a
|
||||
</Link>
|
||||
<Link
|
||||
className={page === "Aliases" ? "selected" : undefined}
|
||||
href="/aliases"
|
||||
to="/aliases"
|
||||
>
|
||||
Aliases
|
||||
</a>
|
||||
</Link>
|
||||
{/* {NET_MODE === "TEST" ?
|
||||
<a
|
||||
<Link
|
||||
className={page === "Assets" ? "selected" : undefined}
|
||||
href="/assets"
|
||||
to="/assets"
|
||||
>
|
||||
Assets
|
||||
</a> :
|
||||
</Link> :
|
||||
<p>
|
||||
Assets
|
||||
</p>
|
||||
} */}
|
||||
<a
|
||||
<Link
|
||||
className={page === "Assets" ? "selected" : undefined}
|
||||
href="/assets"
|
||||
to="/assets"
|
||||
>
|
||||
Assets
|
||||
</a>
|
||||
<a
|
||||
</Link>
|
||||
{/* <Link
|
||||
className={page === "Charts" ? "selected" : undefined}
|
||||
href="/charts"
|
||||
to="/charts"
|
||||
>
|
||||
Charts
|
||||
</a>
|
||||
<a
|
||||
</Link> */}
|
||||
<Link
|
||||
className={page === "API" ? "selected" : undefined}
|
||||
href="/zano_api"
|
||||
to="/zano_api"
|
||||
>
|
||||
API
|
||||
</a>
|
||||
</Link>
|
||||
{NET_MODE === "MAIN" &&
|
||||
<p>
|
||||
Governance
|
||||
|
|
@ -71,25 +72,25 @@ function Header(props: HeaderProps) {
|
|||
<header className="header">
|
||||
<div className="header__top">
|
||||
<div className="header__top__main">
|
||||
<a href="/">
|
||||
<Link to="/">
|
||||
<div className="header__logo">
|
||||
<LogoImg />
|
||||
<p>ZANO</p>
|
||||
</div>
|
||||
</a>
|
||||
</Link>
|
||||
<Nav />
|
||||
</div>
|
||||
|
||||
<div className="header__top__right">
|
||||
<a
|
||||
href={NET_MODE === "TEST" ? "https://explorer.zano.org/" : "https://testnet-explorer.zano.org/"}
|
||||
<Link
|
||||
to={NET_MODE === "TEST" ? "https://explorer.zano.org/" : "https://testnet-explorer.zano.org/"}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Button>
|
||||
<p>Switch to {NET_MODE === "TEST" ? "Main Net" : "Test Net"}</p>
|
||||
</Button>
|
||||
</a>
|
||||
</Link>
|
||||
<Button
|
||||
onClick={() => setBurgerOpened(!burgerOpened)}
|
||||
className="header__burger__button"
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { ReactComponent as SearchImg } from "../../../assets/images/UI/search.sv
|
|||
import { ReactComponent as BackImg } from "../../../assets/images/UI/back.svg";
|
||||
import { useState } from "react";
|
||||
import Fetch from "../../../utils/methods";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import InfoTopPanelProps from "./InfoTopPanel.props";
|
||||
|
||||
function InfoTopPanel(props: InfoTopPanelProps) {
|
||||
|
|
@ -74,12 +74,12 @@ function InfoTopPanel(props: InfoTopPanelProps) {
|
|||
>
|
||||
|
||||
{back &&
|
||||
<a href="/" onClick={onBackClick}>
|
||||
<Link to="/" onClick={onBackClick}>
|
||||
<div className="info__back">
|
||||
<BackImg />
|
||||
<p>Back</p>
|
||||
</div>
|
||||
</a>
|
||||
</Link>
|
||||
}
|
||||
<div className={"info__top__title"}>
|
||||
<h4 className={contentNotHiding ? "hiding_element" : undefined}>{title}</h4>
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import AliasText from "../../components/default/AliasText/AliasText";
|
|||
import Block from "../../interfaces/state/Block";
|
||||
import Fetch from "../../utils/methods";
|
||||
import Utils from "../../utils/utils";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
|
||||
function AltBlocks() {
|
||||
|
|
@ -45,14 +46,14 @@ function AltBlocks() {
|
|||
|
||||
return [
|
||||
<p>
|
||||
<a href={hashLink}>{e.height}</a>
|
||||
<Link to={hashLink}>{e.height}</Link>
|
||||
{` (${e.type})`}
|
||||
</p>,
|
||||
Utils.formatTimestampUTC(e.timestamp),
|
||||
Utils.formatTimestampUTC(e.timestamp),
|
||||
`${e.size} bytes`,
|
||||
e.transactions?.toString() || "0",
|
||||
<AliasText href={hashLink}>{e.hash}</AliasText>
|
||||
<AliasText to={hashLink}>{e.hash}</AliasText>
|
||||
]
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import "../../styles/Assets.scss";
|
||||
import { useState, useEffect, useRef, memo } from "react";
|
||||
import { useState, useEffect, useRef, memo, useCallback } from "react";
|
||||
import Header from "../../components/default/Header/Header";
|
||||
import InfoTopPanel from "../../components/default/InfoTopPanel/InfoTopPanel";
|
||||
import Table from "../../components/default/Table/Table";
|
||||
|
|
@ -85,6 +85,18 @@ function Assets() {
|
|||
return price;
|
||||
}
|
||||
|
||||
const fetchZanoPrice = useCallback(async () => {
|
||||
const zanoPrice = await getZanoPrice();
|
||||
setAssets(prev => {
|
||||
const newAssets = [...prev];
|
||||
const zanoAsset = newAssets.find(e => e.asset_id === ZANO_ID);
|
||||
if (zanoAsset) {
|
||||
zanoAsset.price = zanoPrice;
|
||||
}
|
||||
return newAssets;
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchAssetsStats() {
|
||||
const result = await Fetch.getAssetsCount();
|
||||
|
|
@ -131,21 +143,15 @@ function Assets() {
|
|||
}, [searchParams, initFetched]);
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchZanoPrice() {
|
||||
const zanoPrice = await getZanoPrice();
|
||||
setAssets(prev => {
|
||||
const newAssets = [...prev];
|
||||
const zanoAsset = newAssets.find(e => e.asset_id === ZANO_ID);
|
||||
if (zanoAsset) {
|
||||
zanoAsset.price = zanoPrice;
|
||||
}
|
||||
return newAssets;
|
||||
});
|
||||
}
|
||||
fetchZanoPrice();
|
||||
|
||||
setInterval(() => {
|
||||
const intervalId = setInterval(() => {
|
||||
fetchZanoPrice();
|
||||
}, 10e3);
|
||||
|
||||
return () => {
|
||||
clearInterval(intervalId);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -173,6 +179,7 @@ function Assets() {
|
|||
if (!resultAssets || !(resultAssets instanceof Array)) return;
|
||||
|
||||
setAssets(resultAssets);
|
||||
fetchZanoPrice();
|
||||
}
|
||||
|
||||
fetchAssets();
|
||||
|
|
@ -191,7 +198,7 @@ function Assets() {
|
|||
e?.ticker || "",
|
||||
<div className="assets__table_asset-id">
|
||||
<CopyButton text={e?.asset_id || ""} />
|
||||
<AliasText href="/" onClick={(event) => onAssetClick(event, e)}>
|
||||
<AliasText to="/" onClick={(event) => onAssetClick(event, e)}>
|
||||
{e?.asset_id || ""}
|
||||
</AliasText>
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import Table from "../../components/default/Table/Table";
|
|||
import { ReactComponent as ArrowImg } from "../../assets/images/UI/arrow.svg";
|
||||
import BlockInfo from "../../interfaces/common/BlockInfo";
|
||||
import Utils from "../../utils/utils";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
import Fetch from "../../utils/methods";
|
||||
import Popup from "../../components/default/Popup/Popup";
|
||||
|
||||
|
|
@ -37,9 +37,9 @@ function Block(props: { alt?: boolean }) {
|
|||
!alt
|
||||
?
|
||||
(
|
||||
<a href={"/transaction/" + (e.hash || "")} className="block__table__hash">
|
||||
<Link to={"/transaction/" + (e.hash || "")} className="block__table__hash">
|
||||
{e.hash}
|
||||
</a>
|
||||
</Link>
|
||||
)
|
||||
:
|
||||
(
|
||||
|
|
@ -165,15 +165,15 @@ function Block(props: { alt?: boolean }) {
|
|||
<h2>Zano Block</h2>
|
||||
<div>
|
||||
{!alt && prevHash !== "" &&
|
||||
<a href={prevHash ? "/block/" + prevHash : undefined}>
|
||||
<Link to={prevHash ? "/block/" + prevHash : "/"}>
|
||||
<ArrowImg />
|
||||
</a>
|
||||
</Link>
|
||||
}
|
||||
<h2>{height}</h2>
|
||||
{!alt && nextHash !== "" &&
|
||||
<a href={nextHash ? "/block/" + nextHash : undefined}>
|
||||
<Link to={nextHash ? "/block/" + nextHash : "/"}>
|
||||
<ArrowImg />
|
||||
</a>
|
||||
</Link>
|
||||
}
|
||||
</div>
|
||||
<p>{hash?.toUpperCase() || ""}</p>
|
||||
|
|
@ -197,7 +197,7 @@ function Block(props: { alt?: boolean }) {
|
|||
</tr>
|
||||
<tr>
|
||||
<td>ID</td>
|
||||
<td><a href="">{Utils.shortenAddress(blockInfo?.tx_id ?? "-")}</a></td>
|
||||
<td><Link to="/">{Utils.shortenAddress(blockInfo?.tx_id ?? "-")}</Link></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Actual Timestamp (UTC):</td>
|
||||
|
|
@ -249,7 +249,7 @@ function Block(props: { alt?: boolean }) {
|
|||
</tr>
|
||||
<tr>
|
||||
<td>Previous ID:</td>
|
||||
<td><a href={`/block/${blockInfo?.prev_id}`}>{Utils.shortenAddress(blockInfo?.prev_id ?? "-")}</a></td>
|
||||
<td><Link to={`/block/${blockInfo?.prev_id}`}>{Utils.shortenAddress(blockInfo?.prev_id ?? "-")}</Link></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Total block size, bytes:</td>
|
||||
|
|
@ -286,15 +286,15 @@ function Block(props: { alt?: boolean }) {
|
|||
<tr>
|
||||
<td>JSON data:</td>
|
||||
<td>
|
||||
<a
|
||||
href="/"
|
||||
<Link
|
||||
to="/"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
setJsonPopupOpened(true);
|
||||
}}
|
||||
>
|
||||
[ view ]
|
||||
</a>
|
||||
</Link>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import Utils from "../../../../utils/utils";
|
|||
import "./LatestBlocks.scss";
|
||||
import { useState, useEffect } from "react";
|
||||
import { socket } from "../../../../utils/socket";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
function LatestBlocks() {
|
||||
|
||||
|
|
@ -82,14 +83,14 @@ function LatestBlocks() {
|
|||
const hashLink = hash ? "/block/" + hash : "/";
|
||||
return [
|
||||
<p>
|
||||
<a href={hashLink}>{e.height}</a>
|
||||
<Link to={hashLink}>{e.height}</Link>
|
||||
{` (${e.type})`}
|
||||
</p>,
|
||||
Utils.formatTimestampUTC(e.timestamp),
|
||||
Utils.timeElapsedString(e.timestamp),
|
||||
`${e.size} bytes`,
|
||||
e.transactions?.toString() || "0",
|
||||
<AliasText href={hashLink}>{hash}</AliasText>
|
||||
<AliasText to={hashLink}>{hash}</AliasText>
|
||||
]
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ function TransactionPool() {
|
|||
fee: string,
|
||||
id: string,
|
||||
timestamp: string,
|
||||
tx_id: string,
|
||||
}
|
||||
|
||||
const [turnedOn, setTurnedOn] = useState(true);
|
||||
|
|
@ -77,7 +78,7 @@ function TransactionPool() {
|
|||
timeAgo(parseInt(element.timestamp, 10)*1000),
|
||||
element.blob_size + " bytes",
|
||||
parseInt(element.fee, 10)/10**12,
|
||||
<AliasText href={`/transaction/${element.id}`}>{element.id}</AliasText>
|
||||
<AliasText to={`/transaction/${element.id}`}>{element.tx_id}</AliasText>
|
||||
]));
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { chartOptions } from "../../utils/constants";
|
|||
import Utils from "../../utils/utils";
|
||||
import ChartSeriesElem from "../../interfaces/common/ChartSeriesElem";
|
||||
import Preloader from "../../components/UI/Preloader/Preloader";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
function Charts() {
|
||||
const [burgerOpened, setBurgerOpened] = useState(false);
|
||||
|
|
@ -65,7 +66,7 @@ function Charts() {
|
|||
} = props;
|
||||
|
||||
return (
|
||||
<a href={"/charts/" + requestTitle} className="charts__chart__wrapper">
|
||||
<Link to={"/charts/" + requestTitle} className="charts__chart__wrapper">
|
||||
<div className="charts__chart__title">
|
||||
<p>{title}</p>
|
||||
</div>
|
||||
|
|
@ -117,7 +118,7 @@ function Charts() {
|
|||
}
|
||||
}}
|
||||
/>
|
||||
</a>
|
||||
</Link>
|
||||
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import StatsPanel from "../../components/default/StatsPanel/StatsPanel";
|
|||
import Table from "../../components/default/Table/Table";
|
||||
import TransactionInfo, { Input } from "../../interfaces/common/TransactionInfo";
|
||||
import Fetch from "../../utils/methods";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { Link, useNavigate, useParams } from "react-router-dom";
|
||||
import Utils from "../../utils/utils";
|
||||
import { nanoid } from "nanoid";
|
||||
import Popup from "../../components/default/Popup/Popup";
|
||||
|
|
@ -141,16 +141,16 @@ function Transaction() {
|
|||
e.globalIndexes.length,
|
||||
e.globalIndexes.length > 1 ?
|
||||
(
|
||||
<a href="/" onClick={event => showIndexesClick(event, e)}>Show all...</a>
|
||||
<Link to="/" onClick={event => showIndexesClick(event, e)}>Show all...</Link>
|
||||
)
|
||||
:
|
||||
(
|
||||
<a
|
||||
href="/"
|
||||
<Link
|
||||
to="/"
|
||||
onClick={event => onIndexClick(event, e.amount, e.globalIndexes[0])}
|
||||
>
|
||||
{e.globalIndexes[0] ?? ""}
|
||||
</a>
|
||||
</Link>
|
||||
)
|
||||
])
|
||||
) : [];
|
||||
|
|
@ -177,13 +177,13 @@ function Transaction() {
|
|||
<div>
|
||||
{popupIndexes.map(e =>
|
||||
(
|
||||
<a
|
||||
href="/"
|
||||
<Link
|
||||
to="/"
|
||||
key={e}
|
||||
onClick={event => onIndexClick(event, amount, e)}
|
||||
>
|
||||
{e}
|
||||
</a>
|
||||
</Link>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
|
|
@ -269,12 +269,12 @@ function Transaction() {
|
|||
className="custom-scroll"
|
||||
headers={[ "HASH", "HEIGHT", "TIMESTAMP (UTC)" ]}
|
||||
elements={[[
|
||||
<a
|
||||
<Link
|
||||
className="table__hash"
|
||||
href={blockOrigin?.hash ? "/block/" + blockOrigin.hash : undefined}
|
||||
to={blockOrigin?.hash ? "/block/" + blockOrigin.hash : "/"}
|
||||
>
|
||||
{blockOrigin?.hash}
|
||||
</a>,
|
||||
</Link>,
|
||||
blockOrigin?.height || "",
|
||||
blockOrigin?.timestamp ? Utils.formatTimestampUTC(parseInt(blockOrigin.timestamp, 10)) : ""
|
||||
]]}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue