fix: Voting power will be captured on contract and shown on UI. Minor UI changes are done.

This commit is contained in:
Raja Ilayaperumal
2022-09-09 16:48:21 +05:30
parent 1e859eef45
commit 6ac8feecdb
9 changed files with 119 additions and 114 deletions

View File

@@ -1,13 +1,13 @@
import { nanoid } from 'nanoid';
import Router from 'next/router';
import { useEffect, useState } from "react";
import { Button, Col, Container, Form, Row } from "react-bootstrap";
import { Button, Form } from "react-bootstrap";
import { v4 as uuidv4 } from "uuid";
import { deployContract } from "../../services/contract"
import { getRecentBlock } from "../../services/utils";
import { getFileFromGaia, getMyStxAddress, getUserData, putFileToGaia } from "../../services/auth.js";
import { deployContract } from "../../services/contract";
import { getRecentBlock } from "../../services/utils";
import styles from "../../styles/Builder.module.css";
import PreviewComponent from "./Preview.component";
import { nanoid } from 'nanoid'
export default function BuilderComponent(props) {
// Variables

View File

@@ -35,28 +35,6 @@ export function DashboardNavBarComponent() {
setDisplayUsername(_username);
}
const loadBlockSurveyWidgetScript = () => {
// If script is not loaded, load first
if (!window.blocksurvey) {
let body = document.body;
let script = document.createElement("script");
script.innerHTML = "";
script.src = "https://blocksurvey.io/assets/js/blocksurvey-widget.js";
script.async = true;
script.defer = true;
script.onload = () => {
window.blocksurvey = {
loaded: true,
};
feedbackButton.current.click();
};
body.appendChild(script);
} else {
feedbackButton.current.click();
}
};
// UI
return (
<>
@@ -72,11 +50,11 @@ export function DashboardNavBarComponent() {
isUserSignedIn ?
<div style={{ display: "flex", gap: "26px", alignItems: "center" }}>
<div style={{ margin: "10px 0" }}>
<Link href="/builder/new">
<a href="/builder/new">
<Button variant="secondary">
+ New Poll
</Button>
</Link>
</a>
</div>
<div className="d-none d-md-block" style={{ margin: "10px 0" }}>
@@ -112,9 +90,8 @@ export function DashboardNavBarComponent() {
</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item
onClick={() => {
loadBlockSurveyWidgetScript();
}}>
href="https://github.com/BlockSurvey/ballot/issues"
target="_blank">
Share feedback
</Dropdown.Item>
<Dropdown.Item eventKey="1" onClick={() => { signOut() }}>Logout</Dropdown.Item>
@@ -136,26 +113,6 @@ export function DashboardNavBarComponent() {
handleCloseMyVotesPopup={handleCloseMyVotesPopup}
handleShowMyVotesPopup={handleShowMyVotesPopup}
/>
{/* Adding BlockSurvey script */}
<blocksurvey-widget
origin="blocksurvey.io"
uid="t"
sid="c4fc8c45-cc9f-4f8d-94eb-0dcc98ad716d"
mode="popupcard"
alignpopup="center"
popupsize="large"
background="rgb(0, 0, 0)"
color="rgb(255, 255, 255)"
params=""
></blocksurvey-widget>
<button
style={{ display: "none" }}
className="blocksurvey-share"
ref={feedbackButton}
>
Launch me
</button>
</>
);
}

View File

@@ -43,7 +43,10 @@ export default function HeaderComponent(props) {
<div style={{ display: "flex", alignItems: "center", columnGap: "20px", fontSize: "14px", marginBottom: "30px" }}>
{/* Status */}
<div>
{pollObject?.status == "draft" ? "Draft" : "Active"} {' '}
{pollObject?.status == "draft" ? "Draft" :
((pollObject?.endAtDate && (new Date(pollObject?.endAtDate) < new Date())) ?
(<span style={{ color: "#ff4d4d" }}>Closed</span>) : "Active")}
{' '}
</div>
{/* Created by */}

View File

@@ -1,3 +1,4 @@
import { Table } from "react-bootstrap";
import { Constants } from "../../common/constants";
import { convertToDisplayDateFormat, formStacksExplorerUrl } from "../../services/utils";
@@ -116,14 +117,26 @@ export default function InformationComponent(props) {
<h6>Current results</h6>
<div style={{ marginTop: "10px" }}>
<Table striped bordered>
<tbody>
{pollObject?.options?.map((option, index) => (
<div key={index}>
<tr key={index}>
<td style={{ width: "70%" }}>
{option?.value}
</td>
<td>
<span style={{ float: "right", fontWeight: "bold", textTransform: "capitalize" }}>
{resultsByOption && resultsByOption[option.id] ? resultsByOption[option.id] : "-"}
{resultsByOption && resultsByOption[option.id] ?
<>
{resultsByOption[option.id]["percentage"]}% ({resultsByOption[option.id]["total"]})
</>
: "-"}
</span>
</div>
</td>
</tr>
))}
</tbody>
</Table>
</div>
</div>
</>

View File

@@ -125,7 +125,7 @@ export default function MyVotePopup(props) {
) : // Once data found
votes && votes.length > 0 ? (
<div style={{ padding: "0px 20px 10px", fontSize: "14px" }}>
<Table striped bordered hover>
<Table striped bordered>
<thead>
<tr>
<th>Title</th>

View File

@@ -1,9 +1,9 @@
import { useEffect, useState } from "react";
import { Col, Container, Row, Button } from "react-bootstrap";
import styles from "../../styles/Dashboard.module.css";
import { deleteFileToGaia, getFileFromGaia, getUserData, putFileToGaia } from "../../services/auth.js"
import Link from "next/link";
import { useEffect, useState } from "react";
import { Button } from "react-bootstrap";
import { deleteFileToGaia, getFileFromGaia, getUserData, putFileToGaia } from "../../services/auth.js";
import { convertToDisplayDateFormat } from "../../services/utils";
import styles from "../../styles/Dashboard.module.css";
export default function DashboardAllPollsComponent() {
// Variables
@@ -66,7 +66,11 @@ export default function DashboardAllPollsComponent() {
<div style={{ fontSize: "14px", color: "#737373" }}>
<span>
Status : {pollIndexObject?.status == "draft" ? "Draft" : "Active"}
Status : {
pollIndexObject?.status == "draft" ? "Draft" :
((pollIndexObject?.endAt && (new Date(pollIndexObject?.endAt) < new Date())) ?
(<span style={{ color: "#ff4d4d" }}>Closed</span>) : "Active")
}
</span>
{', '}
<span>

View File

@@ -38,8 +38,8 @@ export default function PollComponent(props) {
const handleShow = () => setShow(true);
const handleClose = () => setShow(false);
// Loading
const [isLoading, setIsLoading] = useState(false);
// Processing
const [isProcessing, setIsProcessing] = useState(false);
// Functions
useEffect(() => {
@@ -127,7 +127,7 @@ export default function PollComponent(props) {
const castMyVote = () => {
if (pollObject?.publishedInfo?.contractAddress && pollObject?.publishedInfo?.contractName) {
// Start processing
setIsLoading(true);
setIsProcessing(true);
const contractAddress = pollObject?.publishedInfo?.contractAddress;
const contractName = pollObject?.publishedInfo?.contractName;
@@ -183,7 +183,8 @@ export default function PollComponent(props) {
{/* Vote button */}
{isUserSignedIn ?
<Button variant="dark" style={{ marginTop: "30px" }}
disabled={(isPreview || !holdingTokenArr || alreadyVoted) ? true : false}
disabled={(isPreview || !holdingTokenArr || alreadyVoted || isProcessing ||
(pollObject?.endAtDate && (new Date(pollObject?.endAtDate) < new Date()))) ? true : false}
onClick={() => { castMyVote() }}>
Vote
</Button>
@@ -219,17 +220,19 @@ export default function PollComponent(props) {
{/* Results */}
<div style={{ marginTop: "20px" }}>
<h5>Votes ({total})</h5>
<Table striped bordered hover>
<h5>Votes {total >= 0 ? <>({total})</> : ""}</h5>
<Table striped bordered>
<thead>
<tr>
<th>Address</th>
<th>Option</th>
<th>Voting Power</th>
<th>Voting power</th>
</tr>
</thead>
<tbody>
{Object.keys(resultsByPosition).map((position, index) => (
{total >= 0 ?
(total > 0 ?
Object.keys(resultsByPosition).map((position, index) => (
<tr key={index}>
<td>{resultsByPosition[position]?.address &&
<a className="ballot_link" target="_blank" rel="noreferrer" href={formStacksExplorerUrl(resultsByPosition[position]?.address)}>
@@ -260,9 +263,25 @@ export default function PollComponent(props) {
</div>
))}
</td>
<td>1</td>
<td>
{Object.values(resultsByPosition[position]?.vote)?.[0]}
</td>
</tr>
))}
))
:
<tr>
<td style={{ textAlign: "center" }} colSpan={3}>
No data found
</td>
</tr>
)
:
<tr>
<td style={{ textAlign: "center" }} colSpan={3}>
Loading
</td>
</tr>
}
</tbody>
</Table>
</div>
@@ -281,6 +300,7 @@ export default function PollComponent(props) {
}
</div>
{/* Success message popup */}
<Modal show={show} onHide={handleClose}>
<Modal.Header closeButton>
<Modal.Title>Information</Modal.Title>

View File

@@ -12,7 +12,6 @@ import { getMyStxAddress, getStacksAPIPrefix, userSession } from "../../services
export default function Poll(props) {
const { pollObject, pollId, gaiaAddress } = props;
// const [pollObject, setPollObject] = useState();
const [publicUrl, setPublicUrl] = useState();
const [optionsMap, setOptionsMap] = useState({});
const [resultsByOption, setResultsByOption] = useState({});
@@ -188,16 +187,21 @@ export default function Poll(props) {
if (content && content.okay) {
const results = cvToValue(parseReadOnlyResponse(content)).value;
let resultsObj = {};
results?.options?.value.forEach((option, index) => {
resultsObj[option?.value] = results?.results?.value?.[index]?.value;
});
setResultsByOption(resultsObj)
const total = parseInt(results?.total?.value);
const total = parseInt(results?.["total-with-voting-power"]?.value ? (results?.["total-with-voting-power"]?.value) : (results?.total?.value));
setTotal(total);
getFirstTenResults((total > 10 ? 10 : total), contractAddress, contractName);
let resultsObj = {};
results?.options?.value.forEach((option, index) => {
resultsObj[option?.value] = {
total: results?.results?.value?.[index]?.value,
percentage: results?.results?.value?.[index]?.value == 0 ? 0 : ((results?.results?.value?.[index]?.value / total) * 100)
};
});
setResultsByOption(resultsObj);
getFirstTenResults((results?.total?.value > 10 ? 10 : results?.total?.value), contractAddress, contractName);
} else {
setTotal(0);
}
}
};

View File

@@ -119,6 +119,7 @@ function getRawContract() {
(define-map users {id: principal} {count: uint, vote: (list &{noOfOptions} (string-ascii 36)), volume: (list &{noOfOptions} uint)})
(define-map register {id: uint} {user: principal, bns: (string-ascii 256), vote: (list &{noOfOptions} (string-ascii 36)), volume: (list &{noOfOptions} uint)})
(define-data-var total uint u0)
(define-data-var total-with-voting-power uint u0)
(define-data-var options (list &{noOfOptions} (string-ascii 36)) (list))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -216,6 +217,9 @@ function getRawContract() {
(map-set users {id: tx-sender} {count: u1, vote: vote, volume: volume})
(map-set register {id: next-total} {user: tx-sender, bns: bns, vote: vote, volume: volume})
;; Increase the total with voting power
(var-set total-with-voting-power (+ (unwrap-panic (element-at volume u0)) (var-get total-with-voting-power)))
;; Increase the total
(var-set total next-total)
@@ -226,7 +230,7 @@ function getRawContract() {
(define-read-only (get-results)
(begin
(ok {total: (var-get total),options: (var-get options), results: (map get-single-result (var-get options))})
(ok {total: (var-get total), total-with-voting-power: (var-get total-with-voting-power), options: (var-get options), results: (map get-single-result (var-get options))})
)
)