Refactor ProgressBar
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { CurrencyRates } from "@/app/api/types";
|
||||
import type { CurrencyRates, IAccountBalancesInfo } from "@/app/api/types";
|
||||
import { NYM_ACCOUNT_ADDRESS, NYM_PRICES_API } from "@/app/api/urls";
|
||||
import { AccountBalancesCard } from "@/components/accountPageComponents/AccountBalancesCard";
|
||||
import { AccountInfoCard } from "@/components/accountPageComponents/AccountInfoCard";
|
||||
@@ -7,42 +7,6 @@ import SectionHeading from "@/components/headings/SectionHeading";
|
||||
import ExplorerButtonGroup from "@/components/toggleButton/ToggleButton";
|
||||
import { Box, Grid2 } from "@mui/material";
|
||||
|
||||
interface IRewardDetails {
|
||||
amount_staked: IAmountDetails;
|
||||
node_id: number;
|
||||
node_still_fully_bonded: boolean;
|
||||
rewards: IAmountDetails;
|
||||
}
|
||||
|
||||
interface IAmountDetails {
|
||||
denom: string;
|
||||
amount: string;
|
||||
}
|
||||
|
||||
interface IDelegationDetails {
|
||||
node_id: number;
|
||||
delegated: IAmountDetails;
|
||||
height: number;
|
||||
proxy: null | string;
|
||||
}
|
||||
|
||||
interface ITotalDetails {
|
||||
amount: string;
|
||||
denom: string;
|
||||
}
|
||||
|
||||
export interface IAccountInfo {
|
||||
accumulated_rewards: IRewardDetails[];
|
||||
address: string;
|
||||
balances: IAmountDetails[];
|
||||
claimable_rewards: IAmountDetails;
|
||||
delegations: IDelegationDetails[];
|
||||
operator_rewards?: null | IAmountDetails;
|
||||
total_delegations: ITotalDetails;
|
||||
total_value: ITotalDetails;
|
||||
vesting_account?: null | string;
|
||||
}
|
||||
|
||||
export default async function Account({
|
||||
params,
|
||||
}: {
|
||||
@@ -61,12 +25,12 @@ export default async function Account({
|
||||
next: { revalidate: 60 },
|
||||
// refresh event list cache at given interval
|
||||
});
|
||||
const nymAccountData: IAccountInfo = await accountData.json();
|
||||
const nymAccountBalancesData: IAccountBalancesInfo = await accountData.json();
|
||||
|
||||
if (!nymAccountData) {
|
||||
if (!nymAccountBalancesData) {
|
||||
return null;
|
||||
}
|
||||
|
||||
console.log("nymAccountBalancesData :>> ", nymAccountBalancesData);
|
||||
const nymPrice = await fetch(NYM_PRICES_API, {
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
@@ -80,7 +44,7 @@ export default async function Account({
|
||||
|
||||
console.log("nymPriceData :>> ", nymPriceData);
|
||||
|
||||
console.log("nymAccountData :>> ", nymAccountData);
|
||||
console.log("nymAccountData :>> ", nymAccountBalancesData);
|
||||
return (
|
||||
<ContentLayout>
|
||||
<Grid2 container columnSpacing={5} rowSpacing={5}>
|
||||
@@ -102,11 +66,11 @@ export default async function Account({
|
||||
</Box>
|
||||
</Grid2>
|
||||
<Grid2 size={4}>
|
||||
<AccountInfoCard accountInfo={nymAccountData} />
|
||||
<AccountInfoCard accountInfo={nymAccountBalancesData} />
|
||||
</Grid2>
|
||||
<Grid2 size={8}>
|
||||
<AccountBalancesCard
|
||||
accountInfo={nymAccountData}
|
||||
accountInfo={nymAccountBalancesData}
|
||||
nymPrice={nymPriceData.usd}
|
||||
/>
|
||||
</Grid2>
|
||||
|
||||
@@ -114,3 +114,36 @@ export interface CurrencyRates {
|
||||
timestamp: number;
|
||||
usd: number;
|
||||
}
|
||||
|
||||
// ACCOUNT BALANCES
|
||||
|
||||
export interface IRewardDetails {
|
||||
amount_staked: IAmountDetails;
|
||||
node_id: number;
|
||||
node_still_fully_bonded: boolean;
|
||||
rewards: IAmountDetails;
|
||||
}
|
||||
|
||||
export interface IAmountDetails {
|
||||
denom: string;
|
||||
amount: string;
|
||||
}
|
||||
|
||||
export interface IDelegationDetails {
|
||||
node_id: number;
|
||||
delegated: IAmountDetails;
|
||||
height: number;
|
||||
proxy: null | string;
|
||||
}
|
||||
|
||||
export interface IAccountBalancesInfo {
|
||||
accumulated_rewards: IRewardDetails[];
|
||||
address: string;
|
||||
balances: IAmountDetails[];
|
||||
claimable_rewards: IAmountDetails;
|
||||
delegations: IDelegationDetails[];
|
||||
operator_rewards?: null | IAmountDetails;
|
||||
total_delegations: IAmountDetails;
|
||||
total_value: IAmountDetails;
|
||||
vesting_account?: null | string;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ export const NYM_NODE_DESCRIPTION =
|
||||
"https://nym-api.swiss-staking.ch/v1/nym-nodes/described";
|
||||
export const NYM_NODE_BONDED =
|
||||
"https://nym-api.swiss-staking.ch/v1/nym-nodes/bonded";
|
||||
|
||||
export const NYM_ACCOUNT_ADDRESS =
|
||||
"https://explorer.nymtech.net/api/v1/tmp/unstable/account/";
|
||||
export const NYM_PRICES_API =
|
||||
|
||||
@@ -16,8 +16,7 @@ export default async function NymNode({
|
||||
}: {
|
||||
params: Promise<{ id: string }>;
|
||||
}) {
|
||||
const id = (await params).id;
|
||||
console.log("id :>> ", id);
|
||||
const id = Number((await params).id);
|
||||
|
||||
const descriptionData = await fetch(NYM_NODE_DESCRIPTION, {
|
||||
headers: {
|
||||
@@ -44,7 +43,7 @@ export default async function NymNode({
|
||||
}
|
||||
|
||||
const nodeBondInfo = nymbondedData.data.filter(
|
||||
(item: IBondInfo) => item.bond_information.node_id === 5,
|
||||
(item: IBondInfo) => item.bond_information.node_id === id,
|
||||
);
|
||||
|
||||
const nodeDescriptionInfo = nymNodesDescription.data.filter(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"use client";
|
||||
import type { IAccountInfo } from "@/app/account/[id]/page";
|
||||
import type { IAccountBalancesInfo, IRewardDetails } from "@/app/api/types";
|
||||
import { AccountBalancesTable } from "../cards/AccountBalancesTable";
|
||||
import ExplorerCard from "../cards/ExplorerCard";
|
||||
|
||||
@@ -14,7 +14,7 @@ export interface IAccontStatsRowProps {
|
||||
}
|
||||
|
||||
interface IAccountBalancesCardProps {
|
||||
accountInfo: IAccountInfo;
|
||||
accountInfo: IAccountBalancesInfo;
|
||||
nymPrice: number;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,18 @@ const getAllocation = (unyms: number, totalUnyms: number): number => {
|
||||
return Number(allocationPercentage.toFixed(2));
|
||||
};
|
||||
|
||||
const calculateStakingRewards = (
|
||||
accumulatedRewards: IRewardDetails[],
|
||||
): number => {
|
||||
const totalRewards = accumulatedRewards.reduce((total, rewardDetail) => {
|
||||
return total + Number.parseFloat(rewardDetail.rewards.amount);
|
||||
}, 0);
|
||||
|
||||
const result = getNymsFormated(totalRewards);
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
export const AccountBalancesCard = (props: IAccountBalancesCardProps) => {
|
||||
const { accountInfo, nymPrice } = props;
|
||||
|
||||
@@ -75,6 +87,11 @@ export const AccountBalancesCard = (props: IAccountBalancesCardProps) => {
|
||||
Number(accountInfo.total_value.amount),
|
||||
);
|
||||
|
||||
const stakingRewards =
|
||||
accountInfo.accumulated_rewards.length > 0
|
||||
? calculateStakingRewards(accountInfo.accumulated_rewards)
|
||||
: 0;
|
||||
|
||||
const tableRows = [
|
||||
{
|
||||
type: "Spendable",
|
||||
@@ -87,10 +104,10 @@ export const AccountBalancesCard = (props: IAccountBalancesCardProps) => {
|
||||
allocation: delegationsAllocation,
|
||||
amount: delegationsNYM,
|
||||
value: delegationsUSD,
|
||||
history: [
|
||||
{ type: "Liquid", amount: 6900 },
|
||||
{ type: "Locked", amount: 6900 },
|
||||
],
|
||||
// history: [
|
||||
// { type: "Liquid", amount: 6900 },
|
||||
// { type: "Locked", amount: 6900 },
|
||||
// ],
|
||||
},
|
||||
{
|
||||
type: "Claimable",
|
||||
@@ -98,22 +115,19 @@ export const AccountBalancesCard = (props: IAccountBalancesCardProps) => {
|
||||
amount: claimableNYM,
|
||||
value: claimableUSD,
|
||||
history: [
|
||||
{ type: "Unlocked", amount: 6900 },
|
||||
{ type: "Staking rewards", amount: 6900 },
|
||||
{ type: "Operator comission", amount: 6900 },
|
||||
// { type: "Unlocked", amount: 6900 },
|
||||
{
|
||||
type: "Staking rewards",
|
||||
amount: stakingRewards,
|
||||
},
|
||||
{ type: "Operator comission", amount: 0 },
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "Self bonded",
|
||||
allocation: 15.53,
|
||||
amount: 12800,
|
||||
value: 1200,
|
||||
},
|
||||
{
|
||||
type: "Locked",
|
||||
allocation: 15.53,
|
||||
amount: 12800,
|
||||
value: 1200,
|
||||
allocation: 0,
|
||||
amount: 0,
|
||||
value: 0,
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"use client";
|
||||
import type { IAccountInfo } from "@/app/account/[id]/page";
|
||||
import type { IAccountBalancesInfo } from "@/app/api/types";
|
||||
import { Box, Stack, Typography } from "@mui/material";
|
||||
import ExplorerCard from "../cards/ExplorerCard";
|
||||
import CopyToClipboard from "../copyToClipboard/CopyToClipboard";
|
||||
@@ -7,7 +7,7 @@ import ExplorerListItem from "../list/ListItem";
|
||||
import { CardQRCode } from "../qrCode/QrCode";
|
||||
|
||||
interface IAccountInfoCardProps {
|
||||
accountInfo: IAccountInfo;
|
||||
accountInfo: IAccountBalancesInfo;
|
||||
}
|
||||
|
||||
export const AccountInfoCard = (props: IAccountInfoCardProps) => {
|
||||
|
||||
@@ -147,7 +147,7 @@ const Row = (props: IAccontStatsRowProps) => {
|
||||
}}
|
||||
>
|
||||
<Box display={"flex"} gap={1} alignItems={"center"}>
|
||||
<CircleIcon sx={{ color: progressBarColor }} fontSize="small" />
|
||||
<CircleIcon sx={{ color: progressBarColor, fontSize: 12 }} />
|
||||
{type}
|
||||
</Box>
|
||||
</TableCell>
|
||||
|
||||
@@ -1,26 +1,60 @@
|
||||
"use client";
|
||||
import { Stack } from "@mui/material";
|
||||
import Box from "@mui/material/Box";
|
||||
import { addHours, differenceInMinutes, format } from "date-fns";
|
||||
import { addHours, format } from "date-fns";
|
||||
import React from "react";
|
||||
import ListItem from "../list/ListItem";
|
||||
import ProgressBar from "../progressBar/ProgressBar";
|
||||
import ProgressBar from "./ProgressBar";
|
||||
|
||||
export interface IDynamicProgressBarProps {
|
||||
start: string; // Start timestamp as ISO 8601 string
|
||||
showEpoch: boolean;
|
||||
}
|
||||
|
||||
const EpochProgressBar = async ({
|
||||
start,
|
||||
showEpoch,
|
||||
}: IDynamicProgressBarProps) => {
|
||||
const EpochProgressBar = ({ start, showEpoch }: IDynamicProgressBarProps) => {
|
||||
const [progress, setProgress] = React.useState(0);
|
||||
|
||||
const startDate = new Date(start);
|
||||
const endDate = addHours(new Date(start), 1);
|
||||
const startTime = format(startDate, "HH:mm dd-MM-yyyy");
|
||||
const endTime = format(endDate, "HH:mm dd-MM-yyyy");
|
||||
const totalEpochTime = differenceInMinutes(endDate, startDate);
|
||||
|
||||
const progress =
|
||||
(differenceInMinutes(new Date(), startDate) / totalEpochTime) * 100;
|
||||
React.useEffect(() => {
|
||||
// Parse the start timestamp
|
||||
const startTime = new Date(start).getTime();
|
||||
const endTime = startTime + 60 * 60 * 1000; // Add 1 hour to the start time
|
||||
|
||||
// Validate start timestamp
|
||||
if (Number.isNaN(startTime)) {
|
||||
console.error("Invalid start timestamp:", { start });
|
||||
return;
|
||||
}
|
||||
|
||||
// Function to calculate progress
|
||||
const calculateProgress = () => {
|
||||
const currentTime = Date.now();
|
||||
if (currentTime < startTime) {
|
||||
return 0;
|
||||
}
|
||||
if (currentTime >= endTime) {
|
||||
return 100;
|
||||
}
|
||||
const elapsed = currentTime - startTime;
|
||||
const total = endTime - startTime;
|
||||
return (elapsed / total) * 100;
|
||||
};
|
||||
|
||||
// Set initial progress and start timer
|
||||
setProgress(calculateProgress());
|
||||
const timer = setInterval(() => {
|
||||
setProgress(calculateProgress());
|
||||
}, 60000); // Update every minute (60000 milliseconds)
|
||||
|
||||
// Cleanup on unmount
|
||||
return () => {
|
||||
clearInterval(timer);
|
||||
};
|
||||
}, [start]);
|
||||
|
||||
return (
|
||||
<Box sx={{ width: "100%" }}>
|
||||
|
||||
Reference in New Issue
Block a user