Spending.tsx 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import React from "react";
  2. import { Link } from "react-router-dom";
  3. import { IState, ProposalDetail } from "../../types";
  4. import Back from "../Back";
  5. const amount = (amount: number) => (amount / 1000000).toFixed(2);
  6. const getRound = (block: number): number =>
  7. Math.round((block - 57600) / 201600);
  8. const executionFailed = (result: string, executed: any) => {
  9. if (result !== "Approved") return result;
  10. if (!executed || !Object.keys(executed)) return;
  11. if (executed.Approved && executed.Approved.ExecutionFailed)
  12. return executed.Approved.ExecutionFailed.error;
  13. return false;
  14. };
  15. const Spending = (props: IState) => {
  16. const spending = props.proposals.filter(
  17. (p: ProposalDetail) => p && p.type === "spending"
  18. );
  19. const rounds: ProposalDetail[][] = [];
  20. let unknown = 0;
  21. let sum = 0;
  22. let sums: number[] = [];
  23. spending.forEach((p) => {
  24. const r = getRound(p.finalizedAt);
  25. rounds[r] = rounds[r] ? rounds[r].concat(p) : [p];
  26. if (!sums[r]) sums[r] = 0;
  27. if (!p.detail) return unknown++;
  28. if (executionFailed(p.result, p.executed)) return;
  29. sum += p.detail.spending[0];
  30. sums[r] += p.detail.spending[0];
  31. });
  32. return (
  33. <div className="box text-left">
  34. <div className="back position-fixed">
  35. <Back history={props.history} />
  36. </div>
  37. <h1 className="text-left">
  38. Total: {amount(sum)}
  39. {unknown ? `*` : ``} M tJOY
  40. </h1>
  41. {unknown ? `* subject to change until all details are available` : ``}
  42. {rounds.map((proposals, i: number) => (
  43. <div key={`round-${i}`} className="bg-secondary p-1 my-2">
  44. <h2 className="text-left mt-3">
  45. Round {i} <small>{amount(sums[i])} M</small>
  46. </h2>
  47. {proposals.map((p) => (
  48. <ProposalLine key={p.id} {...p} />
  49. ))}
  50. </div>
  51. ))}
  52. </div>
  53. );
  54. };
  55. export default Spending;
  56. const ProposalLine = (props: any) => {
  57. const { id, title, detail, author, executed, result } = props;
  58. const failed = executionFailed(result, executed);
  59. return (
  60. <div key={id} className={failed ? "bg-danger" : "bg-warn"}>
  61. <span
  62. className={`bg-${failed ? "danger" : "warning"} text-body p-1 mr-2`}
  63. >
  64. {detail ? amount(detail.spending[0]) : `?`} M
  65. </span>
  66. <Link to={`/proposals/${id}`}>{title}</Link> (
  67. <Link to={`/members/${author}`}>{author}</Link>)
  68. {failed ? ` - ${failed}` : ""}
  69. </div>
  70. );
  71. };