Skip to content
This repository was archived by the owner on Oct 30, 2024. It is now read-only.

Update to allow multi stake/unstake #34

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions components/NFTCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ import {
ThirdwebNftMedia,
useContract,
useNFT,
Web3Button,
} from "@thirdweb-dev/react";
import type { FC } from "react";
import {
nftDropContractAddress,
stakingContractAddress,
} from "../consts/contractAddresses";
import styles from "../styles/Home.module.css";

Expand All @@ -22,20 +20,14 @@ const NFTCard: FC<NFTCardProps> = ({ tokenId }) => {
return (
<>
{nft && (
<div className={styles.nftBox}>
<div>
{nft.metadata && (
<ThirdwebNftMedia
metadata={nft.metadata}
className={styles.nftMedia}
/>
)}
<h3>{nft.metadata.name}</h3>
<Web3Button
action={(contract) => contract?.call("withdraw", [[nft.metadata.id]])}
contractAddress={stakingContractAddress}
>
Withdraw
</Web3Button>
</div>
)}
</>
Expand Down
78 changes: 66 additions & 12 deletions pages/stake.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ const Stake: NextPage = () => {
const { data: stakedTokens } = useContractRead(contract, "getStakeInfo", [
address,
]);
const [selectedNftsToStake, setSelectedNftsToStake] = useState<string[]>([]);
const [selectedNftsToWithdraw, setSelectedNftsToWithdraw] = useState<string[]>([]);

useEffect(() => {
if (!contract || !address) return;
Expand All @@ -48,7 +50,8 @@ const Stake: NextPage = () => {
loadClaimableRewards();
}, [address, contract]);

async function stakeNft(id: string) {

async function stakeNfts(ids: string[]) {
if (!address) return;

const isApproved = await nftDropContract?.isApproved(
Expand All @@ -58,13 +61,21 @@ const Stake: NextPage = () => {
if (!isApproved) {
await nftDropContract?.setApprovalForAll(stakingContractAddress, true);
}
await contract?.call("stake", [[id]]);
await contract?.call("stake", [ids]);
setSelectedNftsToStake([]);
}

if (isLoading) {
return <div>Loading</div>;
}

async function withdrawNfts(ids: string[]) {
if (!address) return;
await contract?.call("withdraw", [ids]);
setSelectedNftsToWithdraw([]);
}


return (
<div className={styles.container}>
<h1 className={styles.h1}>Stake Your NFTs</h1>
Expand Down Expand Up @@ -107,32 +118,75 @@ const Stake: NextPage = () => {
<div className={styles.nftBoxGrid}>
{stakedTokens &&
stakedTokens[0]?.map((stakedToken: BigNumber) => (
<NFTCard
tokenId={stakedToken.toNumber()}
<div
className={`${styles.nftBox} ${
selectedNftsToWithdraw.includes(stakedToken.toString())
? styles.selected
: ""
}`}
key={stakedToken.toString()}
/>
onClick={() => {
setSelectedNftsToWithdraw((prevSelectedNfts) => {
const tokenId = stakedToken.toString();
if (prevSelectedNfts.includes(tokenId)) {
return prevSelectedNfts.filter((id) => id !== tokenId);
} else {
return [...prevSelectedNfts, tokenId];
}
});
}}
>
<NFTCard tokenId={stakedToken.toNumber()} />
</div>
))}
</div>

<Web3Button
contractAddress={stakingContractAddress}
action={() => withdrawNfts(selectedNftsToWithdraw)}
isDisabled={selectedNftsToWithdraw.length === 0}
>
Withdraw Selected NFTs
</Web3Button>


<hr className={`${styles.divider} ${styles.spacerTop}`} />
<h2>Your Unstaked NFTs</h2>
<div className={styles.nftBoxGrid}>
{ownedNfts?.map((nft) => (
<div className={styles.nftBox} key={nft.metadata.id.toString()}>
<div
className={`${styles.nftBox} ${
selectedNftsToStake.includes(nft.metadata.id) ? styles.selected : ""
}`}
key={nft.metadata.id.toString()}
onClick={() => {
setSelectedNftsToStake((prevSelectedNfts) => {
if (prevSelectedNfts.includes(nft.metadata.id)) {
return prevSelectedNfts.filter(
(id) => id !== nft.metadata.id
);
} else {
return [...prevSelectedNfts, nft.metadata.id];
}
});
}}
>
<ThirdwebNftMedia
metadata={nft.metadata}
className={styles.nftMedia}
/>
<h3>{nft.metadata.name}</h3>
<Web3Button
contractAddress={stakingContractAddress}
action={() => stakeNft(nft.metadata.id)}
>
Stake
</Web3Button>
</div>
))}
</div>

<Web3Button
contractAddress={stakingContractAddress}
action={() => stakeNfts(selectedNftsToStake)}
isDisabled={selectedNftsToStake.length === 0}
>
Stake Selected NFTs
</Web3Button>
</>
)}
</div>
Expand Down
54 changes: 53 additions & 1 deletion styles/Home.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,48 @@
.nftBox {
border-radius: 16px;
border: 1px solid #ccc;
width: 19%;
min-height: 200px;
height: 300px;
padding: 16px;
max-width: 200px;
transition: transform 0.3s ease-in-out, border 0.3s ease-in-out;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin: 5px;
margin-bottom: 60px;
}

.nftBox h3 {
height: 60px;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}

.nftMedia {
max-width: 50%;
max-height: 140px;
padding-top: 20px;
padding-bottom: 20px;
border-radius: 15px;
object-fit: contain;
}

.nftBox .nftMedia {
transition: transform 0.3s ease-in-out;
}

.selected {
transform: scale(1.1);
border: 1px solid #f213a4;
animation: glowing-border 1.5s infinite;
}

.selected .nftMedia {
transform: scale(1.1);
}

.optionSelectBox {
Expand Down Expand Up @@ -77,6 +116,19 @@
margin-top: 0px;
}

/* Keyframes for select border aniamtion*/
@keyframes glowing-border {
0% {
box-shadow: 0 0 5px #f213a4;
}
50% {
box-shadow: 0 0 10px #f213a4, 0 0 20px #8008b7;
}
100% {
box-shadow: 0 0 5px #f213a4;
}
}

/* Between 1200 and 800 */
@media only screen and (min-width: 800px) and (max-width: 1200px) {
.nftBox {
Expand Down