Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import React, { useState, useEffect, useCallback } from 'react'
- import { Flex, Text, Image, Box } from 'rebass'
- import { Input } from '@rebass/forms'
- import { useBlockchainContextState } from 'contexts/Blockchain'
- import { useModalContextState } from 'contexts/Modal'
- import { useAccountContextState } from 'contexts/Account'
- import { PrimaryButton } from 'styles/common'
- import { useDebounce } from 'hooks'
- import BN from 'utils/bignumber'
- import BigNumber from 'bignumber.js'
- import Slider from './Slider'
- import { isPositiveNumber } from 'utils'
- export default props => {
- const { data } = props
- const {
- stake: totalStake,
- provider,
- providerAddress,
- tokenLock,
- userStake, // userStake = tokenLock + revenue
- userOwnership,
- totalOwnership,
- symbol,
- } = data
- const { balances } = useAccountContextState()
- const [error, setError] = useState('')
- const { stake, withdraw } = useBlockchainContextState()
- const { hide } = useModalContextState()
- const [userBalance, setUserBalance] = useState(new BN(0))
- const [newTokenLock, setNewTokenLock] = useState(tokenLock)
- useEffect(() => {
- if (balances[symbol]) {
- const userToken = balances[symbol]
- setUserBalance(userToken.value)
- }
- }, [balances[symbol]])
- const stakeOrWithdraw = () => {
- // stake more
- // console.log(
- // newTokenLock.toString(),
- // tokenLock.toString(),
- // userBalance.toString(),
- // )
- if (newTokenLock.gt(tokenLock)) {
- console.log('stake')
- const stakeAmount = newTokenLock.sub(tokenLock)
- stake(providerAddress, stakeAmount)
- // add tx right here
- } else {
- console.log('withdraw')
- const withdrawOwnership = tokenLock
- .sub(newTokenLock)
- .mul(totalOwnership)
- .div(totalStake)
- withdraw(providerAddress, withdrawOwnership)
- // add tx right here
- }
- hide()
- }
- return (
- <Flex
- width="100%"
- flexDirection="column"
- px="25px"
- alignItems="center"
- fontSize="14px"
- fontWeight="bold"
- >
- <Flex width="100%">
- <Box
- width="80px"
- height="80px"
- ml="10px"
- mr="20px"
- style={{
- backgroundImage: `url(${provider.image})`,
- backgroundSize: 'contain',
- backgroundPosition: 'center',
- backgroundRepeat: 'no-repeat',
- }}
- />
- <Flex flexDirection="column" justifyContent="space-between" py="10px">
- <Flex fontSize="18px" color="#9ea3bc">
- Staking for
- </Flex>
- <Flex fontSize="36px" color="#232a4d">
- {provider.name}
- </Flex>
- </Flex>
- </Flex>
- <LiveAmountAndSlider
- userBalance={userBalance}
- defaultStakeAmount={tokenLock}
- newTokenLock={newTokenLock}
- setNewTokenLock={setNewTokenLock}
- error={error}
- setError={setError}
- symbol={symbol}
- />
- {/* Staking detail */}
- <Flex width="100%" mt="10px" justifyContent="space-between">
- <Text color="#9ea3bc">Projected APR</Text>
- <Text color="#232a4d">30%</Text>
- </Flex>
- <Flex width="100%" mt="10px" justifyContent="space-between">
- <Text color="#9ea3bc">Projected daily revenue</Text>
- <Text color="#232a4d">
- {newTokenLock.percentage(0.072).pretty(4)} {symbol}
- </Text>
- </Flex>
- {/* revenue = userStake - tokenLock */}
- <Flex width="100%" mt="10px" justifyContent="space-between">
- <Text color="#9ea3bc">% of staking poll for the provider</Text>
- <Text color="#232a4d">
- {newTokenLock
- .add(userStake.sub(tokenLock))
- .percentageOf(totalStake.add(newTokenLock))}
- %
- </Text>
- </Flex>
- {/* error message */}
- <Flex
- mt="8px"
- fontSize="14px"
- color="red"
- alignSelf="flex-start"
- alignItems="center"
- style={{ height: '18px' }}
- >
- {error}
- </Flex>
- <PrimaryButton
- mt="20px"
- style={{ pointerEvents: error ? 'none' : 'auto' }}
- bg={error ? 'gray' : ''}
- onClick={stakeOrWithdraw}
- >
- CONFIRM
- </PrimaryButton>
- </Flex>
- )
- }
- const LiveAmountAndSlider = ({
- userBalance,
- error,
- setError,
- defaultStakeAmount,
- newTokenLock,
- setNewTokenLock,
- symbol,
- }) => {
- const [stakeShown, setStakeShown] = useState(
- Number(defaultStakeAmount.pretty()),
- )
- const [inputValue, setInputValue] = useState(Number(stakeShown))
- const [isEdit, setIsEdit] = useState(false)
- const maxValScale = 100000000
- const inputValueDebounced = useDebounce(inputValue, 500)
- console.log('inputValueDebounced', inputValueDebounced)
- useEffect(() => {
- console.log('setNewTokenLock', inputValueDebounced)
- setNewTokenLock(BN.parse(inputValueDebounced))
- }, [inputValueDebounced])
- useEffect(() => {
- console.log('setInputValue', newTokenLock.toString())
- setInputValue(
- Number(
- Number(newTokenLock.div(new BN('1000000000000000000'))).toFixed(2),
- ),
- )
- }, [newTokenLock.toString()])
- const handleChange = useCallback(e => setInputValue(e.target.value || 0), [])
- // update when input value change
- useEffect(() => {
- console.log('input value change')
- if (isEdit) {
- if (isPositiveNumber(inputValue)) {
- const inputValueBN = BN.parse(inputValue)
- // console.log(inputValue, userBalance)
- if (inputValueBN.gt(userBalance)) {
- setError('Insufficient balance')
- } else {
- setStakeShown(inputValue)
- // setNewTokenLock(inputValueBN)
- setError('')
- }
- } else {
- setError('Invalid amount')
- }
- }
- }, [inputValue])
- // update when slider change immediate
- // useEffect(() => {
- // setInputValue(Number(stakeShown).toFixed(2))
- // }, [stakeShown])
- return (
- <>
- <Flex
- width="100%"
- mt="20px"
- alignItems="center"
- justifyContent="space-between"
- >
- <Text color="#9ea3bc">You're staking </Text>
- <Flex
- style={{ position: 'relative', minHeight: '25px' }}
- alignItems="center"
- onClick={() => setIsEdit(true)}
- >
- {!isEdit && (
- <Text
- color="#9ea3bc"
- fontSize="9px"
- width="60px"
- textAlign="right"
- style={{ position: 'absolute', right: 0, top: '-7px' }}
- >
- Tap to change
- </Text>
- )}
- {isEdit ? (
- <Input
- width="110px"
- textAlign="right"
- value={inputValue}
- type="number"
- bg="white"
- mr="4px"
- py="2px"
- px="2px"
- fontSize="14px"
- style={{
- border: error ? '1px solid red' : '1px solid #ececec',
- borderRadius: '4px',
- }}
- onChange={handleChange}
- />
- ) : (
- <Text color="#232a4d" mr="4px">
- {stakeShown.toFixed(2)}
- </Text>
- )}
- <Text color="#232a4d">{symbol}</Text>
- </Flex>
- </Flex>
- <Flex width="100%" my="15px">
- <Slider
- circleColor="#3542e4"
- val={
- userBalance.eq(new BN(0))
- ? 0
- : Number(newTokenLock.mul(new BN(maxValScale)).div(userBalance))
- }
- setVal={val => {
- setNewTokenLock(
- userBalance.mul(new BN(val)).div(new BN(maxValScale)),
- )
- }}
- setValImmediate={val => {
- setStakeShown(Number(userBalance / 1e18 / maxValScale) * val)
- }}
- maxVal={maxValScale}
- />
- </Flex>
- </>
- )
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement