Filter votes cards (#81)

This commit is contained in:
Szymon Szlachtowicz 2021-07-06 08:46:21 +02:00 committed by GitHub
parent 27e3c26ee1
commit 205dfd0e77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 121 additions and 48 deletions

View File

@ -18,7 +18,8 @@ import { getVotingWinner } from '../helpers/voting'
import { useVotesAggregate } from '../hooks/useVotesAggregate'
import rightIcon from '../assets/images/arrowRight.svg'
import { VoteAnimatedModal } from './card/VoteAnimatedModal'
import voting from '../helpers/voting'
import { DetailedVotingRoom } from '../models/smartContract'
interface CardCommunityProps {
community: CommunityDetail
showRemoveButton?: boolean
@ -104,12 +105,11 @@ export const CardCommunity = ({ community, showRemoveButton }: CardCommunityProp
}
interface CardVoteProps {
community: CommunityDetail
room: number
room: DetailedVotingRoom
hideModalFunction?: (val: boolean) => void
}
export const CardVote = ({ community, room, hideModalFunction }: CardVoteProps) => {
export const CardVote = ({ room, hideModalFunction }: CardVoteProps) => {
const { account } = useEthers()
const [showVoteModal, setShowVoteModal] = useState(false)
const [showConfirmModal, setShowConfirmModal] = useState(false)
@ -117,11 +117,13 @@ export const CardVote = ({ community, room, hideModalFunction }: CardVoteProps)
const [selectedVoted, setSelectedVoted] = useState(voteTypes['Add'].for)
const { votingContract } = useContracts()
const { votes } = useVotesAggregate(room)
const { votes } = useVotesAggregate(room.room)
const { send } = useContractFunction(votingContract, 'castVotes')
const finalizeVoting = useContractFunction(votingContract, 'finalizeVotingRoom')
const community = room.details
const setNext = (val: boolean) => {
setShowConfirmModal(val)
setShowVoteModal(false)
@ -134,7 +136,7 @@ export const CardVote = ({ community, room, hideModalFunction }: CardVoteProps)
setShowConfirmModal(val)
}
const vote = community.currentVoting
const vote = voting.fromRoom(room)
if (!vote) {
return <CardVoteBlock />
@ -154,7 +156,7 @@ export const CardVote = ({ community, room, hideModalFunction }: CardVoteProps)
<Modal heading={`${vote?.type} ${community.name}?`} setShowModal={setShowVoteModal}>
<VoteModal
vote={vote}
room={room}
room={room.room}
selectedVote={selectedVoted}
availableAmount={availableAmount}
proposingAmount={proposingAmount}
@ -187,7 +189,7 @@ export const CardVote = ({ community, room, hideModalFunction }: CardVoteProps)
) : (
<CardVoteTop>
<CardHeading>{voteConstants.question}</CardHeading>
{votes.length > 0 && community.currentVoting && community?.currentVoting.timeLeft > 0 && (
{votes.length > 0 && vote && vote.timeLeft > 0 && (
<VoteSendingBtn onClick={() => send(votes)}> {votes.length} votes need saving</VoteSendingBtn>
)}
</CardVoteTop>
@ -196,7 +198,7 @@ export const CardVote = ({ community, room, hideModalFunction }: CardVoteProps)
<VoteChart vote={vote} voteWinner={winner} />
{winner ? (
<VoteBtnFinal onClick={() => finalizeVoting.send(room)} disabled={!account}>
<VoteBtnFinal onClick={() => finalizeVoting.send(room.room)} disabled={!account}>
Finalize the vote <span></span>
</VoteBtnFinal>
) : (

View File

@ -34,7 +34,7 @@ export const CardFeature = ({ community, heading, text, icon, sum, timeLeft }: C
setShowFeatureModal(false)
}
const { votingContract } = useContracts()
const [roomList] =
const [roomNumber] =
useContractCall({
abi: votingContract.interface,
address: votingContract.address,
@ -42,14 +42,25 @@ export const CardFeature = ({ community, heading, text, icon, sum, timeLeft }: C
args: [community.publicKey],
}) ?? []
const room = useContractCall({
abi: votingContract.interface,
address: votingContract.address,
method: 'votingRoomMap',
args: [roomNumber],
}) as any
return (
<CardVoteBlock style={{ backgroundColor: `${Colors.GrayLight}` }}>
<FeatureTop>
<CardHeading>{heading}</CardHeading>
{roomList > 0 && (
{roomNumber > 0 && room && (
<div>
{showOngoingVote && (
<OngoingVote community={community} setShowOngoingVote={setShowOngoingVote} room={roomList} />
<OngoingVote
community={community}
setShowOngoingVote={setShowOngoingVote}
room={{ ...room, room: roomNumber }}
/>
)}
<CardLinkFeature onClick={() => setShowOngoingVote(true)}>Ongoing vote for removal</CardLinkFeature>
</div>

View File

@ -1,23 +1,26 @@
import React from 'react'
import { votingFromRoom } from '../../helpers/voting'
import { CommunityDetail } from '../../models/community'
import { VotingRoom } from '../../models/smartContract'
import { CardVote, CardVoteBlock } from '../Card'
import { Modal } from '../Modal'
export interface OngoingVoteProps {
community: CommunityDetail
setShowOngoingVote: (show: boolean) => void
room: number
room: VotingRoom
}
export function OngoingVote({ community, setShowOngoingVote, room }: OngoingVoteProps) {
const vote = community.currentVoting
const vote = votingFromRoom(room)
const detailedVoting = { ...room, details: community }
if (!vote) {
return <CardVoteBlock />
}
return (
<Modal heading={`${vote?.type} ${community.name}?`} setShowModal={setShowOngoingVote}>
<CardVote community={community} hideModalFunction={setShowOngoingVote} room={room} />
<CardVote hideModalFunction={setShowOngoingVote} room={detailedVoting} />
</Modal>
)
}

View File

@ -1,29 +1,22 @@
import React from 'react'
import { DetailedVotingRoom } from '../../models/smartContract'
import { Card, CardCommunity, CardCommunityWrap, CardVote, CardVoteWrap } from '../Card'
import { useCommunity } from '../../hooks/useCommunity'
import { VotingCardSkeleton } from './VotingCardSkeleton'
interface VotingCardProps {
room: number
room: DetailedVotingRoom
}
export function VotingCard({ room }: VotingCardProps) {
const { community } = useCommunity(room)
if (community) {
return (
<Card>
<CardCommunityWrap>
{' '}
<CardCommunity community={community} />
</CardCommunityWrap>
<CardVoteWrap>
{' '}
<CardVote community={community} room={room} />
</CardVoteWrap>
</Card>
)
}
return <VotingCardSkeleton />
return (
<Card>
<CardCommunityWrap>
{' '}
<CardCommunity community={room.details} />
</CardCommunityWrap>
<CardVoteWrap>
{' '}
<CardVote room={room} />
</CardVoteWrap>
</Card>
)
}

View File

@ -7,22 +7,16 @@ import { ButtonPrimary } from '../Button'
import { Colors } from '../../constants/styles'
import { VotingCard } from './VotingCard'
import { Search } from '../Input'
import { useContractCall } from '@usedapp/core'
import { VotingSortingOptions } from '../../constants/SortingOptions'
import { useContracts } from '../../hooks/useContracts'
import { VotingCardSkeleton } from './VotingCardSkeleton'
import { useVotingCommunities } from '../../hooks/useVotingCommunities'
export function VotingCards() {
const { votingContract } = useContracts()
const [sortedBy, setSortedBy] = useState(VotingSortingEnum.EndingSoonest)
const [voteType, setVoteType] = useState('')
const [filterKeyword, setFilterKeyword] = useState('')
const roomsToShow = useVotingCommunities(filterKeyword)
const [roomList] = useContractCall({
abi: votingContract.interface,
address: votingContract.address,
method: 'getActiveVotingRooms',
args: [],
}) ?? [[]]
return (
<div>
<PageBar>
@ -51,9 +45,10 @@ export function VotingCards() {
</VoteFilter>
<FilterList value={sortedBy} setValue={setSortedBy} options={VotingSortingOptions} />
</PageBar>
{roomList.map((room: any) => (
<VotingCard key={room.toString()} room={Number(room.toString())} />
{roomsToShow.map((room: any) => (
<VotingCard key={room.room.toString()} room={room} />
))}
{roomsToShow.length === 0 && <VotingCardSkeleton />}
</div>
)
}

View File

@ -0,0 +1,63 @@
import { useContractCall, useContractCalls } from '@usedapp/core'
import { useEffect, useState } from 'react'
import { getCommunityDetails } from '../helpers/apiMock'
import { DetailedVotingRoom } from '../models/smartContract'
import { useContracts } from './useContracts'
export function useVotingCommunities(filterKeyword: string): DetailedVotingRoom[] {
const [roomsWithCommunity, setRoomsWithCommunity] = useState<any[]>([])
const [roomsToShow, setRoomsToShow] = useState<any[]>([])
const { votingContract } = useContracts()
const [roomList] = useContractCall({
abi: votingContract.interface,
address: votingContract.address,
method: 'getActiveVotingRooms',
args: [],
}) ?? [[]]
const contractCalls = roomList.map((el: any) => {
return {
abi: votingContract.interface,
address: votingContract.address,
method: 'votingRoomMap',
args: [el],
}
})
const votingRooms = useContractCalls(contractCalls)
useEffect(() => {
if (votingRooms.length > 0) {
const getPromises = async () => {
const rooms = await Promise.all(
votingRooms.map(async (el: any, idx) => {
if (el) {
return { ...el, room: roomList[idx].toNumber(), details: await getCommunityDetails(el.community) }
}
return undefined
})
)
setRoomsWithCommunity(rooms)
}
getPromises()
}
}, [JSON.stringify(votingRooms)])
useEffect(() => {
setRoomsToShow(
roomsWithCommunity.filter((room: any) => {
if (room) {
return (
room.details.name.toLowerCase().includes(filterKeyword.toLowerCase()) ||
room.details.description.toLowerCase().includes(filterKeyword.toLowerCase()) ||
room.details.tags.findIndex((item: any) => filterKeyword.toLowerCase() === item.toLowerCase()) > -1
)
}
return false
})
)
}, [roomsWithCommunity, filterKeyword])
return roomsToShow
}

View File

@ -1,4 +1,5 @@
import { BigNumber } from 'ethers'
import { CommunityDetail } from './community'
export type VotingRoom = {
startBlock: BigNumber
@ -9,4 +10,7 @@ export type VotingRoom = {
totalVotesFor: BigNumber
totalVotesAgainst: BigNumber
voters: string[]
room: number
}
export type DetailedVotingRoom = VotingRoom & { details: CommunityDetail }

View File

@ -15,6 +15,7 @@ describe('voting', () => {
totalVotesFor: BigNumber.from(100),
totalVotesAgainst: BigNumber.from(100),
voters: ['0x01', '0x02'],
room: 1,
}
const room = voting.fromRoom(votingRoom)
@ -32,6 +33,7 @@ describe('voting', () => {
totalVotesFor: BigNumber.from(1000),
totalVotesAgainst: BigNumber.from(100),
voters: ['0x01', '0x02'],
room: 1,
}
const room = voting.fromRoom(votingRoom)