index.tsx 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import React from "react";
  2. import { Button, OverlayTrigger, Tooltip, Table } from "react-bootstrap";
  3. import { Link } from "react-router-dom";
  4. import { ProposalDetail } from "../../types";
  5. import Loading from "..//Loading";
  6. import Row from "./Row";
  7. import moment from "moment";
  8. const Proposals = (props: {
  9. now: number;
  10. block: number;
  11. proposals: ProposalDetail[];
  12. proposalPosts: any[];
  13. }) => {
  14. const { proposalPosts, block, now } = props;
  15. const startTime: number = now - block * 6000;
  16. // prepare proposals
  17. // - remove empty
  18. const proposals = props.proposals
  19. .filter((p) => p)
  20. .sort((a, b) => b.id - a.id);
  21. // - communicate loading state
  22. if (!proposals.length)
  23. return (
  24. <div className="box">
  25. <h1>Loading</h1>
  26. <Loading />
  27. </div>
  28. );
  29. // - calculate blocks until finalized
  30. const durations: any = proposals.map((p) =>
  31. p.finalizedAt ? p.finalizedAt - p.createdAt : 0
  32. );
  33. // - calculate mean voting duration
  34. const avgBlocks =
  35. durations.reduce((a: number, b: number) => a + b) / durations.length;
  36. const avgDays = avgBlocks ? Math.floor(avgBlocks / 14400) : 0;
  37. const avgHours = avgBlocks
  38. ? Math.floor((avgBlocks - avgDays * 14400) / 600)
  39. : 0;
  40. // - list all proposals
  41. return (
  42. <div className="bg-light text-center">
  43. <Link to={`/`}>
  44. <Button variant="secondary" className="p-1 m-3">
  45. back
  46. </Button>
  47. </Link>
  48. <h1>Joystream Proposals</h1>
  49. <Table>
  50. <thead>
  51. <tr>
  52. <td>ID</td>
  53. <td className="text-right">Proposal</td>
  54. <td>Result</td>
  55. <td>
  56. Voting Duration
  57. <br />
  58. Average: {avgDays ? `${avgDays}d` : ""}{" "}
  59. {avgHours ? `${avgHours}h` : ""}
  60. </td>
  61. <td className="text-right">Created</td>
  62. <td className="text-left">Finalized</td>
  63. </tr>
  64. </thead>
  65. <tbody>
  66. {proposals.map((p) => (
  67. <Row
  68. key={p.id}
  69. {...p}
  70. block={block}
  71. startTime={startTime}
  72. posts={proposalPosts.filter((post) => post.threadId === p.id)}
  73. />
  74. ))}
  75. </tbody>
  76. </Table>
  77. </div>
  78. );
  79. };
  80. export default Proposals;