diff --git a/src/components/Card.tsx b/src/components/Card.tsx index 9053b91..dc8889c 100644 --- a/src/components/Card.tsx +++ b/src/components/Card.tsx @@ -152,17 +152,18 @@ export const Card = styled.div` display: flex; align-items: stretch; ` - -const CardInfoBlock = styled.div` +export const CardCommunityWrap = styled.div` width: 50%; margin: 13px 0; - display: flex; - flex-direction: column; - align-items: center; padding: 24px 24px 16px; box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.1); border-radius: 6px 0px 0px 6px; ` +const CardInfoBlock = styled.div` + display: flex; + flex-direction: column; + align-items: center; +` const Community = styled.div` display: flex; diff --git a/src/components/Modal.tsx b/src/components/Modal.tsx index da84ec7..e6706af 100644 --- a/src/components/Modal.tsx +++ b/src/components/Modal.tsx @@ -38,13 +38,14 @@ const PopUpOverlay = styled.div` background-color: rgba(0, 0, 0, 0.4); z-index: 9999; transition: all 0.3s; + overflow: auto; ` const PopUpWindow = styled.div` display: flex; flex-direction: column; max-width: 475px; - margin: 205px auto 0; + margin: 20vh auto 2vh; padding: 24px; background-color: ${Colors.GrayLight}; box-shadow: 0px 6px 12px rgba(0, 0, 0, 0.1); diff --git a/src/components/PageInfo.tsx b/src/components/PageInfo.tsx index 0008d06..aad67b4 100644 --- a/src/components/PageInfo.tsx +++ b/src/components/PageInfo.tsx @@ -15,8 +15,12 @@ export const PageInfo = ({ heading, text }: PageInfoProps) => ( ) -export function ProposeButton() { - return Propose community +interface ProposeButtonProps { + onClick: () => void +} + +export function ProposeButton({ onClick }: ProposeButtonProps) { + return Propose community } export function ConnectButton() { diff --git a/src/components/card/ProposeModal.tsx b/src/components/card/ProposeModal.tsx new file mode 100644 index 0000000..bad9d83 --- /dev/null +++ b/src/components/card/ProposeModal.tsx @@ -0,0 +1,106 @@ +import React from 'react' +import styled from 'styled-components' +import { getCommunityDetails } from '../../helpers/apiMock' +import { ButtonPrimary } from '../Button' +import { CardCommunity } from '../Card' +import { Input } from '../Input' +import { VotePropose } from '../votes/VotePropose' + +interface ProposeModalProps { + availableAmount: number + setShowConfirmModal: (val: boolean) => void + setPublicKey: (publicKey: string) => void + publicKey: string +} + +export function ProposeModal({ availableAmount, setShowConfirmModal, setPublicKey, publicKey }: ProposeModalProps) { + const communityFound = getCommunityDetails(publicKey) + + return ( + + + Community public key + { + setPublicKey(e.currentTarget.value) + }} + > + + + {publicKey && communityFound && ( +
+ + + + +
+ )} + + {!communityFound && ( + + ℹ️ + To propose a community, it must have at least 42 members and have a ENS domain. + + )} + + setShowConfirmModal(true)} + onClick={() => setShowConfirmModal(true)} + > + Confirm vote to add community + +
+ ) +} + +const CommunityProposing = styled.form` + display: flex; + flex-direction: column; + align-items: center; +` + +const CommunityKey = styled(Input)` + width: 100%; + margin-top: 10px; + margin-bottom: 32px; + font-size: 15px; + line-height: 22px; +` +const CommunityKeyLabel = styled.label` + width: 100%; + font-size: 15px; + line-height: 22px; +` + +const VoteProposeWrap = styled.div` + margin-top: 32px; +` + +const ProposingInfo = styled.div` + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + margin-bottom: 32px; + + & > span { + font-size: 24px; + line-height: 32px; + margin-right: 16px; + } +` + +const InfoText = styled.div` + font-size: 12px; + line-height: 16px; + letter-spacing: 0.1px; +` + +const ProposingBtn = styled(ButtonPrimary)` + width: 100%; + padding: 11px 0; +` diff --git a/src/components/card/VoteModal.tsx b/src/components/card/VoteModal.tsx index d841e6e..566caf8 100644 --- a/src/components/card/VoteModal.tsx +++ b/src/components/card/VoteModal.tsx @@ -1,11 +1,9 @@ -import React, { useState } from 'react' +import React from 'react' import styled from 'styled-components' -import { Colors } from '../../constants/styles' import { VoteChart } from '../votes/VoteChart' -import { Input } from '../Input' import { ButtonSecondary } from '../Button' -import { addCommas } from '../../helpers/addCommas' import { CurrentVoting } from '../../models/community' +import { VotePropose } from '../votes/VotePropose' export interface VoteModalProps { vote: CurrentVoting @@ -20,63 +18,10 @@ export interface VoteModalProps { } export function VoteModal({ vote, selectedVote, availableAmount, setShowConfirmModal }: VoteModalProps) { - const [proposingAmount, setProposingAmount] = useState(0) - const [displayAmount, setDisplayAmount] = useState('0 SNT') - - let step = 10 ** (Math.floor(Math.log10(availableAmount)) - 2) - if (availableAmount < 100) { - step = 1 - } - - const sliderChange = (e: React.ChangeEvent) => { - if (Number(e.target.value) == step * Math.floor(availableAmount / step)) { - setProposingAmount(availableAmount) - setDisplayAmount(addCommas(availableAmount) + ' SNT') - } else { - setProposingAmount(Number(e.target.value)) - setDisplayAmount(addCommas(Number(e.target.value)) + ' SNT') - } - } - - const progress = (proposingAmount / availableAmount) * 100 + '%' - return ( - - -

My vote

- Available {addCommas(availableAmount)} SNT -
- { - setProposingAmount(Number(e.currentTarget.value)) - setDisplayAmount(e.currentTarget.value) - }} - onBlur={() => setDisplayAmount(addCommas(proposingAmount) + ' SNT')} - onFocus={() => setDisplayAmount(proposingAmount.toString())} - /> - - - -
- {vote?.type === 'Remove' && Number(proposingAmount) > 2000000 && vote.timeLeft / 3600 > 24 && ( - - ⚠️ - {`Your vote will shorten vote duration! Votes over 2,000,000 SNT for ${selectedVote.noun} of the community shortens the vote duration to 24 hours.`} - - )} + setShowConfirmModal(true)} @@ -91,90 +36,6 @@ const CardProposing = styled.div` align-items: center; ` -const VoteProposing = styled.div` - display: flex; - flex-direction: column; - align-items: center; - width: 100%; -` -const VoteProposingInfo = styled.div` - display: flex; - align-items: center; - justify-content: space-between; - width: 100%; - margin-bottom: 10px; - - & > span { - font-size: 12px; - line-height: 16px; - color: ${Colors.GreyText}; - } -` - -const VoteProposingAmount = styled(Input)` - width: 100%; - margin-bottom: 16px; - font-size: 15px; - line-height: 22px; -` - -const VoteProposingRangeWrap = styled.div` - width: 294px; - margin-bottom: 32px; -` - -const VoteProposingRange = styled.input` - appearance: none; - width: 100%; - height: 4px; - padding: 0; - margin: 10px 0; - border-radius: 2px; - outline: none; - - &::-webkit-slider-thumb { - -webkit-appearance: none; - appearance: none; - width: 20px; - height: 20px; - border-radius: 50%; - background: ${Colors.Violet}; - cursor: pointer; - } - - &::-moz-range-thumb { - width: 20px; - height: 20px; - background: ${Colors.Violet}; - border: 0.5px solid rgba(0, 0, 0, 0); - border-radius: 50px; - cursor: pointer; - } -` - -const VoteWarning = styled.div` - display: flex; - justify-content: space-between; - align-items: center; - width: 100%; - padding: 16px; - background: #ffeff2; - border-radius: 6px; - margin-bottom: 32px; - - & > span { - font-size: 24px; - line-height: 32px; - } -` - -const WarningText = styled.div` - max-width: 353px; - font-size: 12px; - line-height: 16px; - letter-spacing: 0.1px; -` - const VoteConfirmBtn = styled(ButtonSecondary)` width: 100%; padding: 11px 0; diff --git a/src/components/directory/DirectoryCards.tsx b/src/components/directory/DirectoryCards.tsx index 0f100d2..a17eb40 100644 --- a/src/components/directory/DirectoryCards.tsx +++ b/src/components/directory/DirectoryCards.tsx @@ -1,5 +1,5 @@ import React, { useState } from 'react' -import { Card, CardCommunity } from '../Card' +import { Card, CardCommunity, CardCommunityWrap } from '../Card' import { CardFeature } from '../card/CardFeature' import styled from 'styled-components' import { CommunityDetail, DirectorySortingEnum } from '../../models/community' @@ -26,7 +26,10 @@ function DirectoryCard({ community }: DirectoryCardProps) { } return ( - + + {' '} + + ) => { + if (Number(e.target.value) == step * Math.floor(availableAmount / step)) { + setProposingAmount(availableAmount) + setDisplayAmount(addCommas(availableAmount) + ' SNT') + } else { + setProposingAmount(Number(e.target.value)) + setDisplayAmount(addCommas(Number(e.target.value)) + ' SNT') + } + } + + const progress = (proposingAmount / availableAmount) * 100 + '%' + + return ( + + +

