From a55ea4ed74b34f9a360edeabbfbaa56e4a34383a Mon Sep 17 00:00:00 2001 From: saml33 Date: Thu, 29 Apr 2021 23:51:16 +1000 Subject: [PATCH] fix slider, submit and edit contribution screens --- components/Button.tsx | 42 ++++- components/ConnectWalletButton.tsx | 13 ++ components/ContributionModal.tsx | 275 +++++++++++++++++++---------- components/Input.tsx | 2 +- components/Loading.tsx | 12 +- components/Slider.tsx | 21 ++- 6 files changed, 261 insertions(+), 104 deletions(-) diff --git a/components/Button.tsx b/components/Button.tsx index 2782632..17bde1d 100644 --- a/components/Button.tsx +++ b/components/Button.tsx @@ -1,4 +1,37 @@ import { FunctionComponent } from 'react' +import styled from '@emotion/styled' +import tw from 'twin.macro' + +type StyledButtonProps = { + secondary: boolean +} + +const StyledButton = styled.button` + :before { + ${tw`absolute left-0 top-0 opacity-0 h-full w-full block bg-gradient-to-tl from-secondary-1-light via-secondary-1-dark to-secondary-2-light transition-opacity duration-500`} + border-radius: inherit; + content: ''; + z-index: -10; + } + + :hover { + :before { + ${tw`opacity-100`}; + ${({ disabled, secondary }) => (disabled || secondary) && tw`hidden`} + } + } + + :focus { + ${tw`ring-4 ring-secondary-2-light ring-opacity-40`} + ${({ secondary }) => secondary && tw`ring-0`} + } + + :active { + :before { + ${tw`ring-4 ring-secondary-2-light ring-opacity-40`} + } + } +` interface ButtonProps { onClick?: (x?) => void @@ -16,20 +49,21 @@ const Button: FunctionComponent = ({ ...props }) => { return ( - + ) } diff --git a/components/ConnectWalletButton.tsx b/components/ConnectWalletButton.tsx index a389c55..28419d9 100644 --- a/components/ConnectWalletButton.tsx +++ b/components/ConnectWalletButton.tsx @@ -4,6 +4,7 @@ import { WALLET_PROVIDERS, DEFAULT_PROVIDER } from '../hooks/useWallet' import useLocalStorageState from '../hooks/useLocalStorageState' import WalletSelect from './WalletSelect' import WalletIcon from './WalletIcon' +import Button from './Button' const StyledWalletTypeLabel = styled.div` font-size: 0.6rem; @@ -43,3 +44,15 @@ const ConnectWalletButton = () => { } export default ConnectWalletButton + +export const ConnectWalletButtonSmall = ({ children, onClick }) => ( +
+ +
+
+) diff --git a/components/ContributionModal.tsx b/components/ContributionModal.tsx index b19cbbb..2567d38 100644 --- a/components/ContributionModal.tsx +++ b/components/ContributionModal.tsx @@ -1,24 +1,43 @@ import { useEffect, useState } from 'react' -import { LinkIcon } from '@heroicons/react/solid' +import styled from '@emotion/styled' +import tw from 'twin.macro' +import { + LinkIcon, + LockClosedIcon, + LockOpenIcon, +} from '@heroicons/react/outline' import useWalletStore from '../stores/useWalletStore' import { getUsdcBalance } from '../utils' import Input from './Input' import Button from './Button' +import { ConnectWalletButtonSmall } from './ConnectWalletButton' import Slider from './Slider' import Loading from './Loading' import WalletIcon from './WalletIcon' +const StyledModalWrapper = styled.div` + height: 414px; + ${tw`bg-bkg-2 border border-bkg-3 flex flex-col items-center rounded-lg shadow-lg p-7 w-96`} + } +` + const ContributionModal = () => { const connected = useWalletStore((s) => s.connected) const wallet = useWalletStore((s) => s.current) const usdcBalance = getUsdcBalance() const [contributionAmount, setContributionAmount] = useState(null) + const [sliderPercentage, setSliderPercentage] = useState(null) const [submitting, setSubmitting] = useState(false) + const [submitted, setSubmitted] = useState(false) + const [editContribution, setEditContribution] = useState(false) const [loading, setLoading] = useState(true) const handleConnectDisconnect = () => { if (connected) { + setContributionAmount(null) + setSubmitted(false) + setEditContribution(false) wallet.disconnect() } else { wallet.connect() @@ -27,6 +46,27 @@ const ContributionModal = () => { const handleSetContribution = () => { setSubmitting(true) + setEditContribution(false) + } + + const handleEditContribution = () => { + setEditContribution(true) + setSubmitted(false) + } + + const onChangeAmountInput = (amount) => { + setContributionAmount(amount) + setSliderPercentage((amount / usdcBalance) * 100) + } + + const onChangeSlider = (percentage) => { + setContributionAmount((percentage / 100) * usdcBalance) + setSliderPercentage(percentage) + } + + const handleMax = () => { + setContributionAmount(usdcBalance) + setSliderPercentage(100) } useEffect(() => { @@ -37,107 +77,164 @@ const ContributionModal = () => { }, [usdcBalance]) useEffect(() => { - const submitTimer = setTimeout(() => { - setSubmitting(false) - }, 1000) - return () => clearTimeout(submitTimer) + if (submitting) { + const submitTimer = setTimeout(() => { + setSubmitted(true) + setSubmitting(false) + }, 2000) + return () => clearTimeout(submitTimer) + } }, [submitting]) return ( -
+
-

Plant your seed

-

This is the start of something big.

+ {!submitted && !submitting && !editContribution ? ( + <> +

Plant your seed

+

This is the start of something big.

+ + ) : null} + + {!submitted && submitting ? ( + <> +

Approve the transaction

+

Almost there...

+ + ) : null} + + {submitted && !submitting ? ( + <> +

Your contribution amount

+

A new seed planted...

+ + ) : null} + + {editContribution && !submitting ? ( + <> +

Funds unlocked

+

Increase or reduce your contribution...

+ + ) : null}
-
-
-
-
- - {connected ? ( - loading ? ( -
+ {submitting ? ( +
+ +
+ ) : ( + <> +
+
+
+ + {connected ? ( + loading ? ( +
+ ) : ( + + {usdcBalance} + + ) ) : ( - - {usdcBalance} - - ) - ) : ( - '----' - )} - +
+
+ {submitted ? ( + + ) : null} + +
+
+
+ {submitted ? ( + + ) : null} + {editContribution ? ( + + ) : null} + onChangeAmountInput(e.target.value)} + value={loading ? '' : contributionAmount} + suffix="USDC" />
+
+
+ onChangeSlider(v)} + step={1} + /> +
+ +
+
+ {connected ? ( -
-
- setContributionAmount(e.target.value)} - value={loading ? '' : usdcBalance * (contributionAmount / 100)} - suffix="USDC" - /> -
- setContributionAmount(v)} - step={usdcBalance / 100} - /> -
- -
- {connected ? ( - - ) : ( -
- -
-
+ ) : ( + +
+ + Connect Wallet +
+
+ )} + )} -
+ ) } diff --git a/components/Input.tsx b/components/Input.tsx index 5f0a580..486aec3 100644 --- a/components/Input.tsx +++ b/components/Input.tsx @@ -35,7 +35,7 @@ const Input = ({ className={`${className} font-display px-2 py-2 w-full bg-bkg-1 rounded text-fgd-1 border border-fgd-4 default-transition hover:border-primary-dark focus:border-primary-light focus:outline-none - ${disabled ? 'cursor-not-allowed hover:border-fgd-4' : ''} + ${disabled ? 'cursor-not-allowed hover:border-fgd-4 text-fgd-3' : ''} ${prefix ? 'rounded-l-none' : ''}`} disabled={disabled} {...props} diff --git a/components/Loading.tsx b/components/Loading.tsx index 0a5c1cd..72a7276 100644 --- a/components/Loading.tsx +++ b/components/Loading.tsx @@ -1,7 +1,13 @@ -const Loading = () => { +import { FunctionComponent } from 'react' + +interface LoadingProps { + className?: string +} + +const Loading: FunctionComponent = ({ className }) => { return ( { strokeWidth="4" > diff --git a/components/Slider.tsx b/components/Slider.tsx index 9251cf9..a851b26 100644 --- a/components/Slider.tsx +++ b/components/Slider.tsx @@ -5,7 +5,8 @@ import Slider from 'rc-slider' import 'rc-slider/assets/index.css' type StyledSliderProps = { - enableTransition: boolean + enableTransition?: boolean + disabled?: boolean } const StyledSlider = styled(Slider)` @@ -14,12 +15,10 @@ const StyledSlider = styled(Slider)` } .rc-slider-track { - ${tw`bg-gradient-to-r from-secondary-1-light via-primary-light to-secondary-2-light h-2.5 rounded-full`} + ${tw`bg-gradient-to-r from-secondary-1-dark via-primary-light to-secondary-2-light h-2.5 rounded-full ring-1 ring-primary-light ring-inset`} ${({ enableTransition }) => enableTransition && tw`transition-all duration-500`} - - box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.3); } .rc-slider-step { @@ -29,11 +28,11 @@ const StyledSlider = styled(Slider)` .rc-slider-handle { ${tw`bg-fgd-1 border-4 border-primary-dark h-4 w-4`} - ${({ enableTransition }) => - enableTransition && tw`transition-all duration-500`} - box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.3); margin-top: -3px; + + ${({ enableTransition }) => + enableTransition && tw`transition-all duration-500`} } .rc-slider-mark-text { @@ -52,12 +51,16 @@ const StyledSlider = styled(Slider)` .rc-slider-mark-text:last-of-type { padding-right: 24px; } + + ${({ disabled }) => disabled && 'background-color: transparent'} ` type SliderProps = { onChange: (...args: any[]) => any step: number value: number + disabled: boolean + max?: number } const marks = { @@ -72,12 +75,15 @@ const AmountSlider: FunctionComponent = ({ onChange, step, value, + disabled, + max, }) => { const [enableTransition, setEnableTransition] = useState(true) return ( = ({ enableTransition={enableTransition} onBeforeChange={() => setEnableTransition(false)} onAfterChange={() => setEnableTransition(true)} + disabled={disabled} /> ) }