Allow the creation of a multiple options poll

This commit is contained in:
Richard Ramos 2018-09-25 15:24:34 -04:00
parent d4fcd9f5f2
commit 4f9df0119e
4 changed files with 67 additions and 24 deletions

View File

@ -1,10 +1,10 @@
import React, { Fragment } from 'react';
import Card from '@material-ui/core/Card';
import CardActions from '@material-ui/core/CardActions';
import CardContent from '@material-ui/core/CardContent';
import PollManager from 'Embark/contracts/PollManager';
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button';
import rlp from 'rlp';
import CircularProgress from '@material-ui/core/CircularProgress';
import { withStyles } from '@material-ui/core/styles';
import { withFormik } from 'formik';
@ -51,14 +51,14 @@ const InnerForm = ({
<CardContent>
<form onSubmit={handleSubmit} className={classes.form}>
<TextField
id="description"
label="Enter your proposal description"
id="title"
label="Enter your proposal title"
className={classes.textField}
value={values.description}
value={values.title}
onChange={handleChange}
margin="normal"
fullWidth
error={!!errors.description}
error={!!errors.title}
InputProps={{
classes: {
input: classes.textFieldInput
@ -67,8 +67,30 @@ const InnerForm = ({
InputLabelProps={{
className: classes.textFieldFormLabel
}}
helperText={errors.description}
helperText={errors.title}
/>
<TextField
id="ballots"
label="Enter the proposal options, separated by '|' (optional)"
className={classes.textField}
value={values.ballots}
onChange={handleChange}
margin="normal"
fullWidth
error={!!errors.ballots}
InputProps={{
classes: {
input: classes.textFieldInput
},
}}
InputLabelProps={{
className: classes.textFieldFormLabel
}}
helperText={errors.ballots}
/>
{!isSubmitting ?
<Button type="submit" variant="extendedFab" aria-label="add" className={classes.button}>Submit</Button> :
<CircularProgress style={{ margin: '10px 10px 10px 50%' }} />
@ -80,20 +102,31 @@ const InnerForm = ({
const StyledForm = withStyles(styles)(InnerForm);
const AddPoll = withFormik({
mapPropsToValues: props => ({ description: ''}),
mapPropsToValues: props => ({ title: '', ballots: ''}),
validate(values, props){
const errors = {};
const { description } = values;
if(description.toString().trim() === "") errors.description = true;
const { title, ballots } = values;
const ballotOptions = ballots.toString().split("|")
if(title.toString().trim() === "") {
errors.title = "Required";
}
if(ballotOptions.filter(n => n).length == 1) {
errors.ballots = "A minimum of 2 options is required if using multiple options";
}
return errors;
},
async handleSubmit(values, { setSubmitting, setErrors, props }) {
const { description } = values;
const { title, ballots } = values;
const { eth: { getBlockNumber } } = window.web3;
const { addPoll } = PollManager.methods;
const addPoll = PollManager.methods["addPoll(uint256,bytes,uint8)"];
const currentBlock = await getBlockNumber();
const endTime = currentBlock + (oneDayinBlocks * 90);
const toSend = addPoll(endTime, description);
const options = ballots.split("|");
const encodedDesc = "0x" + rlp.encode([title, options]).toString('hex');
const toSend = addPoll(endTime, encodedDesc, options.length || 0);
setSubmitting(true);

View File

@ -17,6 +17,7 @@ import web3 from "Embark/web3"
import CircularProgress from '@material-ui/core/CircularProgress';
import { withStyles } from '@material-ui/core/styles';
import { VotingContext } from '../../context';
import rlp from 'rlp';
const styles = {
card: {
@ -111,23 +112,32 @@ class Poll extends PureComponent {
_canVote,
balance,
classes,
ideaSites
ideaSites,
_numBallots,
} = this.props;
const { value, originalValue, isSubmitting, error } = this.state;
const cantVote = balance == 0 || !_canVote;
const disableVote = cantVote || isSubmitting;
const { fromWei } = web3.utils;
const fromWei = (m) => m;
const maxValue = Math.floor(Math.sqrt(balance));
const buttonText = originalValue != 0 && value != originalValue ? 'Change Vote' : 'Vote';
const idea = getIdeaFromStr(_description)
const ideaSite = ideaSites && ideaSites.filter(site => site.includes(idea));
const decodedDesc = rlp.decode(_description);
const title = decodedDesc[0].toString();
const ballots = decodedDesc[1];
return (
<Card>
<CardContent>
<Typography variant="headline">{_description}</Typography>
<Typography variant="headline">{title}</Typography>
<Typography variant="subheading" color="textSecondary">
<b>Total:</b> {_voters} voters. {_qvResults} votes ({fromWei(_results)} SNT)
</Typography>
{ _numBallots > 0 && ballots.map((opt, i) => <p key={i}>{opt.toString()}</p>) }
<Typography variant="subheading" color="textSecondary">
<b>Your vote:</b> {value} votes ({value * value} SNT)
</Typography>
@ -184,7 +194,7 @@ const PollsList = ({ classes }) => (
<Fragment>
{rawPolls
.sort(sortingFn[pollOrder])
.map((poll) => <Poll key={poll._token} classes={classes} appendToPoll={appendToPoll} updatePoll={updatePoll} ideaSites={ideaSites} {...poll} />)}
.map((poll) => <Poll key={poll.idPoll} classes={classes} appendToPoll={appendToPoll} updatePoll={updatePoll} ideaSites={ideaSites} {...poll} />)}
</Fragment>
}
</VotingContext.Consumer>

View File

@ -1,6 +1,7 @@
import web3 from "Embark/web3"
import MiniMeTokenInterface from 'Embark/contracts/MiniMeTokenInterface';
import PollManager from 'Embark/contracts/PollManager';
import SNT from 'Embark/contracts/SNT';
const excluded = {
PROPER_LIGHT_CLIENT_SUPPORT : 3,
@ -8,14 +9,12 @@ const excluded = {
SHIP_1_0 : 16
};
export const getBalance = async (idPoll, token, startBlock) => {
export const getBalance = async (startBlock) => {
const { fromWei } = web3.utils;
const { balanceOfAt } = MiniMeTokenInterface.methods;
MiniMeTokenInterface.options.address = token;
const { balanceOfAt } = SNT.methods;
const balance = await balanceOfAt(web3.eth.defaultAccount, startBlock - 1).call();
return fromWei(balance);
}
export const getVote = async(idPoll) => {
const { fromWei } = web3.utils;
const votes = await PollManager.methods.getVote(idPoll, web3.eth.defaultAccount).call();
@ -24,9 +23,10 @@ export const getVote = async(idPoll) => {
const fetchPollData = async (index, pollMethod) => {
const poll = await pollMethod(index).call();
const balance = await getBalance(index, poll._token, poll._startBlock);
const votes = await getVote(index);
return { ...poll, idPoll: index, balance, votes };
const balance = await getBalance(poll._startBlock);
//const votes = await getVote(index);
return { ...poll, idPoll: index, balance, votes: "0" };
}
export const getPolls = (number, pollMethod) => {

View File

@ -44,7 +44,7 @@
]
},
"PollManager": {
"args": ["$MiniMeTokenFactory", "$SNT"]
"args": ["$SNT"]
}
}
},