Fix styling (#20)

This commit is contained in:
Szymon Szlachtowicz 2021-08-23 15:28:22 +02:00 committed by GitHub
parent bdf845943e
commit 7564d142ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 199 additions and 103 deletions

View File

@ -139,8 +139,8 @@ class WakuVoting {
let updated = false let updated = false
if (!this.asyncUpdating) { if (!this.asyncUpdating) {
this.asyncUpdating = true this.asyncUpdating = true
const { polls, updatedPolls } = await this.getTimedPolls() const { updatedPolls } = await this.getTimedPolls()
const { votes, updatedVotes } = await this.getTimedPollsVotes() const { updatedVotes } = await this.getTimedPollsVotes()
updated = updatedPolls || updatedVotes updated = updatedPolls || updatedVotes
this.asyncUpdating = false this.asyncUpdating = false
} }

View File

@ -1,9 +1,9 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" />
<link rel="icon" href="/favicon.ico" /> <link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0,minimum-scale=1" />
<link rel="icon" type="image/svg+xml" sizes="any" href="/favicon.ico" /> <link rel="icon" type="image/svg+xml" sizes="any" href="/favicon.ico" />
<title>waku voting example</title> <title>waku voting example</title>
</head> </head>

View File

@ -1,10 +1,28 @@
import React from 'react' import React from 'react'
import ReactDOM from 'react-dom' import ReactDOM from 'react-dom'
import { WakuPolling } from '@status-waku-voting/react-components' import { WakuPolling } from '@status-waku-voting/react-components'
import styled, { createGlobalStyle } from 'styled-components'
export const GlobalStyle = createGlobalStyle`
* {
box-sizing: border-box;
}
body, html, #root {
margin: 0;
width: 100%;
height: 100%;
}
`
const Page = styled.div`
height: 100%;
`
ReactDOM.render( ReactDOM.render(
<div> <Page>
<GlobalStyle />
<WakuPolling appName={'testApp_'} /> <WakuPolling appName={'testApp_'} />
</div>, </Page>,
document.getElementById('root') document.getElementById('root')
) )

View File

@ -5,7 +5,6 @@ import React, { useEffect, useState } from 'react'
import { JsonRpcSigner } from '@ethersproject/providers' import { JsonRpcSigner } from '@ethersproject/providers'
import { PollType } from '@status-waku-voting/core/dist/esm/src/types/PollType' import { PollType } from '@status-waku-voting/core/dist/esm/src/types/PollType'
import styled from 'styled-components' import styled from 'styled-components'
import checkIcon from '../assets/svg/checkIcon.svg'
import { RadioGroup } from '../components/radioGroup' import { RadioGroup } from '../components/radioGroup'
import { SmallButton } from '../components/misc/Buttons' import { SmallButton } from '../components/misc/Buttons'
import { PollResults } from './PollResults' import { PollResults } from './PollResults'
@ -20,21 +19,22 @@ export function Poll({ poll, wakuVoting, signer }: PollProps) {
const [selectedAnswer, setSelectedAnswer] = useState<number | undefined>(undefined) const [selectedAnswer, setSelectedAnswer] = useState<number | undefined>(undefined)
const [tokenAmount, setTokenAmount] = useState(0) const [tokenAmount, setTokenAmount] = useState(0)
const [address, setAddress] = useState('') const [address, setAddress] = useState('')
const [userInVoters, setUserInVoters] = useState(false) const [userInVoters, setUserInVoters] = useState(-1)
useEffect(() => { useEffect(() => {
signer.getAddress().then((e) => setAddress(e)) signer.getAddress().then((e) => setAddress(e))
}, [signer]) }, [signer])
useEffect(() => { useEffect(() => {
setUserInVoters(!!poll.votesMessages.find((vote) => vote.voter === address)) const msg = poll.votesMessages.find((vote) => vote.voter === address)
setUserInVoters(msg?.answer ?? -1)
}, [poll, address]) }, [poll, address])
return ( return (
<PollWrapper> <PollWrapper>
<PollTitle>{poll.poll.question}</PollTitle> <PollTitle>{poll.poll.question}</PollTitle>
<PollAnswersWrapper> <PollAnswersWrapper>
{!userInVoters && ( {userInVoters < 0 && (
<VotingWrapper> <VotingWrapper>
<RadioGroup <RadioGroup
options={poll.poll.answers} options={poll.poll.answers}
@ -53,9 +53,9 @@ export function Poll({ poll, wakuVoting, signer }: PollProps) {
)} )}
</VotingWrapper> </VotingWrapper>
)} )}
{userInVoters && <PollResults poll={poll} />} {userInVoters > -1 && <PollResults poll={poll} selectedVote={userInVoters} />}
</PollAnswersWrapper> </PollAnswersWrapper>
{!userInVoters && ( {userInVoters < 0 && (
<SmallButton <SmallButton
onClick={() => { onClick={() => {
if (wakuVoting) { if (wakuVoting) {

View File

@ -4,6 +4,9 @@ import { JsonRpcSigner } from '@ethersproject/providers'
import styled from 'styled-components' import styled from 'styled-components'
import { PollType } from '@status-waku-voting/core/dist/esm/src/types/PollType' import { PollType } 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 { Input } from '../components/Input'
import addIcon from '../assets/svg/addIcon.svg'
import { SmallButton } from '../components/misc/Buttons'
function getLocaleIsoTime(dateTime: Date) { function getLocaleIsoTime(dateTime: Date) {
const MS_PER_MINUTE = 60000 const MS_PER_MINUTE = 60000
@ -19,122 +22,123 @@ type PollCreationProps = {
} }
export function PollCreation({ signer, wakuVoting, setShowPollCreation }: PollCreationProps) { export function PollCreation({ signer, wakuVoting, setShowPollCreation }: PollCreationProps) {
const [answers, setAnswers] = useState<string[]>(['']) const [answers, setAnswers] = useState<string[]>(['', ''])
const [question, setQuestion] = useState('') const [question, setQuestion] = useState('')
const [selectedType, setSelectedType] = useState(PollType.WEIGHTED) const [selectedType, setSelectedType] = useState(PollType.NON_WEIGHTED)
const [endTimePicker, setEndTimePicker] = useState(new Date(new Date().getTime() + 10000000)) const [endTimePicker, setEndTimePicker] = useState(new Date(new Date().getTime() + 10000000))
return ( return (
<NewPollBoxWrapper onClick={(e) => e.stopPropagation()}> <NewPollBoxWrapper onClick={(e) => e.stopPropagation()}>
<NewPollBox> <BoxWrapper>
<NewPollBoxTitle> <NewPollBox>
Question <NewPollBoxTitle>
<CloseNewPollBoxButton onClick={() => setShowPollCreation(false)}>X</CloseNewPollBoxButton> Create a poll
</NewPollBoxTitle> <CloseNewPollBoxButton onClick={() => setShowPollCreation(false)}>X</CloseNewPollBoxButton>
<input value={question} onChange={(e) => setQuestion(e.target.value)} /> </NewPollBoxTitle>
Poll end time <Input
<input label={'Question or title of the poll'}
type="datetime-local" placeholder={'E.g. What is your favourite color?'}
value={getLocaleIsoTime(endTimePicker)} value={question}
onChange={(e) => setEndTimePicker(new Date(e.target.value))} onChange={(e) => setQuestion(e.target.value)}
/> />
Answers
<button onClick={() => setAnswers((answers) => [...answers, ''])}>Add answer</button> <AnswersWraper>
{answers.map((answer, idx) => ( {answers.map((answer, idx) => (
<AnswerWraper key={idx}> <Input
<AnswerInput key={idx}
value={answer} label={`Option ${idx + 1}`}
onChange={(e) => value={answer}
setAnswers((answers) => { onChange={(e) =>
const newAnswers = [...answers] setAnswers((answers) => {
newAnswers[idx] = e.target.value const newAnswers = [...answers]
return newAnswers newAnswers[idx] = e.target.value
}) return newAnswers
} })
/> }
<RemoveAnswerButton />
onClick={() => ))}
setAnswers((answers) => { </AnswersWraper>
const newAnswers = [...answers] <NewOptionButton onClick={() => setAnswers((answers) => [...answers, ''])}>
if (newAnswers.length > 1) { Add another option
newAnswers.splice(idx, 1) <AddIcon />
} </NewOptionButton>
return newAnswers <SmallButton
}) onClick={async () => {
} await wakuVoting?.createTimedPoll(
> signer,
- question,
</RemoveAnswerButton> answers,
</AnswerWraper> selectedType,
))} undefined,
<div onChange={(e) => setSelectedType(Number.parseInt((e.target as any).value))}> endTimePicker.getTime()
<input type="radio" value={PollType.WEIGHTED} name="newPollType" /> Weighted )
<input type="radio" value={PollType.NON_WEIGHTED} name="newPollType" /> Non weighted setShowPollCreation(false)
</div> }}
<SendButton >
onClick={async () => { Send
await wakuVoting?.createTimedPoll( </SmallButton>
signer, </NewPollBox>
question, </BoxWrapper>
answers,
selectedType,
undefined,
endTimePicker.getTime()
)
setAnswers([''])
setShowPollCreation(false)
}}
>
Send
</SendButton>
</NewPollBox>
</NewPollBoxWrapper> </NewPollBoxWrapper>
) )
} }
const AddIcon = styled.div`
width: 20px;
height: 20px;
background-image: url(${addIcon});
margin-left: 10px;
`
const CloseNewPollBoxButton = styled.div` const CloseNewPollBoxButton = styled.div`
width: 5px; width: 5px;
margin-right: 5px; margin-right: 5px;
margin-left: auto; margin-left: auto;
font-weight: bold; font-weight: bold;
color: red;
` `
const NewPollBoxTitle = styled.div` const NewPollBoxTitle = styled.div`
display: flex; display: flex;
font-style: normal;
font-weight: bold;
font-size: 17px;
line-height: 24px;
` `
const AnswerInput = styled.input` const NewOptionButton = styled.div`
margin-right: 5px; margin-top: 33px;
width: 200px; margin-bottom: 33px;
`
const RemoveAnswerButton = styled.button`
margin-right: 5px;
margin-left: auto; margin-left: auto;
` margin-right: auto;
const SendButton = styled.button`
margin: 10px;
`
const AnswerWraper = styled.div`
display: flex; display: flex;
margin: 5px; font-family: 'Inter, sans-serif';
width: 250px; font-style: normal;
font-weight: normal;
font-size: 15px;
line-height: 22px;
`
const AnswersWraper = styled.div`
margin-left: 64px;
margin-right: 64px;
` `
const NewPollBox = styled.div` const NewPollBox = styled.div`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
background-color: white; background-color: white;
margin: 20px;
padding: 20px; padding: 20px;
box-shadow: 10px 10px 31px -2px #a3a1a1; box-shadow: 10px 10px 31px -2px #a3a1a1;
border-radius: 5px; border-radius: 5px;
overflow: auto; overflow: auto;
z-index: 1; z-index: 5;
width: 300px; width: 468px;
height: 300px; `
const BoxWrapper = styled.div`
position: absolute; position: absolute;
marign-bottom: 100px;
left: 0px; left: 0px;
top: 0px; top: 0px;
` `

View File

@ -2,12 +2,14 @@ import React from 'react'
import { DetailedTimedPoll } from '@status-waku-voting/core/dist/esm/src/models/DetailedTimedPoll' import { DetailedTimedPoll } from '@status-waku-voting/core/dist/esm/src/models/DetailedTimedPoll'
import styled from 'styled-components' import styled from 'styled-components'
import { colorRouletteGenerator } from '../style/colors' import { colorRouletteGenerator } from '../style/colors'
import checkCircle from '../assets/svg/checkCircle.svg'
type PollResultsProps = { type PollResultsProps = {
poll: DetailedTimedPoll poll: DetailedTimedPoll
selectedVote: number
} }
export function PollResults({ poll }: PollResultsProps) { export function PollResults({ poll, selectedVote }: PollResultsProps) {
const colors = colorRouletteGenerator() const colors = colorRouletteGenerator()
return ( return (
<Wrapper> <Wrapper>
@ -21,6 +23,7 @@ export function PollResults({ poll }: PollResultsProps) {
<ColorBar style={{ backgroundColor: colors.next().value ?? '', width: `${percentage}%` }} /> <ColorBar style={{ backgroundColor: colors.next().value ?? '', width: `${percentage}%` }} />
<Transparent> <Transparent>
<PollAnswerText>{answer.text}</PollAnswerText> <PollAnswerText>{answer.text}</PollAnswerText>
{selectedVote === idx && <CheckCircle />}
<VoteCount>{`${percentage}%`}</VoteCount> <VoteCount>{`${percentage}%`}</VoteCount>
</Transparent> </Transparent>
</PollAnswer> </PollAnswer>
@ -35,6 +38,15 @@ export function PollResults({ poll }: PollResultsProps) {
) )
} }
const CheckCircle = styled.div`
width: 14px;
height: 14px;
margin-top: auto;
margin-bottom: auto;
margin-left: 8px;
background-image: url(${checkCircle});
`
const Transparent = styled.div` const Transparent = styled.div`
width: 100%; width: 100%;
height: 100%; height: 100%;
@ -63,26 +75,40 @@ const ResultInfoWrapper = styled.div`
margin-right: auto; margin-right: auto;
margin-bottom: 32px; margin-bottom: 32px;
margin-top: 32px; margin-top: 32px;
font-style: normal;
font-weight: normal;
font-size: 15px; font-size: 15px;
line-height: 22px;
text-align: center; text-align: center;
` `
const VoteCount = styled.div` const VoteCount = styled.div`
margin-left: auto; margin-left: auto;
margin-top: auto;
margin-bottom: auto;
font-weight: 400; font-weight: 400;
font-size: 12px; font-size: 16px;
line-height: 16px;
font-family: 'Inter, sans-serif'; font-family: 'Inter, sans-serif';
` `
const PollAnswer = styled.div` const PollAnswer = styled.div`
display: flex; display: flex;
margin-bottom: 8px; margin-bottom: 16px;
height: 40px;
position: relative; position: relative;
font-family: 'Inter, sans-serif'; font-family: 'Inter, sans-serif';
` `
const PollAnswerText = styled.div` const PollAnswerText = styled.div`
width: 200px; height: 100%;
font-weight: 700; margin-top: 12px;
font-size: 10px; margin-bottom: 12px;
margin-left: 8px;
font-weight: 500;
font-size: 16px;
line-height: 16px;
align-items: center;
letter-spacing: 1.5px;
text-transform: uppercase;
` `

View File

@ -55,7 +55,7 @@ const Wrapper = styled.div`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: auto; overflow: auto;
min-height: 500px; height: 100%;
` `
export default WakuPolling export default WakuPolling

View File

@ -0,0 +1,4 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10 5.25C10.4142 5.25 10.75 5.58579 10.75 6V8.75C10.75 9.02614 10.9739 9.25 11.25 9.25H14C14.4142 9.25 14.75 9.58579 14.75 10C14.75 10.4142 14.4142 10.75 14 10.75H11.25C10.9739 10.75 10.75 10.9739 10.75 11.25V14C10.75 14.4142 10.4142 14.75 10 14.75C9.58579 14.75 9.25 14.4142 9.25 14V11.25C9.25 10.9739 9.02614 10.75 8.75 10.75H6C5.58579 10.75 5.25 10.4142 5.25 10C5.25 9.58579 5.58579 9.25 6 9.25H8.75C9.02614 9.25 9.25 9.02614 9.25 8.75V6C9.25 5.58579 9.58579 5.25 10 5.25Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M10 20C15.5228 20 20 15.5228 20 10C20 4.47715 15.5228 -2.41411e-07 10 0C4.47715 2.41411e-07 -2.41411e-07 4.47715 0 10C2.41411e-07 15.5228 4.47715 20 10 20ZM10 18.5C14.6944 18.5 18.5 14.6944 18.5 10C18.5 5.30558 14.6944 1.5 10 1.5C5.30558 1.5 1.5 5.30558 1.5 10C1.5 14.6944 5.30558 18.5 10 18.5Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 964 B

View File

@ -0,0 +1,3 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5 7L6.33333 8.33333L9 5.66667M13 7C13 7.78793 12.8448 8.56815 12.5433 9.2961C12.2417 10.0241 11.7998 10.6855 11.2426 11.2426C10.6855 11.7998 10.0241 12.2417 9.2961 12.5433C8.56815 12.8448 7.78793 13 7 13C6.21207 13 5.43185 12.8448 4.7039 12.5433C3.97595 12.2417 3.31451 11.7998 2.75736 11.2426C2.20021 10.6855 1.75825 10.0241 1.45672 9.2961C1.15519 8.56815 1 7.78793 1 7C1 5.4087 1.63214 3.88258 2.75736 2.75736C3.88258 1.63214 5.4087 1 7 1C8.5913 1 10.1174 1.63214 11.2426 2.75736C12.3679 3.88258 13 5.4087 13 7Z" stroke="#374151" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 713 B

View File

@ -0,0 +1,41 @@
import React from 'react'
import styled from 'styled-components'
type InputProps = {
label: string
value: string
onChange: (e: any) => void
placeholder?: string
}
export function Input({ label, value, onChange, placeholder }: InputProps) {
return (
<InputWrapper>
<LabelWrapper>{label}</LabelWrapper>
<StyledInput value={value} onChange={onChange} placeholder={placeholder} />
</InputWrapper>
)
}
const StyledInput = styled.input`
background-color: #eef2f5;
border-radius: 8px;
border: 0px;
height: 44px;
padding-left: 20px;
font-weight: 400px;
font-size: 15px;
font-family: 'Inter, sans-serif';
`
const LabelWrapper = styled.div`
font-weight: 400px;
font-size: 15px;
font-family: 'Inter, sans-serif';
margin-bottom: 10px;
`
const InputWrapper = styled.div`
display: flex;
flex-direction: column;
margin-top: 32px;
`