Hampus Sjöberg
4 years ago
4 changed files with 178 additions and 3 deletions
@ -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 ( |
||||
|
<MenuContainer> |
||||
|
<Anchor style={{ textDecoration: "none" }} href="/"> |
||||
|
<MenuItem active={routePath === "/"}>Overview</MenuItem> |
||||
|
</Anchor> |
||||
|
<Anchor style={{ textDecoration: "none" }} href="/miners"> |
||||
|
<MenuItem active={routePath === "/miners"}>Miners</MenuItem> |
||||
|
</Anchor> |
||||
|
</MenuContainer> |
||||
|
); |
||||
|
}; |
||||
|
|
||||
|
export default SiteMenuComponent; |
@ -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 ( |
||||
|
<Container> |
||||
|
<head> |
||||
|
<title>{forkName} activation - Miners</title> |
||||
|
</head> |
||||
|
<Content> |
||||
|
<SiteTitle /> |
||||
|
<SiteMenu /> |
||||
|
<Table> |
||||
|
<TableHead> |
||||
|
<TableRow> |
||||
|
<TableHeader>Miner name</TableHeader> |
||||
|
<TableHeader>Signals</TableHeader> |
||||
|
</TableRow> |
||||
|
</TableHead> |
||||
|
|
||||
|
<TableBody> |
||||
|
{Object.entries(miners).map(([_, miner]) => { |
||||
|
return ( |
||||
|
<TableRow> |
||||
|
<Cell>{miner.name}</Cell> |
||||
|
<SignallingCell> |
||||
|
{miner.signals && <>✅</>} |
||||
|
{!miner.signals && <>🚫</>} |
||||
|
</SignallingCell> |
||||
|
</TableRow> |
||||
|
); |
||||
|
})} |
||||
|
<TableRow> |
||||
|
<Cell>AntMiner</Cell> |
||||
|
<SignallingCell>🚫</SignallingCell> |
||||
|
</TableRow> |
||||
|
</TableBody> |
||||
|
</Table> |
||||
|
</Content> |
||||
|
</Container> |
||||
|
); |
||||
|
} |
Loading…
Reference in new issue