My vote

+ Available {addCommas(availableAmount)} SNT +
+ { + setProposingAmount(Number(e.currentTarget.value)) + setDisplayAmount(e.currentTarget.value) + }} + onBlur={() => setDisplayAmount(addCommas(proposingAmount) + ' SNT')} + onFocus={() => setDisplayAmount(proposingAmount.toString())} + /> + + + + + {vote?.type === 'Remove' && Number(proposingAmount) > 2000000 && vote.timeLeft / 3600 > 24 && ( + + ⚠️ + {`Your vote will shorten vote duration! Votes over 2,000,000 SNT for ${selectedVote?.noun} of the community shortens the vote duration to 24 hours.`} + + )} +
+ ) +} + +export const VoteProposing = styled.div` + display: flex; + flex-direction: column; + align-items: center; + width: 100%; +` +const VoteProposingInfo = styled.div` + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + margin-bottom: 10px; + + & > span { + font-size: 12px; + line-height: 16px; + color: ${Colors.GreyText}; + } +` + +const VoteProposingAmount = styled(Input)` + width: 100%; + margin-bottom: 16px; + font-size: 15px; + line-height: 22px; +` + +const VoteProposingRangeWrap = styled.div` + width: 294px; + margin-bottom: 32px; +` + +const VoteProposingRange = styled.input` + appearance: none; + width: 100%; + height: 4px; + padding: 0; + margin: 10px 0; + border-radius: 2px; + outline: none; + + &::-webkit-slider-thumb { + -webkit-appearance: none; + appearance: none; + width: 20px; + height: 20px; + border-radius: 50%; + background: ${Colors.Violet}; + cursor: pointer; + } + + &::-moz-range-thumb { + width: 20px; + height: 20px; + background: ${Colors.Violet}; + border: 0.5px solid rgba(0, 0, 0, 0); + border-radius: 50px; + cursor: pointer; + } +` + +const VoteWarning = styled.div` + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + padding: 16px; + background: #ffeff2; + border-radius: 6px; + margin-bottom: 32px; + + & > span { + font-size: 24px; + line-height: 32px; + } +` + +const WarningText = styled.div` + max-width: 353px; + font-size: 12px; + line-height: 16px; + letter-spacing: 0.1px; +` diff --git a/src/components/votes/VotesInfo.tsx b/src/components/votes/VotesInfo.tsx index 5d5d409..73097fb 100644 --- a/src/components/votes/VotesInfo.tsx +++ b/src/components/votes/VotesInfo.tsx @@ -1,16 +1,60 @@ -import React from 'react' +import React, { useState } from 'react' import { InfoWrap, ConnectButton, ProposeButton, PageInfo } from '../PageInfo' import { useEthers } from '@usedapp/core' +import { Modal } from '../Modal' +import { ProposeModal } from '../card/ProposeModal' +import { VoteConfirmModal } from '../card/VoteConfirmModal' +import { getCommunityDetails } from '../../helpers/apiMock' export function VotesInfo() { const { account } = useEthers() + const [showProposeModal, setShowProposeModal] = useState(false) + const [showConfirmModal, setShowConfirmModal] = useState(false) + const [publicKey, setPublicKey] = useState('') + + const setNext = (val: boolean) => { + setShowConfirmModal(val) + setShowProposeModal(false) + } + + const clearKey = (val: boolean) => { + setShowConfirmModal(val) + setPublicKey('') + } + return ( - {account ? : } + {showProposeModal && ( + { + setShowProposeModal(val) + setPublicKey('') + }} + > + {' '} + + )} + {showConfirmModal && ( + + + + )} + + {account ? setShowProposeModal(true)} /> : } ) } diff --git a/src/components/votes/VotingCards.tsx b/src/components/votes/VotingCards.tsx index c245de6..0d89913 100644 --- a/src/components/votes/VotingCards.tsx +++ b/src/components/votes/VotingCards.tsx @@ -1,5 +1,5 @@ import React, { useState } from 'react' -import { Card, CardCommunity, CardVote } from '../Card' +import { Card, CardCommunity, CardCommunityWrap, CardVote } from '../Card' import { getCommunitiesUnderVote } from '../../helpers/apiMock' import { CommunityDetail, VotingSortingEnum } from '../../models/community' import styled from 'styled-components' @@ -20,7 +20,11 @@ interface VotingCardProps { function VotingCard({ community }: VotingCardProps) { return ( - + + {' '} + + + )