From e664a74606b865f981927729a885e4082fedbca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hampus=20Sj=C3=B6berg?= Date: Thu, 29 Apr 2021 02:09:02 +0200 Subject: [PATCH] Add miners page --- frontend/components/SiteMenu.tsx | 42 ++++++++++ frontend/components/SiteTitle.tsx | 2 +- frontend/pages/index.tsx | 5 +- frontend/pages/miners.tsx | 132 ++++++++++++++++++++++++++++++ 4 files changed, 178 insertions(+), 3 deletions(-) create mode 100644 frontend/components/SiteMenu.tsx create mode 100644 frontend/pages/miners.tsx diff --git a/frontend/components/SiteMenu.tsx b/frontend/components/SiteMenu.tsx new file mode 100644 index 0000000..aba4d1e --- /dev/null +++ b/frontend/components/SiteMenu.tsx @@ -0,0 +1,42 @@ +import React from "https://esm.sh/react@17.0.2"; +import styled from "https://esm.sh/styled-components"; + +import Anchor from "https://deno.land/x/aleph/framework/react/components/Anchor.ts"; +import { useRouter } from "https://deno.land/x/aleph/framework/react/hooks.ts"; + +const MenuContainer = styled.div` + display: flex; + justify-content: center; + padding: 0; + margin-bottom: 40px; +`; + +const MenuItem = styled.p<{ active: boolean }>` + margin: 0 10px; + display: block; + font-size: 20px; + text-align: center; + color: #ffd9aa; + text-shadow: #000 3px 3px 0px; + text-decoration: none; + + border-bottom: ${(props) => (props.active ? "1px solid #555" : "0 solid #fff")}; +`; + +const SiteMenuComponent = () => { + const router = useRouter(); + const routePath = router.routePath; + + return ( + + + Overview + + + Miners + + + ); +}; + +export default SiteMenuComponent; diff --git a/frontend/components/SiteTitle.tsx b/frontend/components/SiteTitle.tsx index 59bb12d..c83637d 100644 --- a/frontend/components/SiteTitle.tsx +++ b/frontend/components/SiteTitle.tsx @@ -4,7 +4,7 @@ import styled from "https://esm.sh/styled-components"; import config from "../back/config/config.ts"; const Title = styled.h1` - margin-top: 40px; + margin: 40px 0 20px; font-size: 42px; text-align: center; color: #d97b08; diff --git a/frontend/pages/index.tsx b/frontend/pages/index.tsx index 69b1410..49d4ecb 100644 --- a/frontend/pages/index.tsx +++ b/frontend/pages/index.tsx @@ -1,14 +1,14 @@ -import React, { useEffect, useState } from "https://esm.sh/react@17.0.2"; +import React from "https://esm.sh/react@17.0.2"; import styled from "https://esm.sh/styled-components"; import config from "../back/config/config.ts"; -import { IBlock } from "../back/blocks/index.ts"; import { Container } from "../components/Container.ts"; import { Content } from "../components/Content.ts"; import { BlockContainer, Block } from "../components/Block.tsx"; import { Donation } from "../components/Donation.tsx"; import SiteTitle from "../components/SiteTitle.tsx"; +import SiteMenu from "../components/SiteMenu.tsx"; import { useStoreState } from "../state/index.ts"; const DescriptionBlock = styled.div` @@ -70,6 +70,7 @@ export default function Blocks() { + {config.fork.info.map((text, index) => ( {text} diff --git a/frontend/pages/miners.tsx b/frontend/pages/miners.tsx new file mode 100644 index 0000000..f17ab2d --- /dev/null +++ b/frontend/pages/miners.tsx @@ -0,0 +1,132 @@ +import React, { useMemo } from "https://esm.sh/react@17.0.2"; +import styled from "https://esm.sh/styled-components"; + +import config from "../back/config/config.ts"; + +import { Container } from "../components/Container.ts"; +import { Content } from "../components/Content.ts"; +import SiteTitle from "../components/SiteTitle.tsx"; +import { useStoreState } from "../state/index.ts"; +import SiteMenu from "../components/SiteMenu.tsx"; + +const Table = styled.table` + max-width: 100%; + width: 1000px; + + box-shadow: #000 3px 3px 14px; + border-radius: 6px; + margin: auto; + border: 0; + border-collapse: collapse; + border-radius: 8px; + overflow: hidden; +`; + +const TableHead = styled.thead` + background-color: #383838; +`; + +const TableBody = styled.tbody` + text-align: center; + background-color: #434343; + + tr:hover { + background-color: #505050; + } +`; + +const TableRow = styled.tr` + border-bottom: 2px solid #393939; + + &:last-child { + border-bottom: 0; + } +`; + +const TableHeader = styled.th` + color: #efefef; + padding: 9px; +`; + +const Cell = styled.td` + color: #f0f0f0; + padding: 19px; +`; + +const SignallingCell = styled.td` + padding: 16px; + text-align: center; +`; + +interface IMinerData { + [key: string]: { + name: string; + signals: boolean; + }; +} + +export default function Miners() { + const blocks = useStoreState((store) => store.blocks); + + const forkName = config.fork.name; + + const miners = useMemo(() => { + // We have to reverse the array as we have to check + // for the latest block by a miner to decide whether they + // are signalling or not. + const blocksReversed = blocks.slice(0); + blocksReversed.reverse(); + + return blocksReversed.reduce((prev, currBlock) => { + if (!currBlock.miner) { + return prev; + } + + if (!prev[currBlock.miner]) { + prev[currBlock.miner] = { + name: currBlock.miner, + signals: currBlock.signals ?? false, + }; + } + return prev; + }, {} as IMinerData); + }, [blocks]); + + return ( + + + {forkName} activation - Miners + + + + + + + + Miner name + Signals + + + + + {Object.entries(miners).map(([_, miner]) => { + return ( + + {miner.name} + + {miner.signals && <>✅} + {!miner.signals && <>🚫} + + + ); + })} + + AntMiner + 🚫 + + +
+
+
+ ); +}