对接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 &&
|
||||||
return (
|
list.map((item) => {
|
||||||
<TrFlex key={item.id}>
|
return (
|
||||||
<TdFlex>
|
<TrFlex key={item.id}>
|
||||||
<TdImage src="/images/nft/epic-icon.svg" width={24} height={40} />
|
<TdFlex>
|
||||||
{item.name}
|
{/* <TdImage src="/images/nft/epic-icon.svg" width={24} height={40} /> */}
|
||||||
</TdFlex>
|
{item.goodsName}
|
||||||
<TdFlex>{item.price}</TdFlex>
|
</TdFlex>
|
||||||
<TdFlex>{item.newPrice}</TdFlex>
|
<TdFlex>{item.price}</TdFlex>
|
||||||
<TdFlex>{item.time}</TdFlex>
|
<TdFlex>{item.lastPrice}</TdFlex>
|
||||||
<TdFlex>{item.status}</TdFlex>
|
<TdFlex>{item.updatedAt}</TdFlex>
|
||||||
<TdBtnFlex>
|
<TdFlex>{statusTxt[item.status]}</TdFlex>
|
||||||
<DetailButton>{t('Detail')}</DetailButton>
|
<TdBtnFlex>
|
||||||
<HashText>{t('deal Hash')}</HashText>
|
<DetailButton onClick={() => lookDetail(item)}>{t('Detail')}</DetailButton>
|
||||||
</TdBtnFlex>
|
<HashText onClick={() => goHash(item)}>{t('deal Hash')}</HashText>
|
||||||
</TrFlex>
|
</TdBtnFlex>
|
||||||
)
|
</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,29 +26,44 @@ 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>
|
||||||
<HeaderText>{t('Auction rule')}</HeaderText>
|
{typeIndex === 1 && (
|
||||||
<DetailText>
|
<>
|
||||||
{t('1. When the countdown is less than 1 hour, the countdown time will be increased by 1 hour each time')}
|
<HeaderText>{t('Selling rules')}</HeaderText>
|
||||||
</DetailText>
|
<DetailText>{t('1.NFT may not be traded or transferred at the time of sale')}</DetailText>
|
||||||
<DetailText>
|
<DetailText>
|
||||||
{t(
|
{t(
|
||||||
'2. Each auction has a fixed 10% markup. After the countdown, the item will be awarded to the bidder who made the last bid',
|
'2. After the successful sale of NFT, the platform will charge the publisher 6% of the profits as a commission fee',
|
||||||
)}
|
)}
|
||||||
</DetailText>
|
</DetailText>
|
||||||
<DetailText>{t('3. After the auction is successful')}</DetailText>
|
</>
|
||||||
<DetailText>
|
)}
|
||||||
{t(
|
{typeIndex === 2 && (
|
||||||
'4. After the auction, the publisher or the last bidder will collect revenue or NFT in the auction history. After one party of the bidder or the publisher receives revenue or NFT, the other party will automatically receive the corresponding revenue or NFT',
|
<>
|
||||||
)}
|
<HeaderText>{t('Auction rule')}</HeaderText>
|
||||||
</DetailText>
|
<DetailText>
|
||||||
<DetailText>
|
{t('1. When the countdown is less than 1 hour, the countdown time will be increased by 1 hour each time')}
|
||||||
{t('5. NFT shall not be traded or transferred after the auction is issued by the issuer')}
|
</DetailText>
|
||||||
</DetailText>
|
<DetailText>
|
||||||
|
{t(
|
||||||
|
'2. Each auction has a fixed 10% markup. After the countdown, the item will be awarded to the bidder who made the last bid',
|
||||||
|
)}
|
||||||
|
</DetailText>
|
||||||
|
<DetailText>{t('3. After the auction is successful')}</DetailText>
|
||||||
|
<DetailText>
|
||||||
|
{t(
|
||||||
|
'4. After the auction, the publisher or the last bidder will collect revenue or NFT in the auction history. After one party of the bidder or the publisher receives revenue or NFT, the other party will automatically receive the corresponding revenue or NFT',
|
||||||
|
)}
|
||||||
|
</DetailText>
|
||||||
|
<DetailText>
|
||||||
|
{t('5. NFT shall not be traded or transferred after the auction is issued by the issuer')}
|
||||||
|
</DetailText>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</FlexMain>
|
</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 ? (
|
||||||
return (
|
list?.map((item, index) => {
|
||||||
<TrFlex key={item.id}>
|
return (
|
||||||
<TdFlex>{item.name}</TdFlex>
|
<TrFlex key={item.id}>
|
||||||
<TdFlex>{item.price}</TdFlex>
|
<TdFlex>
|
||||||
<TdFlex>{item.newPrice}</TdFlex>
|
<Tooltip title={item.address}>
|
||||||
<TdFlex>{item.time}</TdFlex>
|
<div>
|
||||||
<TdFlex>{item.status}</TdFlex>
|
{item.address && item.address.substring(0, 6)}....
|
||||||
</TrFlex>
|
{item.address && item.address.substring(item.address.length - 6, item.tx.length)}
|
||||||
)
|
</div>
|
||||||
})}
|
</Tooltip>
|
||||||
|
</TdFlex>
|
||||||
|
<TdFlex>
|
||||||
|
<TxFlex onClick={() => goHash(item.tx)}>
|
||||||
|
<div className="linkText" style={{ borderBottom: '1px solid #666' }}>
|
||||||
|
{item.tx && item.tx.substring(0, 6)}....
|
||||||
|
{item.tx && item.tx.substring(item.tx.length - 6, item.tx.length)}
|
||||||
|
</div>
|
||||||
|
</TxFlex>
|
||||||
|
</TdFlex>
|
||||||
|
<TdFlex>{item.price}</TdFlex>
|
||||||
|
<TdFlex>{item.updatedAt}</TdFlex>
|
||||||
|
<TdFlex>
|
||||||
|
{time < new Date().getTime() && index === 0
|
||||||
|
? t('traded')
|
||||||
|
: time > new Date().getTime() && index === 0
|
||||||
|
? '-'
|
||||||
|
: t('out')}
|
||||||
|
</TdFlex>
|
||||||
|
</TrFlex>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
) : (
|
||||||
|
<Empty />
|
||||||
|
)}
|
||||||
</TableBody>
|
</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,19 +223,42 @@ 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))
|
||||||
arr.forEach((item) => {
|
if (!locationData?.type) {
|
||||||
if (item.id === locationData.id) {
|
arr.forEach((item) => {
|
||||||
setDetail(item)
|
if (item.id === locationData.id) {
|
||||||
setDetailVisible(true)
|
setDetail(item)
|
||||||
}
|
setDetailVisible(true)
|
||||||
})
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
setCount(getTotalPageNum(data.total, data.size))
|
setCount(getTotalPageNum(data.total, data.size))
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getData()
|
if (location.search) {
|
||||||
}, [pageNum, searchGrade])
|
const locationData = qs.parse(location.search.slice(1))
|
||||||
|
if (locationData.type) {
|
||||||
|
setTypeIndex(Number(locationData.type))
|
||||||
|
setId(locationData.id.toString())
|
||||||
|
setDetailVisible(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
useEffect(() => {
|
||||||
|
switch (typeIndex) {
|
||||||
|
case 0:
|
||||||
|
getData()
|
||||||
|
break
|
||||||
|
case 1:
|
||||||
|
getTradeList('NORMAL')
|
||||||
|
break
|
||||||
|
case 2:
|
||||||
|
getTradeList('AUCTION')
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
getData()
|
||||||
|
}
|
||||||
|
}, [pageNum, searchGrade, typeIndex, detailVisible, auctionSelect])
|
||||||
|
|
||||||
useEffect(() => {
|
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,30 +82,54 @@ 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)}>
|
||||||
<ShopList
|
{typeIndex === 0 && (
|
||||||
item={item}
|
<>
|
||||||
width={278}
|
<ShopList
|
||||||
height={302}
|
item={item}
|
||||||
img={item.coverResource.url}
|
width={278}
|
||||||
grade={item.grade}
|
height={302}
|
||||||
borderRadius="20px 20px 0 0"
|
img={item.coverResource.url}
|
||||||
/>
|
grade={item.grade}
|
||||||
<ShopName>{item.name}</ShopName>
|
borderRadius="20px 20px 0 0"
|
||||||
<ShopFooter>
|
/>
|
||||||
<FooterLabel>{t('trading value')}</FooterLabel>
|
<ShopName>{item.name}</ShopName>
|
||||||
<FooterValue>
|
<ShopFooter>
|
||||||
{item.priceList.map((childItem, index) => {
|
<FooterLabel>{t('trading value')}</FooterLabel>
|
||||||
return (
|
<FooterValue>
|
||||||
<Flex alignItems="center" key={childItem.label}>
|
{item?.priceList?.map((childItem, index) => {
|
||||||
{/* <>{formatTimeNumber(childItem.value)}</> */}
|
return (
|
||||||
<>{Number(childItem.value).toFixed(2)}</>
|
<Flex alignItems="center" key={childItem.label}>
|
||||||
<Text color="text">{childItem.label}</Text>
|
{/* <>{formatTimeNumber(childItem.value)}</> */}
|
||||||
{index === 0 && item.priceList.length === 2 && <Text margin="0 5px">-</Text>}
|
<>{Number(childItem.value).toFixed(2)}</>
|
||||||
</Flex>
|
<Text color="text">{childItem.label}</Text>
|
||||||
)
|
{index === 0 && item.priceList.length === 2 && <Text margin="0 5px">-</Text>}
|
||||||
})}
|
</Flex>
|
||||||
</FooterValue>
|
)
|
||||||
</ShopFooter>
|
})}
|
||||||
|
</FooterValue>
|
||||||
|
</ShopFooter>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{typeIndex !== 0 && (
|
||||||
|
<>
|
||||||
|
<ShopList
|
||||||
|
item={item}
|
||||||
|
width={278}
|
||||||
|
height={302}
|
||||||
|
img={item.coverResource.url}
|
||||||
|
grade={item.grade}
|
||||||
|
borderRadius="20px 20px 0 0"
|
||||||
|
/>
|
||||||
|
<ShopName>{item?.goodsName}</ShopName>
|
||||||
|
<ShopFooter>
|
||||||
|
<FooterLabel>{t('trading value')}</FooterLabel>
|
||||||
|
<FooterValue>
|
||||||
|
{item?.price}
|
||||||
|
{TOKEN_SYMBOL}
|
||||||
|
</FooterValue>
|
||||||
|
</ShopFooter>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</ShopFlex>
|
</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 */}
|
||||||
<ShopFlex>
|
{!shopData?.info?.id && <AddNftButton onClick={onSelectNft}>{t('add NFT')}</AddNftButton>}
|
||||||
<ShopList item={shopData} width={278} height={280} borderRadius="20px 20px 0 0" />
|
{shopData?.info?.id && (
|
||||||
<ShopName>{shopData.label}</ShopName>
|
<ShopFlex>
|
||||||
</ShopFlex>
|
<ShopList
|
||||||
<ShopButton>{t('Selling immediately')}</ShopButton>
|
item={shopData}
|
||||||
<ShopButton onClick={onSelectNft}>{t('reselect NFT')}</ShopButton>
|
img={shopData?.info?.coverResource?.url}
|
||||||
|
width={278}
|
||||||
|
height={280}
|
||||||
|
borderRadius="20px 20px 0 0"
|
||||||
|
/>
|
||||||
|
<ShopName>{shopData?.info?.name}</ShopName>
|
||||||
|
</ShopFlex>
|
||||||
|
)}
|
||||||
|
{shopData?.info?.id && isApprovedFor && (
|
||||||
|
<ShopButton onClick={sellNow} disabled={loading}>
|
||||||
|
{t('Selling immediately')}
|
||||||
|
</ShopButton>
|
||||||
|
)}
|
||||||
|
{shopData?.info?.id && <ShopButton onClick={onSelectNft}>{t('reselect NFT')}</ShopButton>}
|
||||||
|
{shopData?.info?.id && !isApprovedFor && (
|
||||||
|
<AddNftButton mt="8px" width="100%" onClick={agreement} disabled={agreementLoading}>
|
||||||
|
{t('license agreement')}
|
||||||
|
</AddNftButton>
|
||||||
|
)}
|
||||||
</Shop>
|
</Shop>
|
||||||
{showModal && (
|
{showModal && (
|
||||||
<SelectShopModal>
|
<SelectShopModal>
|
||||||
<ShopModal close={close} />
|
<ShopModal close={close} add={(v) => getShopDetail(v)} />
|
||||||
</SelectShopModal>
|
</SelectShopModal>
|
||||||
)}
|
)}
|
||||||
</FlexMain>
|
</FlexMain>
|
||||||
|
|
|
||||||
|
|
@ -194,22 +194,32 @@ 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"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<FlexCom
|
{!detail.record && (
|
||||||
name={t('present price%price%', { price: '' })}
|
<FlexCom
|
||||||
value={price}
|
name={t('present price%price%', { price: '' })}
|
||||||
size="18px"
|
value={price}
|
||||||
rightSize="30px"
|
size="18px"
|
||||||
textColor="#1FC7D4"
|
rightSize="30px"
|
||||||
/>
|
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 &&
|
||||||
return (
|
list?.map((item, index) => {
|
||||||
<ShopFlex key={item.id} onClick={() => pitchOn(index)} className={item.select ? 'active' : ''}>
|
return (
|
||||||
<SelectFlex>{item.select && <SelectDiv />}</SelectFlex>
|
<ShopFlex key={item?.id} onClick={() => pitchOn(index)} className={item?.select ? 'active' : ''}>
|
||||||
<ShopList item={item} width={278} height={280} borderRadius="20px 20px 0 0" />
|
<SelectFlex>{item?.select && <SelectDiv />}</SelectFlex>
|
||||||
<ShopName>{item.label}</ShopName>
|
<ShopList
|
||||||
</ShopFlex>
|
item={item}
|
||||||
)
|
img={item?.info?.coverResource?.url}
|
||||||
})}
|
width={278}
|
||||||
|
height={280}
|
||||||
|
borderRadius="20px 20px 0 0"
|
||||||
|
/>
|
||||||
|
<ShopName>{item?.info?.name}</ShopName>
|
||||||
|
</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(() => {
|
||||||
getList()
|
if (activeIndex !== 0) {
|
||||||
}, [pageNum])
|
getWayList()
|
||||||
|
} else {
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
}, [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) => {
|
||||||
const res = await getNftDetail(item.token, { token: item.token })
|
let obj = { record: false, token: '' }
|
||||||
const obj = res.info
|
if (activeIndex !== 0) {
|
||||||
obj.record = true
|
obj = item
|
||||||
|
} else {
|
||||||
|
const res = await getNftDetail(item.token, { token: item.token })
|
||||||
|
obj = res.info
|
||||||
|
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,18 +252,22 @@ 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>
|
||||||
<TdFlex>
|
{activeIndex === 0 && (
|
||||||
{item.priceList.map((childItem, childIndex) => {
|
<TdFlex>
|
||||||
return (
|
{item.priceList.map((childItem, childIndex) => {
|
||||||
<Flex alignItems="center" key={childItem.label}>
|
return (
|
||||||
<>{Number(childItem.value).toFixed(2)}</>
|
<Flex alignItems="center" key={childItem.label}>
|
||||||
<Text color="text">{childItem.label}</Text>
|
<>{Number(childItem.value).toFixed(2)}</>
|
||||||
{childIndex === 0 && item.priceList.length === 2 && <Text margin="0 5px">-</Text>}
|
<Text color="text">{childItem.label}</Text>
|
||||||
</Flex>
|
{childIndex === 0 && item.priceList.length === 2 && <Text margin="0 5px">-</Text>}
|
||||||
)
|
</Flex>
|
||||||
})}
|
)
|
||||||
</TdFlex>
|
})}
|
||||||
<TdFlex>{dayjs(Number(item.tradeTime)).format('YYYY-MM-DD HH:mm:ss')}</TdFlex>
|
</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