SealedVote.tsx 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import React from 'react';
  2. import { Link } from 'react-router-dom';
  3. import { Table } from 'semantic-ui-react';
  4. import { I18nProps } from '@polkadot/react-components/types';
  5. import { ApiProps } from '@polkadot/react-api/types';
  6. import { withCalls } from '@polkadot/react-api/with';
  7. import { Hash } from '@polkadot/types/interfaces';
  8. import { formatBalance } from '@polkadot/util';
  9. import translate from './translate';
  10. import { calcTotalStake } from '@polkadot/joy-utils/index';
  11. import { SealedVote } from '@joystream/types/council';
  12. import AddressMini from '@polkadot/react-components/AddressMiniJoy';
  13. import CandidatePreview from './CandidatePreview';
  14. import { findVoteByHash } from './myVotesStore';
  15. type Props = ApiProps & I18nProps & {
  16. hash: Hash;
  17. sealedVote?: SealedVote;
  18. };
  19. class Comp extends React.PureComponent<Props> {
  20. renderCandidateOrAction () {
  21. const { hash, sealedVote } = this.props;
  22. if (!sealedVote) {
  23. return <em>Unknown hashed vote: {hash.toHex()}</em>;
  24. }
  25. if (sealedVote.vote.isSome) {
  26. const candidateId = sealedVote.vote.unwrap();
  27. return <CandidatePreview accountId={candidateId} />;
  28. } else {
  29. const revealUrl = `/council/reveals?hashedVote=${hash.toHex()}`;
  30. return <Link to={revealUrl} className='ui button primary inverted'>Reveal this vote</Link>;
  31. }
  32. }
  33. render () {
  34. const { hash, sealedVote } = this.props;
  35. const myVote = findVoteByHash(hash.toHex());
  36. return !sealedVote ? null : (
  37. <Table celled selectable compact definition className='SealedVoteTable'>
  38. <Table.Body>
  39. <Table.Row>
  40. <Table.Cell>Hash</Table.Cell>
  41. <Table.Cell><code>{hash.toHex()}</code></Table.Cell>
  42. </Table.Row>
  43. {myVote && <Table.Row>
  44. <Table.Cell>Salt</Table.Cell>
  45. <Table.Cell><code>{myVote.salt}</code></Table.Cell>
  46. </Table.Row>}
  47. <Table.Row>
  48. <Table.Cell>Stake</Table.Cell>
  49. <Table.Cell>{formatBalance(calcTotalStake(sealedVote.stake))}</Table.Cell>
  50. </Table.Row>
  51. {myVote && <Table.Row>
  52. <Table.Cell>Voted on</Table.Cell>
  53. <Table.Cell>{new Date(myVote.votedOnTime).toLocaleString()}</Table.Cell>
  54. </Table.Row>}
  55. <Table.Row>
  56. <Table.Cell>Voter</Table.Cell>
  57. <Table.Cell><AddressMini value={sealedVote.voter} isShort={false} isPadded={false} withBalance={true} /></Table.Cell>
  58. </Table.Row>
  59. <Table.Row>
  60. <Table.Cell>Candidate</Table.Cell>
  61. <Table.Cell>{this.renderCandidateOrAction()}</Table.Cell>
  62. </Table.Row>
  63. </Table.Body>
  64. </Table>
  65. );
  66. }
  67. }
  68. // inject the actual API calls automatically into props
  69. export default translate(
  70. withCalls<Props>(
  71. ['query.councilElection.votes',
  72. { paramName: 'hash', propName: 'sealedVote' }]
  73. )(Comp)
  74. );