Add empty state (#57)

This commit is contained in:
Maria Rushkova 2021-09-13 10:59:59 +02:00 committed by GitHub
parent 024c9ac1f5
commit 06bfb01ffc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 402 additions and 4 deletions

View File

@ -89,3 +89,24 @@ export const FinalBtn = styled(Btn)`
margin-top: 32px; margin-top: 32px;
} }
` `
export const ProposingBtn = styled(Btn)`
width: 100%;
background-color: #5d7be2;
color: #ffffff;
font-weight: bold;
font-size: 15px;
line-height: 24px;
&:not(:disabled):hover {
background: #0f3595;
}
&:not(:disabled):active {
background: #7e98f4;
}
&:disabled {
background: #888888;
filter: grayscale(1);
}
`

View File

@ -4,7 +4,34 @@ export const Input = styled.input`
max-width: 420px; max-width: 420px;
padding: 11px 20px; padding: 11px 20px;
background: #f0f1f3; background: #f0f1f3;
color: #00000; color: #000;
border-radius: 8px;
border: 1px solid #eef2f5;
outline: none;
&:active,
&:focus {
border: 1px solid #5d7be2;
caret-color: #5d7be2;
}
@media (max-width: 600px) {
max-width: 100%;
}
`
export const TextArea = styled.textarea`
width: 100%;
resize: none;
padding: 11px 20px;
margin-bottom: 32px;
margin-top: 10px;
font-family: Inter;
font-style: normal;
font-size: 15px;
line-height: 22px;
text-align: left;
background: #f0f1f3;
color: #000;
border-radius: 8px; border-radius: 8px;
border: 1px solid #eef2f5; border: 1px solid #eef2f5;
outline: none; outline: none;

View File

@ -3,10 +3,12 @@ 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 { VotingEmpty } from './VotingEmpty'
export function Proposal() { export function Proposal() {
return ( return (
<ProposalWrapper> <ProposalWrapper>
<VotingEmpty theme={blueTheme} />
<ProposalHeader theme={blueTheme} /> <ProposalHeader theme={blueTheme} />
<ProposalList theme={blueTheme} /> <ProposalList theme={blueTheme} />
</ProposalWrapper> </ProposalWrapper>
@ -18,7 +20,7 @@ const ProposalWrapper = styled.div`
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
max-width: 1000px; max-width: 1000px;
position: relative; // position: relative;
margin: 0 auto; margin: 0 auto;
padding: 150px 32px 50px; padding: 150px 32px 50px;
width: 100%; width: 100%;

View File

@ -43,7 +43,7 @@ export const Card = styled.div`
} }
` `
const CardHeading = styled.div` export const CardHeading = styled.div`
font-weight: bold; font-weight: bold;
font-size: 22px; font-size: 22px;
line-height: 24px; line-height: 24px;
@ -55,7 +55,7 @@ const CardHeading = styled.div`
} }
` `
const CardText = styled.div` export const CardText = styled.div`
font-size: 13px; font-size: 13px;
line-height: 18px; line-height: 18px;
margin-bottom: 16px; margin-bottom: 16px;

View File

@ -0,0 +1,125 @@
import React from 'react'
import styled from 'styled-components'
import { ProposingBtn } from './Buttons'
import { TextArea } from './Input'
import { blueTheme } from '@status-waku-voting/react-components/dist/esm/src/style/themes'
interface ProposeModalProps {
availableAmount: number
title: string
text: string
setShowProposeVoteModal: (val: boolean) => void
setTitle: (val: string) => void
setText: (val: string) => void
}
export function ProposeModal({
availableAmount,
title,
text,
setShowProposeVoteModal,
setTitle,
setText,
}: ProposeModalProps) {
const insufficientFunds = availableAmount < 10000
return (
<ProposingData>
{insufficientFunds && (
<ProposingInfo>
<span></span>
<InfoText>You need at least 10,000 ABC to create a proposal!</InfoText>
</ProposingInfo>
)}
<Label>
Title
<ProposingInput
cols={2}
maxLength={90}
placeholder="E.g. Change the rate of the token issuance"
value={title}
onInput={(e) => {
setTitle(e.currentTarget.value)
}}
required
/>
</Label>
<Label>
Description
<ProposingTextInput
maxLength={440}
placeholder="Describe your proposal as detailed as you can in 440 characters."
value={text}
onInput={(e) => {
setText(e.currentTarget.value)
}}
required
/>
</Label>
<ProposingBtn
disabled={!text || !title || insufficientFunds}
theme={blueTheme}
onClick={() => setShowProposeVoteModal(true)}
>
Continue
</ProposingBtn>
</ProposingData>
)
}
export const VoteProposeWrap = styled.div`
margin-top: 32px;
@media (max-width: 600px) {
margin-top: 0;
}
`
export const ProposingData = styled.div`
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
margin-top: 32px;
`
export const ProposingInfo = styled.div`
width: 100%;
display: flex;
justify-content: flex-start;
align-items: center;
padding: 10px 16px;
margin-bottom: 32px;
background: #ffeff2;
@media (max-width: 600px) {
max-width: 525px;
}
& > span {
font-size: 24px;
line-height: 32px;
margin-right: 24px;
}
`
const InfoText = styled.div`
font-size: 12px;
line-height: 16px;
letter-spacing: 0.1px;
`
const ProposingInput = styled(TextArea)`
height: 68px;
`
const ProposingTextInput = styled(ProposingInput)`
height: 222px;
`
const Label = styled.label`
width: 100%;
font-size: 15px;
line-height: 22px;
align-self: flex-start;
`

View File

@ -0,0 +1,60 @@
import React, { useState } from 'react'
import styled from 'styled-components'
import { ProposingBtn } from './Buttons'
import { Card, CardHeading, CardText } from './ProposalInfo'
import { ProposingData } from './ProposeModal'
import { VotePropose } from './VotePropose'
interface ProposeVoteModalProps {
availableAmount: number
title: string
text: string
setShowModal: (val: boolean) => void
setTitle: (val: string) => void
setText: (val: string) => void
}
export function ProposeVoteModal({
availableAmount,
title,
text,
setShowModal,
setTitle,
setText,
}: ProposeVoteModalProps) {
const [proposingAmount, setProposingAmount] = useState(0)
return (
<ProposingData>
<ProposingCardHeading>{title}</ProposingCardHeading>
<ProposingCardText>{text}</ProposingCardText>
<VoteProposeWrap>
<VotePropose
availableAmount={availableAmount}
setProposingAmount={setProposingAmount}
proposingAmount={proposingAmount}
/>
</VoteProposeWrap>
<ProposingBtn
onClick={() => {
setShowModal(false), setTitle(''), setText('')
}}
>
Create proposal
</ProposingBtn>
</ProposingData>
)
}
export const VoteProposeWrap = styled.div`
margin-bottom: 32px;
width: 100%;
`
const ProposingCardHeading = styled(CardHeading)`
margin-bottom: 16px;
`
const ProposingCardText = styled(CardText)`
margin-bottom: 0;
`

View File

@ -0,0 +1,163 @@
import React, { useEffect, useState } from 'react'
import { useEthers } from '@usedapp/core'
import styled from 'styled-components'
import { CreateButton, Modal, Theme } from '@status-waku-voting/react-components'
import { ProposeModal } from './ProposeModal'
import { ProposeVoteModal } from './ProposeVoteModal'
type VotingEmptyProps = {
theme: Theme
}
export function VotingEmpty({ theme }: VotingEmptyProps) {
const { account, activateBrowserWallet } = useEthers()
const [selectConnect, setSelectConnect] = useState(false)
const [showProposeModal, setShowProposeModal] = useState(false)
const [showProposeVoteModal, setShowProposeVoteModal] = useState(false)
const [mobileVersion, setMobileVersion] = useState(false)
const [title, setTitle] = useState('')
const [text, setText] = useState('')
const setNext = (val: boolean) => {
setShowProposeVoteModal(val)
setShowProposeModal(false)
}
useEffect(() => {
const handleResize = () => {
if (window.innerWidth < 600) {
setMobileVersion(true)
} else {
setMobileVersion(false)
}
}
handleResize()
window.addEventListener('resize', handleResize)
return () => window.removeEventListener('resize', handleResize)
}, [])
return (
<VotingEmptyWrap>
<EmptyWrap>
<EmptyHeading>There are no proposals at the moment!</EmptyHeading>
<EmptyText>
Any worthwhile idea going on on your mind? Feel free to smash that button and see find out if the community
likes it!
</EmptyText>
</EmptyWrap>
{showProposeModal && (
<Modal heading="Create proposal" theme={theme} setShowModal={setShowProposeModal}>
<ProposeModal
title={title}
text={text}
setText={setText}
setTitle={setTitle}
availableAmount={6524}
setShowProposeVoteModal={setNext}
/>
</Modal>
)}
{showProposeVoteModal && (
<Modal heading="Create proposal" theme={theme} setShowModal={setShowProposeVoteModal}>
<ProposeVoteModal
title={title}
text={text}
availableAmount={6524}
setShowModal={setShowProposeVoteModal}
setText={setText}
setTitle={setTitle}
/>
</Modal>
)}
{!mobileVersion && (
<div>
{account ? (
<CreateButton theme={theme} onClick={() => setShowProposeModal(true)}>
Create proposal
</CreateButton>
) : (
<CreateButton
theme={theme}
onClick={() => {
if ((window as any).ethereum) {
activateBrowserWallet()
} else setSelectConnect(true)
}}
>
Connect to vote
</CreateButton>
)}
</div>
)}
</VotingEmptyWrap>
)
}
const VotingEmptyWrap = styled.div`
position: absolute;
top: 96px;
left: 50%;
transform: translateX(-50%);
padding: 0 32px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
height: calc(100vh - 96px);
background: #fffff;
z-index: 99;
@media (max-width: 600px) {
height: 250px;
top: 50vh;
padding: 0 16px;
}
`
const EmptyWrap = styled.div`
width: 100%;
max-width: 800px;
display: flex;
flex-direction: column;
align-items: center;
`
const EmptyHeading = styled.h1`
font-weight: bold;
font-size: 28px;
line-height: 38px;
letter-spacing: -0.4px;
margin-bottom: 8px;
text-align: center;
@media (max-width: 600px) {
font-size: 22px;
line-height: 22px;
padding: 0 16px;
}
@media (max-width: 375px) {
font-size: 20px;
}
`
const EmptyText = styled.p`
font-size: 22px;
text-align: center;
line-height: 32px;
margin: 0;
margin-bottom: 24px;
@media (max-width: 600px) {
font-size: 13px;
line-height: 18px;
margin: 0;
padding: 0 16px;
}
@media (max-width: 340px) {
font-size: 12px;
}
`