diff --git a/build.zip b/build.zip index 467807a..7322278 100644 Binary files a/build.zip and b/build.zip differ diff --git a/public/images/nft/close.png b/public/images/nft/close.png new file mode 100644 index 0000000..2b77bc0 Binary files /dev/null and b/public/images/nft/close.png differ diff --git a/public/locales/zh-CN.json b/public/locales/zh-CN.json index 6db59d4..6b47c44 100644 --- a/public/locales/zh-CN.json +++ b/public/locales/zh-CN.json @@ -1305,5 +1305,6 @@ "In the sale": "售卖中", "The purchase": "竞拍成功", "The selling time cannot be less than %hour% hour": "出售时间不能小于%hour%小时", - "Did not take": "未拍中" + "Did not take": "未拍中", + "transaction price": "成交价" } diff --git a/src/App.tsx b/src/App.tsx index a389cf0..8dabb54 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -132,6 +132,8 @@ const App: React.FC = () => { + + {/* diff --git a/src/components/Menu/config.ts b/src/components/Menu/config.ts index 46813b4..7d802e7 100644 --- a/src/components/Menu/config.ts +++ b/src/components/Menu/config.ts @@ -41,24 +41,24 @@ const config: (t: ContextApi['t']) => MenuEntry[] = (t) => [ // }, // ], // }, - // { - // label: t('Trade'), - // icon: 'TradeIcon', - // items: [ - // { - // label: t('Exchange'), - // href: '/swap', - // }, - // { - // label: t('Liquidity'), - // href: '/pool', - // }, - // // { - // // label: t('LP Migration'), - // // href: 'https://v1exchange.pancakeswap.finance/#/migrate', - // // }, - // ], - // }, + { + label: t('Trade'), + icon: 'TradeIcon', + items: [ + { + label: t('Exchange'), + href: '/swap', + }, + { + label: t('Liquidity'), + href: '/pool', + }, + // { + // label: t('LP Migration'), + // href: 'https://v1exchange.pancakeswap.finance/#/migrate', + // }, + ], + }, // { // label: t('Exchange'), // icon: 'FarmIcon', diff --git a/src/config/localization/translations.json b/src/config/localization/translations.json index c287940..14823b7 100644 --- a/src/config/localization/translations.json +++ b/src/config/localization/translations.json @@ -1432,5 +1432,6 @@ "In the sale": "In the sale", "The purchase": "The purchase", "The selling time cannot be less than %hour% hour": "The selling time cannot be less than %hour% hour", - "Did not take": "Did not take" + "Did not take": "Did not take", + "transaction price": "transaction price" } diff --git a/src/services/bazaar.ts b/src/services/bazaar.ts index 24ad9cb..3467899 100644 --- a/src/services/bazaar.ts +++ b/src/services/bazaar.ts @@ -105,5 +105,11 @@ export const getPublishTime = () => { method: 'get', }) } +export const getGoodsDetail = (id) => { + return request.request({ + url: `/high_city/app/api/goods/${id}`, + method: 'get', + }) +} export default getOfficialPage diff --git a/src/views/Bazaar/components/AuctionRecord.tsx b/src/views/Bazaar/components/AuctionRecord.tsx index c021a9d..2e8eb6d 100644 --- a/src/views/Bazaar/components/AuctionRecord.tsx +++ b/src/views/Bazaar/components/AuctionRecord.tsx @@ -24,7 +24,7 @@ interface ListProps { } const FlexMain = styled.div` - width: 70%; + width: 1062px; height: 658px; background: #fff; font-size: 18px; @@ -121,11 +121,12 @@ const TdBtnFlex = styled(Flex)` align-items: center; ` const DetailButton = styled(Button)` - width: 80px; + width: 60px; height: 30px; background: linear-gradient(90deg, #1fd4b0 0%, #1fc9d3 100%); border-radius: 30px; font-size: 12px; + padding: 0; ` const HashText = styled(Text)` cursor: pointer; @@ -319,7 +320,7 @@ const AuctionRecord: React.FC = ({ onDismiss, recordDetail } {/* */} - {item.goodsName} + {`${item.goodsName}(#${item.token})`} {item.price} {item.lastPrice}HCC diff --git a/src/views/Bazaar/components/AuctionTable.tsx b/src/views/Bazaar/components/AuctionTable.tsx index f156324..bb58df7 100644 --- a/src/views/Bazaar/components/AuctionTable.tsx +++ b/src/views/Bazaar/components/AuctionTable.tsx @@ -4,6 +4,7 @@ import Tooltip from '@mui/material/Tooltip' import { Text, Flex } from '@pancakeswap/uikit' import { useTranslation } from 'contexts/Localization' import { tradeRecord } from 'services/bazaar' +import useRefresh from 'hooks/useRefresh' import Empty from 'components/Empty' interface AuctionTableProps { @@ -95,6 +96,7 @@ const TxFlex = styled(Flex)` const AuctionTable: React.FC = ({ token, time }) => { const { t } = useTranslation() + const { fastRefresh } = useRefresh() const [pageNum, setPage] = useState(1) const [list, serList] = useState() // 交易记录 @@ -107,6 +109,11 @@ const AuctionTable: React.FC = ({ token, time }) => { getTradeRecord() } }, [pageNum, token]) + useEffect(() => { + if (token) { + getTradeRecord() + } + }, [fastRefresh]) const goHash = (val) => { window.open(`https://goerli.etherscan.io/tx/${val}`) } diff --git a/src/views/Bazaar/components/BtnStatus.tsx b/src/views/Bazaar/components/BtnStatus.tsx index 40978da..6e550c1 100644 --- a/src/views/Bazaar/components/BtnStatus.tsx +++ b/src/views/Bazaar/components/BtnStatus.tsx @@ -25,7 +25,7 @@ const PriceButton = styled(Button)` background: linear-gradient(269deg, #1fc8d3 0%, #1fd4b0 100%); border-radius: 30px; font-size: 16px; - margin: 30px 0; + /* margin: 30px 0; */ ` const AuthorizationBtn = styled(Button)` width: 100%; @@ -86,6 +86,7 @@ const BtnStatus: React.FC = ({ detail }) => { } useEffect(() => { + console.log(detail) if (detail.priceList) { const priceList = detail.priceList.map((item) => { return `${Number(item.value).toFixed(3)} ${item.label}` @@ -150,10 +151,10 @@ const BtnStatus: React.FC = ({ detail }) => { <> {buyVisible && {t('Buy It Now')}} - {detail.priceList.map((item, i) => + {detail?.priceList?.map((item, i) => item.label === 'HCC' && !allowanceList.HCC ? ( { handleApprove(onHccApprove) @@ -163,7 +164,7 @@ const BtnStatus: React.FC = ({ detail }) => { ) : item.label === 'USDT' && !allowanceList.USDT ? ( { handleApprove(onUsdtApprove) diff --git a/src/views/Bazaar/components/Content.tsx b/src/views/Bazaar/components/Content.tsx index a30e923..e521f7f 100644 --- a/src/views/Bazaar/components/Content.tsx +++ b/src/views/Bazaar/components/Content.tsx @@ -9,6 +9,7 @@ import { useAccount } from 'state/userInfo/hooks' import useRefresh from 'hooks/useRefresh' import useToast from 'hooks/useToast' import { ListProps } from 'types/bazaar' +import { getGoodsDetail } from 'services/bazaar' import Empty from 'components/Empty' import { useGetOfficialPage, useGetTradePage } from '../hooks' @@ -225,12 +226,22 @@ const Content: React.FC = () => { if (location.search) { const locationData = qs.parse(location.search.slice(1)) if (!locationData?.type) { - arr.forEach((item) => { - if (item.id === locationData.id) { - setDetail(item) - setDetailVisible(true) - } + const res = await getGoodsDetail(locationData.id) + console.log(res) + res.priceList = [] + Object.keys(res.price).forEach((childItem) => { + res.priceList.push({ label: childItem, value: res.price[childItem] }) }) + res.price = undefined + console.log(res) + setDetail(res) + setDetailVisible(true) + // arr.forEach((item) => { + // if (item.id === locationData.id) { + // setDetail(item) + // setDetailVisible(true) + // } + // }) } } setCount(getTotalPageNum(data.total, data.size)) diff --git a/src/views/Bazaar/components/SellModal.tsx b/src/views/Bazaar/components/SellModal.tsx index 8e1db73..20cdb92 100644 --- a/src/views/Bazaar/components/SellModal.tsx +++ b/src/views/Bazaar/components/SellModal.tsx @@ -40,40 +40,46 @@ interface CoverResourceProps { url?: string } +const MainContainer = styled.div` + position: relative; + z-index: 9999; +` +const CloseImage = styled(Image)` + cursor: pointer; + position: absolute; + bottom: -100px; + left: 50%; + margin-left: -25px; +` + const FlexMain = styled.div` - width: 70%; - min-height: 598px; + width: 480px; + /* min-height: 598px; */ overflow-y: auto; background: #fff; font-size: 18px; color: #999999; z-index: 9999; border-radius: 15px; - position: relative; ${({ theme }) => theme.mediaQueries.xs} { - width: 90%; + width: 350px; } ${({ theme }) => theme.mediaQueries.lg} { - width: 70%; + width: 480px; } ` -const CloseImage = styled(Image)` - cursor: pointer; - position: absolute; - top: 30px; - right: 30px; -` const HeaderText = styled(Text)` font-size: 24px; color: #333333; margin-top: 40px; text-align: center; + margin-bottom: 35px; ` const SelectFlex = styled(Flex)` align-items: center; justify-content: space-between; flex-wrap: wrap; - padding: 35px 100px 30px 100px; + padding: 0 40px; border-bottom: 1px solid #e3e3e3; ${({ theme }) => theme.mediaQueries.xs} { justify-content: center; @@ -150,7 +156,7 @@ const AddNftButton = styled(Button)` font-size: 14px; ` const ShopFlex = styled(Flex)` - width: 278px; + width: 248px; flex-direction: column; background: #fff; box-shadow: 0px 1px 8px rgba(0, 0, 0, 0.15); @@ -160,7 +166,7 @@ const ShopFlex = styled(Flex)` ` const ShopName = styled(Text)` - padding: 26px 0; + padding: 24px 29px 24px 29px; text-align: center; font-size: 18px; color: #666666; @@ -190,6 +196,7 @@ const SelectShopModal = styled(Flex)` ` const InputDiv = styled.div` position: relative; + margin-bottom: 20px; ` const InputText = styled(Text)` position: absolute; @@ -264,8 +271,8 @@ const SellModal: React.FC = ({ onDismiss, detailData }) => { toastError(t('Please enter price')) return } - if (Number(price) <= 0) { - toastError(t('The price is greater than %num%', { num: 0 })) + if (Number(price) < 1) { + toastError(t('The price is greater than %num%', { num: 1 })) return } if (sellingWay?.value === '2' && Number(time) < 0) { @@ -322,79 +329,81 @@ const SellModal: React.FC = ({ onDismiss, detailData }) => { }, [fastRefresh]) return ( - - - {t('sell NFT')} - - - - {sellingWay ? sellingWay.label : t('Selling way')} - - - } - > - {SellingWayList.map((item) => { - return ( - setSellingWay(item)}> - {item.label} - - ) - })} - - - - HCC - - {sellingWay?.value === '2' && ( + + + {t('sell NFT')} + + + + {sellingWay ? sellingWay.label : t('Selling way')} + + + } + > + {SellingWayList.map((item) => { + return ( + setSellingWay(item)}> + {item.label} + + ) + })} + - - {t('hour')} + + HCC + {sellingWay?.value === '2' && ( + + + {t('hour')} + + )} + + + + {/* isApprovedFor */} + {!shopData?.info?.id && {t('add NFT')}} + {shopData?.info?.id && ( + + + {shopData?.info?.name} + )} - - - - {/* isApprovedFor */} - {!shopData?.info?.id && {t('add NFT')}} - {shopData?.info?.id && ( - - - {shopData?.info?.name} - + {shopData?.info?.id && isApprovedFor && ( + + {t('Selling immediately')} + + )} + {shopData?.info?.id && {t('reselect NFT')}} + {shopData?.info?.id && !isApprovedFor && ( + + {t('license agreement')} + + )} + + {showModal && ( + + getShopDetail(v)} /> + )} - {shopData?.info?.id && isApprovedFor && ( - - {t('Selling immediately')} - - )} - {shopData?.info?.id && {t('reselect NFT')}} - {shopData?.info?.id && !isApprovedFor && ( - - {t('license agreement')} - - )} - - {showModal && ( - - getShopDetail(v)} /> - - )} - + + + ) } diff --git a/src/views/Bazaar/components/ShopDetail.tsx b/src/views/Bazaar/components/ShopDetail.tsx index abab6b8..4ac1889 100644 --- a/src/views/Bazaar/components/ShopDetail.tsx +++ b/src/views/Bazaar/components/ShopDetail.tsx @@ -89,7 +89,7 @@ const PriceButton = styled(Button)` background: linear-gradient(269deg, #1fc8d3 0%, #1fd4b0 100%); border-radius: 30px; font-size: 16px; - margin: 30px 0; + /* margin: 30px 0; */ ` const AuthorizationBtn = styled(Button)` width: 100%; @@ -106,10 +106,11 @@ const UnlockButtonDiv = styled(UnlockButton)` background: linear-gradient(269deg, #1fc8d3 0%, #1fd4b0 100%); border-radius: 30px; font-size: 16px; - margin: 30px 0; + /* margin: 30px 0; */ ` const DetailFlexInfo = styled(Flex)` flex-direction: column; + justify-content: space-between; width: 100%; height: 304px; background: #f5ffff; @@ -131,6 +132,7 @@ const ShopDetail: React.FC = ({ close, detail, typeIndex }) => { const { fastRefresh } = useRefresh() const account = useAccount() useEffect(() => { + console.log(detail) if (detail.priceList) { const priceList = detail.priceList.map((item) => { return `${Number(item.value).toFixed(3)} ${item.label}` @@ -175,7 +177,7 @@ const ShopDetail: React.FC = ({ close, detail, typeIndex }) => { item={detail} width={476} height={606} - img={detail?.coverResource.url} + img={detail?.coverResource?.url} grade={detail.grade} borderRadius="20px" /> diff --git a/src/views/Bazaar/components/ShopDetailBazaar.tsx b/src/views/Bazaar/components/ShopDetailBazaar.tsx index 131ad96..64a0cd5 100644 --- a/src/views/Bazaar/components/ShopDetailBazaar.tsx +++ b/src/views/Bazaar/components/ShopDetailBazaar.tsx @@ -159,6 +159,7 @@ const UnlockButtonDiv = styled(UnlockButton)` ` const DetailFlexInfo = styled(Flex)` flex-direction: column; + justify-content: space-between; width: 100%; height: 304px; background: #f5ffff; @@ -182,12 +183,14 @@ const ShopDetail: React.FC = ({ close, id, typeIndex }) => { CANCEL: t('Canceled'), STREAMING: t('abortive auction'), SUCCESS: t('success'), + BID_SUCCESS: t('The purchase'), } const statusHeaderTxt = { PENDING: t('They are in'), CANCEL: t('Canceled'), STREAMING: t('abortive auction'), SUCCESS: t('success'), + BID_SUCCESS: t('The purchase'), } const [loading, setLoading] = useState(false) @@ -377,7 +380,7 @@ const ShopDetail: React.FC = ({ close, id, typeIndex }) => { const getNft = async () => { setLoading(true) // const res = await executeOrder(detail.token, orderMapData?.bid) - const res = await executeOrder(orderMapData?.bidder, orderMapData?.bid) + const res = await executeOrder(detail.token, orderMapData?.bid) setTxExecuteId(res.hash) } const getOrderMap = async (token) => { @@ -453,7 +456,7 @@ const ShopDetail: React.FC = ({ close, id, typeIndex }) => { style={{ cursor: 'pointer' }} /> - {orderMapData?.expiresAt > new Date().getTime() && typeIndex === 2 && ( + {orderMapData?.expiresAt > new Date().getTime() && typeIndex === 2 && statusBtnTxt !== 'SUCCESS' && ( = ({ close, id, typeIndex }) => { textColor="#666666" /> )} - {typeIndex !== 2 && ( + {typeIndex !== 2 && statusBtnTxt !== 'SUCCESS' && statusBtnTxt !== 'CANCEL' && ( = ({ close, id, typeIndex }) => { textColor="#1FC7D4" /> )} - {typeIndex === 2 && ( + {typeIndex !== 2 && statusBtnTxt === 'SUCCESS' && ( + + )} + {typeIndex !== 2 && statusBtnTxt === 'CANCEL' && ( + + )} + {typeIndex === 2 && + statusBtnTxt !== 'SUCCESS' && + statusBtnTxt !== 'CANCEL' && + statusBtnTxt !== 'BID_SUCCESS' && ( + // + new Date().getTime() + ? `${t('The latest offer')}(HCC)` + : t('present price%price%', { price: '(HCC)' }) + } + // value={detail?.price} + value={orderMapData?.bidder === '0' ? orderMapData?.price : orderMapData?.bid} + size="18px" + rightSize="30px" + textColor="#1FC7D4" + /> + )} + {/* 竞拍成功之后使用接口数据 */} + {typeIndex === 2 && (statusBtnTxt === 'SUCCESS' || statusBtnTxt === 'BID_SUCCESS') && ( // new Date().getTime() - ? `${t('The latest offer')}(HCC)` - : t('present price%price%', { price: '(HCC)' }) - } + name={`${t('transaction price')}(HCC)`} // value={detail?.price} - value={orderMapData?.bidder === '0' ? orderMapData?.price : orderMapData?.bid} + value={detail?.price} + size="18px" + rightSize="30px" + textColor="#1FC7D4" + /> + )} + {typeIndex === 2 && statusBtnTxt === 'CANCEL' && ( + // + = ({ close, id, typeIndex }) => { )} {/* 改版 */} {/* 竞拍取消挂单:没有人竞拍时 */} - {account && allowance && ownOrder && orderMapData?.bidder === '0' ? ( + {account && + allowance && + ownOrder && + orderMapData?.bidder === '0' && + statusBtnTxt !== 'STREAMING' && + statusBtnTxt !== 'SUCCESS' ? ( {statusTxt[statusBtnTxt]} + ) : account && + allowance && + ownOrder && + orderMapData?.bidder === '0' && + statusBtnTxt !== 'STREAMING' && + statusBtnTxt === 'SUCCESS' ? ( + {statusTxt[statusBtnTxt]} + ) : ( + '' + )} + {account && allowance && ownOrder && orderMapData?.bidder === '0' && statusBtnTxt === 'STREAMING' ? ( + + {t('Cancel the deity')} + ) : ( '' )} @@ -530,14 +598,20 @@ const ShopDetail: React.FC = ({ close, id, typeIndex }) => { ) : ( '' )} - {bidAuctionStatus && ( + {bidAuctionStatus && statusBtnTxt !== 'SUCCESS' ? ( {t('Fixed markup (%price% premium)', { price: '10%' })} + ) : bidAuctionStatus && statusBtnTxt === 'SUCCESS' ? ( + + {statusTxt[statusBtnTxt]} + + ) : ( + '' )} {account && orderMapData?.expiresAt < new Date().getTime() && - account === orderMapData?.bidder && + account.toLowerCase() === orderMapData?.bidder.toLowerCase() && typeIndex === 2 ? ( {t('Claim now')} diff --git a/src/views/Bazaar/components/ShopModal.tsx b/src/views/Bazaar/components/ShopModal.tsx index b445d65..df5fb0b 100644 --- a/src/views/Bazaar/components/ShopModal.tsx +++ b/src/views/Bazaar/components/ShopModal.tsx @@ -38,21 +38,24 @@ interface CoverResourceProps { url?: string } const Main = styled.div` - width: 60%; + width: 890px; background-color: #fff; - padding: 30px 15px; border-radius: 30px; + /* padding-top: 30px; */ /* height: 80%; */ z-index: 10; ` const Shop = styled.div` + padding: 30px 30px 0 30px; + max-height: 544px; width: 100%; display: grid; - gap: 18px; + gap: 9px; grid-template-rows: 1fr; margin: 0px auto; grid-template-columns: repeat(4, 1fr); box-sizing: border-box; + overflow-y: auto; & > .active { border: 3px solid #0deeff; } @@ -69,14 +72,15 @@ const Shop = styled.div` ` const ShopFlex = styled(Flex)` flex-direction: column; + width: 198px; + height: 252px; background: rgba(255, 255, 255, 0.39); box-shadow: 0px 1px 8px rgba(0, 0, 0, 0.15); - opacity: 1; border-radius: 20px; position: relative; ` const ShopName = styled(Text)` - padding: 26px 0; + padding: 10px 0; text-align: center; font-size: 18px; color: #666666; @@ -86,8 +90,8 @@ const SelectFlex = styled(Flex)` position: absolute; top: 10px; right: 10px; - width: 30px; - height: 30px; + width: 20px; + height: 20px; background: #fff; box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.16); border-radius: 50%; @@ -96,8 +100,8 @@ const SelectFlex = styled(Flex)` justify-content: center; ` const SelectDiv = styled.div` - width: 15px; - height: 15px; + width: 10px; + height: 10px; background: #0deeff; border-radius: 50%; margin-left: 1px; @@ -190,8 +194,8 @@ const ShopModal: React.FC = ({ name, value, onDismiss, close, add }) = @@ -201,7 +205,7 @@ const ShopModal: React.FC = ({ name, value, onDismiss, close, add }) = })} {list?.length > 0 && ( - + )} diff --git a/src/views/Bazaar/components/Transaction.tsx b/src/views/Bazaar/components/Transaction.tsx index 54d9892..7d8a938 100644 --- a/src/views/Bazaar/components/Transaction.tsx +++ b/src/views/Bazaar/components/Transaction.tsx @@ -68,17 +68,17 @@ const Transaction: React.FC = () => { return ( - {Number(detail?.tradeAmount).toFixed(3)} + {Math.round(Number(detail?.tradeAmount))} {t('The total volume')} - {detail?.tradeTimes} + {detail?.tradeTimes || 0} {t('The total number of transactions')} - {detail?.auctionTimes} + {detail?.auctionTimes || 0} {t('Total number of auctions')} {/* diff --git a/src/views/Bazaar/components/TransactionRecord.tsx b/src/views/Bazaar/components/TransactionRecord.tsx index ef9cddc..0aff56b 100644 --- a/src/views/Bazaar/components/TransactionRecord.tsx +++ b/src/views/Bazaar/components/TransactionRecord.tsx @@ -15,7 +15,7 @@ interface TransactionRecordProps { } const FlexMain = styled.div` - width: 70%; + width: 1062px; height: 658px; background: #fff; font-size: 18px; @@ -98,6 +98,10 @@ const TdFlex = styled(Flex)` white-space: nowrap; text-overflow: ellipsis; ` +const PriceText = styled(Text)` + color: #666666; + font-size: 14px; +` const TdBtnFlex = styled(Flex)` width: 20%; flex-direction: column; @@ -261,14 +265,14 @@ const TransactionRecord: React.FC = ({ onDismiss, active {list.map((item) => { return ( - {item.goodsName} + {`${item.goodsName}(#${item.token})`} {activeIndex === 0 && ( {item.priceList.map((childItem, childIndex) => { return ( <>{Number(childItem.value).toFixed(2)} - {childItem.label} + {childItem.label} {childIndex === 0 && item.priceList.length === 2 && -} ) diff --git a/src/views/Bazaar/hooks/index.ts b/src/views/Bazaar/hooks/index.ts index c004132..6e8ecf0 100644 --- a/src/views/Bazaar/hooks/index.ts +++ b/src/views/Bazaar/hooks/index.ts @@ -202,6 +202,7 @@ export const useExecuteOrder = () => { const transaction = async (tokenId, price) => { const hccMarketplaceAddress = getHccMarketplaceAddress() const mintParams = [tokenId, getDecimalAmount(price).toString()] + console.log(mintParams) const res = await hccMarketplace.executeOrder(...mintParams) return res } @@ -243,6 +244,7 @@ export const useOrderMap = () => { bid: getBalanceNumber(item.bid._hex), } }) + console.log(arr[0]) return arr[0] } return transaction