Joystream Stats 4 tahun lalu
induk
melakukan
c7f942c94d

+ 71 - 0
src/components/Chart/index.tsx

@@ -0,0 +1,71 @@
+import React from "react";
+import { OverlayTrigger, Tooltip } from "react-bootstrap";
+
+interface IProps {
+  data: { [x: string]: any }[];
+  x: string;
+  y: string;
+  pixels: number;
+  scaleY?: boolean;
+  xLabel?: string;
+  yLabel?: string;
+  barStyle?: (o: any) => string;
+}
+
+const Chart = (props: IProps) => {
+  const { barStyle, data, x, y, pixels, scaleY, xLabel, yLabel } = props;
+
+  if (!data.length) return <div>No data.</div>;
+
+  const sorted = data.sort((a, b) => a[x] - b[x]).filter((e) => e[y] > 0);
+
+  let yMin = scaleY ? sorted[0][y] : 0;
+  let yMax = sorted[0][y];
+
+  data.forEach((d) => {
+    if (d[y] > yMax) yMax = d[y];
+    if (d[y] < yMin) yMin = d[y];
+  });
+
+  const width = (pixels || 400) / sorted.length;
+  const color = `bg-danger`;
+
+  return (
+    <div className="d-flex flex-column">
+      <div
+        className={`d-flex flex-row align-items-baseline`}
+        style={{ height: `100px`, borderBottom: `0.01px solid black` }}
+      >
+        <div
+          className={color}
+          style={{ height: `100%`, borderRight: `0.01px solid black` }}
+        />
+        {sorted.map((d, i) => (
+          <OverlayTrigger
+            key={`overlay${i}`}
+            placement="top"
+            overlay={
+              <Tooltip id={`tooltip${i}`}>
+                <div>
+                  {xLabel}: {d[x]}: {d[y]} {yLabel}
+                </div>
+              </Tooltip>
+            }
+          >
+            <div
+              key={i}
+              className={barStyle ? barStyle(d) : color}
+              style={{
+                border: `1px solid teal`,
+                width,
+                height: `${(90 * d[y]) / yMax}%`,
+              }}
+            />
+          </OverlayTrigger>
+        ))}
+      </div>
+    </div>
+  );
+};
+
+export default Chart;

+ 2 - 1
src/components/Dashboard/index.tsx

@@ -3,8 +3,8 @@ import { Link } from "react-router-dom";
 import { ActiveProposals, Council } from "..";
 import Nominators from "./Nominators";
 import Validators from "./Validators";
-import { IState } from "../../types";
 import Loading from "../Loading";
