1- import React , { useMemo } from "https://esm.sh/react@17.0.2" ;
1+ import React , { useMemo , useState } from "https://esm.sh/react@17.0.2" ;
22import styled from "https://esm.sh/styled-components" ;
33import Anchor from "https://deno.land/x/aleph@v0.3.0-alpha.32/framework/react/components/Anchor.ts" ;
44
@@ -13,6 +13,7 @@ import SiteMenu from "../components/SiteMenu.tsx";
1313import { Donation } from "../components/Donation.tsx" ;
1414import ContactTwitter from "../components/ContactTwitter.tsx" ;
1515import CommonHeader from "../components/CommonHeader.ts" ;
16+ import { IMinerData , IMiners } from "../back/common/interfaces.ts" ;
1617
1718const Table = styled . table `
1819 width: 100%;
@@ -51,12 +52,24 @@ const TableHeader = styled.th`
5152 padding: 9px;
5253` ;
5354
55+ export const TableHeaderLink = styled . a `
56+ color: #efefef;
57+ cursor: pointer;
58+ text-decoration: none;
59+ display: inline-block;
60+ ` ;
61+
62+ export const TableHeaderSortContainer = styled . span `
63+ position: absolute;
64+ margin-left: 3px;
65+ ` ;
66+
5467const Cell = styled . td `
5568 color: #f0f0f0;
5669 > a {
5770 color: #f0f0f0;
5871 }
59- padding: 17px ;
72+ padding: 16px ;
6073` ;
6174
6275const SignallingCell = styled . td `
@@ -85,6 +98,15 @@ const TotalsPotential = styled(CommonHeader)`
8598 text-underline-position: under;
8699` ;
87100
101+ type SortKey = "name" | "share" | "blocks" | "signallingStatus" ;
102+ interface TableRow {
103+ name : string ;
104+ share : string ;
105+ blocks : string ;
106+ signallingStatus : boolean ;
107+ website : string | undefined ;
108+ }
109+
88110export default function Miners ( ) {
89111 const blocks = useStoreState ( ( store ) => store . blocks ) ;
90112 const forkName = config . fork . name ;
@@ -96,6 +118,47 @@ export default function Miners() {
96118 const totalSignallingPotentialRatio = miners
97119 . filter ( ( [ _ , m ] ) => m . numSignallingBlocks > 0 )
98120 . reduce ( ( sum , [ _ , m ] ) => sum + m . numBlocks / currentNumberOfBlocks , 0 ) ;
121+ const [ sortKey , setSortKey ] = useState < SortKey > ( "share" ) ;
122+ const [ sortDirection , setSortDirection ] = useState < "ASC" | "DESC" > ( "DESC" ) ;
123+
124+ const fixTable = ( miners : [ string , IMinerData ] [ ] , key : SortKey ) : TableRow [ ] => {
125+ let data = miners
126+ . map ( ( [ _ , miner ] ) => {
127+ const r : TableRow = {
128+ name : miner . name ,
129+ share : `${ ( ( miner . numBlocks / currentNumberOfBlocks ) * 100 ) . toFixed ( 2 ) } %` ,
130+ blocks : `${ miner . numSignallingBlocks } /${ miner . numBlocks + " " } ` ,
131+ signallingStatus : miner . signals ,
132+ website : miner . website ,
133+ } ;
134+ return r ;
135+ } )
136+ . sort ( ( a , b ) => {
137+ if ( key === "blocks" ) {
138+ return Number . parseInt ( b [ "blocks" ] . split ( "/" ) [ 0 ] ) - Number . parseInt ( a [ "blocks" ] . split ( "/" ) [ 0 ] ) ;
139+ } else if ( key === "share" ) {
140+ return Number . parseFloat ( b [ "share" ] . split ( "%" ) [ 0 ] ) - Number . parseFloat ( a [ "share" ] . split ( "%" ) [ 0 ] ) ;
141+ }
142+ return `${ b [ key ] } ` . localeCompare ( `${ a [ key ] } ` ) ;
143+ } ) ;
144+
145+ if ( sortDirection === "ASC" ) {
146+ data = data . slice ( ) . reverse ( ) ;
147+ }
148+ return data ;
149+ } ;
150+
151+ const onClickSort = ( e : React . MouseEvent < HTMLAnchorElement , MouseEvent > , key : SortKey ) => {
152+ e . preventDefault ( ) ;
153+ if ( sortKey !== key ) {
154+ setSortKey ( key ) ;
155+ setSortDirection ( "DESC" ) ;
156+ } else {
157+ setSortDirection ( sortDirection === "DESC" ? "ASC" : "DESC" ) ;
158+ }
159+ } ;
160+
161+ const tableData = fixTable ( miners , sortKey ) ;
99162
100163 return (
101164 < Container >
@@ -116,34 +179,59 @@ export default function Miners() {
116179 < Table >
117180 < TableHead >
118181 < TableRow >
119- < TableHeader > Mining pool</ TableHeader >
120- < TableHeader > Share</ TableHeader >
121- < TableHeader > Blocks</ TableHeader >
122- < TableHeader > Signals</ TableHeader >
182+ < TableHeader >
183+ < TableHeaderLink href = "#" onClick = { ( e ) => onClickSort ( e , "name" ) } >
184+ Mining pool{ " " }
185+ < TableHeaderSortContainer >
186+ { sortKey === "name" && ( sortDirection === "ASC" ? "▴" : "▾" ) }
187+ </ TableHeaderSortContainer >
188+ </ TableHeaderLink >
189+ </ TableHeader >
190+ < TableHeader >
191+ < TableHeaderLink href = "#" onClick = { ( e ) => onClickSort ( e , "share" ) } >
192+ Share{ " " }
193+ < TableHeaderSortContainer >
194+ { sortKey === "share" && ( sortDirection === "ASC" ? "▴" : "▾" ) }
195+ </ TableHeaderSortContainer >
196+ </ TableHeaderLink >
197+ </ TableHeader >
198+ < TableHeader >
199+ < TableHeaderLink href = "#" onClick = { ( e ) => onClickSort ( e , "blocks" ) } >
200+ Blocks{ " " }
201+ < TableHeaderSortContainer >
202+ { sortKey === "blocks" && ( sortDirection === "ASC" ? "▴" : "▾" ) }
203+ </ TableHeaderSortContainer >
204+ </ TableHeaderLink >
205+ </ TableHeader >
206+ < TableHeader >
207+ < TableHeaderLink href = "#" onClick = { ( e ) => onClickSort ( e , "signallingStatus" ) } >
208+ Signals{ " " }
209+ < TableHeaderSortContainer >
210+ { sortKey === "signallingStatus" && ( sortDirection === "ASC" ? "▴" : "▾" ) }
211+ </ TableHeaderSortContainer >
212+ </ TableHeaderLink >
213+ </ TableHeader >
123214 </ TableRow >
124215 </ TableHead >
125-
126216 < TableBody >
127- { miners . map ( ( [ key , miner ] ) => {
217+ { tableData . map ( ( row ) => {
128218 return (
129- < TableRow key = { key } >
219+ < TableRow key = { row . name } >
130220 < Cell >
131- { miner . website && (
132- < a href = { miner . website } target = "_blank" >
133- { miner . name }
221+ { row . website && (
222+ < a href = { row . website } target = "_blank" >
223+ { row . name }
134224 </ a >
135225 ) }
136- { ! miner . website && miner . name }
226+ { ! row . website && row . name }
137227 </ Cell >
138- < Cell > { ( ( miner . numBlocks / currentNumberOfBlocks ) * 100 ) . toFixed ( 2 ) } % </ Cell >
228+ < Cell > { row . share } </ Cell >
139229 < SignallingCell >
140- < Anchor href = { `/miner/${ miner . name } ` } >
141- { miner . numSignallingBlocks } /{ miner . numBlocks + " " }
142- </ Anchor >
230+ < Anchor href = { `/miner/${ row . name } ` } > { row . blocks } </ Anchor >
143231 </ SignallingCell >
144232 < SignallingCell >
145- { miner . signals && < > ✅</ > }
146- { ! miner . signals && < > 🚫</ > }
233+ { row . signallingStatus && < > ✅</ > }
234+ { ! row . signallingStatus && < > 🚫</ > }
147235 </ SignallingCell >
148236 </ TableRow >
149237 ) ;
0 commit comments