Advertisement
Guest User

Untitled

a guest
Oct 15th, 2019
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.98 KB | None | 0 0
  1. import React, { useState, useEffect, useCallback } from 'react'
  2. import { Flex, Text, Image, Box } from 'rebass'
  3. import { Input } from '@rebass/forms'
  4. import { useBlockchainContextState } from 'contexts/Blockchain'
  5. import { useModalContextState } from 'contexts/Modal'
  6. import { useAccountContextState } from 'contexts/Account'
  7. import { PrimaryButton } from 'styles/common'
  8. import { useDebounce } from 'hooks'
  9. import BN from 'utils/bignumber'
  10. import BigNumber from 'bignumber.js'
  11. import Slider from './Slider'
  12. import { isPositiveNumber } from 'utils'
  13.  
  14. export default props => {
  15. const { data } = props
  16. const {
  17. stake: totalStake,
  18. provider,
  19. providerAddress,
  20. tokenLock,
  21. userStake, // userStake = tokenLock + revenue
  22. userOwnership,
  23. totalOwnership,
  24. symbol,
  25. } = data
  26. const { balances } = useAccountContextState()
  27. const [error, setError] = useState('')
  28. const { stake, withdraw } = useBlockchainContextState()
  29. const { hide } = useModalContextState()
  30. const [userBalance, setUserBalance] = useState(new BN(0))
  31. const [newTokenLock, setNewTokenLock] = useState(tokenLock)
  32.  
  33. useEffect(() => {
  34. if (balances[symbol]) {
  35. const userToken = balances[symbol]
  36. setUserBalance(userToken.value)
  37. }
  38. }, [balances[symbol]])
  39.  
  40. const stakeOrWithdraw = () => {
  41. // stake more
  42. // console.log(
  43. // newTokenLock.toString(),
  44. // tokenLock.toString(),
  45. // userBalance.toString(),
  46. // )
  47. if (newTokenLock.gt(tokenLock)) {
  48. console.log('stake')
  49. const stakeAmount = newTokenLock.sub(tokenLock)
  50. stake(providerAddress, stakeAmount)
  51. // add tx right here
  52. } else {
  53. console.log('withdraw')
  54. const withdrawOwnership = tokenLock
  55. .sub(newTokenLock)
  56. .mul(totalOwnership)
  57. .div(totalStake)
  58. withdraw(providerAddress, withdrawOwnership)
  59. // add tx right here
  60. }
  61. hide()
  62. }
  63.  
  64. return (
  65. <Flex
  66. width="100%"
  67. flexDirection="column"
  68. px="25px"
  69. alignItems="center"
  70. fontSize="14px"
  71. fontWeight="bold"
  72. >
  73. <Flex width="100%">
  74. <Box
  75. width="80px"
  76. height="80px"
  77. ml="10px"
  78. mr="20px"
  79. style={{
  80. backgroundImage: `url(${provider.image})`,
  81. backgroundSize: 'contain',
  82. backgroundPosition: 'center',
  83. backgroundRepeat: 'no-repeat',
  84. }}
  85. />
  86. <Flex flexDirection="column" justifyContent="space-between" py="10px">
  87. <Flex fontSize="18px" color="#9ea3bc">
  88. Staking for
  89. </Flex>
  90. <Flex fontSize="36px" color="#232a4d">
  91. {provider.name}
  92. </Flex>
  93. </Flex>
  94. </Flex>
  95.  
  96. <LiveAmountAndSlider
  97. userBalance={userBalance}
  98. defaultStakeAmount={tokenLock}
  99. newTokenLock={newTokenLock}
  100. setNewTokenLock={setNewTokenLock}
  101. error={error}
  102. setError={setError}
  103. symbol={symbol}
  104. />
  105.  
  106. {/* Staking detail */}
  107. <Flex width="100%" mt="10px" justifyContent="space-between">
  108. <Text color="#9ea3bc">Projected APR</Text>
  109. <Text color="#232a4d">30%</Text>
  110. </Flex>
  111.  
  112. <Flex width="100%" mt="10px" justifyContent="space-between">
  113. <Text color="#9ea3bc">Projected daily revenue</Text>
  114. <Text color="#232a4d">
  115. {newTokenLock.percentage(0.072).pretty(4)} {symbol}
  116. </Text>
  117. </Flex>
  118.  
  119. {/* revenue = userStake - tokenLock */}
  120. <Flex width="100%" mt="10px" justifyContent="space-between">
  121. <Text color="#9ea3bc">% of staking poll for the provider</Text>
  122. <Text color="#232a4d">
  123. {newTokenLock
  124. .add(userStake.sub(tokenLock))
  125. .percentageOf(totalStake.add(newTokenLock))}
  126. %
  127. </Text>
  128. </Flex>
  129.  
  130. {/* error message */}
  131. <Flex
  132. mt="8px"
  133. fontSize="14px"
  134. color="red"
  135. alignSelf="flex-start"
  136. alignItems="center"
  137. style={{ height: '18px' }}
  138. >
  139. {error}
  140. </Flex>
  141.  
  142. <PrimaryButton
  143. mt="20px"
  144. style={{ pointerEvents: error ? 'none' : 'auto' }}
  145. bg={error ? 'gray' : ''}
  146. onClick={stakeOrWithdraw}
  147. >
  148. CONFIRM
  149. </PrimaryButton>
  150. </Flex>
  151. )
  152. }
  153.  
  154. const LiveAmountAndSlider = ({
  155. userBalance,
  156. error,
  157. setError,
  158. defaultStakeAmount,
  159. newTokenLock,
  160. setNewTokenLock,
  161. symbol,
  162. }) => {
  163. const [stakeShown, setStakeShown] = useState(
  164. Number(defaultStakeAmount.pretty()),
  165. )
  166. const [inputValue, setInputValue] = useState(Number(stakeShown))
  167. const [isEdit, setIsEdit] = useState(false)
  168. const maxValScale = 100000000
  169.  
  170. const inputValueDebounced = useDebounce(inputValue, 500)
  171.  
  172. console.log('inputValueDebounced', inputValueDebounced)
  173.  
  174. useEffect(() => {
  175. console.log('setNewTokenLock', inputValueDebounced)
  176. setNewTokenLock(BN.parse(inputValueDebounced))
  177. }, [inputValueDebounced])
  178.  
  179. useEffect(() => {
  180. console.log('setInputValue', newTokenLock.toString())
  181. setInputValue(
  182. Number(
  183. Number(newTokenLock.div(new BN('1000000000000000000'))).toFixed(2),
  184. ),
  185. )
  186. }, [newTokenLock.toString()])
  187.  
  188. const handleChange = useCallback(e => setInputValue(e.target.value || 0), [])
  189.  
  190. // update when input value change
  191. useEffect(() => {
  192. console.log('input value change')
  193. if (isEdit) {
  194. if (isPositiveNumber(inputValue)) {
  195. const inputValueBN = BN.parse(inputValue)
  196. // console.log(inputValue, userBalance)
  197. if (inputValueBN.gt(userBalance)) {
  198. setError('Insufficient balance')
  199. } else {
  200. setStakeShown(inputValue)
  201. // setNewTokenLock(inputValueBN)
  202. setError('')
  203. }
  204. } else {
  205. setError('Invalid amount')
  206. }
  207. }
  208. }, [inputValue])
  209.  
  210. // update when slider change immediate
  211. // useEffect(() => {
  212. // setInputValue(Number(stakeShown).toFixed(2))
  213. // }, [stakeShown])
  214.  
  215. return (
  216. <>
  217. <Flex
  218. width="100%"
  219. mt="20px"
  220. alignItems="center"
  221. justifyContent="space-between"
  222. >
  223. <Text color="#9ea3bc">You're staking </Text>
  224. <Flex
  225. style={{ position: 'relative', minHeight: '25px' }}
  226. alignItems="center"
  227. onClick={() => setIsEdit(true)}
  228. >
  229. {!isEdit && (
  230. <Text
  231. color="#9ea3bc"
  232. fontSize="9px"
  233. width="60px"
  234. textAlign="right"
  235. style={{ position: 'absolute', right: 0, top: '-7px' }}
  236. >
  237. Tap to change
  238. </Text>
  239. )}
  240. {isEdit ? (
  241. <Input
  242. width="110px"
  243. textAlign="right"
  244. value={inputValue}
  245. type="number"
  246. bg="white"
  247. mr="4px"
  248. py="2px"
  249. px="2px"
  250. fontSize="14px"
  251. style={{
  252. border: error ? '1px solid red' : '1px solid #ececec',
  253. borderRadius: '4px',
  254. }}
  255. onChange={handleChange}
  256. />
  257. ) : (
  258. <Text color="#232a4d" mr="4px">
  259. {stakeShown.toFixed(2)}
  260. </Text>
  261. )}
  262. <Text color="#232a4d">{symbol}</Text>
  263. </Flex>
  264. </Flex>
  265.  
  266. <Flex width="100%" my="15px">
  267. <Slider
  268. circleColor="#3542e4"
  269. val={
  270. userBalance.eq(new BN(0))
  271. ? 0
  272. : Number(newTokenLock.mul(new BN(maxValScale)).div(userBalance))
  273. }
  274. setVal={val => {
  275. setNewTokenLock(
  276. userBalance.mul(new BN(val)).div(new BN(maxValScale)),
  277. )
  278. }}
  279. setValImmediate={val => {
  280. setStakeShown(Number(userBalance / 1e18 / maxValScale) * val)
  281. }}
  282. maxVal={maxValScale}
  283. />
  284. </Flex>
  285. </>
  286. )
  287. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement