Refactor voting modal (#84)
This commit is contained in:
parent
bd6f195b98
commit
e4f65a84be
|
@ -33,6 +33,7 @@ export class WakuMessaging {
|
||||||
protected observers: { callback: (msg: WakuMessage) => void; topics: string[] }[] = []
|
protected observers: { callback: (msg: WakuMessage) => void; topics: string[] }[] = []
|
||||||
protected multicall: Contract
|
protected multicall: Contract
|
||||||
public tokenDecimals: number | undefined
|
public tokenDecimals: number | undefined
|
||||||
|
public tokenSymbol: string | undefined
|
||||||
|
|
||||||
protected constructor(
|
protected constructor(
|
||||||
appName: string,
|
appName: string,
|
||||||
|
@ -69,7 +70,8 @@ export class WakuMessaging {
|
||||||
|
|
||||||
protected async setObserver() {
|
protected async setObserver() {
|
||||||
this.tokenDecimals = await this.token.decimals()
|
this.tokenDecimals = await this.token.decimals()
|
||||||
|
this.tokenSymbol = await this.token.symbol()
|
||||||
|
console.log(this.tokenSymbol)
|
||||||
this.waku = await createWaku(this.waku)
|
this.waku = await createWaku(this.waku)
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
Object.values(this.wakuMessages).map(async (msgObj) => {
|
Object.values(this.wakuMessages).map(async (msgObj) => {
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
"lint:prettier": "yarn prettier './{src,test}/**/*.{ts,tsx}'"
|
"lint:prettier": "yarn prettier './{src,test}/**/*.{ts,tsx}'"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@status-waku-voting/polling-page": "^0.1.0",
|
"@status-waku-voting/polling-example": "^0.1.0",
|
||||||
"@status-waku-voting/proposal-page": "^0.1.0",
|
"@status-waku-voting/proposal-example": "^0.1.0",
|
||||||
"assert": "^2.0.0",
|
"assert": "^2.0.0",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"crypto-browserify": "^3.12.0",
|
"crypto-browserify": "^3.12.0",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom'
|
||||||
import { PollingPage } from '@status-waku-voting/polling-page'
|
import { PollingPage } from '@status-waku-voting/polling-example'
|
||||||
import { ProposalPage } from '@status-waku-voting/proposal-page'
|
import { ProposalPage } from '@status-waku-voting/proposal-example'
|
||||||
import { BrowserRouter } from 'react-router-dom'
|
import { BrowserRouter } from 'react-router-dom'
|
||||||
import { Route, Switch } from 'react-router'
|
import { Route, Switch } from 'react-router'
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "@status-waku-voting/polling-page",
|
"name": "@status-waku-voting/polling-example",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"main": "dist/cjs/src/index.js",
|
"main": "dist/cjs/src/index.js",
|
||||||
"module": "dist/esm/src/index.js",
|
"module": "dist/esm/src/index.js",
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
@ -35,7 +35,6 @@
|
||||||
"@status-waku-voting/core": "^0.1.0",
|
"@status-waku-voting/core": "^0.1.0",
|
||||||
"@status-waku-voting/proposal-hooks": "^0.1.0",
|
"@status-waku-voting/proposal-hooks": "^0.1.0",
|
||||||
"@status-waku-voting/react-components": "^0.1.0",
|
"@status-waku-voting/react-components": "^0.1.0",
|
||||||
"@usedapp/core": "^0.4.7",
|
|
||||||
"ethers": "^5.4.4",
|
"ethers": "^5.4.4",
|
||||||
"humanize-duration": "^3.27.0",
|
"humanize-duration": "^3.27.0",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
import React, { useCallback, useEffect, useRef, useState } from 'react'
|
import React, { useCallback, useRef, useState } from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import { ProposalHeader } from './ProposalHeader'
|
import { ProposalHeader } from './ProposalHeader'
|
||||||
import { blueTheme } from '@status-waku-voting/react-components/dist/esm/src/style/themes'
|
import { blueTheme } from '@status-waku-voting/react-components/dist/esm/src/style/themes'
|
||||||
import { ProposalList } from './ProposalList'
|
import { ProposalList } from './ProposalList'
|
||||||
import { NotificationItem } from './NotificationItem'
|
|
||||||
import { WakuVoting } from '@status-waku-voting/core'
|
import { WakuVoting } from '@status-waku-voting/core'
|
||||||
import { VotingEmpty } from './VotingEmpty'
|
import { VotingEmpty } from './VotingEmpty'
|
||||||
import { VotingRoom } from '@status-waku-voting/core/dist/esm/src/types/PollType'
|
|
||||||
import { useTokenBalance } from '@status-waku-voting/react-components'
|
import { useTokenBalance } from '@status-waku-voting/react-components'
|
||||||
import { NewVoteModal } from './newVoteModal/NewVoteModal'
|
import { NewVoteModal } from './newVoteModal/NewVoteModal'
|
||||||
import { useEthers } from '@usedapp/core'
|
import { useEthers } from '@usedapp/core'
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import React from 'react'
|
import React, { ReactElement, useCallback, useState } from 'react'
|
||||||
import { useHistory } from 'react-router'
|
import { useHistory } from 'react-router'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import { Theme } from '@status-waku-voting/react-components'
|
import { Theme } from '@status-waku-voting/react-components'
|
||||||
import { ProposalInfo } from './ProposalInfo'
|
import { ProposalInfo } from './ProposalInfo'
|
||||||
import { ProposalVote } from './ProposalVoteCard/ProposalVote'
|
import { ProposalVote } from './ProposalVoteCard/ProposalVote'
|
||||||
import { VotingRoom } from '@status-waku-voting/core/dist/esm/src/types/PollType'
|
|
||||||
import { WakuVoting } from '@status-waku-voting/core'
|
import { WakuVoting } from '@status-waku-voting/core'
|
||||||
import { useVotingRoom } from '@status-waku-voting/proposal-hooks'
|
import { useVotingRoom } from '@status-waku-voting/proposal-hooks'
|
||||||
|
import { VoteModal, VoteModalProps } from './VoteModal/VoteModal'
|
||||||
|
|
||||||
interface ProposalCardProps {
|
interface ProposalCardProps {
|
||||||
votingRoomId: number
|
votingRoomId: number
|
||||||
|
@ -16,6 +16,9 @@ interface ProposalCardProps {
|
||||||
availableAmount: number
|
availableAmount: number
|
||||||
wakuVoting: WakuVoting
|
wakuVoting: WakuVoting
|
||||||
account: string | null | undefined
|
account: string | null | undefined
|
||||||
|
CustomVoteModal?: (props: VoteModalProps) => ReactElement
|
||||||
|
customAgainstClick?: () => void
|
||||||
|
customForClick?: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ProposalCard({
|
export function ProposalCard({
|
||||||
|
@ -25,22 +28,61 @@ export function ProposalCard({
|
||||||
mobileVersion,
|
mobileVersion,
|
||||||
availableAmount,
|
availableAmount,
|
||||||
wakuVoting,
|
wakuVoting,
|
||||||
|
CustomVoteModal,
|
||||||
|
customAgainstClick,
|
||||||
|
customForClick,
|
||||||
}: ProposalCardProps) {
|
}: ProposalCardProps) {
|
||||||
const history = useHistory()
|
const history = useHistory()
|
||||||
const votingRoom = useVotingRoom(votingRoomId, wakuVoting)
|
const votingRoom = useVotingRoom(votingRoomId, wakuVoting)
|
||||||
|
|
||||||
|
const [showVoteModal, setShowVoteModal] = useState(false)
|
||||||
|
const [selectedVote, setSelectedVote] = useState(0)
|
||||||
|
|
||||||
|
const againstClick = useCallback(() => {
|
||||||
|
setSelectedVote(0)
|
||||||
|
setShowVoteModal(true)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const forClick = useCallback(() => {
|
||||||
|
setSelectedVote(1)
|
||||||
|
setShowVoteModal(true)
|
||||||
|
}, [])
|
||||||
|
|
||||||
if (!votingRoom) {
|
if (!votingRoom) {
|
||||||
return <></>
|
return <></>
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card onClick={() => mobileVersion && history.push(`/votingRoom/${votingRoom.id.toString()}`)}>
|
<Card onClick={() => mobileVersion && history.push(`/votingRoom/${votingRoom.id.toString()}`)}>
|
||||||
|
{CustomVoteModal ? (
|
||||||
|
<CustomVoteModal
|
||||||
|
setShowModal={setShowVoteModal}
|
||||||
|
showModal={showVoteModal}
|
||||||
|
votingRoom={votingRoom}
|
||||||
|
availableAmount={availableAmount}
|
||||||
|
selectedVote={selectedVote}
|
||||||
|
wakuVoting={wakuVoting}
|
||||||
|
theme={theme}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<VoteModal
|
||||||
|
setShowModal={setShowVoteModal}
|
||||||
|
showModal={showVoteModal}
|
||||||
|
votingRoom={votingRoom}
|
||||||
|
availableAmount={availableAmount}
|
||||||
|
selectedVote={selectedVote}
|
||||||
|
wakuVoting={wakuVoting}
|
||||||
|
theme={theme}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<ProposalInfo votingRoom={votingRoom} providerName={wakuVoting.providerName} />
|
<ProposalInfo votingRoom={votingRoom} providerName={wakuVoting.providerName} />
|
||||||
<ProposalVote
|
<ProposalVote
|
||||||
votingRoom={votingRoom}
|
votingRoom={votingRoom}
|
||||||
theme={theme}
|
selectedVote={selectedVote}
|
||||||
availableAmount={availableAmount}
|
|
||||||
wakuVoting={wakuVoting}
|
wakuVoting={wakuVoting}
|
||||||
account={account}
|
account={account}
|
||||||
|
againstClick={customAgainstClick ?? againstClick}
|
||||||
|
forClick={customForClick ?? forClick}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import React, { useEffect, useState } from 'react'
|
import React from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import { useEthers } from '@usedapp/core'
|
import { CreateButton } from '@status-waku-voting/react-components'
|
||||||
import { Modal, Networks, CreateButton } from '@status-waku-voting/react-components'
|
|
||||||
import { Theme } from '@status-waku-voting/react-components/dist/esm/src/style/themes'
|
import { Theme } from '@status-waku-voting/react-components/dist/esm/src/style/themes'
|
||||||
|
|
||||||
type ProposalHeaderProps = {
|
type ProposalHeaderProps = {
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import { WakuVoting } from '@status-waku-voting/core'
|
|
||||||
import { VotingRoom } from '@status-waku-voting/core/dist/esm/src/types/PollType'
|
import { VotingRoom } from '@status-waku-voting/core/dist/esm/src/types/PollType'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
|
@ -3,8 +3,6 @@ import styled from 'styled-components'
|
||||||
import { Theme, useMobileVersion } from '@status-waku-voting/react-components'
|
import { Theme, useMobileVersion } from '@status-waku-voting/react-components'
|
||||||
import { ProposalCard } from './ProposalCard'
|
import { ProposalCard } from './ProposalCard'
|
||||||
import { WakuVoting } from '@status-waku-voting/core'
|
import { WakuVoting } from '@status-waku-voting/core'
|
||||||
import { VotingEmpty } from './VotingEmpty'
|
|
||||||
import { VotingRoom } from '@status-waku-voting/core/dist/esm/src/types/PollType'
|
|
||||||
|
|
||||||
type ProposalListProps = {
|
type ProposalListProps = {
|
||||||
theme: Theme
|
theme: Theme
|
||||||
|
|
|
@ -4,33 +4,26 @@ import { FinalBtn, VoteBtnAgainst, VoteBtnFor } from '../Buttons'
|
||||||
import { VoteSubmitButton } from './VoteSubmitButton'
|
import { VoteSubmitButton } from './VoteSubmitButton'
|
||||||
import { VoteChart } from './VoteChart'
|
import { VoteChart } from './VoteChart'
|
||||||
import { ViewLink } from '../ViewLink'
|
import { ViewLink } from '../ViewLink'
|
||||||
import { Modal, Theme } from '@status-waku-voting/react-components'
|
|
||||||
import { VoteModal } from '../VoteModal'
|
|
||||||
import { VoteAnimatedModal } from '../VoteAnimatedModal'
|
|
||||||
import { VotingRoom } from '@status-waku-voting/core/dist/esm/src/types/PollType'
|
import { VotingRoom } from '@status-waku-voting/core/dist/esm/src/types/PollType'
|
||||||
import { WakuVoting } from '@status-waku-voting/core'
|
import { WakuVoting } from '@status-waku-voting/core'
|
||||||
|
|
||||||
interface ProposalVoteProps {
|
interface ProposalVoteProps {
|
||||||
theme: Theme
|
|
||||||
votingRoom: VotingRoom
|
votingRoom: VotingRoom
|
||||||
availableAmount: number
|
selectedVote: number
|
||||||
hideModalFunction?: (val: boolean) => void
|
|
||||||
wakuVoting: WakuVoting
|
wakuVoting: WakuVoting
|
||||||
account: string | null | undefined
|
account: string | null | undefined
|
||||||
|
againstClick: () => void
|
||||||
|
forClick: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ProposalVote({
|
export function ProposalVote({
|
||||||
account,
|
account,
|
||||||
votingRoom,
|
votingRoom,
|
||||||
theme,
|
selectedVote,
|
||||||
availableAmount,
|
|
||||||
hideModalFunction,
|
|
||||||
wakuVoting,
|
wakuVoting,
|
||||||
|
againstClick,
|
||||||
|
forClick,
|
||||||
}: ProposalVoteProps) {
|
}: ProposalVoteProps) {
|
||||||
const [showVoteModal, setShowVoteModal] = useState(false)
|
|
||||||
const [showConfirmModal, setShowConfirmModal] = useState(false)
|
|
||||||
const [proposingAmount, setProposingAmount] = useState(0)
|
|
||||||
const [selectedVoted, setSelectedVoted] = useState(0)
|
|
||||||
const [alreadyVoted, setAlreadyVoted] = useState(false)
|
const [alreadyVoted, setAlreadyVoted] = useState(false)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -41,72 +34,25 @@ export function ProposalVote({
|
||||||
}
|
}
|
||||||
}, [account, votingRoom])
|
}, [account, votingRoom])
|
||||||
|
|
||||||
const setNext = (val: boolean) => {
|
|
||||||
setShowConfirmModal(val)
|
|
||||||
setShowVoteModal(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
const hideConfirm = (val: boolean) => {
|
|
||||||
if (hideModalFunction) {
|
|
||||||
hideModalFunction(false)
|
|
||||||
}
|
|
||||||
setShowConfirmModal(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
{showVoteModal && (
|
|
||||||
<Modal heading={votingRoom.question} setShowModal={setShowVoteModal} theme={theme}>
|
|
||||||
<VoteModal
|
|
||||||
votingRoom={votingRoom}
|
|
||||||
availableAmount={availableAmount}
|
|
||||||
selectedVote={selectedVoted}
|
|
||||||
proposingAmount={proposingAmount}
|
|
||||||
setShowConfirmModal={setNext}
|
|
||||||
setProposingAmount={setProposingAmount}
|
|
||||||
wakuVoting={wakuVoting}
|
|
||||||
/>{' '}
|
|
||||||
</Modal>
|
|
||||||
)}
|
|
||||||
{showConfirmModal && (
|
|
||||||
<Modal heading={votingRoom.question} setShowModal={hideConfirm} theme={theme}>
|
|
||||||
<VoteAnimatedModal
|
|
||||||
votingRoom={votingRoom}
|
|
||||||
selectedVote={selectedVoted}
|
|
||||||
setShowModal={hideConfirm}
|
|
||||||
proposingAmount={proposingAmount}
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
)}
|
|
||||||
{votingRoom.voteWinner ? (
|
{votingRoom.voteWinner ? (
|
||||||
<CardHeading>Proposal {votingRoom.voteWinner == 1 ? 'rejected' : 'passed'}</CardHeading>
|
<CardHeading>Proposal {votingRoom.voteWinner == 1 ? 'rejected' : 'passed'}</CardHeading>
|
||||||
) : (
|
) : (
|
||||||
<CardHeading />
|
<CardHeading />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<VoteChart votingRoom={votingRoom} selectedVote={selectedVoted} />
|
<VoteChart votingRoom={votingRoom} selectedVote={selectedVote} wakuVoting={wakuVoting} />
|
||||||
|
|
||||||
<CardButtons>
|
<CardButtons>
|
||||||
{votingRoom.voteWinner ? (
|
{votingRoom.voteWinner ? (
|
||||||
<></>
|
<></>
|
||||||
) : (
|
) : (
|
||||||
<VotesBtns>
|
<VotesBtns>
|
||||||
<VoteBtnAgainst
|
<VoteBtnAgainst disabled={!account || alreadyVoted} onClick={againstClick}>
|
||||||
disabled={!account || alreadyVoted}
|
|
||||||
onClick={() => {
|
|
||||||
setSelectedVoted(0)
|
|
||||||
setShowVoteModal(true)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Vote Against
|
Vote Against
|
||||||
</VoteBtnAgainst>
|
</VoteBtnAgainst>
|
||||||
<VoteBtnFor
|
<VoteBtnFor disabled={!account || alreadyVoted} onClick={forClick}>
|
||||||
disabled={!account || alreadyVoted}
|
|
||||||
onClick={() => {
|
|
||||||
setSelectedVoted(1)
|
|
||||||
setShowVoteModal(true)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Vote For
|
Vote For
|
||||||
</VoteBtnFor>
|
</VoteBtnFor>
|
||||||
</VotesBtns>
|
</VotesBtns>
|
||||||
|
|
|
@ -10,24 +10,43 @@ import checkIcon from '../../assets/svg/check.svg'
|
||||||
import checkWinnerIcon from '../../assets/svg/checkWinner.svg'
|
import checkWinnerIcon from '../../assets/svg/checkWinner.svg'
|
||||||
import { useMobileVersion } from '@status-waku-voting/react-components'
|
import { useMobileVersion } from '@status-waku-voting/react-components'
|
||||||
import { VotingRoom } from '@status-waku-voting/core/dist/esm/src/types/PollType'
|
import { VotingRoom } from '@status-waku-voting/core/dist/esm/src/types/PollType'
|
||||||
|
import { WakuVoting } from '@status-waku-voting/core'
|
||||||
|
|
||||||
export interface VoteChartProps {
|
export interface VoteChartProps {
|
||||||
votingRoom: VotingRoom
|
votingRoom: VotingRoom
|
||||||
|
wakuVoting: WakuVoting
|
||||||
proposingAmount?: number
|
proposingAmount?: number
|
||||||
selectedVote?: number
|
selectedVote?: number
|
||||||
isAnimation?: boolean
|
isAnimation?: boolean
|
||||||
tabletMode?: (val: boolean) => void
|
tabletMode?: (val: boolean) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export function VoteChart({ votingRoom, proposingAmount, selectedVote, isAnimation, tabletMode }: VoteChartProps) {
|
export function VoteChart({
|
||||||
|
votingRoom,
|
||||||
|
wakuVoting,
|
||||||
|
proposingAmount,
|
||||||
|
selectedVote,
|
||||||
|
isAnimation,
|
||||||
|
tabletMode,
|
||||||
|
}: VoteChartProps) {
|
||||||
const ref = useRef<HTMLHeadingElement>(null)
|
const ref = useRef<HTMLHeadingElement>(null)
|
||||||
const mobileVersion = useMobileVersion(ref, 600)
|
const mobileVersion = useMobileVersion(ref, 600)
|
||||||
|
|
||||||
const voteSum = useMemo(
|
const totalVotesFor = useMemo(
|
||||||
() => votingRoom.wakuTotalVotesFor.add(votingRoom.wakuTotalVotesAgainst),
|
() => (isAnimation ? votingRoom.totalVotesFor : votingRoom.wakuTotalVotesFor),
|
||||||
[votingRoom.wakuTotalVotesFor.toString(), votingRoom.wakuTotalVotesAgainst.toString()]
|
[votingRoom, proposingAmount]
|
||||||
)
|
)
|
||||||
const graphWidth = useMemo(() => votingRoom.wakuTotalVotesAgainst.mul(100).div(voteSum).toNumber(), [voteSum])
|
|
||||||
|
const totalVotesAgainst = useMemo(
|
||||||
|
() => (isAnimation ? votingRoom.totalVotesAgainst : votingRoom.wakuTotalVotesAgainst),
|
||||||
|
[votingRoom, proposingAmount]
|
||||||
|
)
|
||||||
|
|
||||||
|
const voteSum = useMemo(
|
||||||
|
() => totalVotesFor.add(totalVotesAgainst),
|
||||||
|
[totalVotesFor.toString(), totalVotesAgainst.toString()]
|
||||||
|
)
|
||||||
|
const graphWidth = useMemo(() => totalVotesAgainst.mul(100).div(voteSum).toNumber(), [voteSum])
|
||||||
|
|
||||||
const balanceWidth = useMemo(() => {
|
const balanceWidth = useMemo(() => {
|
||||||
if (!proposingAmount) {
|
if (!proposingAmount) {
|
||||||
|
@ -35,8 +54,8 @@ export function VoteChart({ votingRoom, proposingAmount, selectedVote, isAnimati
|
||||||
} else {
|
} else {
|
||||||
const divider = voteSum.add(proposingAmount)
|
const divider = voteSum.add(proposingAmount)
|
||||||
return selectedVote === 0
|
return selectedVote === 0
|
||||||
? votingRoom.wakuTotalVotesAgainst.add(proposingAmount).mul(100).div(divider).toNumber()
|
? totalVotesAgainst.add(proposingAmount).mul(100).div(divider).toNumber()
|
||||||
: votingRoom.wakuTotalVotesAgainst.mul(100).div(divider).toNumber()
|
: totalVotesAgainst.mul(100).div(divider).toNumber()
|
||||||
}
|
}
|
||||||
}, [graphWidth, voteSum, proposingAmount])
|
}, [graphWidth, voteSum, proposingAmount])
|
||||||
|
|
||||||
|
@ -47,10 +66,11 @@ export function VoteChart({ votingRoom, proposingAmount, selectedVote, isAnimati
|
||||||
<VoteBox
|
<VoteBox
|
||||||
voteType={2}
|
voteType={2}
|
||||||
mobileVersion={mobileVersion}
|
mobileVersion={mobileVersion}
|
||||||
totalVotes={votingRoom.wakuTotalVotesAgainst.toNumber()}
|
totalVotes={totalVotesAgainst.toNumber()}
|
||||||
won={voteWinner === 2}
|
won={voteWinner === 2}
|
||||||
selected={isAnimation && selectedVote === 0}
|
selected={isAnimation && selectedVote === 0}
|
||||||
proposingAmount={proposingAmount}
|
proposingAmount={proposingAmount}
|
||||||
|
wakuVoting={wakuVoting}
|
||||||
/>
|
/>
|
||||||
{!voteWinner && (
|
{!voteWinner && (
|
||||||
<TimeLeft className={selectedVote ? '' : 'notModal'}>{formatTimeLeft(votingRoom.timeLeft)}</TimeLeft>
|
<TimeLeft className={selectedVote ? '' : 'notModal'}>{formatTimeLeft(votingRoom.timeLeft)}</TimeLeft>
|
||||||
|
@ -58,10 +78,11 @@ export function VoteChart({ votingRoom, proposingAmount, selectedVote, isAnimati
|
||||||
<VoteBox
|
<VoteBox
|
||||||
voteType={1}
|
voteType={1}
|
||||||
mobileVersion={mobileVersion}
|
mobileVersion={mobileVersion}
|
||||||
totalVotes={votingRoom.wakuTotalVotesFor.toNumber()}
|
totalVotes={totalVotesFor.toNumber()}
|
||||||
won={voteWinner === 1}
|
won={voteWinner === 1}
|
||||||
selected={isAnimation && selectedVote === 1}
|
selected={isAnimation && selectedVote === 1}
|
||||||
proposingAmount={proposingAmount}
|
proposingAmount={proposingAmount}
|
||||||
|
wakuVoting={wakuVoting}
|
||||||
/>
|
/>
|
||||||
</VotesChart>
|
</VotesChart>
|
||||||
<VoteGraphBarWrap className={selectedVote || tabletMode ? '' : 'notModal'}>
|
<VoteGraphBarWrap className={selectedVote || tabletMode ? '' : 'notModal'}>
|
||||||
|
@ -84,11 +105,12 @@ type VoteBoxProps = {
|
||||||
mobileVersion: boolean
|
mobileVersion: boolean
|
||||||
voteType: number
|
voteType: number
|
||||||
totalVotes: number
|
totalVotes: number
|
||||||
|
wakuVoting: WakuVoting
|
||||||
selected?: boolean
|
selected?: boolean
|
||||||
proposingAmount?: number
|
proposingAmount?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
function VoteBox({ won, mobileVersion, voteType, totalVotes, proposingAmount, selected }: VoteBoxProps) {
|
function VoteBox({ won, mobileVersion, voteType, totalVotes, proposingAmount, selected, wakuVoting }: VoteBoxProps) {
|
||||||
return (
|
return (
|
||||||
<VoteBoxWrapper
|
<VoteBoxWrapper
|
||||||
style={{
|
style={{
|
||||||
|
@ -110,7 +132,7 @@ function VoteBox({ won, mobileVersion, voteType, totalVotes, proposingAmount, se
|
||||||
) : (
|
) : (
|
||||||
addCommas(totalVotes)
|
addCommas(totalVotes)
|
||||||
)}{' '}
|
)}{' '}
|
||||||
<span style={{ fontWeight: 'normal' }}>ABC</span>
|
<span style={{ fontWeight: 'normal' }}>{wakuVoting.tokenSymbol}</span>
|
||||||
</span>
|
</span>
|
||||||
</VoteBoxWrapper>
|
</VoteBoxWrapper>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback } from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import { VoteChart } from './ProposalVoteCard/VoteChart'
|
import { VoteChart } from '../ProposalVoteCard/VoteChart'
|
||||||
import { DisabledButton, VoteBtnAgainst, VoteBtnFor } from './Buttons'
|
import { DisabledButton, VoteBtnAgainst, VoteBtnFor } from '../Buttons'
|
||||||
import { VotePropose } from './VotePropose'
|
import { VotePropose } from '../VotePropose'
|
||||||
import { VotingRoom } from '@status-waku-voting/core/dist/esm/src/types/PollType'
|
import { VotingRoom } from '@status-waku-voting/core/dist/esm/src/types/PollType'
|
||||||
import { WakuVoting } from '@status-waku-voting/core'
|
import { WakuVoting } from '@status-waku-voting/core'
|
||||||
import { BigNumber } from 'ethers'
|
import { BigNumber } from 'ethers'
|
||||||
|
|
||||||
export interface VoteModalProps {
|
export interface AmountModalProps {
|
||||||
votingRoom: VotingRoom
|
votingRoom: VotingRoom
|
||||||
availableAmount: number
|
availableAmount: number
|
||||||
selectedVote: number
|
selectedVote: number
|
||||||
|
@ -17,7 +17,7 @@ export interface VoteModalProps {
|
||||||
wakuVoting: WakuVoting
|
wakuVoting: WakuVoting
|
||||||
}
|
}
|
||||||
|
|
||||||
export function VoteModal({
|
export function AmountModal({
|
||||||
votingRoom,
|
votingRoom,
|
||||||
selectedVote,
|
selectedVote,
|
||||||
availableAmount,
|
availableAmount,
|
||||||
|
@ -25,7 +25,7 @@ export function VoteModal({
|
||||||
setShowConfirmModal,
|
setShowConfirmModal,
|
||||||
setProposingAmount,
|
setProposingAmount,
|
||||||
wakuVoting,
|
wakuVoting,
|
||||||
}: VoteModalProps) {
|
}: AmountModalProps) {
|
||||||
const disabled = proposingAmount === 0
|
const disabled = proposingAmount === 0
|
||||||
const funds = availableAmount > 0
|
const funds = availableAmount > 0
|
||||||
const onClick = useCallback(async () => {
|
const onClick = useCallback(async () => {
|
||||||
|
@ -34,14 +34,20 @@ export function VoteModal({
|
||||||
}, [votingRoom, selectedVote, proposingAmount, wakuVoting])
|
}, [votingRoom, selectedVote, proposingAmount, wakuVoting])
|
||||||
return (
|
return (
|
||||||
<Column>
|
<Column>
|
||||||
<VoteChart votingRoom={votingRoom} proposingAmount={proposingAmount} selectedVote={selectedVote} />
|
<VoteChart
|
||||||
|
votingRoom={votingRoom}
|
||||||
|
proposingAmount={proposingAmount}
|
||||||
|
selectedVote={selectedVote}
|
||||||
|
wakuVoting={wakuVoting}
|
||||||
|
/>
|
||||||
<VotePropose
|
<VotePropose
|
||||||
availableAmount={availableAmount}
|
availableAmount={availableAmount}
|
||||||
setProposingAmount={setProposingAmount}
|
setProposingAmount={setProposingAmount}
|
||||||
proposingAmount={proposingAmount}
|
proposingAmount={proposingAmount}
|
||||||
|
wakuVoting={wakuVoting}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{!funds && <DisabledButton>Not enought ABC to vote</DisabledButton>}
|
{!funds && <DisabledButton>Not enough {wakuVoting.tokenSymbol} to vote</DisabledButton>}
|
||||||
|
|
||||||
{funds && selectedVote === 0 ? (
|
{funds && selectedVote === 0 ? (
|
||||||
<BtnAgainst disabled={disabled} onClick={onClick}>
|
<BtnAgainst disabled={disabled} onClick={onClick}>
|
|
@ -1,17 +1,25 @@
|
||||||
|
import { WakuVoting } from '@status-waku-voting/core'
|
||||||
import { VotingRoom } from '@status-waku-voting/core/dist/esm/src/types/PollType'
|
import { VotingRoom } from '@status-waku-voting/core/dist/esm/src/types/PollType'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import { FinalBtn } from './Buttons'
|
import { FinalBtn } from '../Buttons'
|
||||||
import { VoteChart } from './ProposalVoteCard/VoteChart'
|
import { VoteChart } from '../ProposalVoteCard/VoteChart'
|
||||||
|
|
||||||
interface VoteAnimatedModalProps {
|
interface ConfirmModalProps {
|
||||||
votingRoom: VotingRoom
|
votingRoom: VotingRoom
|
||||||
proposingAmount: number
|
proposingAmount: number
|
||||||
selectedVote: number
|
selectedVote: number
|
||||||
setShowModal: (val: boolean) => void
|
setShowModal: (val: boolean) => void
|
||||||
|
wakuVoting: WakuVoting
|
||||||
}
|
}
|
||||||
|
|
||||||
export function VoteAnimatedModal({ votingRoom, selectedVote, proposingAmount, setShowModal }: VoteAnimatedModalProps) {
|
export function ConfirmModal({
|
||||||
|
votingRoom,
|
||||||
|
selectedVote,
|
||||||
|
proposingAmount,
|
||||||
|
setShowModal,
|
||||||
|
wakuVoting,
|
||||||
|
}: ConfirmModalProps) {
|
||||||
return (
|
return (
|
||||||
<VoteConfirm>
|
<VoteConfirm>
|
||||||
<ConfirmText>Your vote {selectedVote === 0 ? 'against' : 'for'} this proposal has been cast!</ConfirmText>
|
<ConfirmText>Your vote {selectedVote === 0 ? 'against' : 'for'} this proposal has been cast!</ConfirmText>
|
||||||
|
@ -20,6 +28,7 @@ export function VoteAnimatedModal({ votingRoom, selectedVote, proposingAmount, s
|
||||||
proposingAmount={proposingAmount}
|
proposingAmount={proposingAmount}
|
||||||
selectedVote={selectedVote}
|
selectedVote={selectedVote}
|
||||||
isAnimation={true}
|
isAnimation={true}
|
||||||
|
wakuVoting={wakuVoting}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<FinalBtn onClick={() => setShowModal(false)}>Close</FinalBtn>
|
<FinalBtn onClick={() => setShowModal(false)}>Close</FinalBtn>
|
|
@ -0,0 +1,63 @@
|
||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import { VotingRoom } from '@status-waku-voting/core/dist/esm/src/types/PollType'
|
||||||
|
import { Modal, Theme } from '@status-waku-voting/react-components'
|
||||||
|
import { AmountModal } from './AmountModal'
|
||||||
|
import { ConfirmModal } from './ConfirmModal'
|
||||||
|
import { WakuVoting } from '@status-waku-voting/core'
|
||||||
|
|
||||||
|
export interface VoteModalProps {
|
||||||
|
setShowModal: (val: boolean) => void
|
||||||
|
showModal: boolean
|
||||||
|
votingRoom: VotingRoom
|
||||||
|
availableAmount: number
|
||||||
|
selectedVote: number
|
||||||
|
wakuVoting: WakuVoting
|
||||||
|
theme: Theme
|
||||||
|
}
|
||||||
|
|
||||||
|
export function VoteModal({
|
||||||
|
setShowModal,
|
||||||
|
showModal,
|
||||||
|
votingRoom,
|
||||||
|
availableAmount,
|
||||||
|
selectedVote,
|
||||||
|
wakuVoting,
|
||||||
|
theme,
|
||||||
|
}: VoteModalProps) {
|
||||||
|
const [screen, setScreen] = useState(0)
|
||||||
|
useEffect(() => setScreen(0), [])
|
||||||
|
const [proposingAmount, setProposingAmount] = useState(0)
|
||||||
|
useEffect(() => {
|
||||||
|
setScreen(0)
|
||||||
|
setProposingAmount(0)
|
||||||
|
}, [showModal])
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{showModal && (
|
||||||
|
<Modal heading={votingRoom.question} setShowModal={setShowModal} theme={theme}>
|
||||||
|
{screen == 0 ? (
|
||||||
|
<AmountModal
|
||||||
|
votingRoom={votingRoom}
|
||||||
|
availableAmount={availableAmount}
|
||||||
|
selectedVote={selectedVote}
|
||||||
|
proposingAmount={proposingAmount}
|
||||||
|
setShowConfirmModal={() => setScreen(1)}
|
||||||
|
setProposingAmount={setProposingAmount}
|
||||||
|
wakuVoting={wakuVoting}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<ConfirmModal
|
||||||
|
votingRoom={votingRoom}
|
||||||
|
selectedVote={selectedVote}
|
||||||
|
setShowModal={() => {
|
||||||
|
setShowModal(false)
|
||||||
|
}}
|
||||||
|
wakuVoting={wakuVoting}
|
||||||
|
proposingAmount={proposingAmount}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Modal>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { WakuVoting } from '@status-waku-voting/core'
|
||||||
import React, { useCallback, useMemo } from 'react'
|
import React, { useCallback, useMemo } from 'react'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
@ -8,9 +9,10 @@ export interface VoteProposingProps {
|
||||||
availableAmount: number
|
availableAmount: number
|
||||||
setProposingAmount: (show: number) => void
|
setProposingAmount: (show: number) => void
|
||||||
proposingAmount: number
|
proposingAmount: number
|
||||||
|
wakuVoting: WakuVoting
|
||||||
}
|
}
|
||||||
|
|
||||||
export function VotePropose({ availableAmount, proposingAmount, setProposingAmount }: VoteProposingProps) {
|
export function VotePropose({ availableAmount, proposingAmount, setProposingAmount, wakuVoting }: VoteProposingProps) {
|
||||||
const [inputFocused, setInputFocused] = useState(false)
|
const [inputFocused, setInputFocused] = useState(false)
|
||||||
const step = useMemo(
|
const step = useMemo(
|
||||||
() => (availableAmount < 100 ? 1 : 10 ** (Math.floor(Math.log10(availableAmount)) - 2)),
|
() => (availableAmount < 100 ? 1 : 10 ** (Math.floor(Math.log10(availableAmount)) - 2)),
|
||||||
|
@ -37,10 +39,12 @@ export function VotePropose({ availableAmount, proposingAmount, setProposingAmou
|
||||||
<VoteProposing>
|
<VoteProposing>
|
||||||
<VoteProposingInfo>
|
<VoteProposingInfo>
|
||||||
<p>My vote</p>
|
<p>My vote</p>
|
||||||
<span>Available {addCommas(availableAmount)} ABC</span>
|
<span>
|
||||||
|
Available {addCommas(availableAmount)} {wakuVoting.tokenSymbol}
|
||||||
|
</span>
|
||||||
</VoteProposingInfo>
|
</VoteProposingInfo>
|
||||||
<VoteProposingAmount
|
<VoteProposingAmount
|
||||||
value={inputFocused ? proposingAmount.toString() : addCommas(proposingAmount) + ' ABC'}
|
value={inputFocused ? proposingAmount.toString() : addCommas(proposingAmount) + ` wakuVoting.tokenSymbol`}
|
||||||
onInput={(e) => {
|
onInput={(e) => {
|
||||||
setProposingAmount(Number(e.currentTarget.value))
|
setProposingAmount(Number(e.currentTarget.value))
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -33,13 +33,14 @@ export function ProposalVoteMobile({ wakuVoting, availableAmount }: ProposalVote
|
||||||
<Card>
|
<Card>
|
||||||
<ProposalInfo votingRoom={votingRoom} mobileMode={true} providerName={wakuVoting.providerName} />
|
<ProposalInfo votingRoom={votingRoom} mobileMode={true} providerName={wakuVoting.providerName} />
|
||||||
<VoteChartWrap>
|
<VoteChartWrap>
|
||||||
<VoteChart votingRoom={votingRoom} selectedVote={selectedVoted} />
|
<VoteChart votingRoom={votingRoom} selectedVote={selectedVoted} wakuVoting={wakuVoting} />
|
||||||
</VoteChartWrap>
|
</VoteChartWrap>
|
||||||
{!voteWinner && (
|
{!voteWinner && (
|
||||||
<VotePropose
|
<VotePropose
|
||||||
availableAmount={availableAmount}
|
availableAmount={availableAmount}
|
||||||
setProposingAmount={setProposingAmount}
|
setProposingAmount={setProposingAmount}
|
||||||
proposingAmount={proposingAmount}
|
proposingAmount={proposingAmount}
|
||||||
|
wakuVoting={wakuVoting}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ export function ProposeMobile({ availableAmount, wakuVoting }: ProposeVoteModalP
|
||||||
{insufficientFunds && (
|
{insufficientFunds && (
|
||||||
<ProposingInfo>
|
<ProposingInfo>
|
||||||
<span>⚠️</span>
|
<span>⚠️</span>
|
||||||
<InfoText>You need at least 10,000 ABC to create a proposal!</InfoText>
|
<InfoText>You need at least 10,000 {wakuVoting.tokenSymbol} to create a proposal!</InfoText>
|
||||||
</ProposingInfo>
|
</ProposingInfo>
|
||||||
)}
|
)}
|
||||||
<ProposingCardHeading>Create proposal</ProposingCardHeading>
|
<ProposingCardHeading>Create proposal</ProposingCardHeading>
|
||||||
|
@ -88,6 +88,7 @@ export function ProposeMobile({ availableAmount, wakuVoting }: ProposeVoteModalP
|
||||||
availableAmount={availableAmount}
|
availableAmount={availableAmount}
|
||||||
setProposingAmount={setProposingAmount}
|
setProposingAmount={setProposingAmount}
|
||||||
proposingAmount={proposingAmount}
|
proposingAmount={proposingAmount}
|
||||||
|
wakuVoting={wakuVoting}
|
||||||
/>
|
/>
|
||||||
</VoteProposeWrap>
|
</VoteProposeWrap>
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ export function NewVoteModal({ theme, showModal, setShowModal, availableAmount,
|
||||||
setTitle={setTitle}
|
setTitle={setTitle}
|
||||||
availableAmount={availableAmount}
|
availableAmount={availableAmount}
|
||||||
setShowProposeVoteModal={() => setScreen(2)}
|
setShowProposeVoteModal={() => setScreen(2)}
|
||||||
|
wakuVoting={wakuVoting}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{screen === 2 && (
|
{screen === 2 && (
|
||||||
|
|
|
@ -3,7 +3,7 @@ import styled from 'styled-components'
|
||||||
import { ProposingBtn } from '../Buttons'
|
import { ProposingBtn } from '../Buttons'
|
||||||
import { TextArea } from '../Input'
|
import { TextArea } from '../Input'
|
||||||
import { blueTheme } from '@status-waku-voting/react-components/dist/esm/src/style/themes'
|
import { blueTheme } from '@status-waku-voting/react-components/dist/esm/src/style/themes'
|
||||||
import { BigNumber } from 'ethers'
|
import { WakuVoting } from '@status-waku-voting/core'
|
||||||
|
|
||||||
interface ProposeModalProps {
|
interface ProposeModalProps {
|
||||||
availableAmount: number
|
availableAmount: number
|
||||||
|
@ -12,6 +12,7 @@ interface ProposeModalProps {
|
||||||
setShowProposeVoteModal: (val: boolean) => void
|
setShowProposeVoteModal: (val: boolean) => void
|
||||||
setTitle: (val: string) => void
|
setTitle: (val: string) => void
|
||||||
setText: (val: string) => void
|
setText: (val: string) => void
|
||||||
|
wakuVoting: WakuVoting
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ProposeModal({
|
export function ProposeModal({
|
||||||
|
@ -21,6 +22,7 @@ export function ProposeModal({
|
||||||
setShowProposeVoteModal,
|
setShowProposeVoteModal,
|
||||||
setTitle,
|
setTitle,
|
||||||
setText,
|
setText,
|
||||||
|
wakuVoting,
|
||||||
}: ProposeModalProps) {
|
}: ProposeModalProps) {
|
||||||
const insufficientFunds = useMemo(() => availableAmount < 10000, [availableAmount])
|
const insufficientFunds = useMemo(() => availableAmount < 10000, [availableAmount])
|
||||||
|
|
||||||
|
@ -29,7 +31,7 @@ export function ProposeModal({
|
||||||
{availableAmount < 10000 && (
|
{availableAmount < 10000 && (
|
||||||
<ProposingInfo>
|
<ProposingInfo>
|
||||||
<span>⚠️</span>
|
<span>⚠️</span>
|
||||||
<InfoText>You need at least 10,000 ABC to create a proposal!</InfoText>
|
<InfoText>You need at least 10,000 {wakuVoting.tokenSymbol} to create a proposal!</InfoText>
|
||||||
</ProposingInfo>
|
</ProposingInfo>
|
||||||
)}
|
)}
|
||||||
<Label>
|
<Label>
|
||||||
|
|
|
@ -38,6 +38,7 @@ export function ProposeVoteModal({
|
||||||
availableAmount={availableAmount}
|
availableAmount={availableAmount}
|
||||||
setProposingAmount={setProposingAmount}
|
setProposingAmount={setProposingAmount}
|
||||||
proposingAmount={proposingAmount}
|
proposingAmount={proposingAmount}
|
||||||
|
wakuVoting={wakuVoting}
|
||||||
/>
|
/>
|
||||||
</VoteProposeWrap>
|
</VoteProposeWrap>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "@status-waku-voting/proposal-page",
|
"name": "@status-waku-voting/proposal-example",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"main": "dist/cjs/src/index.js",
|
"main": "dist/cjs/src/index.js",
|
||||||
"module": "dist/esm/src/index.js",
|
"module": "dist/esm/src/index.js",
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Loading…
Reference in New Issue