CouncilVotes.tsx 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import React, { Component } from "react";
  2. import { Table } from "react-bootstrap";
  3. import ProposalOverlay from "../Proposals/ProposalOverlay";
  4. import VoteDiv from "./VoteDiv";
  5. import { Member, ProposalDetail, Seat } from "../../types";
  6. interface IProps {
  7. block: number;
  8. round: number;
  9. council: Seat[];
  10. members: Member[];
  11. proposals: ProposalDetail[];
  12. expand?: boolean;
  13. }
  14. interface IState {
  15. expand: boolean;
  16. }
  17. class CouncilVotes extends Component<IProps, IState> {
  18. constructor(props: IProps) {
  19. super(props);
  20. this.state = { expand: false };
  21. this.toggleExpand = this.toggleExpand.bind(this);
  22. }
  23. componentDidMount() {
  24. const { expand } = this.props;
  25. if (expand) this.setState({ expand });
  26. }
  27. toggleExpand() {
  28. this.setState({ expand: !this.state.expand });
  29. }
  30. render() {
  31. const { block, council, members, proposals, round } = this.props;
  32. const { expand } = this.state;
  33. let councilMembers: Member[] = [];
  34. council.forEach((seat) => {
  35. const member = members.find((m) => m.account === seat.member);
  36. if (!member) return;
  37. councilMembers.push(member);
  38. });
  39. const fail = "btn btn-outline-danger";
  40. const styles: { [key: string]: string } = {
  41. Approved: "btn btn-success",
  42. Rejected: fail,
  43. Canceled: fail,
  44. Expired: fail,
  45. Pending: "btn btn-warning",
  46. };
  47. return (
  48. <Table className="text-light text-center">
  49. <thead onClick={this.toggleExpand}>
  50. <tr>
  51. <th className="text-right" style={{ width: "40%" }}>
  52. Round {round}
  53. </th>
  54. {councilMembers.map((member) => (
  55. <th key={member.handle} style={{ width: "10%" }}>
  56. {member.handle}
  57. </th>
  58. ))}
  59. </tr>
  60. </thead>
  61. <tbody>
  62. {expand &&
  63. proposals
  64. .sort((a, b) => a.createdAt - b.createdAt)
  65. .map((p) => (
  66. <tr key={p.id} className={`text-left`}>
  67. <td
  68. className={`float-right mt-1 p-0 px-1 ${styles[p.result]}`}
  69. >
  70. <ProposalOverlay block={block} {...p} />
  71. </td>
  72. {p.votesByAccount &&
  73. council.map((seat) => (
  74. <VoteDiv
  75. key={seat.member}
  76. votes={p.votesByAccount}
  77. member={members.find((m) => m.account === seat.member)}
  78. />
  79. ))}
  80. </tr>
  81. ))}
  82. </tbody>
  83. </Table>
  84. );
  85. }
  86. }
  87. export default CouncilVotes;