对接nft市场
This commit is contained in:
parent
08bd178bf5
commit
f565316323
|
|
@ -1256,7 +1256,7 @@
|
|||
"Selling time": "出售时间",
|
||||
"Add as a trading pair": "添加为交易对",
|
||||
"reselect NFT": "重新选择NFT",
|
||||
"Auction countdown": "拍卖倒计时",
|
||||
"Auction remaining time": "拍卖剩余时间",
|
||||
"present price%price%": "当前价格%price%",
|
||||
"Fixed markup (%price% premium)": "固定加价(%price%溢价)",
|
||||
"owner": "拥有者",
|
||||
|
|
@ -1285,5 +1285,20 @@
|
|||
"PROPS": "道具",
|
||||
"rarity": "稀有度",
|
||||
"success": "成功",
|
||||
"Exchange closed": "兑换已结束"
|
||||
"Exchange closed": "兑换已结束",
|
||||
"Have they": "已挂单",
|
||||
"Cancel the deity": "取消挂单",
|
||||
"abortive auction": "流拍",
|
||||
"out": "出局",
|
||||
"For successful": "竞价成功",
|
||||
"Please enter the time": "请输入时间",
|
||||
"Please enter price": "请输入价格",
|
||||
"hour": "小时",
|
||||
"Selling rules": "售卖规则",
|
||||
"1.NFT may not be traded or transferred at the time of sale": "1.NFT在出售挂单时不可进行交易或转让",
|
||||
"2. After the successful sale of NFT, the platform will charge the publisher 6% of the profits as a commission fee": "2.NFT出售成功后,平台将收取发布人收益的6%作为手续费",
|
||||
"order status": "订单状态",
|
||||
"Asking price": "起拍价格",
|
||||
"Can't be less than %num%": "不能小于%num%",
|
||||
"They are in": "挂单中"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ const Menu = (props) => {
|
|||
}, [userInfo])
|
||||
const sign = useSignLogin()
|
||||
const handleLogin = async (connectorID: ConnectorNames) => {
|
||||
console.log(connectorID)
|
||||
await login(connectorID)
|
||||
setHasWalletLogin(true)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,388 @@
|
|||
[
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "address", "name": "_hccToken", "type": "address" },
|
||||
{ "internalType": "address", "name": "_owner", "type": "address" },
|
||||
{ "internalType": "address", "name": "_teamAddress", "type": "address" },
|
||||
{ "internalType": "address", "name": "_nftAddress", "type": "address" }
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [{ "indexed": false, "internalType": "uint256", "name": "bidLimit", "type": "uint256" }],
|
||||
"name": "ChangedBidLimit",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{ "indexed": false, "internalType": "uint256", "name": "extensionTime", "type": "uint256" },
|
||||
{ "indexed": false, "internalType": "uint256", "name": "extensionTimeLimit", "type": "uint256" }
|
||||
],
|
||||
"name": "ChangedExtensionTimeAndLimit",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [{ "indexed": false, "internalType": "uint256", "name": "publicationFee", "type": "uint256" }],
|
||||
"name": "ChangedPublicationFee",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [{ "indexed": false, "internalType": "address", "name": "teamAddress", "type": "address" }],
|
||||
"name": "ChangedTeamAddress",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [{ "indexed": false, "internalType": "uint256", "name": "tradeFee", "type": "uint256" }],
|
||||
"name": "ChangedTradeFee",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{ "indexed": false, "internalType": "address", "name": "userAddress", "type": "address" },
|
||||
{ "indexed": false, "internalType": "address", "name": "relayerAddress", "type": "address" },
|
||||
{ "indexed": false, "internalType": "bytes", "name": "functionSignature", "type": "bytes" }
|
||||
],
|
||||
"name": "MetaTransactionExecuted",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{ "indexed": false, "internalType": "bytes32", "name": "id", "type": "bytes32" },
|
||||
{ "indexed": true, "internalType": "address", "name": "bidder", "type": "address" },
|
||||
{ "indexed": false, "internalType": "uint256", "name": "latestPrice", "type": "uint256" }
|
||||
],
|
||||
"name": "OrderBidFailed",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{ "indexed": false, "internalType": "bytes32", "name": "id", "type": "bytes32" },
|
||||
{ "indexed": true, "internalType": "uint256", "name": "assetId", "type": "uint256" },
|
||||
{ "indexed": true, "internalType": "address", "name": "seller", "type": "address" },
|
||||
{ "indexed": true, "internalType": "address", "name": "bidder", "type": "address" },
|
||||
{ "indexed": false, "internalType": "uint256", "name": "latestPrice", "type": "uint256" },
|
||||
{ "indexed": false, "internalType": "uint256", "name": "expiresAt", "type": "uint256" },
|
||||
{ "indexed": false, "internalType": "uint256", "name": "timestamp", "type": "uint256" }
|
||||
],
|
||||
"name": "OrderBidSuccess",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{ "indexed": false, "internalType": "bytes32", "name": "id", "type": "bytes32" },
|
||||
{ "indexed": true, "internalType": "uint256", "name": "assetId", "type": "uint256" },
|
||||
{ "indexed": true, "internalType": "address", "name": "seller", "type": "address" }
|
||||
],
|
||||
"name": "OrderCancelled",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{ "indexed": false, "internalType": "uint256", "name": "tpe", "type": "uint256" },
|
||||
{ "indexed": false, "internalType": "bytes32", "name": "id", "type": "bytes32" },
|
||||
{ "indexed": true, "internalType": "uint256", "name": "assetId", "type": "uint256" },
|
||||
{ "indexed": true, "internalType": "address", "name": "seller", "type": "address" },
|
||||
{ "indexed": false, "internalType": "uint256", "name": "price", "type": "uint256" },
|
||||
{ "indexed": false, "internalType": "uint256", "name": "expiresAt", "type": "uint256" }
|
||||
],
|
||||
"name": "OrderCreated",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{ "indexed": false, "internalType": "bytes32", "name": "id", "type": "bytes32" },
|
||||
{ "indexed": true, "internalType": "uint256", "name": "assetId", "type": "uint256" },
|
||||
{ "indexed": true, "internalType": "address", "name": "seller", "type": "address" },
|
||||
{ "indexed": false, "internalType": "uint256", "name": "price", "type": "uint256" },
|
||||
{ "indexed": true, "internalType": "address", "name": "buyer", "type": "address" },
|
||||
{ "indexed": false, "internalType": "uint256", "name": "timestamp", "type": "uint256" }
|
||||
],
|
||||
"name": "OrderSuccessful",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{ "indexed": true, "internalType": "address", "name": "previousOwner", "type": "address" },
|
||||
{ "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" }
|
||||
],
|
||||
"name": "OwnershipTransferred",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [{ "indexed": false, "internalType": "address", "name": "account", "type": "address" }],
|
||||
"name": "Paused",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [{ "indexed": false, "internalType": "address", "name": "account", "type": "address" }],
|
||||
"name": "Unpaused",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "ERC721_Interface",
|
||||
"outputs": [{ "internalType": "bytes4", "name": "", "type": "bytes4" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InterfaceId_ValidateFingerprint",
|
||||
"outputs": [{ "internalType": "bytes4", "name": "", "type": "bytes4" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "ORDER_TYPE_AUCTION",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "ORDER_TYPE_NORMAL",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "assetId", "type": "uint256" },
|
||||
{ "internalType": "uint256", "name": "bid", "type": "uint256" }
|
||||
],
|
||||
"name": "bidAuctionOrder",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "bidLimit",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [{ "internalType": "uint256", "name": "assetId", "type": "uint256" }],
|
||||
"name": "cancelOrder",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "assetId", "type": "uint256" },
|
||||
{ "internalType": "uint256", "name": "priceInWei", "type": "uint256" },
|
||||
{ "internalType": "uint256", "name": "expiresAt", "type": "uint256" }
|
||||
],
|
||||
"name": "createAuctionOrder",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "assetId", "type": "uint256" },
|
||||
{ "internalType": "uint256", "name": "priceInWei", "type": "uint256" }
|
||||
],
|
||||
"name": "createNormalOrder",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "domainSeparator",
|
||||
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "address", "name": "userAddress", "type": "address" },
|
||||
{ "internalType": "bytes", "name": "functionSignature", "type": "bytes" },
|
||||
{ "internalType": "bytes32", "name": "sigR", "type": "bytes32" },
|
||||
{ "internalType": "bytes32", "name": "sigS", "type": "bytes32" },
|
||||
{ "internalType": "uint8", "name": "sigV", "type": "uint8" }
|
||||
],
|
||||
"name": "executeMetaTransaction",
|
||||
"outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],
|
||||
"stateMutability": "payable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "assetId", "type": "uint256" },
|
||||
{ "internalType": "uint256", "name": "price", "type": "uint256" }
|
||||
],
|
||||
"name": "executeOrder",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "extensionTime",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "extensionTimeLimit",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "getChainId",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [{ "internalType": "address", "name": "user", "type": "address" }],
|
||||
"name": "getNonce",
|
||||
"outputs": [{ "internalType": "uint256", "name": "nonce", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "hccToken",
|
||||
"outputs": [{ "internalType": "contract ERC20Interface", "name": "", "type": "address" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "nftAddress",
|
||||
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"name": "orderMap",
|
||||
"outputs": [
|
||||
{ "internalType": "uint256", "name": "tpe", "type": "uint256" },
|
||||
{ "internalType": "bytes32", "name": "id", "type": "bytes32" },
|
||||
{ "internalType": "address", "name": "seller", "type": "address" },
|
||||
{ "internalType": "uint256", "name": "price", "type": "uint256" },
|
||||
{ "internalType": "address", "name": "bidder", "type": "address" },
|
||||
{ "internalType": "uint256", "name": "bid", "type": "uint256" },
|
||||
{ "internalType": "uint256", "name": "expiresAt", "type": "uint256" }
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "owner",
|
||||
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "paused",
|
||||
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "publicationFeeInWei",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{ "inputs": [], "name": "renounceOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" },
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "assetId", "type": "uint256" },
|
||||
{ "internalType": "uint256", "name": "price", "type": "uint256" },
|
||||
{ "internalType": "bytes", "name": "fingerprint", "type": "bytes" }
|
||||
],
|
||||
"name": "safeExecuteOrder",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [{ "internalType": "uint256", "name": "_bidLimit", "type": "uint256" }],
|
||||
"name": "setBidLimit",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "_extensionTime", "type": "uint256" },
|
||||
{ "internalType": "uint256", "name": "_extensionTimeLimit", "type": "uint256" }
|
||||
],
|
||||
"name": "setExtensionTimeAndLimit",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [{ "internalType": "uint256", "name": "_publicationFee", "type": "uint256" }],
|
||||
"name": "setPublicationFee",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [{ "internalType": "address", "name": "_teamAddress", "type": "address" }],
|
||||
"name": "setTeamAddress",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [{ "internalType": "uint256", "name": "_tradeFee", "type": "uint256" }],
|
||||
"name": "setTradeFee",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "teamAddress",
|
||||
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "tradeFee",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }],
|
||||
"name": "transferOwnership",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
|
|
@ -49,6 +49,11 @@ export default {
|
|||
56: '0x2f562A9fE0325501A6Aa92cd9e2081B026fC35aa', // NEED CHANGE IDO兑换
|
||||
5: '0x81cdaf31147b86ffe6303b1bde6f20a5377d87b1',
|
||||
},
|
||||
hccMarketplace: {
|
||||
97: '0x91b9a998eedbb513f86b7d2a8efc01624a6d9636',
|
||||
56: '0x75c6c866f9f4ba6d0cad39d29f8e54a7ec64afb8', // NEED CHANGE NFT市场
|
||||
5: '0x8678a822dfa815da423517b315641ef7f20020d7',
|
||||
},
|
||||
blindBox: {
|
||||
97: '0x0e226d7b83b511ce224803b1330beb4a59bfa5d6',
|
||||
56: '0x0e226d7b83b511ce224803b1330beb4a59bfa5d6', // NEED CHANGE 官方市场 盲盒
|
||||
|
|
|
|||
|
|
@ -1383,7 +1383,7 @@
|
|||
"Selling time": "Selling time",
|
||||
"Add as a trading pair": "Add as a trading pair",
|
||||
"reselect NFT": "reselect NFT",
|
||||
"Auction countdown": "Auction countdown",
|
||||
"Auction remaining time": "Auction remaining time",
|
||||
"present price%price%": "present price%price%",
|
||||
"Fixed markup (%price% premium)": "Fixed markup (%price% premium)",
|
||||
"owner": "owner",
|
||||
|
|
@ -1412,5 +1412,20 @@
|
|||
"PROPS": "PROPS",
|
||||
"rarity": "rarity",
|
||||
"success": "success",
|
||||
"Exchange closed": "Exchange closed"
|
||||
"Exchange closed": "Exchange closed",
|
||||
"Have they": "Have they",
|
||||
"Cancel the deity": "Cancel the deity",
|
||||
"abortive auction": "abortive auction",
|
||||
"out": "out",
|
||||
"For successful": "For successful",
|
||||
"Please enter the time": "Please enter the time",
|
||||
"Please enter price": "Please enter price",
|
||||
"hour": "hour",
|
||||
"Selling rules": "Selling rules",
|
||||
"1.NFT may not be traded or transferred at the time of sale": "1.NFT may not be traded or transferred at the time of sale",
|
||||
"2. After the successful sale of NFT, the platform will charge the publisher 6% of the profits as a commission fee": "2. After the successful sale of NFT, the platform will charge the publisher 6% of the profits as a commission fee",
|
||||
"order status": "order status",
|
||||
"Asking price": "Asking price",
|
||||
"Can't be less than %num%": "Can't be less than %num%",
|
||||
"They are in": "They are in"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import {
|
|||
getIdoPurchaseContract,
|
||||
getBlindBoxContract,
|
||||
getHolderPoolContract,
|
||||
getHccMarketplaceContract,
|
||||
} from 'utils/contractHelpers'
|
||||
|
||||
// Imports below migrated from Exchange useContract.ts
|
||||
|
|
@ -124,6 +125,10 @@ export const useHolderPool = () => {
|
|||
const { library } = useActiveWeb3React()
|
||||
return useMemo(() => getHolderPoolContract(library.getSigner()), [library])
|
||||
}
|
||||
export const useHccMarketplace = () => {
|
||||
const { library } = useActiveWeb3React()
|
||||
return useMemo(() => getHccMarketplaceContract(library.getSigner()), [library])
|
||||
}
|
||||
export const useReferralRewardchef = () => {
|
||||
const { library } = useActiveWeb3React()
|
||||
return useMemo(() => getReferralRewardchefContract(library.getSigner()), [library])
|
||||
|
|
|
|||
|
|
@ -36,4 +36,61 @@ export const getNftDetail = (id, params) => {
|
|||
params,
|
||||
})
|
||||
}
|
||||
export const getTradePage = (params) => {
|
||||
return request.request({
|
||||
url: `/high_city/app/api/market/trade/page`,
|
||||
method: 'get',
|
||||
params,
|
||||
})
|
||||
}
|
||||
export const marketTradeCreateOrderTx = (params) => {
|
||||
return request.request({
|
||||
url: `/high_city/app/api/market/trade/create/order/tx`,
|
||||
method: 'get',
|
||||
params,
|
||||
})
|
||||
}
|
||||
export const marketTradeRecordDetail = (id) => {
|
||||
return request.request({
|
||||
url: `/high_city/app/api/market/trade/record/detail/${id}`,
|
||||
method: 'get',
|
||||
params: { id },
|
||||
})
|
||||
}
|
||||
export const cancelOrderTx = (tx) => {
|
||||
return request.request({
|
||||
url: `/high_city/app/api/market/trade/cancel/order/tx`,
|
||||
method: 'get',
|
||||
params: { tx },
|
||||
})
|
||||
}
|
||||
export const executeOrderTx = (tx) => {
|
||||
return request.request({
|
||||
url: `/high_city/app/api/market/trade/execute/order/tx`,
|
||||
method: 'get',
|
||||
params: { tx },
|
||||
})
|
||||
}
|
||||
export const bidOrderTx = (tx) => {
|
||||
return request.request({
|
||||
url: `/high_city/app/api/market/trade/bid/order/tx`,
|
||||
method: 'get',
|
||||
params: { tx },
|
||||
})
|
||||
}
|
||||
export const tradeRecord = (params) => {
|
||||
return request.request({
|
||||
url: `/high_city/app/api/market/trade/record/option/page/${params.id}`,
|
||||
method: 'get',
|
||||
params,
|
||||
})
|
||||
}
|
||||
export const tradeRecordPage = (params) => {
|
||||
return request.request({
|
||||
url: `/high_city/app/api/market/trade/record/page`,
|
||||
method: 'get',
|
||||
params,
|
||||
})
|
||||
}
|
||||
|
||||
export default getOfficialPage
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
import { createSlice } from '@reduxjs/toolkit'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import erc20ABI from 'config/abi/erc20.json'
|
||||
import multicall from 'utils/multicall'
|
||||
import tokens from 'config/constants/tokens'
|
||||
import { getAddress, getHccMarketplaceAddress } from 'utils/addressHelpers'
|
||||
|
||||
export const fetchBazaarUserAllowances = async (account: string) => {
|
||||
const tokenAddresses = getAddress(tokens.hcc.address)
|
||||
const hccMarketplaceAddress = getHccMarketplaceAddress()
|
||||
const calls = [{ address: tokenAddresses, name: 'allowance', params: [account, hccMarketplaceAddress] }]
|
||||
const rawLpAllowances = await multicall(erc20ABI, calls)
|
||||
const parsedLpAllowances = rawLpAllowances.map((balance) => {
|
||||
return new BigNumber(balance).toNumber()
|
||||
})
|
||||
return {
|
||||
hcc: parsedLpAllowances[0],
|
||||
}
|
||||
}
|
||||
|
||||
export default fetchBazaarUserAllowances
|
||||
|
|
@ -13,8 +13,8 @@ const payWayList = {
|
|||
export const fetchBlindBoxUserAllowances = async (account: string) => {
|
||||
const calls = Object.values(payWayList).map((payWayItem) => {
|
||||
const tokenAddresses = getAddress(payWayItem.address)
|
||||
const referralChefAddress = getBlindBoxAddress()
|
||||
return { address: tokenAddresses, name: 'allowance', params: [account, referralChefAddress] }
|
||||
const blindBoxAddress = getBlindBoxAddress()
|
||||
return { address: tokenAddresses, name: 'allowance', params: [account, blindBoxAddress] }
|
||||
})
|
||||
|
||||
const rawLpAllowances = await multicall(erc20ABI, calls)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,12 @@ export interface ListProps {
|
|||
priceList?: PriceProps[]
|
||||
type?: string
|
||||
record?: boolean
|
||||
token?: string
|
||||
|
||||
goodsName?: string
|
||||
goodsType?: string
|
||||
goodsId?: string
|
||||
goodsGrade?: string
|
||||
}
|
||||
export interface CoverResourceProps {
|
||||
path?: string
|
||||
|
|
|
|||
|
|
@ -77,6 +77,9 @@ export const getBunnySpecialPredictionAddress = () => {
|
|||
export const getIdoPurchaseAddress = () => {
|
||||
return getAddress(addresses.idoPurchase)
|
||||
}
|
||||
export const getHccMarketplaceAddress = () => {
|
||||
return getAddress(addresses.hccMarketplace)
|
||||
}
|
||||
export const getBlindBoxAddress = () => {
|
||||
return getAddress(addresses.blindBox)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import {
|
|||
getReferralAddress,
|
||||
getReferralRewardAddress,
|
||||
getIdoPurchaseAddress,
|
||||
getHccMarketplaceAddress,
|
||||
getBlindBoxAddress,
|
||||
getHolderPoolAddress,
|
||||
} from 'utils/addressHelpers'
|
||||
|
|
@ -63,6 +64,7 @@ import MultiCallAbi from 'config/abi/Multicall.json'
|
|||
import bunnySpecialCakeVaultAbi from 'config/abi/bunnySpecialCakeVault.json'
|
||||
import bunnySpecialPredictionAbi from 'config/abi/bunnySpecialPrediction.json'
|
||||
import idoPurchase from 'config/abi/idoPurchase.json'
|
||||
import hccMarketplace from 'config/abi/hccMarketplace.json'
|
||||
import holderPool from 'config/abi/holderPool.json'
|
||||
import blindBox from 'config/abi/blindBox.json'
|
||||
import { ChainLinkOracleContract, PredictionsContract } from './types'
|
||||
|
|
@ -136,6 +138,9 @@ export const getReferralRewardchefContract = (signer?: ethers.Signer | ethers.pr
|
|||
export const getIdoPurchaseContract = (signer?: ethers.Signer | ethers.providers.Provider) => {
|
||||
return getContract(idoPurchase, getIdoPurchaseAddress(), signer)
|
||||
}
|
||||
export const getHccMarketplaceContract = (signer?: ethers.Signer | ethers.providers.Provider) => {
|
||||
return getContract(hccMarketplace, getHccMarketplaceAddress(), signer)
|
||||
}
|
||||
export const getHolderPoolContract = (signer?: ethers.Signer | ethers.providers.Provider) => {
|
||||
return getContract(holderPool, getHolderPoolAddress(), signer)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ import FlexCom from './FlexCom'
|
|||
|
||||
interface DetailProps {
|
||||
typeIndex: number
|
||||
tokenId?: string
|
||||
address?: string
|
||||
}
|
||||
|
||||
const DetailFlex = styled(Flex)`
|
||||
|
|
@ -20,7 +22,7 @@ const DetailFlex = styled(Flex)`
|
|||
margin-top: 24px;
|
||||
`
|
||||
|
||||
const AssetsInfo: React.FC<DetailProps> = ({ typeIndex }) => {
|
||||
const AssetsInfo: React.FC<DetailProps> = ({ typeIndex, tokenId, address }) => {
|
||||
const { t } = useTranslation()
|
||||
const [link, setLink] = useState('')
|
||||
|
||||
|
|
@ -34,13 +36,13 @@ const AssetsInfo: React.FC<DetailProps> = ({ typeIndex }) => {
|
|||
|
||||
return (
|
||||
<DetailFlex>
|
||||
{typeIndex !== 0 && <FlexCom name={t('owner')} value="钱包地址" />}
|
||||
{typeIndex !== 0 && <FlexCom name={t('owner')} value={address} />}
|
||||
<FlexCom
|
||||
name={t('Contract address')}
|
||||
typeLink={`https://bscscan.com/token/${link}`}
|
||||
value={`${link && link.substring(0, 6)}...${link && link.substring(link.length - 4, link.length)}`}
|
||||
value={`${link && link.substring(0, 6)}....${link && link.substring(link.length - 6, link.length)}`}
|
||||
/>
|
||||
{typeIndex !== 0 && <FlexCom name="token ID" value="token ID" />}
|
||||
{typeIndex !== 0 && <FlexCom name="token ID" value={`#${tokenId}`} />}
|
||||
<FlexCom name={t('Assets agreement')} value="ERC721" />
|
||||
<FlexCom name={t('Assets and chain')} value="BSC" />
|
||||
</DetailFlex>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,24 @@
|
|||
import React, { useState } from 'react'
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import styled from 'styled-components'
|
||||
import Pagination from '@mui/material/Pagination'
|
||||
import { Text, Button, Image, Flex } from '@pancakeswap/uikit'
|
||||
import { useTranslation } from 'contexts/Localization'
|
||||
import { tradeRecordPage } from 'services/bazaar'
|
||||
import Empty from 'components/Empty'
|
||||
|
||||
interface AuctionRecordProps {
|
||||
onDismiss?: () => void
|
||||
recordDetail?: (v) => void
|
||||
}
|
||||
interface ListProps {
|
||||
goodsName?: string
|
||||
id?: string
|
||||
lastPrice?: string
|
||||
price?: string
|
||||
status?: string
|
||||
token?: string
|
||||
tx?: string
|
||||
updatedAt?: string
|
||||
}
|
||||
|
||||
const FlexMain = styled.div`
|
||||
|
|
@ -70,7 +84,10 @@ const ThemedItem = styled.div`
|
|||
color: #666666;
|
||||
border-top: 1px solid #e3e3e3;
|
||||
`
|
||||
const TableBody = styled.div``
|
||||
const TableBody = styled.div`
|
||||
height: 350px;
|
||||
overflow-y: auto;
|
||||
`
|
||||
const TrFlex = styled(Flex)`
|
||||
/* height: 80px; */
|
||||
padding: 10px 0;
|
||||
|
|
@ -113,15 +130,18 @@ const HashText = styled(Text)`
|
|||
border-bottom: 1px solid #1fc7d4;
|
||||
`
|
||||
|
||||
const AuctionRecord: React.FC<AuctionRecordProps> = ({ onDismiss }) => {
|
||||
const AuctionRecord: React.FC<AuctionRecordProps> = ({ onDismiss, recordDetail }) => {
|
||||
const { t } = useTranslation()
|
||||
const [count, setCount] = useState(undefined)
|
||||
|
||||
const typeList = [
|
||||
{ label: t('All transactions'), value: '1' },
|
||||
{ label: t('I released'), value: '2' },
|
||||
{ label: t('I participate in'), value: '3' },
|
||||
{ label: t('All transactions'), value: '' },
|
||||
{ label: t('I released'), value: 'PUBLISH' },
|
||||
{ label: t('I participate in'), value: 'PARTICIPATE' },
|
||||
]
|
||||
const [typeIndex, setTypeIndex] = useState(0)
|
||||
const [pageNum, setPage] = useState(1)
|
||||
const [list, setList] = useState<ListProps[]>()
|
||||
|
||||
const ThemedList = [
|
||||
t('NFT name'),
|
||||
|
|
@ -131,18 +151,48 @@ const AuctionRecord: React.FC<AuctionRecordProps> = ({ onDismiss }) => {
|
|||
t('state'),
|
||||
t('operation'),
|
||||
]
|
||||
const statusTxt = {
|
||||
PENDING: t('They are in'),
|
||||
CANCEL: t('Canceled'),
|
||||
STREAMING: t('abortive auction'),
|
||||
SUCCESS: t('success'),
|
||||
end: t('finished'),
|
||||
}
|
||||
|
||||
const list = [
|
||||
{
|
||||
name: 'Cat goddess Emerald ',
|
||||
icon: '',
|
||||
price: '1',
|
||||
newPrice: '2',
|
||||
time: '2022-02-02',
|
||||
status: '已售卖',
|
||||
id: '1',
|
||||
},
|
||||
]
|
||||
const getList = async () => {
|
||||
setList([])
|
||||
const res = await tradeRecordPage({
|
||||
page: pageNum,
|
||||
size: 4,
|
||||
type: 'AUCTION',
|
||||
relationType: typeList[typeIndex].value,
|
||||
})
|
||||
setCount(getTotalPageNum(res.total, 4))
|
||||
setList([...res.content])
|
||||
}
|
||||
|
||||
const getTotalPageNum = (total, pageSize) => {
|
||||
const countTotal = ((Number(total) + Number(pageSize) - 1) / Number(pageSize)).toString()
|
||||
return parseInt(countTotal)
|
||||
}
|
||||
const pageChange = (event, page) => {
|
||||
setPage(page)
|
||||
}
|
||||
useEffect(() => {
|
||||
getList()
|
||||
}, [pageNum, typeIndex])
|
||||
const goHash = (val) => {
|
||||
window.open(`https://goerli.etherscan.io/tx/${val.tx}`)
|
||||
}
|
||||
|
||||
const changeType = async (index) => {
|
||||
setTypeIndex(index)
|
||||
setPage(1)
|
||||
}
|
||||
const lookDetail = async (item) => {
|
||||
recordDetail(item)
|
||||
onDismiss()
|
||||
}
|
||||
|
||||
return (
|
||||
<FlexMain>
|
||||
|
|
@ -154,7 +204,7 @@ const AuctionRecord: React.FC<AuctionRecordProps> = ({ onDismiss }) => {
|
|||
<TypeItem
|
||||
key={item.value}
|
||||
className={index === typeIndex ? 'active' : ''}
|
||||
onClick={() => setTypeIndex(index)}
|
||||
onClick={() => changeType(index)}
|
||||
>
|
||||
{item.label}
|
||||
</TypeItem>
|
||||
|
|
@ -168,24 +218,32 @@ const AuctionRecord: React.FC<AuctionRecordProps> = ({ onDismiss }) => {
|
|||
})}
|
||||
</TableThemed>
|
||||
<TableBody>
|
||||
{list.map((item) => {
|
||||
return (
|
||||
<TrFlex key={item.id}>
|
||||
<TdFlex>
|
||||
<TdImage src="/images/nft/epic-icon.svg" width={24} height={40} />
|
||||
{item.name}
|
||||
</TdFlex>
|
||||
<TdFlex>{item.price}</TdFlex>
|
||||
<TdFlex>{item.newPrice}</TdFlex>
|
||||
<TdFlex>{item.time}</TdFlex>
|
||||
<TdFlex>{item.status}</TdFlex>
|
||||
<TdBtnFlex>
|
||||
<DetailButton>{t('Detail')}</DetailButton>
|
||||
<HashText>{t('deal Hash')}</HashText>
|
||||
</TdBtnFlex>
|
||||
</TrFlex>
|
||||
)
|
||||
})}
|
||||
{list?.length > 0 &&
|
||||
list.map((item) => {
|
||||
return (
|
||||
<TrFlex key={item.id}>
|
||||
<TdFlex>
|
||||
{/* <TdImage src="/images/nft/epic-icon.svg" width={24} height={40} /> */}
|
||||
{item.goodsName}
|
||||
</TdFlex>
|
||||
<TdFlex>{item.price}</TdFlex>
|
||||
<TdFlex>{item.lastPrice}</TdFlex>
|
||||
<TdFlex>{item.updatedAt}</TdFlex>
|
||||
<TdFlex>{statusTxt[item.status]}</TdFlex>
|
||||
<TdBtnFlex>
|
||||
<DetailButton onClick={() => lookDetail(item)}>{t('Detail')}</DetailButton>
|
||||
<HashText onClick={() => goHash(item)}>{t('deal Hash')}</HashText>
|
||||
</TdBtnFlex>
|
||||
</TrFlex>
|
||||
)
|
||||
})}
|
||||
{list?.length === 0 ? (
|
||||
<Empty />
|
||||
) : (
|
||||
<Flex justifyContent="center" padding={10}>
|
||||
<Pagination count={count} onChange={pageChange} page={pageNum} />
|
||||
</Flex>
|
||||
)}
|
||||
</TableBody>
|
||||
</>
|
||||
</FlexMain>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,10 @@ import styled from 'styled-components'
|
|||
import { Text, Button, Image, Flex } from '@pancakeswap/uikit'
|
||||
import { useTranslation } from 'contexts/Localization'
|
||||
|
||||
interface AuctionRuleProps {
|
||||
typeIndex?: number
|
||||
}
|
||||
|
||||
const FlexMain = styled.div`
|
||||
margin-top: 30px;
|
||||
padding: 34px 30px;
|
||||
|
|
@ -22,29 +26,44 @@ const DetailText = styled(Text)`
|
|||
margin-bottom: 6px;
|
||||
`
|
||||
|
||||
const AuctionRule: React.FC = () => {
|
||||
const AuctionRule: React.FC<AuctionRuleProps> = ({ typeIndex }) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<FlexMain>
|
||||
<HeaderText>{t('Auction rule')}</HeaderText>
|
||||
<DetailText>
|
||||
{t('1. When the countdown is less than 1 hour, the countdown time will be increased by 1 hour each time')}
|
||||
</DetailText>
|
||||
<DetailText>
|
||||
{t(
|
||||
'2. Each auction has a fixed 10% markup. After the countdown, the item will be awarded to the bidder who made the last bid',
|
||||
)}
|
||||
</DetailText>
|
||||
<DetailText>{t('3. After the auction is successful')}</DetailText>
|
||||
<DetailText>
|
||||
{t(
|
||||
'4. After the auction, the publisher or the last bidder will collect revenue or NFT in the auction history. After one party of the bidder or the publisher receives revenue or NFT, the other party will automatically receive the corresponding revenue or NFT',
|
||||
)}
|
||||
</DetailText>
|
||||
<DetailText>
|
||||
{t('5. NFT shall not be traded or transferred after the auction is issued by the issuer')}
|
||||
</DetailText>
|
||||
{typeIndex === 1 && (
|
||||
<>
|
||||
<HeaderText>{t('Selling rules')}</HeaderText>
|
||||
<DetailText>{t('1.NFT may not be traded or transferred at the time of sale')}</DetailText>
|
||||
<DetailText>
|
||||
{t(
|
||||
'2. After the successful sale of NFT, the platform will charge the publisher 6% of the profits as a commission fee',
|
||||
)}
|
||||
</DetailText>
|
||||
</>
|
||||
)}
|
||||
{typeIndex === 2 && (
|
||||
<>
|
||||
<HeaderText>{t('Auction rule')}</HeaderText>
|
||||
<DetailText>
|
||||
{t('1. When the countdown is less than 1 hour, the countdown time will be increased by 1 hour each time')}
|
||||
</DetailText>
|
||||
<DetailText>
|
||||
{t(
|
||||
'2. Each auction has a fixed 10% markup. After the countdown, the item will be awarded to the bidder who made the last bid',
|
||||
)}
|
||||
</DetailText>
|
||||
<DetailText>{t('3. After the auction is successful')}</DetailText>
|
||||
<DetailText>
|
||||
{t(
|
||||
'4. After the auction, the publisher or the last bidder will collect revenue or NFT in the auction history. After one party of the bidder or the publisher receives revenue or NFT, the other party will automatically receive the corresponding revenue or NFT',
|
||||
)}
|
||||
</DetailText>
|
||||
<DetailText>
|
||||
{t('5. NFT shall not be traded or transferred after the auction is issued by the issuer')}
|
||||
</DetailText>
|
||||
</>
|
||||
)}
|
||||
</FlexMain>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,39 @@
|
|||
import React, { useState } from 'react'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import styled from 'styled-components'
|
||||
import Tooltip from '@mui/material/Tooltip'
|
||||
import { Text, Flex } from '@pancakeswap/uikit'
|
||||
import { useTranslation } from 'contexts/Localization'
|
||||
import { tradeRecord } from 'services/bazaar'
|
||||
import Empty from 'components/Empty'
|
||||
|
||||
interface AuctionTableProps {
|
||||
token?: string
|
||||
time?: number
|
||||
}
|
||||
interface ListProps {
|
||||
address?: string
|
||||
coverResource?: CoverResource
|
||||
goodsGrade?: string
|
||||
goodsId?: number
|
||||
goodsName?: string
|
||||
goodsType?: string
|
||||
id?: number
|
||||
lastPrice?: number
|
||||
price?: number
|
||||
status?: string
|
||||
token?: number
|
||||
tx?: string
|
||||
updatedAt?: number
|
||||
}
|
||||
interface CoverResource {
|
||||
path?: string
|
||||
url?: string
|
||||
}
|
||||
|
||||
const FlexMain = styled.div`
|
||||
margin-top: 30px;
|
||||
height: 405px;
|
||||
/* height: 405px; */
|
||||
padding-bottom: 20px;
|
||||
background: #fff;
|
||||
font-size: 18px;
|
||||
color: #999999;
|
||||
|
|
@ -45,33 +73,51 @@ const TrFlex = styled(Flex)`
|
|||
align-items: center;
|
||||
/* flex-wrap: wrap; */
|
||||
`
|
||||
const TdFlex = styled(Flex)`
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
const TdFlex = styled.div`
|
||||
width: 60%;
|
||||
padding: 0 20px;
|
||||
text-align: center;
|
||||
color: #666666;
|
||||
font-size: 16px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
cursor: pointer;
|
||||
`
|
||||
const TxFlex = styled(Flex)`
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
& > .linkText:hover {
|
||||
color: #1fc7d4 !important;
|
||||
border-bottom: 1px solid #1fc7d4 !important;
|
||||
}
|
||||
`
|
||||
|
||||
const AuctionTable: React.FC = () => {
|
||||
const AuctionTable: React.FC<AuctionTableProps> = ({ token, time }) => {
|
||||
const { t } = useTranslation()
|
||||
const [pageNum, setPage] = useState(1)
|
||||
const [list, serList] = useState<ListProps[]>()
|
||||
// 交易记录
|
||||
const getTradeRecord = async () => {
|
||||
const res = await tradeRecord({ page: pageNum, size: 10000, id: token })
|
||||
serList(res.content)
|
||||
}
|
||||
useEffect(() => {
|
||||
if (token) {
|
||||
getTradeRecord()
|
||||
}
|
||||
}, [pageNum, token])
|
||||
const goHash = (val) => {
|
||||
window.open(`https://goerli.etherscan.io/tx/${val}`)
|
||||
}
|
||||
|
||||
const ThemedList = [t('The wallet address'), 'HASH', t('auction price'), t('The auction time'), t('state')]
|
||||
|
||||
const list = [
|
||||
{
|
||||
name: 'Cat goddess Emerald ',
|
||||
icon: '',
|
||||
price: '1',
|
||||
newPrice: '2',
|
||||
time: '2022-02-02',
|
||||
status: '已售卖',
|
||||
id: '1',
|
||||
},
|
||||
]
|
||||
const statusTxt = {
|
||||
PENDING: t('Cancel the deity'),
|
||||
CANCEL: t('Canceled'),
|
||||
STREAMING: t('abortive auction'),
|
||||
SUCCESS: t('success'),
|
||||
}
|
||||
|
||||
return (
|
||||
<FlexMain>
|
||||
|
|
@ -83,17 +129,41 @@ const AuctionTable: React.FC = () => {
|
|||
})}
|
||||
</TableThemed>
|
||||
<TableBody>
|
||||
{list.map((item) => {
|
||||
return (
|
||||
<TrFlex key={item.id}>
|
||||
<TdFlex>{item.name}</TdFlex>
|
||||
<TdFlex>{item.price}</TdFlex>
|
||||
<TdFlex>{item.newPrice}</TdFlex>
|
||||
<TdFlex>{item.time}</TdFlex>
|
||||
<TdFlex>{item.status}</TdFlex>
|
||||
</TrFlex>
|
||||
)
|
||||
})}
|
||||
{list?.length > 0 ? (
|
||||
list?.map((item, index) => {
|
||||
return (
|
||||
<TrFlex key={item.id}>
|
||||
<TdFlex>
|
||||
<Tooltip title={item.address}>
|
||||
<div>
|
||||
{item.address && item.address.substring(0, 6)}....
|
||||
{item.address && item.address.substring(item.address.length - 6, item.tx.length)}
|
||||
</div>
|
||||
</Tooltip>
|
||||
</TdFlex>
|
||||
<TdFlex>
|
||||
<TxFlex onClick={() => goHash(item.tx)}>
|
||||
<div className="linkText" style={{ borderBottom: '1px solid #666' }}>
|
||||
{item.tx && item.tx.substring(0, 6)}....
|
||||
{item.tx && item.tx.substring(item.tx.length - 6, item.tx.length)}
|
||||
</div>
|
||||
</TxFlex>
|
||||
</TdFlex>
|
||||
<TdFlex>{item.price}</TdFlex>
|
||||
<TdFlex>{item.updatedAt}</TdFlex>
|
||||
<TdFlex>
|
||||
{time < new Date().getTime() && index === 0
|
||||
? t('traded')
|
||||
: time > new Date().getTime() && index === 0
|
||||
? '-'
|
||||
: t('out')}
|
||||
</TdFlex>
|
||||
</TrFlex>
|
||||
)
|
||||
})
|
||||
) : (
|
||||
<Empty />
|
||||
)}
|
||||
</TableBody>
|
||||
</>
|
||||
</FlexMain>
|
||||
|
|
|
|||
|
|
@ -11,11 +11,12 @@ import useToast from 'hooks/useToast'
|
|||
import { ListProps } from 'types/bazaar'
|
||||
|
||||
import Empty from 'components/Empty'
|
||||
import { useGetOfficialPage } from '../hooks'
|
||||
import { useGetOfficialPage, useGetTradePage } from '../hooks'
|
||||
import HeaderOperation from './HeaderOperation'
|
||||
import ContentShop from './ContentShop'
|
||||
import Transaction from './Transaction'
|
||||
import ShopDetail from './ShopDetail'
|
||||
import ShopDetailBazaar from './ShopDetailBazaar'
|
||||
|
||||
const HeaderFlex = styled(Flex)`
|
||||
width: 100%;
|
||||
|
|
@ -138,6 +139,7 @@ const Content: React.FC = () => {
|
|||
const { toastSuccess, toastError } = useToast()
|
||||
const [detail, setDetail] = useState<ListProps>({})
|
||||
const [detailVisible, setDetailVisible] = useState(false)
|
||||
const [ids, setId] = useState('')
|
||||
const typeList = [
|
||||
{ label: t('official market'), type: 1 },
|
||||
{ label: t('bazaar'), type: 2 },
|
||||
|
|
@ -145,10 +147,10 @@ const Content: React.FC = () => {
|
|||
]
|
||||
const [typeIndex, setTypeIndex] = useState(0)
|
||||
const auctionList = [
|
||||
{ label: t('In the auction'), value: '0' },
|
||||
{ label: t('traded'), value: '1' },
|
||||
{ label: t('In the auction'), value: 'PENDING' },
|
||||
{ label: t('traded'), value: 'SUCCESS' },
|
||||
]
|
||||
const [auctionSelect, setAuctionSelect] = useState({ label: t('In the auction'), value: '0' })
|
||||
const [auctionSelect, setAuctionSelect] = useState({ label: t('In the auction'), value: 'PENDING' })
|
||||
const newPrice = [
|
||||
// { label: t('The latest offer'), value: '0' },
|
||||
// { label: t('latest release'), value: '1' },
|
||||
|
|
@ -175,11 +177,35 @@ const Content: React.FC = () => {
|
|||
const [count, setCount] = useState(undefined)
|
||||
|
||||
const getOfficialPage = useGetOfficialPage()
|
||||
const getTradePage = useGetTradePage()
|
||||
|
||||
const getData = async () => {
|
||||
const changePage = (index) => {
|
||||
setGrade('')
|
||||
setSearchTitle('')
|
||||
setPage(1)
|
||||
setTypeIndex(index)
|
||||
}
|
||||
// 获取市场列表
|
||||
const getTradeList = async (type) => {
|
||||
setList([])
|
||||
const params = {
|
||||
page: pageNum,
|
||||
size: 10,
|
||||
size: 8,
|
||||
name: searchTitle,
|
||||
grade: searchGrade,
|
||||
status: auctionSelect.value,
|
||||
type,
|
||||
}
|
||||
const data = await getTradePage(params)
|
||||
setList(data.content)
|
||||
setCount(getTotalPageNum(data.total, data.size))
|
||||
}
|
||||
|
||||
const getData = async () => {
|
||||
setList([])
|
||||
const params = {
|
||||
page: pageNum,
|
||||
size: 8,
|
||||
name: searchTitle,
|
||||
grade: searchGrade,
|
||||
}
|
||||
|
|
@ -197,19 +223,42 @@ const Content: React.FC = () => {
|
|||
setList(arr)
|
||||
if (location.search) {
|
||||
const locationData = qs.parse(location.search.slice(1))
|
||||
arr.forEach((item) => {
|
||||
if (item.id === locationData.id) {
|
||||
setDetail(item)
|
||||
setDetailVisible(true)
|
||||
}
|
||||
})
|
||||
if (!locationData?.type) {
|
||||
arr.forEach((item) => {
|
||||
if (item.id === locationData.id) {
|
||||
setDetail(item)
|
||||
setDetailVisible(true)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
setCount(getTotalPageNum(data.total, data.size))
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getData()
|
||||
}, [pageNum, searchGrade])
|
||||
if (location.search) {
|
||||
const locationData = qs.parse(location.search.slice(1))
|
||||
if (locationData.type) {
|
||||
setTypeIndex(Number(locationData.type))
|
||||
setId(locationData.id.toString())
|
||||
setDetailVisible(true)
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
useEffect(() => {
|
||||
switch (typeIndex) {
|
||||
case 0:
|
||||
getData()
|
||||
break
|
||||
case 1:
|
||||
getTradeList('NORMAL')
|
||||
break
|
||||
case 2:
|
||||
getTradeList('AUCTION')
|
||||
break
|
||||
default:
|
||||
getData()
|
||||
}
|
||||
}, [pageNum, searchGrade, typeIndex, detailVisible, auctionSelect])
|
||||
|
||||
useEffect(() => {
|
||||
setPriceSelect({ label: t('Prices go from low to high'), value: '3' })
|
||||
|
|
@ -221,9 +270,12 @@ const Content: React.FC = () => {
|
|||
}
|
||||
const searchList = () => {
|
||||
setPage(1)
|
||||
getData()
|
||||
// getData()
|
||||
}
|
||||
const showDetail = (val) => {
|
||||
if (typeIndex !== 0) {
|
||||
setId(val.id)
|
||||
}
|
||||
setDetail(val)
|
||||
setDetailVisible(!detailVisible)
|
||||
}
|
||||
|
|
@ -240,14 +292,10 @@ const Content: React.FC = () => {
|
|||
setGrade(grade)
|
||||
setPage(1)
|
||||
}
|
||||
const changePage = (index) => {
|
||||
if (index !== 0) {
|
||||
toastError(t('This page is not currently open'))
|
||||
return
|
||||
}
|
||||
setTypeIndex(index)
|
||||
}
|
||||
const lookDetail = (val) => {
|
||||
if (typeIndex !== 0) {
|
||||
setId(val.id)
|
||||
}
|
||||
setDetail(val)
|
||||
setDetailVisible(true)
|
||||
// detail
|
||||
|
|
@ -260,7 +308,8 @@ const Content: React.FC = () => {
|
|||
|
||||
return (
|
||||
<>
|
||||
{detailVisible && <ShopDetail detail={detail} typeIndex={typeIndex} close={closeDetail} />}
|
||||
{detailVisible && typeIndex === 0 && <ShopDetail detail={detail} typeIndex={typeIndex} close={closeDetail} />}
|
||||
{detailVisible && typeIndex !== 0 && <ShopDetailBazaar id={ids} typeIndex={typeIndex} close={closeDetail} />}
|
||||
|
||||
{!detailVisible && (
|
||||
<>
|
||||
|
|
@ -297,7 +346,7 @@ const Content: React.FC = () => {
|
|||
})}
|
||||
</StatusFlexContent>
|
||||
<Flex>
|
||||
{typeIndex !== 0 && (
|
||||
{typeIndex === 2 && (
|
||||
<SelectMain>
|
||||
<Dropdown
|
||||
position="bottom"
|
||||
|
|
@ -318,7 +367,7 @@ const Content: React.FC = () => {
|
|||
</Dropdown>
|
||||
</SelectMain>
|
||||
)}
|
||||
{typeIndex !== 0 && (
|
||||
{/* {typeIndex !== 0 && (
|
||||
<SelectMain>
|
||||
<Dropdown
|
||||
position="bottom"
|
||||
|
|
@ -338,7 +387,7 @@ const Content: React.FC = () => {
|
|||
})}
|
||||
</Dropdown>
|
||||
</SelectMain>
|
||||
)}
|
||||
)} */}
|
||||
</Flex>
|
||||
</StatusFlex>
|
||||
<SearchDiv>
|
||||
|
|
@ -349,7 +398,7 @@ const Content: React.FC = () => {
|
|||
</SearchBtn>
|
||||
</InputMain>
|
||||
</SearchDiv>
|
||||
<ContentShop list={list} getDetail={(v) => showDetail(v)} />
|
||||
<ContentShop list={list} typeIndex={typeIndex} getDetail={(v) => showDetail(v)} />
|
||||
{list.length > 0 && (
|
||||
<Flex justifyContent="center" padding={10}>
|
||||
<Pagination count={count} onChange={pageChange} page={pageNum} />
|
||||
|
|
|
|||
|
|
@ -10,9 +10,11 @@ import useRefresh from 'hooks/useRefresh'
|
|||
import { TOKEN_SYMBOL } from 'config/index'
|
||||
|
||||
import ShopList from './ShopList'
|
||||
import ShopListBazaar from './ShopListBazaar'
|
||||
|
||||
interface ContentShop {
|
||||
list?: ListProps[]
|
||||
typeIndex?: number
|
||||
getDetail?: (v) => void
|
||||
}
|
||||
|
||||
|
|
@ -66,7 +68,7 @@ const FooterValue = styled(Flex)`
|
|||
flex-wrap: wrap;
|
||||
`
|
||||
|
||||
const ContentShop: React.FC<ContentShop> = ({ list, getDetail }) => {
|
||||
const ContentShop: React.FC<ContentShop> = ({ list, getDetail, typeIndex }) => {
|
||||
const { t } = useTranslation()
|
||||
const account = useAccount()
|
||||
const { toastSuccess, toastError } = useToast()
|
||||
|
|
@ -80,30 +82,54 @@ const ContentShop: React.FC<ContentShop> = ({ list, getDetail }) => {
|
|||
{list.map((item) => {
|
||||
return (
|
||||
<ShopFlex key={item.id} onClick={() => showDetail(item)}>
|
||||
<ShopList
|
||||
item={item}
|
||||
width={278}
|
||||
height={302}
|
||||
img={item.coverResource.url}
|
||||
grade={item.grade}
|
||||
borderRadius="20px 20px 0 0"
|
||||
/>
|
||||
<ShopName>{item.name}</ShopName>
|
||||
<ShopFooter>
|
||||
<FooterLabel>{t('trading value')}</FooterLabel>
|
||||
<FooterValue>
|
||||
{item.priceList.map((childItem, index) => {
|
||||
return (
|
||||
<Flex alignItems="center" key={childItem.label}>
|
||||
{/* <>{formatTimeNumber(childItem.value)}</> */}
|
||||
<>{Number(childItem.value).toFixed(2)}</>
|
||||
<Text color="text">{childItem.label}</Text>
|
||||
{index === 0 && item.priceList.length === 2 && <Text margin="0 5px">-</Text>}
|
||||
</Flex>
|
||||
)
|
||||
})}
|
||||
</FooterValue>
|
||||
</ShopFooter>
|
||||
{typeIndex === 0 && (
|
||||
<>
|
||||
<ShopList
|
||||
item={item}
|
||||
width={278}
|
||||
height={302}
|
||||
img={item.coverResource.url}
|
||||
grade={item.grade}
|
||||
borderRadius="20px 20px 0 0"
|
||||
/>
|
||||
<ShopName>{item.name}</ShopName>
|
||||
<ShopFooter>
|
||||
<FooterLabel>{t('trading value')}</FooterLabel>
|
||||
<FooterValue>
|
||||
{item?.priceList?.map((childItem, index) => {
|
||||
return (
|
||||
<Flex alignItems="center" key={childItem.label}>
|
||||
{/* <>{formatTimeNumber(childItem.value)}</> */}
|
||||
<>{Number(childItem.value).toFixed(2)}</>
|
||||
<Text color="text">{childItem.label}</Text>
|
||||
{index === 0 && item.priceList.length === 2 && <Text margin="0 5px">-</Text>}
|
||||
</Flex>
|
||||
)
|
||||
})}
|
||||
</FooterValue>
|
||||
</ShopFooter>
|
||||
</>
|
||||
)}
|
||||
{typeIndex !== 0 && (
|
||||
<>
|
||||
<ShopList
|
||||
item={item}
|
||||
width={278}
|
||||
height={302}
|
||||
img={item.coverResource.url}
|
||||
grade={item.grade}
|
||||
borderRadius="20px 20px 0 0"
|
||||
/>
|
||||
<ShopName>{item?.goodsName}</ShopName>
|
||||
<ShopFooter>
|
||||
<FooterLabel>{t('trading value')}</FooterLabel>
|
||||
<FooterValue>
|
||||
{item?.price}
|
||||
{TOKEN_SYMBOL}
|
||||
</FooterValue>
|
||||
</ShopFooter>
|
||||
</>
|
||||
)}
|
||||
</ShopFlex>
|
||||
)
|
||||
})}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { useTranslation } from 'contexts/Localization'
|
|||
import { Flex, Button, Text, Input, Image, useModal, Dropdown } from '@pancakeswap/uikit'
|
||||
import { useAccount } from 'state/userInfo/hooks'
|
||||
import useRefresh from 'hooks/useRefresh'
|
||||
import UnlockButton from 'components/UnlockButton'
|
||||
|
||||
import TransactionRecord from './TransactionRecord'
|
||||
import AuctionRecord from './AuctionRecord'
|
||||
|
|
@ -34,24 +35,35 @@ const HeaderButton = styled(Button)`
|
|||
margin-right: 0px;
|
||||
}
|
||||
`
|
||||
const UnlockButtonDiv = styled(UnlockButton)`
|
||||
width: 110px;
|
||||
height: 40px;
|
||||
border: 1px solid #1fc7d4;
|
||||
border-radius: 30px;
|
||||
font-size: 14px;
|
||||
color: #1fc7d4;
|
||||
background-color: #fff;
|
||||
`
|
||||
|
||||
const HeaderOperation: React.FC<HeaderOperationProps> = ({ activeIndex, getDetail }) => {
|
||||
const { t } = useTranslation()
|
||||
const account = useAccount()
|
||||
|
||||
const [onTransactionRecord] = useModal(
|
||||
<TransactionRecord activeIndex={activeIndex} recordDetail={(v) => getDetail(v)} />,
|
||||
)
|
||||
const [onAuctionRecord] = useModal(<AuctionRecord />)
|
||||
const [onAuctionRecord] = useModal(<AuctionRecord recordDetail={(v) => getDetail(v)} />)
|
||||
const [onSellModal] = useModal(<SellModal />)
|
||||
|
||||
return (
|
||||
<Flex alignContent="center">
|
||||
<HeaderButton onClick={onSellModal}>{t('I want to sell')}</HeaderButton>
|
||||
{!account && <UnlockButtonDiv />}
|
||||
{account && <HeaderButton onClick={onSellModal}>{t('I want to sell')}</HeaderButton>}
|
||||
{/* 当顶部切换选中的是全部和市场则显示交易记录,选中拍卖时展示拍卖纪录 */}
|
||||
{activeIndex === 2 ? (
|
||||
{activeIndex === 2 && account ? (
|
||||
<HeaderButton onClick={onAuctionRecord}>{t('Auctions a record')}</HeaderButton>
|
||||
) : (
|
||||
<HeaderButton onClick={onTransactionRecord}>{t('transaction record')}</HeaderButton>
|
||||
account && <HeaderButton onClick={onTransactionRecord}>{t('transaction record')}</HeaderButton>
|
||||
)}
|
||||
</Flex>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
import React, { useState } from 'react'
|
||||
import styled from 'styled-components'
|
||||
import { Text, Button, Image, Input, Flex, Dropdown } from '@pancakeswap/uikit'
|
||||
import { useTranslation } from 'contexts/Localization'
|
||||
import ShopList from './ShopList'
|
||||
import ShopModal from './ShopModal'
|
||||
|
||||
interface sellModalProps {
|
||||
onDismiss?: () => void
|
||||
getInputValue?: (v) => void
|
||||
}
|
||||
interface Detail {
|
||||
address?: string
|
||||
createdAt?: string
|
||||
id?: string
|
||||
info: InfoProps
|
||||
token?: string
|
||||
updatedAt?: string
|
||||
select?: boolean
|
||||
}
|
||||
interface InfoProps {
|
||||
coverResource?: CoverResourceProps
|
||||
grade?: string
|
||||
id?: string
|
||||
name?: string
|
||||
price?: any
|
||||
type?: string
|
||||
}
|
||||
interface CoverResourceProps {
|
||||
path?: string
|
||||
url?: string
|
||||
}
|
||||
|
||||
const PriceInput = styled(Input)`
|
||||
width: 180px;
|
||||
height: 35px;
|
||||
margin-top: 20px;
|
||||
`
|
||||
|
||||
const SellInput: React.FC<sellModalProps> = ({ onDismiss, getInputValue }) => {
|
||||
const { t } = useTranslation()
|
||||
const [inputValue, setValue] = useState('')
|
||||
|
||||
const handleChange = (evt: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const { value } = evt.target
|
||||
setValue(value)
|
||||
getInputValue(value)
|
||||
}
|
||||
return (
|
||||
<PriceInput type="number" placeholder={t('Please enter the amount')} value={inputValue} onChange={handleChange} />
|
||||
)
|
||||
}
|
||||
|
||||
export default SellInput
|
||||
|
|
@ -1,12 +1,42 @@
|
|||
import React, { useState } from 'react'
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { useLocation, useHistory, useParams } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
import { Text, Button, Image, Input, Flex, Dropdown } from '@pancakeswap/uikit'
|
||||
import { useTranslation } from 'contexts/Localization'
|
||||
import useToast from 'hooks/useToast'
|
||||
import { getHccMarketplaceAddress } from 'utils/addressHelpers'
|
||||
import useRefresh from 'hooks/useRefresh'
|
||||
import { marketTradeCreateOrderTx } from 'services/bazaar'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import { useCreateNormalOrder, useCreateAuctionOrder, useIsApproved, useApproved } from '../hooks'
|
||||
import ShopList from './ShopList'
|
||||
import ShopModal from './ShopModal'
|
||||
|
||||
interface sellModalProps {
|
||||
onDismiss?: () => void
|
||||
detailData?: Detail
|
||||
}
|
||||
interface Detail {
|
||||
address?: string
|
||||
createdAt?: string
|
||||
id?: string
|
||||
info: InfoProps
|
||||
token?: string
|
||||
updatedAt?: string
|
||||
select?: boolean
|
||||
pending?: boolean
|
||||
}
|
||||
interface InfoProps {
|
||||
coverResource?: CoverResourceProps
|
||||
grade?: string
|
||||
id?: string
|
||||
name?: string
|
||||
price?: any
|
||||
type?: string
|
||||
}
|
||||
interface CoverResourceProps {
|
||||
path?: string
|
||||
url?: string
|
||||
}
|
||||
|
||||
const FlexMain = styled.div`
|
||||
|
|
@ -70,8 +100,10 @@ const SellingWayFlex = styled(Flex)`
|
|||
}
|
||||
`
|
||||
const WayFlex = styled(Flex)`
|
||||
width: 400px;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
/* flex-direction: column; */
|
||||
`
|
||||
const FlexOption = styled(Flex)`
|
||||
align-items: center;
|
||||
|
|
@ -88,7 +120,6 @@ const FlexOption = styled(Flex)`
|
|||
}
|
||||
`
|
||||
const SellInput = styled(Input)`
|
||||
margin-top: 20px;
|
||||
width: 400px;
|
||||
height: 35px;
|
||||
background: #eeeaf4;
|
||||
|
|
@ -102,78 +133,6 @@ const SellInput = styled(Input)`
|
|||
width: 400px;
|
||||
}
|
||||
`
|
||||
const FlexPrice = styled(Flex)`
|
||||
width: 500px;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
|
||||
${({ theme }) => theme.mediaQueries.xs} {
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
margin-top: 10px;
|
||||
}
|
||||
${({ theme }) => theme.mediaQueries.lg} {
|
||||
width: 500px;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
`
|
||||
const TransactionMain = styled(Flex)`
|
||||
align-items: center;
|
||||
${({ theme }) => theme.mediaQueries.xs} {
|
||||
margin-top: 10px;
|
||||
}
|
||||
${({ theme }) => theme.mediaQueries.lg} {
|
||||
margin-top: 0px;
|
||||
}
|
||||
`
|
||||
const PriceItem = styled(Flex)`
|
||||
width: 180px;
|
||||
/* margin-right: 80px; */
|
||||
flex-direction: column;
|
||||
`
|
||||
const FlexCoinOption = styled(Flex)`
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 180px;
|
||||
height: 40px;
|
||||
cursor: pointer;
|
||||
`
|
||||
const PriceWay = styled(Flex)`
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 180px;
|
||||
height: 35px;
|
||||
background: #eeeaf4;
|
||||
border: 1px solid #d7caec;
|
||||
border-radius: 18px;
|
||||
padding: 0 15px;
|
||||
color: #666666;
|
||||
font-size: 16px;
|
||||
`
|
||||
const PriceInput = styled(Input)`
|
||||
width: 180px;
|
||||
height: 35px;
|
||||
margin-top: 20px;
|
||||
`
|
||||
const AddButton = styled(Button)`
|
||||
width: 140px;
|
||||
height: 35px;
|
||||
border: 1px solid #1fc7d4;
|
||||
border-radius: 30px;
|
||||
font-size: 14px;
|
||||
color: #1fc7d4;
|
||||
background-color: #fff;
|
||||
margin-left: 80px;
|
||||
|
||||
${({ theme }) => theme.mediaQueries.xs} {
|
||||
margin-left: 0px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
${({ theme }) => theme.mediaQueries.lg} {
|
||||
margin-left: 80px;
|
||||
margin-top: 0px;
|
||||
}
|
||||
`
|
||||
const Shop = styled(Flex)`
|
||||
/* min-height: 366px; */
|
||||
padding: 30px 0;
|
||||
|
|
@ -189,12 +148,6 @@ const AddNftButton = styled(Button)`
|
|||
color: #fff;
|
||||
font-size: 14px;
|
||||
`
|
||||
const PriceImage = styled(Image)`
|
||||
margin: 0 10px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
cursor: pointer;
|
||||
`
|
||||
const ShopFlex = styled(Flex)`
|
||||
width: 278px;
|
||||
flex-direction: column;
|
||||
|
|
@ -234,44 +187,121 @@ const SelectShopModal = styled(Flex)`
|
|||
z-index: 999;
|
||||
/* background-color: #7a6eaa; */
|
||||
`
|
||||
const InputDiv = styled.div`
|
||||
position: relative;
|
||||
`
|
||||
const InputText = styled(Text)`
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 4px;
|
||||
`
|
||||
|
||||
const SellModal: React.FC<sellModalProps> = ({ onDismiss }) => {
|
||||
const SellModal: React.FC<sellModalProps> = ({ onDismiss, detailData }) => {
|
||||
const { t } = useTranslation()
|
||||
const [tradingOnList, setTradingOnList] = useState([{ price: '', value: 'HCC', id: 1 }])
|
||||
const [sellingWay, setSellingWay] = useState(undefined)
|
||||
const [coin, setCoin] = useState({ label: 'HCC', value: 'HCC' })
|
||||
const [shopData, setShopData] = useState({ label: 'Cat goddess Emerald ', type: 1, id: 1 })
|
||||
const history = useHistory()
|
||||
const { fastRefresh } = useRefresh()
|
||||
const [isApprovedFor, setIsApprovedFor] = useState(false)
|
||||
const [token, setTokenId] = useState('')
|
||||
const { toastSuccess, toastError } = useToast()
|
||||
const [price, setPrice] = useState('')
|
||||
const [sellingWay, setSellingWay] = useState({ label: t('fixed price'), value: '1' })
|
||||
const [time, setTime] = useState('')
|
||||
const [shopData, setShopData] = useState<Detail>()
|
||||
const [showModal, setShowModal] = useState(false)
|
||||
|
||||
const coinList = [
|
||||
{ label: 'HCC', value: 'HCC' },
|
||||
{ label: 'USDT', value: 'USDT' },
|
||||
]
|
||||
const [txId, setTxId] = useState()
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [createOrderId, setCreateOrderId] = useState('')
|
||||
const [agreementLoading, setAgreementLoading] = useState(false)
|
||||
|
||||
const SellingWayList = [
|
||||
{ label: t('Auction'), value: '0' },
|
||||
{ label: t('fixed price'), value: '1' },
|
||||
{ label: t('Auction'), value: '2' },
|
||||
]
|
||||
|
||||
const selectTradingOn = (index, value) => {
|
||||
tradingOnList[index].value = value
|
||||
setTradingOnList([...tradingOnList])
|
||||
}
|
||||
const addTradingOn = () => {
|
||||
tradingOnList.push({ price: '', value: 'HCC', id: 2 })
|
||||
setTradingOnList([...tradingOnList])
|
||||
}
|
||||
const reduceTradingOn = () => {
|
||||
tradingOnList.splice(1, 1)
|
||||
setTradingOnList([...tradingOnList])
|
||||
}
|
||||
|
||||
const onSelectNft = () => {
|
||||
setShowModal(!showModal)
|
||||
}
|
||||
const close = () => {
|
||||
setShowModal(false)
|
||||
}
|
||||
const getShopDetail = (v) => {
|
||||
setShopData(v)
|
||||
getIsApprovedForAll(v.token)
|
||||
setShowModal(false)
|
||||
}
|
||||
const handlePriceChange = (evt: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const { value } = evt.target
|
||||
setPrice(value)
|
||||
}
|
||||
const handleChange = (evt: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const { value } = evt.target
|
||||
setTime(value)
|
||||
}
|
||||
const createAuctionOrder = useCreateAuctionOrder()
|
||||
const createNormalOrder = useCreateNormalOrder()
|
||||
const isApproved = useIsApproved()
|
||||
const approved = useApproved()
|
||||
const getIsApprovedForAll = async (tokenId) => {
|
||||
const res = await isApproved(tokenId)
|
||||
setIsApprovedFor(res)
|
||||
if (res) {
|
||||
setAgreementLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
const sellNow = async () => {
|
||||
if (sellingWay?.value === '2' && !time) {
|
||||
toastError(t('Please enter the time'))
|
||||
return
|
||||
}
|
||||
// const priceVisible = tradingOnList.find((item) => !item.price)
|
||||
if (!price) {
|
||||
toastError(t('Please enter price'))
|
||||
return
|
||||
}
|
||||
if (Number(price) < 0) {
|
||||
toastError(t("Can't be less than %num%", { num: 0 }))
|
||||
return
|
||||
}
|
||||
if (sellingWay?.value === '2' && Number(time) < 0) {
|
||||
toastError(t("Can't be less than %num%", { num: 0 }))
|
||||
return
|
||||
}
|
||||
setLoading(true)
|
||||
let res = { hash: undefined }
|
||||
if (sellingWay?.value === '2') {
|
||||
const auctionTime = new BigNumber(time).multipliedBy(3600000).plus(new Date().getTime()).toNumber()
|
||||
// const auctionTime = Number(time) * 3600000 + new Date().getTime()
|
||||
res = await createAuctionOrder(shopData.token, price, auctionTime)
|
||||
} else {
|
||||
res = await createNormalOrder(shopData.token, price)
|
||||
}
|
||||
|
||||
setTxId(res.hash)
|
||||
}
|
||||
const agreement = async () => {
|
||||
setAgreementLoading(true)
|
||||
const res = await approved(shopData.token)
|
||||
}
|
||||
const getMarketTradeCreateOrderTx = async () => {
|
||||
const res = await marketTradeCreateOrderTx({ tx: txId })
|
||||
if (res) {
|
||||
setLoading(false)
|
||||
setCreateOrderId(res)
|
||||
window.location.href = `${window.location.href}?id=${res}&type=${sellingWay?.value}`
|
||||
}
|
||||
}
|
||||
useEffect(() => {
|
||||
detailData && setShopData(detailData)
|
||||
}, [])
|
||||
useEffect(() => {
|
||||
if (!isApprovedFor) {
|
||||
shopData && getIsApprovedForAll(shopData.token)
|
||||
}
|
||||
if (txId && loading) {
|
||||
getMarketTradeCreateOrderTx()
|
||||
}
|
||||
}, [fastRefresh])
|
||||
|
||||
return (
|
||||
<FlexMain>
|
||||
|
|
@ -282,7 +312,7 @@ const SellModal: React.FC<sellModalProps> = ({ onDismiss }) => {
|
|||
<Dropdown
|
||||
position="bottom"
|
||||
target={
|
||||
<SellingWayFlex>
|
||||
<SellingWayFlex style={{ marginBottom: '20px' }}>
|
||||
{sellingWay ? sellingWay.label : t('Selling way')}
|
||||
<Image src="/images/nft/bottom-arrows.svg" width={12} height={7} />
|
||||
</SellingWayFlex>
|
||||
|
|
@ -296,58 +326,53 @@ const SellModal: React.FC<sellModalProps> = ({ onDismiss }) => {
|
|||
)
|
||||
})}
|
||||
</Dropdown>
|
||||
{sellingWay?.value === '0' && <SellInput placeholder={t('Selling time')} />}
|
||||
<InputDiv>
|
||||
<SellInput
|
||||
type="number"
|
||||
style={{ marginBottom: '20px' }}
|
||||
placeholder={t('Please enter price')}
|
||||
onChange={handlePriceChange}
|
||||
/>
|
||||
<InputText>HCC</InputText>
|
||||
</InputDiv>
|
||||
{sellingWay?.value === '2' && (
|
||||
<InputDiv>
|
||||
<SellInput type="number" placeholder={t('Selling time')} onChange={handleChange} />
|
||||
<InputText>{t('hour')}</InputText>
|
||||
</InputDiv>
|
||||
)}
|
||||
</WayFlex>
|
||||
<FlexPrice>
|
||||
<>
|
||||
{tradingOnList.map((item, index) => {
|
||||
return (
|
||||
<TransactionMain key={item.id}>
|
||||
<PriceItem>
|
||||
<Dropdown
|
||||
position="bottom"
|
||||
target={
|
||||
<PriceWay>
|
||||
{item.value}
|
||||
<Image src="/images/nft/bottom-arrows.svg" width={12} height={7} />
|
||||
</PriceWay>
|
||||
}
|
||||
>
|
||||
{coinList.map((coinItem) => {
|
||||
return (
|
||||
<FlexCoinOption key={coinItem.value} onClick={() => selectTradingOn(index, coinItem.value)}>
|
||||
{coinItem.label}
|
||||
</FlexCoinOption>
|
||||
)
|
||||
})}
|
||||
</Dropdown>
|
||||
<PriceInput placeholder={t('Please enter the amount')} />
|
||||
</PriceItem>
|
||||
{index === 0 && tradingOnList.length === 2 && (
|
||||
<PriceImage src="/images/nft/add.svg" width={20} height={20} />
|
||||
)}
|
||||
{index === 1 && (
|
||||
<PriceImage src="/images/nft/reduce.svg" width={20} height={20} onClick={reduceTradingOn} />
|
||||
)}
|
||||
</TransactionMain>
|
||||
)
|
||||
})}
|
||||
</>
|
||||
{tradingOnList.length < 2 && <AddButton onClick={addTradingOn}>{t('Add as a trading pair')}</AddButton>}
|
||||
</FlexPrice>
|
||||
</SelectFlex>
|
||||
<Shop>
|
||||
{/* <AddNftButton>{t('add NFT)}</AddNftButton> */}
|
||||
<ShopFlex>
|
||||
<ShopList item={shopData} width={278} height={280} borderRadius="20px 20px 0 0" />
|
||||
<ShopName>{shopData.label}</ShopName>
|
||||
</ShopFlex>
|
||||
<ShopButton>{t('Selling immediately')}</ShopButton>
|
||||
<ShopButton onClick={onSelectNft}>{t('reselect NFT')}</ShopButton>
|
||||
{/* isApprovedFor */}
|
||||
{!shopData?.info?.id && <AddNftButton onClick={onSelectNft}>{t('add NFT')}</AddNftButton>}
|
||||
{shopData?.info?.id && (
|
||||
<ShopFlex>
|
||||
<ShopList
|
||||
item={shopData}
|
||||
img={shopData?.info?.coverResource?.url}
|
||||
width={278}
|
||||
height={280}
|
||||
borderRadius="20px 20px 0 0"
|
||||
/>
|
||||
<ShopName>{shopData?.info?.name}</ShopName>
|
||||
</ShopFlex>
|
||||
)}
|
||||
{shopData?.info?.id && isApprovedFor && (
|
||||
<ShopButton onClick={sellNow} disabled={loading}>
|
||||
{t('Selling immediately')}
|
||||
</ShopButton>
|
||||
)}
|
||||
{shopData?.info?.id && <ShopButton onClick={onSelectNft}>{t('reselect NFT')}</ShopButton>}
|
||||
{shopData?.info?.id && !isApprovedFor && (
|
||||
<AddNftButton mt="8px" width="100%" onClick={agreement} disabled={agreementLoading}>
|
||||
{t('license agreement')}
|
||||
</AddNftButton>
|
||||
)}
|
||||
</Shop>
|
||||
{showModal && (
|
||||
<SelectShopModal>
|
||||
<ShopModal close={close} />
|
||||
<ShopModal close={close} add={(v) => getShopDetail(v)} />
|
||||
</SelectShopModal>
|
||||
)}
|
||||
</FlexMain>
|
||||
|
|
|
|||
|
|
@ -194,22 +194,32 @@ const ShopDetail: React.FC<DetailProps> = ({ close, detail, typeIndex }) => {
|
|||
</DetailHeaderFlex>
|
||||
{typeIndex !== 0 && (
|
||||
<FlexCom
|
||||
name={t('Auction countdown')}
|
||||
name={t('Auction remaining time')}
|
||||
value="10:57:55:79"
|
||||
size="18px"
|
||||
rightSize="30px"
|
||||
textColor="#666666"
|
||||
/>
|
||||
)}
|
||||
<FlexCom
|
||||
name={t('present price%price%', { price: '' })}
|
||||
value={price}
|
||||
size="18px"
|
||||
rightSize="30px"
|
||||
textColor="#1FC7D4"
|
||||
/>
|
||||
{detail.record ? (
|
||||
''
|
||||
{!detail.record && (
|
||||
<FlexCom
|
||||
name={t('present price%price%', { price: '' })}
|
||||
value={price}
|
||||
size="18px"
|
||||
rightSize="30px"
|
||||
textColor="#1FC7D4"
|
||||
/>
|
||||
)}
|
||||
{detail.record && (
|
||||
<FlexCom name="TokenID" value={detail?.token} size="18px" rightSize="30px" textColor="#1FC7D4" />
|
||||
)}
|
||||
{!detail.record && typeIndex === 0 && !account && <UnlockButtonDiv />}
|
||||
{!detail.record && typeIndex === 0 && account && <BtnStatus detail={detail} />}
|
||||
{!detail.record && typeIndex !== 0 && account && (
|
||||
<PriceButton>{t('Fixed markup (%price% premium)', { price: '10%' })}</PriceButton>
|
||||
)}
|
||||
{/* {detail.record ? (
|
||||
<FlexCom name="TokenID" value={detail?.token} size="18px" rightSize="30px" textColor="#1FC7D4" />
|
||||
) : typeIndex === 0 ? (
|
||||
!account ? (
|
||||
<UnlockButtonDiv />
|
||||
|
|
@ -218,7 +228,7 @@ const ShopDetail: React.FC<DetailProps> = ({ close, detail, typeIndex }) => {
|
|||
)
|
||||
) : (
|
||||
<PriceButton>{t('Fixed markup (%price% premium)', { price: '10%' })}</PriceButton>
|
||||
)}
|
||||
)} */}
|
||||
</DetailFlexInfo>
|
||||
<AssetsInfo typeIndex={typeIndex} />
|
||||
</Detail>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,547 @@
|
|||
import React, { useState, useEffect } from 'react'
|
||||
import dayjs from 'dayjs'
|
||||
import styled from 'styled-components'
|
||||
import { useTranslation } from 'contexts/Localization'
|
||||
import { Flex, Button, Text, Image, useModal } from '@pancakeswap/uikit'
|
||||
import { useAccount } from 'state/userInfo/hooks'
|
||||
import useRefresh from 'hooks/useRefresh'
|
||||
import useToast from 'hooks/useToast'
|
||||
// import { ListProps } from 'types/bazaar'
|
||||
import {
|
||||
marketTradeRecordDetail,
|
||||
checkBuyResult,
|
||||
cancelOrderTx,
|
||||
executeOrderTx,
|
||||
bidOrderTx,
|
||||
tradeRecord,
|
||||
} from 'services/bazaar'
|
||||
import { fetchBazaarUserAllowances } from 'state/bazaar'
|
||||
import UnlockButton from 'components/UnlockButton'
|
||||
import { getAddress } from 'utils/addressHelpers'
|
||||
import { useERC20 } from 'hooks/useContract'
|
||||
import tokens from 'config/constants/tokens'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import {
|
||||
useBuyTransaction,
|
||||
useMarketplaceApproveHcc,
|
||||
useCancelOrder,
|
||||
useExecuteOrder,
|
||||
useOrderMap,
|
||||
useBidAuctionOrder,
|
||||
} from '../hooks'
|
||||
import ShopList from './ShopList'
|
||||
import FlexCom from './FlexCom'
|
||||
import AuctionTable from './AuctionTable'
|
||||
import TransactionTable from './TransactionTable'
|
||||
import AuctionRule from './AuctionRule'
|
||||
import AssetsInfo from './AssetsInfo'
|
||||
import BtnStatus from './BtnStatus'
|
||||
import SellModal from './SellModal'
|
||||
|
||||
interface DetailProps {
|
||||
close: () => void
|
||||
id: string
|
||||
typeIndex: number
|
||||
}
|
||||
|
||||
interface ListProps {
|
||||
address?: string
|
||||
coverResource?: CoverResourceProps
|
||||
goodsGrade?: string
|
||||
goodsId?: string
|
||||
goodsName?: string
|
||||
goodsType?: string
|
||||
id?: string
|
||||
lastPrice?: string
|
||||
optionList?: OptionListProps[]
|
||||
price?: string
|
||||
status?: string
|
||||
token?: string
|
||||
tx?: string
|
||||
updatedAt?: string
|
||||
}
|
||||
interface CoverResourceProps {
|
||||
path?: string
|
||||
url?: string
|
||||
}
|
||||
interface OptionListProps {
|
||||
address?: string
|
||||
id?: string
|
||||
price?: string
|
||||
tx?: string
|
||||
}
|
||||
|
||||
const HeaderFlex = styled(Flex)`
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
`
|
||||
const FirstText = styled(Text)`
|
||||
font-size: 16px;
|
||||
color: #1fc7d4;
|
||||
cursor: pointer;
|
||||
`
|
||||
const ShopText = styled(Text)`
|
||||
color: #666666;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
`
|
||||
const MainFlex = styled(Flex)`
|
||||
margin-top: 36px;
|
||||
padding: 30px;
|
||||
background: #fff;
|
||||
box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.16);
|
||||
border-radius: 20px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
${({ theme }) => theme.mediaQueries.xs} {
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
${({ theme }) => theme.mediaQueries.lg} {
|
||||
flex-wrap: nowrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
`
|
||||
const ShopFlex = styled(Flex)`
|
||||
width: 476px;
|
||||
flex-direction: column;
|
||||
border-radius: 20px;
|
||||
position: relative;
|
||||
`
|
||||
const Detail = styled(Flex)`
|
||||
width: 614px;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
/* height: 590px; */
|
||||
box-sizing: border-box;
|
||||
border-radius: 20px;
|
||||
margin-left: 30px;
|
||||
${({ theme }) => theme.mediaQueries.xs} {
|
||||
margin-top: 30px;
|
||||
margin-left: 0px;
|
||||
width: 482px;
|
||||
}
|
||||
${({ theme }) => theme.mediaQueries.lg} {
|
||||
margin-top: 0px;
|
||||
margin-left: 30px;
|
||||
width: 614px;
|
||||
}
|
||||
`
|
||||
const TitleText = styled(Text)`
|
||||
font-size: 28px;
|
||||
color: #333333;
|
||||
text-align: center;
|
||||
`
|
||||
const PriceButton = styled(Button)`
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
background: linear-gradient(269deg, #1fc8d3 0%, #1fd4b0 100%);
|
||||
border-radius: 30px;
|
||||
font-size: 16px;
|
||||
margin-top: 20px;
|
||||
`
|
||||
const AuthorizationBtn = styled(Button)`
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
background: linear-gradient(269deg, #1fc8d3 0%, #1fd4b0 100%);
|
||||
border-radius: 30px;
|
||||
font-size: 16px;
|
||||
margin-top: 20px;
|
||||
`
|
||||
|
||||
const UnlockButtonDiv = styled(UnlockButton)`
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
background: linear-gradient(269deg, #1fc8d3 0%, #1fd4b0 100%);
|
||||
border-radius: 30px;
|
||||
font-size: 16px;
|
||||
margin-top: 20px;
|
||||
`
|
||||
const DetailFlexInfo = styled(Flex)`
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 304px;
|
||||
background: #f5ffff;
|
||||
box-shadow: 0px 2px 8px rgba(0, 67, 70, 0.15);
|
||||
border-radius: 20px;
|
||||
padding: 26px 30px;
|
||||
`
|
||||
const DetailHeaderFlex = styled(Flex)`
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
`
|
||||
|
||||
const ShopDetail: React.FC<DetailProps> = ({ close, id, typeIndex }) => {
|
||||
const { t } = useTranslation()
|
||||
const [txId, setTxId] = useState()
|
||||
const [txCancelId, setTxCancelId] = useState()
|
||||
const [cancelStatus, setCancelStatus] = useState(false)
|
||||
const [statusBtnTxt, setStatusBtnTxt] = useState('')
|
||||
const statusTxt = {
|
||||
PENDING: t('Cancel the deity'),
|
||||
CANCEL: t('Canceled'),
|
||||
STREAMING: t('abortive auction'),
|
||||
SUCCESS: t('success'),
|
||||
}
|
||||
const statusHeaderTxt = {
|
||||
PENDING: t('They are in'),
|
||||
CANCEL: t('Canceled'),
|
||||
STREAMING: t('abortive auction'),
|
||||
SUCCESS: t('success'),
|
||||
}
|
||||
|
||||
const [loading, setLoading] = useState(false)
|
||||
const { toastSuccess, toastError } = useToast()
|
||||
const { fastRefresh } = useRefresh()
|
||||
const [detail, setDetail] = useState<ListProps>()
|
||||
const [countDown, setCountDown] = useState('')
|
||||
const account = useAccount()
|
||||
const [ownOrder, setOwnOrder] = useState(false)
|
||||
const [forbid, setForbid] = useState(false)
|
||||
const [cancelDeity, setCancelDeity] = useState(false)
|
||||
const [approveStatus, setApproveStatus] = useState(false)
|
||||
const [bidAuctionStatus, setBidAuctionStatus] = useState(true)
|
||||
const [orderMapData, setOrderMapData] = useState(undefined)
|
||||
const [sellData, setSellData] = useState(undefined)
|
||||
const [allowance, setAllowance] = useState(0)
|
||||
const executeOrder = useExecuteOrder()
|
||||
const [txExecuteId, setTxExecuteId] = useState('')
|
||||
const [txAuctionId, setTxAuctionId] = useState('')
|
||||
const [sellVerify, setSellVerify] = useState(false)
|
||||
const cancelOrderHook = useCancelOrder()
|
||||
const orderMap = useOrderMap()
|
||||
const bidAuctionOrder = useBidAuctionOrder()
|
||||
const hccContract = useERC20(getAddress(tokens.hcc.address))
|
||||
const { onApprove: onHccApprove } = useMarketplaceApproveHcc(hccContract)
|
||||
|
||||
useEffect(() => {
|
||||
getDetail()
|
||||
if (account) {
|
||||
getAllowances()
|
||||
}
|
||||
}, [account])
|
||||
useEffect(() => {
|
||||
if (txId && loading) {
|
||||
getTransactionResult()
|
||||
}
|
||||
}, [fastRefresh])
|
||||
useEffect(() => {
|
||||
// 取消挂单
|
||||
if (txCancelId && loading) {
|
||||
cancelOrderTxFun()
|
||||
}
|
||||
// 购买
|
||||
if (txExecuteId && loading) {
|
||||
executeOrderFn()
|
||||
}
|
||||
// 竞价
|
||||
if (txAuctionId && loading) {
|
||||
bidOrderTxFn()
|
||||
}
|
||||
if (detail) {
|
||||
getOrderMap(detail.token)
|
||||
}
|
||||
// 取消挂单按钮
|
||||
if (account && ownOrder && !cancelStatus) {
|
||||
setCancelDeity(true)
|
||||
} else {
|
||||
setCancelDeity(false)
|
||||
}
|
||||
}, [fastRefresh])
|
||||
useEffect(() => {
|
||||
if (typeIndex === 2) {
|
||||
const date2 = dayjs(new Date(orderMapData?.expiresAt).getTime()).diff(dayjs())
|
||||
if (date2 > 0) {
|
||||
setTimeout(() => {
|
||||
const time = new Date(orderMapData?.expiresAt).getTime() - 1
|
||||
countDownFun(time)
|
||||
}, 1000)
|
||||
} else {
|
||||
setCountDown(t('finished'))
|
||||
// setStatusBtnTxt('end')
|
||||
}
|
||||
}
|
||||
}, [countDown, orderMapData])
|
||||
|
||||
const getAllowances = async () => {
|
||||
const allowances = await fetchBazaarUserAllowances(account)
|
||||
setAllowance(allowances.hcc)
|
||||
// 授权HCC按钮
|
||||
if (!allowances.hcc && !cancelDeity) {
|
||||
setApproveStatus(true)
|
||||
} else {
|
||||
setApproveStatus(false)
|
||||
}
|
||||
}
|
||||
const getDetail = async () => {
|
||||
const res = await marketTradeRecordDetail(id)
|
||||
if (res.address === account) {
|
||||
setOwnOrder(true)
|
||||
setCancelDeity(true)
|
||||
} else {
|
||||
setOwnOrder(false)
|
||||
setCancelDeity(false)
|
||||
}
|
||||
setSellData({
|
||||
address: res?.address,
|
||||
info: {
|
||||
coverResource: res?.coverResource,
|
||||
grade: res?.goodsGrade,
|
||||
id: res?.id,
|
||||
name: res?.goodsName,
|
||||
price: res?.price,
|
||||
type: res?.goodsType,
|
||||
},
|
||||
updatedAt: res?.updatedAt,
|
||||
token: res?.token,
|
||||
})
|
||||
setStatusBtnTxt(res.status)
|
||||
setDetail(res)
|
||||
}
|
||||
|
||||
const getTransactionResult = async () => {
|
||||
const res = await checkBuyResult({ tx: txId })
|
||||
if (res) {
|
||||
setLoading(false)
|
||||
setTxId(undefined)
|
||||
toastSuccess(t('purchase succeeds'))
|
||||
}
|
||||
}
|
||||
|
||||
const handleApprove = async (approve) => {
|
||||
try {
|
||||
setLoading(true)
|
||||
await approve()
|
||||
setLoading(false)
|
||||
getAllowances()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const getLink = () => {
|
||||
const createInput = document.createElement('input')
|
||||
createInput.value = `${window.location.href}?id=${detail.id}`
|
||||
document.body.appendChild(createInput)
|
||||
createInput.select()
|
||||
document.execCommand('Copy')
|
||||
createInput.remove()
|
||||
toastSuccess(t('Copy success'))
|
||||
}
|
||||
|
||||
const cancelOrder = async () => {
|
||||
setLoading(true)
|
||||
const res = await cancelOrderHook(detail.token)
|
||||
setTxCancelId(res.hash)
|
||||
}
|
||||
const executeOrderFn = async () => {
|
||||
setLoading(true)
|
||||
const res = await executeOrderTx(txExecuteId)
|
||||
if (res) {
|
||||
getDetail()
|
||||
setTxExecuteId(undefined)
|
||||
setLoading(false)
|
||||
setSellVerify(true)
|
||||
}
|
||||
}
|
||||
const bidOrderTxFn = async () => {
|
||||
setLoading(true)
|
||||
const res = await bidOrderTx(txAuctionId)
|
||||
if (res) {
|
||||
getDetail()
|
||||
setTxExecuteId(undefined)
|
||||
setLoading(false)
|
||||
toastSuccess(t('For successful'))
|
||||
}
|
||||
}
|
||||
const cancelOrderTxFun = async () => {
|
||||
const res = await cancelOrderTx(txCancelId)
|
||||
if (res) {
|
||||
getDetail()
|
||||
setCancelStatus(true)
|
||||
setTxCancelId(undefined)
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
// 购买
|
||||
const onSell = async () => {
|
||||
setLoading(true)
|
||||
const res = await executeOrder(detail.token, detail.price)
|
||||
setTxExecuteId(res.hash)
|
||||
}
|
||||
const getNft = async () => {
|
||||
setLoading(true)
|
||||
const res = await executeOrder(detail.token, 0)
|
||||
setTxExecuteId(res.hash)
|
||||
}
|
||||
const getOrderMap = async (token) => {
|
||||
const res = await orderMap(token)
|
||||
// 竞价按钮
|
||||
if (allowance && !ownOrder && typeIndex === 2 && res?.expiresAt > new Date().getTime()) {
|
||||
setBidAuctionStatus(true)
|
||||
} else {
|
||||
setBidAuctionStatus(false)
|
||||
}
|
||||
if (res.bidder.toLowerCase() === account.toLowerCase()) {
|
||||
setForbid(true)
|
||||
} else {
|
||||
setForbid(false)
|
||||
}
|
||||
setOrderMapData(res)
|
||||
}
|
||||
const onBidAuctionOrder = async () => {
|
||||
// bidder
|
||||
let prices = 0
|
||||
if (orderMapData?.bidder === '0') {
|
||||
prices = new BigNumber(orderMapData.price).multipliedBy(0.1).plus(orderMapData.price).toNumber()
|
||||
// prices = Number(orderMapData.price) + new BigNumber(orderMapData.price).multipliedBy(0.1).toNumber()
|
||||
} else {
|
||||
prices = new BigNumber(orderMapData.bid).multipliedBy(0.1).plus(orderMapData.bid).toNumber()
|
||||
// prices = Number(orderMapData.bid) + new BigNumber(orderMapData.bid).multipliedBy(0.1).toNumber()
|
||||
}
|
||||
setLoading(true)
|
||||
const res = await bidAuctionOrder(detail.token, prices)
|
||||
setTxAuctionId(res.hash)
|
||||
}
|
||||
const countDownFun = (date) => {
|
||||
const date1 = dayjs()
|
||||
const date2 = dayjs(date)
|
||||
const time = date2.diff(date1)
|
||||
if (time > 0) {
|
||||
const hour = Math.floor(time / (1000 * 60 * 60))
|
||||
const minute = Math.floor((time / (1000 * 60)) % 60)
|
||||
const second = Math.round((time / 1000) % 60)
|
||||
setCountDown(`${hour}:${minute}:${second}`)
|
||||
} else {
|
||||
setCountDown(t('finished'))
|
||||
setStatusBtnTxt('end')
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<HeaderFlex>
|
||||
<FirstText onClick={close}>{t('Bazaar')}</FirstText>
|
||||
<ShopText> > {detail?.goodsName}</ShopText>
|
||||
</HeaderFlex>
|
||||
<MainFlex>
|
||||
<ShopFlex>
|
||||
<ShopList
|
||||
item={detail}
|
||||
width={476}
|
||||
height={606}
|
||||
img={detail?.coverResource.url}
|
||||
grade={detail?.goodsGrade}
|
||||
borderRadius="20px"
|
||||
/>
|
||||
</ShopFlex>
|
||||
<Detail>
|
||||
<DetailFlexInfo>
|
||||
<DetailHeaderFlex>
|
||||
<TitleText>{detail?.goodsName}</TitleText>
|
||||
<Image
|
||||
src="/images/nft/share.svg"
|
||||
width={35}
|
||||
height={35}
|
||||
onClick={getLink}
|
||||
style={{ cursor: 'pointer' }}
|
||||
/>
|
||||
</DetailHeaderFlex>
|
||||
{orderMapData?.expiresAt > new Date().getTime() && typeIndex === 2 && (
|
||||
<FlexCom
|
||||
name={t('Auction remaining time')}
|
||||
value={countDown}
|
||||
size="18px"
|
||||
rightSize="30px"
|
||||
textColor="#666666"
|
||||
/>
|
||||
)}
|
||||
{statusBtnTxt !== 'PENDING' && (
|
||||
<FlexCom
|
||||
name={t('order status')}
|
||||
value={statusHeaderTxt[statusBtnTxt]}
|
||||
size="18px"
|
||||
rightSize="30px"
|
||||
textColor="#666666"
|
||||
/>
|
||||
)}
|
||||
{typeIndex !== 2 && (
|
||||
<FlexCom
|
||||
name={t('present price%price%', { price: '' })}
|
||||
value={detail?.price}
|
||||
size="18px"
|
||||
rightSize="30px"
|
||||
textColor="#1FC7D4"
|
||||
/>
|
||||
)}
|
||||
{typeIndex === 2 && (
|
||||
<FlexCom
|
||||
name={orderMapData?.bidder === '0' ? t('Asking price') : t('present price%price%', { price: '' })}
|
||||
value={detail?.price}
|
||||
size="18px"
|
||||
rightSize="30px"
|
||||
textColor="#1FC7D4"
|
||||
/>
|
||||
)}
|
||||
{!account && <UnlockButtonDiv />}
|
||||
{approveStatus && (
|
||||
<AuthorizationBtn
|
||||
disabled={loading}
|
||||
onClick={() => {
|
||||
handleApprove(onHccApprove)
|
||||
}}
|
||||
>
|
||||
{t('Approve %coin% Contract', { coin: 'HCC' })}
|
||||
</AuthorizationBtn>
|
||||
)}
|
||||
{allowance && !ownOrder && sellVerify && typeIndex !== 2 ? (
|
||||
<AuthorizationBtn disabled>{statusTxt[statusBtnTxt]}</AuthorizationBtn>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{/* 改版 */}
|
||||
{/* 竞拍取消挂单:没有人竞拍时 */}
|
||||
{account && allowance && ownOrder && orderMapData?.bidder === '0' ? (
|
||||
<AuthorizationBtn onClick={cancelOrder} disabled={!orderMapData}>
|
||||
{statusTxt[statusBtnTxt]}
|
||||
</AuthorizationBtn>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{allowance && !ownOrder && !sellVerify && typeIndex === 1 ? (
|
||||
<AuthorizationBtn disabled={loading} onClick={onSell}>
|
||||
{t('Buy It Now')}
|
||||
</AuthorizationBtn>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{bidAuctionStatus && (
|
||||
<PriceButton onClick={onBidAuctionOrder} disabled={loading || !orderMapData?.price || forbid}>
|
||||
{t('Fixed markup (%price% premium)', { price: '10%' })}
|
||||
</PriceButton>
|
||||
)}
|
||||
{account &&
|
||||
orderMapData?.expiresAt < new Date().getTime() &&
|
||||
account === orderMapData?.bidder &&
|
||||
typeIndex === 2 ? (
|
||||
<AuthorizationBtn disabled={loading} onClick={getNft}>
|
||||
{t('Claim now')}
|
||||
</AuthorizationBtn>
|
||||
) : (
|
||||
typeIndex === 2 &&
|
||||
account &&
|
||||
!ownOrder &&
|
||||
!approveStatus &&
|
||||
!bidAuctionStatus && <AuthorizationBtn disabled>{statusTxt[statusBtnTxt]}</AuthorizationBtn>
|
||||
)}
|
||||
</DetailFlexInfo>
|
||||
<AssetsInfo typeIndex={typeIndex} tokenId={detail?.token} address={detail?.address} />
|
||||
</Detail>
|
||||
</MainFlex>
|
||||
{typeIndex === 2 && <AuctionTable token={id} time={orderMapData?.expiresAt} />}
|
||||
{/* {typeIndex !== 0 && <TransactionTable />} */}
|
||||
{typeIndex !== 0 && <AuctionRule typeIndex={typeIndex} />}
|
||||
</>
|
||||
)
|
||||
}
|
||||
export default ShopDetail
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
import React, { useState, useEffect } from 'react'
|
||||
import styled from 'styled-components'
|
||||
import { useTranslation } from 'contexts/Localization'
|
||||
import { Flex, Image } from '@pancakeswap/uikit'
|
||||
|
||||
const MainFlex = styled.div`
|
||||
& > .epicBcg {
|
||||
background-color: #ffd7d7;
|
||||
}
|
||||
& > .legendBcg {
|
||||
background-color: #d7d7ff;
|
||||
}
|
||||
& > .uncommonBcg {
|
||||
background-color: #cdf7d2;
|
||||
}
|
||||
& > .commonBcg {
|
||||
background-color: #daf0ff;
|
||||
}
|
||||
|
||||
${({ theme }) => theme.mediaQueries.xs} {
|
||||
flex-direction: column;
|
||||
}
|
||||
${({ theme }) => theme.mediaQueries.md} {
|
||||
flex-direction: row;
|
||||
}
|
||||
${({ theme }) => theme.mediaQueries.lg} {
|
||||
flex-direction: row;
|
||||
}
|
||||
`
|
||||
|
||||
const ShopItem = styled(Flex)`
|
||||
background: rgba(255, 255, 255, 0.39);
|
||||
box-shadow: 0px 1px 8px rgba(0, 0, 0, 0.15);
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
|
||||
& > .ribbon {
|
||||
width: 106px;
|
||||
height: 108px;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
left: -6px;
|
||||
z-index: 10;
|
||||
& > .ribbon1 {
|
||||
line-height: 14px;
|
||||
text-align: center;
|
||||
transform: rotate(-45deg);
|
||||
position: relative;
|
||||
padding: 8px 0;
|
||||
left: -33px;
|
||||
top: 26px;
|
||||
width: 150px;
|
||||
color: white;
|
||||
box-shadow: 0 5px 5px rgba(0, 0, 0, 0.1);
|
||||
letter-spacing: 1px;
|
||||
font-size: 14px;
|
||||
|
||||
${({ theme }) => theme.mediaQueries.xs} {
|
||||
padding: 2px 0;
|
||||
left: -43px;
|
||||
top: 16px;
|
||||
}
|
||||
${({ theme }) => theme.mediaQueries.lg} {
|
||||
padding: 8px 0;
|
||||
left: -33px;
|
||||
top: 26px;
|
||||
}
|
||||
}
|
||||
& > .epic {
|
||||
background: linear-gradient(-90deg, #efea48 0%, #f32121 100%);
|
||||
}
|
||||
& > .legend {
|
||||
background: linear-gradient(-90deg, #4b84f5 0%, #bc21f3 100%);
|
||||
}
|
||||
& > .uncommon {
|
||||
background: linear-gradient(-90deg, #3dffec 0%, #24bf52 100%);
|
||||
}
|
||||
& > .common {
|
||||
background: linear-gradient(-90deg, #b5e9f3 0%, #1195d9 100%);
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
interface ShopListItemProps {
|
||||
item?: Detail
|
||||
width?: number
|
||||
height?: number
|
||||
borderRadius?: string
|
||||
grade?: string
|
||||
img?: string
|
||||
}
|
||||
interface Detail {
|
||||
label?: string
|
||||
type?: number | string
|
||||
id?: number | string
|
||||
}
|
||||
|
||||
const ShopListBazaar: React.FC<ShopListItemProps> = ({
|
||||
item,
|
||||
width = 186,
|
||||
height = 187,
|
||||
borderRadius = '20px',
|
||||
img,
|
||||
grade,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const getClassBcg = () => {
|
||||
let bcg = ''
|
||||
switch (grade) {
|
||||
case 'EPIC':
|
||||
bcg = 'epicBcg'
|
||||
break
|
||||
case 'LEGEND':
|
||||
bcg = 'legendBcg'
|
||||
break
|
||||
case 'RARE':
|
||||
bcg = 'uncommonBcg'
|
||||
break
|
||||
case 'NORMAL':
|
||||
bcg = 'commonBcg'
|
||||
break
|
||||
default:
|
||||
bcg = 'epicBcg'
|
||||
}
|
||||
return bcg
|
||||
}
|
||||
|
||||
return (
|
||||
<MainFlex>
|
||||
<ShopItem className={getClassBcg()} style={{ borderRadius }}>
|
||||
<div className="ribbon">
|
||||
{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>
|
||||
{img ? (
|
||||
<Image src={img} width={width} height={height} />
|
||||
) : (
|
||||
<Image src="/images/nft/uncommon.svg" width={width} height={height} />
|
||||
)}
|
||||
</ShopItem>
|
||||
</MainFlex>
|
||||
)
|
||||
}
|
||||
export default ShopListBazaar
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
import React, { useState, useEffect } from 'react'
|
||||
import Pagination from '@mui/material/Pagination'
|
||||
import styled from 'styled-components'
|
||||
import { useTranslation } from 'contexts/Localization'
|
||||
import { Flex, Text, Button } from '@pancakeswap/uikit'
|
||||
import Empty from 'components/Empty'
|
||||
import { useGetSelfPage } from '../../NftBox/hooks'
|
||||
import ShopList from './ShopList'
|
||||
|
||||
interface ShopProp {
|
||||
|
|
@ -9,8 +12,31 @@ interface ShopProp {
|
|||
value?: string | number
|
||||
onDismiss?: () => void
|
||||
close: () => void
|
||||
add?: (v) => void
|
||||
}
|
||||
|
||||
interface Detail {
|
||||
address?: string
|
||||
createdAt?: string
|
||||
id?: string
|
||||
info: InfoProps
|
||||
token?: string
|
||||
updatedAt?: string
|
||||
select?: boolean
|
||||
pending?: boolean
|
||||
}
|
||||
interface InfoProps {
|
||||
coverResource?: CoverResourceProps
|
||||
grade?: string
|
||||
id?: string
|
||||
name?: string
|
||||
price?: any
|
||||
type?: string
|
||||
}
|
||||
interface CoverResourceProps {
|
||||
path?: string
|
||||
url?: string
|
||||
}
|
||||
const Main = styled.div`
|
||||
width: 60%;
|
||||
background-color: #fff;
|
||||
|
|
@ -63,6 +89,7 @@ const SelectFlex = styled(Flex)`
|
|||
width: 30px;
|
||||
height: 30px;
|
||||
background: #fff;
|
||||
box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.16);
|
||||
border-radius: 50%;
|
||||
z-index: 9;
|
||||
align-items: center;
|
||||
|
|
@ -100,9 +127,35 @@ const OutButton = styled(Button)`
|
|||
margin-top: 20px;
|
||||
`
|
||||
|
||||
const ShopModal: React.FC<ShopProp> = ({ name, value, onDismiss, close }) => {
|
||||
const ShopModal: React.FC<ShopProp> = ({ name, value, onDismiss, close, add }) => {
|
||||
const { t } = useTranslation()
|
||||
const [list, setList] = useState([])
|
||||
const [list, setList] = useState<Detail[]>()
|
||||
const [pageNum, setPage] = useState(1)
|
||||
const [count, setCount] = useState(undefined)
|
||||
const getSelfPage = useGetSelfPage()
|
||||
const getData = async () => {
|
||||
const params = {
|
||||
page: pageNum,
|
||||
size: 8,
|
||||
pending: false,
|
||||
}
|
||||
const { size, total, content } = await getSelfPage(params)
|
||||
const arr = []
|
||||
content.forEach((item) => {
|
||||
const obj = item
|
||||
obj.select = false
|
||||
arr.push(item)
|
||||
})
|
||||
setList([...arr])
|
||||
setCount(getTotalPageNum(total, size))
|
||||
}
|
||||
const getTotalPageNum = (total, pageSize) => {
|
||||
const countTotal = ((Number(total) + Number(pageSize) - 1) / Number(pageSize)).toString()
|
||||
return parseInt(countTotal)
|
||||
}
|
||||
const pageChange = (event, page) => {
|
||||
setPage(page)
|
||||
}
|
||||
|
||||
const pitchOn = (index) => {
|
||||
const arr = []
|
||||
|
|
@ -116,32 +169,44 @@ const ShopModal: React.FC<ShopProp> = ({ name, value, onDismiss, close }) => {
|
|||
const onClose = () => {
|
||||
close()
|
||||
}
|
||||
// 添加nft
|
||||
const addNft = () => {
|
||||
const info = list.find((item) => item.select)
|
||||
add(info)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setList([
|
||||
{ label: 'Cat goddess Emerald ', type: 1, id: 1, select: true },
|
||||
{ label: 'Cat goddess Emerald ', type: 2, id: 2, select: false },
|
||||
{ label: 'Cat goddess Emerald ', type: 3, id: 3, select: false },
|
||||
{ label: 'Cat goddess Emerald ', type: 4, id: 4, select: false },
|
||||
{ label: 'Cat goddess Emerald ', type: 1, id: 5, select: false },
|
||||
])
|
||||
}, [])
|
||||
getData()
|
||||
}, [pageNum])
|
||||
|
||||
return (
|
||||
<Main>
|
||||
<Shop>
|
||||
{list.map((item, index) => {
|
||||
return (
|
||||
<ShopFlex key={item.id} onClick={() => pitchOn(index)} className={item.select ? 'active' : ''}>
|
||||
<SelectFlex>{item.select && <SelectDiv />}</SelectFlex>
|
||||
<ShopList item={item} width={278} height={280} borderRadius="20px 20px 0 0" />
|
||||
<ShopName>{item.label}</ShopName>
|
||||
</ShopFlex>
|
||||
)
|
||||
})}
|
||||
{list?.length > 0 &&
|
||||
list?.map((item, index) => {
|
||||
return (
|
||||
<ShopFlex key={item?.id} onClick={() => pitchOn(index)} className={item?.select ? 'active' : ''}>
|
||||
<SelectFlex>{item?.select && <SelectDiv />}</SelectFlex>
|
||||
<ShopList
|
||||
item={item}
|
||||
img={item?.info?.coverResource?.url}
|
||||
width={278}
|
||||
height={280}
|
||||
borderRadius="20px 20px 0 0"
|
||||
/>
|
||||
<ShopName>{item?.info?.name}</ShopName>
|
||||
</ShopFlex>
|
||||
)
|
||||
})}
|
||||
</Shop>
|
||||
{list?.length > 0 && (
|
||||
<Flex justifyContent="center" padding={10}>
|
||||
<Pagination count={count} onChange={pageChange} page={pageNum} />
|
||||
</Flex>
|
||||
)}
|
||||
{list?.length === 0 && <Empty />}
|
||||
<BtnFlex>
|
||||
<AddButton>{t('add NFT')}</AddButton>
|
||||
{list?.length > 0 && <AddButton onClick={addNft}>{t('add NFT')}</AddButton>}
|
||||
<OutButton onClick={onClose}>{t('Sign out')}</OutButton>
|
||||
</BtnFlex>
|
||||
</Main>
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import Pagination from '@mui/material/Pagination'
|
|||
import { Text, Button, Image, Flex } from '@pancakeswap/uikit'
|
||||
import { useTranslation } from 'contexts/Localization'
|
||||
import Empty from 'components/Empty'
|
||||
import { tradeRecordPage } from 'services/bazaar'
|
||||
import { useGetPurchaseRecord, useGetNftDetail } from '../hooks'
|
||||
|
||||
interface TransactionRecordProps {
|
||||
|
|
@ -137,6 +138,37 @@ const TransactionRecord: React.FC<TransactionRecordProps> = ({ onDismiss, active
|
|||
const [count, setCount] = useState(undefined)
|
||||
|
||||
const getPurchaseRecord = useGetPurchaseRecord()
|
||||
|
||||
const getWayList = async () => {
|
||||
let relationType = ''
|
||||
let status = ''
|
||||
switch (typeIndex) {
|
||||
case 0:
|
||||
relationType = ''
|
||||
status = ''
|
||||
break
|
||||
case 1:
|
||||
relationType = 'PUBLISH'
|
||||
status = 'PENDING'
|
||||
break
|
||||
case 2:
|
||||
relationType = 'PUBLISH'
|
||||
status = 'SUCCESS'
|
||||
break
|
||||
case 3:
|
||||
relationType = 'PARTICIPATE'
|
||||
status = 'SUCCESS'
|
||||
break
|
||||
default:
|
||||
relationType = ''
|
||||
status = ''
|
||||
}
|
||||
const obj = { page: pageNum, size: 10, type: 'NORMAL', relationType, status }
|
||||
const res = await tradeRecordPage(obj)
|
||||
setCount(getTotalPageNum(res.total, 4))
|
||||
setList(res.content)
|
||||
}
|
||||
|
||||
const getList = async () => {
|
||||
const result = await getPurchaseRecord(pageNum, 10)
|
||||
setCount(getTotalPageNum(result.total, result.size))
|
||||
|
|
@ -154,8 +186,12 @@ const TransactionRecord: React.FC<TransactionRecordProps> = ({ onDismiss, active
|
|||
}
|
||||
|
||||
useEffect(() => {
|
||||
getList()
|
||||
}, [pageNum])
|
||||
if (activeIndex !== 0) {
|
||||
getWayList()
|
||||
} else {
|
||||
getList()
|
||||
}
|
||||
}, [pageNum, typeIndex])
|
||||
|
||||
const pageChange = (event, page) => {
|
||||
setPage(page)
|
||||
|
|
@ -169,13 +205,22 @@ const TransactionRecord: React.FC<TransactionRecordProps> = ({ onDismiss, active
|
|||
}
|
||||
const getNftDetail = useGetNftDetail()
|
||||
const lookDetail = async (item) => {
|
||||
const res = await getNftDetail(item.token, { token: item.token })
|
||||
const obj = res.info
|
||||
obj.record = true
|
||||
let obj = { record: false, token: '' }
|
||||
if (activeIndex !== 0) {
|
||||
obj = item
|
||||
} else {
|
||||
const res = await getNftDetail(item.token, { token: item.token })
|
||||
obj = res.info
|
||||
obj.record = true
|
||||
obj.token = res.token
|
||||
}
|
||||
recordDetail(obj)
|
||||
onDismiss()
|
||||
}
|
||||
|
||||
const changeType = (index) => {
|
||||
setTypeIndex(index)
|
||||
setPage(1)
|
||||
}
|
||||
return (
|
||||
<FlexMain>
|
||||
<CloseImage src="/images/nft/close.svg" width={15} height={15} onClick={onDismiss} />
|
||||
|
|
@ -187,7 +232,7 @@ const TransactionRecord: React.FC<TransactionRecordProps> = ({ onDismiss, active
|
|||
<TypeItem
|
||||
key={item.value}
|
||||
className={index === typeIndex ? 'active' : ''}
|
||||
onClick={() => setTypeIndex(index)}
|
||||
onClick={() => changeType(index)}
|
||||
>
|
||||
{item.label}
|
||||
</TypeItem>
|
||||
|
|
@ -207,18 +252,22 @@ const TransactionRecord: React.FC<TransactionRecordProps> = ({ onDismiss, active
|
|||
return (
|
||||
<TrFlex key={item.id}>
|
||||
<TdFlex>{item.goodsName}</TdFlex>
|
||||
<TdFlex>
|
||||
{item.priceList.map((childItem, childIndex) => {
|
||||
return (
|
||||
<Flex alignItems="center" key={childItem.label}>
|
||||
<>{Number(childItem.value).toFixed(2)}</>
|
||||
<Text color="text">{childItem.label}</Text>
|
||||
{childIndex === 0 && item.priceList.length === 2 && <Text margin="0 5px">-</Text>}
|
||||
</Flex>
|
||||
)
|
||||
})}
|
||||
</TdFlex>
|
||||
<TdFlex>{dayjs(Number(item.tradeTime)).format('YYYY-MM-DD HH:mm:ss')}</TdFlex>
|
||||
{activeIndex === 0 && (
|
||||
<TdFlex>
|
||||
{item.priceList.map((childItem, childIndex) => {
|
||||
return (
|
||||
<Flex alignItems="center" key={childItem.label}>
|
||||
<>{Number(childItem.value).toFixed(2)}</>
|
||||
<Text color="text">{childItem.label}</Text>
|
||||
{childIndex === 0 && item.priceList.length === 2 && <Text margin="0 5px">-</Text>}
|
||||
</Flex>
|
||||
)
|
||||
})}
|
||||
</TdFlex>
|
||||
)}
|
||||
{activeIndex !== 0 && <TdFlex>{item.lastPrice}</TdFlex>}
|
||||
{activeIndex === 0 && <TdFlex>{dayjs(Number(item.tradeTime)).format('YYYY-MM-DD HH:mm:ss')}</TdFlex>}
|
||||
{activeIndex !== 0 && <TdFlex>{item.updatedAt}</TdFlex>}
|
||||
<TdFlex>{item.status ? item.status : t('success')}</TdFlex>
|
||||
<TdBtnFlex>
|
||||
<DetailButton onClick={() => lookDetail(item)}>{t('Detail')}</DetailButton>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,20 @@
|
|||
import { useCallback } from 'react'
|
||||
import { useBlindBox } from 'hooks/useContract'
|
||||
import { getAddress, getBlindBoxAddress } from 'utils/addressHelpers'
|
||||
import { getOfficialPage, getOfficialPurchase, getPurchaseRecord, getNftDetail } from 'services/bazaar'
|
||||
import hccMarketplaceABI from 'config/abi/hccMarketplace.json'
|
||||
import blindBoxABI from 'config/abi/blindBox.json'
|
||||
import { useBlindBox, useHccMarketplace } from 'hooks/useContract'
|
||||
import { getAddress, getBlindBoxAddress, getHccMarketplaceAddress } from 'utils/addressHelpers'
|
||||
import { useAccount } from 'state/userInfo/hooks'
|
||||
import { getOfficialPage, getOfficialPurchase, getPurchaseRecord, getNftDetail, getTradePage } from 'services/bazaar'
|
||||
import { ethers, Contract } from 'ethers'
|
||||
import multicall from 'utils/multicall'
|
||||
import {
|
||||
getBalanceNumber,
|
||||
getDecimalAmount,
|
||||
formatDivNumber,
|
||||
getDecimalAmountNumber,
|
||||
formatTimeNumber,
|
||||
} from 'utils/formatBalance'
|
||||
import BigNumber from 'bignumber.js'
|
||||
|
||||
export const useGetOfficialPage = () => {
|
||||
const data = async (params) => {
|
||||
|
|
@ -39,6 +51,19 @@ export const useApproveHcc = (tokenContract: Contract) => {
|
|||
|
||||
return { onApprove: handleApprove }
|
||||
}
|
||||
export const useMarketplaceApproveHcc = (tokenContract: Contract) => {
|
||||
const handleApprove = useCallback(async () => {
|
||||
try {
|
||||
const tx = await tokenContract.approve(getHccMarketplaceAddress(), ethers.constants.MaxUint256)
|
||||
const receipt = await tx.wait()
|
||||
return receipt.status
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
}, [tokenContract])
|
||||
|
||||
return { onApprove: handleApprove }
|
||||
}
|
||||
|
||||
// 交易记录
|
||||
export const useGetPurchaseRecord = () => {
|
||||
|
|
@ -74,4 +99,212 @@ export const useGetNftDetail = () => {
|
|||
return data
|
||||
}
|
||||
|
||||
// 市场分页
|
||||
export const useGetTradePage = () => {
|
||||
const data = async (params) => {
|
||||
const result = await getTradePage(params)
|
||||
console.log(result)
|
||||
return result
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
// 是否授权合约
|
||||
export const useIsApproved = () => {
|
||||
const account = useAccount()
|
||||
const blindBox = useBlindBox()
|
||||
const address = getBlindBoxAddress()
|
||||
const hccMarketplaceAddress = getHccMarketplaceAddress()
|
||||
const transaction = async (tokenId) => {
|
||||
const mintParams = [tokenId]
|
||||
|
||||
const calls = [
|
||||
{
|
||||
address,
|
||||
name: 'getApproved',
|
||||
params: [tokenId],
|
||||
},
|
||||
]
|
||||
|
||||
const res = await multicall(blindBoxABI, calls)
|
||||
// const res = await blindBox.getApproved(...mintParams)
|
||||
console.log(res[0][0].toLowerCase())
|
||||
console.log(hccMarketplaceAddress)
|
||||
let status = false
|
||||
if (res[0][0].toLowerCase() === hccMarketplaceAddress.toLowerCase()) {
|
||||
status = true
|
||||
}
|
||||
return status
|
||||
}
|
||||
return transaction
|
||||
}
|
||||
// approve
|
||||
export const useApproved = () => {
|
||||
const account = useAccount()
|
||||
const blindBox = useBlindBox()
|
||||
const address = getBlindBoxAddress()
|
||||
const hccMarketplaceAddress = getHccMarketplaceAddress()
|
||||
const transaction = async (tokenId) => {
|
||||
const mintParams = [hccMarketplaceAddress, tokenId]
|
||||
console.log(mintParams)
|
||||
// const calls = [
|
||||
// {
|
||||
// address,
|
||||
// name: 'getApproved',
|
||||
// params: [tokenId],
|
||||
// },
|
||||
// ]
|
||||
|
||||
// const res = await multicall(blindBoxABI, calls)
|
||||
const res = await blindBox.approve(...mintParams)
|
||||
console.log(res)
|
||||
return res
|
||||
}
|
||||
return transaction
|
||||
}
|
||||
|
||||
// 一口价
|
||||
export const useCreateNormalOrder = () => {
|
||||
const hccMarketplace = useHccMarketplace()
|
||||
const transaction = async (tokenId, price) => {
|
||||
const hccMarketplaceAddress = getHccMarketplaceAddress()
|
||||
const calls = [
|
||||
{
|
||||
address: hccMarketplaceAddress,
|
||||
name: 'createNormalOrder',
|
||||
params: [tokenId, getDecimalAmount(price).toString()],
|
||||
},
|
||||
]
|
||||
const mintParams = [tokenId, getDecimalAmount(price).toString()]
|
||||
console.log(mintParams)
|
||||
const res = await hccMarketplace.createNormalOrder(...mintParams)
|
||||
|
||||
// const res = await multicall(hccMarketplaceABI, calls)
|
||||
console.log(res)
|
||||
return res
|
||||
}
|
||||
return transaction
|
||||
}
|
||||
|
||||
// 拍卖
|
||||
export const useCreateAuctionOrder = () => {
|
||||
const hccMarketplace = useHccMarketplace()
|
||||
const transaction = async (tokenId, price, time) => {
|
||||
const hccMarketplaceAddress = getHccMarketplaceAddress()
|
||||
// const calls = [
|
||||
// {
|
||||
// address: hccMarketplaceAddress,
|
||||
// name: 'createAuctionOrder',
|
||||
// params: [account],
|
||||
// },
|
||||
// ]
|
||||
console.log(hccMarketplace)
|
||||
const mintParams = [tokenId, getDecimalAmount(price).toString(), time]
|
||||
console.log(mintParams)
|
||||
const res = await hccMarketplace.createAuctionOrder(...mintParams)
|
||||
// const res = await multicall(hccMarketplaceABI, calls)
|
||||
console.log(res)
|
||||
return res
|
||||
}
|
||||
return transaction
|
||||
}
|
||||
|
||||
// 取消挂单
|
||||
export const useCancelOrder = () => {
|
||||
const hccMarketplace = useHccMarketplace()
|
||||
const transaction = async (id) => {
|
||||
const hccMarketplaceAddress = getHccMarketplaceAddress()
|
||||
// const calls = [
|
||||
// {
|
||||
// address: hccMarketplaceAddress,
|
||||
// name: 'createAuctionOrder',
|
||||
// params: [account],
|
||||
// },
|
||||
// ]
|
||||
|
||||
const mintParams = [id]
|
||||
console.log(...mintParams)
|
||||
const res = await hccMarketplace.cancelOrder(...mintParams)
|
||||
// const res = await multicall(hccMarketplaceABI, calls)
|
||||
console.log(res)
|
||||
return res
|
||||
}
|
||||
return transaction
|
||||
}
|
||||
|
||||
// 一口价购买
|
||||
export const useExecuteOrder = () => {
|
||||
const hccMarketplace = useHccMarketplace()
|
||||
const transaction = async (tokenId, price) => {
|
||||
const hccMarketplaceAddress = getHccMarketplaceAddress()
|
||||
// const calls = [
|
||||
// {
|
||||
// address: hccMarketplaceAddress,
|
||||
// name: 'createAuctionOrder',
|
||||
// params: [account],
|
||||
// },
|
||||
// ]
|
||||
|
||||
const mintParams = [tokenId, getDecimalAmount(price).toString()]
|
||||
console.log(...mintParams)
|
||||
const res = await hccMarketplace.executeOrder(...mintParams)
|
||||
// const res = await multicall(hccMarketplaceABI, calls)
|
||||
console.log(res)
|
||||
return res
|
||||
}
|
||||
return transaction
|
||||
}
|
||||
// 竞价
|
||||
export const useBidAuctionOrder = () => {
|
||||
const hccMarketplace = useHccMarketplace()
|
||||
const transaction = async (tokenId, price) => {
|
||||
const hccMarketplaceAddress = getHccMarketplaceAddress()
|
||||
// const calls = [
|
||||
// {
|
||||
// address: hccMarketplaceAddress,
|
||||
// name: 'createAuctionOrder',
|
||||
// params: [account],
|
||||
// },
|
||||
// ]
|
||||
|
||||
const mintParams = [tokenId, getDecimalAmount(price).toString()]
|
||||
console.log(...mintParams)
|
||||
const res = await hccMarketplace.bidAuctionOrder(...mintParams)
|
||||
// const res = await multicall(hccMarketplaceABI, calls)
|
||||
console.log(res)
|
||||
return res
|
||||
}
|
||||
return transaction
|
||||
}
|
||||
|
||||
export const useOrderMap = () => {
|
||||
const hccMarketplace = useHccMarketplace()
|
||||
const transaction = async (tokenId) => {
|
||||
const hccMarketplaceAddress = getHccMarketplaceAddress()
|
||||
const calls = [
|
||||
{
|
||||
address: hccMarketplaceAddress,
|
||||
name: 'orderMap',
|
||||
params: [tokenId],
|
||||
},
|
||||
]
|
||||
const res = await multicall(hccMarketplaceABI, calls)
|
||||
const arr = res.map((item) => {
|
||||
console.log(item)
|
||||
console.log(new BigNumber(item.expiresAt._hex).toNumber())
|
||||
return {
|
||||
price: getBalanceNumber(item.price._hex),
|
||||
expiresAt: new BigNumber(item.expiresAt._hex).toNumber(),
|
||||
bidder:
|
||||
new BigNumber(item.bidder).toString().toLowerCase() === 'nan'
|
||||
? item.bidder
|
||||
: new BigNumber(item.bidder).toString().toLowerCase(),
|
||||
bid: getBalanceNumber(item.bid._hex),
|
||||
}
|
||||
})
|
||||
return arr[0]
|
||||
}
|
||||
return transaction
|
||||
}
|
||||
|
||||
export default useGetOfficialPage
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ const HeaderStatus: React.FC<HeaderStatusProps> = ({ status, roundDetail }) => {
|
|||
|
||||
return (
|
||||
<TimeText>
|
||||
{/* {status === 'close' && t('Exchange closed')} */}
|
||||
{status === 'close' && t('Exchange closed')}
|
||||
{status === 'none' && t('Exchange not commenced')}
|
||||
|
||||
{status === 'proceed' && (
|
||||
|
|
|
|||
|
|
@ -68,8 +68,6 @@ export const useGetRound = () => {
|
|||
}
|
||||
const { id } = data
|
||||
const idoPurchaseAddress = getIdoPurchaseAddress()
|
||||
console.log(idoPurchaseAddress)
|
||||
console.log(id)
|
||||
const calls = [
|
||||
{
|
||||
address: idoPurchaseAddress,
|
||||
|
|
@ -91,6 +89,7 @@ export const useGetRound = () => {
|
|||
total: formatDivNumber(item?.total._hex, 18),
|
||||
}
|
||||
})
|
||||
console.log(detail[0])
|
||||
return detail[0]
|
||||
}
|
||||
return transaction
|
||||
|
|
|
|||
|
|
@ -41,10 +41,17 @@ const Exchange: React.FC = () => {
|
|||
const getRound = useGetRound()
|
||||
const init = async () => {
|
||||
const detail = await getRound()
|
||||
console.log(typeof detail.remaining)
|
||||
if (!detail || detail.endTime < new Date().getTime()) {
|
||||
setStatus('none')
|
||||
} else if (detail.beginTime < new Date().getTime() && detail.endTime > new Date().getTime()) {
|
||||
} else if (
|
||||
detail.beginTime < new Date().getTime() &&
|
||||
detail.endTime > new Date().getTime() &&
|
||||
detail.remaining > 0
|
||||
) {
|
||||
setStatus('proceed')
|
||||
} else if (detail.remaining === 0) {
|
||||
setStatus('close')
|
||||
} else {
|
||||
setStatus('end')
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import React, { useState, useEffect } from 'react'
|
||||
import styled from 'styled-components'
|
||||
import { useTranslation } from 'contexts/Localization'
|
||||
import { Modal, Flex, Text, Image, Button } from '@pancakeswap/uikit'
|
||||
import { Modal, Flex, Text, Image, Button, useModal } from '@pancakeswap/uikit'
|
||||
import { useGetNftDetails } from '../hooks'
|
||||
import AssetsInfo from './AssetsInfo'
|
||||
import SellModal from '../../Bazaar/components/SellModal'
|
||||
|
||||
interface DetailProp {
|
||||
token?: string
|
||||
|
|
@ -133,7 +134,11 @@ const DetailFlex = styled(Flex)`
|
|||
const SellButton = styled(Button)`
|
||||
height: 60px;
|
||||
background: linear-gradient(269deg, #1fc8d3 0%, #1fd4b0 100%);
|
||||
opacity: 1;
|
||||
border-radius: 30px;
|
||||
margin-top: 30px;
|
||||
`
|
||||
const HaveButton = styled(Button)`
|
||||
height: 60px;
|
||||
border-radius: 30px;
|
||||
margin-top: 30px;
|
||||
`
|
||||
|
|
@ -156,6 +161,8 @@ const DetailModal: React.FC<DetailProp> = ({ token, onDismiss }) => {
|
|||
getDetail()
|
||||
}, [token])
|
||||
|
||||
const [onSellModal] = useModal(<SellModal detailData={detail} />)
|
||||
|
||||
return (
|
||||
<Main title="" onDismiss={onDismiss}>
|
||||
<CenterDiv>
|
||||
|
|
@ -171,7 +178,8 @@ const DetailModal: React.FC<DetailProp> = ({ token, onDismiss }) => {
|
|||
</ShopItem>
|
||||
<DetailFlex>
|
||||
<AssetsInfo detail={detail} />
|
||||
<SellButton>{t('Selling immediately')}</SellButton>
|
||||
{!detail?.pending && <SellButton onClick={onSellModal}>{t('Selling immediately')}</SellButton>}
|
||||
{detail?.pending && <HaveButton disabled>{t('Have they')}</HaveButton>}
|
||||
</DetailFlex>
|
||||
</MainFlex>
|
||||
</CenterDiv>
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ interface Detail {
|
|||
info: InfoProps
|
||||
token?: string
|
||||
updatedAt?: string
|
||||
pending?: boolean
|
||||
}
|
||||
interface InfoProps {
|
||||
coverResource?: CoverResourceProps
|
||||
|
|
|
|||
Loading…
Reference in New Issue