+import { IState } from "../../types";
 
 const Dashboard = (props: IState) => {
   const { block, council, domain, handles, proposals } = props;
@@ -26,6 +26,7 @@ const Dashboard = (props: IState) => {
         <hr />
         <Link to={`/proposals`}>Show all</Link>
       </div>
+
       <Council
         council={council}
         handles={handles}

+ 42 - 0
src/components/Tokenomics/Burns.tsx

@@ -0,0 +1,42 @@
+import React from "react";
+import Chart from "../Chart";
+import { Exchange } from "../../types";
+
+const Burns = (props: {
+  exchanges: Exchange[];
+  extecutedBurnsAmount: number;
+}) => {
+  if (!props.exchanges) return <div />;
+
+  const data = props.exchanges.map((b) => {
+    return {
+      time: b.logTime.split("T")[0],
+      amount: Math.floor(b.amountUSD),
+      status: b.status,
+    };
+  });
+  const executed = Math.floor(props.extecutedBurnsAmount / 100000) / 10;
+
+  return (
+    <div className="box">
+      <h3 className="text-light">Burns</h3>
+      <Chart
+        data={data}
+        x="time"
+        y="amount"
+        xLabel="Date"
+        yLabel="$"
+        scaleY={true}
+        pixels={150}
+        barStyle={(o: Exchange) =>
+          o.status === "PENDING" ? `bg-warning` : `bg-danger`
+        }
+      />
+      <div className="my-1 text-left">
+        Total Amount Burned: {executed} M JOY
+      </div>
+    </div>
+  );
+};
+
+export default Burns;

+ 23 - 0
src/components/Tokenomics/Navigation.tsx

@@ -0,0 +1,23 @@
+import React from "react";
+import { Button } from "react-bootstrap";
+import { Link } from "react-router-dom";
+
+const Navigation = () => {
+  return (
+    <div className="d-flex flex-row justify-content-center">
+      <Link to={`/`}>
+        <Button variant="secondary" className="p-1 m-1">
+          Back
+        </Button>
+      </Link>
+
+      <Link to={`/councils`}>
+        <Button variant="secondary" className="p-1 m-1">
+          Previous Councils
+        </Button>
+      </Link>
+    </div>
+  );
+};
+
+export default Navigation;

+ 1 - 5
src/components/Tokenomics/Overview.tsx

@@ -4,7 +4,7 @@ import { Table } from "react-bootstrap";
 import { Tokenomics } from "../../types";
 
 const Overview = (props: Tokenomics) => {
-  const { extecutedBurnsAmount, price, totalIssuance, validators } = props;
+  const { price, totalIssuance, validators } = props;
 
   return (
     <Table>
@@ -13,10 +13,6 @@ const Overview = (props: Tokenomics) => {
           <td>Total Issuance</td>
           <td>{totalIssuance} JOY</td>
         </tr>
-        <tr>
-          <td>Burns Amount</td>
-          <td>{extecutedBurnsAmount} JOY</td>
-        </tr>
         <tr>
           <td>Validator Stake</td>
           <td>{validators.total_stake} JOY</td>

+ 9 - 16
src/components/Tokenomics/index.tsx

@@ -1,22 +1,12 @@
 import React from "react";
-import { Button } from "react-bootstrap";
-import { Link } from "react-router-dom";
+import Burns from "./Burns";
+import Navigation from "./Navigation";
 import Overview from "./Overview";
 import ReportBrowser from "./ReportBrowser";
 import Loading from "../Loading";
 
 import { Tokenomics } from "../../types";
 
-const Back = () => {
-  return (
-    <Link to={`/`}>
-      <Button variant="secondary" className="p-1 m-3">
-        back
-      </Button>
-    </Link>
-  );
-};
-
 interface IProps {
   reports: { [key: string]: string };
   tokenomics?: Tokenomics;
@@ -24,6 +14,8 @@ interface IProps {
 
 const CouncilReports = (props: IProps) => {
   const { reports, tokenomics } = props;
+  if (!tokenomics) return <Loading />;
+  const { exchanges, extecutedBurnsAmount } = tokenomics;
 
   return (
     <div className="h-100 py-3 d-flex flex-row justify-content-center">
@@ -33,11 +25,12 @@ const CouncilReports = (props: IProps) => {
           {tokenomics ? <Overview {...tokenomics} /> : <Loading />}
         </div>
 
-        <Link to={`/councils`}>
-          <Button variant="dark">Previous Councils</Button>
-        </Link>
+        <Burns
+          exchanges={exchanges}
+          extecutedBurnsAmount={extecutedBurnsAmount}
+        />
 
-        <Back />
+        <Navigation />
       </div>
 
       <div className="box col-8">

+ 25 - 1
src/types.ts

@@ -121,9 +121,33 @@ export interface Handles {
 }
 
 export interface Thread {}
+
 export interface Tokenomics {
-  extecutedBurnsAmount: string;
   price: string;
   totalIssuance: string;
   validators: { total_stake: string };
+  burns: Burn[];
+  exchanges: Exchange[];
+  extecutedBurnsAmount: number;
+}
+
+export interface Burn {
+  amount: number;
+  blockHeight: number;
+  date: string; // "2020-09-21T11:07:54.000Z"
+  logTime: string; //"2020-09-21T11:08:54.091Z"
+}
+
+export interface Exchange {
+  amount: number;
+  amountUSD: number;
+  blockHeight: number;
+  date: string; // "2020-09-21T11:07:48.000Z"
+  logTime: string; // "2020-09-21T11:08:48.552Z"
+  price: number; // 0.000053676219442924057
+  recipient: string; //"5D5PhZQNJzcJXVBxwJxZcsutjKPqUPydrvpu6HeiBfMaeKQu"
+  sender: string; // "5DACzSg65taZ2NRktUtzBjhLZr8H5T8rwNoZUng9gQV6ayqT"
+  senderMemo: string; //"4Testing1337SendToBurnerAddressHopingItWorksOfc5D5PhZQNJzcJXVBxwJxZcsutjKPqUPydrvpu6HeiBfMaeKQu"
+  status: string; // FINALIZED | PENDING
+  xmrAddress: string; //"No address found"
 }