VotingSection.tsx 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import React, { useState } from "react";
  2. import { Icon, Button, Message, Divider, Header } from "semantic-ui-react";
  3. import useVoteStyles from "./useVoteStyles";
  4. import TxButton from "@polkadot/joy-utils/TxButton";
  5. import { MemberId } from "@joystream/types/members";
  6. import { ProposalId } from "@joystream/types/proposals";
  7. import { useTransport } from "../runtime";
  8. import { VoteKind } from '@joystream/types/proposals';
  9. import { usePromise } from "../utils";
  10. import { VoteKinds } from "@joystream/types/proposals";
  11. export type VoteKindStr = typeof VoteKinds[number];
  12. type VoteButtonProps = {
  13. memberId: MemberId,
  14. voteKind: VoteKindStr,
  15. proposalId: ProposalId,
  16. onSuccess: () => void
  17. }
  18. function VoteButton({ voteKind, proposalId, memberId, onSuccess }: VoteButtonProps) {
  19. const { icon, color } = useVoteStyles(voteKind);
  20. return (
  21. // Button.Group "cheat" to force TxButton color
  22. <Button.Group color={color} style={{ marginRight: '5px' }}>
  23. <TxButton
  24. // isDisabled={ isSubmitting }
  25. params={[
  26. memberId,
  27. proposalId,
  28. voteKind
  29. ]}
  30. tx={ `proposalsEngine.vote` }
  31. onClick={ sendTx => sendTx() }
  32. txFailedCb={ () => null }
  33. txSuccessCb={ onSuccess }
  34. className={`icon left labeled`}>
  35. <Icon name={icon} inverted />
  36. { voteKind }
  37. </TxButton>
  38. </Button.Group>
  39. )
  40. }
  41. type VotingSectionProps = {
  42. memberId: MemberId,
  43. proposalId: ProposalId,
  44. isVotingPeriod: boolean,
  45. };
  46. export default function VotingSection({
  47. memberId,
  48. proposalId,
  49. isVotingPeriod
  50. }: VotingSectionProps) {
  51. const transport = useTransport();
  52. const [voted, setVoted] = useState<VoteKindStr | null >(null);
  53. const [vote] = usePromise<VoteKind | null | undefined>(
  54. () => transport.voteByProposalAndMember(proposalId, memberId),
  55. undefined
  56. );
  57. if (vote === undefined) {
  58. // Loading / error
  59. return null;
  60. }
  61. const voteStr: VoteKindStr | null = voted || (vote && vote.type.toString() as VoteKindStr);
  62. if (voteStr) {
  63. const { icon, color } = useVoteStyles(voteStr);
  64. return (
  65. <Message icon color={color}>
  66. <Icon name={icon} />
  67. <Message.Content>
  68. You voted <span className="bold">{`"${voteStr}"`}</span>
  69. </Message.Content>
  70. </Message>
  71. );
  72. }
  73. else if (!isVotingPeriod) {
  74. return null;
  75. }
  76. return (
  77. <>
  78. <Header as="h3">Sumbit your vote</Header>
  79. <Divider />
  80. { VoteKinds.map((voteKind) =>
  81. <VoteButton
  82. voteKind={voteKind}
  83. memberId={memberId}
  84. proposalId={proposalId}
  85. key={voteKind}
  86. onSuccess={ () => setVoted(voteKind) }/>
  87. ) }
  88. </>
  89. );
  90. }