Add Delegations Table

This commit is contained in:
Yana
2025-01-08 21:15:30 +02:00
parent c116b75f33
commit 2ca034be1c
6 changed files with 184 additions and 9 deletions
@@ -2,8 +2,10 @@ import type NodeData from "@/app/api/types";
import type { IObservatoryNode } from "@/app/api/types";
import { DATA_OBSERVATORY_NODES_URL, NYM_NODES } from "@/app/api/urls";
import BlogArticlesCards from "@/components/blogs/BlogArticleCards";
import ExplorerCard from "@/components/cards/ExplorerCard";
import { ContentLayout } from "@/components/contentLayout/ContentLayout";
import SectionHeading from "@/components/headings/SectionHeading";
import DelegationsTable from "@/components/nodeTable/DelegationsTable";
import { BasicInfoCard } from "@/components/nymNodePageComponents/BasicInfoCard";
import { NodeChatCard } from "@/components/nymNodePageComponents/ChatCard";
import { NodeMetricsCard } from "@/components/nymNodePageComponents/NodeMetricsCard";
@@ -60,6 +62,19 @@ export default async function NymNode({
if (!nymNode) {
return null;
}
const nodeDelegationsResponse = await fetch(
`${DATA_OBSERVATORY_NODES_URL}/${id}/delegations`,
{
headers: {
Accept: "application/json",
"Content-Type": "application/json; charset=utf-8",
},
next: { revalidate: 60 },
// refresh event list cache at given interval
},
);
const delegations = await nodeDelegationsResponse.json();
return (
<ContentLayout>
@@ -134,6 +149,18 @@ export default async function NymNode({
nodeId={nymNode.bond_information.node_id}
/>
</Grid>
{delegations && (
<Grid
size={{
xs: 12,
}}
>
<ExplorerCard label="Delegations" sx={{ height: "100%" }}>
<DelegationsTable delegations={delegations} />
</ExplorerCard>
</Grid>
)}
<Grid
size={{
xs: 12,
+10
View File
@@ -244,3 +244,13 @@ export interface IObservatoryNode {
total_stake: number;
uptime: number;
}
export interface NodeRewardDetails {
amount: {
amount: string;
denom: string;
};
cumulative_reward_ratio: string;
height: number;
node_id: number;
owner: string;
}
-4
View File
@@ -34,7 +34,3 @@ export const VALIDATOR_BASE_URL =
process.env.NEXT_PUBLIC_VALIDATOR_URL || "https://rpc.nymtech.net";
export const DATA_OBSERVATORY_NODES_URL =
"https://api.nym.spectredao.net/api/v1/nodes";
export const DATA_OBSERVATORY_BALANCES_URL =
"https://api.nym.spectredao.net/api/v1/balances";
export const DATA_OBSERVATORY_DELEGATIONS_URL =
"https://api.nym.spectredao.net/api/v1/delegations";
@@ -10,9 +10,11 @@ const CountryFlag = ({ countryCode, countryName }: ICountryFlag) => {
return (
<Stack direction="row" gap={1}>
<Flag code={countryCode} width="19" />
<Typography variant="subtitle2" sx={{ color: "pine.950" }}>
{countryName}
</Typography>
{countryName && (
<Typography variant="subtitle2" sx={{ color: "pine.950" }}>
{countryName}
</Typography>
)}
</Stack>
);
};
@@ -0,0 +1,137 @@
"use client";
import type { NodeRewardDetails } from "@/app/api/types";
import { Stack, Typography } from "@mui/material";
import {
type MRT_ColumnDef,
MaterialReactTable,
useMaterialReactTable,
} from "material-react-table";
import { useRouter } from "next/navigation";
import { useMemo } from "react";
const ColumnHeading = ({
children,
}: {
children: string | React.ReactNode;
}) => {
return (
<Typography sx={{ py: 2, textAlign: "center" }} variant="h5">
{children}
</Typography>
);
};
const getNymsFormated = (unyms: string) => {
const balance = Number(unyms) / 1000000;
return balance.toFixed();
};
const DelegationsTable = ({
delegations,
}: {
delegations: NodeRewardDetails[];
}) => {
const router = useRouter();
const columns: MRT_ColumnDef<NodeRewardDetails>[] = useMemo(
() => [
{
id: "height",
header: "",
Header: <ColumnHeading>Height</ColumnHeading>,
accessorKey: "height",
Cell: ({ row }) => (
<Stack spacing={1}>
<Typography variant="body4">{row.original.height}</Typography>
</Stack>
),
},
{
id: "address",
header: "Delegation Address",
align: "center",
accessorKey: "address",
Header: <ColumnHeading>Delegation Address</ColumnHeading>,
Cell: ({ row }) => (
<Typography variant="body4">{row.original.owner}</Typography>
),
},
{
id: "amount",
header: "Amount",
accessorKey: "amount",
Header: <ColumnHeading>Amount</ColumnHeading>,
Cell: ({ row }) => (
<Typography variant="body4">
{getNymsFormated(row.original.amount.amount)} NYM
</Typography>
),
},
],
[],
);
const table = useMaterialReactTable({
columns,
data: delegations,
enableRowSelection: false, //enable some features
enableColumnOrdering: false, //enable a feature for all columns
enableColumnActions: false,
enableFullScreenToggle: false,
enableHiding: false,
paginationDisplayMode: "pages",
muiPaginationProps: {
showRowsPerPage: false,
SelectProps: {
sx: {
fontFamily: "labGrotesqueMono",
fontSize: "14px",
},
},
color: "primary",
shape: "circular",
},
initialState: {
columnPinning: { right: ["Amount"] },
},
muiColumnActionsButtonProps: {
sx: {
color: "red",
},
size: "small",
},
muiTablePaperProps: {
elevation: 0,
},
muiTableHeadRowProps: {
sx: {
bgcolor: "background.paper",
},
},
muiTableBodyCellProps: {
sx: {
border: "none",
},
},
muiTableBodyRowProps: ({ row }) => ({
onClick: () => {
router.push(`/account/${row.original.owner}`);
},
hover: true,
sx: {
":nth-child(odd)": {
bgcolor: "#F3F7FB !important",
},
":nth-child(even)": {
bgcolor: "white !important",
},
cursor: "pointer",
},
}),
});
return <MaterialReactTable table={table} />;
};
export default DelegationsTable;
@@ -1,4 +1,4 @@
import type { NodeDescription } from "@/app/api/types";
import type { IObservatoryNode, NodeDescription } from "@/app/api/types";
import { Chip, Stack } from "@mui/material";
import ExplorerCard from "../cards/ExplorerCard";
import ExplorerListItem from "../list/ListItem";
@@ -6,6 +6,7 @@ import StarRating from "../starRating/StarRating";
interface IQualityIndicatorsCardProps {
nodeDescription: NodeDescription;
nodeInfo?: IObservatoryNode;
}
type NodeDescriptionNotNull = NonNullable<NodeDescription>;
@@ -30,7 +31,7 @@ function getNodeRoles(
}
export const QualityIndicatorsCard = (props: IQualityIndicatorsCardProps) => {
const { nodeDescription } = props;
const { nodeDescription, nodeInfo } = props;
if (!nodeDescription) {
return null;
@@ -43,6 +44,8 @@ export const QualityIndicatorsCard = (props: IQualityIndicatorsCardProps) => {
</Stack>
));
console.log("activeRoles :>> ", nodeDescription.declared_role);
return (
<ExplorerCard label="Quality indicatiors" sx={{ height: "100%" }}>
<ExplorerListItem