5.6.1Màn hình và chức năng: ● Màn hình Hình 5.5 Màn hình trang Resell NFT. ● Chức năng: STT Thành phần Mô tả 1 Asset price in Eth
Một trường cho phép nhập giá của NFT (tính bằng Ethereum) để bán lại NFT này
2 Nút List NFT Đưa NFT vào danh sách bán
Bảng 5.5 Bảng chức năng trang Resell NFT.
5.6.2 Code:
/* pages/resell-nft.js */
import { useEffect, useState } from'react'
import { ethers } from'ethers'
import { useRouter } from'next/router'
importaxiosfrom'axios'
import {
marketplaceAddress } from'../config'
import NFTMarketplace from
'../artifacts/contracts/NFTMarketplace.sol/NFTMarketplace.json'
exportdefaultfunctionResellNFT() {
const [formInput, updateFormInput] = useState({ price: '', image:'' }) constrouter = useRouter()
const { id, tokenURI } = router.query const { image, price } = formInput useEffect(() => {
fetchNFT() }, [id])
asyncfunctionfetchNFT() { if (!tokenURI) return
const meta = awaitaxios.get(tokenURI)
updateFormInput(state=> ({ ...state, image:meta.data.image })) }
/* List các NFT dùng để mua bán */
asyncfunctionlistNFTForSale() { if (!price) return
const web3Modal = newWeb3Modal()
const connection = awaitweb3Modal.connect()
const provider = newethers.providers.Web3Provider(connection) const signer = provider.getSigner()
const priceFormatted = ethers.utils.parseUnits(formInput.price, 'ether')
let contract = new ethers.Contract(marketplaceAddress, NFTMarketplace.abi, signer)
let listingPrice = await contract.getListingPrice() listingPrice = listingPrice.toString()
let transaction = await contract.resellToken(id, priceFormatted, { value: listingPrice })
await transaction.wait() router.push('/')
} return (
<divclassName="flex justify-center">
<divclassName="w-1/2 flex flex-col pb-12"> <input
placeholder="Asset Price in Eth"
className="mt-2 border rounded p-4"
onChange={e=>updateFormInput({ ...formInput, price:e.target.value })} />
{
image && (
<imgclassName="rounded mt-4" width="350"src={image}/> )
}
<button onClick={listNFTForSale} className="font-bold mt-4 bg-pink-500 text-white rounded p-4 shadow-lg">
List NFT </button> </div> </div> ) } 5.7 Màn hình Dashboard 5.7.1 Màn hình và chức năng: ● Màn hình
Hình 5.6 Màn hình trang Dashboard.
● Chức năng:
STT Thành phần Mô tả
1 Items Listed Liệt kê các NFT hiện có gồm thông tin về tên, mô tả, hình ảnh, giá.
2 Thanh
Search
Tìm NFT trong danh sách hiện có 3 Nút Detail Xem thông tin chi tiết NFT
Bảng 5.6 Bảng chức năng trang Dashboard.
5.7.2 Code:
/* pages/dashboard.js */
import { ethers } from'ethers'
import { useEffect, useState } from'react'
importaxiosfrom'axios'
import { useRouter } from'next/router'
import {
marketplaceAddress } from'../config'
import NFTMarketplace from
'../artifacts/contracts/NFTMarketplace.sol/NFTMarketplace.json'
exportdefaultfunctionCreatorDashboard() {
const [searchTerm, setSearchTerm] = useState(""); const [nfts, setNfts] = useState([])
const [loadingState, setLoadingState] = useState('not-loaded') useEffect(() => {
loadNFTs() }, [])
constrouter = useRouter() asyncfunctionloadNFTs() {
const web3Modal = newWeb3Modal({ network:'mainnet',
cacheProvider:true, })
const connection = awaitweb3Modal.connect()
const provider = newethers.providers.Web3Provider(connection) const signer = provider.getSigner()
const contract = new ethers.Contract(marketplaceAddress, NFTMarketplace.abi, signer)
const data = awaitcontract.fetchItemsListed()
const items = awaitPromise.all(data.map(asynci => { consttokenUri = await contract.tokenURI(i.tokenId) constmeta = awaitaxios.get(tokenUri)
let price = ethers.utils.formatUnits(i.price.toString(), 'ether') let item = {
price,
tokenId:i.tokenId.toNumber(), seller:i.seller,
owner:i.owner,
image:meta.data.image, name:meta.data.name,
description:meta.data.description, tokenURI :tokenUri } return item })) setNfts(items) setLoadingState('loaded') } /** * Chi tiết NFT * * @param{nft}nft */ functiondetailNFT(nft) {
router.push(`/detail-nft?id=${nft.tokenId}&tokenURI=$ {nft.tokenURI}&prev=dashboard`)
}
if (loadingState === 'loaded' && !nfts.length) return (<h1 className="py-10 px- 20 text-3xl">No NFTs listed</h1>)
return ( <div>
<divclass="w-full m-3 max-w-xs border-solid border-2 border-gray">
<input class="shadow appearance-none border rounded w-full py-2 px-3 text- gray-700 leading-tight focus:outline-none focus:shadow-outline" type="search"
placeholder="Search..."
onChange={(event) => {
setSearchTerm(event.target.value) } } />
</div> <div>
<divclassName="p-4"style={{ maxWidth:'1600px' }}> <h2className="text-2xl py-2">Items Listed</h2>
<divclassName="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 pt-4"> {
nfts.filter(nft => nft.name.toLowerCase().includes(searchTerm.toLowerCase())).map((nft, i) => ( <divkey={i}className="border shadow rounded-xl overflow-hidden"> <imgsrc={nft.image} className="rounded"/>
<divclassName="p-4">
<p style={{ height: '64px' }} className="text-2xl font- semibold">{nft.name}</p>
<divstyle={{ height:'70px', overflow:'hidden' }}> <pclassName="text-gray-400">{nft.description}</p> </div>
</div>
<divclassName="p-4 bg-black">
<pclassName="text-2xl font-bold text-white">Price - {nft.price} Eth</p> <button className="mt-4 w-full bg-pink-500 text-white font-bold py-2 px-12 rounded"onClick={() =>detailNFT(nft)}>Detail</button>
</div> </div> )) } </div> </div> </div> </div> ) }