diff --git a/packages/proposal-components/src/components/Proposal.tsx b/packages/proposal-components/src/components/Proposal.tsx index 0720f90..7e2f6a5 100644 --- a/packages/proposal-components/src/components/Proposal.tsx +++ b/packages/proposal-components/src/components/Proposal.tsx @@ -15,6 +15,7 @@ export function Proposal({ wakuVoting }: ProposalProps) { + {/* */} ) @@ -29,12 +30,4 @@ const ProposalWrapper = styled.div` padding: 150px 32px 50px; width: 100%; min-height: 100vh; - - @media (max-width: 600px) { - padding: 132px 16px 32px; - } - - @media (max-width: 425px) { - padding: 64px 16px 84px; - } ` diff --git a/packages/proposal-components/src/components/ProposalCard.tsx b/packages/proposal-components/src/components/ProposalCard.tsx index 3c2b4cd..70625a6 100644 --- a/packages/proposal-components/src/components/ProposalCard.tsx +++ b/packages/proposal-components/src/components/ProposalCard.tsx @@ -1,10 +1,12 @@ import React from 'react' +import { useHistory } from 'react-router' import styled from 'styled-components' import { Theme } from '@status-waku-voting/react-components' import { ProposalInfo } from './ProposalInfo' import { ProposalVote } from './ProposalVoteCard/ProposalVote' interface ProposalCardProps { + id: number theme: Theme heading: string text: string @@ -14,9 +16,11 @@ interface ProposalCardProps { hideModalFunction?: (val: boolean) => void } -export function ProposalCard({ heading, text, address, vote, voteWinner, theme }: ProposalCardProps) { +export function ProposalCard({ id, heading, text, address, vote, voteWinner, theme }: ProposalCardProps) { + const history = useHistory() + return ( - + history.push(`/votingRoom/${id.toString}`)}> diff --git a/packages/proposal-components/src/components/ProposalHeader.tsx b/packages/proposal-components/src/components/ProposalHeader.tsx index bdcedb5..14f7956 100644 --- a/packages/proposal-components/src/components/ProposalHeader.tsx +++ b/packages/proposal-components/src/components/ProposalHeader.tsx @@ -90,7 +90,7 @@ export function ProposalHeader({ theme, wakuVoting }: ProposalHeaderProps) { ) } -const Wrapper = styled.div` +export const Wrapper = styled.div` display: flex; flex-direction: column; align-items: center; diff --git a/packages/proposal-components/src/components/ProposalInfo.tsx b/packages/proposal-components/src/components/ProposalInfo.tsx index 5d6bfb1..14b8662 100644 --- a/packages/proposal-components/src/components/ProposalInfo.tsx +++ b/packages/proposal-components/src/components/ProposalInfo.tsx @@ -6,14 +6,15 @@ type ProposalInfoProps = { heading: string text: string address: string + mobileMode?: boolean } -export function ProposalInfo({ heading, text, address }: ProposalInfoProps) { +export function ProposalInfo({ heading, text, address, mobileMode }: ProposalInfoProps) { return ( {heading} - {text} - + {text} + @@ -68,10 +69,27 @@ export const CardText = styled.div` -webkit-line-clamp: 3; -webkit-box-orient: vertical; } + + &.mobile { + @media (max-width: 600px) { + height: 100%; + overflow: unset; + text-overflow: unset; + -webkit-line-clamp: unset; + margin-bottom: 24px; + } + } ` const CardViewLink = styled.div` @media (max-width: 768px) { display: none; } + + &.mobile { + @media (max-width: 600px) { + display: block; + margin-bottom: 37px; + } + } ` diff --git a/packages/proposal-components/src/components/ProposalList.tsx b/packages/proposal-components/src/components/ProposalList.tsx index e45836e..1327992 100644 --- a/packages/proposal-components/src/components/ProposalList.tsx +++ b/packages/proposal-components/src/components/ProposalList.tsx @@ -22,7 +22,7 @@ export function ProposalList({ theme, wakuVoting }: ProposalListProps) { return ( {votes.map((vote, idx) => { - return + return })} {votes && votes?.length === 0 && } diff --git a/packages/proposal-components/src/components/ProposeModal.tsx b/packages/proposal-components/src/components/ProposeModal.tsx index b253cc8..7a045d9 100644 --- a/packages/proposal-components/src/components/ProposeModal.tsx +++ b/packages/proposal-components/src/components/ProposeModal.tsx @@ -105,19 +105,19 @@ export const ProposingInfo = styled.div` } ` -const InfoText = styled.div` +export const InfoText = styled.div` font-size: 12px; line-height: 16px; letter-spacing: 0.1px; ` -const ProposingInput = styled(TextArea)` +export const ProposingInput = styled(TextArea)` height: 68px; ` -const ProposingTextInput = styled(ProposingInput)` +export const ProposingTextInput = styled(ProposingInput)` height: 222px; ` -const Label = styled.label` +export const Label = styled.label` width: 100%; font-size: 15px; line-height: 22px; diff --git a/packages/proposal-components/src/components/VoteAnimatedModal.tsx b/packages/proposal-components/src/components/VoteAnimatedModal.tsx index 33c73f9..b39708a 100644 --- a/packages/proposal-components/src/components/VoteAnimatedModal.tsx +++ b/packages/proposal-components/src/components/VoteAnimatedModal.tsx @@ -23,7 +23,6 @@ export function VoteAnimatedModal({ return ( Your vote {selectedVote === 0 ? 'against' : 'for'} this proposal has been cast! - { 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 ( @@ -60,9 +76,14 @@ export function VotingEmpty({ wakuVoting, theme }: VotingEmptyProps) { )} {account ? ( - setShowProposeModal(true)}> + { + mobileVersion ? history.push(`/creation`) : setShowProposeModal(true) + }} + > Create proposal - + ) : ( +
+ Your voice has real power + + Take part in a decentralised governance by voting on proposals provided by community or creating your own. + +
+ {account ? ( + history.push(`/creation`)}> + Create proposal + + ) : ( + { + if ((window as any).ethereum) { + activateBrowserWallet() + } else setSelectConnect(true) + }} + > + Connect to vote + + )} + {selectConnect && ( + + + + )} + + ) +} + +const Header = styled.div` + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + max-width: 680px; + + @media (max-width: 425px) { + position: fixed; + padding: 12px 16px 0; + width: 100%; + background: #f8faff; + } +` + +const Heading = styled.h1` + font-weight: bold; + font-size: 28px; + line-height: 38px; + letter-spacing: -0.4px; + margin: 0; + margin-bottom: 8px; + + @media (max-width: 425px) { + font-size: 22px; + line-height: 30px; + } +` + +const HeaderText = styled.p` + font-size: 22px; + line-height: 32px; + margin: 0; + margin-bottom: 24px; + + @media (max-width: 425px) { + font-size: 13px; + line-height: 18px; + margin-bottom: 16px; + } +` diff --git a/packages/proposal-components/src/components/mobile/ProposalMainMobile.tsx b/packages/proposal-components/src/components/mobile/ProposalMainMobile.tsx new file mode 100644 index 0000000..5e8ff17 --- /dev/null +++ b/packages/proposal-components/src/components/mobile/ProposalMainMobile.tsx @@ -0,0 +1,38 @@ +import React from 'react' +import { blueTheme } from '@status-waku-voting/react-components/dist/esm/src/style/themes' +import { ProposalList } from '../ProposalList' +import { VotingEmpty } from '../VotingEmpty' +import { NotificationItem } from '../NotificationItem' +import { ProposalHeaderMobile } from './ProposalHeaderMobile' +import styled from 'styled-components' +import { WakuVoting } from '@status-waku-voting/core' + +type ProposalMainMobileProps = { + wakuVoting: WakuVoting +} + +export function ProposalMainMobile({ wakuVoting }: ProposalMainMobileProps) { + return ( + + + + {/* */} + + + ) +} + +const ProposalWrapper = styled.div` + display: flex; + flex-direction: column; + align-items: center; + max-width: 1000px; + margin: 0 auto; + width: 100%; + min-height: 100vh; + padding: 132px 16px 32px; + + @media (max-width: 425px) { + padding: 64px 16px 84px; + } +` diff --git a/packages/proposal-components/src/components/mobile/ProposalMobile.tsx b/packages/proposal-components/src/components/mobile/ProposalMobile.tsx new file mode 100644 index 0000000..1c2e821 --- /dev/null +++ b/packages/proposal-components/src/components/mobile/ProposalMobile.tsx @@ -0,0 +1,39 @@ +import React from 'react' +import { Redirect, Route, Switch } from 'react-router' +import { BrowserRouter } from 'react-router-dom' +import styled from 'styled-components' +import { ProposalVoteMobile } from './ProposalVoteMobile' +import { ProposeMobile } from './ProposeMobile' +import { ProposalMainMobile } from './ProposalMainMobile' +import { WakuVoting } from '@status-waku-voting/core' + +type ProposalMobileProps = { + wakuVoting: WakuVoting +} + +export function ProposalMobile({ wakuVoting }: ProposalMobileProps) { + return ( + + + + } /> + + + + + + + + + ) +} + +const ProposalWrapper = styled.div` + display: flex; + flex-direction: column; + align-items: center; + max-width: 1000px; + margin: 0 auto; + width: 100%; + min-height: 100vh; +` diff --git a/packages/proposal-components/src/components/mobile/ProposalVoteMobile.tsx b/packages/proposal-components/src/components/mobile/ProposalVoteMobile.tsx new file mode 100644 index 0000000..2f6dd60 --- /dev/null +++ b/packages/proposal-components/src/components/mobile/ProposalVoteMobile.tsx @@ -0,0 +1,118 @@ +import React, { useState } from 'react' +import { useParams } from 'react-router' +import styled from 'styled-components' +import { useEthers } from '@usedapp/core' +import { FinalBtn, VoteBtnAgainst, VoteBtnFor } from '../Buttons' +import { VoteSubmitButton } from '../ProposalVoteCard/VoteSubmitButton' +import { VoteChart } from '../ProposalVoteCard/VoteChart' +import { ProposalInfo } from '../ProposalInfo' +import { VotePropose } from '../VotePropose' +import { VotesBtns } from '../ProposalVoteCard/ProposalVote' + +interface ProposalVoteMobileProps { + vote?: number + voteWinner?: number + votesFor: number + votesAgainst: number + timeLeft: number + availableAmount: number + heading: string + text: string + address: string +} + +export function ProposalVoteMobile({ + votesFor, + votesAgainst, + timeLeft, + vote, + voteWinner, + address, + heading, + text, + availableAmount, +}: ProposalVoteMobileProps) { + const { id } = useParams<{ id: string }>() + const { account } = useEthers() + const [proposingAmount, setProposingAmount] = useState(0) + const [selectedVoted, setSelectedVoted] = useState(0) + const [mobileVersion, setMobileVersion] = useState(true) + + return ( + + + + + + {!voteWinner && ( + + )} + + + {voteWinner ? ( + Finalize the vote + ) : ( + + { + setSelectedVoted(0) + }} + > + Vote Against + + { + setSelectedVoted(1) + }} + > + Vote For + + + )} + + + + {' '} + + + + ) +} + +export const Card = styled.div` + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; + padding: 88px 16px 32px; +` + +const CardButtons = styled.div` + width: 100%; +` + +const CardVoteBottom = styled.div` + display: flex; + justify-content: center; + align-items: center; + width: 100%; + margin-top: 32px; +` + +const VoteChartWrap = styled.div` + width: 100%; + margin-bottom: 32px; +` diff --git a/packages/proposal-components/src/components/mobile/ProposeMobile.tsx b/packages/proposal-components/src/components/mobile/ProposeMobile.tsx new file mode 100644 index 0000000..1540e08 --- /dev/null +++ b/packages/proposal-components/src/components/mobile/ProposeMobile.tsx @@ -0,0 +1,121 @@ +import { blueTheme } from '@status-waku-voting/react-components/dist/esm/src/style/themes' +import React, { useState } from 'react' +import styled from 'styled-components' +import { useHistory } from 'react-router' +import { ProposingBtn } from '../Buttons' +import { CardHeading, CardText } from '../ProposalInfo' +import { InfoText, Label, ProposingData, ProposingInfo, ProposingInput, ProposingTextInput } from '../ProposeModal' +import { VotePropose } from '../VotePropose' + +interface ProposeVoteModalProps { + availableAmount: number +} + +export function ProposeMobile({ availableAmount }: ProposeVoteModalProps) { + const insufficientFunds = availableAmount < 10000 + const [proposingAmount, setProposingAmount] = useState(0) + const [title, setTitle] = useState('') + const [text, setText] = useState('') + const [customData, setCustomData] = useState(false) + const history = useHistory() + + return ( + + {insufficientFunds && ( + + ⚠️ + You need at least 10,000 ABC to create a proposal! + + )} + Create proposal + + {!customData && ( + + + + + + setCustomData(true)} + > + Continue + + + )} + + {customData && ( + + {title} + {text} + + + + + + { + history.push(`/proposal`), setTitle(''), setText('') + }} + > + Create proposal + + + )} + + ) +} + +const ProposingDataMobile = styled(ProposingData)` + padding: 88px 16px 32px; + margin-top: 0; +` +export const VoteProposeWrap = styled.div` + margin-bottom: 32px; + width: 100%; +` + +const ProposingCustomData = styled.div` + width: 100%; +` + +const ProposingCardHeading = styled(CardHeading)` + margin-bottom: 16px; +` +const CustomProposingHeading = styled(ProposingCardHeading)` + font-size: 22px; + margin-top: 24px; +` + +const ProposingCardText = styled(CardText)` + margin-bottom: 0; +` diff --git a/packages/proposal-components/src/index.ts b/packages/proposal-components/src/index.ts index 403ec99..51233bd 100644 --- a/packages/proposal-components/src/index.ts +++ b/packages/proposal-components/src/index.ts @@ -1,3 +1,4 @@ import { Proposal } from './components/Proposal' +import { ProposalMobile } from './components/mobile/ProposalMobile' -export { Proposal } +export { Proposal, ProposalMobile } diff --git a/packages/proposal-page/src/index.tsx b/packages/proposal-page/src/index.tsx index 5a2bf9b..1d3bd43 100644 --- a/packages/proposal-page/src/index.tsx +++ b/packages/proposal-page/src/index.tsx @@ -1,6 +1,6 @@ -import React from 'react' +import React, { useEffect, useState } from 'react' import { useWakuProposal } from '@status-waku-voting/proposal-hooks' -import { Proposal } from '@status-waku-voting/proposal-components' +import { Proposal, ProposalMobile } from '@status-waku-voting/proposal-components' import { TopBar, GlobalStyle } from '@status-waku-voting/react-components' import votingIcon from './assets/images/voting.svg' import styled from 'styled-components' @@ -27,6 +27,20 @@ const config = { function Proposals() { const { account, library, activateBrowserWallet, deactivate } = useEthers() const waku = useWakuProposal() + const [mobileVersion, setMobileVersion] = useState(false) + + useEffect(() => { + const handleResize = () => { + if (window.innerWidth < 600) { + setMobileVersion(true) + } else { + setMobileVersion(false) + } + } + handleResize() + window.addEventListener('resize', handleResize) + return () => window.removeEventListener('resize', handleResize) + }, []) return ( @@ -38,7 +52,7 @@ function Proposals() { account={account} deactivate={deactivate} /> - {waku && } + {waku && (mobileVersion ? : )} ) }