mirror of
https://github.com/status-im/snt-voting.git
synced 2025-02-23 07:38:07 +00:00
Allow the creation of a multiple options poll
This commit is contained in:
parent
d4fcd9f5f2
commit
4f9df0119e
@ -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);
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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) => {
|
||||
|
@ -44,7 +44,7 @@
|
||||
]
|
||||
},
|
||||
"PollManager": {
|
||||
"args": ["$MiniMeTokenFactory", "$SNT"]
|
||||
"args": ["$SNT"]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user