home done
This commit is contained in:
parent
b473d7ad4f
commit
de2a297399
78
README.md
78
README.md
|
@ -1,68 +1,46 @@
|
|||
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
|
||||
# COINCH
|
||||
|
||||
## Available Scripts
|
||||
The name is meaningless ??
|
||||
|
||||
In the project directory, you can run:
|
||||
## Dependencies
|
||||
|
||||
### `npm start`
|
||||
see `package.json`
|
||||
|
||||
Runs the app in the development mode.<br />
|
||||
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
|
||||
## What
|
||||
|
||||
The page will reload if you make edits.<br />
|
||||
You will also see any lint errors in the console.
|
||||
Frontend project (H5 cross platfrom) for CoinWind.
|
||||
|
||||
### `npm test`
|
||||
## Mobile
|
||||
|
||||
Launches the test runner in the interactive watch mode.<br />
|
||||
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
|
||||
Webview is recommended, always, if possible.
|
||||
|
||||
### `npm run build`
|
||||
## Debug
|
||||
|
||||
Builds the app for production to the `build` folder.<br />
|
||||
It correctly bundles React in production mode and optimizes the build for the best performance.
|
||||
```shell
|
||||
$ npm i
|
||||
$ npm start
|
||||
```
|
||||
|
||||
The build is minified and the filenames include the hashes.<br />
|
||||
Your app is ready to be deployed!
|
||||
## Build
|
||||
|
||||
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
|
||||
``` shell
|
||||
$ npm i
|
||||
$ npm run build
|
||||
```
|
||||
|
||||
### `npm run eject`
|
||||
see directory `build`
|
||||
|
||||
**Note: this is a one-way operation. Once you `eject`, you can’t go back!**
|
||||
Run it in-place:
|
||||
|
||||
If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
|
||||
```shell
|
||||
npm i serve -g
|
||||
serve -s build
|
||||
```
|
||||
|
||||
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
|
||||
## Bug report
|
||||
|
||||
You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
|
||||
`john@mx.com`
|
||||
|
||||
## Learn More
|
||||
## Pull request
|
||||
|
||||
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
|
||||
|
||||
To learn React, check out the [React documentation](https://reactjs.org/).
|
||||
|
||||
### Code Splitting
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting
|
||||
|
||||
### Analyzing the Bundle Size
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size
|
||||
|
||||
### Making a Progressive Web App
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app
|
||||
|
||||
### Advanced Configuration
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration
|
||||
|
||||
### Deployment
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/deployment
|
||||
|
||||
### `npm run build` fails to minify
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify
|
||||
Unsupported for now(2022-03-18 UTC).
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
const webpack = require('webpack');
|
||||
|
||||
module.exports = function override(config) {
|
||||
const fallback = config.resolve.fallback || {};
|
||||
Object.assign(fallback, {
|
||||
"crypto": require.resolve("crypto-browserify"),
|
||||
"stream": require.resolve("stream-browserify"),
|
||||
"assert": require.resolve("assert"),
|
||||
"http": require.resolve("stream-http"),
|
||||
"https": require.resolve("https-browserify"),
|
||||
"os": require.resolve("os-browserify"),
|
||||
"url": require.resolve("url")
|
||||
})
|
||||
config.resolve.fallback = fallback;
|
||||
config.plugins = (config.plugins || []).concat([
|
||||
new webpack.ProvidePlugin({
|
||||
process: 'process/browser',
|
||||
Buffer: ['buffer', 'Buffer']
|
||||
})
|
||||
])
|
||||
config.ignoreWarnings = [/Failed to parse source map/];
|
||||
return config;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
29
package.json
29
package.json
|
@ -3,20 +3,35 @@
|
|||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@chakra-ui/icons": "^1.1.7",
|
||||
"@chakra-ui/react": "^1.8.8",
|
||||
"@coinbase/wallet-sdk": "^3.0.11",
|
||||
"@emotion/react": "^11.9.0",
|
||||
"@emotion/styled": "^11.8.1",
|
||||
"@testing-library/jest-dom": "^5.16.4",
|
||||
"@testing-library/react": "^10.4.9",
|
||||
"@testing-library/user-event": "^12.8.3",
|
||||
"@walletconnect/web3-provider": "^1.7.8",
|
||||
"axios": "^0.27.2",
|
||||
"framer-motion": "^4.1.17",
|
||||
"react": "^18.1.0",
|
||||
"react-dom": "^18.1.0",
|
||||
"react-icons": "^3.11.0",
|
||||
"react-router-dom": "^6.3.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"web-vitals": "^0.2.4"
|
||||
"react-slick": "^0.29.0",
|
||||
"slick-carousel": "^1.8.1",
|
||||
"web-vitals": "^0.2.4",
|
||||
"web3": "^1.7.3",
|
||||
"web3modal": "^1.9.7"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-app-rewired start",
|
||||
"build": "react-app-rewired build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"scriptsxxx": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
|
@ -36,5 +51,17 @@
|
|||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"assert": "^2.0.0",
|
||||
"buffer": "^6.0.3",
|
||||
"crypto-browserify": "^3.12.0",
|
||||
"https-browserify": "^1.0.0",
|
||||
"os-browserify": "^0.3.0",
|
||||
"process": "^0.11.10",
|
||||
"react-app-rewired": "^2.2.1",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"stream-http": "^3.2.0",
|
||||
"url": "^0.11.0"
|
||||
}
|
||||
}
|
||||
|
|
41
src/App.js
41
src/App.js
|
@ -8,17 +8,46 @@ import {
|
|||
Code,
|
||||
Grid,
|
||||
theme,
|
||||
Button,
|
||||
} from '@chakra-ui/react';
|
||||
import { ColorModeSwitcher } from './ColorModeSwitcher';
|
||||
import { Logo } from './Logo';
|
||||
import { PhoneIcon } from '@chakra-ui/icons';
|
||||
import { connectWallet } from './lib/eth'
|
||||
import { Layout } from './components/Layout';
|
||||
import { Outlet } from 'react-router-dom'
|
||||
import { Home } from './pages'
|
||||
import { AppContextProvider } from './AppContext';
|
||||
|
||||
|
||||
|
||||
function App() {
|
||||
|
||||
const onConnect = () => {
|
||||
connectWallet()
|
||||
}
|
||||
|
||||
return (
|
||||
<AppContextProvider>
|
||||
<ChakraProvider theme={theme}>
|
||||
<Box textAlign="center" fontSize="xl">
|
||||
<Layout>
|
||||
<Outlet />
|
||||
</Layout>
|
||||
</ChakraProvider>
|
||||
</AppContextProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
||||
{/* <Box textAlign="center" fontSize="xl">
|
||||
<Grid minH="100vh" p={3}>
|
||||
<ColorModeSwitcher justifySelf="flex-end" />
|
||||
<VStack spacing={8}>
|
||||
<PhoneIcon />
|
||||
<Text>
|
||||
{process.env.NODE_ENV}
|
||||
</Text>
|
||||
<Logo h="40vmin" pointerEvents="none" />
|
||||
<Text>
|
||||
Edit <Code fontSize="xl">src/App.js</Code> and save to reload.
|
||||
|
@ -32,11 +61,9 @@ function App() {
|
|||
>
|
||||
Learn Chakra
|
||||
</Link>
|
||||
<Button colorScheme='teal' onClick={onConnect}>
|
||||
Connect
|
||||
</Button>
|
||||
</VStack>
|
||||
</Grid>
|
||||
</Box>
|
||||
</ChakraProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
</Box> */}
|
|
@ -0,0 +1,86 @@
|
|||
import { useSafeLayoutEffect } from "@chakra-ui/react"
|
||||
import axios from "axios"
|
||||
import { config } from "./config"
|
||||
import React from "react"
|
||||
import { get_settings } from './api'
|
||||
import { ImTwitter, ImTelegram, ImFacebook } from "react-icons/im";
|
||||
|
||||
const AppContext = React.createContext(null)
|
||||
|
||||
export const useApp = () => {
|
||||
return React.useContext(AppContext)
|
||||
}
|
||||
|
||||
let SOCIALS = [
|
||||
{ name: 'telegram', icon: ImTelegram, path: 'https://telegram.org' },
|
||||
{ name: 'twitter', icon: ImTwitter, path: 'https://twitter.com' },
|
||||
{ name: 'facebook', icon: ImFacebook, path: 'https://facebook.com' },
|
||||
]
|
||||
|
||||
export const AppContextProvider = ({ children }) => {
|
||||
const [address, setAddress] = React.useState('')
|
||||
// from settings
|
||||
const [title, setTitle] = React.useState('')
|
||||
const [logo, setLogo] = React.useState('')
|
||||
const [banners, setBanners] = React.useState([])
|
||||
|
||||
const [socials, setSocials] = React.useState(SOCIALS)
|
||||
|
||||
const [bannerLink, setBannerLink] = React.useState('')
|
||||
const [rewards, setRewards] = React.useState([])
|
||||
const [appAddress, setAppAddress] = React.useState('')
|
||||
const [appKey, setAppKey] = React.useState('')
|
||||
const [kefuUrl, setKefuUrl] = React.useState('')
|
||||
|
||||
React.useEffect(() => {
|
||||
|
||||
get_settings().then((res) => {
|
||||
const o = res.data.other
|
||||
const s = res.data.system
|
||||
|
||||
setTitle(o.title)
|
||||
document.title = o.title + ' - DeFi platform for professor'
|
||||
|
||||
let banr = []
|
||||
o.banner?.forEach((item) => {
|
||||
banr.push(config.ENDPOINT + 'upload/' + item)
|
||||
})
|
||||
|
||||
setBanners(banr)
|
||||
setLogo(config.ENDPOINT + 'upload/' + o.logo_url)
|
||||
|
||||
setBannerLink(s.pic_url)
|
||||
|
||||
SOCIALS[0].path = s.telegram
|
||||
SOCIALS[1].path = s.twitter
|
||||
|
||||
setSocials(SOCIALS)
|
||||
setKefuUrl(s.kefu_url)
|
||||
setRewards(s.reward)
|
||||
setAppAddress(s.app_address)
|
||||
setAppKey(s.app_key)
|
||||
|
||||
}).catch(err => {
|
||||
console.error('get_settings() error: ' + err.message)
|
||||
})
|
||||
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<AppContext.Provider value={{
|
||||
address,
|
||||
setAddress,
|
||||
logo,
|
||||
title,
|
||||
banners,
|
||||
bannerLink,
|
||||
rewards,
|
||||
appAddress,
|
||||
appKey,
|
||||
socials,
|
||||
kefuUrl,
|
||||
}}>
|
||||
{children}
|
||||
</AppContext.Provider>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
import axios from 'axios'
|
||||
import { config } from '../config'
|
||||
|
||||
const get = (path, onSuccess, onFailed) => {
|
||||
return axios.get(config.ENDPOINT + path)
|
||||
}
|
||||
|
||||
const post = (path, data, onSuccess, onFailed) => {
|
||||
axios.post(config.ENDPOINT + path, data).then(res => {
|
||||
onSuccess && onSuccess(res.data)
|
||||
}).catch(err => {
|
||||
onFailed && onFailed(err)
|
||||
})
|
||||
}
|
||||
|
||||
export const get_settings = () => {
|
||||
return get('v1/settings')
|
||||
}
|
||||
|
||||
export const get_coins_platform = () => {
|
||||
return get('v1/coins/platform')
|
||||
}
|
||||
|
||||
// export const
|
|
@ -0,0 +1 @@
|
|||
export * from './api'
|
|
@ -0,0 +1,47 @@
|
|||
import {
|
||||
Button, Box, CloseButton, Drawer, DrawerContent, Text, Flex, HStack, Icon, IconButton,
|
||||
Menu, MenuButton, MenuDivider, MenuItem, MenuList, useColorModeValue,
|
||||
} from '@chakra-ui/react'
|
||||
import { FiBell, FiArrowRight, FiChevronDown, FiCompass, FiHome, FiMenu, FiSettings, FiStar, FiTrendingUp } from 'react-icons/fi'
|
||||
import { ImTwitter, ImTelegram, ImFacebook } from "react-icons/im";
|
||||
import { Logo } from './Logo'
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
export const AppBar = ({ onOpen, ...rest }) => {
|
||||
|
||||
const bg = useColorModeValue('white', 'gray.900')
|
||||
const borderBottomColor = useColorModeValue('gray.200', 'gray.700')
|
||||
const bgMenu = useColorModeValue('white', 'gray.900')
|
||||
const colorMenuBorder = useColorModeValue('gray.200', 'gray.700')
|
||||
|
||||
return (
|
||||
<Flex
|
||||
ml={{ base: 0, md: 60 }}
|
||||
px={{ base: 4, md: 4 }}
|
||||
height="20"
|
||||
alignItems="center"
|
||||
bg={bg}
|
||||
borderBottomWidth="1px"
|
||||
borderBottomColor={borderBottomColor}
|
||||
justifyContent={{ base: 'space-between', md: 'flex-end' }}
|
||||
{...rest}>
|
||||
|
||||
<Logo display={{ base: 'flex', md: 'none' }} />
|
||||
|
||||
<HStack>
|
||||
<Button size="md"
|
||||
border="2px"
|
||||
borderColor='green.500'>
|
||||
Connect Wallet
|
||||
</Button>
|
||||
<IconButton
|
||||
display={{ base: 'flex', md: 'none' }}
|
||||
onClick={onOpen}
|
||||
variant="outline"
|
||||
aria-label="open menu"
|
||||
icon={<FiMenu />}
|
||||
/>
|
||||
</HStack>
|
||||
</Flex>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
import { Box, Center, HStack, VStack, Text, Image } from "@chakra-ui/react"
|
||||
import { Images } from '../data'
|
||||
import React from "react"
|
||||
|
||||
/**
|
||||
* list auditors
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
export const Auditors = ({ ...rest }) => {
|
||||
|
||||
return (
|
||||
<VStack
|
||||
borderWidth="1px"
|
||||
borderRadius="lg"
|
||||
w="full"
|
||||
bg="white"
|
||||
boxShadow="lg"
|
||||
p="2"
|
||||
{...rest}
|
||||
>
|
||||
<Center>
|
||||
<Text fontSize="2xl" fontFamily="body" py="4"
|
||||
borderBottom="1px"
|
||||
borderColor='gray.200'
|
||||
>
|
||||
Auditors
|
||||
</Text>
|
||||
</Center>
|
||||
<HStack
|
||||
spacing={{ base: '6', md: '30', lg: '60' }}
|
||||
py='4'
|
||||
>
|
||||
{
|
||||
Images.auditors.map((img) => (
|
||||
<Box key={img}>
|
||||
<Image src={img} alt="auditor" />
|
||||
</Box>
|
||||
))
|
||||
}
|
||||
</HStack>
|
||||
</VStack>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
import {
|
||||
Box,
|
||||
IconButton,
|
||||
useBreakpointValue,
|
||||
Stack,
|
||||
Heading,
|
||||
Text,
|
||||
Container,
|
||||
AspectRatio,
|
||||
} from '@chakra-ui/react';
|
||||
import React from "react"
|
||||
import Slider from 'react-slick'
|
||||
// import { BiLeftArrowAlt, BiRightArrowAlt } from 'react-icons/bi';
|
||||
import "slick-carousel/slick/slick.css";
|
||||
import "slick-carousel/slick/slick-theme.css";
|
||||
|
||||
const settings = {
|
||||
dots: true,
|
||||
arrows: false,
|
||||
fade: true,
|
||||
infinite: true,
|
||||
autoplay: true,
|
||||
speed: 500,
|
||||
autoplaySpeed: 4000,
|
||||
slidesToShow: 1,
|
||||
slidesToScroll: 1,
|
||||
swipeToSlide: true,
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} url all images point to the same url
|
||||
* @param {array} cards
|
||||
* @returns
|
||||
*/
|
||||
export const Carousel = ({ url, cards, ...rest }) => {
|
||||
const [slider, setSlider] = React.useState(null)
|
||||
|
||||
const top = useBreakpointValue({ base: '90%', md: '50%' })
|
||||
const side = useBreakpointValue({ base: '30%', md: '40px' })
|
||||
|
||||
return (
|
||||
<Box
|
||||
borderWidth="1px"
|
||||
borderRadius="lg"
|
||||
bg="white"
|
||||
boxShadow="lg"
|
||||
p="0"
|
||||
position="relative"
|
||||
w="full"
|
||||
overflow="hidden"
|
||||
{...rest}>
|
||||
|
||||
{/* Slider */}
|
||||
<Slider {...settings} ref={(slider) => setSlider(slider)}>
|
||||
{
|
||||
cards.length > 0 && cards.map((card, index) => (
|
||||
<a key={index} href={url} target="_blank" >
|
||||
<AspectRatio maxW='full' ratio={4/1} >
|
||||
<Box
|
||||
w="full"
|
||||
position="relative"
|
||||
borderRadius="5"
|
||||
backgroundPosition="center"
|
||||
backgroundRepeat="no-repeat"
|
||||
backgroundSize="cover"
|
||||
backgroundImage={`url(${card})`}>
|
||||
{/* This is the block you need to change, to customize the caption */}
|
||||
<Container size="container.lg" height="220px" position="relative">
|
||||
<Stack
|
||||
spacing={2}
|
||||
w={'full'}
|
||||
maxW={'lg'}
|
||||
position="absolute"
|
||||
top="50%"
|
||||
transform="translate(0, -50%)">
|
||||
|
||||
</Stack>
|
||||
</Container>
|
||||
</Box>
|
||||
</AspectRatio>
|
||||
</a>
|
||||
))}
|
||||
</Slider>
|
||||
</Box>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
import React from 'react'
|
||||
import { Box, Image, Text, Stack, HStack, VStack, Flex } from '@chakra-ui/react'
|
||||
|
||||
export const FarmCoinCard = () => {
|
||||
return (
|
||||
<Box>
|
||||
|
||||
</Box>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
import {
|
||||
Button, Box, CloseButton, Drawer, DrawerContent, Text, Flex, HStack, Icon, IconButton,
|
||||
Menu, MenuButton, MenuDivider, MenuItem, MenuList, useColorModeValue, useDisclosure, VStack, DrawerOverlay, DrawerFooter, Spacer
|
||||
} from '@chakra-ui/react'
|
||||
import React from 'react'
|
||||
import { SideBar } from './SideBar';
|
||||
import { AppBar } from './AppBar';
|
||||
|
||||
/**
|
||||
* This component was not composed for more widely using but just for this project.
|
||||
*/
|
||||
export const Layout = ({ children }) => {
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
const bg = useColorModeValue('gray.100', 'gray.900')
|
||||
|
||||
return (
|
||||
<Box minH="100vh" bg={bg}>
|
||||
<SideBar
|
||||
onClose={onClose}
|
||||
display={{ base: 'none', md: 'block' }}
|
||||
/>
|
||||
|
||||
<Drawer
|
||||
autoFocus={false}
|
||||
isOpen={isOpen}
|
||||
placement="right"
|
||||
onClose={onClose}
|
||||
returnFocusOnClose={false}
|
||||
onOverlayClick={onClose}
|
||||
size="md">
|
||||
|
||||
<DrawerOverlay />
|
||||
|
||||
<DrawerContent>
|
||||
<SideBar onClose={onClose} />
|
||||
</DrawerContent>
|
||||
|
||||
</Drawer>
|
||||
|
||||
<AppBar onOpen={onOpen} />
|
||||
|
||||
<Box ml={{ base: 0, md: 60 }} p="4" overflowY="auto">
|
||||
{children}
|
||||
</Box>
|
||||
</Box>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
import { config } from '../config'
|
||||
import { Box, Image } from '@chakra-ui/react'
|
||||
import { Images } from '../data'
|
||||
import { useApp } from '../AppContext'
|
||||
// we have know which picture we are using
|
||||
export const Logo = (props) => {
|
||||
|
||||
const app = useApp()
|
||||
|
||||
return (
|
||||
<Box
|
||||
w="120px"
|
||||
h="32px"
|
||||
{...props}>
|
||||
<Image src={app.logo} alt='logo' />
|
||||
</Box>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
import React from 'react'
|
||||
import { HStack, Stack, Flex, Box, Slider, Image, Text, Button, VStack, Icon, AspectRatio, useCallbackRef } from '@chakra-ui/react'
|
||||
import { ImArrowRight2 } from 'react-icons/im'
|
||||
import { config } from '../config'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
|
||||
const FarmListItem = ({ id, img, symbol, percentage, ...rest }) => {
|
||||
|
||||
const onBtnMining = () => {
|
||||
console.log('press ' + id)
|
||||
}
|
||||
|
||||
return (
|
||||
<HStack
|
||||
w="full"
|
||||
justify="space-between"
|
||||
align="center"
|
||||
>
|
||||
<HStack>
|
||||
<Image w="8" h="8" borderRadius="50%" src={config.ENDPOINT + 'upload/' + img} alt={symbol} />
|
||||
<Text fontWeight="600">{symbol}</Text>
|
||||
</HStack>
|
||||
|
||||
<Text
|
||||
fontWeight="600"
|
||||
color="green.500"
|
||||
>
|
||||
{percentage}%
|
||||
</Text>
|
||||
<Button colorScheme="teal" size='sm'
|
||||
onClick={onBtnMining}
|
||||
>Mining</Button>
|
||||
</HStack>
|
||||
)
|
||||
}
|
||||
|
||||
export const MiningListCard = ({ coins, ...rest }) => {
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<VStack
|
||||
borderWidth="1px"
|
||||
borderRadius="lg"
|
||||
w="full"
|
||||
bg="white"
|
||||
boxShadow="lg"
|
||||
p="6"
|
||||
justify="start"
|
||||
>
|
||||
<Stack
|
||||
p="4"
|
||||
w="full"
|
||||
borderBottom="1px"
|
||||
borderBottomColor="gray.300"
|
||||
direction="row"
|
||||
justify="space-between"
|
||||
alignItems="center"
|
||||
>
|
||||
<Box>
|
||||
<Text>Defi Farm</Text>
|
||||
</Box>
|
||||
|
||||
<Link to="/farm">
|
||||
<Flex
|
||||
color="gray.300"
|
||||
fontSize="14"
|
||||
fontFamily="monospace"
|
||||
justify="end"
|
||||
alignItems="center"
|
||||
>
|
||||
|
||||
<Text>More</Text><Icon as={ImArrowRight2} />
|
||||
|
||||
</Flex>
|
||||
</Link>
|
||||
</Stack>
|
||||
|
||||
<VStack
|
||||
w="full"
|
||||
justify="start"
|
||||
>
|
||||
{
|
||||
coins.map((coin) => (
|
||||
<FarmListItem
|
||||
key={coin.name}
|
||||
id={coin.id}
|
||||
img={coin.name_img}
|
||||
symbol={coin.name}
|
||||
percentage={coin.yield}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</VStack>
|
||||
</VStack>
|
||||
</Box>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
import React from "react"
|
||||
import { Box, Flex, Stack, Icon, Heading, Text, VStack, HStack } from "@chakra-ui/react"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const NumCard = ({ icon, title, num }) => {
|
||||
|
||||
React.useEffect(() => {
|
||||
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<Stack
|
||||
align="center"
|
||||
justify="center"
|
||||
direction="column"
|
||||
flex={1}
|
||||
>
|
||||
|
||||
<Flex>
|
||||
{icon && <Icon as={icon} />}
|
||||
{<Text>{title}</Text>}
|
||||
</Flex>
|
||||
|
||||
<Flex>
|
||||
<Text>{num}</Text>
|
||||
</Flex>
|
||||
|
||||
</Stack>
|
||||
)
|
||||
}
|
||||
|
||||
export const MultiChainCard = ({ icon, title, num }) => {
|
||||
|
||||
React.useEffect(() => {
|
||||
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<VStack
|
||||
align="center"
|
||||
justify="center"
|
||||
direction="column"
|
||||
flex={1}
|
||||
bg="blue.600"
|
||||
borderRadius="5"
|
||||
color="white"
|
||||
>
|
||||
|
||||
<HStack
|
||||
align="center"
|
||||
justify="center"
|
||||
my="4"
|
||||
fontSize="16"
|
||||
fontWeight="600"
|
||||
>
|
||||
{icon && <Icon as={icon} />}
|
||||
{<Text>{title}</Text>}
|
||||
</HStack>
|
||||
|
||||
<HStack
|
||||
align="center"
|
||||
justify="center"
|
||||
pb="4"
|
||||
fontSize="22"
|
||||
fontWeight="900"
|
||||
>
|
||||
<Text>{num}</Text>
|
||||
</HStack>
|
||||
|
||||
</VStack>
|
||||
)
|
||||
}
|
||||
|
||||
export const StateCard = ({ icon, title, num }) => {
|
||||
|
||||
React.useEffect(() => {
|
||||
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<VStack
|
||||
align="center"
|
||||
justify="center"
|
||||
direction="column"
|
||||
flex={1}
|
||||
borderRadius="5"
|
||||
>
|
||||
|
||||
<HStack
|
||||
align="center"
|
||||
justify="center"
|
||||
my="4"
|
||||
color="gray.500"
|
||||
fontSize="12"
|
||||
fontWeight="600"
|
||||
wrap="nowrap"
|
||||
>
|
||||
{icon && <Icon as={icon} />}
|
||||
{<Text>{title}</Text>}
|
||||
</HStack>
|
||||
|
||||
<HStack
|
||||
align="center"
|
||||
justify="center"
|
||||
pb="4"
|
||||
fontSize="18"
|
||||
fontWeight="700"
|
||||
>
|
||||
<Text>{num}</Text>
|
||||
</HStack>
|
||||
|
||||
</VStack>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import { Box } from "@chakra-ui/react"
|
||||
|
||||
|
||||
export const Panel = ({...props}) => {
|
||||
|
||||
return (
|
||||
<Box>
|
||||
|
||||
</Box>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
import { Box, Center, HStack, Image, VStack, SimpleGrid, Text, Stack } from "@chakra-ui/react"
|
||||
import React from "react"
|
||||
import { Images } from '../data'
|
||||
|
||||
const Partner3 = ({ imgs, ...rest }) => {
|
||||
|
||||
return (
|
||||
<HStack
|
||||
{...rest}
|
||||
>
|
||||
{
|
||||
imgs.map((img) => (
|
||||
<Stack flex={1} key={img}>
|
||||
<Image display='block' w='80%' m='0' src={img} alt='partner' />
|
||||
</Stack>
|
||||
))
|
||||
}
|
||||
</HStack>
|
||||
)
|
||||
}
|
||||
|
||||
const PartnerRow = ({ left, right }) => {
|
||||
|
||||
return (
|
||||
<Stack
|
||||
direction={{ base: 'column', md: 'row' }}
|
||||
>
|
||||
<Partner3 imgs={left} flex={1} />
|
||||
<Partner3 imgs={right} flex={1} />
|
||||
</Stack>
|
||||
)
|
||||
}
|
||||
|
||||
export const Partners = ({...rest}) => {
|
||||
|
||||
return (
|
||||
<VStack
|
||||
borderWidth="1px"
|
||||
borderRadius="lg"
|
||||
w="full"
|
||||
bg="white"
|
||||
boxShadow="lg"
|
||||
p="2"
|
||||
{...rest}
|
||||
>
|
||||
<Center>
|
||||
<Text fontSize="2xl" fontFamily="body" py="2"
|
||||
borderBottom="1px"
|
||||
borderColor='gray.200'
|
||||
>
|
||||
Partners
|
||||
</Text>
|
||||
</Center>
|
||||
|
||||
<VStack
|
||||
py='4'
|
||||
px='4'
|
||||
flexWrap='wrap'
|
||||
alignItems='center'
|
||||
justifyContent='start'
|
||||
>
|
||||
<PartnerRow left={Images.partners.slice(0, 3)} right={Images.partners.slice(3, 6)} />
|
||||
<PartnerRow left={Images.partners.slice(6, 9)} right={Images.partners.slice(9)} />
|
||||
</VStack>
|
||||
</VStack>
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
import {
|
||||
Button, Box, CloseButton, Drawer, DrawerContent, Text, Flex, HStack, Icon, IconButton,
|
||||
Menu, MenuButton, MenuDivider, MenuItem, MenuList, useColorModeValue,
|
||||
} from '@chakra-ui/react'
|
||||
import { FiBell, FiArrowRight, FiChevronDown, FiCompass, FiHome, FiMenu, FiSettings, FiStar, FiTrendingUp } from 'react-icons/fi'
|
||||
import { useApp } from '../AppContext'
|
||||
import { Logo } from './Logo'
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
const menuItems = [
|
||||
{ name: 'Home', icon: FiHome, path: '/home' },
|
||||
{ name: 'Farm', icon: FiTrendingUp, path: '/farm' },
|
||||
]
|
||||
|
||||
const docItems = [
|
||||
{ name: 'Anouncement', icon: '', path: '' },
|
||||
{ name: 'FAQ', icon: '', path: '' },
|
||||
{ name: 'Tutorial', icon: '', path: '' },
|
||||
]
|
||||
|
||||
const NavItem = ({ icon, path, children, ...rest }) => {
|
||||
return (
|
||||
<Link to={path}>
|
||||
<Flex
|
||||
align="center"
|
||||
p="4"
|
||||
mx="4"
|
||||
borderRadius="lg"
|
||||
role="group"
|
||||
cursor="pointer"
|
||||
_hover={{ bg: 'cyan.400', color: 'white' }}
|
||||
{...rest}
|
||||
>
|
||||
{icon && (
|
||||
<Icon mr="4" fontSize="16" _groupHover={{ color: 'white' }} as={icon} />
|
||||
)}
|
||||
|
||||
{children}
|
||||
</Flex>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
const DocItem = ({ path, children, ...rest }) => {
|
||||
return (
|
||||
<Link to={path}>
|
||||
<Flex
|
||||
align="center"
|
||||
p="4"
|
||||
mx="4"
|
||||
borderRadius="lg"
|
||||
role="group"
|
||||
cursor="pointer"
|
||||
fontFamily="monospace"
|
||||
fontSize="12"
|
||||
color="gray.400"
|
||||
_hover={{ bg: 'gray.600', color: 'white' }}
|
||||
justifyContent="space-between"
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
<Icon mr="4" fontSize="16" _groupHover={{ color: 'white' }} as={FiArrowRight} />
|
||||
</Flex>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
const SocialItem = ({ icon, path, ...rest }) => {
|
||||
return (
|
||||
<a href={path} target="_blank">
|
||||
<Icon _hover={{ color: 'gray.900' }} as={icon} />
|
||||
</a>
|
||||
)
|
||||
}
|
||||
|
||||
export const SideBar = ({ onClose, ...rest }) => {
|
||||
const app = useApp()
|
||||
|
||||
const bg = useColorModeValue('white', 'gray.900')
|
||||
const colorBorderRight = useColorModeValue('gray.200', 'gray.700')
|
||||
|
||||
return (
|
||||
<Box
|
||||
transition="3s ease"
|
||||
bg={bg}
|
||||
// borderRight="1px"
|
||||
// borderRightColor={colorBorderRight}
|
||||
w={{ base: 'full', md: 60 }}
|
||||
pos="fixed"
|
||||
h="full"
|
||||
{...rest}>
|
||||
|
||||
<Flex h="20"
|
||||
alignItems="center"
|
||||
mx="8"
|
||||
justifyContent="space-between">
|
||||
<Logo />
|
||||
|
||||
<CloseButton display={{ base: 'flex', md: 'none' }} onClick={onClose} />
|
||||
</Flex>
|
||||
|
||||
<Flex h="90%" direction="column" justifyContent="space-between">
|
||||
<Box>
|
||||
{/* nav links */}
|
||||
{
|
||||
menuItems.map((item) => (
|
||||
<NavItem key={item.name} icon={item.icon} path={item.path}>
|
||||
{item.name}
|
||||
</NavItem>
|
||||
))
|
||||
}
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
{/* document links */}
|
||||
{
|
||||
docItems.map((item) => (
|
||||
<DocItem key={item.name} icon={item.icon} path={item.path}>
|
||||
{item.name}
|
||||
</DocItem>
|
||||
))
|
||||
}
|
||||
{/* social icons */}
|
||||
<Flex
|
||||
px="8"
|
||||
my="8"
|
||||
fontSize="18"
|
||||
color="gray.400"
|
||||
|
||||
justifyContent="space-between"
|
||||
>
|
||||
{
|
||||
app.socials.map((item) => (
|
||||
<SocialItem key={item.name} icon={item.icon} path={item.path} />
|
||||
))
|
||||
}
|
||||
</Flex>
|
||||
</Box>
|
||||
</Flex>
|
||||
</Box>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
export * from './Layout'
|
||||
export * from './Logo'
|
||||
export * from './Carousel'
|
||||
export * from './NumCard'
|
||||
export * from './MiningListCard'
|
||||
export * from './Partners'
|
||||
export * from './Auditors'
|
||||
export * from './FarmCoinCard'
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
const items = {
|
||||
development: {
|
||||
|
||||
},
|
||||
production: {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export const config = {
|
||||
APP_NAME: 'CoinWind',
|
||||
ENABLE_WALLETCONNECT: true,
|
||||
ENABLE_COINBASE: true,
|
||||
INFURAL_ID: 'a4a92ab2377d4bb9a693d96c27c6523e',
|
||||
ENDPOINT: 'http://coinwind.test/',
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
import { config } from "./config"
|
||||
|
||||
export const Images = {
|
||||
logo: config.ENDPOINT + 'upload/images/LOGO1.svg',
|
||||
auditors: [
|
||||
config.ENDPOINT + '/static/media/logo-lingzonganquan.5ab95e1c.svg',
|
||||
config.ENDPOINT + '/static/media/logo-chengdulianan.8167d6d1.svg',
|
||||
],
|
||||
partners: [
|
||||
config.ENDPOINT + '/static/media/mexc.png',
|
||||
config.ENDPOINT + '/static/media/WhatsCion LOGO.6719d0fe.svg',
|
||||
config.ENDPOINT + '/static/media/huobi wallet logo.fb179453.svg',
|
||||
config.ENDPOINT + '/static/media/Coinhub-logo.19662e8b.svg',
|
||||
config.ENDPOINT + '/static/media/king_logo.edbe9b20.svg',
|
||||
config.ENDPOINT + '/static/media/math.02fb72a5.svg',
|
||||
config.ENDPOINT + '/static/media/TokenPocket_Logo__ traverse.619dc8b8.svg',
|
||||
config.ENDPOINT + '/static/media/bitkeep.png',
|
||||
config.ENDPOINT + '/static/media/HyperPay-Logo.f0568b2a.svg',
|
||||
config.ENDPOINT + '/static/media/ONTO-black.a40460bb.svg',
|
||||
config.ENDPOINT + '/static/media/aolink.55778d9b.svg',
|
||||
config.ENDPOINT + '/static/media/codebank.db7917c8.svg',
|
||||
],
|
||||
more: config.ENDPOINT + '/static/media/icon-more.c502d302.svg'
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
import React, { useEffect } from 'react'
|
||||
|
||||
function getStorageJson(name, default_value) {
|
||||
if (!localStorage) {
|
||||
console.warn('Something went wrong, check your environment')
|
||||
return default_value
|
||||
}
|
||||
|
||||
const rawdata = localStorage.getItem(name)
|
||||
const val = JSON.parse(rawdata)
|
||||
return val || default_value
|
||||
}
|
||||
|
||||
/**
|
||||
* Purpose:
|
||||
* Step 1: init state by localStorage
|
||||
* Step 2: save state to localStorage automatically
|
||||
*
|
||||
* @name: key of localStorage
|
||||
* @default_value: default value of @name
|
||||
*
|
||||
* @return [val, setVal] the state and setter.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* function SomeComponent() {
|
||||
* const [state, setState] = useLocalStorage('mystate', 0)
|
||||
* }
|
||||
*/
|
||||
export default useLocalStorage = (name, default_value) => {
|
||||
const [value, setValue] = React.useState(() => getStorageJson(name, default_value))
|
||||
|
||||
React.useEffect(() => {
|
||||
localStorage.setItem(name, JSON.stringify(value))
|
||||
}, [name, value])
|
||||
|
||||
return [value, setValue]
|
||||
}
|
27
src/index.js
27
src/index.js
|
@ -1,17 +1,32 @@
|
|||
import { ColorModeScript } from '@chakra-ui/react';
|
||||
import React, { StrictMode } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import App from './App';
|
||||
import { Home, Farm } from './pages'
|
||||
import reportWebVitals from './reportWebVitals';
|
||||
import * as serviceWorker from './serviceWorker';
|
||||
import { BrowserRouter, Routes, Route } from 'react-router-dom';
|
||||
|
||||
ReactDOM.render(
|
||||
const element = document.getElementById('root')
|
||||
const root = createRoot(element)
|
||||
|
||||
root.render(
|
||||
<StrictMode>
|
||||
<BrowserRouter>
|
||||
<ColorModeScript />
|
||||
<App />
|
||||
</StrictMode>,
|
||||
document.getElementById('root')
|
||||
);
|
||||
<Routes>
|
||||
<Route path="/" element={<App />}>
|
||||
<Route index element={<Home />} />
|
||||
<Route path="home" element={<Home />} />
|
||||
<Route path="farm" element={<Farm />} />
|
||||
<Route path="*" element={<div>Not Found</div>} />
|
||||
</Route>
|
||||
</Routes>
|
||||
|
||||
</BrowserRouter>
|
||||
</StrictMode >
|
||||
)
|
||||
|
||||
|
||||
// If you want your app to work offline and load faster, you can change
|
||||
// unregister() to register() below. Note this comes with some pitfalls.
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
import Web3 from "web3"
|
||||
import Web3Modal from "web3modal"
|
||||
import WalletConnectProvider from "@walletconnect/web3-provider"
|
||||
import { config } from '../config'
|
||||
import CoinbaseWalletSDK from "@coinbase/wallet-sdk"
|
||||
|
||||
let provider
|
||||
|
||||
let providerOptions = {}
|
||||
|
||||
if (config.ENABLE_WALLETCONNECT) {
|
||||
providerOptions.walletconnct = {
|
||||
package: WalletConnectProvider,
|
||||
options: {
|
||||
infuraId: config.INFURAL_ID,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if (config.ENABLE_COINBASE) {
|
||||
providerOptions.coinbasewallet = {
|
||||
package: CoinbaseWalletSDK,
|
||||
options: {
|
||||
appName: config.APP_NAME,
|
||||
infuraId: config.INFURAL_ID,
|
||||
darkMode: false,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const web3Modal = new Web3Modal({
|
||||
network: "mainnet",
|
||||
cacheProvider: true,
|
||||
providerOptions,
|
||||
disableInjectedProvider: false,
|
||||
})
|
||||
|
||||
export const connectWallet = async () => {
|
||||
try {
|
||||
provider = await web3Modal.connect()
|
||||
provider.enable()
|
||||
} catch (err) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
export const addEventListeners = async () => {
|
||||
if (!provider) {
|
||||
return false
|
||||
}
|
||||
|
||||
provider.on('accountChanged', async (accounts) => {
|
||||
|
||||
})
|
||||
|
||||
provider.on('chainChanged', async (accounts) => {
|
||||
|
||||
})
|
||||
|
||||
provider.on('networkChanged', async (networkId) => {
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
export const fetchAccount = async () => {
|
||||
const web3 = new Web3(provider)
|
||||
const accounts = await web3.eth.getAccounts()
|
||||
return accounts[0]
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import React from "react";
|
||||
|
||||
|
||||
export const Announcement = () => {
|
||||
|
||||
return (
|
||||
<div>Announcement</div>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
import { Box } from "@chakra-ui/react"
|
||||
import React from "react"
|
||||
|
||||
|
||||
export const Assets = () => {
|
||||
|
||||
return (
|
||||
<Box>
|
||||
|
||||
</Box>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
import { Box } from "@chakra-ui/react";
|
||||
import React from "react";
|
||||
|
||||
|
||||
export const Farm = () => {
|
||||
|
||||
return (
|
||||
<Box>
|
||||
{/* pool list */}
|
||||
|
||||
</Box>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
import React from "react";
|
||||
import { Box, Stack, VStack, Image, Text, Flex, HStack, Spacer } from "@chakra-ui/react";
|
||||
import { Auditors, Partners, Carousel, MultiChainCard, NumCard, StateCard, MiningListCard } from "../components";
|
||||
import { Link } from "react-router-dom";
|
||||
import { useApp } from '../AppContext'
|
||||
import { get_coins_platform } from '../api'
|
||||
import { ImPieChart, ImFire } from 'react-icons/im'
|
||||
|
||||
const HomeFooter = () => {
|
||||
|
||||
const app = useApp()
|
||||
|
||||
return (
|
||||
<Flex
|
||||
mt="6"
|
||||
mx="4"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
color="gray.500"
|
||||
>
|
||||
<Image src={app.logo} filter="grayscale(100%)" opacity="0.5" alt='logo' />
|
||||
|
||||
<a href="https://www.fairyproof.com/" target="_blank">
|
||||
<Text
|
||||
fontFamily="monospace"
|
||||
fontSize="14"
|
||||
>FAIRYPROOF</Text>
|
||||
</a>
|
||||
</Flex>
|
||||
)
|
||||
}
|
||||
|
||||
export const Home = () => {
|
||||
const [coins, setCoins] = React.useState([])
|
||||
|
||||
const app = useApp()
|
||||
|
||||
React.useEffect(() => {
|
||||
get_coins_platform().then((res) => {
|
||||
setCoins(res.data)
|
||||
}).catch(err => {
|
||||
console.error('get_coins_platform() error:' + err.message)
|
||||
})
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box>
|
||||
<Carousel url={app.bannerLink} cards={app.banners} />
|
||||
</Box>
|
||||
|
||||
<VStack
|
||||
borderWidth="1px"
|
||||
borderRadius="lg"
|
||||
w="full"
|
||||
bg="white"
|
||||
boxShadow="lg"
|
||||
p="6"
|
||||
my="4"
|
||||
>
|
||||
<Stack
|
||||
w="full"
|
||||
direction={{ base: 'column', md: 'row' }}
|
||||
>
|
||||
<MultiChainCard icon={ImFire} title="Multi-chain Lock-up Value($)" num={app.rewards[0]} />
|
||||
<MultiChainCard icon={ImPieChart} title="Multi-chain User Revenue($)" num={app.rewards[1]} />
|
||||
</Stack>
|
||||
|
||||
<Stack
|
||||
bg="gray.100"
|
||||
w="full"
|
||||
borderRadius="lg"
|
||||
direction={{ base: 'column', md: 'row' }}
|
||||
>
|
||||
<HStack
|
||||
flex={1}
|
||||
>
|
||||
<StateCard title="Mining Output" num={app.rewards[2]} />
|
||||
<StateCard title="Mining Output Value($)" num={app.rewards[3]} />
|
||||
</HStack>
|
||||
|
||||
<HStack
|
||||
flex={1}
|
||||
>
|
||||
<StateCard title="Multi-chain Rewards($)" num={app.rewards[4]} />
|
||||
<StateCard title="Multi-chain Burned" num="0" />
|
||||
</HStack>
|
||||
</Stack>
|
||||
|
||||
</VStack>
|
||||
|
||||
<MiningListCard coins={coins} />
|
||||
|
||||
<Auditors mt="4" />
|
||||
|
||||
<Partners mt="4" />
|
||||
|
||||
<HomeFooter />
|
||||
</>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import React from "react";
|
||||
|
||||
|
||||
export const Staking = () => {
|
||||
|
||||
return (
|
||||
<div>Staking</div>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
export * from './Home'
|
||||
export * from './Farm'
|
||||
export * from './Staking'
|
||||
export * from './Announcement'
|
Loading…
Reference in New Issue