Fix Funding Progress calculation
Fix BN types Add contributors tab Adjust UserRow to optionally show amount as secondary text Add contributionAmount to contributors in crowdFund General cleanup
This commit is contained in:
parent
329319692a
commit
3862b18670
|
@ -12,11 +12,11 @@ import { RadioChangeEvent } from 'antd/lib/radio';
|
|||
import TrusteeFields from './TrusteeFields';
|
||||
import MilestoneFields, { Milestone } from './MilestoneFields';
|
||||
import CreateSuccess from './CreateSuccess';
|
||||
import { computePercentage } from 'utils/helpers';
|
||||
import { getAmountError } from 'utils/validators';
|
||||
import MarkdownEditor from 'components/MarkdownEditor';
|
||||
import * as Styled from './styled';
|
||||
|
||||
import { Wei, toWei } from 'utils/units';
|
||||
import BN from 'bn.js';
|
||||
interface StateProps {
|
||||
crowdFundLoading: AppState['web3']['crowdFundLoading'];
|
||||
crowdFundError: AppState['web3']['crowdFundError'];
|
||||
|
@ -74,8 +74,8 @@ const DEFAULT_STATE: State = {
|
|||
milestoneDeadline: 60 * 60 * 24 * 7,
|
||||
};
|
||||
|
||||
function milestoneToMilestoneAmount(milestone: Milestone, raiseGoal: number) {
|
||||
return computePercentage(raiseGoal, milestone.payoutPercent);
|
||||
function milestoneToMilestoneAmount(milestone: Milestone, raiseGoal: Wei) {
|
||||
return raiseGoal.divn(100).mul(new BN(milestone.payoutPercent));
|
||||
}
|
||||
|
||||
class CreateProposal extends React.Component<Props, State> {
|
||||
|
@ -159,7 +159,7 @@ class CreateProposal extends React.Component<Props, State> {
|
|||
};
|
||||
|
||||
createCrowdFund = async () => {
|
||||
const { contract, createCrowdFund, web3 } = this.props;
|
||||
const { contract, createCrowdFund } = this.props;
|
||||
const {
|
||||
title,
|
||||
proposalBody,
|
||||
|
@ -173,11 +173,11 @@ class CreateProposal extends React.Component<Props, State> {
|
|||
} = this.state;
|
||||
|
||||
const backendData = { content: proposalBody, title, category };
|
||||
|
||||
const targetInWei = web3.utils.toWei(String(amountToRaise), 'ether');
|
||||
const targetInWei = toWei(amountToRaise, 'ether');
|
||||
const milestoneAmounts = milestones.map(milestone =>
|
||||
milestoneToMilestoneAmount(milestone, targetInWei),
|
||||
Wei(milestoneToMilestoneAmount(milestone, targetInWei)),
|
||||
);
|
||||
console.log('milestoneAmounts', milestoneAmounts);
|
||||
const immediateFirstMilestonePayout = milestones[0].immediatePayout;
|
||||
|
||||
const contractData = {
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
import React from 'react';
|
||||
import { Spin } from 'antd';
|
||||
import { CrowdFund } from 'modules/proposals/reducers';
|
||||
import UserRow from 'components/UserRow';
|
||||
import * as ProposalStyled from '../styled';
|
||||
|
||||
interface Props {
|
||||
crowdFund: CrowdFund;
|
||||
}
|
||||
|
||||
const ContributorsBlock = ({ crowdFund }: Props) => {
|
||||
let content;
|
||||
if (crowdFund) {
|
||||
content = crowdFund.contributors.map(contributor => (
|
||||
<UserRow
|
||||
key={contributor.address}
|
||||
address={contributor.address}
|
||||
amount={contributor.contributionAmount}
|
||||
/>
|
||||
));
|
||||
} else {
|
||||
content = <Spin />;
|
||||
}
|
||||
|
||||
return (
|
||||
<ProposalStyled.SideBlock>
|
||||
<ProposalStyled.BlockTitle>Contributors</ProposalStyled.BlockTitle>
|
||||
<ProposalStyled.Block>{content}</ProposalStyled.Block>
|
||||
</ProposalStyled.SideBlock>
|
||||
);
|
||||
};
|
||||
|
||||
export default ContributorsBlock;
|
|
@ -15,6 +15,7 @@ import Milestones from './Milestones';
|
|||
import CommentsTab from './Comments';
|
||||
import UpdatesTab from './Updates';
|
||||
import GovernanceTab from './Governance';
|
||||
import ContributorsTab from './Contributors';
|
||||
// import CommunityTab from './Community';
|
||||
import * as Styled from './styled';
|
||||
import { withRouter } from 'next/router';
|
||||
|
@ -113,9 +114,12 @@ class ProposalDetail extends React.Component<Props, State> {
|
|||
<div style={{ marginTop: '1.5rem' }} />
|
||||
<UpdatesTab proposalId={proposal.proposalId} />
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="Governance" key="governanc">
|
||||
<Tabs.TabPane tab="Governance" key="governance">
|
||||
<GovernanceTab proposal={proposal} />
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="Contributors" key="contributors">
|
||||
<ContributorsTab crowdFund={proposal.crowdFund} />
|
||||
</Tabs.TabPane>
|
||||
</Tabs>
|
||||
)}
|
||||
</Styled.Container>
|
||||
|
|
|
@ -2,14 +2,14 @@ import React from 'react';
|
|||
import ShortAddress from 'components/ShortAddress';
|
||||
import Identicon from 'components/Identicon';
|
||||
import * as Styled from './styled';
|
||||
import { Wei, fromWei } from 'utils/units';
|
||||
|
||||
interface Props {
|
||||
address: string;
|
||||
amount?: Wei;
|
||||
}
|
||||
|
||||
// TODO - don't hardcode monero image
|
||||
|
||||
const UserRow = ({ address }: Props) => (
|
||||
const UserRow = ({ address, amount }: Props) => (
|
||||
<Styled.Container>
|
||||
<Styled.Avatar>
|
||||
<Identicon address={address} />
|
||||
|
@ -18,7 +18,9 @@ const UserRow = ({ address }: Props) => (
|
|||
<Styled.InfoMain>
|
||||
<ShortAddress address={address} />
|
||||
</Styled.InfoMain>
|
||||
<Styled.InfoSecondary>{/* user.title */}</Styled.InfoSecondary>
|
||||
{amount && (
|
||||
<Styled.InfoSecondary>{fromWei(amount, 'ether')} ETH</Styled.InfoSecondary>
|
||||
)}
|
||||
</Styled.Info>
|
||||
</Styled.Container>
|
||||
);
|
||||
|
|
|
@ -14,7 +14,7 @@ export interface User {
|
|||
|
||||
export interface Contributor {
|
||||
address: string;
|
||||
contributionAmount: string;
|
||||
contributionAmount: Wei;
|
||||
refundVote: boolean;
|
||||
refunded: boolean;
|
||||
proportionalContribution: string;
|
||||
|
|
|
@ -7,6 +7,7 @@ import { sleep } from 'utils/helpers';
|
|||
import { fetchProposal, fetchProposals } from 'modules/proposals/actions';
|
||||
import { PROPOSAL_CATEGORY } from 'api/constants';
|
||||
import { AppState } from 'store/reducers';
|
||||
import { Wei } from 'utils/units';
|
||||
|
||||
type GetState = () => AppState;
|
||||
|
||||
|
@ -97,10 +98,10 @@ interface MilestoneData {
|
|||
}
|
||||
|
||||
interface ProposalContractData {
|
||||
ethAmount: number | string; // TODO: BigNumber
|
||||
ethAmount: Wei;
|
||||
payOutAddress: string;
|
||||
trusteesAddresses: string[];
|
||||
milestoneAmounts: number[] | string[]; // TODO: BigNumber
|
||||
milestoneAmounts: Wei[];
|
||||
milestones: MilestoneData[];
|
||||
durationInMinutes: number;
|
||||
milestoneVotingPeriodInMinutes: number;
|
||||
|
|
|
@ -5,7 +5,3 @@ export function isNumeric(n: any) {
|
|||
export async function sleep(ms: number) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
export function computePercentage(num: number, percent: number) {
|
||||
return (num / 100) * percent;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ export const Units = {
|
|||
gether: '1000000000000000000000000000',
|
||||
tether: '1000000000000000000000000000000',
|
||||
};
|
||||
const handleValues = (input: string | BN) => {
|
||||
const handleValues = (input: string | BN | number) => {
|
||||
if (typeof input === 'string') {
|
||||
return input.startsWith('0x') ? new BN(stripHexPrefix(input), 16) : new BN(input);
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ const Data = (input: string) => toBuffer(addHexPrefix(input));
|
|||
|
||||
const Nonce = (input: string | BN) => handleValues(input);
|
||||
|
||||
const Wei = (input: string | BN): Wei => handleValues(input);
|
||||
const Wei = (input: string | BN | number): Wei => handleValues(input);
|
||||
|
||||
const TokenValue = (input: string | BN) => handleValues(input);
|
||||
|
||||
|
@ -93,7 +93,13 @@ const fromWei = (wei: Wei, unit: UnitKey) => {
|
|||
return baseToConvertedUnit(wei.toString(), decimal);
|
||||
};
|
||||
|
||||
const toWei = (value: string, decimal: number): Wei => {
|
||||
const toWei = (value: string, unitType: number | UnitKey): Wei => {
|
||||
let decimal;
|
||||
if (typeof unitType === 'number') {
|
||||
decimal = unitType;
|
||||
} else if (typeof unitType === 'string') {
|
||||
decimal = getDecimalFromEtherUnit(unitType);
|
||||
}
|
||||
const wei = convertedToBaseUnit(value, decimal);
|
||||
return Wei(wei);
|
||||
};
|
||||
|
|
|
@ -2,6 +2,7 @@ import Web3 from 'web3';
|
|||
import { CrowdFund, Milestone, MILESTONE_STATE } from 'modules/proposals/reducers';
|
||||
import { collectArrayElements } from 'utils/web3Utils';
|
||||
import { Wei } from 'utils/units';
|
||||
import BN from 'bn.js';
|
||||
|
||||
export async function getCrowdFundState(
|
||||
crowdFundContract: any,
|
||||
|
@ -26,7 +27,10 @@ export async function getCrowdFundState(
|
|||
? 100
|
||||
: balance.divn(100).isZero()
|
||||
? 0
|
||||
: target.div(balance.divn(100)).toNumber();
|
||||
: balance
|
||||
.mul(new BN(100))
|
||||
.divRound(target)
|
||||
.toNumber();
|
||||
const amountVotingForRefund = isRaiseGoalReached
|
||||
? Wei(await crowdFundContract.methods.amountVotingForRefund().call({ from: account }))
|
||||
: Wei('0');
|
||||
|
@ -103,6 +107,11 @@ export async function getCrowdFundState(
|
|||
.call({ form: account }),
|
||||
),
|
||||
);
|
||||
contributor.contributionAmount = Wei(
|
||||
await crowdFundContract.methods
|
||||
.getContributorContributionAmount(addr)
|
||||
.call({ from: account }),
|
||||
);
|
||||
return contributor;
|
||||
}),
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue