Skip to content

Commit

Permalink
Added extra components
Browse files Browse the repository at this point in the history
  • Loading branch information
adriandelgg committed Sep 30, 2021
1 parent 283ba8b commit 01c71e6
Show file tree
Hide file tree
Showing 11 changed files with 19,452 additions and 6,654 deletions.
23 changes: 23 additions & 0 deletions frontend/components/context/Layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import NavBar from '@components/navbar/NavBar';
import Head from 'next/head';

const Layout: React.FC = ({ children }) => (
<>
<Head>
<link rel="icon" href="/bp-logo.svg" />
<link rel="shortcut icon" href="/bp-logo.svg" />
</Head>
<NavBar />
<main>
<img
className="mx-auto mt-6 mb-2"
src="bp-logo.svg"
alt="BP Logo"
width="110"
/>
{children}
</main>
</>
);

export default Layout;
89 changes: 89 additions & 0 deletions frontend/components/context/Web3Context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { createContext, useState, useEffect } from 'react';
import type { BigNumberish } from '@ethersproject/bignumber';
import type { Web3 } from '@components/navbar/MetaMask';
import { formatEther } from '@ethersproject/units';

declare let window: any;

export const Web3Context = createContext<any>(null);

const Web3ProviderComponent: React.FC = ({ children }) => {
const [newRegister, setNewRegister] = useState<boolean>();
const [
{
gameContract,
nftContract,
provider,
account,
etherBalance,
tokenBalance
},
setWeb3
] = useState<any>({
gameContract: '',
nftContract: '',
provider: '',
account: '',
etherBalance: '',
tokenBalance: ''
});

// Listens for network changes to reload the page
useEffect(() => {
window.ethereum.on('chainChanged', (chainId: string) =>
window.location.reload()
);
return () =>
window.ethereum.removeListener('chainChanged', (chainId: string) =>
window.location.reload()
);
}, []);

// Listens for a change in account and updates state
useEffect(() => {
if (gameContract && provider) {
function newAccount(accounts: Array<string>) {
const signer = provider?.getSigner(accounts[0]);

gameContract
.balanceOf(signer._address)
.then((tokenBalance: BigNumberish) => {
signer?.getBalance().then((balance: BigNumberish) =>
setWeb3((prev: Web3) => ({
...prev,
gameContract: gameContract?.connect(signer),
nftContract: nftContract?.connect(signer),
account: signer._address,
etherBalance: Number(formatEther(balance)).toFixed(4),
tokenBalance: Number(formatEther(tokenBalance)).toFixed(4)
}))
);
});
}

window.ethereum.on('accountsChanged', newAccount);
return () =>
window.ethereum.removeListener('accountsChanged', newAccount);
}
}, [account]);

return (
<Web3Context.Provider
value={{
gameContract,
nftContract,
provider,
account,
etherBalance,
tokenBalance,
newRegister,
setNewRegister,
setWeb3
}}
>
{children}
</Web3Context.Provider>
);
};

export default Web3ProviderComponent;
19 changes: 19 additions & 0 deletions frontend/components/helpers/DarkModeToggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useState } from 'react';
import { DarkModeSwitch } from 'react-toggle-dark-mode';

const DarkModeToggle = () => {
const [isDarkMode, setDarkMode] = useState(false);

const toggleDarkMode = (checked: boolean) => {
setDarkMode(checked);
isDarkMode
? document.documentElement.classList.remove('dark')
: document.documentElement.classList.add('dark');
};

return (
<DarkModeSwitch checked={isDarkMode} onChange={toggleDarkMode} size={35} />
);
};

export default DarkModeToggle;
14 changes: 14 additions & 0 deletions frontend/components/helpers/Loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Loader from 'react-loader-spinner';

interface Props {
isLoading: boolean;
}

const Loading = ({ isLoading }: Props) =>
isLoading ? (
<div className="flex justify-center">
<Loader type="TailSpin" color="#009900" height={100} width={100} />
</div>
) : null;

export default Loading;
130 changes: 130 additions & 0 deletions frontend/components/navbar/MetaMask.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import { useContext } from 'react';
import { Web3Context } from '@components/context/Web3Context';
import { gameABI } from '@components/ABIs/gameABI';
import { nftABI } from '@components/ABIs/nftABI';

