对接nft市场
This commit is contained in:
parent
08bd178bf5
commit
f565316323
|
|
@ -1256,7 +1256,7 @@
|
||||||
"Selling time": "出售时间",
|
"Selling time": "出售时间",
|
||||||
"Add as a trading pair": "添加为交易对",
|
"Add as a trading pair": "添加为交易对",
|
||||||
"reselect NFT": "重新选择NFT",
|
"reselect NFT": "重新选择NFT",
|
||||||
"Auction countdown": "拍卖倒计时",
|
"Auction remaining time": "拍卖剩余时间",
|
||||||
"present price%price%": "当前价格%price%",
|
"present price%price%": "当前价格%price%",
|
||||||
"Fixed markup (%price% premium)": "固定加价(%price%溢价)",
|
"Fixed markup (%price% premium)": "固定加价(%price%溢价)",
|
||||||
"owner": "拥有者",
|
"owner": "拥有者",
|
||||||
|
|
@ -1285,5 +1285,20 @@
|
||||||
"PROPS": "道具",
|
"PROPS": "道具",
|
||||||
"rarity": "稀有度",
|
"rarity": "稀有度",
|
||||||
"success": "成功",
|
"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])
|
}, [userInfo])
|
||||||
const sign = useSignLogin()
|
const sign = useSignLogin()
|
||||||
const handleLogin = async (connectorID: ConnectorNames) => {
|
const handleLogin = async (connectorID: ConnectorNames) => {
|
||||||
console.log(connectorID)
|
|
||||||
await login(connectorID)
|
await login(connectorID)
|
||||||
setHasWalletLogin(true)
|
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兑换
|
56: '0x2f562A9fE0325501A6Aa92cd9e2081B026fC35aa', // NEED CHANGE IDO兑换
|
||||||
5: '0x81cdaf31147b86ffe6303b1bde6f20a5377d87b1',
|
5: '0x81cdaf31147b86ffe6303b1bde6f20a5377d87b1',
|
||||||
},
|
},
|
||||||
|
hccMarketplace: {
|
||||||
|
97: '0x91b9a998eedbb513f86b7d2a8efc01624a6d9636',
|
||||||
|
56: '0x75c6c866f9f4ba6d0cad39d29f8e54a7ec64afb8', // NEED CHANGE NFT市场
|
||||||
|
5: '0x8678a822dfa815da423517b315641ef7f20020d7',
|
||||||
|
},
|
||||||
blindBox: {
|
blindBox: {
|
||||||
97: '0x0e226d7b83b511ce224803b1330beb4a59bfa5d6',
|
97: '0x0e226d7b83b511ce224803b1330beb4a59bfa5d6',
|
||||||
56: '0x0e226d7b83b511ce224803b1330beb4a59bfa5d6', // NEED CHANGE 官方市场 盲盒
|
56: '0x0e226d7b83b511ce224803b1330beb4a59bfa5d6', // NEED CHANGE 官方市场 盲盒
|
||||||
|
|
|
||||||
|
|
@ -1383,7 +1383,7 @@
|
||||||
"Selling time": "Selling time",
|
"Selling time": "Selling time",
|
||||||
"Add as a trading pair": "Add as a trading pair",
|
"Add as a trading pair": "Add as a trading pair",
|
||||||
"reselect NFT": "reselect NFT",
|
"reselect NFT": "reselect NFT",
|
||||||
"Auction countdown": "Auction countdown",
|
"Auction remaining time": "Auction remaining time",
|
||||||
"present price%price%": "present price%price%",
|
"present price%price%": "present price%price%",
|
||||||
"Fixed markup (%price% premium)": "Fixed markup (%price% premium)",
|
"Fixed markup (%price% premium)": "Fixed markup (%price% premium)",
|
||||||
"owner": "owner",
|
"owner": "owner",
|
||||||
|
|
@ -1412,5 +1412,20 @@
|
||||||
"PROPS": "PROPS",
|
"PROPS": "PROPS",
|
||||||
"rarity": "rarity",
|
"rarity": "rarity",
|
||||||
"success": "success",
|
"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,
|
getIdoPurchaseContract,
|
||||||
getBlindBoxContract,
|
getBlindBoxContract,
|
||||||
getHolderPoolContract,
|
getHolderPoolContract,
|
||||||
|
getHccMarketplaceContract,
|
||||||
} from 'utils/contractHelpers'
|
} from 'utils/contractHelpers'
|
||||||
|
|
||||||
// Imports below migrated from Exchange useContract.ts
|
// Imports below migrated from Exchange useContract.ts
|
||||||
|
|
@ -124,6 +125,10 @@ export const useHolderPool = () => {
|
||||||
const { library } = useActiveWeb3React()
|
const { library } = useActiveWeb3React()
|
||||||
return useMemo(() => getHolderPoolContract(library.getSigner()), [library])
|
return useMemo(() => getHolderPoolContract(library.getSigner()), [library])
|
||||||
}
|
}
|
||||||
|
export const useHccMarketplace = () => {
|
||||||
|
const { library } = useActiveWeb3React()
|
||||||
|
return useMemo(() => getHccMarketplaceContract(library.getSigner()), [library])
|
||||||
|
}
|
||||||
export const useReferralRewardchef = () => {
|
export const useReferralRewardchef = () => {
|
||||||
const { library } = useActiveWeb3React()
|
const { library } = useActiveWeb3React()
|
||||||
return useMemo(() => getReferralRewardchefContract(library.getSigner()), [library])
|
return useMemo(() => getReferralRewardchefContract(library.getSigner()), [library])
|
||||||
|
|
|
||||||
|
|
@ -36,4 +36,61 @@ export const getNftDetail = (id, params) => {
|
||||||
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
|
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) => {
|
export const fetchBlindBoxUserAllowances = async (account: string) => {
|
||||||
const calls = Object.values(payWayList).map((payWayItem) => {
|
const calls = Object.values(payWayList).map((payWayItem) => {
|
||||||
const tokenAddresses = getAddress(payWayItem.address)
|
const tokenAddresses = getAddress(payWayItem.address)
|
||||||
const referralChefAddress = getBlindBoxAddress()
|
const blindBoxAddress = getBlindBoxAddress()
|
||||||
return { address: tokenAddresses, name: 'allowance', params: [account, referralChefAddress] }
|
return { address: tokenAddresses, name: 'allowance', params: [account, blindBoxAddress] }
|
||||||
})
|
})
|
||||||
|
|
||||||
const rawLpAllowances = await multicall(erc20ABI, calls)
|
const rawLpAllowances = await multicall(erc20ABI, calls)
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,12 @@ export interface ListProps {
|
||||||
priceList?: PriceProps[]
|
priceList?: PriceProps[]
|
||||||
type?: string
|
type?: string
|
||||||
record?: boolean
|
record?: boolean
|
||||||
|
token?: string
|
||||||
|
|
||||||
|
goodsName?: string
|
||||||
|
goodsType?: string
|
||||||
|
goodsId?: string
|
||||||
|
goodsGrade?: string
|
||||||
}
|
}
|
||||||
export interface CoverResourceProps {
|
export interface CoverResourceProps {
|
||||||
path?: string
|
path?: string
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,9 @@ export const getBunnySpecialPredictionAddress = () => {
|
||||||
export const getIdoPurchaseAddress = () => {
|
export const getIdoPurchaseAddress = () => {
|
||||||
return getAddress(addresses.idoPurchase)
|
return getAddress(addresses.idoPurchase)
|
||||||
}
|
}
|
||||||
|
export const getHccMarketplaceAddress = () => {
|
||||||
|
return getAddress(addresses.hccMarketplace)
|
||||||
|
}
|
||||||
export const getBlindBoxAddress = () => {
|
export const getBlindBoxAddress = () => {
|
||||||
return getAddress(addresses.blindBox)
|
return getAddress(addresses.blindBox)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ import {
|
||||||
getReferralAddress,
|
getReferralAddress,
|
||||||
getReferralRewardAddress,
|
getReferralRewardAddress,
|
||||||
getIdoPurchaseAddress,
|
getIdoPurchaseAddress,
|
||||||
|
getHccMarketplaceAddress,
|
||||||
getBlindBoxAddress,
|
getBlindBoxAddress,
|
||||||
getHolderPoolAddress,
|
getHolderPoolAddress,
|
||||||
} from 'utils/addressHelpers'
|
} from 'utils/addressHelpers'
|
||||||
|
|
@ -63,6 +64,7 @@ import MultiCallAbi from 'config/abi/Multicall.json'
|
||||||
import bunnySpecialCakeVaultAbi from 'config/abi/bunnySpecialCakeVault.json'
|
import bunnySpecialCakeVaultAbi from 'config/abi/bunnySpecialCakeVault.json'
|
||||||
import bunnySpecialPredictionAbi from 'config/abi/bunnySpecialPrediction.json'
|
import bunnySpecialPredictionAbi from 'config/abi/bunnySpecialPrediction.json'
|
||||||
import idoPurchase from 'config/abi/idoPurchase.json'
|
import idoPurchase from 'config/abi/idoPurchase.json'
|
||||||
|
import hccMarketplace from 'config/abi/hccMarketplace.json'
|
||||||
import holderPool from 'config/abi/holderPool.json'
|
import holderPool from 'config/abi/holderPool.json'
|
||||||
import blindBox from 'config/abi/blindBox.json'
|
import blindBox from 'config/abi/blindBox.json'
|
||||||
import { ChainLinkOracleContract, PredictionsContract } from './types'
|
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) => {
|
export const getIdoPurchaseContract = (signer?: ethers.Signer | ethers.providers.Provider) => {
|
||||||
return getContract(idoPurchase, getIdoPurchaseAddress(), signer)
|
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) => {
|
export const getHolderPoolContract = (signer?: ethers.Signer | ethers.providers.Provider) => {
|
||||||
return getContract(holderPool, getHolderPoolAddress(), signer)
|
return getContract(holderPool, getHolderPoolAddress(), signer)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ import FlexCom from './FlexCom'
|
||||||
|
|
||||||
interface DetailProps {
|
interface DetailProps {
|
||||||
typeIndex: number
|
typeIndex: number
|
||||||
|
tokenId?: string
|
||||||
|
address?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const DetailFlex = styled(Flex)`
|
const DetailFlex = styled(Flex)`
|
||||||
|
|
@ -20,7 +22,7 @@ const DetailFlex = styled(Flex)`
|
||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
`
|
`
|
||||||
|
|
||||||
const AssetsInfo: React.FC<DetailProps> = ({ typeIndex }) => {
|
const AssetsInfo: React.FC<DetailProps> = ({ typeIndex, tokenId, address }) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const [link, setLink] = useState('')
|
const [link, setLink] = useState('')
|
||||||
|
|
||||||
|
|
@ -34,13 +36,13 @@ const AssetsInfo: React.FC<DetailProps> = ({ typeIndex }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DetailFlex>
|
<DetailFlex>
|
||||||
{typeIndex !== 0 && <FlexCom name={t('owner')} value="钱包地址" />}
|
{typeIndex !== 0 && <FlexCom name={t('owner')} value={address} />}
|
||||||
<FlexCom
|
<FlexCom
|
||||||
name={t('Contract address')}
|
name={t('Contract address')}
|
||||||
typeLink={`https://bscscan.com/token/${link}`}
|
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 agreement')} value="ERC721" />
|
||||||
<FlexCom name={t('Assets and chain')} value="BSC" />
|
<FlexCom name={t('Assets and chain')} value="BSC" />
|
||||||
</DetailFlex>
|
</DetailFlex>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,24 @@
|
||||||
import React, { useState } from 'react'
|
import React, { useState, useEffect } from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
import Pagination from '@mui/material/Pagination'
|
||||||
import { Text, Button, Image, Flex } from '@pancakeswap/uikit'
|
import { Text, Button, Image, Flex } from '@pancakeswap/uikit'
|
||||||
import { useTranslation } from 'contexts/Localization'
|
import { useTranslation } from 'contexts/Localization'
|
||||||
|
import { tradeRecordPage } from 'services/bazaar'
|
||||||
|
import Empty from 'components/Empty'
|
||||||
|
|
||||||
interface AuctionRecordProps {
|
interface AuctionRecordProps {
|
||||||
onDismiss?: () => void
|
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`
|
const FlexMain = styled.div`
|
||||||
|
|
@ -70,7 +84,10 @@ const ThemedItem = styled.div`
|
||||||
color: #666666;
|
color: #666666;
|
||||||
border-top: 1px solid #e3e3e3;
|
border-top: 1px solid #e3e3e3;
|
||||||
`
|
`
|
||||||
const TableBody = styled.div``
|
const TableBody = styled.div`
|
||||||
|
height: 350px;
|
||||||
|
overflow-y: auto;
|
||||||
|
`
|
||||||
const TrFlex = styled(Flex)`
|
const TrFlex = styled(Flex)`
|
||||||
/* height: 80px; */
|
/* height: 80px; */
|
||||||
padding: 10px 0;
|
padding: 10px 0;
|
||||||
|
|
@ -113,15 +130,18 @@ const HashText = styled(Text)`
|
||||||
border-bottom: 1px solid #1fc7d4;
|
border-bottom: 1px solid #1fc7d4;
|
||||||
`
|
`
|
||||||
|
|
||||||
const AuctionRecord: React.FC<AuctionRecordProps> = ({ onDismiss }) => {
|
const AuctionRecord: React.FC<AuctionRecordProps> = ({ onDismiss, recordDetail }) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
const [count, setCount] = useState(undefined)
|
||||||
|
|
||||||
const typeList = [
|
const typeList = [
|
||||||
{ label: t('All transactions'), value: '1' },
|
{ label: t('All transactions'), value: '' },
|
||||||
{ label: t('I released'), value: '2' },
|
{ label: t('I released'), value: 'PUBLISH' },
|
||||||
{ label: t('I participate in'), value: '3' },
|
{ label: t('I participate in'), value: 'PARTICIPATE' },
|
||||||
]
|
]
|
||||||
const [typeIndex, setTypeIndex] = useState(0)
|
const [typeIndex, setTypeIndex] = useState(0)
|
||||||
|
const [pageNum, setPage] = useState(1)
|
||||||
|
const [list, setList] = useState<ListProps[]>()
|
||||||
|
|
||||||
const ThemedList = [
|
const ThemedList = [
|
||||||
t('NFT name'),
|
t('NFT name'),
|
||||||
|
|
@ -131,18 +151,48 @@ const AuctionRecord: React.FC<AuctionRecordProps> = ({ onDismiss }) => {
|
||||||
t('state'),
|
t('state'),
|
||||||
t('operation'),
|
t('operation'),
|
||||||
]
|
]
|
||||||
|
const statusTxt = {
|
||||||
|
PENDING: t('They are in'),
|
||||||
|
CANCEL: t('Canceled'),
|
||||||
|
STREAMING: t('abortive auction'),
|
||||||
|
SUCCESS: t('success'),
|
||||||
|
end: t('finished'),
|
||||||
|
}
|
||||||
|
|
||||||
const list = [
|
const getList = async () => {
|
||||||
{
|
setList([])
|
||||||
name: 'Cat goddess Emerald ',
|
const res = await tradeRecordPage({
|
||||||
icon: '',
|
page: pageNum,
|
||||||
price: '1',
|
size: 4,
|
||||||
newPrice: '2',
|
type: 'AUCTION',
|
||||||
time: '2022-02-02',
|
relationType: typeList[typeIndex].value,
|
||||||
status: '已售卖',
|
})
|
||||||
id: '1',
|
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 (
|
return (
|
||||||
<FlexMain>
|
<FlexMain>
|
||||||
|
|
@ -154,7 +204,7 @@ const AuctionRecord: React.FC<AuctionRecordProps> = ({ onDismiss }) => {
|
||||||
<TypeItem
|
<TypeItem
|
||||||
key={item.value}
|
key={item.value}
|
||||||
className={index === typeIndex ? 'active' : ''}
|
className={index === typeIndex ? 'active' : ''}
|
||||||
onClick={() => setTypeIndex(index)}
|
onClick={() => changeType(index)}
|
||||||
>
|
>
|
||||||
{item.label}
|
{item.label}
|
||||||
</TypeItem>
|
</TypeItem>
|
||||||
|
|
@ -168,24 +218,32 @@ const AuctionRecord: React.FC<AuctionRecordProps> = ({ onDismiss }) => {
|
||||||
})}
|
})}
|
||||||
</TableThemed>
|
</TableThemed>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{list.map((item) => {
|
{list?.length > 0 &&
|
||||||
|
list.map((item) => {
|
||||||
return (
|
return (
|
||||||
<TrFlex key={item.id}>
|
<TrFlex key={item.id}>
|
||||||
<TdFlex>
|
<TdFlex>
|
||||||
<TdImage src="/images/nft/epic-icon.svg" width={24} height={40} />
|
{/* <TdImage src="/images/nft/epic-icon.svg" width={24} height={40} /> */}
|
||||||
{item.name}
|
{item.goodsName}
|
||||||
</TdFlex>
|
</TdFlex>
|
||||||
<TdFlex>{item.price}</TdFlex>
|
<TdFlex>{item.price}</TdFlex>
|
||||||
<TdFlex>{item.newPrice}</TdFlex>
|
<TdFlex>{item.lastPrice}</TdFlex>
|
||||||
<TdFlex>{item.time}</TdFlex>
|
<TdFlex>{item.updatedAt}</TdFlex>
|
||||||
<TdFlex>{item.status}</TdFlex>
|
<TdFlex>{statusTxt[item.status]}</TdFlex>
|
||||||
<TdBtnFlex>
|
<TdBtnFlex>
|
||||||
<DetailButton>{t('Detail')}</DetailButton>
|
<DetailButton onClick={() => lookDetail(item)}>{t('Detail')}</DetailButton>
|
||||||
<HashText>{t('deal Hash')}</HashText>
|
<HashText onClick={() => goHash(item)}>{t('deal Hash')}</HashText>
|
||||||
</TdBtnFlex>
|
</TdBtnFlex>
|
||||||
</TrFlex>
|
</TrFlex>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
{list?.length === 0 ? (
|
||||||
|
<Empty />
|
||||||
|
) : (
|
||||||
|
<Flex justifyContent="center" padding={10}>
|
||||||
|
<Pagination count={count} onChange={pageChange} page={pageNum} />
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</>
|
</>
|
||||||
</FlexMain>
|
</FlexMain>
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,10 @@ import styled from 'styled-components'
|
||||||
import { Text, Button, Image, Flex } from '@pancakeswap/uikit'
|
import { Text, Button, Image, Flex } from '@pancakeswap/uikit'
|
||||||
import { useTranslation } from 'contexts/Localization'
|
import { useTranslation } from 'contexts/Localization'
|
||||||
|
|
||||||
|
interface AuctionRuleProps {
|
||||||
|
typeIndex?: number
|
||||||
|
}
|
||||||
|
|
||||||
const FlexMain = styled.div`
|
const FlexMain = styled.div`
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
padding: 34px 30px;
|
padding: 34px 30px;
|
||||||
|
|
@ -22,11 +26,24 @@ const DetailText = styled(Text)`
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
`
|
`
|
||||||
|
|
||||||
const AuctionRule: React.FC = () => {
|
const AuctionRule: React.FC<AuctionRuleProps> = ({ typeIndex }) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FlexMain>
|
<FlexMain>
|
||||||
|
{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>
|
<HeaderText>{t('Auction rule')}</HeaderText>
|
||||||
<DetailText>
|
<DetailText>
|
||||||
{t('1. When the countdown is less than 1 hour, the countdown time will be increased by 1 hour each time')}
|
{t('1. When the countdown is less than 1 hour, the countdown time will be increased by 1 hour each time')}
|
||||||
|
|
@ -45,6 +62,8 @@ const AuctionRule: React.FC = () => {
|
||||||
<DetailText>
|
<DetailText>
|
||||||
{t('5. NFT shall not be traded or transferred after the auction is issued by the issuer')}
|
{t('5. NFT shall not be traded or transferred after the auction is issued by the issuer')}
|
||||||
</DetailText>
|
</DetailText>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</FlexMain>
|
</FlexMain>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,39 @@
|
||||||
import React, { useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
import Tooltip from '@mui/material/Tooltip'
|
||||||
import { Text, Flex } from '@pancakeswap/uikit'
|
import { Text, Flex } from '@pancakeswap/uikit'
|
||||||
import { useTranslation } from 'contexts/Localization'
|
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`
|
const FlexMain = styled.div`
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
height: 405px;
|
/* height: 405px; */
|
||||||
|
padding-bottom: 20px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
color: #999999;
|
color: #999999;
|
||||||
|
|
@ -45,33 +73,51 @@ const TrFlex = styled(Flex)`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
/* flex-wrap: wrap; */
|
/* flex-wrap: wrap; */
|
||||||
`
|
`
|
||||||
const TdFlex = styled(Flex)`
|
const TdFlex = styled.div`
|
||||||
align-items: center;
|
width: 60%;
|
||||||
justify-content: center;
|
padding: 0 20px;
|
||||||
width: 100%;
|
text-align: center;
|
||||||
color: #666666;
|
color: #666666;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
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 { 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 ThemedList = [t('The wallet address'), 'HASH', t('auction price'), t('The auction time'), t('state')]
|
||||||
|
const statusTxt = {
|
||||||
const list = [
|
PENDING: t('Cancel the deity'),
|
||||||
{
|
CANCEL: t('Canceled'),
|
||||||
name: 'Cat goddess Emerald ',
|
STREAMING: t('abortive auction'),
|
||||||
icon: '',
|
SUCCESS: t('success'),
|
||||||
price: '1',
|
}
|
||||||
newPrice: '2',
|
|
||||||
time: '2022-02-02',
|
|
||||||
status: '已售卖',
|
|
||||||
id: '1',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FlexMain>
|
<FlexMain>
|
||||||
|
|
@ -83,17 +129,41 @@ const AuctionTable: React.FC = () => {
|
||||||
})}
|
})}
|
||||||
</TableThemed>
|
</TableThemed>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{list.map((item) => {
|
{list?.length > 0 ? (
|
||||||
|
list?.map((item, index) => {
|
||||||
return (
|
return (
|
||||||
<TrFlex key={item.id}>
|
<TrFlex key={item.id}>
|
||||||
<TdFlex>{item.name}</TdFlex>
|
<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.price}</TdFlex>
|
||||||
<TdFlex>{item.newPrice}</TdFlex>
|
<TdFlex>{item.updatedAt}</TdFlex>
|
||||||
<TdFlex>{item.time}</TdFlex>
|
<TdFlex>
|
||||||
<TdFlex>{item.status}</TdFlex>
|
{time < new Date().getTime() && index === 0
|
||||||
|
? t('traded')
|
||||||
|
: time > new Date().getTime() && index === 0
|
||||||
|
? '-'
|
||||||
|
: t('out')}
|
||||||
|
</TdFlex>
|
||||||
</TrFlex>
|
</TrFlex>
|
||||||
)
|
)
|
||||||
})}
|
})
|
||||||
|
) : (
|
||||||
|
<Empty />
|
||||||
|
)}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</>
|
</>
|
||||||
</FlexMain>
|
</FlexMain>
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,12 @@ import useToast from 'hooks/useToast'
|
||||||
import { ListProps } from 'types/bazaar'
|
import { ListProps } from 'types/bazaar'
|
||||||
|
|
||||||
import Empty from 'components/Empty'
|
import Empty from 'components/Empty'
|
||||||
import { useGetOfficialPage } from '../hooks'
|
import { useGetOfficialPage, useGetTradePage } from '../hooks'
|
||||||
import HeaderOperation from './HeaderOperation'
|
import HeaderOperation from './HeaderOperation'
|
||||||
import ContentShop from './ContentShop'
|
import ContentShop from './ContentShop'
|
||||||
import Transaction from './Transaction'
|
import Transaction from './Transaction'
|
||||||
import ShopDetail from './ShopDetail'
|
import ShopDetail from './ShopDetail'
|
||||||
|
import ShopDetailBazaar from './ShopDetailBazaar'
|
||||||
|
|
||||||
const HeaderFlex = styled(Flex)`
|
const HeaderFlex = styled(Flex)`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
@ -138,6 +139,7 @@ const Content: React.FC = () => {
|
||||||
const { toastSuccess, toastError } = useToast()
|
const { toastSuccess, toastError } = useToast()
|
||||||
const [detail, setDetail] = useState<ListProps>({})
|
const [detail, setDetail] = useState<ListProps>({})
|
||||||
const [detailVisible, setDetailVisible] = useState(false)
|
const [detailVisible, setDetailVisible] = useState(false)
|
||||||
|
const [ids, setId] = useState('')
|
||||||
const typeList = [
|
const typeList = [
|
||||||
{ label: t('official market'), type: 1 },
|
{ label: t('official market'), type: 1 },
|
||||||
{ label: t('bazaar'), type: 2 },
|
{ label: t('bazaar'), type: 2 },
|
||||||
|
|
@ -145,10 +147,10 @@ const Content: React.FC = () => {
|
||||||
]
|
]
|
||||||
const [typeIndex, setTypeIndex] = useState(0)
|
const [typeIndex, setTypeIndex] = useState(0)
|
||||||
const auctionList = [
|
const auctionList = [
|
||||||
{ label: t('In the auction'), value: '0' },
|
{ label: t('In the auction'), value: 'PENDING' },
|
||||||
{ label: t('traded'), value: '1' },
|
{ 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 = [
|
const newPrice = [
|
||||||
// { label: t('The latest offer'), value: '0' },
|
// { label: t('The latest offer'), value: '0' },
|
||||||
// { label: t('latest release'), value: '1' },
|
// { label: t('latest release'), value: '1' },
|
||||||
|
|
@ -175,11 +177,35 @@ const Content: React.FC = () => {
|
||||||
const [count, setCount] = useState(undefined)
|
const [count, setCount] = useState(undefined)
|
||||||
|
|
||||||
const getOfficialPage = useGetOfficialPage()
|
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 = {
|
const params = {
|
||||||
page: pageNum,
|
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,
|
name: searchTitle,
|
||||||
grade: searchGrade,
|
grade: searchGrade,
|
||||||
}
|
}
|
||||||
|
|
@ -197,6 +223,7 @@ const Content: React.FC = () => {
|
||||||
setList(arr)
|
setList(arr)
|
||||||
if (location.search) {
|
if (location.search) {
|
||||||
const locationData = qs.parse(location.search.slice(1))
|
const locationData = qs.parse(location.search.slice(1))
|
||||||
|
if (!locationData?.type) {
|
||||||
arr.forEach((item) => {
|
arr.forEach((item) => {
|
||||||
if (item.id === locationData.id) {
|
if (item.id === locationData.id) {
|
||||||
setDetail(item)
|
setDetail(item)
|
||||||
|
|
@ -204,12 +231,34 @@ const Content: React.FC = () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
setCount(getTotalPageNum(data.total, data.size))
|
setCount(getTotalPageNum(data.total, data.size))
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
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()
|
getData()
|
||||||
}, [pageNum, searchGrade])
|
break
|
||||||
|
case 1:
|
||||||
|
getTradeList('NORMAL')
|
||||||
|
break
|
||||||
|
case 2:
|
||||||
|
getTradeList('AUCTION')
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
getData()
|
||||||
|
}
|
||||||
|
}, [pageNum, searchGrade, typeIndex, detailVisible, auctionSelect])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setPriceSelect({ label: t('Prices go from low to high'), value: '3' })
|
setPriceSelect({ label: t('Prices go from low to high'), value: '3' })
|
||||||
|
|
@ -221,9 +270,12 @@ const Content: React.FC = () => {
|
||||||
}
|
}
|
||||||
const searchList = () => {
|
const searchList = () => {
|
||||||
setPage(1)
|
setPage(1)
|
||||||
getData()
|
// getData()
|
||||||
}
|
}
|
||||||
const showDetail = (val) => {
|
const showDetail = (val) => {
|
||||||
|
if (typeIndex !== 0) {
|
||||||
|
setId(val.id)
|
||||||
|
}
|
||||||
setDetail(val)
|
setDetail(val)
|
||||||
setDetailVisible(!detailVisible)
|
setDetailVisible(!detailVisible)
|
||||||
}
|
}
|
||||||
|
|
@ -240,14 +292,10 @@ const Content: React.FC = () => {
|
||||||
setGrade(grade)
|
setGrade(grade)
|
||||||
setPage(1)
|
setPage(1)
|
||||||
}
|
}
|
||||||
const changePage = (index) => {
|
|
||||||
if (index !== 0) {
|
|
||||||
toastError(t('This page is not currently open'))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
setTypeIndex(index)
|
|
||||||
}
|
|
||||||
const lookDetail = (val) => {
|
const lookDetail = (val) => {
|
||||||
|
if (typeIndex !== 0) {
|
||||||
|
setId(val.id)
|
||||||
|
}
|
||||||
setDetail(val)
|
setDetail(val)
|
||||||
setDetailVisible(true)
|
setDetailVisible(true)
|
||||||
// detail
|
// detail
|
||||||
|
|
@ -260,7 +308,8 @@ const Content: React.FC = () => {
|
||||||
|
|
||||||
return (
|
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 && (
|
{!detailVisible && (
|
||||||
<>
|
<>
|
||||||
|
|
@ -297,7 +346,7 @@ const Content: React.FC = () => {
|
||||||
})}
|
})}
|
||||||
</StatusFlexContent>
|
</StatusFlexContent>
|
||||||
<Flex>
|
<Flex>
|
||||||
{typeIndex !== 0 && (
|
{typeIndex === 2 && (
|
||||||
<SelectMain>
|
<SelectMain>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
position="bottom"
|
position="bottom"
|
||||||
|
|
@ -318,7 +367,7 @@ const Content: React.FC = () => {
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</SelectMain>
|
</SelectMain>
|
||||||
)}
|
)}
|
||||||
{typeIndex !== 0 && (
|
{/* {typeIndex !== 0 && (
|
||||||
<SelectMain>
|
<SelectMain>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
position="bottom"
|
position="bottom"
|
||||||
|
|
@ -338,7 +387,7 @@ const Content: React.FC = () => {
|
||||||
})}
|
})}
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</SelectMain>
|
</SelectMain>
|
||||||
)}
|
)} */}
|
||||||
</Flex>
|
</Flex>
|
||||||
</StatusFlex>
|
</StatusFlex>
|
||||||
<SearchDiv>
|
<SearchDiv>
|
||||||
|
|
@ -349,7 +398,7 @@ const Content: React.FC = () => {
|
||||||
</SearchBtn>
|
</SearchBtn>
|
||||||
</InputMain>
|
</InputMain>
|
||||||
</SearchDiv>
|
</SearchDiv>
|
||||||
<ContentShop list={list} getDetail={(v) => showDetail(v)} />
|
<ContentShop list={list} typeIndex={typeIndex} getDetail={(v) => showDetail(v)} />
|
||||||
{list.length > 0 && (
|
{list.length > 0 && (
|
||||||
<Flex justifyContent="center" padding={10}>
|
<Flex justifyContent="center" padding={10}>
|
||||||
<Pagination count={count} onChange={pageChange} page={pageNum} />
|
<Pagination count={count} onChange={pageChange} page={pageNum} />
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,11 @@ import useRefresh from 'hooks/useRefresh'
|
||||||
import { TOKEN_SYMBOL } from 'config/index'
|
import { TOKEN_SYMBOL } from 'config/index'
|
||||||
|
|
||||||
import ShopList from './ShopList'
|
import ShopList from './ShopList'
|
||||||
|
import ShopListBazaar from './ShopListBazaar'
|
||||||
|
|
||||||
interface ContentShop {
|
interface ContentShop {
|
||||||
list?: ListProps[]
|
list?: ListProps[]
|
||||||
|
typeIndex?: number
|
||||||
getDetail?: (v) => void
|
getDetail?: (v) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,7 +68,7 @@ const FooterValue = styled(Flex)`
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
`
|
`
|
||||||
|
|
||||||
const ContentShop: React.FC<ContentShop> = ({ list, getDetail }) => {
|
const ContentShop: React.FC<ContentShop> = ({ list, getDetail, typeIndex }) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const account = useAccount()
|
const account = useAccount()
|
||||||
const { toastSuccess, toastError } = useToast()
|
const { toastSuccess, toastError } = useToast()
|
||||||
|
|
@ -80,6 +82,8 @@ const ContentShop: React.FC<ContentShop> = ({ list, getDetail }) => {
|
||||||
{list.map((item) => {
|
{list.map((item) => {
|
||||||
return (
|
return (
|
||||||
<ShopFlex key={item.id} onClick={() => showDetail(item)}>
|
<ShopFlex key={item.id} onClick={() => showDetail(item)}>
|
||||||
|
{typeIndex === 0 && (
|
||||||
|
<>
|
||||||
<ShopList
|
<ShopList
|
||||||
item={item}
|
item={item}
|
||||||
width={278}
|
width={278}
|
||||||
|
|
@ -92,7 +96,7 @@ const ContentShop: React.FC<ContentShop> = ({ list, getDetail }) => {
|
||||||
<ShopFooter>
|
<ShopFooter>
|
||||||
<FooterLabel>{t('trading value')}</FooterLabel>
|
<FooterLabel>{t('trading value')}</FooterLabel>
|
||||||
<FooterValue>
|
<FooterValue>
|
||||||
{item.priceList.map((childItem, index) => {
|
{item?.priceList?.map((childItem, index) => {
|
||||||
return (
|
return (
|
||||||
<Flex alignItems="center" key={childItem.label}>
|
<Flex alignItems="center" key={childItem.label}>
|
||||||
{/* <>{formatTimeNumber(childItem.value)}</> */}
|
{/* <>{formatTimeNumber(childItem.value)}</> */}
|
||||||
|
|
@ -104,6 +108,28 @@ const ContentShop: React.FC<ContentShop> = ({ list, getDetail }) => {
|
||||||
})}
|
})}
|
||||||
</FooterValue>
|
</FooterValue>
|
||||||
</ShopFooter>
|
</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>
|
</ShopFlex>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { useTranslation } from 'contexts/Localization'
|
||||||
import { Flex, Button, Text, Input, Image, useModal, Dropdown } from '@pancakeswap/uikit'
|
import { Flex, Button, Text, Input, Image, useModal, Dropdown } from '@pancakeswap/uikit'
|
||||||
import { useAccount } from 'state/userInfo/hooks'
|
import { useAccount } from 'state/userInfo/hooks'
|
||||||
import useRefresh from 'hooks/useRefresh'
|
import useRefresh from 'hooks/useRefresh'
|
||||||
|
import UnlockButton from 'components/UnlockButton'
|
||||||
|
|
||||||
import TransactionRecord from './TransactionRecord'
|
import TransactionRecord from './TransactionRecord'
|
||||||
import AuctionRecord from './AuctionRecord'
|
import AuctionRecord from './AuctionRecord'
|
||||||
|
|
@ -34,24 +35,35 @@ const HeaderButton = styled(Button)`
|
||||||
margin-right: 0px;
|
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 HeaderOperation: React.FC<HeaderOperationProps> = ({ activeIndex, getDetail }) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
const account = useAccount()
|
||||||
|
|
||||||
const [onTransactionRecord] = useModal(
|
const [onTransactionRecord] = useModal(
|
||||||
<TransactionRecord activeIndex={activeIndex} recordDetail={(v) => getDetail(v)} />,
|
<TransactionRecord activeIndex={activeIndex} recordDetail={(v) => getDetail(v)} />,
|
||||||
)
|
)
|
||||||
const [onAuctionRecord] = useModal(<AuctionRecord />)
|
const [onAuctionRecord] = useModal(<AuctionRecord recordDetail={(v) => getDetail(v)} />)
|
||||||
const [onSellModal] = useModal(<SellModal />)
|
const [onSellModal] = useModal(<SellModal />)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex alignContent="center">
|
<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={onAuctionRecord}>{t('Auctions a record')}</HeaderButton>
|
||||||
) : (
|
) : (
|
||||||
<HeaderButton onClick={onTransactionRecord}>{t('transaction record')}</HeaderButton>
|
account && <HeaderButton onClick={onTransactionRecord}>{t('transaction record')}</HeaderButton>
|
||||||
)}
|
)}
|
||||||
</Flex>
|
</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 styled from 'styled-components'
|
||||||
import { Text, Button, Image, Input, Flex, Dropdown } from '@pancakeswap/uikit'
|
import { Text, Button, Image, Input, Flex, Dropdown } from '@pancakeswap/uikit'
|
||||||
import { useTranslation } from 'contexts/Localization'
|
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 ShopList from './ShopList'
|
||||||
import ShopModal from './ShopModal'
|
import ShopModal from './ShopModal'
|
||||||
|
|
||||||
interface sellModalProps {
|
interface sellModalProps {
|
||||||
onDismiss?: () => void
|
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`
|
const FlexMain = styled.div`
|
||||||
|
|
@ -70,8 +100,10 @@ const SellingWayFlex = styled(Flex)`
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
const WayFlex = styled(Flex)`
|
const WayFlex = styled(Flex)`
|
||||||
width: 400px;
|
width: 100%;
|
||||||
flex-direction: column;
|
justify-content: space-between;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
/* flex-direction: column; */
|
||||||
`
|
`
|
||||||
const FlexOption = styled(Flex)`
|
const FlexOption = styled(Flex)`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
@ -88,7 +120,6 @@ const FlexOption = styled(Flex)`
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
const SellInput = styled(Input)`
|
const SellInput = styled(Input)`
|
||||||
margin-top: 20px;
|
|
||||||
width: 400px;
|
width: 400px;
|
||||||
height: 35px;
|
height: 35px;
|
||||||
background: #eeeaf4;
|
background: #eeeaf4;
|
||||||
|
|
@ -102,78 +133,6 @@ const SellInput = styled(Input)`
|
||||||
width: 400px;
|
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)`
|
const Shop = styled(Flex)`
|
||||||
/* min-height: 366px; */
|
/* min-height: 366px; */
|
||||||
padding: 30px 0;
|
padding: 30px 0;
|
||||||
|
|
@ -189,12 +148,6 @@ const AddNftButton = styled(Button)`
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
`
|
`
|
||||||
const PriceImage = styled(Image)`
|
|
||||||
margin: 0 10px;
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
cursor: pointer;
|
|
||||||
`
|
|
||||||
const ShopFlex = styled(Flex)`
|
const ShopFlex = styled(Flex)`
|
||||||
width: 278px;
|
width: 278px;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
@ -234,44 +187,121 @@ const SelectShopModal = styled(Flex)`
|
||||||
z-index: 999;
|
z-index: 999;
|
||||||
/* background-color: #7a6eaa; */
|
/* 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 { t } = useTranslation()
|
||||||
const [tradingOnList, setTradingOnList] = useState([{ price: '', value: 'HCC', id: 1 }])
|
const history = useHistory()
|
||||||
const [sellingWay, setSellingWay] = useState(undefined)
|
const { fastRefresh } = useRefresh()
|
||||||
const [coin, setCoin] = useState({ label: 'HCC', value: 'HCC' })
|
const [isApprovedFor, setIsApprovedFor] = useState(false)
|
||||||
const [shopData, setShopData] = useState({ label: 'Cat goddess Emerald ', type: 1, id: 1 })
|
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 [showModal, setShowModal] = useState(false)
|
||||||
|
const [txId, setTxId] = useState()
|
||||||
const coinList = [
|
const [loading, setLoading] = useState(false)
|
||||||
{ label: 'HCC', value: 'HCC' },
|
const [createOrderId, setCreateOrderId] = useState('')
|
||||||
{ label: 'USDT', value: 'USDT' },
|
const [agreementLoading, setAgreementLoading] = useState(false)
|
||||||
]
|
|
||||||
|
|
||||||
const SellingWayList = [
|
const SellingWayList = [
|
||||||
{ label: t('Auction'), value: '0' },
|
|
||||||
{ label: t('fixed price'), value: '1' },
|
{ 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 = () => {
|
const onSelectNft = () => {
|
||||||
setShowModal(!showModal)
|
setShowModal(!showModal)
|
||||||
}
|
}
|
||||||
const close = () => {
|
const close = () => {
|
||||||
setShowModal(false)
|
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 (
|
return (
|
||||||
<FlexMain>
|
<FlexMain>
|
||||||
|
|
@ -282,7 +312,7 @@ const SellModal: React.FC<sellModalProps> = ({ onDismiss }) => {
|
||||||
<Dropdown
|
<Dropdown
|
||||||
position="bottom"
|
position="bottom"
|
||||||
target={
|
target={
|
||||||
<SellingWayFlex>
|
<SellingWayFlex style={{ marginBottom: '20px' }}>
|
||||||
{sellingWay ? sellingWay.label : t('Selling way')}
|
{sellingWay ? sellingWay.label : t('Selling way')}
|
||||||
<Image src="/images/nft/bottom-arrows.svg" width={12} height={7} />
|
<Image src="/images/nft/bottom-arrows.svg" width={12} height={7} />
|
||||||
</SellingWayFlex>
|
</SellingWayFlex>
|
||||||
|
|
@ -296,58 +326,53 @@ const SellModal: React.FC<sellModalProps> = ({ onDismiss }) => {
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</Dropdown>
|
</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>
|
</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>
|
</SelectFlex>
|
||||||
<Shop>
|
<Shop>
|
||||||
{/* <AddNftButton>{t('add NFT)}</AddNftButton> */}
|
{/* isApprovedFor */}
|
||||||
|
{!shopData?.info?.id && <AddNftButton onClick={onSelectNft}>{t('add NFT')}</AddNftButton>}
|
||||||
|
{shopData?.info?.id && (
|
||||||
<ShopFlex>
|
<ShopFlex>
|
||||||
<ShopList item={shopData} width={278} height={280} borderRadius="20px 20px 0 0" />
|
<ShopList
|
||||||
<ShopName>{shopData.label}</ShopName>
|
item={shopData}
|
||||||
|
img={shopData?.info?.coverResource?.url}
|
||||||
|
width={278}
|
||||||
|
height={280}
|
||||||
|
borderRadius="20px 20px 0 0"
|
||||||
|
/>
|
||||||
|
<ShopName>{shopData?.info?.name}</ShopName>
|
||||||
</ShopFlex>
|
</ShopFlex>
|
||||||
<ShopButton>{t('Selling immediately')}</ShopButton>
|
)}
|
||||||
<ShopButton onClick={onSelectNft}>{t('reselect NFT')}</ShopButton>
|
{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>
|
</Shop>
|
||||||
{showModal && (
|
{showModal && (
|
||||||
<SelectShopModal>
|
<SelectShopModal>
|
||||||
<ShopModal close={close} />
|
<ShopModal close={close} add={(v) => getShopDetail(v)} />
|
||||||
</SelectShopModal>
|
</SelectShopModal>
|
||||||
)}
|
)}
|
||||||
</FlexMain>
|
</FlexMain>
|
||||||
|
|
|
||||||
|
|
@ -194,13 +194,14 @@ const ShopDetail: React.FC<DetailProps> = ({ close, detail, typeIndex }) => {
|
||||||
</DetailHeaderFlex>
|
</DetailHeaderFlex>
|
||||||
{typeIndex !== 0 && (
|
{typeIndex !== 0 && (
|
||||||
<FlexCom
|
<FlexCom
|
||||||
name={t('Auction countdown')}
|
name={t('Auction remaining time')}
|
||||||
value="10:57:55:79"
|
value="10:57:55:79"
|
||||||
size="18px"
|
size="18px"
|
||||||
rightSize="30px"
|
rightSize="30px"
|
||||||
textColor="#666666"
|
textColor="#666666"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
{!detail.record && (
|
||||||
<FlexCom
|
<FlexCom
|
||||||
name={t('present price%price%', { price: '' })}
|
name={t('present price%price%', { price: '' })}
|
||||||
value={price}
|
value={price}
|
||||||
|
|
@ -208,8 +209,17 @@ const ShopDetail: React.FC<DetailProps> = ({ close, detail, typeIndex }) => {
|
||||||
rightSize="30px"
|
rightSize="30px"
|
||||||
textColor="#1FC7D4"
|
textColor="#1FC7D4"
|
||||||
/>
|
/>
|
||||||
{detail.record ? (
|
)}
|
||||||
''
|
{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 ? (
|
) : typeIndex === 0 ? (
|
||||||
!account ? (
|
!account ? (
|
||||||
<UnlockButtonDiv />
|
<UnlockButtonDiv />
|
||||||
|
|
@ -218,7 +228,7 @@ const ShopDetail: React.FC<DetailProps> = ({ close, detail, typeIndex }) => {
|
||||||
)
|
)
|
||||||
) : (
|
) : (
|
||||||
<PriceButton>{t('Fixed markup (%price% premium)', { price: '10%' })}</PriceButton>
|
<PriceButton>{t('Fixed markup (%price% premium)', { price: '10%' })}</PriceButton>
|
||||||
)}
|
)} */}
|
||||||
</DetailFlexInfo>
|
</DetailFlexInfo>
|
||||||
<AssetsInfo typeIndex={typeIndex} />
|
<AssetsInfo typeIndex={typeIndex} />
|
||||||
</Detail>
|
</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 React, { useState, useEffect } from 'react'
|
||||||
|
import Pagination from '@mui/material/Pagination'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import { useTranslation } from 'contexts/Localization'
|
import { useTranslation } from 'contexts/Localization'
|
||||||
import { Flex, Text, Button } from '@pancakeswap/uikit'
|
import { Flex, Text, Button } from '@pancakeswap/uikit'
|
||||||
|
import Empty from 'components/Empty'
|
||||||
|
import { useGetSelfPage } from '../../NftBox/hooks'
|
||||||
import ShopList from './ShopList'
|
import ShopList from './ShopList'
|
||||||
|
|
||||||
interface ShopProp {
|
interface ShopProp {
|
||||||
|
|
@ -9,8 +12,31 @@ interface ShopProp {
|
||||||
value?: string | number
|
value?: string | number
|
||||||
onDismiss?: () => void
|
onDismiss?: () => void
|
||||||
close: () => 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`
|
const Main = styled.div`
|
||||||
width: 60%;
|
width: 60%;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
|
|
@ -63,6 +89,7 @@ const SelectFlex = styled(Flex)`
|
||||||
width: 30px;
|
width: 30px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.16);
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
z-index: 9;
|
z-index: 9;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
@ -100,9 +127,35 @@ const OutButton = styled(Button)`
|
||||||
margin-top: 20px;
|
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 { 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 pitchOn = (index) => {
|
||||||
const arr = []
|
const arr = []
|
||||||
|
|
@ -116,32 +169,44 @@ const ShopModal: React.FC<ShopProp> = ({ name, value, onDismiss, close }) => {
|
||||||
const onClose = () => {
|
const onClose = () => {
|
||||||
close()
|
close()
|
||||||
}
|
}
|
||||||
|
// 添加nft
|
||||||
|
const addNft = () => {
|
||||||
|
const info = list.find((item) => item.select)
|
||||||
|
add(info)
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setList([
|
getData()
|
||||||
{ label: 'Cat goddess Emerald ', type: 1, id: 1, select: true },
|
}, [pageNum])
|
||||||
{ 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 },
|
|
||||||
])
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Main>
|
<Main>
|
||||||
<Shop>
|
<Shop>
|
||||||
{list.map((item, index) => {
|
{list?.length > 0 &&
|
||||||
|
list?.map((item, index) => {
|
||||||
return (
|
return (
|
||||||
<ShopFlex key={item.id} onClick={() => pitchOn(index)} className={item.select ? 'active' : ''}>
|
<ShopFlex key={item?.id} onClick={() => pitchOn(index)} className={item?.select ? 'active' : ''}>
|
||||||
<SelectFlex>{item.select && <SelectDiv />}</SelectFlex>
|
<SelectFlex>{item?.select && <SelectDiv />}</SelectFlex>
|
||||||
<ShopList item={item} width={278} height={280} borderRadius="20px 20px 0 0" />
|
<ShopList
|
||||||
<ShopName>{item.label}</ShopName>
|
item={item}
|
||||||
|
img={item?.info?.coverResource?.url}
|
||||||
|
width={278}
|
||||||
|
height={280}
|
||||||
|
borderRadius="20px 20px 0 0"
|
||||||
|
/>
|
||||||
|
<ShopName>{item?.info?.name}</ShopName>
|
||||||
</ShopFlex>
|
</ShopFlex>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</Shop>
|
</Shop>
|
||||||
|
{list?.length > 0 && (
|
||||||
|
<Flex justifyContent="center" padding={10}>
|
||||||
|
<Pagination count={count} onChange={pageChange} page={pageNum} />
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
{list?.length === 0 && <Empty />}
|
||||||
<BtnFlex>
|
<BtnFlex>
|
||||||
<AddButton>{t('add NFT')}</AddButton>
|
{list?.length > 0 && <AddButton onClick={addNft}>{t('add NFT')}</AddButton>}
|
||||||
<OutButton onClick={onClose}>{t('Sign out')}</OutButton>
|
<OutButton onClick={onClose}>{t('Sign out')}</OutButton>
|
||||||
</BtnFlex>
|
</BtnFlex>
|
||||||
</Main>
|
</Main>
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import Pagination from '@mui/material/Pagination'
|
||||||
import { Text, Button, Image, Flex } from '@pancakeswap/uikit'
|
import { Text, Button, Image, Flex } from '@pancakeswap/uikit'
|
||||||
import { useTranslation } from 'contexts/Localization'
|
import { useTranslation } from 'contexts/Localization'
|
||||||
import Empty from 'components/Empty'
|
import Empty from 'components/Empty'
|
||||||
|
import { tradeRecordPage } from 'services/bazaar'
|
||||||
import { useGetPurchaseRecord, useGetNftDetail } from '../hooks'
|
import { useGetPurchaseRecord, useGetNftDetail } from '../hooks'
|
||||||
|
|
||||||
interface TransactionRecordProps {
|
interface TransactionRecordProps {
|
||||||
|
|
@ -137,6 +138,37 @@ const TransactionRecord: React.FC<TransactionRecordProps> = ({ onDismiss, active
|
||||||
const [count, setCount] = useState(undefined)
|
const [count, setCount] = useState(undefined)
|
||||||
|
|
||||||
const getPurchaseRecord = useGetPurchaseRecord()
|
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 getList = async () => {
|
||||||
const result = await getPurchaseRecord(pageNum, 10)
|
const result = await getPurchaseRecord(pageNum, 10)
|
||||||
setCount(getTotalPageNum(result.total, result.size))
|
setCount(getTotalPageNum(result.total, result.size))
|
||||||
|
|
@ -154,8 +186,12 @@ const TransactionRecord: React.FC<TransactionRecordProps> = ({ onDismiss, active
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (activeIndex !== 0) {
|
||||||
|
getWayList()
|
||||||
|
} else {
|
||||||
getList()
|
getList()
|
||||||
}, [pageNum])
|
}
|
||||||
|
}, [pageNum, typeIndex])
|
||||||
|
|
||||||
const pageChange = (event, page) => {
|
const pageChange = (event, page) => {
|
||||||
setPage(page)
|
setPage(page)
|
||||||
|
|
@ -169,13 +205,22 @@ const TransactionRecord: React.FC<TransactionRecordProps> = ({ onDismiss, active
|
||||||
}
|
}
|
||||||
const getNftDetail = useGetNftDetail()
|
const getNftDetail = useGetNftDetail()
|
||||||
const lookDetail = async (item) => {
|
const lookDetail = async (item) => {
|
||||||
|
let obj = { record: false, token: '' }
|
||||||
|
if (activeIndex !== 0) {
|
||||||
|
obj = item
|
||||||
|
} else {
|
||||||
const res = await getNftDetail(item.token, { token: item.token })
|
const res = await getNftDetail(item.token, { token: item.token })
|
||||||
const obj = res.info
|
obj = res.info
|
||||||
obj.record = true
|
obj.record = true
|
||||||
|
obj.token = res.token
|
||||||
|
}
|
||||||
recordDetail(obj)
|
recordDetail(obj)
|
||||||
onDismiss()
|
onDismiss()
|
||||||
}
|
}
|
||||||
|
const changeType = (index) => {
|
||||||
|
setTypeIndex(index)
|
||||||
|
setPage(1)
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<FlexMain>
|
<FlexMain>
|
||||||
<CloseImage src="/images/nft/close.svg" width={15} height={15} onClick={onDismiss} />
|
<CloseImage src="/images/nft/close.svg" width={15} height={15} onClick={onDismiss} />
|
||||||
|
|
@ -187,7 +232,7 @@ const TransactionRecord: React.FC<TransactionRecordProps> = ({ onDismiss, active
|
||||||
<TypeItem
|
<TypeItem
|
||||||
key={item.value}
|
key={item.value}
|
||||||
className={index === typeIndex ? 'active' : ''}
|
className={index === typeIndex ? 'active' : ''}
|
||||||
onClick={() => setTypeIndex(index)}
|
onClick={() => changeType(index)}
|
||||||
>
|
>
|
||||||
{item.label}
|
{item.label}
|
||||||
</TypeItem>
|
</TypeItem>
|
||||||
|
|
@ -207,6 +252,7 @@ const TransactionRecord: React.FC<TransactionRecordProps> = ({ onDismiss, active
|
||||||
return (
|
return (
|
||||||
<TrFlex key={item.id}>
|
<TrFlex key={item.id}>
|
||||||
<TdFlex>{item.goodsName}</TdFlex>
|
<TdFlex>{item.goodsName}</TdFlex>
|
||||||
|
{activeIndex === 0 && (
|
||||||
<TdFlex>
|
<TdFlex>
|
||||||
{item.priceList.map((childItem, childIndex) => {
|
{item.priceList.map((childItem, childIndex) => {
|
||||||
return (
|
return (
|
||||||
|
|
@ -218,7 +264,10 @@ const TransactionRecord: React.FC<TransactionRecordProps> = ({ onDismiss, active
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</TdFlex>
|
</TdFlex>
|
||||||
<TdFlex>{dayjs(Number(item.tradeTime)).format('YYYY-MM-DD HH:mm:ss')}</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>
|
<TdFlex>{item.status ? item.status : t('success')}</TdFlex>
|
||||||
<TdBtnFlex>
|
<TdBtnFlex>
|
||||||
<DetailButton onClick={() => lookDetail(item)}>{t('Detail')}</DetailButton>
|
<DetailButton onClick={() => lookDetail(item)}>{t('Detail')}</DetailButton>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,20 @@
|
||||||
import { useCallback } from 'react'
|
import { useCallback } from 'react'
|
||||||
import { useBlindBox } from 'hooks/useContract'
|
import hccMarketplaceABI from 'config/abi/hccMarketplace.json'
|
||||||
import { getAddress, getBlindBoxAddress } from 'utils/addressHelpers'
|
import blindBoxABI from 'config/abi/blindBox.json'
|
||||||
import { getOfficialPage, getOfficialPurchase, getPurchaseRecord, getNftDetail } from 'services/bazaar'
|
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 { 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 = () => {
|
export const useGetOfficialPage = () => {
|
||||||
const data = async (params) => {
|
const data = async (params) => {
|
||||||
|
|
@ -39,6 +51,19 @@ export const useApproveHcc = (tokenContract: Contract) => {
|
||||||
|
|
||||||
return { onApprove: handleApprove }
|
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 = () => {
|
export const useGetPurchaseRecord = () => {
|
||||||
|
|
@ -74,4 +99,212 @@ export const useGetNftDetail = () => {
|
||||||
return data
|
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
|
export default useGetOfficialPage
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ const HeaderStatus: React.FC<HeaderStatusProps> = ({ status, roundDetail }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TimeText>
|
<TimeText>
|
||||||
{/* {status === 'close' && t('Exchange closed')} */}
|
{status === 'close' && t('Exchange closed')}
|
||||||
{status === 'none' && t('Exchange not commenced')}
|
{status === 'none' && t('Exchange not commenced')}
|
||||||
|
|
||||||
{status === 'proceed' && (
|
{status === 'proceed' && (
|
||||||
|
|
|
||||||
|
|
@ -68,8 +68,6 @@ export const useGetRound = () => {
|
||||||
}
|
}
|
||||||
const { id } = data
|
const { id } = data
|
||||||
const idoPurchaseAddress = getIdoPurchaseAddress()
|
const idoPurchaseAddress = getIdoPurchaseAddress()
|
||||||
console.log(idoPurchaseAddress)
|
|
||||||
console.log(id)
|
|
||||||
const calls = [
|
const calls = [
|
||||||
{
|
{
|
||||||
address: idoPurchaseAddress,
|
address: idoPurchaseAddress,
|
||||||
|
|
@ -91,6 +89,7 @@ export const useGetRound = () => {
|
||||||
total: formatDivNumber(item?.total._hex, 18),
|
total: formatDivNumber(item?.total._hex, 18),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
console.log(detail[0])
|
||||||
return detail[0]
|
return detail[0]
|
||||||
}
|
}
|
||||||
return transaction
|
return transaction
|
||||||
|
|
|
||||||
|
|
@ -41,10 +41,17 @@ const Exchange: React.FC = () => {
|
||||||
const getRound = useGetRound()
|
const getRound = useGetRound()
|
||||||
const init = async () => {
|
const init = async () => {
|
||||||
const detail = await getRound()
|
const detail = await getRound()
|
||||||
|
console.log(typeof detail.remaining)
|
||||||
if (!detail || detail.endTime < new Date().getTime()) {
|
if (!detail || detail.endTime < new Date().getTime()) {
|
||||||
setStatus('none')
|
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')
|
setStatus('proceed')
|
||||||
|
} else if (detail.remaining === 0) {
|
||||||
|
setStatus('close')
|
||||||
} else {
|
} else {
|
||||||
setStatus('end')
|
setStatus('end')
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
import React, { useState, useEffect } from 'react'
|
import React, { useState, useEffect } from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import { useTranslation } from 'contexts/Localization'
|
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 { useGetNftDetails } from '../hooks'
|
||||||
import AssetsInfo from './AssetsInfo'
|
import AssetsInfo from './AssetsInfo'
|
||||||
|
import SellModal from '../../Bazaar/components/SellModal'
|
||||||
|
|
||||||
interface DetailProp {
|
interface DetailProp {
|
||||||
token?: string
|
token?: string
|
||||||
|
|
@ -133,7 +134,11 @@ const DetailFlex = styled(Flex)`
|
||||||
const SellButton = styled(Button)`
|
const SellButton = styled(Button)`
|
||||||
height: 60px;
|
height: 60px;
|
||||||
background: linear-gradient(269deg, #1fc8d3 0%, #1fd4b0 100%);
|
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;
|
border-radius: 30px;
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
`
|
`
|
||||||
|
|
@ -156,6 +161,8 @@ const DetailModal: React.FC<DetailProp> = ({ token, onDismiss }) => {
|
||||||
getDetail()
|
getDetail()
|
||||||
}, [token])
|
}, [token])
|
||||||
|
|
||||||
|
const [onSellModal] = useModal(<SellModal detailData={detail} />)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Main title="" onDismiss={onDismiss}>
|
<Main title="" onDismiss={onDismiss}>
|
||||||
<CenterDiv>
|
<CenterDiv>
|
||||||
|
|
@ -171,7 +178,8 @@ const DetailModal: React.FC<DetailProp> = ({ token, onDismiss }) => {
|
||||||
</ShopItem>
|
</ShopItem>
|
||||||
<DetailFlex>
|
<DetailFlex>
|
||||||
<AssetsInfo detail={detail} />
|
<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>
|
</DetailFlex>
|
||||||
</MainFlex>
|
</MainFlex>
|
||||||
</CenterDiv>
|
</CenterDiv>
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@ interface Detail {
|
||||||
info: InfoProps
|
info: InfoProps
|
||||||
token?: string
|
token?: string
|
||||||
updatedAt?: string
|
updatedAt?: string
|
||||||
|
pending?: boolean
|
||||||
}
|
}
|
||||||
interface InfoProps {
|
interface InfoProps {
|
||||||
coverResource?: CoverResourceProps
|
coverResource?: CoverResourceProps
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue