Преглед на файлове

Dashboard: council overlay

Joystream Stats преди 4 години
родител
ревизия
954eb4cd67
променени са 6 файла, в които са добавени 80 реда и са изтрити 43 реда
  1. 6 2
      src/App.tsx
  2. 14 10
      src/components/Council/ElectionStatus.tsx
  3. 48 22
      src/components/Council/index.tsx
  4. 9 8
      src/components/Dashboard/index.tsx
  5. 1 1
      src/components/Members/index.tsx
  6. 2 0
      src/types.ts

+ 6 - 2
src/App.tsx

@@ -69,6 +69,7 @@ class App extends React.Component<IProps, IState> {
     let round: number = Number(
       (await api.query.councilElection.round()).toJSON()
     );
+    this.save("round", round);
     let stage: any = await api.query.councilElection.stage();
     this.save("stage", stage);
     let councilElection = { termEndsAt, stage: stage.toJSON(), round };
@@ -486,7 +487,9 @@ class App extends React.Component<IProps, IState> {
   }
   loadCouncils() {
     const councils = this.load("councils");
-    if (councils) this.setState({ councils });
+    if (!councils || !councils.length || typeof councils[0][0] === "number")
+      return;
+    this.setState({ councils });
   }
   loadProposals() {
     const proposals = this.load("proposals");
@@ -557,8 +560,9 @@ class App extends React.Component<IProps, IState> {
     await this.loadReports();
     const block = this.load("block");
     const now = this.load("now");
+    const round = this.load("round");
     const stage = this.load("stage");
-    this.setState({ block, now, stage, termEndsAt, loading: false });
+    this.setState({ block, now, round, stage, termEndsAt, loading: false });
     console.debug(`Finished loading.`);
   }
 

+ 14 - 10
src/components/Council/ElectionStatus.tsx

@@ -1,6 +1,14 @@
 import React from "react";
 import { domain } from "../../config";
 
+const timeLeft = (blocks: number) => {
+  const seconds = blocks * 6;
+  const days = Math.floor(seconds / 86400);
+  const hours = Math.floor((seconds - days * 86400) / 3600);
+  const minutes = Math.floor(seconds / 60);
+  return days ? `${days}d` : hours ? `${hours}h` : `${minutes}min`;
+};
+
 const ElectionStage = (props: {
   termEndsAt: number;
   block: number;
@@ -10,25 +18,21 @@ const ElectionStage = (props: {
 
   if (!stage) {
     if (!block || !termEndsAt) return <div />;
-    const blocks = termEndsAt - block;
-    const seconds = blocks * 6;
-    const days = Math.floor(seconds / 86400);
-    const hours = Math.floor((seconds - days * 86400) / 3600);
-    const minutes = Math.floor(seconds / 60);
-    const counter = days ? `${days}d` : hours ? `${hours}h` : `${minutes}min`;
-    return <div>Next election in {counter}</div>;
+    const left = timeLeft(termEndsAt - block);
+    return <div>election in {left}</div>;
   }
 
   let stageString = Object.keys(JSON.parse(JSON.stringify(stage)))[0];
+  const left = timeLeft(stage[stageString] - block);
 
   if (stageString === "Announcing")
-    return <a href={`${domain}/#/council/applicants`}>Apply now!</a>;
+    return <a href={`${domain}/#/council/applicants`}>{left} to apply</a>;
 
   if (stageString === "Voting")
-    return <a href={`${domain}/#/council/applicants`}>Vote now!</a>;
+    return <a href={`${domain}/#/council/applicants`}>{left} to vote</a>;
 
   if (stageString === "Revealing")
-    return <a href={`${domain}/#/council/votes`}>Reveal your vote!</a>;
+    return <a href={`${domain}/#/council/votes`}>{left} to reveal votes</a>;
 
   return <div>{JSON.stringify(stage)}</div>;
 };

+ 48 - 22
src/components/Council/index.tsx

@@ -1,29 +1,31 @@
 import React from "react";
 import { Link } from "react-router-dom";
 import ElectionStatus from "./ElectionStatus";
-import User from "../User";
+import MemberBox from "../Members/MemberBox";
 import Loading from "../Loading";
-import { Member } from "../../types";
-
-const CouncilMember = (props: { member: Member }) => {
-  const { account, handle } = props.member;
-  return (
-    <div className="col">
-      <User id={String(account)} handle={handle} />
-    </div>
-  );
-};
+import { Handles, Member, Post, ProposalDetail, Seat } from "../../types";
 
 const Council = (props: {
-  council: Member[];
+  councils: Seat[][];
   councilElection?: any;
   block: number;
+  members: Member[];
   stage: any;
   termEndsAt: number;
+  proposals: ProposalDetail[];
+  posts: Post[];
+  now: number;
+  validators: string[];
+  handles: Handles;
+  round: number;
 }) => {
-  const { council, block, councilElection, termEndsAt } = props;
-  const half = Math.floor(council.length / 2);
-  const show = council.length;
+  const { councilElection, members, handles, round, termEndsAt } = props;
+
+  const council = props.councils[props.councils.length - 1];
+  const show = round && council;
+  const half = show ? Math.floor(council.length / 2) : 0;
+
+  const startTime = props.now - props.block * 6000;
 
   return (
     <div className="box">
@@ -31,21 +33,45 @@ const Council = (props: {
         show={show}
         stage={props.stage}
         termEndsAt={termEndsAt}
-        block={block}
+        block={props.block}
         {...councilElection}
       />
       <h3>Council</h3>
 
       {(show && (
         <div className="d-flex flex-column">
-          <div className="d-flex flex-row">
-            {council.slice(0, half).map((member) => (
-              <CouncilMember key={String(member.account)} member={member} />
+          <div className="d-flex flex-row justify-content-between">
+            {council.slice(0, half).map((m) => (
+              <MemberBox
+                key={m.member}
+                id={m.id || 0}
+                account={m.member}
+                handle={m.handle || handles[m.member]}
+                members={members}
+                councils={props.councils}
+                proposals={props.proposals}
+                placement={"top"}
+                posts={props.posts}
+                startTime={startTime}
+                validators={props.validators}
+              />
             ))}
           </div>
-          <div className="d-flex flex-row">
-            {council.slice(half).map((member) => (
-              <CouncilMember key={String(member.account)} member={member} />
+          <div className="d-flex flex-row justify-content-between">
+            {council.slice(half).map((m) => (
+              <MemberBox
+                key={m.member}
+                id={m.id || 0}
+                account={m.member}
+                handle={m.handle || handles[m.member]}
+                members={members}
+                councils={props.councils}
+                proposals={props.proposals}
+                placement={"top"}
+                posts={props.posts}
+                startTime={startTime}
+                validators={props.validators}
+              />
             ))}
           </div>
         </div>

+ 9 - 8
src/components/Dashboard/index.tsx

@@ -7,13 +7,7 @@ import Loading from "../Loading";
 import { IState, Member } from "../../types";
 
 const Dashboard = (props: IState) => {
-  const { block, councils, domain, handles, members, proposals } = props;
-  const council: Member[] = [];
-  if (councils.length)
-    councils[councils.length - 1].forEach((seat) => {
-      const member = members.find((m) => seat.member === m.account);
-      member && council.push(member);
-    });
+  const { block, now, councils, domain, handles, members, proposals } = props;
 
   return (
     <div className="w-100 flex-grow-1 d-flex align-items-center justify-content-center d-flex flex-column">
@@ -34,11 +28,18 @@ const Dashboard = (props: IState) => {
       </div>
 
       <Council
-        council={council}
+        councils={councils}
+        members={members}
         councilElection={props.councilElection}
         block={block}
+        now={now}
+        round={props.round}
+        handles={props.handles}
         termEndsAt={props.termEndsAt}
         stage={props.stage}
+        posts={props.posts}
+        proposals={props.proposals}
+        validators={props.validators}
       />
       <div className="d-flex flex-row">
         <Validators validators={props.validators} handles={handles} />

+ 1 - 1
src/components/Members/index.tsx

@@ -51,7 +51,7 @@ class Members extends React.Component<IProps, IState> {
       <div>
         <Back />
         <h1 className="text-center text-white">Joystream Members</h1>
-        <div className="d-flex flew-row justify-content-inbetween">
+        <div className="d-flex flew-row justify-content-between">
           {cols.map((col, index: number) => (
             <div key={`col-${index}`} className="d-flex flex-column col-3 p-0">
               {col.map((m) => (

+ 2 - 0
src/types.ts

@@ -41,6 +41,8 @@ export interface IState {
 
 export interface Seat {
   member: string;
+  handle?: string;
+  id?: number;
   stake: number;
   backers: Backer[];
 }