import { Web3Provider } from '@ethersproject/providers';
import { Contract } from '@ethersproject/contracts';
import { formatEther } from '@ethersproject/units';
import { toast } from 'react-toastify';

declare let window: any;

export interface Web3 {
gameContract: any;
nftContract: Contract | string;
provider: Web3Provider;
account: string;
etherBalance: string;
tokenBalance: string;
}

const MetaMask = () => {
const { account, setWeb3 } = useContext(Web3Context);

async function enableEth() {
try {
if (window.ethereum) {
const ethereum = window.ethereum;

const provider = new Web3Provider(ethereum);
const [address] = await ethereum.request({
method: 'eth_requestAccounts'
});
const chainId = await ethereum.request({ method: 'eth_chainId' });

let nftAddress;
let gameAddress;
switch (chainId) {
case '0x1': // Mainnet
nftAddress = '';
gameAddress = '';
break;
case '0x3': // Ropsten
nftAddress = '';
gameAddress = '';
break;
case '0x4': // Rinkeby
nftAddress = '0x8F7117FeA39fdB8E3335090d7211A6128E4d5cC0';
gameAddress = '0x141EC0C2b4C193675594EAf316faAD8784dA8A11';
break;
case '0x89': // Polygon Mainnet
nftAddress = '';
gameAddress = '';
break;
case '0x13881': // Polygon Testnet
nftAddress = '';
gameAddress = '';
break;
case '0x7a69': // Hardhat Local
nftAddress = '0x5FbDB2315678afecb367f032d93F642f64180aa3';
gameAddress = '0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512';
}

const signer = provider.getSigner(address);

const nftContract = nftAddress
? new Contract(nftAddress, nftABI, signer)
: '';
const gameContract: any = gameAddress
? new Contract(gameAddress, gameABI, signer)
: '';

const account = signer._address;

const tokenBalance = Number(
formatEther(await gameContract.balanceOf(account))
).toFixed(4);
console.log(tokenBalance);

const etherBalance = Number(
formatEther(await signer.getBalance())
).toFixed(4);

setWeb3((prev: Web3) => ({
...prev,
gameContract,
nftContract,
provider,
account,
etherBalance,
tokenBalance
}));
} else if (window.web3) {
console.log('Update MetaMask');
} else {
console.log('Enable MetaMask');
}
} catch (e) {
console.error(e);
}
}

return (
<div className="py-3">
{!account ? (
<button className="metamask-btn" onClick={enableEth}>
Connect Wallet
</button>
) : (
<button
className="blue-btn"
onClick={() =>
toast.info(`Your wallet address is: ${account}`, {
autoClose: 3000,
position: 'top-center',
style: {
width: 520
},
theme: 'colored'
})
}
>
Wallet Connected
</button>
)}
</div>
);
};

export default MetaMask;
48 changes: 48 additions & 0 deletions frontend/components/navbar/NavBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { useRouter } from 'next/router';
import Link from 'next/link';
import { Web3Context } from '@components/context/Web3Context';

import { ToastContainer } from 'react-toastify';
import MetaMask from './MetaMask';
import { useContext } from 'react';
import DarkModeToggle from '@components/helper/DarkModeToggle';

const NavBar = () => {
const { etherBalance, tokenBalance } = useContext(Web3Context);
const { asPath: path } = useRouter();

return (
<>
<ToastContainer />
<header
className="flex justify-around items-center py-3
border-b-2 border-gray-100 dark:border-gray-700"
>
<nav>
<ul className="flex justify-around text-center">
<li className={path === '/' ? 'active-nav' : 'nav-item'}>
<Link href="/">Home</Link>
</li>
<li
className={path === '/predictiongame' ? 'active-nav' : 'nav-item'}
>
<Link href="/predictiongame">Prediction Game</Link>
</li>
</ul>
</nav>
<div className="flex items-center">
<div className="mr-10 pt-1">
<p>BP Token Balance: {tokenBalance}</p>
<p className="">Ether Balance: {etherBalance}</p>
</div>
<MetaMask />
<div className="ml-5">
<DarkModeToggle />
</div>
</div>
</header>
</>
);
};

export default NavBar;
Loading

0 comments on commit 01c71e6

Please sign in to comment.