mirror of
https://github.com/status-im/snt-voting.git
synced 2025-02-23 23:58:13 +00:00
Added landing page and lazy loading of IPFS text
This commit is contained in:
parent
f7b1b0084e
commit
0aba085ed7
@ -18,6 +18,7 @@ import VotingCredits from './flow/VotingCredits';
|
||||
import PollVoting from './flow/PollVoting';
|
||||
import ReviewVotes from './flow/ReviewVotes';
|
||||
import Results from './flow/Results';
|
||||
import LandingPage from './flow/LandingPage';
|
||||
import { withRouter } from 'react-router-dom'
|
||||
|
||||
|
||||
@ -54,13 +55,14 @@ class Voting extends PureComponent {
|
||||
|
||||
return (
|
||||
<VotingContext.Consumer>
|
||||
{({ getPolls, rawPolls, loading, symbol }) =>
|
||||
{({ getPolls, rawPolls, loading, symbol, replacePoll, loadPollContent }) =>
|
||||
<div>
|
||||
<CssBaseline />
|
||||
{loading && <LinearProgress />}
|
||||
<div id="votingDapp">
|
||||
<Switch>
|
||||
<Route exact path="/" render={props => <TitleScreen polls={rawPolls} />} />
|
||||
<Route exact path="/" render={props => <LandingPage polls={rawPolls} replacePoll={replacePoll} />} />
|
||||
<Route path="/titleScreen/:id" render={props => <TitleScreen polls={rawPolls} idPoll={props.match.params.id} loadPollContent={loadPollContent} />} />
|
||||
<Route path="/learn/:id" render={props => <LearnAboutBallots polls={rawPolls} idPoll={props.match.params.id} />} />
|
||||
<Route path="/votingHelp/:id" render={props => <HowVotingWorks idPoll={props.match.params.id} polls={rawPolls} updateBalances={this.updatePollBalance} />} />
|
||||
<Route path="/wallet/:id" render={props => <ConnectYourWallet polls={rawPolls} idPoll={props.match.params.id} updateBalances={this.updatePollBalance} />} />
|
||||
|
@ -19,7 +19,7 @@ class ExternalWallet extends Component {
|
||||
const {history, polls, updateBalances, idPoll} = this.props;
|
||||
if(!polls) return;
|
||||
|
||||
const poll = polls[idPoll];
|
||||
const poll = polls.find(p => p.idPoll == idPoll);
|
||||
if(!poll) return null;
|
||||
|
||||
|
||||
|
@ -52,7 +52,7 @@ class HowVotingWorks extends Component {
|
||||
|
||||
if(cont){
|
||||
// TODO: extract this code to utils. It's repeated in ConnectYourWallt, ExternalWallet and HowVotingWorks
|
||||
const poll = polls[idPoll];
|
||||
const poll = polls.find(p => p.idPoll == idPoll);
|
||||
if(!poll) return null;
|
||||
|
||||
const tknVotes = await PollManager.methods.getVote(idPoll, web3.eth.defaultAccount).call({from: web3.eth.defaultAccount});
|
||||
|
89
app/components/flow/LandingPage.js
Normal file
89
app/components/flow/LandingPage.js
Normal file
@ -0,0 +1,89 @@
|
||||
import Button from '@material-ui/core/Button';
|
||||
import React, {Component, Fragment} from 'react';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { withRouter } from 'react-router-dom'
|
||||
import {Link} from "react-router-dom";
|
||||
|
||||
class LandingPage extends Component {
|
||||
|
||||
state = {
|
||||
openPoll: null,
|
||||
closedPoll: null
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (this.props.polls !== prevProps.polls) {
|
||||
|
||||
let polls = this.props.polls;
|
||||
if(polls && polls.length){
|
||||
polls = polls.sort((x,y) => x.idPoll < y.idPoll);
|
||||
}
|
||||
|
||||
if(polls && polls.length){
|
||||
const openPoll = polls.find(x => !x._cancelled && x._endTime > (new Date()).getTime() / 1000);
|
||||
EmbarkJS.Storage.get(web3.utils.toAscii(openPoll._description)).then(content => {
|
||||
openPoll.content = JSON.parse(content);
|
||||
this.setState({openPoll})
|
||||
|
||||
this.props.replacePoll(openPoll);
|
||||
})
|
||||
const closedPoll = polls.find(x => !x._cancelled || x._endTime < (new Date()).getTime() / 1000);
|
||||
EmbarkJS.Storage.get(web3.utils.toAscii(closedPoll._description)).then(content => {
|
||||
closedPoll.content = JSON.parse(content);
|
||||
this.setState({closedPoll});
|
||||
this.props.replacePoll(openPoll);
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
render(){
|
||||
const { openPoll, closedPoll } = this.state;
|
||||
|
||||
return <Fragment>
|
||||
<div>
|
||||
<div className="section" style={{marginBottom: 0}}>
|
||||
<img src="images/status-logo.svg" width="36" />
|
||||
<Typography variant="headline">Status SNT Voting</Typography>
|
||||
<Typography variant="body1" component="div">Create a poll or vote in one. Your vote helps us decide our product and community direction.</Typography>
|
||||
</div>
|
||||
|
||||
{ openPoll && openPoll.content &&
|
||||
<div>
|
||||
<h2>Open Polls</h2>
|
||||
<div>
|
||||
<h3>{openPoll.content.title}</h3>
|
||||
[Closes: 12/12/2018]
|
||||
Voters: 300
|
||||
Total SNT: 50.000
|
||||
{openPoll._description}
|
||||
<Link to={"/titleScreen/" + openPoll.idPoll}><Button variant="contained" color="primary">Vote now</Button></Link>
|
||||
</div>
|
||||
<p>More Open Polls</p>
|
||||
</div>
|
||||
}
|
||||
|
||||
{ closedPoll && closedPoll.content &&
|
||||
<div>
|
||||
<h2>Closed Polls</h2>
|
||||
<div>
|
||||
<h3>{closedPoll.content.title}</h3>
|
||||
[Closes: 12/12/2018]
|
||||
Voters: 300
|
||||
Total SNT: 50.000
|
||||
{closedPoll._description}
|
||||
Vote Now
|
||||
</div>
|
||||
<p>More Closed Polls</p>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</Fragment>;
|
||||
}
|
||||
}
|
||||
|
||||
export default LandingPage;
|
@ -34,7 +34,7 @@ class LearnAboutBallots extends Component {
|
||||
|
||||
if(!polls) return null;
|
||||
|
||||
const poll = polls[idPoll];
|
||||
const poll = polls.find(p => p.idPoll == idPoll);
|
||||
if(!poll) return null;
|
||||
|
||||
const title = poll.content.title;
|
||||
|
@ -54,7 +54,9 @@ class OtherWallets extends Component {
|
||||
if(!props.polls){
|
||||
return null;
|
||||
}
|
||||
const poll = props.polls[props.idPoll];
|
||||
|
||||
|
||||
const poll = props.polls.find(p => p.idPoll == props.idPoll);
|
||||
if(!poll) return null;
|
||||
|
||||
d = new Date(poll.blockInfo.timestamp * 1000);
|
||||
|
@ -59,7 +59,7 @@ class PollVoting extends Component {
|
||||
return;
|
||||
}
|
||||
|
||||
const poll = polls[idPoll];
|
||||
const poll = polls.find(p => p.idPoll == idPoll);
|
||||
if(!poll){
|
||||
history.push('/');
|
||||
return;
|
||||
@ -112,7 +112,7 @@ class PollVoting extends Component {
|
||||
|
||||
const symbol = "SNT"; // TODO:
|
||||
|
||||
const poll = polls[idPoll];
|
||||
const poll = polls.find(p => p.idPoll == idPoll);
|
||||
if(!poll) return null;
|
||||
|
||||
const title = poll.content.title;
|
||||
|
@ -18,7 +18,7 @@ class Results extends Component {
|
||||
super(props);
|
||||
|
||||
if(props.polls)
|
||||
this.state.poll = props.polls[props.idPoll];
|
||||
this.state.poll = props.polls.find(p => p.idPoll == props.idPoll);
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps){
|
||||
@ -84,8 +84,10 @@ class Results extends Component {
|
||||
return null;
|
||||
}
|
||||
|
||||
const title = polls[idPoll].content.title;
|
||||
const ballots = polls[idPoll].content.ballots;
|
||||
const p = polls.find(p => p.idPoll == idPoll);
|
||||
|
||||
const title = p.content.title;
|
||||
const ballots = p.content.ballots;
|
||||
const totalVotes = poll._quadraticVotes.map(x => parseInt(x, 10)).reduce((x, y) => x + y, 0);
|
||||
const etherscanURL = netId == 3 ? 'https://ropsten.etherscan.io/tx/' : ( netId == 1 ? "https://etherscan.io/tx/" : '');
|
||||
|
||||
|
@ -66,7 +66,7 @@ class ReviewVotes extends Component {
|
||||
return;
|
||||
}
|
||||
|
||||
const poll = polls[idPoll];
|
||||
const poll = polls.find(p => p.idPoll == idPoll);
|
||||
if(!poll) {
|
||||
history.push('/');
|
||||
return;
|
||||
@ -82,7 +82,7 @@ class ReviewVotes extends Component {
|
||||
return null;
|
||||
}
|
||||
|
||||
const poll = polls[idPoll];
|
||||
const poll = polls.find(p => p.idPoll == idPoll);;
|
||||
if(!poll) return null;
|
||||
|
||||
const ballots = poll.content.ballots
|
||||
|
@ -65,20 +65,24 @@ class TitleScreen extends Component {
|
||||
componentDidUpdate(prevProps){
|
||||
if (this.props.polls !== prevProps.polls && this.props.polls) {
|
||||
this.initTimer();
|
||||
|
||||
const poll = this.props.polls.find(p => p.idPoll == this.props.idPoll);
|
||||
if(poll && !poll.content){
|
||||
this.props.loadPollContent(poll);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
initTimer(){
|
||||
const ids = Object.keys(this.props.polls);
|
||||
if(!ids.length) return;
|
||||
if(!this.props.polls || !this.props.polls.length) return;
|
||||
|
||||
if(this.state.initTimer) return;
|
||||
|
||||
this.setState({initTimer: true});
|
||||
|
||||
const idPoll = ids[ids.length - 1];
|
||||
const poll = this.props.polls.find(p => p.idPoll == this.props.idPoll);
|
||||
|
||||
const seconds = this.props.polls[idPoll]._endTime - (new Date()).getTime() / 1000
|
||||
const seconds = poll._endTime - (new Date()).getTime() / 1000
|
||||
if(seconds > 0){
|
||||
let timeLeftVar = this.secondsToTime(seconds);
|
||||
this.setState({ time: timeLeftVar, seconds });
|
||||
@ -90,19 +94,19 @@ class TitleScreen extends Component {
|
||||
|
||||
render(){
|
||||
const {time, seconds} = this.state;
|
||||
const {polls} = this.props;
|
||||
const {polls, idPoll} = this.props;
|
||||
|
||||
if(!polls) return null;
|
||||
|
||||
const ids = Object.keys(this.props.polls);
|
||||
if(!ids.length) return null;
|
||||
if(!polls || !polls.length) return null;
|
||||
|
||||
const idPoll = ids[ids.length - 1];
|
||||
const poll = polls[idPoll];
|
||||
const poll = polls.find(p => p.idPoll == idPoll);
|
||||
if(!poll) return null;
|
||||
|
||||
if(!poll.content) return null;
|
||||
|
||||
const title = poll.content.title;
|
||||
const description = poll.content.description;
|
||||
const canceled = poll._canceled;
|
||||
|
||||
|
||||
return <Fragment>
|
||||
<div>
|
||||
|
@ -54,7 +54,7 @@ class VotingCredits extends Component {
|
||||
|
||||
if(!polls || !balances) return null;
|
||||
|
||||
const poll = polls[idPoll];
|
||||
const poll = polls.find(p => p.idPoll == idPoll);
|
||||
if(!poll) return null;
|
||||
|
||||
let title = poll.content.title;
|
||||
|
32
app/dapp.js
32
app/dapp.js
@ -32,7 +32,7 @@ class App extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
state = { admin: false, pollOrder: 'NEWEST_ADDED', web3Provider: true, loading: true, symbol: "SNT", networkName: "" };
|
||||
state = { admin: false, pollOrder: 'NEWEST_ADDED', web3Provider: true, loading: true, symbol: "SNT", networkName: "" , rawPolls: []};
|
||||
|
||||
componentDidMount(){
|
||||
EmbarkJS.onReady((err) => {
|
||||
@ -91,7 +91,10 @@ class App extends React.Component {
|
||||
getPolls(polls, poll)
|
||||
.then(omitPolls)
|
||||
.then(rawPolls => {
|
||||
this._loadIPFSContent(rawPolls);
|
||||
|
||||
|
||||
// this._loadIPFSContent(rawPolls);
|
||||
this.setState({rawPolls, loading: false});
|
||||
});
|
||||
else
|
||||
this.setState({ rawPolls: [], loading: false });
|
||||
@ -134,10 +137,31 @@ class App extends React.Component {
|
||||
</Fragment>;
|
||||
}
|
||||
|
||||
|
||||
replacePoll = (poll) => {
|
||||
let rawPolls = this.state.rawPolls;
|
||||
for(let i = 0; i < rawPolls.length; i++){
|
||||
if(rawPolls[i].idPoll == poll.idPoll){
|
||||
rawPolls[i] = poll;
|
||||
this.setState({rawPolls});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loadPollContent = async (poll) => {
|
||||
let ipfsContent = await EmbarkJS.Storage.get(web3.utils.toAscii(poll._description));
|
||||
poll.content = JSON.parse(ipfsContent);
|
||||
this.replacePoll(poll);
|
||||
}
|
||||
|
||||
render(){
|
||||
let { web3Provider, networkName } = this.state;
|
||||
const { _getPolls, updatePoll, setPollOrder, appendToPoll } = this;
|
||||
const votingContext = { getPolls: _getPolls, updatePoll, appendToPoll, setPollOrder, ...this.state };
|
||||
const { _getPolls, updatePoll, setPollOrder, appendToPoll, replacePoll, loadPollContent } = this;
|
||||
const votingContext = { getPolls: _getPolls, updatePoll, appendToPoll, setPollOrder, replacePoll, loadPollContent, ...this.state };
|
||||
|
||||
|
||||
console.log(this.state.rawPolls);
|
||||
|
||||
if(web3Provider){
|
||||
return <Router>
|
||||
|
Loading…
x
Reference in New Issue
Block a user