Merge branch 'backend_2.0' of https://github.com/hyle-team/zano-explorer-zarcanum into backend_2.0

This commit is contained in:
jejolare 2024-09-10 20:33:00 +07:00
commit aec34bcd53
12 changed files with 93 additions and 79 deletions

View file

@ -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']],

View file

@ -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 />} />
} */}

View file

@ -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>
)
}

View file

@ -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"

View file

@ -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>

View file

@ -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>
]
});

View file

@ -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>

View file

@ -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);
}}
>
[ &nbsp;view &nbsp;]
</a>
</Link>
</td>
</tr>
</tbody>

View file

@ -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>
]
});

View file

@ -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 (

View file

@ -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>
)
}

View file

@ -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)) : ""
]]}