nft市场

This commit is contained in:
myf 2022-06-11 14:38:37 +08:00
parent 337409049e
commit 5cc15cec41
5 changed files with 152 additions and 24 deletions

11
src/services/bazaar.ts Normal file
View File

@ -0,0 +1,11 @@
import request from 'utils/request'
export const getOfficialPage = (params) => {
return request.request({
url: '/high_city/app/api/market/official/page',
method: 'get',
params,
})
}
export default getOfficialPage

View File

@ -1,15 +1,35 @@
import React, { useState, useEffect } from 'react'
import styled, { keyframes } from 'styled-components'
import { useTranslation } from 'contexts/Localization'
import Pagination from '@mui/material/Pagination'
import { Flex, Text, Input, Image, Dropdown } from '@pancakeswap/uikit'
import { useAccount } from 'state/userInfo/hooks'
import useRefresh from 'hooks/useRefresh'
import { useGetOfficialPage } from '../hooks'
import HeaderOperation from './HeaderOperation'
import ContentShop from './ContentShop'
import Transaction from './Transaction'
import ShopDetail from './ShopDetail'
interface ListProps {
coverResource?: CoverResourceProps
grade?: string
id?: string
name?: string
price?: undefined
priceList?: PriceProps[]
type?: string
}
interface CoverResourceProps {
path?: string
url?: string
}
interface PriceProps {
label?: string
value?: string
}
const HeaderFlex = styled(Flex)`
width: 100%;
justify-content: space-between;
@ -148,13 +168,7 @@ const Content: React.FC = () => {
const [priceSelect, setPriceSelect] = useState({ label: t('The latest offer'), value: '0' })
const [searchTitle, setSearchTitle] = useState('')
const list = [
{ label: 'Cat goddess Emerald ', type: 1, id: 1 },
{ label: 'Cat goddess Emerald ', type: 2, id: 2 },
{ label: 'Cat goddess Emerald ', type: 3, id: 3 },
{ label: 'Cat goddess Emerald ', type: 4, id: 4 },
{ label: 'Cat goddess Emerald ', type: 1, id: 5 },
]
const [list, setList] = useState<ListProps[]>([])
const statusList = [
{ label: t('All'), id: '1' },
{ label: t('epic'), id: '2' },
@ -164,6 +178,36 @@ const Content: React.FC = () => {
]
const [statusIndex, setStatusIndex] = useState(0)
const [pageNum, setPage] = useState(1)
const [count, setCount] = useState(undefined)
const getOfficialPage = useGetOfficialPage()
const getData = async () => {
const params = {
page: pageNum,
size: 10,
}
const data = await getOfficialPage(params)
const arr = []
data.content.forEach((item) => {
const obj = item
obj.priceList = []
Object.keys(obj.price).forEach((childItem) => {
obj.priceList.push({ label: childItem, value: obj.price[childItem] })
})
obj.price = undefined
arr.push(obj)
})
setList(arr)
setCount(getTotalPageNum(data.total, data.size))
}
useEffect(() => {
getData()
}, [pageNum])
const handleChange = (evt: React.ChangeEvent<HTMLInputElement>) => {
const { value } = evt.target
setSearchTitle(value)
@ -174,6 +218,13 @@ const Content: React.FC = () => {
const showDetail = () => {
setDetailVisible(!detailVisible)
}
const pageChange = (e, page) => {
setPage(page)
}
const getTotalPageNum = (total, pageSize) => {
const countTotal = ((Number(total) + Number(pageSize) - 1) / Number(pageSize)).toString()
return parseInt(countTotal)
}
return (
<>
@ -263,6 +314,9 @@ const Content: React.FC = () => {
</InputMain>
</SearchDiv>
<ContentShop list={list} getDetail={showDetail} />
<Flex justifyContent="center" padding={10}>
<Pagination count={count} onChange={pageChange} page={pageNum} />
</Flex>
</>
)}
</>

View File

@ -1,7 +1,8 @@
import React, { useState, useEffect } from 'react'
import styled, { keyframes } from 'styled-components'
import { useTranslation } from 'contexts/Localization'
import { Flex, Text } from '@pancakeswap/uikit'
import { formatTimeNumber } from 'utils/formatBalance'
import { Flex, Text, Image } from '@pancakeswap/uikit'
import { useAccount } from 'state/userInfo/hooks'
import useRefresh from 'hooks/useRefresh'
import { TOKEN_SYMBOL } from 'config/index'
@ -9,10 +10,27 @@ import { TOKEN_SYMBOL } from 'config/index'
import ShopList from './ShopList'
interface ContentShop {
list?: any
list?: ListProps[]
getDetail?: () => void
}
interface ListProps {
coverResource?: CoverResourceProps
grade?: string
id?: string
name?: string
price?: undefined
priceList?: PriceProps[]
type?: string
}
interface CoverResourceProps {
path?: string
url?: string
}
interface PriceProps {
label?: string
value?: string
}
const ShopMain = styled.div`
width: 100%;
display: grid;
@ -57,6 +75,7 @@ const FooterLabel = styled(Text)`
color: #999999;
`
const FooterValue = styled(Text)`
width: 40%;
font-size: 16px;
color: #1fc7d4;
`
@ -73,11 +92,29 @@ const ContentShop: React.FC<ContentShop> = ({ list, getDetail }) => {
{list.map((item) => {
return (
<ShopFlex key={item.id} onClick={showDetail}>
<ShopList item={item} width={278} height={280} borderRadius="20px 20px 0 0" />
<ShopName>{item.label}</ShopName>
<ShopList
item={item}
width={278}
height={280}
img={item.coverResource.url}
grade={item.grade}
borderRadius="20px 20px 0 0"
/>
<ShopName>{item.name}</ShopName>
<ShopFooter>
<FooterLabel>{t('trading value')}</FooterLabel>
<FooterValue>1000{TOKEN_SYMBOL}</FooterValue>
<FooterValue>
{item.priceList.map((childItem, index) => {
return (
<Flex alignItems="center" flexWrap="wrap" key={childItem.label}>
{/* <>{formatTimeNumber(childItem.value)}</> */}
<>{Number(childItem.value).toFixed(2)}</>
<Text color="text">{childItem.label}</Text>
{index === 0 && item.priceList.length === 2 && <Text marginLeft="10px">-</Text>}
</Flex>
)
})}
</FooterValue>
</ShopFooter>
</ShopFlex>
)

View File

@ -82,6 +82,8 @@ interface ShopListItemProps {
width?: number
height?: number
borderRadius?: string
grade?: string
img?: string
}
interface Detail {
label?: string
@ -89,21 +91,28 @@ interface Detail {
id?: number | string
}
const ShopList: React.FC<ShopListItemProps> = ({ item, width = 186, height = 187, borderRadius = '20px' }) => {
const ShopList: React.FC<ShopListItemProps> = ({
item,
width = 186,
height = 187,
borderRadius = '20px',
img,
grade,
}) => {
const { t } = useTranslation()
const getClassBcg = () => {
let bcg = ''
switch (item.type) {
case 1:
switch (grade) {
case 'EPIC':
bcg = 'epicBcg'
break
case 2:
case 'LEGEND':
bcg = 'legendBcg'
break
case 3:
case 'RARE':
bcg = 'uncommonBcg'
break
case 4:
case 'NORMAL':
bcg = 'commonBcg'
break
default:
@ -116,15 +125,20 @@ const ShopList: React.FC<ShopListItemProps> = ({ item, width = 186, height = 187
<MainFlex>
<ShopItem className={getClassBcg()} style={{ borderRadius }}>
<div className="ribbon">
{item.type === 1 && <div className="ribbon1 epic">{t('epic')}</div>}
{item.type === 2 && <div className="ribbon1 legend">{t('legend')}</div>}
{item.type === 3 && <div className="ribbon1 uncommon">{t('uncommon')}</div>}
{item.type === 4 && <div className="ribbon1 common">{t('common')}</div>}
{grade === 'EPIC' && <div className="ribbon1 epic">{t('epic')}</div>}
{grade === 'LEGEND' && <div className="ribbon1 legend">{t('legend')}</div>}
{grade === 'RARE' && <div className="ribbon1 uncommon">{t('uncommon')}</div>}
{grade === 'NORMAL' && <div className="ribbon1 common">{t('common')}</div>}
</div>
{item.type === 1 && <Image src="/images/nft/epic-icon.svg" width={width} height={height} />}
{/* {item.type === 1 && <Image src="/images/nft/epic-icon.svg" width={width} height={height} />}
{item.type === 2 && <Image src="/images/nft/legend-icon.svg" width={width} height={height} />}
{item.type === 3 && <Image src="/images/nft/uncommon-icon.svg" width={width} height={height} />}
{item.type === 4 && <Image src="/images/nft/box.svg" width={width} height={height} />}
{item.type === 4 && <Image src="/images/nft/box.svg" width={width} height={height} />} */}
{img ? (
<Image src={img} width={width} height={height} />
) : (
<Image src="/images/nft/uncommon.svg" width={width} height={height} />
)}
</ShopItem>
</MainFlex>
)

View File

@ -0,0 +1,12 @@
import { useCallback } from 'react'
import { getOfficialPage } from 'services/bazaar'
export const useGetOfficialPage = () => {
const data = async (params) => {
const result = await getOfficialPage(params)
return result
}
return data
}
export default useGetOfficialPage