Refactor voting modal (#84)

This commit is contained in:
Szymon Szlachtowicz 2021-09-22 01:04:38 +02:00 committed by GitHub
parent bd6f195b98
commit e4f65a84be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 207 additions and 114 deletions

View File

@ -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) => {

View File

@ -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",

View File

@ -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'

View File

@ -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",

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -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",

View File

@ -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'

View File

@ -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>
) )

View File

@ -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 = {

View File

@ -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'

View File

@ -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

View File

@ -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>

View File

@ -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>
) )

View File

@ -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}>

View File

@ -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>

View File

@ -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>
)}
</>
)
}

View File

@ -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))
}} }}

View File

@ -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}
/> />
)} )}

View File

@ -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>

View File

@ -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 && (

View File

@ -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>

View File

@ -38,6 +38,7 @@ export function ProposeVoteModal({
availableAmount={availableAmount} availableAmount={availableAmount}
setProposingAmount={setProposingAmount} setProposingAmount={setProposingAmount}
proposingAmount={proposingAmount} proposingAmount={proposingAmount}
wakuVoting={wakuVoting}
/> />
</VoteProposeWrap> </VoteProposeWrap>

View File

@ -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",

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB