Skip to content

Commit

Permalink
Merge pull request #9 from tezocracy/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
avysel authored Nov 3, 2022
2 parents cc8dfc4 + 324ed1a commit f01a5ba
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 40 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Online voting interface for Tezos bakers.

### Made with

- Node.js 16
- React
- Craco
- Typescript
Expand Down
7 changes: 4 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,26 @@ import Sponsors from './components/Sponsors';
import { localForger } from '@taquito/local-forging'
import { useState } from 'react';
import Constants from "./Constants";
import { ProposalsResponseItem } from '@taquito/rpc';

function App() {

let Tezos: TezosToolkit = new TezosToolkit(Config.network.rpcUrl);
Tezos.setForgerProvider(localForger);

const [period, setPeriod] = useState<string>(Constants.Period.NONE);
const [proposal, setProposal] = useState<string | undefined>();
const [proposals, setProposals] = useState<ProposalsResponseItem[]>([]);

return (
<div>
<Header />
<Container className="content">
<Row>
<Col>
<Proposal Tezos={Tezos} setPeriod={setPeriod} setProposal={setProposal}/>
<Proposal Tezos={Tezos} setPeriod={setPeriod} setProposals={setProposals}/>
</Col>
<Col>
<MyBallot Tezos={Tezos} period={period} proposal={proposal}/>
<MyBallot Tezos={Tezos} period={period} proposals={proposals}/>
</Col>
</Row>
<Sponsors />
Expand Down
6 changes: 6 additions & 0 deletions src/Config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ networks.set('ghostnet', {
viewerUrl: "https://ghostnet.tzkt.io"
});

networks.set('k', {
networkType: NetworkType.KATHMANDUNET,
rpcUrl: "https://rpc.kathmandunet.teztnets.xyz/",
viewerUrl: "https://kathmandunet.tzkt.io"
});

let Config = {
application: {
name: "Tezocracy.xyz",
Expand Down
12 changes: 7 additions & 5 deletions src/components/actions/MyBallot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import Constants from "../../Constants";
import Ballot from "./ballot/Ballot";
import Wallet from "../wallet/Wallet";
import UpVote from "./upvote/UpVote";
import { ProposalsResponseItem } from '@taquito/rpc';

function MyBallot({ Tezos, period, proposal }: { Tezos: TezosToolkit, period: string, proposal: string | undefined }) {

function MyBallot({ Tezos, period, proposals }: { Tezos: TezosToolkit, period: string, proposals: ProposalsResponseItem[] }) {

const [userAddress, setUserAddress] = useState<string>("");
const [wallet, setWallet] = useState<any>();
Expand All @@ -21,12 +23,12 @@ function MyBallot({ Tezos, period, proposal }: { Tezos: TezosToolkit, period: st
setIsBallot(period === Constants.Period.PROMOTION || period === Constants.Period.EXPLORATION);
setIsUpvote(period === Constants.Period.PROPOSAL);

console.log(`proposal ${proposal}`);
console.log(`proposal ${proposals}`);
console.log(`isBallot ${isBallot}`);
console.log(`isUpvote ${isUpvote}`);

})();
}, [period, proposal]);
}, [period, proposals]);

return (
<div>
Expand All @@ -44,15 +46,15 @@ function MyBallot({ Tezos, period, proposal }: { Tezos: TezosToolkit, period: st
userAddress && isBallot &&
<div>
<hr />
<Ballot Tezos={Tezos} wallet={wallet} userAddress={userAddress} isDelegate={isDelegate} proposal={proposal} />
<Ballot Tezos={Tezos} wallet={wallet} userAddress={userAddress} isDelegate={isDelegate} proposal={(proposals[0]) ? proposals[0][0]: ""} />
</div>
}

{
userAddress && isUpvote &&
<div>
<hr />
<UpVote Tezos={Tezos} wallet={wallet} userAddress={userAddress} isDelegate={isDelegate} proposal={proposal} />
<UpVote Tezos={Tezos} wallet={wallet} userAddress={userAddress} isDelegate={isDelegate} proposals={proposals} />
</div>
}

Expand Down
9 changes: 5 additions & 4 deletions src/components/actions/ballot/BallotButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ function BallotButtons({ Tezos, wallet, userAddress }: { Tezos: TezosToolkit, wa
const forgeAndSend = async (ballotValue: 'yay' | 'nay' | 'pass'): Promise<string> => {

try {


console.log("1. create operation object");
const operation = await createBallotOperation(ballotValue);

Expand Down Expand Up @@ -124,7 +122,7 @@ function BallotButtons({ Tezos, wallet, userAddress }: { Tezos: TezosToolkit, wa
if (opResult?.status === Constants.APPLIED) {
console.log("Operation applied")
setStatusType('success');
setFeedbackMessage(`Ballot confirmed. <a href="${Config.network.viewerUrl}/${opHash}" target="_blank">Check it.</a>`);
setFeedbackMessage(`Ballot confirmed. <a href="${Config.network.viewerUrl}/${opHash}" target="_blank" class="alert-link">Check it.</a>`);
window.location.reload();
}

Expand All @@ -146,7 +144,10 @@ function BallotButtons({ Tezos, wallet, userAddress }: { Tezos: TezosToolkit, wa

try {
const opHash = await forgeAndSend(ballotValue);
subscribe(opHash);
//subscribe(opHash);
setStatusType('success');
setFeedbackMessage(`Operation sent. <a href="${Config.network.viewerUrl}/${opHash}" target="_blank" class="alert-link">Check it.</a>`);
setWaiting(false);
}
catch (error: any) {
console.log(error);
Expand Down
15 changes: 8 additions & 7 deletions src/components/actions/upvote/UpVote.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@ import { useEffect, useState } from "react";
import { Alert } from "react-bootstrap";
import UpVoteButton from "./UpVoteButton";
import UpVoteResult from "./UpVoteResult";
import { ProposalsResponseItem } from '@taquito/rpc';


function UpVote({ Tezos, wallet, userAddress, isDelegate, proposal }: { Tezos: TezosToolkit, wallet: BeaconWallet, userAddress: string, isDelegate: boolean, proposal: string | undefined }) {
function UpVote({ Tezos, wallet, userAddress, isDelegate, proposals }: { Tezos: TezosToolkit, wallet: BeaconWallet, userAddress: string, isDelegate: boolean, proposals: ProposalsResponseItem[] }) {

const [hasVoted, setHasVoted] = useState<boolean>(false);

useEffect(() => {
(async () => {

// TODO what about has voted?
})();
}, [proposal]);
}, [proposals]);

return (
<>
Expand All @@ -27,19 +28,19 @@ function UpVote({ Tezos, wallet, userAddress, isDelegate, proposal }: { Tezos: T
</div>
}
{
isDelegate && !proposal &&
isDelegate && proposals.length === 0 &&
<div>
<Alert variant="danger">
No proposals submitted for upvote yet.
</Alert>
</div>
}
{
isDelegate && proposal && !hasVoted &&
<UpVoteButton Tezos={Tezos} wallet={wallet} userAddress={userAddress} proposal={proposal} />
isDelegate && proposals.length > 0 && !hasVoted &&
<UpVoteButton Tezos={Tezos} wallet={wallet} userAddress={userAddress} proposals={proposals} />
}
{
isDelegate && proposal && hasVoted &&
isDelegate && proposals.length > 0 && hasVoted &&
<UpVoteResult />
}

Expand Down
43 changes: 35 additions & 8 deletions src/components/actions/upvote/UpVoteButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,38 @@ import bs58check from "bs58check";
import { useState } from "react";
import { Alert, Button, Col, Row, Spinner } from "react-bootstrap";
import Constants from "../../../Constants";
import { OperationObject, PreapplyResponse } from '@taquito/rpc';
import { OperationObject, PreapplyResponse, ProposalsResponseItem } from '@taquito/rpc';
import Parser from 'html-react-parser';
import Config from "../../../Config";

function UpVoteButton({ Tezos, wallet, userAddress, proposal }: { Tezos: TezosToolkit, wallet: BeaconWallet, userAddress: string, proposal: string | undefined }) {
function UpVoteButton({ Tezos, wallet, userAddress, proposals }: { Tezos: TezosToolkit, wallet: BeaconWallet, userAddress: string, proposals: ProposalsResponseItem[] }) {

const [showAlert, setShowAlert] = useState<boolean>(false);
const [statusType, setStatusType] = useState<'success' | 'danger' | 'primary'>();
const [feedbackMessage, setFeedbackMessage] = useState<string>("");
const [waiting, setWaiting] = useState<boolean>(false);
const [selectedProposals, setSelectedProposals] = useState<string[]>([]);

const createUpvoteOperation = async (): Promise<any> => {

if (proposal === undefined) {
if (proposals === undefined || proposals.length === 0) {
throw new Error("No proposals submitted yet");
}

const branch: string = await Tezos.rpc.getBlockHash();
const period: number = (await Tezos.rpc.getCurrentPeriod()).voting_period.index;

console.log("Upvote for ");
console.log(selectedProposals);

const operation = {
"branch": branch,
"contents": [
{
"kind": OpKind.PROPOSALS,
"source": userAddress,
"period": period,
"proposals": [proposal]
"proposals": selectedProposals
}
]
};
Expand Down Expand Up @@ -120,7 +124,7 @@ function UpVoteButton({ Tezos, wallet, userAddress, proposal }: { Tezos: TezosTo
if (opResult?.status === Constants.APPLIED) {
console.log("Operation applied")
setStatusType('success');
setFeedbackMessage(`Upvote confirmed. <a href="${Config.network.viewerUrl}/${opHash}" target="_blank">Check it.</a>`);
setFeedbackMessage(`Upvote confirmed. <a href="${Config.network.viewerUrl}/${opHash}" target="_blank" class="alert-link">Check it.</a>`);
window.location.reload();
}

Expand All @@ -142,7 +146,10 @@ function UpVoteButton({ Tezos, wallet, userAddress, proposal }: { Tezos: TezosTo

try {
const opHash = await forgeAndSend();
subscribe(opHash);
//subscribe(opHash);
setStatusType('success');
setFeedbackMessage(`Operation sent. <a href="${Config.network.viewerUrl}/${opHash}" target="_blank" class="alert-link">Check it.</a>`);
setWaiting(false);
}
catch (error: any) {
console.log(error);
Expand All @@ -154,15 +161,35 @@ function UpVoteButton({ Tezos, wallet, userAddress, proposal }: { Tezos: TezosTo
}
}


const upVote = async (): Promise<void> => {
sendUpVoteOperation();
};

const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { value, checked } = e.target;
if (checked) {
setSelectedProposals(prev => [...prev, value]);
} else {
setSelectedProposals(prev => prev.filter(x => x !== value));
}
}

return (
<>
<div className="ballot-buttons">
<div className="text-muted ballot-buttons-subtitle">Click on the button to upvote for the proposal:</div>
<div className="text-muted ballot-buttons-subtitle">Select proposals you want to upvote and click on the button to send your vote.</div>

<div className="ballot-buttons-subtitle">
{proposals.map((item, i) => <div key={i}>
<input
type="checkbox"
name="lang"
value={item[0]}
onChange={handleChange}
/> {item[0]}

</div>)}
</div>
<div className="ballot-buttons-group">
<Button className="ballot-button" variant="success" onClick={upVote} disabled={waiting}>Upvote</Button>
</div>
Expand Down
50 changes: 39 additions & 11 deletions src/components/proposal/Proposal.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { TezosToolkit } from "@taquito/taquito";
import { Dispatch, SetStateAction, useEffect, useState } from "react";
import { Card } from "react-bootstrap";
import ProposalStat from "./ProposalStat";
import ProposalBallotStat from "./ProposalBallotStat";
import Constants from "../../Constants";
import { ProposalsResponseItem } from '@taquito/rpc';
import BigNumber from 'bignumber.js';
import React from "react";
import ProposalUpvoteStat from "./ProposalUpvoteStat";

function Proposal({ Tezos, setPeriod, setProposal }: { Tezos: TezosToolkit, setPeriod: Dispatch<SetStateAction<string>>, setProposal: Dispatch<SetStateAction<string | undefined>> }) {
function Proposal({ Tezos, setPeriod, setProposals }: { Tezos: TezosToolkit, setPeriod: Dispatch<SetStateAction<string>>, setProposals: Dispatch<SetStateAction<ProposalsResponseItem[]>> }) {

const [proposalHash, setProposalHash] = useState<any>("");
const [proposals, setInternalProposals] = useState<ProposalsResponseItem[]>([]);
const [remaining, setRemaining] = useState<number | string>(0);
const [periodKind, setPeriodKind] = useState<string>("");

Expand All @@ -16,7 +20,8 @@ function Proposal({ Tezos, setPeriod, setProposal }: { Tezos: TezosToolkit, setP
Tezos.rpc.getCurrentPeriod()
.then((period) => {
console.log(`Current period: ${JSON.stringify(period)}`)
const kind = period.voting_period.kind
let kind = period.voting_period.kind;

setRemaining(period.remaining);
setPeriodKind(kind);
setPeriod(kind);
Expand All @@ -30,8 +35,8 @@ function Proposal({ Tezos, setPeriod, setProposal }: { Tezos: TezosToolkit, setP
.then((proposals) => {
console.log(proposals);
if (proposals && proposals[0]) {
setProposalHash(proposals[0][0]);
setProposal(proposals[0][0]);
setProposals(proposals);
setInternalProposals(proposals);
}
});

Expand All @@ -44,11 +49,14 @@ function Proposal({ Tezos, setPeriod, setProposal }: { Tezos: TezosToolkit, setP
Tezos.rpc.getCurrentProposal()
.then((hash) => {
const proposalHash: string = hash?.toString() || "";
setProposalHash(proposalHash);
setProposal(proposalHash);
const proposalsListOfOne: ProposalsResponseItem[] = [
[proposalHash, BigNumber(0)]
];
setProposals(proposalsListOfOne);
setInternalProposals(proposalsListOfOne);
console.log(`proposal hash ${proposalHash}`)
})
.catch((error) => { console.error(error); setProposalHash("error") });
.catch((error) => { console.error(error); /*setProposalHash("error")*/ });

break;
default:
Expand All @@ -68,12 +76,32 @@ function Proposal({ Tezos, setPeriod, setProposal }: { Tezos: TezosToolkit, setP
<Card.Body>
<div>
<h4>Proposal</h4>
<div className="list-item"><div className="item-name">Prococol:</div><div className="item-value">{proposalHash}</div></div>
<div className="list-item"><div className="item-name">Period:</div><div className="item-value">{periodKind}</div></div>
<div className="list-item"><div className="item-name">Remaining:</div><div className="item-value">{remaining}</div></div>

{
(periodKind === Constants.Period.EXPLORATION || periodKind === Constants.Period.PROMOTION) &&

<div className="list-item">
<div className="item-name">Protocol:</div>
{proposals.map((item: ProposalsResponseItem, index) => (
<React.Fragment key={index}>
<div className="item-value">{item[0]}</div>
</React.Fragment>
))}
</div>
}
</div>
<hr />
<div>
<ProposalStat Tezos={Tezos} />
{
periodKind === Constants.Period.PROPOSAL &&
<ProposalUpvoteStat Tezos={Tezos} proposals={proposals} />
}
{
(periodKind === Constants.Period.EXPLORATION || periodKind === Constants.Period.PROMOTION) &&
<ProposalBallotStat Tezos={Tezos} />
}
</div>
</Card.Body>
</Card>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { TezosToolkit } from "@taquito/taquito";
import { useEffect, useState } from "react";
import { ProgressBar } from "react-bootstrap";

function ProposalStat({ Tezos }: { Tezos: TezosToolkit }) {
function ProposalBallotStat({ Tezos }: { Tezos: TezosToolkit }) {

const [yayPct, setYayPct] = useState<number>(0);
const [nayPct, setNayPct] = useState<number>(0);
Expand Down Expand Up @@ -46,4 +46,4 @@ function ProposalStat({ Tezos }: { Tezos: TezosToolkit }) {
);
}

export default ProposalStat;
export default ProposalBallotStat;
Loading

0 comments on commit f01a5ba

Please sign in to comment.