Initial commit with 🏗️ Scaffold-ETH 2 @ 1.0.5
This commit is contained in:
97
packages/nextjs/app/myNFTs/_components/MyHoldings.tsx
Normal file
97
packages/nextjs/app/myNFTs/_components/MyHoldings.tsx
Normal file
@@ -0,0 +1,97 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { NFTCard } from "./NFTCard";
|
||||
import { useAccount } from "wagmi";
|
||||
import { useScaffoldContract, useScaffoldReadContract } from "~~/hooks/scaffold-eth";
|
||||
import { notification } from "~~/utils/scaffold-eth";
|
||||
import { getMetadataFromIPFS } from "~~/utils/tokenization/ipfs-fetch";
|
||||
import { NFTMetaData } from "~~/utils/tokenization/nftsMetadata";
|
||||
|
||||
export interface Collectible extends Partial<NFTMetaData> {
|
||||
id: number;
|
||||
uri: string;
|
||||
owner: string;
|
||||
}
|
||||
|
||||
export const MyHoldings = () => {
|
||||
const { address: connectedAddress } = useAccount();
|
||||
const [myAllCollectibles, setMyAllCollectibles] = useState<Collectible[]>([]);
|
||||
const [allCollectiblesLoading, setAllCollectiblesLoading] = useState(false);
|
||||
|
||||
const { data: yourCollectibleContract } = useScaffoldContract({
|
||||
contractName: "YourCollectible",
|
||||
});
|
||||
|
||||
const { data: myTotalBalance } = useScaffoldReadContract({
|
||||
contractName: "YourCollectible",
|
||||
functionName: "balanceOf",
|
||||
args: [connectedAddress],
|
||||
watch: true,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const updateMyCollectibles = async (): Promise<void> => {
|
||||
if (myTotalBalance === undefined || yourCollectibleContract === undefined || connectedAddress === undefined)
|
||||
return;
|
||||
|
||||
setAllCollectiblesLoading(true);
|
||||
const collectibleUpdate: Collectible[] = [];
|
||||
const totalBalance = parseInt(myTotalBalance.toString());
|
||||
for (let tokenIndex = 0; tokenIndex < totalBalance; tokenIndex++) {
|
||||
try {
|
||||
const tokenId = await yourCollectibleContract.read.tokenOfOwnerByIndex([
|
||||
connectedAddress,
|
||||
BigInt(tokenIndex),
|
||||
]);
|
||||
|
||||
const tokenURI = await yourCollectibleContract.read.tokenURI([tokenId]);
|
||||
|
||||
const ipfsHash = tokenURI.replace("https://ipfs.io/ipfs/", "");
|
||||
|
||||
const nftMetadata: NFTMetaData = await getMetadataFromIPFS(ipfsHash);
|
||||
|
||||
collectibleUpdate.push({
|
||||
id: parseInt(tokenId.toString()),
|
||||
uri: tokenURI,
|
||||
owner: connectedAddress,
|
||||
...nftMetadata,
|
||||
});
|
||||
} catch (e) {
|
||||
notification.error("Error fetching all collectibles");
|
||||
setAllCollectiblesLoading(false);
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
collectibleUpdate.sort((a, b) => a.id - b.id);
|
||||
setMyAllCollectibles(collectibleUpdate);
|
||||
setAllCollectiblesLoading(false);
|
||||
};
|
||||
|
||||
updateMyCollectibles();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [connectedAddress, myTotalBalance]);
|
||||
|
||||
if (allCollectiblesLoading)
|
||||
return (
|
||||
<div className="flex justify-center items-center mt-10">
|
||||
<span className="loading loading-spinner loading-lg"></span>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{myAllCollectibles.length === 0 ? (
|
||||
<div className="flex justify-center items-center mt-10">
|
||||
<div className="text-2xl text-primary-content">No NFTs found</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-wrap gap-4 my-8 px-5 justify-center">
|
||||
{myAllCollectibles.map(item => (
|
||||
<NFTCard nft={item} key={item.id} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
66
packages/nextjs/app/myNFTs/_components/NFTCard.tsx
Normal file
66
packages/nextjs/app/myNFTs/_components/NFTCard.tsx
Normal file
@@ -0,0 +1,66 @@
|
||||
import { useState } from "react";
|
||||
import { Collectible } from "./MyHoldings";
|
||||
import { Address, AddressInput } from "~~/components/scaffold-eth";
|
||||
import { useScaffoldWriteContract } from "~~/hooks/scaffold-eth";
|
||||
|
||||
export const NFTCard = ({ nft }: { nft: Collectible }) => {
|
||||
const [transferToAddress, setTransferToAddress] = useState("");
|
||||
|
||||
const { writeContractAsync } = useScaffoldWriteContract({ contractName: "YourCollectible" });
|
||||
|
||||
return (
|
||||
<div className="card card-compact bg-base-100 shadow-lg w-[300px] shadow-secondary">
|
||||
<figure className="relative">
|
||||
{/* eslint-disable-next-line */}
|
||||
<img src={nft.image} alt="NFT Image" className="h-60 min-w-full" />
|
||||
<figcaption className="glass absolute bottom-4 left-4 p-4 rounded-xl">
|
||||
<span className="text-white "># {nft.id}</span>
|
||||
</figcaption>
|
||||
</figure>
|
||||
<div className="card-body space-y-3">
|
||||
<div className="flex items-center justify-center">
|
||||
<p className="text-xl p-0 m-0 font-semibold">{nft.name}</p>
|
||||
<div className="flex flex-wrap space-x-2 mt-1">
|
||||
{nft.attributes?.map((attr, index) => (
|
||||
<span key={index} className="badge badge-primary px-1.5">
|
||||
{attr.value}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col justify-center mt-1">
|
||||
<p className="my-0 text-lg">{nft.description}</p>
|
||||
</div>
|
||||
<div className="flex space-x-3 mt-1 items-center">
|
||||
<span className="text-lg font-semibold">Owner : </span>
|
||||
<Address address={nft.owner} />
|
||||
</div>
|
||||
<div className="flex flex-col my-2 space-y-1">
|
||||
<span className="text-lg font-semibold mb-1">Transfer To: </span>
|
||||
<AddressInput
|
||||
value={transferToAddress}
|
||||
placeholder="receiver address"
|
||||
onChange={newValue => setTransferToAddress(newValue)}
|
||||
/>
|
||||
</div>
|
||||
<div className="card-actions justify-end">
|
||||
<button
|
||||
className="btn btn-secondary btn-md px-8 tracking-wide"
|
||||
onClick={() => {
|
||||
try {
|
||||
writeContractAsync({
|
||||
functionName: "transferFrom",
|
||||
args: [nft.owner, transferToAddress, BigInt(nft.id.toString())],
|
||||
});
|
||||
} catch (err) {
|
||||
console.error("Error calling transferFrom function", err);
|
||||
}
|
||||
}}
|
||||
>
|
||||
Send
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
1
packages/nextjs/app/myNFTs/_components/index.ts
Normal file
1
packages/nextjs/app/myNFTs/_components/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from "./MyHoldings";
|
||||
Reference in New Issue
Block a user